In the Using ZIS to obtain Slack OAuth token, you learnt how to start a Slack OAuth flow using ZIS Connections API to obtain an access token. This token can be used to make authenticated REST API calls. In this tutorial, you’ll learn how to store the association between a Zendesk ticket and a Slack message. Then understand how to make use of this to update the Slack thread when there is an update to the ticket (such as adding a new comment) using the access token.

Zendesk Integration Services (ZIS) offers a service called ZIS Links specifically designed to store the association (link) between two objects. The association can be one-to-one such as a ticket ID to a Slack thread, or one-to-many such as a ticket ID to multiple JIRA issues. The service supports creating, updating, and deleting links.

ZIS Flow has native support for links in the form of CreateLink, LoadLinks, PatchLink, and DeleteLink ZIS Action state types. All actions are scoped to your integration and the account for the flow.

Parameters

  • link_type: The link_type identifies the type of link. It along with the left_object_name and right_object_name uniquely identifies the link. In cases where the value of link_type represents a reference path, it should be named link_type.$.
  • left_object_name: The left_object_name represents the "left" side of the link. It along with the link_type and right_object_name uniquely identifies the link. In the case where the value of left_object_name represents a reference path, it should be named left_object_name.$.
  • right_object_name: The right_object_name represents the "right" side of the link. It along with the link_type and left_object_name uniquely identifies the link. In cases where the value of right_object_name represents a reference path, it should be named right_object_name.$.

The parameter values can be 3 to 256 characters and contain numbers, letters, and colon (:), forward slash (/), underscore (_), dash (-), and period (.) special characters.

The CreateLink action is used to create a link between two objects. link_type, left_object and right_object are required when creating a link. The CreateLink Action takes the following form. Each object can have an optional metadata associated with it as well.

"CreateLink": {   "Type":"Action",   "ActionName":"zis:common:action:CreateLink",   "Parameters":{      "link_type":"<link_type>",      "left_object":{         "name":"<left_object_name>",         "metadata": {}      },      "right_object":{         "name":"<right_object_name>",         "metadata": {}      }   },   "Next":"Done"}

The LoadLinks action is used to look up the link given the link_type, either left_object_name, right_object_name, or both. It supports the use of * in the object's name and can be used to perform "like" searches such as left_object_name: foo*. This matches all left_object_name having foo as its prefix. The asterisk (*) can only be at the end of a LoadLinks operation.

Note: The search is not performed on metadata of each object, but only on the object names.

The result of the LoadLinks operation is stored in ResultPath. The LoadLinks action takes the following form:

"LoadLinks": {   "Type":"Action",   "ActionName":"zis:common:action:LoadLinks",   "Parameters":{      "link_type":"<link_type>",      "left_object_name":"<left_object_name>",      "right_object_name":"<right_object_name>"   },   "ResultPath":"<store_at_reference_path>",   "Next":"<next_state>"}

DeleteLink is used to delete a link. link_type, left_object, and right_object are required when deleting a link. The DeleteLink action takes the following form:

"DeleteLink":{   "Type":"Action",   "ActionName":"zis:common:action:DeleteLink",   "Parameters":{      "link_type":"<link_type>",      "left_object_name":"<left_object_name>",      "right_object_name":"<right_object_name>"   },   "Next":"<next_state>"}

PatchLink is used to update the object names (left or right or both) and its associated metadata. It requires the old link names left_object_name and right_object_name and the new objects as right_object and left_object.

"PatchLink":{   "Type":"Action",   "ActionName":"zis:common:action:PatchLink",   "Parameters":{      "link_type":"<link_type>",      "left_object_name":"<left_object_name>",      "right_object_name":"<right_object_name>",      "left_object":{         "name":"<new_name>"      },      "right_object":{         "name":"<new_name>"      },   },   "ResultPath":"<reference_path_to_store_results>",   "Next":"<next_state>"}

Sending a Slack notification

You'll learn how to make use of ZIS Links to store the association between a Zendesk ticket and a Slack thread, then use that association to update a Slack thread. The logic for a flow is shown below. In this tutorial, you’ll use TicketCreated or CommentAdded events as triggers.

Creating and uploading a ZIS Bundle

  1. In your text editor, create a file named send_slack_notification_bundle.json and paste the following code:

    {  "zis_template_version": "2019-10-14",  "name": "Send Slack notification when ticket is updated",  "description": "Send Slack notification when ticket is updated",  "resources": {    "TicketCreatedJobSpec": {      "type": "ZIS::JobSpec",      "properties": {        "name": "TicketCreatedJobSpec",        "event_source": "support",        "event_type": "ticket.TicketCreated",        "flow_name": "zis:<YOUR_INTEGRATION>:flow:SendSlackNotification"      }    },    "CommentAddedJobSpec": {      "type": "ZIS::JobSpec",      "properties": {        "name": "CommentAddedJobSpec",        "event_source": "support",        "event_type": "ticket.CommentAdded",        "flow_name": "zis:<YOUR_INTEGRATION>:flow:SendSlackNotification"      }    },    "SendSlackNotification": {      "type": "ZIS::Flow",      "properties": {        "name": "SendSlackNotification",        "definition": {          "StartAt": "GetLinkedMessage",          "States": {            "GetLinkedMessage": {              "Type": "Action",              "ActionName": "zis:common:action:LoadLinks",              "Parameters": {                "link_type": "ticket_to_message",                "left_object_name.$": "ticket_id:{{$.input.ticket_event.ticket.id}}"              },              "ResultPath": "$.get_linked_message_response",              "Next": "CheckLink"            },            "CheckLink": {              "Type": "Choice",              "Choices": [                {                  "Variable": "$.get_linked_message_response.count",                  "NumericEquals": 0,                  "Next": "SendMessageOnTicketCreate"                },                {                  "Variable": "$.get_linked_message_response.count",                  "NumericEquals": 1,                  "Next": "ExtractThreadId"                }              ]            },            "SendMessageOnTicketCreate": {              "Type": "Action",              "ActionName": "zis:<YOUR_INTEGRATION>:action:PostToSlack",              "Parameters": {                "text.$": ":rotating_light: A <https://{{$.subdomain}}.zendesk.com/agent/tickets/{{$.input.ticket_event.ticket.id}}| ticket> was created!",                "thread_ts": 0,                "access_token.$": "$.connections.slack.access_token"              },              "ResultPath": "$.send_message_response",              "Next": "CreateLink"            },            "ExtractThreadId": {              "Type": "Action",              "ActionName": "zis:common:transform:Jq",              "Parameters": {                "expr": ".right_object.name | split(\":\")[1]",                "data.$": "$.get_linked_message_response.links[0]"              },              "ResultPath": "$.thread_id",              "Next": "ThreadMessageOnTicketUpdate"            },            "ThreadMessageOnTicketUpdate": {              "Type": "Action",              "ActionName": "zis:<YOUR_INTEGRATION>:action:PostToSlack",              "Parameters": {                "text.$": "$.input.ticket_event.comment.body",                "thread_ts.$": "$.thread_id",                "access_token.$": "$.connections.slack.access_token"              },              "Next": "Done"            },            "CreateLink": {              "Type": "Action",              "ActionName": "zis:common:action:CreateLink",              "Parameters": {                "link_type": "ticket_to_message",                "left_object": {                  "name.$": "ticket_id:{{$.input.ticket_event.ticket.id}}"                },                "right_object": {                  "name.$": "thread_ts:{{$.send_message_response.message.ts}}"                }              },              "Next": "Done"            },            "Done": {              "Type": "Succeed"            }          }        }      }    },    "PostToSlack": {      "type": "ZIS::Action::Http",      "properties": {        "name": "PostToSlack",        "definition": {          "method": "POST",          "url": "https://slack.com/api/chat.postMessage",          "headers": [            {              "key": "Authorization",              "value.$": "Bearer {{$.access_token}}"            },            {              "key": "Content-Type",              "value": "application/json"            }          ],          "requestBody": {            "text.$": "$.text",            "channel": "<YOUR_SLACK_CHANNEL>",            "thread_ts.$": "$.thread_ts"          }        }      }    }  }}

    Replace the following placeholders:

  2. Save the file.

  3. From the command line editor, make a cURL request to the Registry API to upload the bundle:

    curl \--request POST \--url https://<SUBDOMAIN>.zendesk.com/api/services/zis/registry/<YOUR_INTEGRATION>/bundles \--user '<EMAIL>:<PASSWORD>' \--header 'content-type: application/json' \-d @send_slack_notification_bundle.json

    Replace <EMAIL> and <PASSWORD> with your Basic Auth credentials.

  4. From the command line, run the curl command to enable the job spec. Note: If you have already enabled the job spec TicketCreatedJobSpec or CommentAddedJobSpec in previous tutorials, you can skip this step.

    curl \--request POST \--url "https://<SUBDOMAIN>.zendesk.com/api/services/zis/registry/job_specs/install?job_spec_name=zis:<YOUR_INTEGRATION>:job_spec:TicketStatusChangedJobSpec,zis:<YOUR)INTEGRATION>:job_spec:CommentAddedJobSpec" \--user '<EMAIL>:<PASSWORD>'

Testing the integration

Test the integration in Zendesk Support by creating a ticket and adding a comment. You should see a notification in your Slack channel. All comments added to the ticket should appear threaded.

Next: Extending your first integration: Triggering a ZIS Flow from external events