Create a webhook
Overview
Webhooks are used to notify other applications of specific events or changes that occur in your Skedulo application in real-time.
You can use the Skedulo API or Skedulo CLI to establish webhooks between the Skedulo application and your secure HTTPS API to implement specific event reactions. For example, your application may need to be notified every time a new job is created, every time a job is updated with resource information, or every time a job status changes from Queued
to Dispatched
.
Skedulo also supports deferred webhooks and filtering, which means that you can configure your webhooks to fire if an object has a field equal to a specified value after a set period of time. For example, you can configure a webhook to send a notification if the status of a job has not been changed to Pending Dispatch
within 24 hours of the job creation time.
This chapter demonstrates how to set up webhooks for Skedulo using the Skedulo API and ngrok, which is a useful tool for locally testing and viewing webhook responses.
About ngrok
For development purposes, this chapter uses ngrok to establish a secure HTTP tunnel to a server running on your local machine.
Skedulo only permits HTTPS URLs for webhooks.
Prerequisites
-
You must have an API user configured in your Skedulo organization. See Skedulo API user for more information.
-
You have a valid API access token and have configured this as an environment variable. This example uses
$AUTH_TOKEN
to represent the API authentication environment variable. -
Node/NPM is installed.
-
(Optional) jq is installed.
This example uses
.json
files executed using cURL commands for readability and simpler query creation -
Tracking must be enabled on custom objects that the webhook uses. Tracking is automatically enabled on most standard objects, and all custom objects created after 10 May 2024. Objects created prior to this date will need to have tracking manually enabled. Additionally, Skedulo for Salesforce teams require additional configuration within Salesforce.
Enable tracking on a custom object
To manually enable tracking on an object, do the following steps.
-
Find the
objectId
of the custom object by making the following request:curl --location --request POST “https://api.skedulo.com/custom/schemas” --header "Authorization: Bearer <token>"
-
Pass the
objectId
to this endpoint:curl --location --request POST "https://api.skedulo.com/custom/standalone/schema/{objectId}/track" --header "Authorization: Bearer <token>"
Create & test a webhook
Setup
-
Create and open a
webhooks
folder from the terminal:mkdir webhooks && cd webhooks
-
Download and install ngrok in the
webhooks
folder:a. Go to https://ngrok.com/ and click Download.
b. Download the version of ngrok for your operating system.
c. Unzip ngrok into the
/webhooks
folder. -
Create a file called
httpserver.js
with the following configuration:const http = require("http"); http.createServer((req, res) => { const body = []; req .on('data', (chunk) => { body.push(chunk); }) .on('end', () => { const bodyStr = Buffer.concat(body).toString(); const obj = { headers: req.headers, body: JSON.parse(bodyStr) } console.log(JSON.stringify(obj, null, 2)) res.write(JSON.stringify(obj, null, 2)) res.end() }); res.writeHead(200, {"Content-Type": "application/json"}) }).listen(8080)
-
Start the HTTP server in one terminal:
node httpserver.js
-
Start ngrok in another terminal:
./ngrok http 8080
Take note of the HTTPS address of your ngrok server. For example:
https://b14b2804.ngrok.io
Create the webhook
Via the API
-
In another terminal, create a file called
webhook.js
.This is just so you can create your queries in a readable way. It’s not necessary if you want to just send your JSON queries using a cURL command.
Add the following content to your
webhook.js
file, using the HTTPS ngrok server address as theurl
.const url = "https://b14b2804.ngrok.io" const json = { name: "test", url: url, type: "graphql", query: ` subscription { schemaJobs { operation timestamp data { UID Duration } previous { Duration } } } ` } console.log(JSON.stringify(json, null, 2))
- One of the fields in the
data
block needs to change to call the webhook. In this case, this includesUID
andDuration
. - The
schemaJobs
field also acceptsfilter
andextendedFilter
parameters. - The
operation
parameter can be used to ignore events that do not have the operation value. Theoperation
parameter accepts an array of values:INSERT
,UPDATE
orDELETE
.
- One of the fields in the
-
Create a webhook request body:
node webhook.js > temp.json
-
Create a
POST
request to the Skedulo API that references thetemp.json
file containing the GraphQL subscription request:curl -s -X POST -H "Authorization: Bearer $AUTH_TOKEN" -H "Content-Type: application/json" -d @temp.json 'https://api.skedulo.com/webhooks' | jq
This returns the following response in the terminal:
{ "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" } }
Via the CLI
-
In another terminal, create a file called
webhook.js
. This is just so you can create your webhook queries in a readable way.Add the following content to your
webhook.js
file, using the ngrok server address as theurl
.const url = "https://b14b2804.ngrok.io" const json = { metadata: { type: "Webhook" }, name: "my-webhook", webhook: { url: url, type: "graphql", query: ` subscription { schemaJobs { operation timestamp data { UID Duration } previous { Duration } } } ` } } console.log(JSON.stringify(json, null, 2))
- One of the fields in the
data
block needs to change to call the webhook. In this case, this includesUID
andDuration
. - The
schemaJobs
field also acceptsfilter
andextendedFilter
parameters. - The
operation
parameter can be used to ignore events that do not have the operation value. Theoperation
parameter accepts an array of values:INSERT
,UPDATE
orDELETE
.
- One of the fields in the
-
Create a webhook state file:
node webhook.js > my-webhook.webhook.json
-
Run the following command to create the webhook from the state file:
sked artifacts webhook upsert -f my-webhook.webhook.json
Test the webhook
-
Create a new job using a GraphQL query.
The following response should appear in the terminal window that is listening on port
8080
:{ "headers": { "user-agent": "Skedulo-Webhook", "skedulo-webhook-id": "9849cceb-c426-488b-89dc-6ff02b33802d", "skedulo-request-id": "317cc297-c9cb-41e5-a741-366b3724cb8e", "content-length": "182", "content-type": "application/json; charset=UTF-8", "accept-encoding": "gzip, deflate", "host": "b14b2804.ngrok.io", "accept": "*/*", "x-forwarded-proto": "https", "x-forwarded-for": "34.215.60.60" }, "body": [ { "data": { "schemaJobs": { "data": { "UID": "00145d1e-974a-4f97-9cd7-7cd280f824a8", "Duration": 60 }, "previous": { "Duration": 60 }, "operation": "INSERT", "timestamp": "2019-07-02T03:29:35.969Z" } } } ] }
You can also view the webhook trigger request responses in the local ngrok web interface.
-
Update a job to change the
Duration
to30
. The response displays in the terminal:{ "headers": { "user-agent": "Skedulo-Webhook", "skedulo-webhook-id": "9849cceb-c426-488b-89dc-6ff02b33802d", "skedulo-request-id": "fdf22ac0-b6d5-4453-9bfa-9735c7e2cdde", "content-length": "182", "content-type": "application/json; charset=UTF-8", "accept-encoding": "gzip, deflate", "host": "b14b2804.ngrok.io", "accept": "*/*", "x-forwarded-proto": "https", "x-forwarded-for": "34.215.60.60" }, "body": [ { "data": { "schemaJobs": { "data": { "UID": "00145d1e-974a-4f97-9cd7-7cd280f824a8", "Duration": 30 }, "previous": { "Duration": 60 }, "operation": "UPDATE", "timestamp": "2019-07-02T03:31:27.970Z" } } } ] }
-
A record of the HTTP request appears in the terminal tab that is running ngrok:
The ngrok web interface also shows both of the operations and responses:
Use configuration variables in webhooks
To make webhooks more portable, they can make use of configuration variable templates.
Templates are formatted as {{ CONFIG_VAR_NAME }}
and are supported on these webhook fields:
url
headers
Example:
{
"type": "graphql",
"query": "subscription { schemaJobs { operation timestamp data { Description }}}",
"name": "job-webhook",
"url": "{{ JOB_CHANGED_URL }}",
"headers": {
"X-Demo": "{{ JOB_CHANGED_HEADER }}"
}
}
When the webhook is triggered, the templates will resolve to the values of the configuration variables. If any of the configuration variables are not found, then the webhook will fail.
Retrieve webhooks
Via the API
You can retrieve webhooks that are currently set up for your tenancy using the following cURL command:
curl -s -X GET -H "Authorization: Bearer $AUTH_TOKEN" https://api.skedulo.com/webhooks
Because I still have both the test
and test_deferred
webhooks active, the response returns both webhooks:
{
"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"
},
{
"id": "6b6d32e0-ad1f-45fa-9f03-b5264ca02ecb",
"name": "test_deferred",
"url": "https://b14b2804.ngrok.io",
"headers": {},
"schemaName": "Jobs",
"fieldName": "CreatedDate",
"offset": 10000,
"filter": "Description != 'cancel'",
"query": "\n subscription {\n jobs {\n UID\n Name\n Description\n Duration\n Start\n End\n CreatedDate\n JobAllocations {\n UID\n }\n }\n }\n ",
"customFields": {},
"type": "graphql_deferred"
}
]
}
Via the CLI
Run the following command to fetch a list of webhooks:
sked artifacts webhook list
which will return a response such as:
✔ Fetching Webhook list...
name type url
────────────────── ─────── ───────────────────────
my-webhook graphql https://my-api/callback
Each webhook can then be retrieved by name by running the get command, for example:
sked artifacts webhook get --name my-webhook
Delete a webhook
Via the API
To delete a webhook when it is no longer required, use the following cURL command with the webhook id
.
curl -s -X DELETE -H "Authorization: Bearer $AUTH_TOKEN" 'https://api.skedulo.com/webhooks/a0cd6a80-8a9d-4ed5-92f6-9c0e03b6281e'
Via the CLI
To delete a webhook when it is no longer required, run the delete command specifying the webhook’s name, for example:
sked artifacts webhook delete --name my-webhook
Feedback
Was this page helpful?