Serverless webhook transformation (DockerHub to Slack)
Tags: serverless, webdev, showdev, docker
Published: 2020-02-28 08:49:56

---
title: Serverless webhook transformation (DockerHub to Slack)
published: true
description: Transform/convert webhooks in a serverless fashion to connect Dockerhub to Slack
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/zrwusup1173v3aftlxo0.png
tags: serverless, webdev, showdev,docker
---

Many Docker registries provide a way to notify team in chat channels when new images are pushed (if you are waiting for a build complete). Let's add this capability to the official DockerHub registry! :) 

We will use newly released [Webhook Relay Functions](https://webhookrelay.com/v1/guide/functions.html) to transform webhooks while they are passing through the service.

Prerequisites:
- [Webhook Relay account](https://my.webhookrelay.com/)
- [DockerHub account](https://hub.docker.com/) 
- Docker


### Create a bucket and configure DockerHub notification

1. Create a bucket here https://my.webhookrelay.com/buckets
2. Once you have it, in the inputs section you will find your public input endpoint, copy it:

    ![Input endpoint URL](https://dev-to-uploads.s3.amazonaws.com/i/hb0nbhnm0foyazklue94.png)

3. Add a new DockerHub webhook setting pointing at our public input endpoint ([DockerHub docs](https://docs.docker.com/docker-hub/webhooks/)):

    ![DockerHub config](https://dev-to-uploads.s3.amazonaws.com/i/4v3w4vhr6tt757a8gppd.png)

### Get a sample of DockerHub webhook

Push a new Docker image:

```
$ docker push karolisr/demo-webhook:latest
The push refers to repository [docker.io/karolisr/demo-webhook]
48bd38e03c42: Mounted from karolisr/webhook-demo
fd9f9fbd5947: Mounted from karolisr/webhook-demo
5216338b40a7: Mounted from karolisr/webhook-demo
latest: digest: sha256:703f2bab2ce8df0c5ec4e45e26718954b09bf4a625ab831c6556fd27d60f1325 size: 949
```

We should be able to see a new incoming webhook. It looks like this:

```json
{
    "push_data": {
        "pushed_at": 1582839308,
        "images": [],
        "tag": "latest",
        "pusher": "karolisr"
    },
    "callback_url": "https://registry.hub.docker.com/u/karolisr/demo-webhook/hook/242ii4ddc2jji4a0cc44fbcdbcdecj1ab/",
    "repository": {
        "status": "Active",
        "description": "",
        "is_trusted": false,
        "full_description": "",
        "repo_url": "https://hub.docker.com/r/karolisr/demo-webhook",
        "owner": "karolisr",
        "is_official": false,
        "is_private": true,
        "name": "demo-webhook",
        "namespace": "karolisr",
        "star_count": 0,
        "comment_count": 0,
        "date_created": 1524557040,
        "repo_name": "karolisr/demo-webhook"
    }
}
```

### Create a Function to transform the webhook

Go to the [Functions page](https://my.webhookrelay.com/functions) and click on a "Create Function" button. Enter a name, for example "dockerhub-to-slack" and click "Submit".

> For this example we are using [Lua language](https://www.lua.org/start.html) which provides an easy way to parse, transform payloads. Webhook Relay Functions also support WebAssembly modules, however they are currently under development and can only be added/updated using relay CLI.

You can now copy/paste webhook payload into the "request body" area for later tests. In the code editor let's add a Lua function to get repository name and prepare a Slack webhook payload:

```lua
local json = require("json")

local body, err = json.decode(r.RequestBody)
if err then error(err) end

local message = "New image pushed at: " .. body["repository"]["repo_name"] .. ":" .. body["push_data"]["tag"]

-- Preparing Slack payload
local slack = {
    response_type= "in_channel", 
    text= message}

local result, err = json.encode(slack)

-- Set request header to application/json
r:SetRequestHeader("Content-Type", "application/json")
-- Set request method to PUT
r:SetRequestMethod("POST")
-- Set modified request body
r:SetRequestBody(result)
```

Click "Save" and then try testing it with the "Send" button:

![Function invoke example](https://dev-to-uploads.s3.amazonaws.com/i/icxxw26h9fhifeqnqfxy.png)

### Connect everything together

1. Navigate to https://api.slack.com/messaging/webhooks and click "Create your Slack app". Select your workspace, enter a name that you will remember.
    
2. Create a new incoming webhook configuration, copy "Webhook URL" (it starts with `https://hooks.slack.com/services/T3...`), we will need to supply it to Webhook Relay.
3. Open your bucket details (via https://my.webhookrelay.com/buckets)
4. Open "OUTPUT DESTINATIONS" tab and create a new output called "Slack" with the Slack URL from step 2:

    ![Create destination](https://dev-to-uploads.s3.amazonaws.com/i/byd869wvndrrj1po5ioo.png)
  
5. Once created, click on the "code" symbol and from the dropdown select `dockerhub_to_slack` function:

    ![Select function](https://dev-to-uploads.s3.amazonaws.com/i/4zl0bug70v022dv01xjd.png)

Push new image to DockerHub, you should see a new notification in your Slack channel:


![Slack notification](https://dev-to-uploads.s3.amazonaws.com/i/prkk6jdldn4srmsmanbl.png)

That's it, feel free to continue modifying Lua function to include pusher's name and message format. Following this process you can transform any webhook into any other webhook.

Have fun!

*Originally released on https://webhookrelay.com/v1/examples/convert-dockerhub-webhook-to-slack.html*