Using webhooks, you can build things that can react to change events being created or updated in FireHydrant the moment it happens. FireHydrant sends a POST request to the endpoints you configure and includes all of the information about the given change formatted as JSON. In this article we'll learn how to create a webhook that sends change event notifications to a HTTP endpoint.

Creating The Webhook

If you are an owner of the organization, you have the ability to create webhooks for change events. Currently the only supported webhook is for change events, but this will change in the future to support other resources type in FireHydrant.

On the left navigation, click "Organization", and then "Webhooks".

Once on this page, click "New" on the top right of the page.

On this page, enter in the HTTP endpoint you would like to receive notifications on. If you are just trying to test webhooks, a great request capturing tool is webhooks.site. The secret is an HMAC secret that is used to sign the requests that are sent to your endpoint. It's used to create SHA256 signature of the request payload that is sent to you. We generate a secret for you, but you are free to enter in your own as well. Keep this key, it will not be displayed again.

After you've entered in your details, click "Save".

That's it! All change event notifications will now be sent to the endpoint you entered in. You can disable webhooks for the endpoint by editing it and selecting "inactive" from the dropdown too.

Verifying Requests

It's important that you verify the requests you're receiving on your webhook endpoint are coming from FireHydrant. To do this, you can verifying the signature provided in the headers of the request against an HMAC signature generated from the request body sent to you.

Using pseudocode, you can verify the request by doing something along these lines:

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 your endpoint, a nice and easy to use one is https://www.freeformatter.com/hmac-generator.html

The Payload

For a change event payload, you'll receive 2 top-level JSON keys, "event" and "data". The event key will contain the operation type and resource type. You can use these to determine which type of event 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"
  }
}

Did this answer your question?