Using webhooks

This topic provides information about webhooks in the following sections:

Webhooks Overview

Webhooks allow you to build integrations into your workflows which subscribe to your workflow webhook event tasks. When a webhook event task is hit during a workflow, we’ll send an HTTP POST payload to the webhook’s configured URL that contains all the workflow variables at that point in time.

Webhooks can be configured at the organization level by an organization admin or organization owner. Once the configuration is complete, you can add webhook tasks to your workflow, and the webhook will be triggered each time the workflow is run and the webhook event is hit.

Webhook Payload

Each payload from a workflow webhook event will have a similar payload that contains a timestamp, and the workflow variables (anything with a property name that is not a document, the workflow initiator name, and the workflow initiator email) for a specific instance.

Delivery Headers

HTTP POST payloads that are delivered to your webhook’s configured URL endpoint may contain special headers.

Header Description
content-type Indicates the media type of the resource. Will always be “application/json” for these requests.
ontask-signature The HMAC hex digest of the response body. This header will be sent if the webhook is configured with a secret. The HMAC hex digest is generated using the SHA-256 hash function and the secret as the HMAC key.

Response JSON

{
     "timestamp":"2019-12-17T02:23:56+00:00",
     "wfVariables":{
          "accusoft_solutions_workflowInitiator":"test@test.com",
          "First_Name":"Joe",
          "accusoft_solutions_workflowInitiatorName":"Joe Test"
     }
}

Configuring Webhooks

To use webhooks in your OnTask workflow, the first thing you need to do is configure one in the account section. Organization owners and organization admins will be able to access the Third Party Integrations page to add a webhook connection.

To configure a webhook connection:

  1. In the Third Party Integrations page, select Webhook from the Add new integration dropdown. Webhooks require a few configuration options before you can make use of them. We’ll go through each of these settings next.
  2. Webhook Name: This is a custom name that you give your webhook connection so that you are able to identify it when adding it to a workflow.
  3. Webhook URL: This is the URL of the server that will receive the webhook POST requests. It must be configured to start with https:// or  http://.
  4. Optional Webhook Secret: Setting a webhook secret allows you to ensure that POST requests sent to the payload URL are from OnTask. When you set a secret, you’ll receive the ontask-signature header in the webhook POST request. See the section Securing Your Webhooks for more information.

Adding Webhooks To Your Workflows

To add a webhook event task to your workflow:

  1. Open the add task selector, go to the Send and Save tab, and click webhook. Everyone who has permissions to build workflows will be able to add webhook tasks.
  2. Once you add a webhook task, you will see a right side panel with configuration options.
    • If you do not have any webhook connections configured yet, depending on your permissions, you will either see a link to take you to the account section to configure one, or you will see a message that you need to contact an organization owner or administrator to configure a webhook.
    • If you do have at least one webhook connection already configured:
      1. Select the webhook connection you would like to send the request to from the dropdown menu.
      2. Use the toggle to choose whether or not to cancel a workflow on a webhook failure. When we send the POST request to a webhook URL, OnTask will try to send the data 3 times before failing the request. By default, if a failure occurs the workflow will still continue on to the next step. If you would like the workflow to fail instead and stop proceeding, switch the toggle on.
  3. Once you have those options configured, you may add any other steps to your workflow as needed before you publish and run it.

Securing Your Webhooks

Once your server is configured to receive payloads, it’ll listen for any payload sent to the endpoint you configured. For security reasons, you probably want to limit requests to those coming from OnTask. The best way to do this is to set up a secret token and validate the information.

Setting Your Secret Token

You will need to set up your secret token when you configure your webhook in OnTask, as well as on your server. When creating your secret token, we recommend using a random string with high entropy. After entering it in the webhook configuration step in OnTask, you should create an environment variable on your server that stores this token; this can be as simple as running:

export SECRET_TOKEN=your_token

We never recommend hard-coding your secret token into your app.

Validating Payloads from OnTask

When you have a secret token configured, OnTask will use it to create a hash signature with each payload. This hash signature is passed along with each request in the headers as ontask-signature. The code snippet below demonstrates a basic server listening for webhook requests with a secret configured. The goal is to compute a hash using your SECRET_TOKEN, and ensure that the hash from OnTask matches. OnTask uses a SHA-256 HMAC base64 digest to compute the hash, so you could do something like this on your server:

const express = require('express');
const crypto = require('crypto');
const app = express();
const bodyParser = require('body-parser');
const mySecret = ENV['SECRET_TOKEN'];
const createComparisonSignature = (reqBody) => {
     const hmac = crypto.createHmac('sha256', mySecret);
     return hmac.update(JSON.stringify(reqBody)).digest('base64');
}
const compareSignatures = (signature, comparisonSignature) => {
     const source = Buffer.from(signature);
     const comparison = Buffer.from(comparisonSignature);
     return crypto.timingSafeEqual(source, comparison);
}
app.post('/webhookTest', bodyParser.json(), (req, res) => {
     // Extract the OnTask Generated HMAC Signature from the incoming headers
     const signature = req.headers['ontask-signature'];
     // Generate a comparison HMAC signature locally using your secret and the incoming request body
     const comparisonSignature = createComparisonSignature(req.body);
     if (!compareSignatures(signature, comparisonSignature)) {
          return res.status(401).send('Mismatched signatures');
     } else {
          return res.sendStatus(200);
     }
});
app.listen(3000, () => console.log('Example app listening'));

Reference

Portions of this article were excerpted from https://developer.github.com/webhooks/.