WhatsApp Webhook无法接收消息,Postman测试正常,Meta设置更新后仅短暂可用
WhatsApp Webhook 接收异常排查方案
1. Heroku Dyno 休眠导致请求超时
Heroku免费版Dyno会在30分钟无请求后进入休眠状态,唤醒需要几秒时间。而Meta的Webhook请求有严格的超时限制(通常15秒内),超时会直接丢弃请求,这就导致你只能用Postman主动唤醒Dyno测试成功,但收不到WhatsApp的消息。更新Meta设置后短暂恢复,是因为验证请求唤醒了Dyno,但很快又会休眠。
- 解决:
- 升级到Heroku付费Dyno,保持实例持续在线;
- 用定时请求工具每隔25分钟给你的Webhook URL发一次GET请求,避免Dyno休眠。
2. 签名验证逻辑错误
Meta会对每个Webhook请求生成HMAC签名,如果你的代码验证逻辑出错,会直接拒绝WhatsApp的请求,但Postman测试通常没做签名验证所以能通过。更新Meta设置后短暂恢复,可能是重置签名密钥后代码里的密钥临时同步,但后续缓存或配置问题导致验证失败。
- 解决:
- 确认代码中使用的
APP_SECRET和Meta开发者平台的应用密钥完全一致,无多余空格或字符; - 检查签名验证代码,确保用原始请求体计算签名(不要用解析后的JSON对象),示例代码:
const crypto = require('crypto'); const verifySignature = (req, res, next) => { const signatureHeader = req.headers['x-hub-signature-256']; if (!signatureHeader) return res.sendStatus(403); const hmac = crypto.createHmac('sha256', process.env.APP_SECRET); const calculatedSignature = `sha256=${hmac.update(req.rawBody).digest('hex')}`; if (!crypto.timingSafeEqual(Buffer.from(signatureHeader), Buffer.from(calculatedSignature))) { return res.sendStatus(403); } next(); }; // 注意:先配置rawBody再用json中间件 app.use(express.json({ verify: (req, res, buf) => req.rawBody = buf })); app.use(verifySignature); - 用Heroku环境变量管理
APP_SECRET,避免硬编码,确保配置同步。
- 确认代码中使用的
3. Webhook订阅字段或权限失效
更新Meta设置后短暂恢复,可能是订阅字段被临时重置,但后续因权限变更、URL同步问题导致订阅失效。
- 解决:
- 进入Meta开发者平台,检查Webhook的订阅字段,确保
messages等所需事件处于订阅状态; - 重新触发Webhook验证流程,确认GET请求能正确返回
hub.challenge参数; - 检查应用的WhatsApp Business API权限,确保权限未被撤销或过期。
- 进入Meta开发者平台,检查Webhook的订阅字段,确保
4. 请求体解析配置问题
Express如果没正确配置JSON解析,可能无法处理WhatsApp发送的复杂JSON请求体,导致处理失败,但Postman测试的请求格式简单能成功。
- 解决:确保在路由前添加
express.json()中间件,并且保留原始请求体用于签名验证(如上面示例代码所示)。
5. 查看Heroku日志定位具体错误
直接查看Heroku应用的实时日志,能看到WhatsApp请求到达时的错误信息(比如403、500错误),快速定位问题。
- 操作:在终端执行
heroku logs --tail,然后发送一条WhatsApp消息,观察日志输出。
内容的提问来源于stack exchange,提问作者Steve Dan
相关产品推荐
相关产品推荐

