Messenger 开放平台专用 Meta Webhooks |
Meta Webhooks 可帮助您接收 Meta 社交关系图谱中特定对象变更的实时 HTTP 通知。例如,当用户向您的 Facebook 公共主页或 Instagram 专业账户发送消息时,我们可以向您发送通知。Webhooks 通知可帮助您追踪传入消息和消息状态更新。为追踪这些变更而查询 Messenger 开放平台端点时,该通知还可帮助您避免受到流量限制。
为成功集成 Messenger 或 Instagram 对话的专用 Webhooks,您需要执行以下操作:
在开始前,假设您已完成以下事项:
您的服务器必须能够处理 2 类 HTTPS 请求:验证请求和事件通知。由于这两类请求都使用 HTTP,所以必须为您的服务器正确配置和安装有效的 TLS 或 SSL 证书。不支持自签名证书。
以下部分将介绍各类请求的内容,以及如何响应这些请求。
此处显示的代码示例来源于 GitHub 中的应用示例 。请浏览 GitHub,查看完整示例及进一步了解如何设置 Webhooks 服务器。
如要创建端点以用于接收 Messenger 开放平台发送的 Webhooks 通知,app.js
文件可能如下所示:
// Create the endpoint for your webhook app.post("/webhook", (req, res) => { let body = req.body; console.log(`\u{1F7EA} Received webhook:`); console.dir(body, { depth: null }); ...
此代码将创建 /webhook
端点,该端点用于接受 POST
请求,检查此请求是否为 Webhooks 通知。
200 OK
响应端点必须返回 200 OK
响应,告知 Messenger 开放平台已收到事件,无需再次发送。通常需要在通知处理完毕后发送这一响应。
端点响应所有通知时均应遵循以下规则:
200 OK HTTPS
响应以下代码将位于 app.post
文件的 app.js
中,可能如下所示:
... // Send a 200 OK response if this is a page webhook if (body.object === "page") { // Returns a '200 OK' response to all requests res.status(200).send("EVENT_RECEIVED"); ... // Determine which webhooks were triggered and get sender PSIDs and locale, message content and more. ... } else { // Return a '404 Not Found' if event is not from a page subscription res.sendStatus(404); } });
每当您在应用面板中配置 Webhooks 产品时,我们都会向您的端点网址发送 GET
请求。验证请求包含以下查询字符串参数,并会将其附加到端点网址的末尾。验证请求如下所示:
GET https://www.your-clever-domain-name.com/webhooks? hub.mode=subscribe& hub.verify_token=mytoken& hub.challenge=1158201444
每当收到验证请求时,您的端点都必须:
hub.verify_token
值与您在应用面板中配置 Webhooks 产品时,在验证口令字段中设置的字符串一致(您尚未设置此口令字符串)。hub.challenge
值做出响应。您的 app.js
文件可能如以下所示:
// Add support for GET requests to our webhook app.get("/messaging-webhook", (req, res) => { // Parse the query params let mode = req.query["hub.mode"]; let token = req.query["hub.verify_token"]; let challenge = req.query["hub.challenge"]; // Check if a token and mode is in the query string of the request if (mode && token) { // Check the mode and token sent is correct if (mode === "subscribe" && token === config.verifyToken) { // Respond with the challenge token from the request console.log("WEBHOOK_VERIFIED"); res.status(200).send(challenge); } else { // Respond with '403 Forbidden' if verify tokens do not match res.sendStatus(403); } } });
参数 | 示例值 | 描述 |
---|---|---|
|
| 始终将此值设置为 |
|
| 您必须传回给我们的 |
|
| 从您应用的应用面板中的验证口令字段获取的字符串。您将在完成 Webhooks 配置设置步骤时设置此字符串。 |
注意:PHP 会将参数名称中的句点 (.) 转换为下划线 (_) 。
如果您在应用面板中配置 Webhooks 产品(并因此触发了验证请求),则面板会显示您的端点是否正确验证了请求。如果您使用图谱 API 的 /app/subscriptions
端点配置 Webhooks 产品,则该 API 会在响应中提示配置成功与否。
配置 Webhooks 产品时,您将订阅某个 object
类型的特定 fields
(例如,page
对象的 messages
字段)。每当其中某个字段有所更改,我们都会向您的端点发送一个 POST
请求,其中包括描述更改的 JSON 负载。
例如,如果您已订阅 page
对象的 message_reactions
字段,并且某客户已对应用发送的消息留下心情,我们会向您发送如下 POST
请求:
{
"object":"page",
"entry":[
{
"id":"<PAGE_ID>",
"time":1458692752478,
"messaging":[
{
"sender":{
"id":"<PSID>"
},
"recipient":{
"id":"<PAGE_ID>"
},
...
}
]
}
]
}
负载会包含描述更改的对象。配置 Webhooks 产品时,您可以指明负载应该仅包含已更改字段的名称,还是也应包含新值。
我们使用 JSON 格式化所有负载,因此您可以使用常见的 JSON 解析方法或解析包来解析负载。
我们不会存储发送给您的任何 Webhooks 事件通知数据,所以请务必获取并存储您想保留的任何负载内容。
我们使用 SHA256 签名来签署所有事件通知负载,并在请求的 X-Hub-Signature-256 标头中添加签名,接着在前面加上“sha256=”。验证负载并非强制要求,但您应该执行此操作,并且我们强烈建议您这样做。
如要验证负载,请执行以下操作:
X-Hub-Signature-256
标头中的签名(sha256=
之后的所有内容)进行对比。如果签名一致,则表示负载真实有效。请注意,我们会使用负载的转义 Unicode 版本生成签名,并以小写十六进制数字表示。如果您仅根据已解码字节计算,则会产生不同的签名。例如,字符串 äöå
应转义为 \u00e4\u00f6\u00e5
。
app.js
文件可能如以下所示:
// Import dependencies and set up http server const express = require("express"), bodyParser = require("body-parser"), { urlencoded, json } = require("body-parser"), app = express().use(bodyParser.json()); ... // Verify that the callback came from Facebook. function verifyRequestSignature(req, res, buf) { var signature = req.headers["x-hub-signature-256"]; if (!signature) { console.warn(`Couldn't find "x-hub-signature-256" in headers.`); } else { var elements = signature.split("="); var signatureHash = elements[1]; var expectedHash = crypto .createHmac("sha256", config.appSecret) .update(buf) .digest("hex"); if (signatureHash != expectedHash) { throw new Error("Couldn't validate the request signature."); } } }
如果向服务器发送的通知失败,我们将立即进行多次尝试。在这类情况下,您的服务器应处理去重操作。如果通知在 15 分钟后仍无法送达,系统会向您的开发者账户发送相关提醒。
如果通知在 1 小时后仍无法送达,您将收到 Webhooks 已禁用提醒,并且系统将取消您的应用对此公共主页或 Instagram 专业账户的 Webhooks 的订阅。在修复这些问题后,您需要重新订阅 Webhooks。
要测试 Webhooks 验证,请使用您的验证口令运行以下 cURL 请求:
curl -X GET "localhost:1337/webhook?hub.verify_token=YOUR-VERIFY-TOKEN&hub.challenge=CHALLENGE_ACCEPTED&hub.mode=subscribe"
如果 Webhooks 验证按预期运行,您应该会看到以下结果:
WEBHOOK_VERIFIED
记录到节点进程运行所在的命令行中。CHALLENGE_ACCEPTED
记录到发送 cURL 请求的命令行中。要测试 Webhooks,请发送以下 cURL 请求:
curl -H "Content-Type: application/json" -X POST "localhost:1337/webhook" -d '{"object": "page", "entry": [{"messaging": [{"message": "TEST_MESSAGE"}]}]}'
如果 Webhooks 按预期运行,您应该会看到以下结果:
TEST_MESSAGE
记录到节点进程运行所在的命令行中。EVENT RECEIVED
记录到发送 cURL 请求的命令行中。在您的 Webhooks 服务器端点或示例应用准备就绪后,请前往应用的应用面板 订阅 Meta Webhooks。
在本例中,我们将使用面板配置 Webhooks,并订阅 messages
字段。每当客户向您的应用发送消息时,系统就会向您的 Webhooks 端点发送通知。
在回调网址字段中输入端点的网址,并在验证口令字段中添加验证口令。我们会在所有验证请求中加入此字符串。如果您使用其中一个示例应用,则此字符串应该与您在应用的 TOKEN
配置变量中使用的字符串相同。
最后一步是订阅各个字段。订阅 messages
字段并发送测试事件通知。
如果您的端点设置正确,则其应验证负载,并在验证成功后执行您为其设置的任何代码。如果您在使用我们的示例应用,请在网页浏览器中加载应用网址。页面应该会显示负载内容。
您可使用应用面板随时更改 Webhooks 订阅,验证口令或 API 版本。
注意:建议您使用最新版 API 来接收每个 Webhooks 的所有可用信息。
您也可以使用/app/subscriptions
端点 以编程方式执行此操作。
Webhook 事件 | 说明 |
---|---|
| 订阅消息接收事件 |
| 订阅帐户绑定事件 |
| 订阅结账更新事件 |
| 订阅消息送达事件 |
| 订阅消息回传事件 |
| 订阅小游戏事件 |
| 订阅移交协议事件 |
| 订阅插件选择加入事件 |
| 订阅支付事件 |
| 订阅政策执行事件 |
| 订阅回传接收事件 |
| 订阅支付预结账事件 |
| 订阅消息读取事件 |
| 订阅推荐来源事件 |
|
您需要关联 Webhooks 应用与您的公共主页,并为您的公共主页订阅想要接收的 Webhooks 通知。
您可以在Meta Business Suite > 所有工具 > 业务应用 中关联应用与公共主页
注意:您需要为企业的所有消息应用订阅消息 Webhooks。
您需要为您的公共主页订阅想要接收的 Webhooks 通知。
MODERATE
任务的用户请求公共主页访问口令
若要订阅 Webhooks 字段,请使用公共主页的访问口令向公共主页的 subscribed_apps 连线发送 POST
请求。
curl -i -X POST "https://graph.facebook.com/PAGE-ID/subscribed_apps ?subscribed_fields=messages &access_token=PAGE-ACCESS-TOKEN"
{ "success": "true" }
要查看您的公共主页安装了哪款应用,请改为发送 GET
请求:
curl -i -X GET "https://graph.facebook.com/PAGE-ID/subscribed_apps &access_token=PAGE-ACCESS-TOKEN"
{ "data": [ { "category": "Business", "link": "https://my-clever-domain-name.com/app", "name": "My Sample App", "id": "APP-ID" "subscribed_fields": [ "messages" ] } ] }
如果您的公共主页未安装任何应用,API 将返回空数据集。
您也可以使用图谱 API 探索工具 发送请求,为您的公共主页订阅某个 Webhooks 字段。
pages_manage_metadata
权限。此操作会将您的应用口令与授予 pages_manage_metadata
权限的用户访问口令互换。GET
下拉菜单,然后选择 POST
,即可更改操作方式。me?fields=id,name
查询替换为公共主页的编号,在此编号之后输入 /subscribed_apps
,然后提交查询。 如要接收拥有应用身份的用户(如应用管理员、开发者和测试者)发出的通知,您的应用仅需要标准访问权限。如要接收客户(即没有应用身份的用户)发出的通知,您的应用需要高级访问权限。
详细了解标准访问级别和高级访问级别 、使用各级别访问权限可以访问的数据,以及实现要求。