You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用rtweet的tweet_post发布带媒体推文时遇错误求助

问题:rtweet发布带图片推文失败+OAuth2授权频繁失效

问题背景

  • 新版Twitter API v2每两小时需重新进行OAuth2授权,导致无法自动每日发布生成的图表推文
  • 已成功使用rtweet的tweet_post发布纯文本推文,但无法发布搭配.png图片的推文

代码示例

library(rtweet);
myclient <- rtweet_client(client_id, client_secret, app, scopes=NULL)
auth <- rtweet_oauth2(client = myclient, scopes = NULL)
png_path <- "P:/myfiles/projCPI.png"
statTweet <- "what i am saying to you"
tweet_post(statTweet, media=png_path, media_alt_text="what i am showing to you", token=auth)

错误及回溯信息

Error in `httr2::req_perform()`:
! Failed to parse error body with method defined in req_error()
Caused by error in `FUN()`:
! is.list(x) is not TRUE
Run `rlang::last_trace()` to see where the error occurred.

> rlang::last_trace()
> <error/rlang_error>
> Error in `httr2::req_perform()`:
> ! Failed to parse error body with method defined in req_error()
> Caused by error in `FUN()`:
> ! is.list(x) is not TRUE

---

Backtrace:
x

 1. -rtweet::tweet_post(...)
 2. -httr2::req_perform(req_final)
 3.     +-httr2:::resp_abort(resp, error_body(req, resp), call = error_call)
 4.     | \-rlang::abort(...)
 5.     |   \-rlang::is_formula(message, scoped = TRUE, lhs = FALSE)
 6.     \-httr2:::error_body(req, resp)
 7.       +-rlang::try_fetch(...)
 8.       | +-base::tryCatch(...)
 9.       | | \-base (local) tryCatchList(expr, classes, parentenv, handlers)
10.       | |   \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
11.       | |     \-base (local) doTryCatch(return(expr), name, parentenv, handler)
12.       | \-base::withCallingHandlers(...)
13.       \-httr2:::req_policy_call(req, "error_body", list(resp), default = NULL)
14.         +-rlang::exec(req$policies[[name]], !!!args)
15.         \-rtweet (local) `<fn>`(`<httr2_rs>`)
16.           +-base::do.call(rbind, lapply(r$errors, list2DF))
17.           \-base::lapply(r$errors, list2DF)
18.             \-base (local) FUN(X[[i]], ...)
19.               \-base::stopifnot(is.list(x), is.null(nrow) || nrow >= 0L)
20.                 \-base::stop(simpleError(msg, call = if (p <- sys.parent(1L)) sys.call(p)))

Run rlang::last_trace(drop = FALSE) to see 3 hidden frames.

已尝试的无效操作

  • 将图片作为对象或路径传入tweet_post均失败
  • 使用twitteR包遇到类似问题
  • 对直接用httr2实现不熟悉

解决建议

1. 修复图片推文发布失败问题

  • 补充OAuth2权限范围:当前代码中scopes=NULL缺少媒体上传必需的权限,需指定完整权限列表:
    myclient <- rtweet_client(client_id, client_secret, app, scopes = c("tweet.read", "tweet.write", "users.read", "media.write"))
    auth <- rtweet_oauth2(client = myclient, scopes = c("tweet.read", "tweet.write", "users.read", "media.write"))
    
    其中media.write是上传媒体文件的核心权限
  • 先上传媒体再发布推文:手动调用upload_media上传图片获取媒体ID,再传入tweet_post:
    media_id <- upload_media(png_path, token = auth)
    tweet_post(statTweet, media = media_id, media_alt_text = "what i am showing to you", token = auth)
    
  • 验证图片有效性:确认png_path指向的文件存在、格式为标准PNG且未损坏

2. 解决OAuth2两小时授权过期问题

  • 开启令牌持久化缓存:在rtweet_oauth2中添加cache=TRUE,令牌会自动保存到本地,下次运行无需重新授权:
    auth <- rtweet_oauth2(client = myclient, scopes = c("tweet.read", "tweet.write", "users.read", "media.write"), cache = TRUE)
    
  • 改用服务账号Bearer Token:如果是自动化脚本,在Twitter开发者平台申请服务账号权限,使用Bearer Token授权,无需频繁刷新:
    auth <- rtweet_bearer_token(token = "YOUR_BEARER_TOKEN")
    
    注意:需在开发者平台配置服务账号的推文发布及媒体上传权限

内容的提问来源于stack exchange,提问作者Michael Ashton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 21:15:21