In this tutorial, you'll use an event from a ZIS inbound webhook to kick off a ZIS flow. You can use an inbound webhook to send custom events to ZIS from a third-party system.

What you'll need

To complete this tutorial, you'll need the following:

Creating the integration

The ZIS integration you create listens for user creation events from a third-party system named Acme. Acme sends the events to ZIS using an inbound webhook. When it detects the event, the integration uses the event's data to create a user profile in Zendesk.

  1. Create an OAuth connection named "zendesk". You'll use the connection to authenticate Zendesk API requests in the integration's ZIS flow.

    In a typical setup, an admin uses a private Zendesk app to create OAuth connections. For this tutorial, you'll create a "zendesk" connection without an app.

    To create the connection, follow the steps in Creating an OAuth connection for Zendesk. Then return here.

  2. Create a JSON file named my_zis_bundle.json.

  3. Add the following bundle skeleton to my_zis_bundle.json:

    {  "name": "Example integration with a ZIS inbound webhook",  "description": "Create Zendesk user for new Acme system user",  "zis_template_version": "2019-10-14",  "resources": {    "AddZendeskUser": {      "_placeholder_": "ZIS custom action definition goes here"    },    "NewAcmeUserFlow": {      "_placeholder_": "ZIS flow goes here"    },    "NewAcmeUserJobSpec": {      "_placeholder_": "ZIS job spec goes here"    }  }}

    You'll define the custom action, ZIS flow, and job spec in the next steps.

  4. In my_zis_bundle.json, replace the AddZendeskUser placeholder with the following custom action definition.

    "AddZendeskUser": {  "type": "ZIS::Action::Http",  "properties": {    "name": "AddZendeskUser",    "definition": {      "method": "POST",      "path": "/api/v2/users",      "connectionName": "zendesk",      "headers": [        {          "key": "Content-Type",          "value": "application/json"        }      ],      "requestBody": {        "user": {          "name.$": "$.user_name",          "email.$": "$.email",          "role.$": "$.role"        }      }    }  }},

    When called, the action sends a POST request to the Zendesk API's Create User endpoint. The request body contains the user's name, email address, and role.

  5. Replace the NewAcmeUserFlow placeholder with the following ZIS flow definition. In the definition, replace "INTEGRATION" with your integration key.

    "NewAcmeUserFlow": {  "type": "ZIS::Flow",  "properties": {    "name": "NewAcmeUserFlow",    "definition": {      "StartAt": "AddZendeskUser",      "States": {        "AddZendeskUser": {          "Type": "Action",          "ActionName": "zis:INTEGRATION:action:AddZendeskUser",          "Parameters": {            "user_name.$": "$",            "email.$": "$",            "role": "agent"          },          "End": true        }      }    }  }},

    The flow contains a single Action state. The state calls the custom action you defined in the previous step. The state requires and values from the event.

  6. Replace the NewAcmeUserSpec placeholder with the following job spec definition. In the definition, replace "INTEGRATION" with your integration key.

    "NewAcmeUserSpec": {  "type": "ZIS::JobSpec",  "properties": {    "name": "NewAcmeUserSpec",    "event_source": "acme_system",    "event_type": "user_created",    "flow_name": "zis:INTEGRATION:flow:NewAcmeUserFlow"  }}

    The job spec tells ZIS to run the ZIS flow when it detects an event with an event_source of "acme_system" and an event_type of "user_created".

  7. Save my_zis_bundle.json. The file should now look like this:

    {  "name": "Example integration with a ZIS inbound webhook",  "description": "Create Zendesk user for new Acme system user",  "zis_template_version": "2019-10-14",  "resources": {    "AddZendeskUser": {      "type": "ZIS::Action::Http",      "properties": {        "name": "AddZendeskUser",        "definition": {          "method": "POST",          "path": "/api/v2/users",          "connectionName": "zendesk",          "headers": [            {              "key": "Content-Type",              "value": "application/json"            }          ],          "requestBody": {            "user": {              "name.$": "$.user_name",              "email.$": "$.email",              "role.$": "$.role"            }          }        }      }    },    "NewAcmeUserFlow": {      "type": "ZIS::Flow",      "properties": {        "name": "NewAcmeUserFlow",        "definition": {          "StartAt": "AddZendeskUser",          "States": {            "AddZendeskUser": {              "Type": "Action",              "ActionName": "zis:INTEGRATION:action:AddZendeskUser",              "Parameters": {                "user_name.$": "$",                "email.$": "$",                "role": "agent"              },              "End": true            }          }        }      }    },    "NewAcmeUserSpec": {      "type": "ZIS::JobSpec",      "properties": {        "name": "NewAcmeUserSpec",        "event_source": "acme_system",        "event_type": "user_created",        "flow_name": "zis:INTEGRATION:flow:NewAcmeUserFlow"      }    }  }}
  8. Upload the bundle to ZIS.

    curl -X POST https://{subdomain}{integration}/bundles \  -u {email}:{password} \  -H "Content-Type: application/json" \  -d @my_zis_bundle.json
  9. Install the job spec to enable the integration.

    curl -X POST "https://{subdomain}{integration}:job_spec:NewAcmeUserSpec" \  -u {email}:{password}

Creating the ZIS inbound webhook

Next, create a ZIS inbound webhook. The following request creates a webhook with a source_system of "acme_system" and an event_type of "user_created". This matches the source_type and event_type of the integration's job spec.

curl -X POST https://{subdomain}{integration} \  -H "Authorization: Bearer {access_token}" \  -H "content-type: application/json" \  -d '{    "source_system": "acme_system",    "event_type": "user_created"  }'

Save the response in a safe place. Later, you'll use the response's path, username, and password to send event data to the webhook's ingest URL.

{  "event_type": "user_created",  "id": "01FDXQXBGQRZ3XN28WKX559PR2",  "integration": "INTEGRATION",  "password": "***password***",  "path": "/api/services/zis/inbound_webhooks/generic/ingest/xyz",  "source_system": "acme_system",  "username": "***username***",  "uuid": "d339ba7f-4a42-40fc-ae75-0e93315d3d0f",  "zendesk_account_id": 1}

Testing the integration

To test the integration, send event data for a test user to the webhook's ingest URL. Then verify the integration created a related Zendesk user profile.

  1. Make a POST request to the webhook's ingest URL. In a typical setup, a developer configures the third-party system to make these requests in response to events in the system. For this tutorial, you'll make the request using the following curl command.

    In the command, replace "{path}", "{username}", and "{password}" with values you saved when creating the webhook. The request body contains the event data as JSON.

    Important: Escape any reserved URI characters in the "{username}" or "{password}" with a leading backslash (\). For example, you'd escape "myp@s$word" as "myp\@s\$word".

    curl -X POST https://{subdomain}{path} \  -u {username}:{password} \  -H "content-type: application/json" \  -i -d '{    "user": {      "name": "John Doe",      "email": "[email protected]"    }  }'

    If successful, the request returns a 200 HTTP status code.

  2. Search for the test user's Zendesk profile using the address from step 1.

    curl https://{subdomain} \  -u {email}:{password} \  -G --data-urlencode "query=email:[email protected]"

    The response contains the test user's id, name, email address, and role. You'll use the id in the next step.

    {  "users": [    {      "id": 12345,      "url": "",      "name": "John Doe",      "email": "[email protected]",      ...      "role": "agent",      ...    }  ],  "next_page": null,  "previous_page": null,  "count": 1}

    You also can verify the test user exists using the Zendesk Admin Center.

  3. To clean up, delete the test user's profile. Replace "{user_id}" with the id from the previous step.

    curl -X DELETE https://{subdomain}{user_id}.json \  -u {email_address}:{password}

    To permanently delete the test user, run the following request afterward.

    curl -X DELETE https://{subdomain}{user_id}.json \  -u {email_address}:{password}