How to handle WebHooks with Parse Server
Tags: parseserver, webhooks, javascript, tutorial
Published: 2019-10-24 14:10:44

## Content List ##

* [Handling Incoming Webhooks](#handlingincomingwebhooks)
     * [Building your Webhook Handler](#buildingyourwebhookhandler)
     * [Extracting information from the Request Body](#extractinginformationfromtherequestbody)
* [Example Webhook Handler with Slack](#examplewebhookhandlerwithslack)
     * [Setting up your SashiDo app](#1settingupyoursashidoapp)
     * [Cloud Code](#2cloudcode)
     * [Setting up Slack](#3settingupslack)
     * [Lets try it out!](#4letstestitout)
* [Other UseCases and Scenarios](#otherusecasesandscenarios)
* [Useful Links](#usefullinks)

## Introduction ##

Have you ever wanted to integrate a 3rd Party Client with your SashiDo applications? I suppose you have, and there's an awesome feature called **WebHooks** which help you do just that. In simple terms, a WebHook allows any 3rd Party Client, that supports Webhooks, communicate and send information (Payload) to your Parse Server instance and vice-versa. 

If you want to get more familiar on how to send WebHooks from your SashiDo application to 3rd Party services, check our article on [How to set up WebHooks on SashiDo](https://blog.sashido.io/how-to-set-up-webhooks-on-sashido/) or watch out [YouTube Video Tutorial](https://www.youtube.com/watch?v=igGsAad6fn0&index=8&list=PLk66IKYX7bjrBKSNwNZVpTjVswA0oq5dr).

Sending your own WebHooks is one thing, but let's say you want to **Handle** a WebHook sent from a 3rd Party Client, do something with the information, and respond back. Such WebHooks are also called **Incoming WebHooks** and the only thing you need to set up is a simple **WebHook Handler**.

## Handling Incoming WebHooks

Handling an Incoming WebHook is a really easy task! An Incoming WebHook is just an HTTP **GET** or **POST** request that sends some information to your Parse Server. 

![request cycle](https://media-blog.sashido.io/content/images/2018/07/1_smLrriyaHX1vEzVTtNZU2A.png)

As you may already know, every time you create an application with SashiDo, we automatically give you a **Free Private** GitHub Repository for it. In order for you to process the WebHook from your Parse Server, all you need to do is implement a **Express** route handler within your **app.js** file. That’s called **Advanced Cloud Code** and we’ve made an article about it. You can check the [Useful Links](#useful-links-videos) section for a direct link to the article.
 The **app.js** file is located in your application's GitHub Repository, in the **cloud** folder. 
 So let's get straight to the point!

### Building your WebHook Handler ###

Let's first navigate to the **app.js** file. Navigate to **Dashboard -> your app -> Core -> Cloud Code** and click on the blue button **Manage on GitHub** in the upper right corner.

![Cloud Code location](https://media-blog.sashido.io/content/images/2018/07/cloudCodeNew.jpg)

When you're in your repository, open the **Cloud** folder and you'll find the file **app.js**.

![cloudFolder & app.js](https://media-blog.sashido.io/content/images/2018/07/cloudFolder.gif)

Now it's time to write the Express route handler.

```javascript
   app.post('/webhookHandler', function(request, response) {
    console.info('Received!'); // Log every time a WebHook is handled.

    // Execute any logic that you want when the 3rd Party Client hits that endpoint

    response.status(200); // Let the sender know that we've received the WebHook
    response.send();
});

```
Afterwards, you can access the handler by adding **/webhookHandler** to the end of your **Server URL**. The **Server URL** is just the **API URL Address** without the **/1/**. You can find it in **Dashboard -> Your App -> App Settings -> Security & Keys**. It should look something like this `https://pg-app-sd5ez1yjgta5vksvux7wdfjwiykcpt.scalabl.cloud/webhookHandler`

Yes, it's that simple! 

Let's break this down a bit. First, we define the **app.post** route handler with an endpoint **/webhookHandler**. You can name the endpoint whatever you want, but for the sake of simplicity, we call it like that. 

After that, we can simply put **console.info(‘Received!’)** so we can track when we've received WebHooks through our **Logs** section in the **Dashboard**. 

**ProTip:** It's good practice to handle the WebHook quickly, as most services require you to respond in a few seconds, otherwise, you'll get a **Timeout error**. If you just need to execute some custom logic of yours after receiving a WebHook, without responding to it, a simple `response.status(200)` and `response.send()` would do just fine to tell the service that you’ve received the WebHook. If you need to respond to the Webhook then you should always check the Docs of the 3rd Party Service so you know in what time interval you need to respond and in what format. Some services may have a `responseURL` attached with the Payload. You can use it if you need to send information back to the 3rd Party Service after some time.

You may also find the [Express Docs](http://devdocs.io/express/) useful so check them out too if you’d like. You can also check the Express [Request](http://devdocs.io/express-request/)/[Response](http://devdocs.io/express-response/) references.

That's about it. Now you can execute any logic that you want when you receive the WebHook! All good, but let's say you want to extract the payload and do something according to it.

### Extracting information from the Request Body ###

Extracting information from the request is pretty easy too. We can use the Express **Body Parser** for that. 

Include it at the beginning of your **app.js** file like this:

```javascript
const bodyParser = require('body-parser');

app.use(
    bodyParser.urlencoded({
        extended: true
    })
);

app.use(bodyParser.json()); // If you are processing a JSON formatted Content-Type

```
After you define the Body Parser you can use it to convert the information to something readable and then use it in some way.

Most 3rd Party Services provide you with unique **Verification Token**. When they send you a WebHook, they also include the **Verification Token** in the payload. That way, you can make sure that the WebHook is coming from the desired 3rd Party Client by comparing your **Verification Token** with the one sent with the WebHook payload like this:

```javascript
app.post('/webhookHandler', function(request, response) {
    var payload = JSON.parse(request.body.payload);
    if (payload.verificationToken !== 'your_verification_token') {
        response.status(403).end('Access forbidden');
    }
    ...
});

```

You should note that every 3rd Party Client may send different information and with Content-Type, so always be sure to check what payload is sent through the WebHook so you know exactly how to process the information.

If you want to learn more about the **body parser**, check out the [body-parser npm package](https://www.npmjs.com/package/body-parser#api). It’s already installed so you don’t have to do it.

Here’s how your **app.js** file would look like if you followed the steps:

```javascript
/*
 * Advanced Cloud Code Example
 */
const express = require('express');
const app = express();
const bodyParser = require('body-parser');

app.use(
    bodyParser.urlencoded({
        extended: true
    })
);

app.post('/webhookHandler', function(request, response) {
    var payload = JSON.parse(request.body.payload);
    if (payload.verificationToken !== 'your_verification_token') {
        response.status(403).end('Access forbidden');
    } else {
        response.status(200);
        response.send();
    }
});

/*
 * Exporting of module.exports.app is required.
 * we mount it automatically to the Parse Server Deployment.
 */

module.exports = app;

```

## Example WebHook Handler with Slack ##

It's time to put everything from above into a good example, in this case, with **Slack**.

As you may already know, Slack is one of the most used chat platforms by developers. But did you know that you can integrate it with your SashiDo application? For example, let us say that you want to have a [**Slash Command**](https://api.slack.com/slash-commands) that will list all unbilled users of your application and another **Slash Command** which will try to bill them. Well, the good news is that this can be done pretty easily using Slack apps and WebHooks!

### 1. Setting up your SashiDo app ###

1. Navigate to **Dashboard -> Your App -> Core -> Browser -> _User_ Class**.
1. Create a new column of type **boolean** and name it **billed**.
1. If you don't have any entries in the **User** class, add some users and set the **billed** field of some of them to **false**
     * Easiest and fastest way to add new entries in your **User** class is to go to **Dashboard -> Your App -> Core -> API Console**.
     * For **Request Type** choose **POST**, be sure to check the **Use MasterKey** toggle to be **true**.
     * Set the endpoint to **classes/\_User**.
     * In **Query Parameters** type **{"username":"someUsername","password":"somePassword","billed": false}** and hit **Send Query**.

![createUser](https://media-blog.sashido.io/content/images/2018/07/createUser.gif)

### 2. Cloud Code  ###

For this example, we’ve implement 2 **Slash Commands**:

* **/unbilled** - Will retreive all unbilled users.
* **/bill** - Tries to bill all the unbilled users.

For each of the two, we’ve created a separate WebHook handler which we've included in a separate file. We've provided a direct link to it at the end of this section.

Now let’s see how the handler for the **/bill** command works. First, we define the **route handler** with an endpoint of **/billUser**.
```javascript
app.post('/billUser', async (req, res) => {});
```
After that, we execute our custom logic to try and bill our users:
```javascript
app.post('/billUser', async (req, res) => {
    // Find all unbilled users
    const unbilled = await new Parse.Query(Parse.User)
        .equalTo('billed', false)
        .find();

    // Iterate through all the user objects
    for (let user of unbilled) {
        await user.save({ billed: true }, { useMasterKey: true });
    }

    // When it's done, we send back a response to Slack
    res.send({ text: `${unbilled.length} users successfully billed!` });
});

```
For the sake of simplicity, we've modified the code so it's short and readable. If you want to check the full code, which includes error handling and the **/unbilled Slash Command Handler**, you can check the **app.js** file in our [Demo app.js Example Code](https://gist.github.com/AlexRuptsov/641f390d1b7da19519ac2d3d837222f5) file. If you want you can even copy-paste the code in your **app.js** file.

### 3. Setting up Slack ###

1. Go to [**Slack**](https://slack.com/create#email) and create your own Workspace.
1. After that, create a new [**Slack App**](https://api.slack.com/apps?new_app=1). Name it whatever you want and select the Workspace in which you want to implement it.
1. Navigate to [**Slash Commands**](https://api.slack.com/apps/ABQ3T3QFP/slash-commands?) in the section **Add features and functionality** and click on **Create New Command**.
     * For **Command**, type **/unbilled** (this is the name of your Slash Command).
     * In **Request URL** type your **ServerURL** + the route we defined in the **app.js** file. You can find your SashiDo App's **ServerURL** in **Dashboard -> Your App -> App Settings -> Security & Keys -> API URL Address**. Just replace the **/1/** at the end with **/getUnbilledUsers**. It shoud look something like this - "https://pg-app-sd5ez1yjgta5vksvux7wdfjwiykcpt.scalabl.cloud/getUnbilledUsers".
     * Add a short description to the command and optionally a hint, then click on **Save**.
     * Repeat for the **/bill** Slash Command. Just replace the **Request URL** endpoint to **/billUser** (that's our second route handler in the **app.js** file).

![create slash command](https://media-blog.sashido.io/content/images/2018/07/billCommand.gif)

### 4. Let’s test it out!  ###

So, we've implemented 2 **Slash Commands** - **/unbilled**, which will return all of our unbilled users, and **/bill** which will try to bill all unbilled users.

Let us try it out and see what happens!

First of all, we can see that we have a few unbilled users in the picture below:

![testUnbilledUsers](https://media-blog.sashido.io/content/images/2018/07/testUnbilledUsers.jpg)

Let's head to our Slack Workspace and try out our newly implemented **Slash Commands**.

![slashCommands](https://media-blog.sashido.io/content/images/2018/07/slashCommands.gif)

We can even check our **Logs** section in **Dashboard -> your app -> Core -> Logs** to see if the process went well internally. In our case, everything was fine, as we can see in the picture below:

![logResult](https://media-blog.sashido.io/content/images/2018/07/logResult.jpg)

We've also implemented logic to handle scenarios should there be no unbilled users. If you execute any of the above **Slash Commands** in this case, you'll get the following response:

![noUnbilled](https://media-blog.sashido.io/content/images/2018/07/noUnbilled.jpg)

That's about it. As I said before, pretty simple, right?

## Other use cases and scenarios ##

By now you've learned how to handle WebHooks. Let's look at some use cases.

### Approving Comments/Uploads ###

Let's say that you have an application in which your users can comment and upload pictures. You would probably want to regulate which comments and pictures are uploaded in some way. 

One neat example is an integration with **Slack** and your SashiDo application with WebHooks. It would work in a way that when a person uploads or makes a comment, a WebHook will be fired to Slack, notifying you and your team and letting you choose whether the comment or picture is appropriate or not. After you've made your choice, another WebHook will be fired, this time to your SashiDo App. After handling it with your custom logic, the picture/comment will be posted or not, and you can send a message to the person if the content is not appropriate.

![fakeLogic](https://media-blog.sashido.io/content/images/2018/07/fakeLogic.gif)

If you want to read more about Slack's **WebHooks**, **Interactive messages** & **Buttons** check out the following links:

* [Slack Incoming WebHooks](https://api.slack.com/incoming-webhooks)
* [Slack Interactive Messages](https://api.slack.com/interactive-messages)
* [Slack Buttons](https://api.slack.com/docs/message-buttons)

### Billing service ###

Say you want to have a paid plan for your SashiDo application. You can imagine how hard it would be to write your own custom billing service and so on. That can be easily avoided by integrating a 3rd Party Billing Service like **Chargebee** for example, with your SashiDo app using WebHooks.

If you're interested and want to learn more about it, check out Chargebee's [Events & WebHooks](https://www.chargebee.com/docs/events_and_webhooks.html)

### Chat/Ticketing ###

Have you ever want to get feedback from your users, handle problems and issues that they might have, but don't want to write such features from scratch? With WebHooks you can do just that. For example, you can use 3rd Party Chat/Ticketing Services like **Intercom** or **Teamwork** and integrate them with your SashiDo apps using WebHooks.

If you're interested in such integration, you can check out both [Teamwork](https://developer.teamwork.com/projects/webhooks/overview) and [Intercom](https://developers.intercom.com/docs/webhooks)'s Documentation about WebHooks.

### SMS & Calling ###

Depending on what your application's about, you can choose to have SMS & Calling through it. That, by itself, would be a very laborious task if you choose to code it yourself. With WebHooks, you can use a service like **Twillio** to send text messages and make calls from your application.

If you're interested in SMS & Calls integration for your application, you can check our blog post [GitHub integration of Advanced Cloud Code part 1](https://blog.sashido.io/github-integration-of-advanced-cloud-code-part-1/) or [Twillio's Documentation](https://www.twilio.com/docs/sms/tutorials/how-to-receive-and-reply)

## Useful Links ##

* If you want to learn how to run your Advanced Cloud Code locally check out our blog post [GitHub integration of Advanced Cloud Code Part 2](https://blog.sashido.io/github-integration-of-advanced-cloud-code-part-2/).
* You can also check our tutorial on [How to set up Cloud Code on SashiDo](https://blog.sashido.io/how-to-set-up-cloud-code-on-sashido/).
* Watch our YouTube Video Tutorial on [Simple Cloud Code on SashiDo](https://www.youtube.com/watch?v=Wm8wv3biWkc&index=6&list=PLk66IKYX7bjrBKSNwNZVpTjVswA0oq5dr)

## Final ##

Whoa! That was a lot to take in. The great part is that you can use this information to your advantage and integrate your SashiDo apps with some other cool services!

Happy coding!