Setting Webhooks for Facebook Apps
Tags: facebook, graphapi, ngrok, javascript
Published: 2021-05-27 17:38:14

# Introduction
Webhooks are a way to get your application to produce a certain behaviour depending on the occurrence of a specific event. Webhooks contain the data or the payload that you would need to identify the event to trigger the corresponding behaviour.

For example, imagine you created a bot that monitors the price of a certain product on an ecommerce website. Once the price hits a certain value on the website, the bot will notify you that such an event has occurred. Now, it may be so that the price takes a lot of time, maybe even days, to reach that value that the bot is set to look for and until that time, the bot is always in a running state monitoring the price. This will be an inefficient approach since the code would have to be running 24x7. If you're running it on a cloud server, it's going to be an expensive bot for not that substantial value that it provides.

But what if the website itself sent a notification to your bot? That would mean that the bot just has to live on a server and doesn't need to be active. It has to be active only when the notification is received from the website. The event will be sent as a POST request to the URL where your bot exists and then the bot does its work. Cool, right? And handy!

This will also give your bot a real time behaviour.

# Working with Facebook Apps

Facebook allows developers to create apps that interact with Facebook for various purposes. To do this, Facebook created the [Graph API](https://developers.facebook.com/docs/graph-api/) which helps in facilitating actions on Facebook for your app. The [Graph API Explorer](https://developers.facebook.com/tools/explorer/) is an excellent tool that helps you run APIs on the browser. It also helps you to get the correct URLs and structure your requests.

Here's a quick list of things you need:
1. A Facebook app.
2. A program that can accept HTTP requests. I'll be using Node.js here with the [Express.js framework](https://expressjs.com) to handle the requests.
3. [Ngrok](https://ngrok.com) to expose your localhost on the internet.

<mark>This tutorial assumes that you know how to set up basic [Facebook apps](https://developers.facebook.com/apps/).</mark>

So, let's get cracking.
##### 1. Create a server.
 Here's the Node.js code that creates a server and listens on port `5000`.
 ```javascript
   const app = require('express')()

   // express middleware
   const bodyParser = require('body-parser')
   app.use(bodyParser.urlencoded({ extended: false }))
   app.use(bodyParser.json())
   
   const PORT = 5000
   // start server  
   app.listen(PORT, () => console.log(`Listening on port ${PORT}`))

```
 Run this code and the server will be up listening to any
incoming requests.
  
##### 2. Start Ngrok on the same port `5000`.
 To do this, run the command `ngrok http 5000`. On running the command, the following view will appear on the terminal:
    ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cj40q3k1vlmalb2dkvpl.png)
 Here, you can see which URLs are being forwarded and the requests that have been received on those URLs. You want to use the HTTPS URL for this purpose since it's a requirement set by the Graph API. For this example, it is `https://7ac66c7f726f.ngrok.io`

##### 3. Setup the Webhook product.
 On your app dashboard, scroll down to **Add Products to Your App**. Look for Webhooks and click on `Set up`.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xzm2cnv098t8ytwu8jwe.png)
At the pane on the left hand side, click on `Webhooks`. You should see something like this 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t50m6ltfpg5bkp1nd80n.png)

##### 4. Handle webhook endpoint.
 Before we add a callback URL, we need to add some more code. This step handles the requests coming to the webhook endpoint. While registering a webhook, Facebook will send a request to the URL that you provide along with the endpoint and it will expect a response from the endpoint, which is the `challenge` code. This has to be echoed back to Facebook only then will the URL be registered.
 
```javascript

app.get('/webhook', (req, res) => {

      const VERIFY_TOKEN = "random string"
      // Parse the query params
      const mode = req.query['hub.mode'];
      const token = req.query['hub.verify_token'];
      const challenge = req.query['hub.challenge'];
        
      // Checks if a token and mode is in the query string of the request
      if (mode && token) {
      
        // Checks the mode and token sent is correct
        if (mode === 'subscribe' && token === VERIFY_TOKEN) {
          
          // Responds with the challenge token from the request
          console.log('WEBHOOK_VERIFIED');
          res.status(200).send(challenge);
        
        } else {
          // Responds with '403 Forbidden' if verify tokens do not match
          res.sendStatus(403);      
        }
      }
})

```

The final code is as follows
{% gist https://gist.github.com/kevinam99/5cac504f0c2ccf941939b03c929d3d7f %}
##### 5. Subscribe to an object
 Click the drop down menu and select any object you want. I'll select the `User` object here and then click on `Subscribe to this object` which will open this modal

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1d8n93hdq3ilglq5in6u.png)
Enter the https URL from Ngrok along with an endpoint. The endpoint can be anything and it should be able to receive HTTP POST requests. The string in the `Verify Token` field can be anything. It is just a security measure put in place to see that the request is coming from the right source to the right destination. You may or may not choose to put a check in the code. Then click on `Verify and Save`. This will then take you to a page where you can choose the subscriptions you need.

 <mark>The GET request is only for registering the callback URL to an object. To handle actual events, make sure to write a POST route to the same endpoint (in this example, `webhook`). This route will handle the behaviour of the bot/app. </mark>
 Most of these subscriptions are available after verification, but if you click on the `Test` button, you'll  be able to see a sample request sent to your endpoint.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h0n30l5qr4u08fdbvey0.png)
Click on `Send to My Server` and you'll see the request.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dciazop8bqrjxjzf3mz8.png)
 If you open Ngrok's web interface, you'll be able to see the details associated with each request on your browser.


I hope this tutorial helped you in setting your own webhook with your Facebook app. I certainly had some trouble getting it done myself and so, I though of writing up this blog to help anyone else save time.

Thank you for your time. Until next time, ciao.

You can reach out to me on
* Email: <kevinam99.work@gmail.com>
* GitHub: [@kevinam99](https://www.github.com/kevinam99)
* Twitter: [@neverloquacious](https://www.twitter.com/neverloquacious)
* LinkedIn: [Kevin A Mathew](https://www.linkedin.com/in/kevin-a-mathew)