Webhooks make it possible to connect the EMS to hundreds of other apps and use logic to perform multi-step workflows. The Webhooks feature can be accessed by EMS administrators. In this article, we'll guide you through the creation of a Webhook that gets data from the EMS and puts it in a Google Sheet—but you can use Webhooks to connect to other apps and do other things, too.
To start, find the Webhooks option under Manage Team in your sidebar.
You'll wind up on the Webhooks page:
Select New Rule on the far right to add a webhook. As you can see in the following image, you will have the option to choose from a list of 6 events for which you’d like to be notified: A new response, vote, or person added, and/or any corresponding updates to those features.
(A new response is created when someone makes a submission. A new vote is created when someone votes in a poll. A new person is added when someone fills out a new unique email address in one of your embeds. A response update occurs when an EMS user in your organization edits a response. A vote update occurs when a person who just voted adds their email address after voting. A person update occurs when an EMS user in your organization edits a person's record within the EMS.)
In the Receiving URL field, you should enter the webhook URL supplied by the application you are linking with. We generally recommend Zapier to generate a link to the specific app you would like because it is relatively easy to use and connects to a wide variety of other apps. (Some apps, like Slack, have built-in webhooks support. The data format these apps expect vary wildly and might not match what the EMS sends. An intermediary service like Zapier can be used to transform the data format to be compatible with our Hearken EMS server.)
To get your Receiving URL in Zapier, start creating a Webhook with the app you want to connect and select "Catch Hook" as the trigger and "Create Spreadsheet Row(s)" as the action. Do not select "Catch Raw Hook"!
Then click "Continue" and get your Webhook URL. This is the Receiving URL you want to paste in your EMS Webhook:
For this example, we'll use "New Response" as a trigger. Click "Save" to save it in the EMS. We'll finish the rest in Zapier.
Zapier will ask you to test your trigger. In our case, the trigger is a new response. Submit a test response on any of your forms, then click "Test trigger."
You should see something like this if it worked:
Click "Continue" to complete the step of connecting the Webhook to the EMS.
Create a Google Sheet and create column headers for each field you want to pull from the EMS. You can name the headers whatever you want and as as many as you want, but there has to be text there for Zapier to place the data in the correct column. Here are the ones I'll use, purely as examples.
Once you have picked out your columns, connect to the spreadsheet and worksheet within it you want to use (you'll need to connect Google Drive to Zapier to do this) and link the columns with the properties you want to use:
From there you can test the Zap to see if it works as you intended:
Here is the Zap I made depositing the data from the form submission into the Google Sheet:
Yay!
When a response or action successfully triggers the webhook, a check mark will show up at the far right of the EMS Webhooks page, and you will also be able to click through the response to see the source response of each notification. Similarly, if a Webhook URL is incorrect or there is otherwise an error, the action will display an error:
Here is a sample format of the JavaScript Object Notation (JSON) of each action at the site of your URL-generator, which you will be able to see after each successful run of your webhooks:
Webhook response structure
The data sent with each webhook will follow this structure (see below for term definitions):
{
"_event": {string},
"_type": {string},
"id": {integer},
"retry_count": {integer},
"_created_at": {milliseconds since UNIX epoch},
"organization": {
"_type": "organization",
"created_at": {milliseconds since UNIX epoch},
"updated_at": {milliseconds since UNIX epoch},
"id": {integer},
"name": {string},
"slug": {string}
},
"payload": {object}
}
_event: The name of the event that triggered the webhook. Eg: updated_question
_type: The class or type of the object in the webhook payload, Eg: question_webhook
id: A numerical id associated with the webhook
created_at: Unix timestamp in milliseconds for when the webhook run is created
_retry_count: An integer starting at 0 indicating the number of attempts made to deliver this webhook. Unless specified otherwise, every webhook makes 3 attempts to deliver the information.
organization: The organization object
id: Numerical id of the organization
created_at: Unix timestamp in milliseconds for when the organization was created
updated_at: Unix timestamp in milliseconds for when the organization was last updated
name: The name of the organization
slug: An alphanumeric string that serves as an unique identifier for the organization
payload: Information about the specific object that triggered the webhook. The format varies based on the type
Example: This is what an updated response webhook looks like
{
"_event": "updated_question",
"_type": "question_webhook",
"_created_at": 1600811238426,
"id": 71338,
"_retry_count": 0,
"organization": {
"_type": "organization",
"created_at": 1518725427802,
"updated_at": 1578356143203,
"id": 322,
"name": "Example",
"slug": "example"
},
"payload": {
"_type": "question",
"created_at": 1598529395806,
"updated_at": 1600811238358,
"question_status": {
"_type": "question_status",
"created_at": 1518725427965,
"updated_at": 1518725427965,
"id": 548,
"name": "New"
},
"lists": {
"_type": "collection",
"total_objects": 1,
"offset": 0,
"limit": 10,
"data": [{
"_type": "list",
"created_at": 1598528086790,
"updated_at": 1598528086790,
"id": 8821,
"name": "City Development in the Future",
"question_count": 1
}]
},
"answers": {
"_type": "collection",
"total_objects": 0,
"offset": 0,
"limit": 10,
"data": []
},
"id": 1003023,
"prompt": "What will happen to the design of cities in the future? How does your perfect City of the Future look?",
"embed_name": "City Development in the Future",
"opt_in_response": true,
"anonymous": false,
"display_text": "Are we going to be using flying cars?",
"original_text": "Are we going to be using flying cars?",
"approved": false,
"deleted": false,
"postcode": null,
"source_url": "https://ems.wearehearken.com/",
"reporter": null,
"notes": null,
"hidden": false,
"quarantined": false,
"source": "prompt_embed:6328",
"custom_fields": [{
"name": "Postal code (optional)",
"type": "string",
"value": "5000"
}],
"organization_audience_member": {
"id": 690566,
"email": "ex@examplemail.com",
"_type": "organization_audience_member",
"name": "Example"
},
"assigned_to_user": "Kavya Sukumar"
}
}