- Group webhooks
- Configure a webhook in WVS
- Configure your webhook receiver endpoint
- Test a webhook
- Create an example webhook receiver
- Validate payloads by using a secret token
- Filter push events by branch
- How image URLs are displayed in the webhook body
- Events
- Troubleshoot webhooks
Webhooks
Webhooks are custom HTTP callbacks that you define. They are usually triggered by an event, such as pushing code to a repository or posting a comment on a blog. When the event occurs, the source app makes an HTTP request to the URI configured for the webhook. The action to take may be anything. For example, you can use webhooks to:
- Trigger continuous integration (CI) jobs, update external issue trackers, update a backup mirror, or deploy to your production server.
- Send a notification to Slack every time a job fails.
- Integrate with Twilio to be notified via SMS every time an issue is created for a specific project or group in WVS.
You can configure your WVS project or group to trigger a percent-encoded webhook URL when an event occurs. For example, when new code is pushed or a new issue is created. The webhook listens for specific events and WVS sends a POST request with data to the webhook URL.
Usually, you set up your own webhook receiver to receive information from WVS and send it to another app, according to your requirements. We have a built-in receiver for sending Slack notifications per project.
WVS.io enforces webhook limits, including:
- The maximum number of webhooks and their size, both per project and per group.
- The number of webhook calls per minute.
Group webhooks
You can configure a group webhook, which is triggered by events that occur across all projects in the group.
Group webhooks can also be configured to listen for events that are specific to a group, including:
Configure a webhook in WVS
You can configure a webhook for a group or a project.
- In your project or group, on the left sidebar, select Project Settings > Webhooks.
- In URL, enter the URL of the webhook endpoint. The URL must be percent-encoded if it contains one or more special characters.
- In Secret token, enter the secret token to validate payloads.
- In the Trigger section, select the events to trigger the webhook.
- Optional. Clear the Enable SSL verification checkbox to disable SSL verification.
- Select Add webhook.
Configure your webhook receiver endpoint
Webhook receivers should be fast and stable. Slow and unstable receivers may be disabled temporarily to ensure system reliability. If you are writing your own endpoint (web server) to receive WVS webhooks, keep in mind the following:
- Your endpoint should send its HTTP response as fast as possible. You should aim for sub-second response times in all circumstances. If the response takes longer than the configured timeout, WVS assumes the hook failed, which can lead to retries and potentially cause duplicate events. To customize the timeout, see Webhook fails or multiple webhook requests are triggered.
- Your endpoint should ALWAYS return a valid HTTP response. If not, WVS assumes the hook failed and retries it. Most HTTP libraries take care of the response for you automatically but if you are writing a low-level hook, this is important to remember.
- WVS usually ignores the HTTP status code returned by your endpoint,
unless the
web_hooks_disable_failed
feature flag is set.
Best practices for a webhook receiver:
- Prefer to return
200
or201
status responses. Only return error statuses (in the4xx
range) to indicate that the webhook has been misconfigured. For example, if your receiver only supports push events, it is acceptable to return400
if sent an issue payload, since that is an indication that the hook has been set up incorrectly. Alternatively, it is acceptable to ignore unrecognized event payloads. Never return500
status responses if the event has been handled. - Your service should be idempotent. In some circumstances (including timeouts), the same event may be sent twice. Be prepared to handle duplicate events. You can reduce the chances of this by ensuring that your endpoint is reliably fast and stable.
- Keep response payloads as short as possible. Empty responses are fine. WVS does not examine the response body, and it is only stored so you can examine it later in the logs.
- Limit the number and size of response headers. Only send headers that would help you diagnose problems when examining the web hook logs.
- To support fast response times, perform I/O or computationally intensive
operations asynchronously. You may indicate that the webhook is
asynchronous by returning
201
.
Failing webhooks
- Currently disabled by default with a flag named
web_hooks_disable_failed
.
web_hooks_disable_failed
.
The feature is not ready for production use.If a webhook fails repeatedly, it may be disabled automatically.
Webhooks that return response codes in the 5xx
range are understood to be failing
intermittently, and are temporarily disabled. This lasts initially
for 10 minutes. If the hook continues to fail, the back-off period is
extended on each retry, up to a maximum disabled period of 24 hours.
Webhooks that return failure codes in the 4xx
range are understood to be
misconfigured, and these are disabled until you manually re-enable
them. These webhooks are not automatically retried.
See troubleshooting for information on how to see if a webhook is disabled, and how to re-enable it.
Test a webhook
You can trigger a webhook manually, to ensure it’s working properly. You can also send a test request to re-enable a disabled webhook.
For example, to test push events
, your project should have at least one commit. The webhook uses this commit in the webhook.
To test a webhook:
- In your project, on the left sidebar, select Settings > Webhooks.
- Scroll down to the list of configured webhooks.
- From the Test dropdown list, select the type of event to test.
You can also test a webhook from its edit page.
Create an example webhook receiver
To test how WVS webhooks work, you can use an echo script running in a console session. For the following script to work you must have Ruby installed.
-
Save the following file as
print_http_body.rb
:require 'webrick' server = WEBrick::HTTPServer.new(:Port => ARGV.first) server.mount_proc '/' do |req, res| puts req.body end trap 'INT' do server.shutdown end server.start
-
Choose an unused port (for example,
8000
) and start the script:ruby print_http_body.rb 8000
-
In WVS, add your webhook receiver as
http://my.host:8000/
. -
Select Test. You should see something like this in the console:
{"before":"077a85dd266e6f3573ef7e9ef8ce3343ad659c4e","after":"95cd4a99e93bc4bbabacfa2cd10e6725b1403c60",<SNIP>} example.com - - [14/May/2014:07:45:26 EDT] "POST / HTTP/1.1" 200 0 - -> /
Validate payloads by using a secret token
You can specify a secret token to validate received payloads.
The token is sent with the hook request in the
X-WVS-Token
HTTP header. Your webhook endpoint can check the token to verify
that the request is legitimate.
Filter push events by branch
Push events can be filtered by branch using a branch name or wildcard pattern to limit which push events are sent to your webhook endpoint. By default, all push events are sent to your webhook endpoint. You can configure branch filtering in the webhook settings in your project.
How image URLs are displayed in the webhook body
Relative image references are rewritten to use an absolute URL in the body of a webhook. For example, if an image, merge request, comment, or wiki page includes the following image reference:
![image](/uploads/$sha/image.png)
If:
- WVS is installed at
WVS.example.io
. - The project is at
example-group/example-project
.
The reference is rewritten in the webhook body as follows:
![image](https://wvs.example.io/example-group/example-project/uploads/$sha/image.png)
Image URLs are not rewritten if:
- They already point to HTTP, HTTPS, or protocol-relative URLs.
- They use advanced Markdown features like link labels.
Events
For more information about supported events for Webhooks, go to Webhook events.
Troubleshoot webhooks
WVS records the history of each webhook request. You can view requests made in the last 2 days in the Recent events table.
To view the table:
- In your project, on the left sidebar, select Project Settings > Webhooks.
- Scroll down to the webhooks.
-
Each failing webhook has a badge listing it as:
- Failed to connect if it is misconfigured, and needs manual intervention to re-enable it.
- Fails to connect if it is temporarily disabled and will retry later.
- Select Edit for the webhook you want to view.
The table includes the following details about each request:
- HTTP status code (green for
200
-299
codes, red for the others, andinternal error
for failed deliveries) - Triggered event
- Elapsed time of the request
- Relative time for when the request was made
Each webhook event has a corresponding Details page. This page details the data that WVS sent (request headers and body) and received (response headers and body). To view the Details page, select View details for the webhook event.
To repeat the delivery with the same data, select Resend Request.
Webhook fails or multiple webhook requests are triggered
When WVS sends a webhook, it expects a response in 10 seconds by default. If the endpoint doesn’t send an HTTP response in those 10 seconds, WVS may assume the webhook failed and retry it.
If your webhooks are failing or you are receiving multiple requests,
an administrator can try changing the default timeout value
by uncommenting or adding the following setting in /etc/wvs/wvs.rb
:
wvs_rails['webhook_timeout'] = 10
Unable to get local issuer certificate
When SSL verification is enabled, you might get an error that WVS cannot verify the SSL certificate of the webhook endpoint. Typically, this error occurs because the root certificate isn’t issued by a trusted certification authority as determined by CAcert.org.
If that is not the case, consider using SSL Checker to identify faults. Missing intermediate certificates are common causes of verification failure.
Re-enable disabled webhooks
If a webhook is failing, a banner displays at the top of the edit page explaining why it is disabled, and when it will be automatically re-enabled. For example:
In the case of a failed webhook, an error banner is displayed:
To re-enable a failing or failed webhook, send a test request. If the test request succeeds, the webhook is re-enabled.