Automation 101: Part 2 — Create your first Webhook
Introduction
Welcome to part two in our Automation 101 series! In part one, we covered the options available to builders on the Skedulo Pulse Platform and today we’re going to take a deep dive into the first one: webhooks!
Let’s begin by understanding what a webhook is and what it does. Put simply, a webhook is a piece of configuration that tells the Pulse Platform to make a call out to a web service when something changes. This change could be the creation, update, or deletion of a record, or it could be an incoming SMS.
The web service that can be called could either be internal or external to the Pulse platform (e.g, a connected function, or a third party system of record).
In the webhook configuration, you can define what criteria must be met in order for the webhook to be fired, upon what record event it is fired (e.g update, insert, delete) and what data to include.
We can consider this example:
You have a webhook on the Job object, which is configured to run every time a job is updated and if the Job Status changes to “Dispatched” from any other value.
This webhook makes a call to a Skedulo connected function (more on these in an upcoming part of this series), which receives the job information as well as the related customer information, and sends an SMS to the customer informing them that the Job has been dispatched.
Creating an Object Triggered Webhook
Now that we know what they are for, let’s step through the process for creating one, beginning with an object triggered webhook.
A webhook can be created for any standard or custom object that is tracked. In this example we will use a custom object and first configure tracking.
You can do this using any method you’d like (such as an API client, or from within some code) but be sure to have an authentication token configured.
Enable tracking
The first thing we need to do is get the ID of the object we want to track. This can be done by making a GET
request to https://api.skedulo.com/custom/schemas
The GET
request will return information about all of your objects, so simply find the one you wish to use (e.g MyCustomObject
) and grab its id
.
Next, we need to enable tracking by making a POST
request (with no body) to https://api.skedulo.com/custom/standalone/schema/
/track (replacing <object id>
with the id
from the first step).
Once that’s done, we can go ahead and create our webhook.
Create the webhook
To create the webhook itself, we need to POST
a webhook configuration to https://api.skedulo.com/webhooks
.
Let’s take a look at the configuration to better understand it:
{
"name": "My Webhook",
"url": "https://path.to/my/endpoint",
"headers": {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
"type": "graphql",
"operation": ["INSERT","UPDATE"],
"query": "subscription {
schemaCustomExternalObject {
operation
timestamp
data {
UID
Name
ExternalId
CreatedDate
LastModifiedDate
}
previous {
UID
Name
ExternalId
CreatedDate
LastModifiedDate
}
}
}"
}
We need to give our webhook a name
, make sure it’s descriptive. This will help when there are multiple webhooks in your Skedulo tenant.
The url
is, as you may have guessed, the URL to call when the webhook fires.
If we need to provide certain headers, such as for authentication, we can do so with the headers
object. We simply provide each key and value within it, as per the above example.
If you want to experiment with webhooks, you can use a service like ngrok and a simple express server for this. For more information, check out the developer documentation here.
The type
, in the case of object trigger is “graphql
” .
The operation
field is optional. It is an array of operations (INSERT
, UPDATE
, or DELETE
) and allows us to choose when our webhook runs (e.g only on INSERT by setting it to [“INSERT
”]).
Finally, we have the query
. This is how we tell Skedulo which object to monitor and which data to provide to the web service that the webhook calls. Because this is just a GraphQL query, we can use filters and also return data from other related objects.
Once we’ve finished our webhook configuration and pushed it to Skedulo, we will receive a response like the following:
{
"result":{
"id": "9849cceb-c426-488b-89dc-6ff02b33802d",
"name": "test",
"url": "https://b14b2804.ngrok.io",
"headers": {},
"query": "\n subscription {\n schemaJobs {\n operation\n timestamp\n data {\n UID\n Duration\n }\n previous {\n Duration\n }\n }\n }\n ",
"customFields": {},
"type": "graphql"
}
}
Based on the query we’ve configured, whenever we make a change in Skedulo, our web service will receive a POST
request like the following:
"data": {
"schemaJobs": {
"data": {
"UID": "00145d1e-974a-4f97-9cd7-7cd280f824a8",
"Duration": 60
},
"previous": {
"Duration": 60
},
"operation": "INSERT",
"timestamp": "2019-07-02T03:29:35.969Z"
}
}
}
As you can see, this will contain data based on the query we specified. We can then use this in our web service to facilitate our business process automation.
SMS triggered webhook
The other main functionality where webhooks can be used is to respond to incoming SMS messages. This allows us to perform automated actions based on an incoming message. For example we could have an SMS sent to a customer asking them to confirm their Job by asking them to reply with “CONFIRM”.
We could then use a webhook to call a connected function to handle the response to this message and update the Job accordingly.
In order to create an SMS triggered webhook, the process is much the same as an Object triggered one, however we don’t need to enable tracking, nor do we need a GraphQL query.
We simply need to POST
a webhook configuration, like the following, to: https://api.skedulo.com/webhooks
{
"name": "Inbound SMS Webhook",
"url": "https://path.to/my/endpoint",
"type": "inbound_sms"
}
The name and url field are as in the previous example, and the type
field is now set to “inbound_sms
” .
When this webhook is triggered, we will receive a POST
request to our web service like the following:
{
"key": {
"id": "message_sid_001",
"vendor": "twilio"
},
"to": "+61411123456",
"from": "+61411222333",
"body": "CONFIRM",
"receivedAt": "2019-09-24T05:57:49.323Z"
}
As you can see, we get the number the SMS was sent to, who it was from, the content of the message, and a timestamp of when it was received.
We can then use this information in our connected function, or external web service, to update the Job (as per our example) or perform any other automation required.
Scheduled and Deferred Webhooks
Both of the previous examples will be run as soon as either the record changes, or the SMS arrives. But what if we want to defer this for a period of time? Or do we want to run a webhook on a schedule?
Well, we can do both of these things! Let’s begin with deferred webhooks.
Deferred Webhooks
We can defer a webhook in two ways: either by a fixed value (e.g, always run it 60s after a record has changed) or a by dynamic value (e.g, based on the value of a field).
Here’s an example of a webhook configuration that is always deferred by 60s:
{
"name": "My Webhook",
"url": "https://path.to/my/endpoint",
"type": "deferred_graphql",
"operation": ["INSERT","UPDATE"],
"offset": 60000
"field": "LastModifiedDate"
"query": "subscription { ..." //full query here
}
As you can see, we simply need to change the type
to be “deferred_graphql
” and add an offset
field with a value of time in milliseconds by which we want to defer the webhook.
We also need to specify a field to calculate our deferred time from. In this case, it’s when the record was last modified. This field has to be a Date/Time (instant
) field. In this example, the webhook would fire 60 seconds after the record was last modified.
The other option we have is to dynamically defer a webhook. That is, use the value from a field to determine how long we defer it by. This field has to be of the integer data type.
This is largely the same as a normal deferred webhook (as above), however, rather than specify a numeric value for offset, we give it a field and a default value (in case the field is empty).
For example:
{
"offset":{
"fieldName": "CustomNumber",
"default": 15000
}
}
This would defer the webhook for the value in the CustomNumber
field (in milliseconds) and if that field was blank, it would be deferred by 15 seconds.
Scheduled Webhooks
Finally, we are able to run a webhook on a schedule (aka. A cron job). These webhooks use a standard cron expression to determine when they are executed.
For example, a cron expression of “30 8 * * 1
” would run every Monday at 8am. You can use a tool like crontab.guru to help you better understand cron expressions.
As normal, we need to provide a name
, a url
and a type
. The type
in this case is “scheduled
”. We also need to provide a cron
expression to tell Skedulo how often to run the webhook:
{
"name": "Runs every minute",
"url": "https://path.to/my/endpoint",
"headers": {},
"cron": "* * * * *",
"type": "scheduled"
}
We can then provide a query that will be executed each time the webhook runs and POST the data to the web service it calls.
CAUTION: Be careful with your query and cron expression here, as it could result in large volumes of data being queried or sent to your web service.
You could use a scheduled webhook if, for example, you needed to get all of the Jobs in a given status for each day and send them to a connected function or external system.
Conclusion
I hope you now have a better understanding of webhooks and how you can use them to automate processes. In the next part, we will be covering webhooks’ sibling, triggered actions, as well as when to use one or the other.
We will then cover connected functions and, finally, an example of how you can put all of these features together to build end-to-end automation on the Skedulo Pulse Platform!
If you can’t wait, you can always check out the documentation on automation on our shiny new docs site.
As always, we’d love to hear about what you’re building so please reach out to us on Twitter @SkeduloDevs or LinkedIn!