GitLab Webhooks

GitLab Webhooks [Python and Google Chat Example]

Hello Bits Lovers! Today, we will learn a great feature from GitLab called WebHooks. Let’s learn how to use it to receive notifications or automate any process that needs interaction with GitLab.

What is GitLab WebHooks?

GitLab Webhooks are HTTP requests that we can define to callback our application or any API when events occur on GitLab. For example, when we commit one code on a specific project and branch, GitLab triggers requests using the previously configured endpoint.

Which events can we watch?

Some of the events that we can watch:

Tag push events

URL is triggered when we push a new tag to the repository.

Comments

URL is triggered when someone adds a comment.

Confidential comments

URL is triggered when someone adds a comment on a confidential issue.

Issues events

URL is triggered when an issue is created, updated, or merged.

Merge request events

URL is triggered when a merge request is created, updated, or merged.

Pipeline events

URL is triggered when the pipeline status changes.

Deployment events

URL is triggered when a deployment starts, finishes, fails, or is canceled.

Why use GitLab WebHooks?

Today, we could integrate the GitLab webhooks with several external services. There is no limitation. Also, besides automating notifications, using webhooks can automate any task we need.

For example, we can trigger one build on Jenkins when releasing a new tag on GitLab. 

Integration with WebHooks

For example, my team uses Google Chat. We can configure a WebHook using a Google Bot. So, every time someone resolves a merge request, we have a specific chat that notifies all users from that Group with an automatic message.

With the same idea, we can integrate Slack with Gitlab and then receive notifications from the event we would like to receive it.

Another fantastic integration is with Twilio API, where we can automate and send an SMS message as our method for notifications.

See the list of Integration current supported:

Google Chat Integration with GitLab

GitLab Webhooks - Using Google Chat
GitLab Webhooks – Using Google Chat

So, Gitlab (a Third-party service) will send notifications directly to the Bot, and the Bot will send it to Google Chat. Later, I will show you how we can easily create the App (Python) and then customize the messages and forward them to Google Chat, but it’s only required if you need to do something more.

Let’s learn how to do the integration with Google Chat. 

Our first step is to create our Google Chat webhook endpoint.

So, go to your Chat space, and click on the “Manage webhooks” option in Menu.

GitLab Webhook - Adding Google Chat
GitLab Webhook – Adding Google Chat

On the next screen, enter the Name, then click “Save.”

GitLab Webhooks with Google Chat - Add
GitLab Webhooks with Google Chat – Add

You will see the Webhook endpoint from Google Chat on the next screen. Save that link because we will use it.

GitLab Webhooks with Google Chat - Endpoint
GitLab Webhooks with Google Chat – Endpoint

For more information, check the official webpage.

Easy, right? Now, we are close to having our notification on Google Chat. Let’s add our webhook endpoint on GitLab.

Open your project on GitLab, and then Settings -> Webhooks:

(click on the image to expand/zoom)

GitLab Webhook - Adding Endpoint
GitLab Webhook – Adding Endpoint

Enter your Google Chat webhook on the URL field that we created in the previous step. The Secret Token you can leave blank.

Now, in the trigger section, it’s the area where we can define which events we would like to receive on our webhook endpoint.

On the push events field, we can define which branch we would like to watch for events or use a wildcard to select a collection of branches. Or leave blank to watch for all branches. It’s up to you.

Below, there are a couple of checkboxes, for each event. So, just check the ones that you want to receive the event through the webhooks.

Finally! Click on “Add webhook”, and we are done!

You can perform any event that we have selected before and see if you receive the notifications on your Google Chat.

Now, I would like to go through a different approach, like a prod! Where we can customize our messages.

Custom Alerts with GitLab WebHooks

When we use the integration, there are ready to use. However, we can’t perform any customization on the messages. For example, using the Google chat solution above, I wouldn’t say I liked the message details (actually, there are no details) for the Pipeline events specifically.

But, we can still create our solution easily. For example, we can build one python code to receive the callback from GitLab and then call our application or ChatBot, like Google Chat or Slack. 

So, using Python, we can intercept the request and receive it from Gitlab, do our customization, and then send the request for our final destination, in my case, Google Chat.

But, I would like to highlight that we can use any language or application. It doesn’t matter. You just need to receive the callback from GitLab and perform or call any other application/system. So, we can do anything here.

Keep reading, and let’s see how we can do it using Python

Prerequisites

Before running your python script, you need to make sure that you have python3 and the modules from the imports.

To install the Gitlab library, execute:

pip3 install python-gitlab

Also, you may need to run

pip3 install flask httplib2
from flask import Flask
from flask import request
from json import dumps
from httplib2 import Http
import json
from gitlab import Gitlab
application = Flask(__name__)
def get_pipeline(project_id, branch):
    gl = Gitlab('https://gitlab.www.bitslovers.com', '')
    gl.auth()
    project = gl.projects.get(project_id)
    pipelines = project.pipelines.list(ref=branch)
    return pipelines[0].web_url
def send(data):
   """Google Chat incoming webhook"""
   url = 'https://chat.googleapis.com/v1/spaces/'
   message_headers = {'Content-Type': 'application/json; charset=UTF-8'}
 
   http_obj = Http()
   status = data['object_attributes']['detailed_status']
   event = data['object_kind']
   isPipeline = event == 'pipeline'
   if status != 'running' and isPipeline:
    project = data['project']['namespace']
    project_id = data['project']['id']
    branch = data['object_attributes']['ref']
    user = data['user']['name']
    
    print('Calling API')
    pipeline = get_pipeline(project_id, branch)
   
	text = " *Event:* " + event + "\n *Project:* " + project + "\n *Status:* " + status + "\n *branch:* " + branch + "\n *User:* " + user + "\n " + pipeline
    bot_message = {'text' : text}
    response = http_obj.request(
        uri=url,
        method='POST',
        headers=message_headers,
        body=dumps(bot_message),
    )
@application.route('/', methods=['POST'])
def index():
    if request.method == 'POST':
        content = request.get_json(silent=True)
        send(content)
        return 'OK\n'
if __name__ == "__main__":
    application.run(host='0.0.0.0', debug=True)

To run

python3 webhook.py

Some important notes

The method get_pipeline gets the pipeline URL and appends to the notification message. So, it’s not required, only if you need the URL; this makes it easier to jump into GitLab to check the logs if the pipeline fails. The response sent by Gitlab to us doesn’t have this information, so we are calling GitLab to retrieve that information.

Replace the following lines:

gl = Gitlab('https://gitlab.www.bitslovers.com', '<TOKEN>')

Specify the URL from your GitLab server and the Token.

url = 'https://chat.googleapis.com/v1/spaces/<REPLACE_THIS_URL>'

Replace the Webhook endpoint that you would like to receive the notification of. In my case, Google Chat. But remember that you can use any external or internal receiver.

Issues and How to resolve them

In my scenario, I am running GitLab on an EC2 instance with Docker. So, my python script will start a web server on port http://172.17.0.1:5000. So I need to add this endpoint as my webhook on the projects that I would like to receive the events through that endpoint.

When you try to add this endpoint or any endpoint that points to a local network, you may get this error:

Url is blocked: Requests to the local network are not allowed

To fix that issue above, you need to go to Admin -> Settings -> Network

or

https://host.gitlab.com/admin/application_settings/network#js-outbound-settings

And check both check-boxes to allow local traffic for webhook.

GitLab Webhooks - Using Internal Network
GitLab Webhooks – Using Internal Network

Conclusion

So, you have learned how webhooks work and that we can design any solution to automate notifications or any process that our scenario may require.

The GitLab API gives us unlimited alternatives to resolve and automate a task requiring several interactions. 

For those who work with GitOPS, this approach provides enormous benefits.

Also, for any company size, it sometimes makes notifications when some events occur in our projects it’s very useful and saves a lot of time.

Leave a Comment

Your email address will not be published. Required fields are marked *

Free PDF with a useful Mind Map that illustrates everything you should know about AWS VPC in a single view.