如何检测Messenger待机事件?Handover协议下机器人监听异常排查
解决Messenger Handover协议下Standby事件无法接收的问题
我之前也踩过Handover协议的坑,咱们一步步来排查解决:
1. 先确认Webhook的订阅配置是否到位
- 打开Facebook开发者后台,找到你的应用的Webhook设置,检查Page订阅的事件列表:必须同时勾选
messaging_handovers和standby这两个事件,缺一个都不行。 - 顺便验证下Webhook的连通性:用后台的「Test」工具发送一个模拟的Standby事件,看看你的fulfillment能不能收到请求。如果连模拟事件都收不到,那肯定是Webhook的验证或者订阅有问题,先把这个搞定。
2. 检查Handover协议的角色配置
- 你的机器人需要被设置为Secondary Receiver,而收件箱(Page Inbox)是Primary Receiver。去Facebook页面的「设置」→「Messenger平台」→「Handover Protocol」里确认:
- 已经把你的机器人应用添加为Secondary Receiver;
- Primary Receiver默认是Page Inbox(如果没改的话),确保它的ID正确。
- 只有当你调用
pass_thread_controlAPI把对话控制权移交给Primary Receiver后,你的机器人进入待机状态,用户发消息才会触发Standby事件给它。
3. 排查DialogFlow集成与Fulfillment代码
- 先看DialogFlow的Facebook集成:在集成页面里,有没有启用Handover相关的配置?要确保已经指定了Primary Receiver的应用ID(就是Page Inbox对应的ID)。
- 重点检查fulfillment代码:Standby事件的请求结构和普通用户消息不一样!普通消息在
entry[0].messaging里,而Standby事件在entry[0].standby里。很多人会忽略这一点,代码只处理了messaging字段,自然收不到Standby事件。
举个简单的Node.js示例,你需要这么判断:app.post('/webhook', (req, res) => { const body = req.body; if (body.object === 'page') { body.entry.forEach(entry => { // 处理普通消息 if (entry.messaging) { // 你的现有逻辑 } // 处理Standby事件 if (entry.standby) { entry.standby.forEach(event => { console.log('收到Standby事件:', event); // 这里写监听待机消息的逻辑,比如判断用户是否要转回机器人 }); } }); res.status(200).send('EVENT_RECEIVED'); } else { res.sendStatus(404); } });
4. 权限与授权验证
- 确保你的机器人应用已经获得了
pages_messaging和pages_messaging_subscriptions这两个权限,并且已经完成了页面的授权(在Facebook开发者后台的「角色」→「页面权限」里确认应用能访问目标主页)。 - 如果权限有问题,即使配置正确,也收不到任何事件。
5. 测试移交流程
- 先让机器人和用户发起对话,然后调用
pass_thread_controlAPI(可以用Postman或者Facebook Graph API Explorer)把控制权交给Primary Receiver:POST /v18.0/<PAGE_ID>/pass_thread_control Body: { "recipient": {"id": "<USER_ID>"}, "target_app_id": "<PRIMARY_RECEIVER_APP_ID>" // 就是Page Inbox的ID } - 之后让用户发消息,查看你的fulfillment日志,看是否收到Standby事件。如果还是收不到,再回到前面的步骤逐一排查。
内容的提问来源于stack exchange,提问作者Yassine Abdellaoui
相关产品推荐
相关产品推荐

