1
0
Fork 0
mirror of https://github.com/adnanh/webhook.git synced 2026-07-23 02:08:39 +00:00

Merge remote-tracking branch 'o'

# Conflicts:
#	README.md
#	docs/Webhook-Parameters.md
#	go.mod
#	webhook_test.go
This commit is contained in:
jason.liao 2026-05-09 21:48:19 +08:00
commit 0645b1404f
604 changed files with 102778 additions and 130025 deletions

View file

@ -22,6 +22,25 @@ although the examples on this page all use the JSON format.
* [Multipart Form Data](#multipart-form-data)
* [Pass string arguments to command](#pass-string-arguments-to-command)
* [Receive Synology DSM notifications](#receive-synology-notifications)
* [Incoming Azure Container Registry (ACR) webhook](#incoming-acr-webhook)
## Printing the Raw Webhook Payload to Standard Output
This hook configuration receives incoming webhook requests and prints the raw request body (payload) directly to the server's standard output (visible in the webhook process logs when running with -verbose). It is particularly useful for debugging and verifying webhook deliveries from external services.
```json
[
{
"id": "print-payload",
"execute-command": "/bin/echo",
"pass-arguments-to-command": [
{
"source": "entire-payload",
}
]
}
]
```
## Incoming Github webhook
@ -213,7 +232,11 @@ Values in the request body can be accessed in the command or to the match rule b
}
]
```
## Incoming Gitea webhook
JSON version:
```json
[
{
@ -228,7 +251,7 @@ Values in the request body can be accessed in the command or to the match rule b
},
{
"source": "payload",
"name": "pusher.name"
"name": "pusher.full_name"
},
{
"source": "payload",
@ -242,12 +265,12 @@ Values in the request body can be accessed in the command or to the match rule b
{
"match":
{
"type": "value",
"value": "mysecret",
"type": "payload-hmac-sha256",
"secret": "mysecret",
"parameter":
{
"source": "payload",
"name": "secret"
"source": "header",
"name": "X-Gitea-Signature"
}
}
},
@ -255,7 +278,7 @@ Values in the request body can be accessed in the command or to the match rule b
"match":
{
"type": "value",
"value": "refs/heads/master",
"value": "refs/heads/main",
"parameter":
{
"source": "payload",
@ -269,6 +292,35 @@ Values in the request body can be accessed in the command or to the match rule b
]
```
YAML version:
```yaml
- id: webhook
execute-command: /home/adnan/redeploy-go-webhook.sh
command-working-directory: /home/adnan/go
pass-arguments-to-command:
- source: payload
name: head_commit.id
- source: payload
name: pusher.full_name
- source: payload
name: pusher.email
trigger-rule:
and:
- match:
type: payload-hmac-sha256
secret: mysecret
parameter:
source: header
name: X-Gitea-Signature
- match:
type: value
value: refs/heads/main
parameter:
source: payload
name: ref
```
## Slack slash command
```json
[
@ -331,7 +383,7 @@ __Not recommended in production due to low security__
### Webhook configuration
<pre>
```json
[
{
"id": "test-file-webhook",
@ -350,29 +402,29 @@ __Not recommended in production due to low security__
"include-command-output-in-response": true
}
]
</pre>
```
### Sample client usage
Store the following file as `testRequest.json`.
<pre>
```json
{"binary":"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2lpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wUmlnaHRzPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvcmlnaHRzLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjEzMTA4RDI0QzMxQjExRTBCMzYzRjY1QUQ1Njc4QzFBIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjEzMTA4RDIzQzMxQjExRTBCMzYzRjY1QUQ1Njc4QzFBIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzMgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ1dWlkOkFDMUYyRTgzMzI0QURGMTFBQUI4QzUzOTBEODVCNUIzIiBzdFJlZjpkb2N1bWVudElEPSJ1dWlkOkM5RDM0OTY2NEEzQ0REMTFCMDhBQkJCQ0ZGMTcyMTU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+IBFgEwAAAmJJREFUeNqkk89rE1EQx2d/NNq0xcYYayPYJDWC9ODBsKIgAREjBmvEg2cvHnr05KHQ9iB49SL+/BMEfxBQKHgwCEbTNNIYaqgaoanFJi+rcXezye4689jYkIMIDnx47837zrx583YFx3Hgf0xA6/dJyAkkgUy4vgryAnmNWH9L4EVmotFoKplMHgoGg6PkrFarjXQ6/bFcLj/G5W1E+3NaX4KZeDx+dX5+7kg4HBlmrC6JoiDFYrGhROLM/mp1Y6JSqdCd3/SW0GUqEAjkl5ZyHTSHKBQKnO6a9khD2m5cr91IJBJ1VVWdiM/n6LruNJtNDs3JR3ukIW03SHTHi8iVsbG9I51OG1bW16HVasHQZopDc/JZVgdIQ1o3BmTkEnJXURS/KIpgGAYPkCQJPi0u8uzDKQN0XQPbtgE1MmrHs9nsfSqAEjxCNtHxZHLy4G4smUQgyzL4LzOegDGGp1ucVqsNqKVrpJCM7F4hg6iaZvhqtZrg8XjA4xnAU3XeKLqWaRImoIZeQXVjQO5pYp4xNVirsR1erxer2O4yfa227WCwhtWoJmn7m0h270NxmemFW4706zMm8GCgxBGEASCfhnukIW03iFdQnOPz0LNKp3362JqQzSw4u2LXBe+Bs3xD+/oc1NxN55RiC9fOme0LEQiRf2rBzaKEeJJ37ZWTVunBeGN2WmQjg/DeLTVP89nzAive2dMwlo9bpFVC2xWMZr+A720FVn88fAUb3wDMOjyN7YNc6TvUSHQ4AH6TOUdLL7em68UtWPsJqxgTpgeiLu1EBt1R+Me/mF7CQPTfAgwAGxY2vOTrR3oAAAAASUVORK5CYII="}
</pre>
```
use then the curl tool to execute a request to the webhook.
<pre>
```sh
#!/bin/bash
curl -H "Content-Type:application/json" -X POST -d @testRequest.json \
http://localhost:9000/hooks/test-file-webhook
</pre>
```
or in a single line, using https://github.com/jpmens/jo to generate the JSON code
<pre>
```console
jo binary=%filename.zip | curl -H "Content-Type:application/json" -X POST -d @- \
http://localhost:9000/hooks/test-file-webhook
</pre>
```
## Incoming Scalr Webhook
@ -380,7 +432,7 @@ http://localhost:9000/hooks/test-file-webhook
Scalr makes webhook calls based on an event to a configured webhook endpoint (for example Host Down, Host Up). Webhook endpoints are URLs where Scalr will deliver Webhook notifications.
Scalr assigns a unique signing key for every configured webhook endpoint.
Refer to this URL for information on how to setup the webhook call on the Scalr side: [Scalr Wiki Webhooks](https://scalr-wiki.atlassian.net/wiki/spaces/docs/pages/6193173/Webhooks)
In order to leverage the Signing Key for addtional authentication/security you must configure the trigger rule with a match type of "scalr-signature".
In order to leverage the Signing Key for additional authentication/security you must configure the trigger rule with a match type of "scalr-signature".
```json
[
@ -498,7 +550,8 @@ A reference to the second item in the array would look like this:
[
{
"id": "sendgrid",
"execute-command": "{{ .Hookecho }}",
"execute-command": "/root/my-server/deployment.sh",
"command-working-directory": "/root/my-server",
"trigger-rule": {
"match": {
"type": "value",
@ -594,7 +647,6 @@ We only care about the payload part.
}
}
]
```
Each part of a multipart form data body will have a `Content-Disposition` header.
@ -675,3 +727,72 @@ Webhooks feature introduced in DSM 7.x seems to be incomplete & broken, but you
}
]
```
## Incoming Azure Container Registry (ACR) webhook
ACR can send webhooks on image push events. The `hooks.json` below will handle those events and pass relevant properties as environment variables to a command.
Here is an example of a working docker webhook container used to handle the webhooks and fill the cache of a local registry: [ACR Harbor local cache feeder](https://github.com/tomdess/registry-cache-feeder).
```json
[
{
"id": "acr-push-event",
"execute-command": "/config/script-acr.sh",
"command-working-directory": "/config",
"pass-environment-to-command":
[
{
"envname": "ACTION",
"source": "payload",
"name": "action"
},
{
"envname": "REPO",
"source": "payload",
"name": "target.repository"
},
{
"envname": "TAG",
"source": "payload",
"name": "target.tag"
},
{
"envname": "DIGEST",
"source": "payload",
"name": "target.digest"
}
],
"trigger-rule":
{
"and":
[
{
"match":
{
"type": "value",
"value": "mysecretToken",
"parameter":
{
"source": "header",
"name": "X-Static-Token"
}
}
},
{
"match":
{
"type": "value",
"value": "push",
"parameter":
{
"source": "payload",
"name": "action"
}
}
}
]
}
}
]
```

View file

@ -269,10 +269,12 @@ The IP can be IPv4- or IPv6-formatted, using [CIDR notation](https://en.wikipedi
}
```
Note this does not work if webhook is running behind a reverse proxy, as the "client IP" will either not be available at all (if webhook is using a Unix socket or named pipe) or it will be the address of the _proxy_, not of the real client. You will probably need to enforce client IP restrictions in the reverse proxy itself, before forwarding the requests to webhook.
### Match scalr-signature
The trigger rule checks the scalr signature and also checks that the request was signed less than 5 minutes before it was received.
A unqiue signing key is generated for each webhook endpoint URL you register in Scalr.
A unique signing key is generated for each webhook endpoint URL you register in Scalr.
Given the time check make sure that NTP is enabled on both your Scalr and webhook server to prevent any issues
```json

View file

@ -20,6 +20,11 @@ There are four types of request values:
```
3. HTTP Request parameters
#### Valid `name` Parameters:
- `"name": "method"`
- `"name": "remote-addr"`
*Note* Anything other than above mentioned `name` parameters would be invalid!
```json
{

View file

@ -0,0 +1,61 @@
# Using systemd socket activation
_New in v2.8.2_
On platforms that use [systemd](https://systemd.io), [webhook][w]
supports the _socket activation_ mechanism. In this mode, systemd itself is responsible for managing the listening socket, and it launches [webhook][w] the first time it receives a request on the socket. This has a number of advantages over the standard mode:
- [webhook][w] can run as a normal user while still being able to use a port number like 80 or 443 that would normally require root privilege
- if the [webhook][w] process dies and is restarted, pending connections are not dropped - they just keep waiting until the restarted [webhook][w] is ready
No special configuration is necessary to tell [webhook][w] that socket activation is being used - socket activation sets specific environment variables when launching the activated service, if [webhook][w] detects these variables it will ignore the `-port` and `-socket` options and simply use the systemd-provided socket instead of opening its own.
## Configuration
To run [webhook][w] with socket activation you need to create _two_ separate unit files in your systemd configuration directory (typically `/etc/systemd/system`), one for the socket and one for the service. They must have matching names; in this example we use `webhook.socket` and `webhook.service`. At their simplest, these files should look like:
**webhook.socket**
```
[Unit]
Description=Webhook server socket
[Socket]
# Listen on all network interfaces, port 9000
ListenStream=9000
# Alternatives:
## Listen on one specific interface only
# ListenStream=10.0.0.1:9000
# FreeBind=true
## Listen on a Unix domain socket
# ListenStream=/tmp/webhook.sock
[Install]
WantedBy=multi-user.target
```
**webhook.service**
```
[Unit]
Description=Webhook server
[Service]
Type=exec
ExecStart=webhook -nopanic -hooks /etc/webhook/hooks.yml
# Which user should the webhooks run as?
User=nobody
Group=nogroup
```
You should enable and start the _socket_, but it is not necessary to enable the _service_ - this will be started automatically when the socket receives its first request.
```sh
sudo systemctl enable webhook.socket
sudo systemctl start webhook.socket
```
Systemd unit files support many other options, see the [systemd.socket](https://www.freedesktop.org/software/systemd/man/latest/systemd.socket.html) and [systemd.service](https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html) manual pages for full details.
[w]: https://github.com/adnanh/webhook

View file

@ -10,6 +10,7 @@ In the example JSON template file below (YAML is also supported), the `payload-h
Additionally, the result is piped through the built-in Go template function `js` to ensure that the result is a well-formed Javascript/JSON string.
```
[
{
"id": "webhook",
"execute-command": "/home/adnan/redeploy-go-webhook.sh",
@ -72,5 +73,38 @@ Additionally, the result is piped through the built-in Go template function `js`
```
## Template Functions
In addition to the [built-in Go template functions and features][tt], `webhook` provides the following functions:
### `getenv`
The `getenv` template function can be used for inserting environment variables into a templated configuration file.
Example:
```
"Secret": "{{getenv TEST_secret | js}}"
```
### `cat`
The `cat` template function can be used to read a file from the local filesystem. This is useful for reading secrets from files. If the file doesn't exist, it returns an empty string.
Example:
```
"secret": "{{ cat "/run/secrets/my-secret" | js }}"
```
### `credential`
The `credential` template function provides a way to retrieve secrets using [systemd's LoadCredential mechanism](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Credentials). It reads the file specified by the given name from the directory specified in the `CREDENTIALS_DIRECTORY` environment variable.
If `CREDENTIALS_DIRECTORY` is not set, it will fall back to using `getenv` to read the secret from an environment variable of the given name.
Example:
```
"secret": "{{ credential "my-secret" | js }}"
```
[w]: https://github.com/adnanh/webhook
[tt]: https://golang.org/pkg/text/template/

View file

@ -16,7 +16,7 @@ Usage of webhook:
-hotreload
watch hooks file for changes and reload them automatically
-http-methods string
globally restrict allowed HTTP methods; separate methods with comma
set default allowed HTTP methods (ie. "POST"); separate methods with comma
-ip string
ip the webhook should serve hooks on (default "0.0.0.0")
-key string
@ -27,6 +27,8 @@ Usage of webhook:
send log output to a file; implicitly enables verbose logging
-max-concurrency int
default maximum number of concurrent executions per hook; 0 disables the limit
-max-multipart-mem int
maximum memory in bytes for parsing multipart form data before disk caching (default 1048576)
-nopanic
do not panic if hooks cannot be loaded when webhook is not running in verbose mode
-pidfile string
@ -39,6 +41,8 @@ Usage of webhook:
set group ID after opening listening port; must be used with setuid
-setuid int
set user ID after opening listening port; must be used with setgid
-socket string
path to a Unix socket (e.g. /tmp/webhook.sock) or Windows named pipe (e.g. \\.\pipe\webhook) to use instead of listening on an ip and port; if specified, the ip and port options are ignored
-template
parse hooks file as a Go template
-tls-min-version string