验证 WhatsApp Webhook 端点
在发送任何事件前,Meta 会向您的端点发送一个包含 hub.mode、hub.verify_token 和 hub.challenge 的 GET 请求。您的端点必须比较令牌,并将 challenge 作为原始正文返回。其他任何响应都会导致发送无法开始。
Meta 具体会发送什么?
Meta 会向您的 URL 发送一个带有 3 个查询参数的 GET 请求。hub.mode 会设为 subscribe。hub.verify_token 是您设置目标地址时配置的令牌。hub.challenge 是 Meta 为本次尝试生成的值。
您的端点应将 hub.verify_token 与您选择的令牌进行比较。如果匹配,则以 200 响应,并将 hub.challenge 作为完整的响应正文返回。不能包装在 JSON 中,不能在两侧加引号,也不能带有某些框架默认添加的尾随换行符。
如果令牌不匹配,请返回 403。这就是完整协议,设计上非常简单。
答错为何会静默失败?
因为验证失败不是您系统中的错误,而是 Meta 系统中缺少该目标地址。
如果没有正确原样返回 challenge,Meta 就不会开始向该目标地址发送内容。您的服务器会对验证请求返回 200,日志也会显示请求已到达,但任何控制台都不会报告问题。唯一症状是消息始终收不到,因此多数人会将其诊断为 Coexistence 问题,而不是握手问题。
所以,在发出请求前进行验证很有价值。我们会在发出 Graph 请求前检查 URL 是否为 HTTPS,以及是否提供了验证令牌,让格式错误的目标地址立即失败,而不是看起来像已连接。
还有什么会阻止验证?
有 3 件事与代码无关。
端点前面有身份验证。网关、基本身份验证层或 IP 允许列表都会拒绝 Meta 的请求,而 Meta 没有可提供的凭据。验证路由必须无需凭据即可访问。
重定向。Meta 会调用您提供的 URL,301 重定向到规范主机的方式无法完成握手。请提供最终 URL。
还有会序列化响应的框架。如果处理程序返回的字符串被框架统一包装成 JSON,正文就会在 challenge 两侧加上引号,因此无法匹配。
常见错误
- 返回 JSON。正文必须是原始 challenge 值,周围不能有任何内容。
- 将端点置于身份验证之后。Meta 没有凭据,因此请求会被拒绝。
- 向 Meta 提供会重定向的 URL。请使用最终 URL。
EasyCoexistence 会在调用 Meta 前验证目标地址是否为 HTTPS 且提供了验证令牌,并在连接时间线记录握手失败,而不是丢弃目标地址。
常见问题
应使用什么令牌?
使用您选择的任何字符串。这样,您的端点就能将 Meta 的请求与其他得知该 URL 的人的请求区分开。
验证多久进行一次?
设置时进行一次,之后每次设置目标地址时也会进行。正常工作的端点不会在每个事件到达时重新验证。
我可以自行测试吗?
可以。使用 3 个参数调用您自己的端点,并检查正文是否完全返回 challenge 值。
如果验证时我的服务器宕机了怎么办?
握手会失败,目标地址不会启用。再次保存即可重新运行验证。
继续阅读
准备开始了吗?
几分钟即可设置 WhatsApp Coexistence,而不是几个月。应用会继续在手机上运行。
开始免费试用验证时间