R中实现Meta WhatsApp API异步“即发即弃”调用的技术问询
在R中实现Meta WhatsApp API的“即发即弃”请求
核心改进思路
你的需求是发送请求后无需等待响应即可继续下一个请求,之前用callr::r_bg的问题在于子进程资源开销大,且httr默认POST会等待完整响应。我们可以通过原生异步HTTP请求+速率控制解决问题,同时避免触发Meta API的每秒80条限流规则。
方案1:使用httr2实现轻量异步请求
httr2是httr的升级版本,原生支持异步请求,无需额外启动子进程,效率更高,能真正实现“即发即弃”。
修改后的代码
library(httr2) library(jsonlite) send_message <- function(number, variables, template, meta_number, meta_key, image_id = NA) { # 构建请求URL url <- paste0('https://graph.facebook.com/v17.0/', meta_number, '/messages') # 初始化请求并设置头部 req <- request(url) %>% req_headers( `Content-Type` = 'application/json', Authorization = paste('Bearer', meta_key) ) # 动态生成模板参数列表 parameters_list <- lapply(variables, function(var) { list(type = 'text', text = var) }) # 构建消息组件(图片头部+文本主体) components <- list() if (!is.na(image_id) && image_id != "") { image_component <- list( type = 'header', parameters = list( list(type = 'image', image = list(id = image_id)) ) ) components <- c(components, list(image_component)) } body_component <- list( type = 'body', parameters = parameters_list ) components <- c(components, list(body_component)) # 构建请求体并转为JSON body <- list( messaging_product = 'whatsapp', recipient_type = 'individual', to = paste0('57', as.character(number)), type = 'template', template = list( name = template, language = list(code = 'es'), components = components ) ) %>% toJSON(auto_unbox = TRUE) # 设置即发即弃规则:超时1ms,异步发送不等待响应 req %>% req_body_raw(body) %>% req_timeout(ms = 1) %>% req_perform_async() # 立即返回,不等待请求结果 return(invisible(TRUE)) }
方案2:批量发送的速率控制
如果要发送数千条消息,必须严格控制发送速率在每秒80条以内,避免被Meta API限流。以下是批量发送的示例:
library(purrr) # 示例:待发送的号码列表和对应变量 numbers <- c("123456789", "987654321", "1122334455") variables_list <- list( c("用户A", "订单号001"), c("用户B", "订单号002"), c("用户C", "订单号003") ) # 按每秒80条的速率批量发送 walk2(numbers, variables_list, function(num, vars) { send_message( number = num, variables = vars, template = "你的模板名称", meta_number = "你的Meta官方号码", meta_key = "你的API密钥" ) Sys.sleep(1/80) # 控制请求间隔,确保不超过速率限制 })
原代码失败原因
callr::r_bg启动子进程的开销极大,批量发送时会占用大量系统资源,导致效率低下httr::POST默认会等待服务器返回完整响应,即使使用子进程,本质上还是在等待结果,没有真正实现“即发即弃”- 未做速率控制,容易触发Meta API的限流机制,导致请求失败
注意事项
- 虽然是“即发即弃”,建议定期记录请求日志,避免丢失重要消息的发送记录
- 确保Meta API密钥、官方号码的权限配置正确,避免因权限问题导致请求静默失败
- 如果需要确认请求成功率,可以在异步请求中添加回调函数记录响应状态(会牺牲部分“即发即弃”的效率)
内容的提问来源于stack exchange,提问作者Ekapunk
相关产品推荐
相关产品推荐

