- Use Case
- Log in →
- Docker Compose update on Github webhook
- Using Google Firestore for a Golang backend application
- Automated Jenkins builds on GitHub pull request
- Rules-based webhook filtering & routing
- Introducing Cloudflare support for Home Assistant remote access
- Setting up simple, self-hosted & fast CI/CD solution with Drone.io
- Controlling TV with Google Home, IFTTT and Node-RED
- Node-RED OwnTracks location tracking without public IP/MQTT
- Secure webhooks to Jenkins on Kubernetes
- Remote YouTube downloader Slack bot
Rules-based webhook filtering & routing
Apr 2, 2019, by Karolis Rusenas
Some webhook providers do not offer fine-grained control over what events are being sent via webhooks. Sometimes, you end up in a situation where webhooks, based on their type have to be delivered to different servers. We will have a look at a new Webhook Relay forwarding feature that allows users to define rules on outputs that help in these situations.
Each output can now have one or more, multi-level rules and rule groups. In this short tutorial, we will create a rule to verify GitHub webhooks and route them to appropriate endpoints based on their contents.
First, go to the Webhook Relay buckets page and create a new bucket. Once you have it, you should be able to set your public input endpoint:
Buckets are a grouping mechanism that let you define multiple inputs and multiple output destinations.
To create a GitHub repository webhooks, go to Settings -> Webhooks and set few parameters:
- Payload URL should be your input endpoints:
- Content type is whatever your webhook receiver is comfortable consuming, usually it will be `application/json.
- Secret is your secret key, set it to anything you want, I set mine to
Once you have your output, click on a triangle to define your rules. For now, we will create a single rule. Click on the dropdown next to “ADD RULE”, select header and then click the “ADD RULE” button.
In the parameter set X-Hub-Signature. It tells Webhook Relay where to find the parameter to match against. Then, from the dropdown select payload SHA1 and set the last field to your secret value, mine was
Configuration is now set. Try pushing to your repository. Webhook should be pass through the service. Feel free to change your secret either in Webhook Relay configuration or GitHub webhook config and retrying push, it will be rejected.
At this point, we can determine whether webhooks are coming from GitHub or not. Next step - differentiating between pushes and tags.
If you create a new release or just make a git tag on your repository, a new webhook will be visible in your repository. Go to request details:
The part that’s interesting for us is
And the second webhook will be for the tag itself:
Let’s create a rule that will catch any tag requests:
- Create a new output called production-ci.
- Copy existing signature matcher rule from the first output (click on a JSON VIEW when in the rules modal and copy it into the new output rule).
- Add a new group and set Logical Operator to Any. This works the same way as or in programming.
- Add a new rule that will be matching payload, set parameter to ref (it will be getting it from payload), select contains matcher and to the value field set refs/tags:
Now, if you push again, webhook will not be relayed to production-ci destination. Let’s modify our first rule to reject all tag webhooks. You can do that by creating a similar rule to the one we added in production-ci output but instead of contains set it to does not contain. Now, make a new tag and check out your bucket logs:
As you see, it’s trivial to set up multi-level rules that can route webhooks to desired destinations based on their contents and also do some basic validation. If you need yet more power on selecting correct webhooks, check out our example implementation of the socket protocol here: https://github.com/webhookrelay/webhookrelay-ws-client. Using WebSockets, you can receive webhooks directly inside your application and process them accordingly. Library is already used in Node-RED workflows via our node (blog post here).
I have recently also had a chance to look at Rust programming language and found that implementing a webhook forwarding application can be quite interesting: https://github.com/rusenask/rust-ws-client.