Meta Webhooks for Messenger Platform

Meta Webhooks allows you to receive real-time HTTP notifications of changes to specific objects in the Meta social graph. For example, we could send you a notification when a person sends your Facebook Page or Instagram Professional account a message. Webhooks notifications allow you to track incoming messages and message status updates. Webhooks notifications also allow you to avoid rate limits that would occur if you were querying the Messenger Platform endpoints to track these changes.

To successfully implement Webhooks for Messenger or Instagram conversations, you will need to:

  1. Create an endpoint on your server to receive and process your Webhooks notifications, JSON objects
  2. Configure the Meta Webhooks product in your App Dashboard
  3. Subscribe to the Meta Webhooks notifications you want to receive
  4. Install your messaging app on the Facebook Page linked to your business or your Instagram Professional account

Before You Start

Before you start we assume you have:

Configure Your Node.JS Server

Your server must be able to process two types of HTTPS requests: Verification Requests and Event Notifications. Since both requests use HTTPs, your server must have a valid TLS or SSL certificate correctly configured and installed. Self-signed certificates are not supported.

The sections below explain what will be in each type of request and how to respond to them.

The code samples shown here are taken from our sample app located on GitHub . Visit GitHub to see the complete example and more information about setting up your webhooks server.

Create an Endpoint

To create an endpoint to receive webhooks notifications from the Messenger Platform, the app.js file may look like the follow:

// 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 });
    
...
   

This code creates a /webhook endpoint that accepts POST requests and checks that the request is a webhook notification.

Return a 200 OK response

The endpoint must return a 200 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.

Respond to Event Notifications

Your endpoint should respond to all notifications:

  • with a 200 OK HTTPS response
  • within 5 or less seconds

The following code will be in the app.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);
  }
}); 

Verification Requests

Anytime you configure the Webhooks product in your App Dashboard, we'll send a 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:

Sample Verification Request

GET https://www.your-clever-domain-name.com/webhooks?
  hub.mode=subscribe&
  hub.verify_token=mytoken&
  hub.challenge=1158201444

Validating Verification Requests

Whenever your endpoint receives a verification request, it must:

  • Verify that the 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).
  • Respond with the hub.challenge value.

Your app.js file may look like the following:

// 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);
    }
  }
});
ParameterSample ValueDescription

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 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.

Note: PHP converts periods (.) to underscores (_) in parameter names .

If you are in your App Dashboard and configuring your Webhooks product (and thus, triggering a Verification Request), the dashboard will indicate if your endpoint validated the request correctly. If you are using the Graph API's /app/subscriptions endpoint to configure the Webhooks product, the API will respond with success or failure.

Event Notifications

When you configure your Webhooks product, you will subscribe to specific 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.

For example, if you subscribed to the 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>"
          },

          ...
        }
      ]
    }
  ]
}

Payload Contents

Payloads will contain an object describing the change. When you configure the webhooks product, you can indicate if payloads should only contain the names of changed fields, or if payloads should include the new values as well.

We format all payloads with JSON, so you can parse the payload using common JSON parsing methods or packages.

We do not store any Webhook event notification data that we send you, so be sure to capture and store any payload content that you want to keep.

Validate Payloads

We sign all Event Notification payloads with a SHA256 signature and include the signature in the request's 'X-Hub-Signature-256' header, preceded with 'sha256='. You don't have to validate the payload, but you should and we strongly recommend that you do.

To validate the payload:

  1. Generate a SHA256 signature using the payload and your app's App Secret.
  2. Compare your signature to the signature in the X-Hub-Signature-256 header (everything after sha256=). If the signatures match, the payload is genuine.

Please note that we generate the signature using an escaped unicode version of the payload, with lowercase hex digits. If you just calculate against the decoded bytes, you will end up with a different signature. For example, the string äöå should be escaped to \u00e4\u00f6\u00e5.

The 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.");
    }
  }
}

Webhooks Delivery Retry

If a notification sent to your server fails, we will immediately try a few more times. Your server should handle deduplication in these cases. If, after 15 minutes, we are still unable to devliver notifications, an alert is sent to your developer account.

If delivery of a notification continues to fail for 1 hour, you will receive a Webhooks Disabled alert, and your app will be unsubscribed from the webhooks for the Page or Instagram Professional account. Once you have fixed the issues you will need to subscribe to the Webhooks again.

Test Your Webhooks

To test your webhook verification run the following cURL request with your verify token:

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

If your webhook verification is working as expected, you should see the following:

  • 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.

To test your webhook send the following cURL request:

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

If your webhook is working as expected, you should see the following:

  • 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.

Subscribe to Meta Webhooks

Once your webhooks server endpoint, or sample app is ready, go to your app's App Dashboard to subscribe to Meta Webhooks.

In this example we will use the dashboard to configure a Webhook and subscribe to the messages field. Any time a customer sends your app a message, a notification will be sent to your webhooks endpoint.

  1. In the App Dashboard, go to Products > Messenger > Settings.
    • Some Messenger Platform webhooks are not available for Instagram messaging. If you are only implementing webhooks for Instagram and know the webhooks available for Instagram messaging, you can subscribe to webhooks here. To only view and subscribe to webhooks for Instagram messaging, you can go to Instagram settings.
  2. Enter your endpoint's URL in the Callback URL field and add your verification token to the Verify Token field. We will include this string in all Verification Requests. If you are using one of our sample apps, this should be the same string you used for your app's TOKEN config variable.

  3. Subscribe to fields for which you would like to be send notifications and click Save.
  4. The last step is to subscribe to individual fields. Subscribe to the messages field and send a test Event Notification.

    If your endpoint is set up correctly, it should validate the payload and execute whatever code you have set it up to do upon successful validation. If you are using our sample app, load the app's URL in your web browser. It should display the payload's contents.

You can change your Webhooks subscriptions, verify token, or API version at any time using the App Dashboard.

Note: It is recommended that you use the latest API version to receive all information available for each webhook.

You can also do this programmatically by using the /app/subscriptions endpoint .

Available Messenger Platform Fields

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. Only availalbe for Messenger conversations. For Instagram Messaging conversations, the message webhook will be triggered.

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, a notification is also sent when your Instagram Professional account has sent a message since message_echoes is not supported 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

A notification is sent when a policy enforcement warning has been sent or a policy enforcement action has been taken on the app associated with the Page.

messaging_postbacks

A notification is sent when a customer clicks a postback button, Get Started button, or persistent menu item for Messenger conversations or an Icebreaker option or Generic Template button for Instagram Messaging conversations.

messaging_referrals

A notification is sent when a customer resumes a conversation with the Page by clicking an ig.me or m.me link, an ad or chat plugin.

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.

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

Connect Your App

You will need to connect your Webhooks app to your Page and subscribe your Page to the Webhooks notifications you want to receive.

Add the App

You can connect an app to a Page in the Meta Business Suite > All Tools > Business Apps

Note: You will need to subscribe all messaging apps for your business to the messaging webhooks.

Subscribe your Page

You will need to subscribe your Page to the Webhooks notifications you want to receive.

Requirements

To subscribe to a Webhooks field, send a POST 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"

Sample Response

{
  "success": "true"
}

To see which app's your Page has installed, send a GET request instead:

Sample Request

curl -i -X GET "https://graph.facebook.com/PAGE-ID/subscribed_apps
  &access_token=PAGE-ACCESS-TOKEN"

Sample Response

{
  "data": [
    {
      "category": "Business",
      "link": "https://my-clever-domain-name.com/app",
      "name": "My Sample App",
      "id": "APP-ID"
      "subscribed_fields": [
        "messages"
      ]
    }
  ]
}

If your Page has not installed any apps, the API will return an empty data set.

Graph API Explorer

You can also use the Graph API Explorer to send the request to subscribe your Page to a Webhooks field.

  1. Select your app in the Application dropdown menu.
  2. Click the Get Token dropdown and select Get User Access Token, then choose the pages_manage_metadata permission. This will exchange your app token for a User access token with the pages_manage_metadata permission granted.
  3. Click Get Token again and select your Page. This will exchange your User access token for a Page access token.
  4. Change the operation method by clicking the GET dropdown menu and selecting POST.
  5. Replace the default me?fields=id,name query with the Page's id followed by /subscribed_apps, then submit the query.

Access Requirements

To receive notifications from people who have a role on your app, such as your app admins, developers or testers, your app only needs Standard Access. To receive notifications from your customers, people who do not have a role on your app, your app will need Advanced Access.

Learn more about Standard and Advanced Access , the data accessible with each, and requirements for implementation.

Next Steps

  • Send a test message – Learn how to use the platform to send a message.
  • Tour our sample app – Download code for our sample app to learn more about the features Messenger Platform has to offer.
  • See Also