Messenger 開放平台的 Meta Webhooks

Meta Webhooks 可讓您接收 Meta 社交關係圖中特定物件變更的即時 HTTP 通知。例如,當用戶傳送訊息到您的 Facebook 粉絲專頁或 Instagram 專業帳號時,我們就會傳送通知給您。Webhooks 通知允許您追蹤傳入訊息和訊息狀態更新。Webhooks 通知也可讓您避免在查詢 Messenger 開放平台端點以追蹤變更時發生的速率限制

為了成功實作 Messenger 開放平台的 Webhooks 或 Instagram 對話,您需要:

  1. 在您的伺服器上建立端點,以接收和處理您的 Webhooks 通知(JSON 物件)
  2. 在應用程式主控板中設定 Meta Webhooks 產品
  3. 訂閱您想要接收的 Meta Webhooks 通知
  4. 在與您的商家或 Instagram 專業帳號連結的 Facebook 粉絲專頁安裝傳訊應用程式

準備工作

開始之前,我們假設您已經:

配置 Node.JS 伺服器

您的伺服器必須能夠處理兩種類型的 HTTPS 要求:驗證要求事件通知。由於這兩種要求皆使用 HTTPS,因此伺服器必須正確配置並安裝有效的 TLS 或 SSL 憑證。我們不支援自我簽署憑證。

以下各節說明這兩種要求類型的內容,以及回應方式。

這裡顯示的程式碼範例取自我們位於 GitHub 上的應用程式範例 。如需完整範例以及設定 Webhooks 伺服器的相關資訊,請前往 GitHub。

建立端點

若要建立端點來接收 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 要求,並檢查要求是否為 Webhook 通知。

傳回 200 OK 回應

此端點必須傳回 200 OK 回應,告知 Messenger 開放平台已收到事件,不需要重新傳送。通常您會在完成處理通知之後,才傳送此回應。

回應事件通知

您的端點應該回應所有通知:

  • 使用 200 OK HTTPS 回應
  • 在 5 秒以內

以下程式碼將會在 app.js 檔案的 app.post 中,可能如下所示:

...
  // 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);
    }
  }
});
參數範例值說明

hub.mode

subscribe

此值必須一律設為 subscribe

hub.challenge

1158201444

您必須傳回給我們的 int

hub.verify_token

mytoken

我們在您應用程式的應用程式主控板上,從驗證權杖欄位擷取的字串。您將會在完成 Webhooks 配置設定步驟後設定此字串。

附註:PHP 會將參數名稱中的句點(.)轉換成底線(_)

如果您正在應用程式主控板中配置 Webhooks 產品(並因此觸發驗證要求),主控板會指出您的端點是否已正確驗證要求。如果您是使用圖形 API 的 /app/subscriptions 端點來配置 Webhooks 產品,API 會回應成功或失敗。

事件通知

當您設定 Webhooks 產品時,會訂閱 object 類型上的特定 fields(例如,page 物件上的 messages 欄位)。每次其中一個欄位發生變更時,我們會傳送包含描述變更之 JSON 承載的 POST 要求至您的端點。

例如,如果您訂閱了 page 物件的 message_reactions 欄位,而顧客對應用程式傳送的訊息傳達心情,我們會傳送類似以下 POST 要求給您:

{
  "object":"page",
  "entry":[
    {
      "id":"<PAGE_ID>",
      "time":1458692752478,
      "messaging":[
        {
          "sender":{
            "id":"<PSID>"
          },
          "recipient":{
            "id":"<PAGE_ID>"
          },

          ...
        }
      ]
    }
  ]
}

承載內容

承載將包含描述變更的物件。當您設定 Webhooks 產品時,可以指示承載是否只包含已變更欄位的名稱,或者承載是否還應包含新值。

所有承載皆為 JSON 格式,因此您可用一般的 JSON 剖析方法或套件來剖析承載。

我們不會儲存任何傳送給您的 Webhook 事件通知資料,因此請您務必擷取或儲存您想保留的任何承載內容。

驗證承載

我們會在所有事件通知承載上簽署 SHA256 簽章,並將簽章包含在要求的「X-Hub-Signature-256」標頭中,前面加上「sha256=」。您不一定要驗證承載,但您應該且我們強烈建議您這麼做。

驗證承載:

  1. 使用承載和應用程式的應用程式密鑰產生 SHA256 簽章。
  2. 比較您的簽章與 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.");
    }
  }
}

重試傳遞 Webhooks

如果傳送到伺服器的通知失敗,我們將立即再嘗試傳送幾次。您的伺服器應該要能夠處理這些情況下的重複資料刪除作業。如果 15 分鐘後,我們仍無法傳遞通知,則會傳送警告至您的開發人員帳號。

如果通知傳遞持續失敗達 1 小時,您會收到 Webhooks 已停用的警告,而且您的應用程式會取消訂閱粉絲專頁或 Instagram 專業帳號的 Webhooks。解決問題後,您將需要重新訂閱 Webhooks。

測試 Webhooks

要測試 Webhook 驗證,請使用驗證權杖執行下列 cURL 要求:

curl -X GET "localhost:1337/webhook?hub.verify_token=YOUR-VERIFY-TOKEN&hub.challenge=CHALLENGE_ACCEPTED&hub.mode=subscribe"

如果 Webhook 驗證如預期運作,您應該會看到以下情況:

  • WEBHOOK_VERIFIED 記錄在執行節點程序的命令列。
  • CHALLENGE_ACCEPTED 記錄在傳送 cURL 要求的命令列。

要測試 Webhook,請傳送下列 cURL 要求:

curl -H "Content-Type: application/json" -X POST "localhost:1337/webhook" -d '{"object": "page", "entry": [{"messaging": [{"message": "TEST_MESSAGE"}]}]}'

如果 Webhook 如預期運作,您應該會看到以下情況:

  • TEST_MESSAGE 記錄在執行節點程序的命令列。
  • EVENT RECEIVED 記錄在傳送 cURL 要求的命令列。

訂閱 Meta Webhooks

準備好您的 Webhooks 伺服器端點或應用程式範例後,進入應用程式的應用程式主控板,訂閱 Meta Webhooks。

在此範例中,我們將使用主控板來配置 Webhook 及訂閱 messages 欄位。只要有顧客傳送訊息給您的應用程式,系統就會傳送通知到您的 Webhooks 端點。

  1. 在應用程式主控板中,前往產品 > Messenger > 設定
    • 部分 Messenger 開放平台的 Webhooks 不適用於 Instagram 傳訊。如果您只要實作 Instagram 的 Webhooks 且知道 Instagram 訊息傳送可以使用的 Webhooks,則可以在此處訂閱 Webhooks。若只要檢視並訂閱 Instagram 傳訊的 Webhooks,您可以前往 Instagram 設定
  2. 回呼網址欄位中輸入端點的網址,並將您的驗證權杖加入驗證權杖欄位。我們會在所有驗證要求中包含此字串。如果您使用我們的其中一個應用程式範例,這應該是用於應用程式 TOKEN 配置變數的相同字串。

  3. 訂閱您想要接收通知的相關欄位,並點擊儲存
  4. 最後一個步驟是訂閱個別欄位。訂閱 messages 欄位,並傳送測試事件通知。

    如果端點設定正確,應該會驗證承載,並執行您設定其於驗證成功時執行的任何程式碼。如果您使用我們的應用程式範例,請在網頁瀏覽器中載入應用程式網址。瀏覽器應該會顯示承載的內容。

您可以隨時使用應用程式主控板來變更 Webhooks 訂閱、驗證權杖或 API 版本。

附註:建議使用最新的 API 版本來接收每個 Webhook 的所有可用資訊。

您也可以使用 /app/subscriptions 端點,以程式設計的方式執行此操作。

可用的 Messenger 開放平台欄位

Webhook 事件說明

messages

訂閱已收到訊息事件

messaging_account_linking

訂閱帳號連結事件

messaging_checkout_updates(試用版)

訂閱結帳更新事件

message_deliveries

訂閱已傳遞訊息事件

message_echoes

訂閱已回送訊息事件

messaging_game_plays

訂閱即時遊戲事件

messaging_handovers(試用版)

訂閱交接通訊協定事件

messaging_optins

訂閱外掛程式選擇加入事件

messaging_payments(試用版)

訂閱付款事件

messaging_policy_enforcement

訂閱政策執行事件

messaging_postbacks

訂閱已收到回傳事件

messaging_pre_checkouts(試用版)

訂閱付款結帳前事件

message_reads

訂閱已讀取訊息事件

messaging_referrals

訂閱轉介事件

standby(試用版)

訂閱交接通訊協定待命管道事件

連結應用程式

您需要將 Webhooks 應用程式連結到粉絲專頁,並為粉絲專頁訂閱您想要接收的 Webhooks 通知。

新增應用程式

您可以在 Meta Business Suite > 所有工具 > 商業應用程式 中,將應用程式連結至粉絲專頁

附註:您需要為商家的所有訊息應用程式訂閱訊息 Webhooks。

訂閱粉絲專頁

您需要為粉絲專頁訂閱您想要接收的 Webhooks 通知。

必備條件

若要訂閱 Webhooks 欄位,請使用粉絲專頁的存取權杖,傳送 POST 要求至粉絲專頁的 subscribed_apps 關係連線。

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 測試工具

您也可以使用圖形 API 測試工具 來傳送要求,為粉絲專頁訂閱 Webhooks 欄位。

  1. 應用程式下拉式功能表中選擇您的應用程式。
  2. 點擊取得權杖下拉式功能表,並選擇取得用戶存取權杖,然後選擇 pages_manage_metadata 權限。這樣會將應用程式權杖交換為已授予 pages_manage_metadata 權限的用戶存取權杖。
  3. 再次點擊取得權杖,然後選擇您的粉絲專頁。這樣會將用戶存取權杖交換為粉絲專頁存取權杖。
  4. 點擊 GET 下拉式功能表,然後選擇 POST 來變更作業方法。
  5. 將預設 me?fields=id,name 查詢替換為粉絲專頁的編號,並在後面加上 /subscribed_apps,然後提交查詢。

存取必備條件

若要接收具備應用程式角色之用戶(例如應用程式管理員、開發人員或測試員)的通知,應用程式只需要標準存取權限。若要接收顧客(不具應用程式角色之用戶)的通知,應用程式將需要進階存取權限

進一步瞭解標準和進階存取權限 、這兩種存取權限分別可存取的資料,以及實作的必備條件。

後續步驟

  • 傳送測試訊息 - 瞭解如何使用平台傳送訊息。
  • 範例應用程式導覽 - 下載範例應用程式的程式碼,協助您進一步瞭解 Messenger 開放平台提供的功能。
  • 另請參閱