This tutorial is part of a series that builds a Zendesk integration for Slack:

The integration listens forTicket Createdevents in Zendesk. When it detects an event with a specific ticket priority, the integration posts a related message to a provided Slack channel.

If you followed along in the series, you should now have a working Zendesk app. The app serves as a user interface (UI) for your integration. In this tutorial, you'll install the integration and finish building the app.

Create a bundle

运行,your integration requires a Zendesk Integration Services (ZIS) bundle. A bundle contains JSON objects that define the logic and resources for an integration.

The bundle for this integration should include JSON objects for:

  • A custom action that gets ticket data
  • A custom action that posts a message to a Slack channel
  • A ZIS flow that defines the integration's logic as states
  • A job spec that runs the above flow when ZIS detects a Ticket Created event

Create a bundle skeleton

To start, create a skeleton file for your bundle.

  1. Create a file namedzendesk-to-slack-bundle.json.

  2. Add the following JSON to the file:

                   
    {"name":"Post Slack message on ticket creation","description":"Posts ticket data to Slack channel on ticket creation","zis_template_version":"2019-10-14","resources":{"get_zendesk_ticket_http_action":{"_placeholder_":"Action properties here"},"post_message_to_slack_http_action":{"_placeholder_":"Action properties here"},“post_ticket_update_flow”:{"_placeholder_":"Flow properties here"},"post_message_to_slack_on_ticket_created_job_spec":{"_placeholder_":"Job spec properties here"}}}

    The JSON contains placeholders for the bundle's action, flow, and job spec objects.

Define the custom actions

Next, define the bundle's custom actions.

  1. Inzendesk-to-slack-bundle.json, replace theget_zendesk_ticket_http_actionplaceholder with the following:

                   
    "get_zendesk_ticket_http_action":{"type":"ZIS::Action::Http","properties":{"name":"get_zendesk_ticket_http_action","definition":{"method":"GET","path":"/api/v2/tickets/{{$.ticketId}}.json","connectionName":"zendesk"}}},

    When run, the action calls the ZendeskShow Ticketendpoint to get ticket data. To make the call, the action requires the "zendesk" OAuth connection and the{{$.ticketId}}输入变量。你本身t the{{$.ticketId}}variable when you define the bundle's flow.

  2. Replace thepost_message_to_slack_http_actionplaceholder with the following:

                   
    "post_message_to_slack_http_action":{"type":"ZIS::Action::Http","properties":{"name":"post_message_to_slack_http_action","definition":{"method":"POST","url":"https://slack.com/api/chat.postMessage","connectionName":"slack","requestBody":{"channel":"{{$.channelId}}","blocks":[{"type":"section","text":{"type":"mrkdwn","text":"{{$.title}}"},"fields":[{"type":"mrkdwn","text":"*Subject*"},{"type":"mrkdwn","text":"*Description*"},{"type":"plain_text","text":"{{$.ticketSubject}}"},{"type":"plain_text","text":"{{$.ticketDescription}}"}]},{"type":"section","text":{"type":"mrkdwn","text":"{{$.link}}"}}]}}}},

    When run, the action calls the Slack API'schat.postMessagemethod to post a message to a Slack channel. To post the message, the action requires the "slack" OAuth connection and the following input variables:

    • {{$.channelId}}
    • {{$.title}}
    • {{$.ticketSubject}}
    • {{$.ticketDescription}}
    • {{$.link}}

    你本身t the input variables when you define the bundle's flow.

Define the flow

Next, define a ZIS flow for the bundle.

Inzendesk-to-slack-bundle.json, replace thepost_ticket_update_flowplaceholder with the following JSON. In the JSON, replace "SUBDOMAIN" with your Zendesk subdomain.

             
“post_ticket_update_flow”:{"type":"ZIS::Flow","properties":{"name":“post_ticket_update_flow”,"definition":{"StartAt":"LoadSettings","States":{"LoadSettings":{"Type":"Action","ActionName":"zis:common:action:LoadConfig","Parameters":{"scope":"slackNotification"},"ResultPath":"$.settings","Next":"IsTicketPriorityMatch"},"IsTicketPriorityMatch":{"Type":"Choice","Choices":[{"Variable":"$.input.ticket_event.ticket.priority","StringEqualsPath":"$.settings.priority","Next":"GetZendeskTicket"}],"Default":"Done"},"GetZendeskTicket":{"Type":"Action","ActionName":"zis:SUBDOMAIN_zendesk_to_slack:action:get_zendesk_ticket_http_action","Parameters":{"ticketId.$":"$.input.ticket_event.ticket.id"},"ResultPath":“.retrievedTicket美元”,"Next":"PostMessageToSlack"},"PostMessageToSlack":{"Type":"Action","ActionName":"zis:SUBDOMAIN_zendesk_to_slack:action:post_message_to_slack_http_action","Parameters":{"channelId.$":"$.settings.channel","ticketSubject.$":"$.retrievedTicket.ticket.subject","ticketDescription.$":"$.retrievedTicket.ticket.description","title.$":"*_New {{$.input.ticket_event.ticket.priority}} ticket #{{$.input.ticket_event.ticket.id}}_*","link.$":"<{{$.retrievedTicket.ticket.url}}|View in Zendesk>"},"ResultPath":"$.postMessageResponse","Next":"Done"},"Done":{"Type":"Succeed"}}}}},

The flow object contains five states:

  • LoadSettings保存使用Zendesk加载配置亚博pp'sconfig UI. The state makes the config's data available to other states as the "$.settings" object.

  • IsTicketPriorityMatchis a choice state. The state compares two properties:

    • The ticket priority from a Ticket Created event
    • The ticket priority from the config settings

    If the priorities are the same, the flow moves to theGetZendeskTicketstate. Otherwise, the flow moves to theDonestate.

  • GetZendeskTicketuses the customget_zendesk_ticket_http_actionaction. The state gets ticket data for the Ticket Created event. The state makes this ticket data available to following states as the "$.retrievedTicket" object.

  • PostMessageToSlackuses the custompost_message_to_slack_http_actionaction. The state posts a message to the Slack channel provided in the config settings. The message contains ticket data from the Ticket Created event and the "$.retrievedTicket" object.

  • TheDonestate ends the flow in a successful state.

Define the job spec

Next, define a job spec for the bundle. The job spec runs the bundle's ZIS flow when it detects a Ticket Created event.

Inzendesk-to-slack-bundle.json, replace the placeholder line in thepost_message_to_slack_on_ticket_created_job_specwith the following JSON. In the JSON, replace "SUBDOMAIN" with your Zendesk subdomain.

             
"post_message_to_slack_on_ticket_creation_job_spec":{"type":"ZIS::JobSpec","properties":{"name":"post_message_to_slack_on_ticket_creation_job_spec",“event_source”:"support","event_type":"ticket.TicketCreated","flow_name":"zis:SUBDOMAIN_zendesk_to_slack:flow:post_ticket_update_flow"}}

Code complete

Your actions, flow, and job spec now make up a complete ZIS bundle. Yourzendesk-to-slack-bundle.jsonfile should look as follows:

             
{"name":"Post Slack message on ticket creation","description":"Posts ticket data to Slack channel on ticket creation","zis_template_version":"2019-10-14","resources":{"get_zendesk_ticket_http_action":{"type":"ZIS::Action::Http","properties":{"name":"get_zendesk_ticket_http_action","definition":{"method":"GET","path":"/api/v2/tickets/{{$.ticketId}}.json","connectionName":"zendesk"}}},"post_message_to_slack_http_action":{"type":"ZIS::Action::Http","properties":{"name":"post_message_to_slack_http_action","definition":{"method":"POST","url":"https://slack.com/api/chat.postMessage","connectionName":"slack","requestBody":{"channel":"{{$.channelId}}","blocks":[{"type":"section","text":{"type":"mrkdwn","text":"{{$.title}}"},"fields":[{"type":"mrkdwn","text":"*Subject*"},{"type":"mrkdwn","text":"*Description*"},{"type":"plain_text","text":"{{$.ticketSubject}}"},{"type":"plain_text","text":"{{$.ticketDescription}}"}]},{"type":"section","text":{"type":"mrkdwn","text":"{{$.link}}"}}]}}}},“post_ticket_update_flow”:{"type":"ZIS::Flow","properties":{"name":“post_ticket_update_flow”,"definition":{"StartAt":"LoadSettings","States":{"LoadSettings":{"Type":"Action","ActionName":"zis:common:action:LoadConfig","Parameters":{"scope":"slackNotification"},"ResultPath":"$.settings","Next":"IsTicketPriorityMatch"},"IsTicketPriorityMatch":{"Type":"Choice","Choices":[{"Variable":"$.input.ticket_event.ticket.priority","StringEqualsPath":"$.settings.priority","Next":"GetZendeskTicket"}],"Default":"Done"},"GetZendeskTicket":{"Type":"Action","ActionName":"zis:SUBDOMAIN_zendesk_to_slack:action:get_zendesk_ticket_http_action","Parameters":{"ticketId.$":"$.input.ticket_event.ticket.id"},"ResultPath":“.retrievedTicket美元”,"Next":"PostMessageToSlack"},"PostMessageToSlack":{"Type":"Action","ActionName":"zis:SUBDOMAIN_zendesk_to_slack:action:post_message_to_slack_http_action","Parameters":{"channelId.$":"$.settings.channel","ticketSubject.$":"$.retrievedTicket.ticket.subject","ticketDescription.$":"$.retrievedTicket.ticket.description","title.$":"*_New {{$.input.ticket_event.ticket.priority}} ticket #{{$.input.ticket_event.ticket.id}}_*","link.$":"<{{$.retrievedTicket.ticket.url}}|View in Zendesk>"},"ResultPath":"$.postMessageResponse","Next":"Done"},"Done":{"Type":"Succeed"}}}}},"post_message_to_slack_on_ticket_creation_job_spec":{"type":"ZIS::JobSpec","properties":{"name":"post_message_to_slack_on_ticket_creation_job_spec",“event_source”:"support","event_type":"ticket.TicketCreated","flow_name":"zis:SUBDOMAIN_zendesk_to_slack:flow:post_ticket_update_flow"}}}}

Upload the bundle

After creating your bundle file, you can deploy your integration. First, upload the bundle using theCreate or Update Bundleendpoint.

  1. In your command-line interface, navigate to the folder that contains yourzendesk-to-slack-bundle.jsonfile.

  2. Run:

                   
    curl-XPOSThttps://{subdomain}.亚博.com/api/services/zis/registry/{subdomain}_zendesk_to_slack/bundles \-u{email}:{password}\-H"Content-Type: application/json"\-i-d @zendesk-to-slack-bundle.json

    If successful, the request returns an empty 200 response.

Add an "Enable integration" button

Next, you'll add anEnable integrationbutton to your Zendesk app. When an admin clicks the button, the app installs the job spec specified in your bundle. ZIS gets the job spec from the bundle you uploaded.

  1. In your Zendesk app'sassetsfolder, openiframe.html. Add the following HTML directly after the

    tag containing theConnect to Slackbutton.

                   
    ...Connect to Slackbutton>div><divclass="c-txt u-mb"><buttonid="btnEnableIntegration"class="c-btn c-btn--primary">Enable integrationbutton>div>...
  2. Inbootstrap.js, add the following:

                   
    ...fetchConfig(integrationName);// Bind button to install the job specdocument.getElementById("btnEnableIntegration").addEventListener("click",function(){enableIntegration(integrationName);});...

    The code binds theEnable integrationbutton to theenableIntegrationfunction.

  3. In theassetsfolder, create aregistry.jsfile. Paste the following into the file:

                   
    // Install the job spec.functionenableIntegration(integrationName){constjobSpec="zis:"+integrationName+":job_spec:post_message_to_slack_on_ticket_creation_job_spec";letrequest={type:"POST",url:"/api/services/zis/integrations/"+integrationName+"/job_specs/installation",contentType:"application/json",data:JSON.stringify([{name:jobSpec}]),};returnclient.request(request).then(function(){console.log("Integration enabled");client.invoke("notify","Integration enabled");},function(error){console.log("Failed to enable flow: ",response);});}

    The code defines theenableIntegrationfunction. When called,enableIntegrationuses theInstall Job Specendpoint to install the job spec defined in your bundle.

  4. Iniframe.html, add the following:

                   
    ...<scripttype="text/javascript"src="config.js">script><scripttype="text/javascript"src="registry.js">script>...
  5. 保存iframe.html,bootstrap.js, andregistry.js. Then refresh the app.

    Your app now displays anEnable integrationbutton.

Install the job spec

Next, use theEnable Integrationbutton to install the job spec.

In your app, clickEnable integration. A success notification is displayed.

Test the integration

To test the integration, create a ticket with the "urgent" priority in Zendesk. To create the ticket, use the Zendesk Agent Workspace or run:

             
curl-XPOSThttps://{subdomain}.亚博.com/api/v2/tickets.json \-u{email_address}:{password}\-H"Content-Type: application/json"\-d '{"ticket":{"subject":"My printer is on fire!","priority":"urgent","status":"open","comment":{"body":"The smoke is very colorful."}}}'

The integration posts a message in the configured Slack channel.

Congratulations! You've completed this tutorial series. You now have a working integration and Zendesk app.

As a next step, you can install your Zendesk app as a private app if wanted. Refer toUploading and installing a private app.