16
Intro to Webhooks with Python
This tutorial will be an introduction to the concept of webhooks. We will also build a simple Flask server that can receive GitHub webhooks. We will also see how to expose our local hosts.
Before talking about webhooks, let's talk about APIs. Below is the data flow for an API.
You make a GET/POST request to the API and you get a response back. If you want to learn more about working with APIs, check out my article on working with APIs with Python or my article on working with APIs with JavaScript.
Consider the Github API, what if we wanted to build an API that would send use an email every time a new issue is made in a repo. One way would be to build an API that would make a request every 1-2 minutes to check if a new issue is made and notify us. This process is known as polling. Basically we would have to periodically make requests to check for a new issue. However, this seems inefficient. What if GitHub makes a request to our API whenever a new issue is created. This is known as a webhook. Instead of us making periodic requests, we just give GitHub our API's endpoint and whenever a new issue is created, a request will be made to the endpoint we gave to Github. Webhooks are also known as Reverse APIs. Below is a comparison between polling and webhooks. This image was inspired by this article
As you might have noticed, a lot of requests are made and depending on how frequently we make requests, there might be a slight delay between the new issue being created and our API getting notified.
Let's create an API to receive a request whenever a new Issue is created in a Github repo.
First, let's create a hello world endpoint.
Now we need to create an endpoint to receive the request from the GitHub API. This will be a standard endpoint that accepts POST requests.
I read the docs and knew the keys for the JSON objects. You can use different keys to access more data like issue labels etc.
Now you can run your flask server
python3 __init__.py
Webhooks require a public API endpoint since they can not make requests to endpoints such as 'http://127.0.0.1:5000/'. One way would be to deploy the API and use the URL of the deployed API. Another way is to expose your localhost as a publically available URL. This will be temporary and will only work as long as your Flask server is running. Any request made to the public URL will also be made to your localhost URL.
We will use ngrok to expose our localhost URL. You will have to create an account.
ngrok http <PORT NUMBER>
Eg: If your flask server is running on port 5000, you'd have to type the following
ngrok http 5000
Enter your endpoint, in my case it is http://35cc-69-58-102-156.ngrok.io/githubIssue
Since we only want requests to be made when an Issue is created in the repo, select 'Let me select individual events.' and scroll down to choose 'Issues'. Once you are down, scroll down and create the webhook.
Create an Issue in your repo
Now check the terminal where the flask server is running. I also added a label and closed the issue.
16