MessengerプラットフォームのMeta Webhooks

Meta Webhooksを使うと、Metaソーシャルグラフの特定のオブジェクトに加えられた変更に関するHTTP通知をリアルタイムで受け取ることができます。例えば、FacebookページやInstagramプロアカウントにメッセージが届いたときに通知を受け取ることができます。Webhooksの通知機能を使うと、受信メッセージやメッセージステータスの最新情報をトラッキングすることができます。また、Webhooksの通知機能を使うと、変更をトラッキングするためにMessengerプラットフォームのエンドポイントをクエリした場合に発生するレート制限を回避することができます。

MessengerやInstagramの会話にWebhooksを実装するには、次のことを行ってください。

  1. サーバーにエンドポイントを作成し、Webhooks通知のJSONオブジェクトを受け取り、処理できるようにする
  2. アプリアプリダッシュボードでMeta Webhooks製品を構成する
  3. 受け取りたいMeta Webhooks通知をサブスクリプション登録する
  4. 自分のビジネスまたは自分のInstagramプロアカウントにリンクされているFacebookページにメッセージアプリをインストールする

開始する前に

開始するための前提条件は次のとおりです。

Node.JSサーバーを構成する

サーバーで、確認リクエストイベントの通知の2つのタイプのHTTPSリクエストを処理できるようにしなければなりません。両方のリクエストがHTTPSを使用するので、有効なTLSまたはSSL証明書が適切に構成されてサーバーにインストールされている必要があります。自己署名の証明書はサポートされていません。

以下のセクションでは、各タイプのリクエストに含まれる内容と、それらのリクエストへの応答の仕方について説明します。

ここに示すコードサンプルは、MetaのGitHubにあるサンプルアプリから取られたものです。GitHubでサンプルの全容と、Webhooksサーバーの詳しい設定方法をご確認ください。

エンドポイントの作成

エンドポイントを作成してWebhooks通知をMessengerプラットフォームから受け取るようにするには、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製品を構成すると、必ずエンドポイントURLにGETリクエストが送られます。確認リクエストには次のクエリ文字列パラメーターがエンドポイントURLの末尾に付け加えられる形で含まれます。このようになります。

確認リクエストの例

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

Facebookに返信する必要のある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イベント通知データをFacebook側が保存することはありません。そのため、保持しておきたいペイロードコンテンツがあれば、忘れずにキャプチャして保存してください。

ペイロードの確認

すべてのイベント通知ペイロードはSHA256で署名されます。この署名は、リクエストの'X-Hub-Signature-256'ヘッダーにあり、先頭に'sha256='が付きます。ペイロードの確認は必須ではありませんが、強く推奨されています。

ペイロードを確認する手順は次のとおりです。

  1. ペイロードとアプリのApp Secretを使って、SHA256署名を生成します。
  2. 自分の署名とX-Hub-Signature-256ヘッダーにある署名(sha256=の後に続くものすべて)を比較します。署名が一致していれば、そのペイロードは本物です。

Facebookは、ペイロードのエスケープしたユニコードバージョン(小文字の16進数)を使って署名を生成します。デコードされたバイト数で計算すると、異なる署名が算出されます。例えば、文字列äöåをエスケープすると\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 Disabledというアラートを受け取ります。アプリでは、ページまたは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が、nodeプロセスを実行しているコマンドラインに記録される。
  • 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が、nodeプロセスを実行しているコマンドラインに記録される。
  • 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. [コールバックURL]フィールドにエンドポイントのURLを入力し、[トークンの認証]フィールドに認証トークンを入力します。この文字列はすべての認証リクエストに含まれます。いずれかのサンプルアプリを使用している場合は、アプリのTOKEN構成変数に使った文字列と同じ文字列にしてください。

  3. 通知を受け取りたいフィールドをサブスクリプション登録し、[保存]をクリックします。
  4. 最後のステップで、フィールドを個別にサブスクリプション登録します。messagesフィールドをサブスクリプション登録し、テスト用にイベント通知を送信します。

    エンドポイントが正しく設定されると、ペイロードが確認され、確認成功時に実行するよう設定されたコードが実行されます。サンプルアプリを使っている場合は、アプリのURLをウェブブラウザーで読み込んでください。ペイロードのコンテンツが表示されます。

アプリダッシュボードを使って、いつでもWebhooksのサブスクリプションを変更したり、トークンやAPIバージョンを確認したりできます。

注: 各Webhookで入手できるすべての情報を受け取るため、最新のAPIバージョンを使うことをおすすめします。

この操作はプログラムを使って行うこともできます。その場合、/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フィールドをサブスクリプション登録するには、当該ページのアクセストークンを使って、ページの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エクスプローラ

グラフAPIエクスプローラを使って、ページでWebhooksフィールドをサブスクリプション登録するリクエストを送信することもできます。

  1. [アプリ]ドロップダウンメニューでアプリを選択します。
  2. [トークンを取得]ドロップダウンをクリックし、[ユーザーアクセストークンを取得]を選んだ後、pages_manage_metadataアクセス許可を選びます。これにより該当アプリのトークンが、pages_manage_metadataアクセス許可が付与されたユーザーアクセストークンに交換されます。
  3. もう一度[トークンを取得]をクリックして、自分のページを選びます。これにより、ユーザーアクセストークンがページアクセストークンに交換されます。
  4. GETドロップダウンメニューをクリックして動作方式を変更し、POSTを選びます。
  5. デフォルトのme?fields=id,nameクエリを、ページのIDの後に/subscribed_appsを付けたものに置き換えてから、クエリを送信します。

アクセスの要件

アプリの管理者、開発者、テスト担当者など、アプリに対して役割を付与されているユーザーから通知を受け取るためにアプリで必要なのは、スタンダードアクセスだけです。アプリに対して権限を持たない人や顧客からの通知を受け取るには、アプリにアドバンスアクセスが必要です。

スタンダードアクセスとアドバンスアクセス、それぞれがアクセスできるデータ、および実装のための要件について詳細をご確認ください。

次のステップ

  • テストメッセージを送信する – メッセージを送信するためにプラットフォームをどのように使用するかを詳しく説明しています。
  • サンプルアプリの紹介 – サンプルアプリのコードをダウンロードして、Messengerプラットフォームが提供している機能について詳しく学習します。
  • 参考情報