Quickstart: Third party event routing with Hookdeck

In this quickstart, you'll learn how to use Hookdeck to integrate two third-party services. In this case, you'll receive a webhook from GitHub and trigger an SMS message using Twilio. The practices demonstrated here can be applied when integrating any number of third-party APIs and services.

Third-party to third-party message routing

You will walk through these steps:

  1. Ensure you have some prerequisites in place before you begin
  2. Set up a Connection within Hookdeck
  3. Receive a webhook from GitHub in Hookdeck
  4. Transform the GitHub webhook event payload into a Twilio SMS request payload
  5. Filter the events so that only new GitHub issues are processed
  6. Fully integrate GitHub and Twilio using Hookdeck

Before you begin

Signup for a Hookdeck account and create a Hookdeck Organization.

Get the API key from your project secrets.

Have a GitHub and Twilio account.

Create a connection

A Connection consists of a Source, optional Rules, and a Destination. It defines the flow of the webhook event, from receipt through to delivery.

From the Connections section of the Hookdeck dashboard, click the Connection button.

In the Create Connection page, under Configure a Source, enter github.

Under Configure a Destination enter the Name twilio and set the Destination Type to Mock API.

Within the Set Connection Name enter send-sms-on-new-issue.

Click the Create button to create the Connection and close the Connection Created dialog that appears by clicking the Close button.

Run the following command to create a Connection within your Hookdeck project:

curl --location 'https://api.hookdeck.com/2023-07-01/connections' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer YOUR_PROJECT_API_KEY' \
--data '{
  "name": "send-sms-on-new-issue",
  "source": {
    "name": "github"
  },
  "destination": {
    "name": "twilio",
    "url": "https://mock.hookdeck.com"
  }
}'

The cURL command creates a Connection named send-sms-on-new-issue, a Source with the name github, and a Destination with the name twilio and url with the value https://mock.hookdeck.com.

The response will be formatted as follows:

{
  "id": "web_oPymMJ0isyuS",
  "team_id": "tm_SAN9hnAiGLbI",
  "disabled_at": null,
  "updated_at": "2023-11-18T16:52:43.897Z",
  "created_at": "2023-11-18T16:52:44.096Z",
  "paused_at": null,
  "name": "send-sms-on-new-issue",
  "rules": [],
  "description": null,
  "destination": {
    "id": "des_wNYxQXpkYHcM",
    "team_id": "tm_SAN9hnAiGLbI",
    "url": "https://mock.hookdeck.com",
    "disabled_at": null,
    "updated_at": "2023-11-18T16:52:43.897Z",
    "created_at": "2023-11-18T16:52:43.903Z",
    "rate_limit": null,
    "rate_limit_period": "second",
    "cli_path": null,
    "path_forwarding_disabled": false,
    "name": "twilio",
    "http_method": null,
    "auth_method": { "type": "HOOKDECK_SIGNATURE", "config": {} },
    "description": null
  },
  "source": {
    "id": "src_KUdNgMByl0uP",
    "team_id": "tm_SAN9hnAiGLbI",
    "disabled_at": null,
    "updated_at": "2023-11-18T16:52:43.897Z",
    "created_at": "2023-11-18T16:52:43.905Z",
    "name": "github",
    "allowed_http_methods": ["POST", "PUT", "PATCH", "DELETE"],
    "custom_response": null,
    "description": null,
    "url": "{YOUR_SOURCE_URL}",
    "verification": null
  },
  "full_name": "github -> send-sms-on-new-issue"
}

The cURL command has created a connection. The source.url value is the URL used to send webhooks. The destination.url value is the URL where Hookdeck will deliver the webhook event payloads to. In the cURL request, you set the Destination URL to https://mock.hookdeck.com, which is a destination you can use for testing that receives the HTTP request and returns a 200 response.

Open the Connections section for your project in the Hookdeck dashboard to see the visual representation of the connection you created.

Third-party integration connection within the Hookdeck dashboard

Receive a webhook from GitHub in Hookdeck

The Source URL should receive a webhook from GitHub whenever any event related to a GitHub issue for a repo occurs.

To set up a webhook in GitHub, head to a GitHub repository, click on Settings, then Webhooks, and then click the Add webhook button.

Enter the Hookdeck Source URL from the previous step for the Payload URL and select application/json from the Content type dropdown.

GitHub webhook setup

In the vast majority of situations you should also set a secret used to verify your webhook payload. Hookdeck provides in-built support for webhook signature verification. However, for the purposes of this quickstart, you can skip this step.

Ensure that only the Issues checkbox is checked.

GitHub webhook issues checkbox

Click the Add webhook button to save the webhook.

GitHub add webhook button

With the webhook configured, you can test it by creating a new issue in the GitHub repository.

Click on the Issues tab in the GitHub repository and click the New issue button. Enter a title and description for the issue and click the Submit new issue button.

Create a new GitHub issue

The webhook event will be sent to Hookdeck.

Open the Requests section of Hookdeck dashboard to see the request within the UI.

Requests within the Hookdeck Dashboard

Next, open the Events section of the Hookeck dashboard. Click on the Event to expand the section to see the Attempts made to deliver the event to a webhook endpoint.

Events within the Hookdeck Dashboard

You will see the event with the GitHub webhook payload, including the action of opened and the issue details.

Transform the GitHub webhook event payload

In this next step, you will transform the GitHub webhook event payload into a Twilio SMS request payload using Hookdeck transformations.

From the Connection section, click on the send-sms-on-new-issue connection and then click Transform + and Create new trasformation.

This opens the New Transformations page. Within this page you can see:

  • Input - the payload and metadata for the input request
  • Output - the payload and metadata from the result of the transformation
  • Diff - the difference between the input and output payloads
  • Code editor - the code used to transform the input payload into the output payload
  • Console - the console output from the transformation code

Update the transformation code in the code editor to the following:

const TWILIO_ACCOUNT_SID = process.env.TWILIO_ACCOUNT_SID;
const FROM_NUMBER = process.env.FROM_NUMBER;
const TO_NUMBER = process.env.TO_NUMBER;

addHandler('transform', (request, context) => {
  request.headers['content-type'] = 'application/x-www-form-urlencoded';

  // URL set in destination:
  // https://api.twilio.com/2010-04-01/Accounts/
  request.path = `/${TWILIO_ACCOUNT_SID}/Messages.json`;

  request.body = {
    From: FROM_NUMBER,
    To: TO_NUMBER,
    Body: 'New issue created\n' +
    request.body.issue.title + '\n\n' +
    request.body.issue.html_url
  };

  return request;
});

To transform the GitHub webhook event payload into a Twilio SMS request payload, the transformation code does the following:

  1. Change the Content-Type header from application/json to application/x-www-form-urlencoded
  2. Update the destination path for the Twilio API to include the Twilio Account SID
  3. Build the request body to contain the From, To, and Body parameters

You'll noticed that this code using environment variables that haven't yet been set. Add them now using the Variables button at the top right of the code editor:

  • TWILIO_ACCOUNT_SID - your Twilio Account SID
  • FROM_NUMBER - the Twilio phone number you want to send the SMS from
  • TO_NUMBER - the phone number you want to send the SMS to

Click the Change Input button to ensure that the payload from a previous GitHub webhook event ({ "action": "opened" }) is used as the input payload, and click the Run button to test the transformation.

You will see the updated event payload in the Output section.

Hookdeck Transformation from GitHub webhook to Twilio send SMS API call

Click the Confirm, enter github-to-twilio-sms-payload when prompted, click Confirm in the dialog, and then Save.

Filter the events for new GitHub issues only

As things stand, this will send an SMS message for every GitHub issue event. However, you only want to send an SMS message when a new issue is created.

Go back into the transformation and if the action is not opened, return the request untouched. You will filter out in the next part of the process.

From the Connection section, click on the send-sms-on-new-issue connection, click Editor next to the github-to-twilio-sms-payload transformation.

Update the transformation code in the code editor to the following:

const TWILIO_ACCOUNT_SID = process.env.TWILIO_ACCOUNT_SID;
const FROM_NUMBER = process.env.FROM_NUMBER;
const TO_NUMBER = process.env.TO_NUMBER;

addHandler('transform', (request, context) => {
  if(request.body.action !== 'opened') {
    return request;
  }
  
  request.headers['content-type'] = 'application/x-www-form-urlencoded';

  // URL set in destination:
  // https://api.twilio.com/2010-04-01/Accounts/
  request.path = `/${TWILIO_ACCOUNT_SID}/Messages.json`;

  request.body = {
    From: FROM_NUMBER,
    To: TO_NUMBER,
    Body: 'New issue created\n' +
      request.body.issue.title + '\n\n' +
      request.body.issue.html_url
  };

  return request;
});

You can manually test this works by ensuring a GitHub webhook is set as the input by selecting a request via the Change Input and then editing the action to not be opened and clicking the Run button. You will see the transformation to the Twilio SMS API payload does not occur.

With the transformation update in place to detect the action type, you can now create a filter rule to filter out GitHub events.

From the Connection section, click on the send-sms-on-new-issue connection, click Filter + and then click Editor to open the filter editor.

Update the filter code in the code editor to the following to ensure the action property does not exist:

{
  "action": {
    "$exist": false
  }
}

Try different payloads using the Change Input button and test the filter using Test Filter.

GitHub webhook filtering syntax

Click Confirm and then Save.

Fully integrate GitHub and Twilio using Hookdeck

The Hookdeck connection now transforms the GitHub webhook event payload into a Twilio SMS request payload and filters out any GitHub events that are not opened issues.

The final steps are to update the Destination URL to point to the Twilio API endpoint, and set your Twilio API credentials.

From the Connection section, click on the twilio Destination and click Open Destination.

Scroll down to the Destination Configuration section and update the Destination Type to HTTP and the URL https://api.twilio.com/2010-04-01/Accounts/.

Remember that the transformation appends the Twilio Account SID to the Destination URL via the request.path property.

Change the Authentication to Basic Auth and enter your Twilio Account SID as the Username and your Twilio Auth Token as the Password.

Click Save

Twilio SMS API Destination URL and credentials

Create a new GitHub issue to test the integration. The phone with the defined TO_NUMBER should receive an SMS message.

As before, you can check this in both the Hookdeck dashboard Requests and Events sections.

What you have learned

By following this quickstart, you set up a Connection with Hookdeck and tested receiving webhooks from GitHub with Hookdeck with the requests sent to the Hookdeck Mock API endpoint.

You then used a Hookdeck transformation to transform the GitHub webhook event payload into a Twilio SMS request payload, including updating the request.path to include the Twilio Account SID.

You also used a Hookdeck filter to filter out GitHub events that are not opened issues.

Finally, you updated the Destination URL to point to the Twilio API endpoint, making use of Hookdeck's in-built support for customized destination auth, to complete the GitHub and Twilio integration using Hookdeck.

Where next?

You've just scratched the surface of Hookdeck. So, try out the following features:

  • Authenticate the sending of webhooks by adding source authentication.
  • Set up a rate limit on your Destination to adhere to the API rate limit of the destination provider's API.
  • Define your retry logic for those occasions when there are problems with the destination's API.
  • Create a second connection that uses the same source to integrate with another third-party service. For example, logging GitHub issues to a database.