Using Rest Hooks

What are REST Hooks#

According to resthooks.org:

REST Hooks are a collection of patterns that treat webhooks like subscriptions. These subscriptions are manipulated via a REST API just like any other resource.

To comply with the REST Hooks pattern, you will need:

  1. A mechanism to store subscriptions
  2. A mechanism to modify subscriptions via API
  3. To list and implement event types
  4. A mechanism to send hooks

Further technical details on how to implement this can be found here.

Are you using them already?#

You are most likely to have implemented the REST Hooks pattern if you have a recently built Zapier integration. You may also already have REST Hooks functionality if your product offers webhooks and a way to manage webhook subcribtions via a REST API.

How to send Trigger events to Rollout via REST Hooks#

There are two ways to configure Rollout to subscribe/unsubscribe to your webhooks using REST Hooks:

  1. Using the UI to set up the request
  2. Writing the code that Rollout should execute to make the request

Using the User Interface (UI Mode)#

Configure how Rollout should both subscribe and unsubscribe to webhooks. For both operations, you can use the designated configuration box and follow these instructions:

  1. Select an HTTP method from the dropdown (e.g. POST)
  2. Enter a request url where Rollout should send webhook subscription requests to (e.g. https://yourapi.com/subscribe)
  3. Configure key value pairs for:
    • Params
    • Headers
    • Body (πŸ’‘ Unavailable for GET and HEAD methods)
  4. Configure options for:
    • Omitting empty parameters
    • Omitting empty body fields

Writing code that Rollout should execute (Code Mode)#

It is also possible to write the code that Rollout should execute to subscribe/unsubscribe to webhooks. This is reffered to as Code Mode in the product and it allows for a greater degree of control over each request. For example, if you require HMAC authentication against the configured endpoint, you'll be able to set it up here.

πŸ’‘ The first time the UI mode is switched to code mode, any current UI configurations will be parsed to code. Once saved, any subsequent switches from UI Mode to Code mode will not override any additional code changes you make. Likewise, any code updates made will not affect UI configuration settings.

Perform functions#

The perform function is executed every time Rollout receives a webhook request, making it an ideal place to perform any data transformations or implementing custom logic. (e.g. HMAC authentication).

Your code will have access to the following objects, which provide useful data and functions:

  • utils
  • context
  • env

You can find detailed info of what each object holds and backwards compatibility with Zapier here.

πŸ’‘ When executing the perform code in a webhook request, the return value of the perform function can be one of:

β€’ A single object which corresponds to 1 event: {...}
β€’ An array with n number of event payloads: [{...}, {...}]
β€’ An empty array which maps to no events and therefore skips the relevant action: []

Default return value:

return utils.flattenTriggerPayload(context.request.body);

Example of a Data Transformation:

const { body } = context.request;
const mappedPayload = {
taskName: body.task_name,
};
return mappedPayload;

Example of a skipped Action in a Webhook invocation:

const { body } = context.request;
const { trigger } = context.automation;
// Skip if user selected property !== incoming server value
// Useful when filtering automation execution at runtime
if (trigger.inputParams.propertyA !== body.propertyA) {
return [];
}
return utils.flattenTriggerPayload(body);

Example of HMAC Authentication:

const hmac = context.request.headers.authorization;
const { public_key, payload } = context.request.body;
const hmacToCompare = utils.crypto
.createHmac("sha256", env.HMAC_SECRET)
.update(payload)
.digest("hex");
if (hmacToCompare != hmac) {
throw new Error("Unauthorized");
}
const mappedPayload = {
taskName: payload.task_name,
};
return mappedPayload;