Creating a Dispatch Task (which starts its Workflow)
To create a Dispatch Task requires the following data:
-
A Source Unique Identifier from the originating system (the Dispatch Task Custom ID)
-
A Priority (fixed list of enum values)
-
A Client ID
-
A Report Template already exists, and is referenced (along with enough data to create report instance from that template)
-
A Date and Time to anchor the dispatch/call-out as being instantiated
-
A Task Type (to categorize the dispatch task)
-
A Location Type (to contextualize the geolocation in relation to the Account umbrella for the location)
Once the data dependencies are defined, a Dispatch Task can be created in the following way via API:
[POST] /dispatch-tasks
{
"customId": "202212191621",
"priority": "LOW",
"account":687,
"report": {
"reportTemplate": 117,
"account": 687,
"reportFields": [
{"field": 1620, "value": "These are the details"},
{"field": 1621, "value": "687"}
]
},
"startedOn": "202212191621",
"taskType": 3,
"locationType": "ACCOUNT_ADDRESS"
}
The success of this posting is observable from the Mobile Dispatch section of the TrackTik web portal in the list below it:
It's also mentioned in the Activity Feed:
The [View] button on the farthest right opens a side panel with the submitted details and areas to interact with the report and associated Workflow. It's from here that the Mobile Dispatch Operator assigns a Guard to enact the physical response to the Call-Out.
A
-(?) Age of call-out before the indicated Dispatch Officer has responded.
B
-Custom ID : from the API POST
-Ticket ID : Dispatch Task ID + Report ID
-Scheduled : from the API POST
-Created : who is the authenticated user of the API (source)
-Location : the Client Site
-Contact : default contact info of Client Site
-Workflows : the Workflow associated to the Task Type who's ID was provided in the API POST
-(?) Extra Information
-(?) Assets
-Assignee : who the current Assignee is (empty when the Dispatch Task is new because the Dispatch Officer hasn't assigned an Employee yet)
C
-The report created based on the template and fields provided in the Dispatch Task API POST
D
-The current progress of the Workflow Instance (the Workflow Instance Log items)
Logging, Responses and Subscriptions
Logs and Responses
The TrackTik API doesn't have an always-on/comprehensive push-notifications engine for integrations. It does however have subscription service that can be defined based on required triggers, entities, fields, filters and relation lists by the integration partner, and then started, left running indefinitely, and/or stopped.
The subscription service is called Events Notifications. Once an Events Notification is triggered, it makes an internal to TrackTik API call, retrieves data as a payload, and POSTs that payload to whatever destination REST API URL has been defined in the subscription (with authentication/security information in the header).
Dispatches with Workflows log all Workflow step progressions via the API endpoint workflow-instance-logs, which can be subscribed to so that all logged events can be published to the Monitoring Center:
E.g.[GET] /workflow-instance-logs?sort=-id&include=status,workflowInstance.workflow
{
"user": 1002,
"createdOn": "2022-12-22T16:06:20+00:00",
"id": 1992,
"status": {
"name": "Report Reviewed / Closed",
"tag": "closed",
"workflow": 2,
"formatBackgroundColor": "#004212",
"formatTextColor": "WHITE",
"warningThresholdInMinutes": 0,
"alertThresholdInMinutes": 0,
"id": 19
},
"workflowInstance": {
"currentStatus": 19,
"modifiedOn": "2022-12-22T16:06:20+00:00",
"startedOn": "2022-08-12T18:33:08+00:00",
"dispatchTask": 531,
"id": 471,
"workflow": {
"name": "Alarm Response (HQ)",
"details": "",
"type": "DISPATCH",
"isGlobal": true,
"region": 2,
"status": "ACTIVE",
"id": 2
}
}
}
An Events Subscription can be configured to leverage the base data of an endpoint payload, include relation lists, or omit fields entirely.
A solution architect can decide if the Events Subscription should be universal so that all logged events for all workflows are captured and aggregated at destination (Monitoring Center), or it can be created to run only as long as the duration of the workflow.
Subscribing to a single Workflow Instance
If we take the scenario where a subscription is only alive and sending data for as long as the dispatch task and associated workflow are progressing, then the steps would be:
-
Subscribe to workflow-instances to receive the ID number of new instances.
-
POST a new events-subscriptions entry for workflow-instance-logs with a "userDefinedFilters": {"workflowInstance": nnn} section that only follows that one instance.
-
Watch for the last status of the workflow instance
-
Disable the events-subscription for that workflow instance via /events-subscriptions/{id}/actions/archive
Getting the Workflow Instance ID
When the Dispatch Task was created as described earlier in this document, the response will have provided the ID of the new instance of a Workflow. This ID must be provided in the event subscription so that events of that workflow will be sent to the listener.
E.g.
{
"customId": "202301091612",
"taskType": 3,
"priority": "LOW",
"taskInstructions": "",
"startedOn": "2023-01-09T21:12:00+00:00",
"startDateTime": "2023-01-09T21:12:00+00:00",
<snip>
⇒ "workflowInstance": 484,
"location": null,
"locationType": "ACCOUNT_ADDRESS",
"closedOn": null,
"id": 545
}
With the Workflow Instance ID in hand, an Events Subscription configured for this could look like:
{
"customId": "WFI-484",
"name": "Steps progression of a Workflow Instance",
"events": [
"entity:workflow-instance-logs:created",
"entity:workflow-instance-logs:updated"
],
"entityResponse": {
"include": [
"status",
"user",
"workflowInstance"
]
},
"contextFilters": {
"filters": [
{
"tag": "context.region.2",
"includeChildren": true
}
]
},
"userDefinedFilters": {
"workflowInstance": 484
},
"url": "https://webhook.site/fd1528a4-a8ff-...",
"failureEmail": "fd1528a4-a8ff-...@email.webhook.site",
"secretHeaderName" : "TrackTik-subscription-secret-without-spaces",
"secret" : "B2C60113ECB70E70CF1...."
}
In this example we see the two triggers of CREATED and UPDATED. The subscription would post data out to the REST listener for any new wokflow-instance-logs record, or when an existing log entry is updated.
"entityResponse": { "include": [ section describes what relation lists to pull in. These are additional 1:1 or 1:many records that are not normally displayed by API calls to workflow-instance-logs.
"contextFilters": { section is for defining the Regional context, to satisfy a requirement by the TrackTik system that tends to limit data access to specific regions based on Access Control Lists of it's Employee Roles management layer.
"userDefinedFilters": {"workflowInstance": 480 } is the most important part of a "only call out on the logged activities of a single dispatch/workflow" as it adds a filter to limit the number of records to POST to the Monitoring Center to only this or those workflow instances identified by unique ID number.
"workflowInstance": 480 line is this unique ID number is obtainable as part of the response of the creation of a Workflow Instance, which gets created when a new Dispatch Task is created and it has been defined to use a Workflow Template. This is the main ID number that should be perceived as joined with the ID number of the Event Subscription as suggested in step #4 in the previous list.
Ending a Subscription to a Workflow Instance
Once the end of the Workflow Instance has been reached and you recognize the status string for however you set up the template for the Workflow that was instanced, you can then archive the subscription.
Events Subscriptions are never deleted completely. They can be paused/suspended, enabled (resumed) or archived (permanent closure). An archived Events Subscription cannot currently be un-archived.
There are dedicated actions for each of these:
Pausing/Suspending an Events Subscription (won't make call-outs but can be resumed)
/rest/v1/events-subscriptions/{id}/actions/suspend
Resuming/enabling a suspended Events Subscription
/rest/v1/events-subscriptions/{id}/actions/enable
Archiving/terminating an Events Subscription with any status
/rest/v1/events-subscriptions/{id}/actions/archive
For troubleshooting or recovering callouts that might have been missed, there is a logs sub-path for any un-archived Events Subscription
/rest/v1/events-subscriptions/{id}/logs
Retry mechanism
Active Events Subscriptions will attempt to make their callouts after triggers and retry upon failure following these rules (can vary a bit per client if they negotiate a different configuration with us):
Setting |
Value |
Max retries |
10 |
Time between retries |
120 seconds |
Timeout (no response received to callout) |
30 seconds (set by Axios) |
HTTP Status Codes (that signal OK, otherwise it’s a failure that will lead to a retry) |
2xx |
Advancing a workflow to another step
Workflows are associated with dipatches, so there is an action to advance the dispatch that will advance its associated workflow:
Transition the workflow from "New Alarm" to "Assigned"
[POST] /dispatch-tasks/{id}/actions/raise-event
{
"event" : "Assigned"
}
The available transitions are defined in the workflows template's transition between two steps as workflow-status-transitions in the Event ID field:
Including a Report
You can also include a reportFields data object if you need to complete a form as part of this transition into the Assigned status. The report fields data requires that you know the ID of the report-template-field record that is defined when the form is created in the UI. You'll need to work with a TrackTik portal administrator to obtain the label names and try to locate these fields. They won't be easily found via a report-template like other normal report templates.
Here's an example of a report form defined on the workflow transition of "Accepted : Pending" to "On The Way" and how it appears in report-template-fields:
[GET] /report-template-fields?sort=-id&include=createdOn
{
"reportTemplate": 1014,
"id": 2538,
"label": "route taken",
"name": "f_2538",
"type": "TEXT",
"required": false,
"adminOnly": false,
"displayOrder": 0,
"extra": "",
"list": null,
"listItems": null,
"isDispatcherField": false,
"fieldTag": "",
"confidential": false,
"createdOn": "2023-01-20T20:43:51+00:00"
}
NB: the reportTemplate indicated by ID 1014, is not part of the regular report templates. But this report field does have a unique ID of 2538 which you need in the reportFields object as mentioned previously to post a form at the same time as advancing the workflow instance:
[POST] /dispatch-tasks/{id}/actions/raise-event
{
"event" : "On The Way",
"reportFields": [
{"field": 2538, "value": "route 12"}
]
}
The report you create will be discoverable via the /reports endpoint, but without a typically associated report template since workflow reports don't participate in the same structure as TrackTik's other Report Templates/Categories system:
E.g.
[GET] /reports/4720?include=reportFields
{
"reportTemplate": null,
"timeZone": "America/New_York",
"reportDateTime": "2024-01-25T15:56:26-05:00",
"submitTime": 1706216186,
"submittedOn": "2024-01-25T20:56:26+00:00",
"account": 687,
"position": null,
"approvedOn": null,
"approvalDateTime": null,
"status": "NEW",
"approvedBy": null,
"checkpoint": null,
"reportFlag": null,
"siteLocation": null,
"id": 4720,
"reportFields": [
{
"fieldTag": "",
"report": 4720,
"templateField": 2526,
"value": {
"type": "text",
"value": "very happy"
},
"archived": false,
"id": 23376
}
]
}
Returning to the previous workflow step of Assigned in the examples below for a moment, making a POST call to raise-event will create a new status change log entry for the workflow instance, captured and visible in workflow-instance-logs.
E.g.
[GET] /workflow-instance-logs?workflowInstance=484&include=status
{
"user": 1002,
"createdOn": "2023-01-09T21:12:28+00:00",
"workflowInstance": 484,
"id": 1994,
"status": {
"name": "New Alarm",
"tag": "New Alarm",
"workflow": 2,
"formatBackgroundColor": "black",
"formatTextColor": "WHITE",
"warningThresholdInMinutes": 1,
"alertThresholdInMinutes": 5,
"id": 11
}
},
=> {
"user": 1002,
"createdOn": "2023-01-19T17:02:49+00:00",
"workflowInstance": 484,
"id": 2001,
"status": {
=> "name": "Assigned",
"tag": "Assigned",
"workflow": 27,
"formatBackgroundColor": "red",
"formatTextColor": "black",
"warningThresholdInMinutes": 1,
"alertThresholdInMinutes": 5,
"id": 12
}
}
It's important to note that some workflow steps require additional data, which the raise-event action can't treat. The "Assigned" event in the example above is such a case. Normally in the TrackTik web application, to move a workflow instance to the status of Assigned, employee data must be provided. The raise-event action can't do this (yet), so a second step is required: updating the Dispatch Task to contain the ID of the assigned employee:
[PATCH] /dispatch-tasks/{id}
{
"assignedUser" : 1404
}
Now the workflow instance status of Assigned has been correctly achieved.
NB: We need to test if it breaks notifications data integrity to advance the workflow without an employee ID being defined in assignedUser. Maybe it's better to assign the employee first, and then advance the workflow to its Assigned status. This is something to think about across all workflow step advancements via API.
Adding a Note/Comment to a Dispatch Task in Progress
You can add a note/comment to a Dispatch Task with the associated endpoint's action add-note:
[POST] /dispatch-tasks/542/actions/add-note
{
"note" : "API added note"
}
The new note is accessible by both API and the TrackTik portal.
New note visible in the list of notes for the dispatch-task:
[GET] /dispatch-tasks/542?include=notes
…
"notes": [
{
"comment": "note 1",
"createdBy": 1002,
"createdOn": "1970-01-01T00:33:43+00:00",
"type": "COMMENT",
"id": 47850
},
{
"comment": "note 2",
"createdBy": 1002,
"createdOn": "1970-01-01T00:33:43+00:00",
"type": "COMMENT",
"id": 47851
},
{
"comment": "API added note",
"createdBy": 1002,
"createdOn": "1970-01-01T00:33:43+00:00",
"type": "COMMENT",
"id": 48108
}
]
These notes are a relation list. TrackTik's API is currently limited to only 100 relation list items that can be included. Normally this limit can be avoided by calling the direct endpoint the relation list gets its records from, but in this case the relation list is pulling from /comments which doesn't have enough filters to target a single Dispatch Task's Comments.
New note as seen in the portal: