Node.js注册WhatsApp Webhooks时webhook验证失败如何解决
WhatsApp 与 Bot Framework 集成时Webhook验证失败修复方案
核心问题原因
你当前代码无法通过校验的核心原因是 Restify默认未注册查询参数解析中间件,直接读取req.query会得到空值,永远匹配不到Meta发来的校验参数,自然会返回400导致验证失败。
另外需要同步确认以下配置项,避免低级错误:
- 代码中配置的校验Token和Meta开发者后台填写的Verify Token完全一致,无多余空格、大小写完全匹配
- Meta后台填写的Webhook回调路径和代码中定义的路由路径完全一致,当前代码路由为
/webhooks,不要漏写路径层级 - 你的服务必须暴露在公网可访问的HTTPS地址下,Meta不支持HTTP协议、不支持本地localhost地址发起校验
修复后可运行代码
const restify = require('restify'); // 创建HTTP服务 const server = restify.createServer(); // 关键:必须在路由定义前注册查询参数解析中间件,否则无法读取URL携带的参数 server.use(restify.plugins.queryParser()); const LISTEN_PORT = process.env.port || process.env.PORT || 3978; const WEBHOOK_VERIFY_TOKEN = "verify-token"; // 该值需与Meta后台填写的校验令牌完全相同 server.listen(LISTEN_PORT, () => { console.log(`${server.name} 服务启动成功,监听地址:${server.url}`); }); // Webhook校验接口 server.get('/webhooks', (req, res) => { const mode = req.query['hub.mode']; const token = req.query['hub.verify_token']; const challenge = req.query['hub.challenge']; if (mode === 'subscribe' && token === WEBHOOK_VERIFY_TOKEN) { // 校验通过时必须直接原样返回challenge值,不要做任何包装 res.status(200).send(challenge); } else { res.sendStatus(403); } });
额外注意事项
- 本地调试时可以用内网穿透工具将本地3978端口映射为公网HTTPS地址,再把该地址填入Meta后台
- 校验通过后需要补充POST路由处理WhatsApp推送的消息事件,否则后续无法收到用户发送的消息
- 不要在校验接口里加多余的返回内容,比如自定义提示语、JSON包装结构,必须直接返回Meta发来的challenge原始值
内容的提问来源于stack exchange,提问作者Hamza Khaled
相关产品推荐
相关产品推荐

