FireHydrant enables you to create webhooks that react instantaneously to change events being created or updated. When you set up a webhook, FireHydrant sends a POST request to the endpoints you configure, and includes all of the information about the given change formatted as JSON. This article describes how to create a webhook that sends change event notifications to a HTTP endpoint.
Creating a webhook
If you are an owner of the organization, you can create webhooks. (Currently the only supported webhook is for change events, but we be adding additional resource types in the future.)
- In the left nav, click Integrations. Click the Webhooks integration card.
- On the Webhooks page, click New.
- In the Create Webhook section, enter the URL where you would like to receive notifications.
The secret is an HMAC secret that is used to sign the requests that are sent to your endpoint. It's used to create the SHA256 signature of the request payload that is sent to you. We generate a secret for you, but you are also free to enter your own. Keep this key! It will not be displayed again. - After entering your details, click Save.
That's it! All change event notifications will now be sent to the URL you entered.
Verifying Requests
It's important to verify that the requests you're receiving on your webhook URL are coming from FireHydrant. To do this, compare the signature provided in the headers of the request to an HMAC signature generated from the request body sent to you.
For example, using pseudocode, you can verify the request this way:
signature = request.headers['fh-signature']
body = request.body
secret = 'your webhook secret'
if HMAC.generate('sha256', secret, body) == signature
# request is valid
end
There are tools that are helpful for generating signatures while you develop an endpoint, such as HMAC generator.
The Payload
In a change event JSON payload, you receive 2 top-level keys: event and data. The event key contains the operation type and resource type. You can use these to determine which type of event notification you just received.
{
"data": {
"attachments": [],
"created_at": "2019-05-31T16:16:11.728Z",
"description": "",
"duration_iso8601": null,
"duration_ms": null,
"ends_at": null,
"environments": [
{
"created_at": "2019-04-17T12:00:54.620Z",
"description": "",
"id": "b73d1a05-6e6f-4e17-9c3e-2b119342c583",
"name": "Production"
}
],
"id": "489d7b90-a9d7-43d2-99be-d33c5acb59f8",
"identities": [],
"labels": {
"stack": "rails"
},
"related_changes": [],
"services": [
{
"created_at": "2019-04-17T12:00:54.772Z",
"description": "",
"functionalities": [
{
"created_at": "2019-04-17T13:38:06.631Z",
"description": "",
"id": "cf13435c-b246-4ffc-9f04-55552cca3d53",
"services": [
{
"created_at": "2019-04-17T12:00:54.772Z",
"description": "",
"id": "355411a9-bbb0-4b58-ad2c-0257d8995f9d",
"labels": {},
"name": "firehouse",
"slug": "firehouse",
"updated_at": "2019-04-17T12:00:54.772Z"
},
{
"created_at": "2019-04-17T13:38:41.625Z",
"description": "",
"id": "bd865254-aea2-4aa0-afa4-2bfb659f0252",
"labels": {},
"name": "laddertruck",
"slug": "laddertruck",
"updated_at": "2019-04-17T13:38:41.625Z"
}
],
"summary": "REST API",
"updated_at": "2019-04-17T13:38:06.631Z"
},
{
"created_at": "2019-04-17T13:39:18.147Z",
"description": "",
"id": "95db369a-186f-4245-86e1-e13dead5cd73",
"services": [
{
"created_at": "2019-04-17T12:00:54.772Z",
"description": "",
"id": "355411a9-bbb0-4b58-ad2c-0257d8995f9d",
"labels": {},
"name": "firehouse",
"slug": "firehouse",
"updated_at": "2019-04-17T12:00:54.772Z"
},
{
"created_at": "2019-04-17T13:38:41.625Z",
"description": "",
"id": "bd865254-aea2-4aa0-afa4-2bfb659f0252",
"labels": {},
"name": "laddertruck",
"slug": "laddertruck",
"updated_at": "2019-04-17T13:38:41.625Z"
}
],
"summary": "Web UI",
"updated_at": "2019-04-17T13:39:18.147Z"
}
],
"id": "355411a9-bbb0-4b58-ad2c-0257d8995f9d",
"labels": {},
"name": "firehouse",
"slug": "firehouse",
"updated_at": "2019-04-17T12:00:54.772Z"
}
],
"starts_at": "2019-06-01T00:12:12.000Z",
"summary": "Production Deploy ",
"updated_at": "2019-05-31T16:33:26.932Z"
},
"event": {
"operation": "updated",
"resource_type": "change_event"
}
}