Establishing webhooks

Establishing and using webhooks.

This chapter demonstrates how to set up webhooks for Skedulo using the Skedulo Lens API and ngrok, which is a useful tool for locally testing and viewing webhook responses.

Prerequisites * 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

Create a webhook

  1. Create and open a webhooks folder from the terminal:

    $ mkdir webhooks && cd webhooks
    
  2. Download and install ngrok in the webhooks folder:

    1. Go to https://ngrok.com/ and click Download.
    2. Download the version of ngrok for your operating system.
    3. Unzip ngrok into the /webhooks folder.
  3. 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)
    

    4. Start the HTTP server in one terminal: node httpserver.js

    5. Start ngrok in another terminal:

    ./ngrok http 8080
    

    Ngrok started in terminal.

    Take note of the HTTPS address of your ngrok server. For example: https://b14b2804.ngrok.io

    6. 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 the url.

    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 includes UID and Duration.
    • The schemaJobs field also accepts filter and extendedFilter parameters.
    • The operation parameter can be used to ignore events that do not have the operation value. The operation parameter accepts an array of values: INSERT, UPDATE or DELETE.

7. Create a webhook request body:

node webhook.js > temp.json 

8. Create a POST request to the Skedulo API that references the temp.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"
  }
}

9. 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.

10. Update a job to change the Duration to 30. 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"
        }
      }
    }
  ]
}

11. A record of the HTTP request appears in the terminal tab that is running ngrok:

Ngrok operations terminal.

The ngrok web interface also shows both of the operations and responses:

Ngrok web interface.

Retrieve webhooks

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"
    }
  ]
}

Delete a webhook

To delete your webhook when you no longer require the connection, you can delete the webhook using 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'

Last modified November 26, 2019: [ENG-9066] Scheduled webhooks (437fce0)