Create a triggered action for modified objects

Setting up a new triggered action that triggers when a Skedulo object is modified.

In this section we will use ngrok to demonstrate how to set up a triggered action with an object_modified trigger.

Object modification triggers fire whenever specific changes that you want to know about are made to the object defined in the request. You can specify what changes you want to know about by applying a filter to the schema object. You can listen for changes on any Skedulo or custom object that exists in your schema.

A common use case for this type of trigger is listening for changes on the Job object. Job object webhooks or triggered actions are often used to alert your application of any changes to the job status, description, or allocation fields.

Create a triggered action that calls a URL when a Job status is changed

The following procedure sets up a triggered action that triggers whenever there is a change to the Job.Status field any job. The call_url action response sends an update via to a local ngrok server that includes information about the new job status.

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.

  • (optional) Have ngrok installed locally if you want to follow this procedure for testing/learning purposes.

Setup

  1. Run a minimal HTTPS web server listening for changes to data and other events on port 8000. Print the contents of requests to stdout, and reply with 200 OK:

    while true; do echo 'HTTP/1.1 200 OK\r\n' | nc -l 8000; done
    
  2. Open another terminal, then start ngrok:

    ./ngrok http 8080 
    
  3. Get the public address of your ngrok endpoint:

    Ngrok started in terminal.

    This is the URL that we are going to use in our request. The API will call it when there is a change to a job status.

Create a triggered action

The request payload includes the following configuration:

  • name: The name of the triggered action.

  • Trigger:

    • schemaName: The name of the object the trigger is listening to for changes.
    • filter: The EQL filter for the query. This specifies exactly what information about jobs we are interested in. In this case, we want the trigger to fire whenever JobStatus changes from one state to another.
    • type: The type of trigger. In this example we are creating an object_modified trigger.
  • Action:

    • type: The type of action in response to the trigger. In this case, it is a call_url action.
    • url: The URL where the query data is to be sent.
    • headers: Header names and values that are added to the request, including authentication tokens.
    • query: A string containing a GraphQL query that is validated against the trigger, in this case, the Jobs object.

Via the API

  1. Send a POST request to the /triggered_actions endpoint with the following JSON payload:

     {
         "name": "Skedulo Test Job Status Change",
         "trigger": {
             "schemaName": "Jobs",
             "filter": "Current.JobStatus != Previous.JobStatus",
             "type": "object_modified"
         },
         "action": {
             "type": "call_url",
             "url": "https://fd4b-2001.au.ngrok.io",
             "headers": {
                 "TestHeader1": "Job Status change with allocations."
             },
             "query": "{ UID JobStatus Description Duration LastModifiedById LastModifiedDate JobAllocations(filter: \"Status != 'Deleted'\") { UID Status LastModifiedById LastModifiedBy { Name } } }"
         }
     }
    

    The request returns the following response, which includes the triggered action ID:

    {
       "result": {
           "id": "5bc94ad1-7b28-49ae-88e8-f0c8ef0a6f2b",
           "name": "Skedulo Test Job Status Change",
           "trigger": {
               "schemaName": "Jobs",
               "filter": "Current.JobStatus != Previous.JobStatus",
               "type": "object_modified"
           },
           "action": {
               "url": "https://fd4b-2001.au.ngrok.io",
               "headers": {
                   "TestHeader1": "Job Status change with allocations."
               },
               "query": "{ UID JobStatus Description Duration LastModifiedById LastModifiedDate JobAllocations(filter: \"Status != 'Deleted'\") { UID Status LastModifiedById LastModifiedBy { Name } } }",
               "type": "call_url"
           },
           "enabled": true,
           "customFields": {},
           "created": "2022-07-22T02:26:20.665809Z",
           "updated": "2022-07-22T02:26:20.665809Z"
       }
    }
    

Via the CLI

  1. Create a state file called job-status-change.triggered-action.json containing:

     {
         "metadata": {
           "type": "TriggeredAction"
         },
         "enabled": true,
         "name": "job-status-change",
         "trigger": {
             "schemaName": "Jobs",
             "filter": "Current.JobStatus != Previous.JobStatus",
             "type": "object_modified"
         },
         "action": {
             "type": "call_url",
             "url": "https://fd4b-2001.au.ngrok.io",
             "headers": {
                 "TestHeader1": "Job Status change with allocations."
             },
             "query": "{ UID JobStatus Description Duration LastModifiedById LastModifiedDate JobAllocations(filter: \"Status != 'Deleted'\") { UID Status LastModifiedById LastModifiedBy { Name } } }"
         }
     }
    
  2. Create the triggered action from the state file by running this command:

    sked artifacts triggered-action upsert -f job-status-change.triggered-action.json`
    

Test the triggered action

  1. Test the above triggered action by changing the status of a job in your Skedulo org. The change triggers a response that sends a notification containing the action query data in the terminal where your ngrok server is listening.

    In this example, a job status has changed from Queued to Pending Dispatch:

Job allocation updated from Queued to Pending Dispatch displayed in a terminal

Use configuration variables in triggered actions

Configuration variables can be used to make triggered actions more portable and secure.

Using the previous example, we can replace the url and headers fields with configuration variable templates. Templates are formatted as {{ CONFIG_VAR_NAME }}.

To use configuration variables in triggered actions, do the following steps:

  1. Create a URL variable in the web app following the user guide instructions and the example data that follows:
  • Set the Name to JOB_STATUS_CHANGED_URL.
  • Set the Value to your ngrok URL e.g. https://fd4b-2001.au.ngrok.io.
  • Set the type and description as required, for this example, you could set the Type to plain text and add a Description like: “Triggered action URL when job status has changed”.
  1. Create a header variable in the same way:
  • Set the Name to JOB_STATUS_CHANGED_HEADER.
  • Set the Value to Job Status change with allocations..
  • Set the type and description as required, for this example, you could set the Type to secret and add a Description like: “Secret header”.
  1. Then create the triggered action containing templates:
{
  "name": "Skedulo Test Job Status Change",
  "trigger": {
      "schemaName": "Jobs",
      "filter": "Current.JobStatus != Previous.JobStatus",
      "type": "object_modified"
  },
  "action": {
      "type": "call_url",
      "url": "{{ JOB_STATUS_CHANGED_URL }}",
      "headers": {
          "TestHeader1": "{{ JOB_STATUS_CHANGED_HEADER }}"
      },
      "query": "{ UID JobStatus Description Duration LastModifiedById LastModifiedDate JobAllocations(filter: \"Status != 'Deleted'\") { UID Status LastModifiedById LastModifiedBy { Name } } }"
  }
}

When the triggered action is triggered, the templates will resolve to the values of the configuration variables. If any of the configuration variables are not found, then the triggered action will fail.

Send an SMS when an object is modified using triggered actions

The other action you can perform in response to a trigger is to send an SMS to a number defined in the triggered action.

To do this, we will need to create a new triggered action. Triggered actions can be updated, however updating a triggered action cannot be used to change the type of the trigger or action.

If you want to test this procedure, use your own SMS number or a number you have access to in the numbers array.

Prerequisite

This procedure assumes that you still have a running ngrok server as covered in steps 1 to 3 of the prerequisite steps in the procedure above.

  1. Create a new POST request to the /triggered_actions endpoint with the following payload:

    {
        "name": "Skedulo Job Status Change send SMS",
        "trigger": {
            "schemaName": "Jobs",
            "filter": "Current.JobStatus != Previous.JobStatus",
            "type": "object_modified"
        },
        "action": {
            "type": "send_sms",
            "to": {
                "numbers": [ "+61401234567" ]
            },
            "template": "Triggered action job status changed {{ Name }} {{ Start }} {{ JobStatus }}"
        }
    }
    

    This example uses the same trigger as the previous procedure to show how the same trigger settings can be used to perform a different action.

    • name: The name of the triggered action.

    Trigger:

    • schemaName: The name of the object the trigger is listening to for changes.
    • filter: The EQL filter for the query. This specifies exactly what information about jobs we are interested in. In this case, we want the trigger to fire whenever JobStatus changes from one state to another.
    • type: The type of trigger. In this example we are creating an object_modified trigger.

    Action:

    • type: The type of action in response to the trigger.
    • to: An array of SMS numbers where the template message is to be sent.
    • template: A {{ mustache }} template that allows EQL field names as variables. The values can reference fields defined on lookups.

    The request returns the following response:

        {
        "result": {
            "id": "0d77076e-ef29-424b-912d-afed4d7d4c35",
            "name": "Skedulo Job Status Change send SMS",
            "trigger": {
                "schemaName": "Jobs",
                "filter": "Current.JobStatus != Previous.JobStatus",
                "type": "object_modified"
            },
            "action": {
                "to": {
                    "numbers": [
                        "+61401234567"
                    ]
                },
                "template": "Triggered action job status changed {{ Name }} {{ ActualStart }} {{ JobStatus }}",
                "type": "send_sms"
            },
            "enabled": true,
            "customFields": {},
            "created": "2022-07-27T03:44:22.670679Z",
            "updated": "2022-07-27T03:44:22.670679Z"
        }
    }
    
  2. To test the above triggered action, change the status of a job in your Skedulo org.

    An SMS is sent and appears as defined in the template:

    SMS received from object modified triggered action.