Azure Event Grid and Zapier Integration

This blog post will demonstrate how to receive events from Azure Event Grid using a webhook from Zapier.

The sample code and hooks from this post can be found at https://github.com/dbarkol/event-grid-zapier.

The following image illustrates what we will be accomplishing in this post:

zapier-9-complete

Background

Event Grid subscriptions can be handled by a growing collection of Azure services (such as Function, Logic Apps, Event Hubs and many more) as well as webhooks:

functional-model

In the case of a webhook event subscription, the endpoint must prove that it can receive events by returning the validation code that is passed in from Event Grid during the registration process (see: WebHook Event Delivery).

Zapier is an integration service, similar to Logic Apps; that allows you to build workflows that can connect to a plethora of other services like Slack, MailChimp, Trello and many others.

Integration with Event Grid and other Azure services comes with first class support in regards to tooling and the validation/handshaking that occurs during the configuration of an event subscription.

Custom endpoints and 3rd party services, such as Zapier or endpoints hosted on other cloud provider, require you to support the validation step yourself.

Challenge – Returning the Validation Code with Zapier

The process of echoing back a validation code is straightforward for applications that you manage and have control over. The challenge with Zapier is that you don’t have as much control over the workflow and cannot respond back to the caller (trigger) that kicked off your application (the Event Grid topic).

To address this limitation, Event Grid now passes in another property called validationUrl that can be used to manually acknowledge the endpoint as a valid event subscription. This feature, currently in preview; will include an updated payload that is resembled below:

[{
 "id": "2d1781af-3a4c-4d7c-bd0c-e34b19da4e66",
 "topic": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
 "subject": "",
 "data": {
 "validationCode": "512d38b6-c7b8-40c8-89fe-f46f9e9622b6",
 "validationUrl": "https://rp-eastus2.eventgrid.azure.net:553/eventsubscriptions/estest/validate?id=B2E34264-7D71-453A-B5FB-B62D0FDC85EE&t=2018-04-26T20:30:54.4538837Z&apiVersion=2018-05-01-preview&token=1BNqCxBBSSE9OnNSfZM4%2b5H9zDegKMY6uJ%2fO2DFRkwQ%3d"
 },
 "eventType": "Microsoft.EventGrid.SubscriptionValidationEvent",
 "eventTime": "2018-01-25T22:12:19.4556811Z",
 "metadataVersion": "1",
 "dataVersion": "1"
}]

The addition of the new field gives endpoints an alternative for acknowledging the request from Event Grid. All they need to do now is send a GET request to the address, which could be done manually through the browser or through other means with REST clients and libraries.

Goal: The goal for this post will be to automate this process within Zapier to avoid any manual steps.

Zapier Setup

When you create a new Zap, the first thing you must configure is a trigger. In this case, we will select Webhooks:

zapier-1-trigger

We then click on the show less common link to pick the Catch Raw Hook option:

zapier-2-rawhook

The next step is where we will get the URL that will need to be copied for later use.

zapier-3-testwebhook

Once we have the Zap endpoint we then send it a sample request.

Important: We want this request to include all the details that we’ll use later within the Zap. That includes not only the body of the request but also any header values that we want to inspect and use. In regards to the body, it should include all the properties that we anticipate using later.

Our next step is to send a request to the webhook URL we just copied. I’ll use Postman since it’s a great tool for testing these scenarios. Here are the details of the request:

  • POST to https://hooks.zapier.com/hooks/catch/{{your-webhook-details}}
  • Header values
    • Content-Type : application/json
    • Aeg-Event-Type: SubscriptionValidation
  • Body
    • [{
       "id": "{{$guid}}",
       "topic": "subscription-details",
       "subject": "playlist",
       "data": {
         "validationCode": "{{$guid}}",
         "validationUrl": "some-url",
         "artist": "something goes here",
         "song": "song title"
       },
       "eventType": "songadded",
       "eventTime": "2017-12-21T23:27:12.2422068Z"
      }]

Notice that the body includes not only the validation fields we anticipate for the initial request (validationCode and validationUrl), but also the fields we want to access when we receive future notifications (artist and song). These fields will vary by publishers. I’ve chosen artist and song to show how this will work end-to-end with a custom topic (more on that later).

After the request is sent we can view what was captured in the raw hook:

zapier-4-testrawwebhook

Now comes the integration step with Event Grid. We’ll add another action to the workflow – Code:

zapier-5-code.PNG

After selecting JavaScript for the coding option. We are able to add variables (or input values) from the previous step that we could leverage in our code.

zapier-6-code-inputdata

We are interested in two values:

  • The aeg-event-type value passed into the header  – we will use this to determine if the request is a validation or notification message from Event Grid.
  • The raw body of the request – this will let us inspect the original request body.

After adding these values, the input data option should look something like this:

zapier-7-code-inputdata-complete

The final piece on the Zapier side is the bit of code that will put this all together:


var obj = JSON.parse(inputData.rawBody);
if (inputData.eventType === 'SubscriptionValidation') {
fetch(obj[0].data.validationUrl)
.then(function(res) {
return res.text();
})
.then(function(body) {
var output = {eventType: inputData.eventType};
callback(null, output);
})
.catch(callback);
} else if (inputData.eventType === 'Notification'){
var artist = obj[0].data.artist;
var song = obj[0].data.song;
var body = {"text": artist + " – " + song, "icon_emoji": ":musical_note:"};
var slackUrl = "https://hooks.slack.com/services/{{slack-key}}";
fetch(slackUrl, {
method: 'POST',
body: JSON.stringify(body),
headers:{'Content-Type':'application/json'}
})
.then(function(res) {
return res.text();
})
.then(function(body) {
var output = {eventType: inputData.eventType};
callback(null, output);
})
.catch(callback);
}

A breakdown of the code:

  • Leveraging the input values from the previous steps, we can determine the type of event (line 3).
  • We will use fetch to send a request to the validationUrl that we retrieved from the message body (lines 5-13). This will complete the validation process.
  • Notification events will retrieve values from the request body and send a message to a slack channel (lines 15-35). This could be anything but we just wanted to show how you could parse values from the body.

Zapier note: I’m currently using the Free Plan on Zapier which limits the number of actions and options to use. Otherwise, we could put together a more meaningful Zap that leverages other services and actions.

Azure Setup

Let’s put together the necessary resources on Azure to see this working end-to-end. From the Cloud Shell in the Azure portal, add the preview extension for Event Grid:

az extension add –-name eventgrid

Initialize a few variables:

rgname=zapiertest-rg
topicname=<unique-topic-name>
zapierendpoint=<your-zapier-webhook-url>

Create a resource group:

az group create -l westus2 -n $rgname

Create a custom topic:

az eventgrid topic create 
  -g $rgname 
  --name $topicname 
  -l westus2

Get the topic endpoint:

topicendpoint=$(az eventgrid topic show --name $topicname -g $rgname --query "endpoint" --output tsv)

 

Get the topic access key:

topickey=$(az eventgrid topic key list --name $topicname -g $rgname --query "key1" --output tsv)

Create the event subscription:

az eventgrid event-subscription create 
   -g $rgname 
   --topic-name $topicname 
   --name zapier-sub
   --endpoint $zapierendpoint

Almost there, let’s copy a sample body:

body=$(eval echo "'$(curl https://raw.githubusercontent.com/dbarkol/event-grid-zapier/master/newsong.json)'")

And finally, make the request to the custom topic using curl:

curl -X POST -H "aeg-sas-key: $topickey" -d "$body" $topicendpoint

The end result looks like:

zapier-8-slack

In summary, there are probably many different ways to accomplish this with Zapier. This seemed like a simple way to automate the validation process with Event Grid, which was our ultimate goal.

Reference

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s