app.js file may look like the following:// 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 endpoint that accepts POST requests and checks that the request is a webhook notification.200 OK response200 OK response, which tells the Messenger Platform the event has been received and does not need to be resent. Normally, you will not send this response until you have completed processing the notification.200 OK HTTPS responseapp.post in your app.js file and may look like the following:...
// 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);
}
});
GET request to your endpoint URL. Verification requests include the following query string parameters, appended to the end of your endpoint URL. They will look something like this:GET https://www.your-clever-domain-name.com/webhooks? hub.mode=subscribe& hub.verify_token=mytoken& hub.challenge=1158201444
hub.verify_token value matches the string you set in the Verify Token field when you configure the Webhooks product in your App Dashboard (you haven’t set up this token string yet).hub.challenge value.app.js file may look like the following:// Add support for GET requests to your webhook
app.get("/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);
}
}
});
| Parameter | Sample Value | Description |
|---|---|---|
hub.mode | subscribe | This value will always be set to subscribe. |
hub.challenge | 1158201444 | An int you must pass back to us. |
hub.verify_token | mytoken | A string that we grab from the Verify Token field in your app’s App Dashboard. You will set this string when you complete the Webhooks configuration settings steps. |
/app/subscriptions endpoint to configure the Webhooks product, the API will respond with success or failure.fields on an object type (for example, the messages field on the page object). Whenever there’s a change to one of these fields, we will send your endpoint a POST request with a JSON payload describing the change.page object’s message_reactions field and a customer reacted to a message your app sent, we would send you a POST request that would look something like this:{ "object":"page", "entry":[ { "id":"<PAGE_ID>", "time":1458692752478, "messaging":[ { "sender":{ "id":"<PSID>" }, "recipient":{ "id":"<PAGE_ID>" }, ... } ] } ] }
entry array contains one or more event objects, each with a messaging array of individual events:{ "object": "page", "entry": [ { "id": "<PAGE_ID>", "time": 1458692752478, "messaging": [ { "sender": { "id": "<PSID>" }, "recipient": { "id": "<PAGE_ID>" }, "timestamp": 1458692752478, ... } ] } ] }
messaging array includes sender, recipient, and timestamp fields. The remaining fields depend on the event type.message object with mid (message ID) and text fields:{ "sender": { "id": "<PSID>" }, "recipient": { "id": "<PAGE_ID>" }, "timestamp": 1458692752478, "message": { "mid": "mid.1457764197618:41d102a3e1ae206a38", "text": "hello, world!" } }
attachments array instead of text:{ "sender": { "id": "<PSID>" }, "recipient": { "id": "<PAGE_ID>" }, "timestamp": 1518479195308, "message": { "mid": "mid.$cAAJdkrCd2ORnva8ErFhjGm0X_Q_c", "attachments": [ { "type": "image", "payload": { "url": "<IMAGE_URL>" } } ] } }
image, audio, video, file, reel, ig_reel.{ "sender": { "id": "<PSID>" }, "recipient": { "id": "<PAGE_ID>" }, "timestamp": 1458692752478, "postback": { "title": "<BUTTON_TITLE>", "payload": "<DEVELOPER_DEFINED_PAYLOAD>" } }
X-Hub-Signature-256 header (everything after sha256=). If the signatures match, the payload is genuine.äöå should be escaped to \u00e4\u00f6\u00e5.app.js file may look like the following:// 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.");
}
}
}
curl -X GET "localhost:1337/webhook?hub.verify_token=YOUR-VERIFY-TOKEN&hub.challenge=CHALLENGE_ACCEPTED&hub.mode=subscribe"
WEBHOOK_VERIFIED logged to the command line where your node process is running.CHALLENGE_ACCEPTED logged to the command line where you sent the cURL request.curl -H "Content-Type: application/json" -X POST "localhost:1337/webhook" -d '{"object": "page", "entry": [{"messaging": [{"message": "TEST_MESSAGE"}]}]}'
TEST_MESSAGE logged to the command line where your node process is running.EVENT RECEIVED logged to the command line where you sent the cURL request.messages field. Any time a customer sends your app a message, a notification will be sent to your webhooks endpoint.TOKEN config variable.messages field and send a test Event Notification.
/app/subscriptions endpoint.| Messaging Webhooks Field | Description |
|---|---|
message_deliveries | A notification is sent when a message that was sent by your business has been delivered to a customer. Only available for Messenger conversations. |
message_echoes | A notification is sent when your business has sent a message. This separate webhook field is available only for Messenger conversations. For Instagram Messaging conversations, the message echo notifications are included with the message webhook field subscription. |
message_edits | A notification is sent when a customer edits a previously-sent message. Only availalbe for Messenger conversations. |
message_reactions | A notification is sent when a customer reacts to a message sent by your business. |
message_reads | A notification is sent when a customer reads a message sent by your business, for Messenger conversations. See messaging_seen for Instagram Messaging conversations. |
messages | A notification is sent when your business has received a message from a customer from any conversation entry point. For Instagram Messaging, this subscription will also include notifications when your Instagram Professional account has sent a message since there is no separate message_echoes subscription field for Instagram Messaging. |
messaging_account_linking | A notification is sent when a customer links or unlinks their Messenger account from their account with your business. Only available for Messenger conversations. |
messaging_feedback | A notification is sent when a person has submitted feedback for your business. Only available for Messenger conversations. |
messaging_game_plays | A notification is sent when a person has played a round of an Instant Game. Only available for Messenger conversations. |
messaging_handovers | A notification is sent when a change has occurred during the Handover Protocol |
messaging_optins | A notification is sent when a customer has clicked a Messenger plugin, accepted a message request using customer matching, or has opted in to receive messages via the checkbox plugin. Only available for Messenger conversations. |
messaging_policy_enforcement | |
messaging_postbacks | |
messaging_referrals | A notification is sent when a customer resumes a conversation with the Page by clicking an ig.me or m.me link, or an ad. |
messaging_seen | A notification is sent when a customer reads a message sent by your business, for Instagram Messaging conversations. See messaging_reads for Messenger conversations. |
messenger_template_status_update | A notification is sent when a utility message template’s review status has change. |
response_feedback | |
send_cart | A notification is sent when your business has received a message from a customer, when the message contains cart/order information. Only available for Messenger conversations. |
standby | A notification is sent when a conversation is idle for an app during the Handover Protocol |
MODERATE task on the Page being queriedpages_messaging and pages_manage_metadata permissionsPOST request to the Page’s subscribed_apps edge using the Page’s acccess token.curl -i -X POST "https://graph.facebook.com/<PAGE_ID>/subscribed_apps?subscribed_fields=messages&access_token=<PAGE_ACCESS_TOKEN>"
{ "success": "true" }
GET request instead: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" ] } ] }
pages_manage_metadata permission. This will exchange your app token for a User access token with the pages_manage_metadata permission granted.GET dropdown menu and selecting POST.me?fields=id,name query with the Page’s id followed by /subscribed_apps, then submit the query.