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イベント通知データは照会できないため、保持しておきたいWebhookペイロードコンテンツがあれば、忘れずにキャプチャして保存してください。
すべてのイベント通知ペイロードは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に含まれているWebhookのtimestampフィールドを使ってください。
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アプリダッシュボードに移動して、Meta Webhooksをサブスクリプション登録します。
この例では、ダッシュボードを使ってWebhookを設定し、messagesフィールドをサブスクリプション登録します。カスタマーがアプリにメッセージを送るたびに、Webhooksエンドポイントに通知が届きます。
TOKEN構成変数に使った文字列と同じ文字列にしてください。messagesフィールドをサブスクリプション登録し、テスト用にイベント通知を送信します。
アプリダッシュボードを使って、いつでも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を付けたものに置き換えてから、クエリを送信します。 アプリの管理者、開発者、テスト担当者など、アプリで役割を付与されているユーザーから通知を受け取るためにアプリで必要なのは、スタンダードアクセスだけです。顧客やアプリで役割を持たない人からの通知を受け取るには、アプリにアドバンスアクセスが必要です。
スタンダードアクセスとアドバンスアクセス、それぞれがアクセスできるデータ、および実装のための要件について詳細をご確認ください。