Learn webhooks in under an hour by example
Tags: tutorial, programming, javascript, webdev
Published: 2021-01-05 21:10:03


## Introduction
This guide is an introduction to webhooks. You will learn what webhooks are and use a very simple webhook example server written in JavaScript to process webhooks from your webhook provider.

Optionally, you could then take that open source code and use it for something more specific.

## Prerequisites
We'll be using one programming language, JavaScript for everything.

Its a languages most coders out there will know, but you don't really need to know it finish this guide, as all the code has been written for you.

It may be useful to know JavaScript if you want to take the open source code and then use it as a base for something more specific.

You'll need to have <a href="https://git-scm.com/downloads" target="_blank">Git</a> and <a href="https://nodejs.org/en/download" target="_blank">NodeJS</a> installed.

## What are webhooks?
A Webhook is a request that a Webhook provider makes to your server.

They use the name web because they are based on HTTP, which is the protocol the web is built on. It runs web applications, web sites and APIs.

They are like APIs in reverse. With an API, you make requests to an API provider. Webhooks reverse this flow.

Instead of your code making a HTTP request to the API provider, the Webhook provider makes a HTTP request to you. Your code receives the request, then does something with it.

Examples of webhook requests would be Stripe sending you a notification you about a new payment or IFTTT sending you a notification of a new tweet from your Twitter account.

There are countless other examples
- Mailchimp can send a you webhook when new users sign up to your newsletter
- Facebook messenger can send you a webhook when you receive new messages
- Github can send you webhooks whenever new commits are pushed to your git repositories

This diagram is a quick high level overview of how webhooks work:
<img src="https://expose.sh/blog/jenkins-add-github-webhook/what-are-webhooks.png" style="width:1000px"></img>

As you can imagine, webhooks are useful for notifying your code of events such as payments processed, new messages, tasks it needs do etc.

They can automate alot of things that previously would have required lots of polling or manual work, for example instead of polling a service many times an hour to get updates, you can just have that service send you a single webhook request with the info you need.

Now that you know the meaning of the word webhook, lets set up a simple webhook server.

## Get the code
We'll use my polyglot webhook example server, written in JavaScript. Its very generic and should work with most webhook providers out there.

This app has a generic endpoint that can receive any `HTTP POST` webhook request (we'll talk more about `HTTP POST` later).

Clone the source: `git clone https://github.com/cipher-code/polyglot-webhook-example.git`.

Then run `npm install` to install the dependencies and `npm start` to start the server. If this does not work, check that you have a clear connection to the internet with no firewalls or restrictions (such as corporate network restrictions).

You should see something like this soon:
```
> express-api-webhook-example@0.0.1 start /home/robbie/projects/polyglot-webhook-example
> node app.js

Polyglot webhook example server listening at http://localhost:3000
```

## Take a look at app.js
Open the app and look at app.js. You'll see this:
<img src="https://expose.sh/blog/shared-images/app-js.png"></img>

The top part initialises `express`, a lightweight framework and web server for JavaScript. When you ran `npm install` earlier, this automatically installed express using `npm`.

This code sets up one endpoint, `/webhook-receive`, which will respond to any HTTP request that is a HTTP `GET`,`POST`,`PUT` or `DELETE` requests. Most webhook requests out there will be one of these.

When a webhook request is received, it outputs request information to the console to let you know.

When you start the app, it will listen on localhost at port `3000`.

If you didn't understand any or all of this, don't worry. You can still test your webhooks and learn about this stuff later.

## Get a public HTTPS URL for your server
You might remember this output when you started the sever:
```
Polyglot webhook example server listening at http://localhost:3000
```
This means the server is listening on `localhost`, port `3000`. If you are new to webhooks, you might think you can configure the webhook endpoint for your webhook provider to `http://localhost:3000/webhook-receive`.

There are a couple of issues with that.

The first is that `localhost` is not a public URL availabe to anyone on the web. `localhost` is a special address which means your own machine, meaning if you send a request to `localhost`, you are sending a request to your own machine. Similarly, if your webhook provider sends a request to `localhost` they are really just sending a request to their own server.

The second is that its plain unencrypted HTTP and alot of webhook providers won't send you a request unless you are using HTTPS.

The slow, expensive way to get around these issues would be to buy a HTTPS certificate, deploy your code to a server, point a domain you own to it and configure HTTPS. That would take time and you may not even know how to do this. Its also not going to help you test your code locally on your own computer, where you can easily make quick changes that you need to make without deploying.

The fast way is to use a tool I've created called `expose`, which will give you a public https url with one command.

## Install and run expose.sh
For Mac or Linux, go to [Expose.sh](https://expose.sh?utm_source=dev.to&utm_campaign=learnWebhooksByExampleArticle) and copy/paste the installation code shown into a terminal.

For Windows go to [Expose.sh](https://expose.sh?utm_source=dev.to&utm_campaign=learnWebhooksByExampleArticle), download the binary and put it somewhere in your PATH.

Now that you have `expose` installed, run `expose 3000`.

Expose.sh will generate a couple of public expose.sh URLs on a random subdomain. You'll see output like this:
```
expose 3000
http://m2hh3u.expose.sh is forwarding to localhost:3000
https://m2hh3u.expose.sh is forwarding to localhost:3000
```

The first URL is HTTP and the second one is HTTPS.

## Test your new public HTTPS endpoint
Your web browser can do more than just visit web sites. It is also a HTTP client, meaning you can use it to test your that your new public HTTPS webhook endpoint is working as expected.

Using the HTTPS url `expose` generated for you, go to `<your https url>/webhook-receive` in your browser. Using my own output above, for me this would be `https://m2hh3u.expose.sh/webhook-receive`.

You should now see a response like this. Im using Firefox, but any browser should work:
<img src="https://expose.sh/blog/shared-images/webhook-output.png">

If you can see a response in your browser this means you have successfully set up a webhook server with a public HTTPS URL. Save the URL as you'll be using it again later.

If you want to do more advanced testing later, you could use something like Postman or even `curl` which are also HTTP clients but have more options than a web browser such as being able to send `POST` and other types of requests.

## Configure your webhook provider settings and send webhook request from your provider
Now that you have a working webhook server with a public HTTPs URL, you need to configure your provider and do something that will trigger them to send you a request.

To configure your webhook provider the steps will vary from provider to provider so check your webhook providers documentation on their web site.

Copy and paste the full URL you used in your web browser test into the endpoint field of your webhook providers settings. Sometimes the endpoint field is called URL or something else.

Now do something that you expect will trigger a webhook request, like sending a sms (for Twilio) or making a commit (for GitHub). Then Check the console output (where you ran `npm start` earlier) and you should see a message when the request is succesfully received. For example, you'll see something like this if you receive a `GET` webhook request:
```
Received GET webhook request
Full URL: /webhook-receive
```

If you see a message like this logged to the console, congratulations!. You have sucessfully set up a webhook integration end to end.

If you do not see a message logged to the console but were able to see a response in your web browser earlier, its either due to misconfiguration or a bug in your webhook provider because you already know your side is set up and working. So double check your webhook providers documentation on their web site.

With alot of providers you might also be able to contact their support team for help if you need it, the code is <a href="https://github.com/cipher-code/polyglot-webhook-example" target="_blank">here</a> on GitHub if they ask for it. Check their web site for contact info.

## Custom subdomains
Because `expose` by default generates random subdomains, using a custom subdomain (like `myapi.expose.sh`) would save you from needing to reconfigure a different endpoint every time you run `expose` in your webhook provider.

Expose.sh is free to use for randomly generated subdomains. If you want to use your own custom subdomains like `myapi.expose.sh`, you can do this for as little as $4.99/month depending on how many domains you want to use. It also helps me keep the service running.

Its usually a good time vs money investment, considering the hourly rate of most people who use expose.sh for work and the time saved from repeated reconfiguration work that you could reinvest into more productive or enjoyable activities.

Here's an example using a custom subdomain, you can [Sign up here](https://dashboard.expose.sh?utm_source=dev.to&utm_campaign=learnWebhooksByExampleArticle) to get random subdomains.
```
expose 80 as mysite.expose.sh
https://mysite.expose.sh is forwarding to localhost:80
http://mysite.expose.sh is forwarding to localhost:80
```

## Conclusion
In the end, webhooks are fairly simple. They are really just regular HTTP requests sent by a webhook provider to your server. Because its not you sending the request and you need a public URL they can be tricky to test, so tools like `expose` can help.

## Further reading
- <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview" target="_blank">An overview of HTTP, by Mozilla</a>. This is a great overview of how HTTP works.
- <a href="https://www.bigcommerce.com/blog/what-is-an-api/" target="_blank">What is an API? by BigCommerce</a>. This is a great overview of what APIs are and how they work.

Happy coding!

### Appendix - A list of services you can use webhooks with
In addition to the services we've mentioned, here are more that we know about that support webhooks. Now you know about webhooks, it might be useful to do an integration with them.
<ul>
    <li> Facebook
    <li> Github
    <li> Slack
    <li> Telegram
    <li> Jenkins
    <li> Bitbucket
    <li> Stripe
    <li> Zapier
    <li> Sendgrid
    <li> Shopify
    <li> Wordpress (look for the wp webhooks plugin)
    <li> Dialogflow
    <li> Azure
    <li> Twilio
    <li> Mailchimp
    <li> Hubspot
    <li> Grafana
    <li> Airtable
    <li> IFTTT
    <li> Kubernetes
    <li> Microsoft Flow
    <li> Meraki
    <li> AWS
    <li> Firebase
    <li> Twitter
    <li> CircleCI
    <li> Mailgun
    <li> Gravity Forms
    <li> Docusign
    <li> Blynk
    <li> Google Assistant
    <li> Pipedrive
    <li> Typeform
    <li> Xero
</ul>