Facebook Messenger sender_action_typing_on功能执行异常求助
嘿,作为折腾过Messenger聊天机器人的过来人,太懂这种“参数对了但功能死活不生效”的憋屈了!结合你说的情况——单独执行sender_action_typing_on有用,但和模板消息连起来就失效,大概率是异步流程处理出了问题,给你梳理几个排查和解决方向:
1. 先把异步调用的“等待逻辑”搞对
你提到用了sleep、await,但这里的坑点是:如果你的代码是异步环境(比如Node.js、Python的asyncio),用同步睡眠方法会直接阻塞事件循环,导致typing_on的请求还没发出去就被卡住了!
举两个常见语言的正确写法:
Python(用asyncio + aiohttp)
import aiohttp import asyncio async def send_typing(user_id, token): url = "https://graph.facebook.com/v18.0/me/messages" headers = { "Authorization": f"Bearer {token}", "Content-Type": "application/json" } payload = { "recipient": {"id": user_id}, "sender_action": "typing_on" } async with aiohttp.ClientSession() as session: # 必须await这个请求完成,确保typing气泡发出去 await session.post(url, json=payload, headers=headers) async def send_template(user_id, token): # 你的模板消息发送逻辑 pass async def handle_request(user_id, token): # 第一步:发送typing气泡,等待请求完成 await send_typing(user_id, token) # 第二步:用异步睡眠等待指定时长(别用time.sleep!) await asyncio.sleep(3) # 第三步:发送模板消息 await send_template(user_id, token)
Node.js(用axios + Promise)
const axios = require('axios'); async function sendTyping(userId, token) { const url = `https://graph.facebook.com/v18.0/me/messages`; const headers = { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }; const payload = { recipient: { id: userId }, sender_action: 'typing_on' }; // 必须await请求完成 await axios.post(url, payload, { headers }); } async function sendTemplate(userId, token) { // 你的模板消息发送逻辑 } async function handleMessage(userId, token) { await sendTyping(userId, token); // 用Promise包装setTimeout实现异步等待 await new Promise(resolve => setTimeout(resolve, 3000)); await sendTemplate(userId, token); }
2. 检查请求顺序和“覆盖问题”
Messenger的typing_on气泡会在你发送新消息时立刻消失,所以要确保:
typing_on的请求完全发送成功后,再开始计时- 计时结束后再发送模板消息,不要让两个请求的时序混乱
比如如果你的代码里没await发送typing_on的请求,直接就sleep+发模板,那typing_on的请求可能还在排队,就被后续的模板消息覆盖了,自然看不到气泡。
3. 再核对几个容易忽略的细节
虽然你说请求JSON符合规范,但再快速检查一遍:
sender_action的值是typing_on(下划线,不是连字符)- 请求的API版本是不是最新的(比如v18.0,旧版本可能有兼容问题)
- 请求头里的
Authorization格式正确:Bearer <你的页面令牌> recipient.id是不是用户的有效PSID(不是测试号的临时ID)
最后再提个小技巧
如果还是不确定,可以在发送typing_on的请求后,打印一下响应状态码和返回值。如果是200 OK,说明请求已经成功发送,问题就出在后续的时序或睡眠逻辑上;如果是其他状态码,再根据错误信息排查权限或参数问题。
内容的提问来源于stack exchange,提问作者Kristoffer Syversen
相关产品推荐
相关产品推荐

