Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/alextmjugador/github-webhook-filter-proxy
Serverless, easy-to-setup GitHub webhook filtering proxy that relays or drops events when they match configurable JSONPath expressions, powered by Cloudflare Workers.
https://github.com/alextmjugador/github-webhook-filter-proxy
cloudflare-worker filtering filtering-proxy github-webhook-handler github-webhook-listener github-webhooks hacktoberfest proxy-server serverless webhooks
Last synced: 2 days ago
JSON representation
Serverless, easy-to-setup GitHub webhook filtering proxy that relays or drops events when they match configurable JSONPath expressions, powered by Cloudflare Workers.
- Host: GitHub
- URL: https://github.com/alextmjugador/github-webhook-filter-proxy
- Owner: AlexTMjugador
- License: mit
- Created: 2022-09-28T22:27:58.000Z (over 2 years ago)
- Default Branch: master
- Last Pushed: 2024-10-24T00:27:35.000Z (2 months ago)
- Last Synced: 2024-10-24T11:29:21.799Z (2 months ago)
- Topics: cloudflare-worker, filtering, filtering-proxy, github-webhook-handler, github-webhook-listener, github-webhooks, hacktoberfest, proxy-server, serverless, webhooks
- Language: TypeScript
- Homepage:
- Size: 1.09 MB
- Stars: 8
- Watchers: 3
- Forks: 3
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
GitHub webhook filter proxy
A serverless, easy-to-setup GitHub webhook filtering proxy that relays or drops events when they match configurable JSONPath expressions, powered by Cloudflare Workers.
- [π‘ Background](#-background)
- [Use cases](#use-cases)
- [β¨ Quickstart](#-quickstart)
- [βοΈ Configuration](#οΈ-configuration)
- [`SECRET_TOKEN`](#secret_token)
- [`TARGET_URL`](#target_url)
- [`UNMATCHED_EVENT_ACTION`](#unmatched_event_action)
- [`_EVENT_MATCH_JSONPATH`](#event-name_event_match_jsonpath)
- [`_EVENT_MATCH_ACTION`](#event-name_event_match_action)
- [Configuration via files](#configuration-via-files)
- [Examples](#examples)
- [β€οΈ Contributing](#οΈ-contributing)
- [π€ Contact](#-contact)
- [π§βπ€βπ§ Contributors](#-contributors)# π‘ Background
GitHub supports sending HTTP POST requests to an arbitrary server in response to events on the platform, known as [_webhooks_](https://docs.github.com/en/developers/webhooks-and-events/webhooks/about-webhooks), to notify external services about them. They are particularly useful for integrating with GitHub.
However, while GitHub lets users select what types of events trigger a webhook, it does not offer any functionality for filtering events by more fine-grained conditions. For example, when a webhook is triggered by a `push` event, it is triggered for a `push` in any branch, even if the service is only interested in a single branch.
This behavior can be undesirable: it wastes traffic for would-be-ignored events, and several external services, which in some cases are not controlled by the end user, may not offer any filtering features, triggering superfluous actions.
This project offers an easy-to-setup, flexible proxy that anyone can use to drop events before they are delivered to the actual external service, as if they never were triggered. GitHub can be configured to deliver events to this proxy, which then decides to relay the event to the external service or drop it, based on whether the event JSON body matches a JSONPath expression.
## Use cases
This proxy is helpful for chores such as:
- **Limiting what pull requests and branches send chat notifications on Discord or Slack**. Get rid of the notification spam caused by automation tools, such as Dependabot or Renovate, and focus on worthwhile events!
- **Enforcing event sender authentication**. [GitHub can sign webhook requests with a shared secret](https://docs.github.com/en/developers/webhooks-and-events/webhooks/securing-your-webhooks), and this proxy expects and verifies that signature. Rest assured knowing that every event relayed by this proxy comes from GitHub.
- **Working around a lack of event filtering features**. Trigger deployments, continuous integration, and similar tasks only for a subset of events, even if the external service does not support that.
- **Reducing the load on an overwhelmed service**.# β¨ Quickstart
The easiest way to get started is to fork this repository and deploy it to your [Cloudflare](https://www.cloudflare.com) account. There are step-by-step instructions to do that below. It's free, and it will only take you a few minutes!
1. Click the button below. Follow the instructions that appear.
> **Note**: Cloudflare will ask you for an API token, which you will need to create if you don't have one yet. The "Edit Cloudflare Workers" template generates API tokens suitable for deploying this proxy.
2. If everything goes well, you will be greeted with the following screen, and the worker will be deployed. Click the "Worker dash" button.
3. Find your way to the "Settings" tab of the worker you've just deployed, at Workers βΊ `github-webhook-filter-proxy`. Once there, go to the "Variables" section and add a new environment variable by clicking "Add variable".
4. As you may have guessed, the proxy is configured via environment variables. For now, we will set three environment variables:
- `SECRET_TOKEN`: a random, unique string that only GitHub and the proxy should know, used by the proxy to authenticate that events come from GitHub. Some ways of generating this token include running `echo "$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c32)"` on a Unix-like terminal, or using websites like [random.org](https://www.random.org/strings/?num=1&len=20&digits=on&upperalpha=on&loweralpha=on&unique=off&format=html&rnd=new). **Make sure to click the "Encrypt" button once you are done typing the token!**
- `TARGET_URL`: the URL to which the proxy will relay events that it does not drop. This is the URL of your target service (or another proxy, if you are into that).
- `UNMATCHED_EVENT_ACTION`: the action to perform when a JSONPath expression match is not configured for an input event. The default is `drop`, so set it to `relay` to make the proxy send all the events it receives to the target URL.Before clicking "Save" to apply the changes, the edition form should look like this:
5. On GitHub, go to the corresponding webhooks settings page. Set the payload URL to the route of your worker, select `application/json` as "Content type", and type the same secret as in `SECRET_TOKEN`. If you are using the default `workers.dev` route, you can (and should) leave SSL verification enabled.
6. **The proxy is ready to rock!** π If you want to know what is going on, check out the "Recent deliveries" on GitHub and the worker logs on Cloudflare. The next section of this document describes the environment variables you can use to configure how it filters events.
# βοΈ Configuration
The proxy can be configured via the following environment variables.
## `SECRET_TOKEN`
**Required**: yes
A random secret shared by GitHub and the proxy that is used to validate the digital signature that GitHub adds to the webhook event request.
The proxy expects and validates these signatures, so both GitHub and the proxy must be configured with the same value for this token.
## `TARGET_URL`
**Required**: yes
**Accepted values**: any HTTP(S) URL
The URL to which the proxy will relay events that it does not drop. This is the URL of the service that is being proxied.
## `UNMATCHED_EVENT_ACTION`
**Required**: no
**Accepted values**: `relay` or `drop`
**Default value**: `drop`
The action to perform when a JSONPath expression match is not defined for an event. `drop` discards the event, while `relay` forwards the request to the target URL.
## `_EVENT_MATCH_JSONPATH`
**Required**: no
**Accepted values**: a [JSONPath expression](https://goessner.net/articles/JsonPath/), as a string
**Default value**: not defined
The JSONPath expression to match against the JSON event payload for `` events, where `` is the name of a webhook event [listed in the GitHub documentation](https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads), converted to uppercase.
For matching, the event JSON object is put into a single-element array, and then the specified JSONPath expression is evaluated by the [`jsonpath` npm package](https://www.npmjs.com/package/jsonpath/v/1.1.1). This wrapping allows filtering JSONPath subscript operator expressions on the event object keys.
If a match occurs, the proxy will either relay or drop the event as defined by [`_EVENT_MATCH_ACTION`](#event-name_event_match_action). If the payload does not match the JSONPath expression, the proxy will take the opposite action to the one it would take if it matched (dropping instead of relaying, and vice versa).
## `_EVENT_MATCH_ACTION`
**Required**: no
**Accepted values**: `relay` or `drop`
**Default value**: `drop`
The action to take when the JSONPath expression defined by [`_EVENT_MATCH_JSONPATH`](#event-name_event_match_jsonpath) matches the JSON event payload.
## Configuration via files
The quickstart guide sets worker environment variables using the Cloudflare web dashboard. Nevertheless, it is also possible to configure them in the `wrangler.toml` file, which is the approach recommended by Cloudflare.
The Cloudflare documentation explains [how to set environment variables this way](https://developers.cloudflare.com/workers/platform/environment-variables/#environment-variables-via-wrangler), and describes [the `wrangler.toml` file format](https://developers.cloudflare.com/workers/wrangler/configuration). The [`wrangler.toml` file at this repository](https://github.com/AlexTMjugador/GitHub-webhook-filter-proxy/blob/master/wrangler.toml) contains comments that illustrate how it would be done.
## Examples
The next example variables configure the proxy to relay everything except push events made by bots or on branches managed by [Renovate](https://github.com/renovatebot/renovate).
- `PUSH_EVENT_MATCH_JSONPATH`: `$[?(@.ref.startsWith('refs/heads/renovate/') || @.sender.login == 'github-actions[bot]')]`
- `PUSH_EVENT_MATCH_ACTION` (optional): `drop`
- `UNMATCHED_EVENT_ACTION`: `relay`# β€οΈ Contributing
Pull requests are accepted. Feel free to contribute if you can improve some aspect of the project!
Contributions include, but are not limited to:
- Writing good bug reports or feature requests.
- Sending a PR with code changes that implement an improvement or fix an issue.
- Recommending the project to others and engaging with the community.
- Economically supporting the project (check out the "Sponsor" button in the GitHub page).Code contributions must pass CI checks and be deemed of enough quality by a repository maintainer to be merged.
The proxy source artifacts are structured as a standard `npm` project, coded in TypeScript. The [Wrangler](https://developers.cloudflare.com/workers/wrangler/get-started/) CLI tool is used for development and deployment. After the first `npm install`, `npm run start` will launch the worker in a local server for development. Before committing any change, you should run ESlint and Prettier with `npm run lint` and `npm run format`, respectively.
# π€ Contact
We welcome friendly talk about the project, including questions, congratulations, and suggestions. Head to the [GitHub Discussions page](https://github.com/AlexTMjugador/GitHub-webhook-filter-proxy/discussions) to interact with fellow users, contributors and developers.
# π§βπ€βπ§ Contributors
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
Alejandro GonzΓ‘lez
π» π π§ π
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!