MessengerプラットフォームのMeta Webhooks |
Meta Webhooksを使うと、Metaソーシャルグラフの特定のオブジェクトに加えられた変更に関するHTTP通知をリアルタイムで受け取ることができます。例えば、FacebookページやInstagramプロアカウントにメッセージが届いたときに通知を受け取ることができます。Webhooksの通知機能を使うと、受信メッセージやメッセージステータスの最新情報をトラッキングすることができます。また、Webhooksの通知機能を使うと、変更をトラッキングするためにMessengerプラットフォームのエンドポイントをクエリした場合に発生するレート制限を回避することができます。
MessengerやInstagramの会話にWebhooksを実装するには、次のことを行ってください。
開始するための前提条件は次のとおりです。
サーバーで、確認リクエストとイベントの通知の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
応答を使う次のコードは、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); } } });
パラメーター | 値の例 | 説明 |
---|---|---|
|
| この値は常に |
|
| Facebookに返信する必要のある |
|
| アプリのアプリダッシュボードのトークンの認証フィールドから取得した文字列。この文字列は、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='が付きます。ペイロードの確認は必須ではありませんが、強く推奨されています。
ペイロードを確認する手順は次のとおりです。
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."); } } }
サーバーへの通知の送信が失敗した場合は、直ちに数回再試行されます。このような場合、サーバー側で重複排除の処理をする必要があります。15分経ってもまだ通知を配信できない場合は、アラートが開発者アカウントに届きます。
通知の配信に1時間失敗し続けると、Webhooks Disabledというアラートを受け取ります。アプリでは、ページまたはInstagramプロアカウントから、その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リクエストを送信したコマンドラインに記録される。Webhooksサーバーエンドポイントまたはサンプルアプリの用意ができたら、アプリのアプリダッシュボードに移動して、Meta Webhooksをサブスクリプション登録します。
この例では、ダッシュボードを使ってWebhookを構成し、messages
フィールドをサブスクリプション登録します。カスタマーがアプリにメッセージを送るたびに、Webhooksエンドポイントに通知が届きます。
[コールバックURL]フィールドにエンドポイントのURLを入力し、[トークンの認証]フィールドに認証トークンを入力します。この文字列はすべての認証リクエストに含まれます。いずれかのサンプルアプリを使用している場合は、アプリのTOKEN
構成変数に使った文字列と同じ文字列にしてください。
最後のステップで、フィールドを個別にサブスクリプション登録します。messages
フィールドをサブスクリプション登録し、テスト用にイベント通知を送信します。
エンドポイントが正しく設定されると、ペイロードが確認され、確認成功時に実行するよう設定されたコードが実行されます。サンプルアプリを使っている場合は、アプリのURLをウェブブラウザーで読み込んでください。ペイロードのコンテンツが表示されます。
アプリダッシュボードを使って、いつでもWebhooksのサブスクリプションを変更したり、トークンやAPIバージョンを確認したりできます。
注: 各Webhookで入手できるすべての情報を受け取るため、最新のAPIバージョンを使うことをおすすめします。
この操作はプログラムを使って行うこともできます。その場合、/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
クエリを、ページのIDの後に/subscribed_apps
を付けたものに置き換えてから、クエリを送信します。 アプリの管理者、開発者、テスト担当者など、アプリに対して役割を付与されているユーザーから通知を受け取るためにアプリで必要なのは、スタンダードアクセスだけです。アプリに対して権限を持たない人や顧客からの通知を受け取るには、アプリにアドバンスアクセスが必要です。
スタンダードアクセスとアドバンスアクセス、それぞれがアクセスできるデータ、および実装のための要件について詳細をご確認ください。