Part 1: Build a Zendesk app with OAuth
In this tutorial series, you'll build a Zendesk integration for Slack. The integration listens for Ticket Created events in Zendesk. When it detects an event with a specific ticket priority, the integration posts a related message to a provided Slack channel.
As part of the series, you'll also build a Zendesk app. The app's user interface (UI) lets admins connect the integration to their Zendesk and Slack instances. The app also lets admins configure settings for the integration. The app uses Zendesk Integration Services (ZIS) APIs to manage the connections and configurations.
This tutorial covers the first steps for setting up the integration and the Zendesk app. Other tutorials in the series teach you how to finish building the app and install the integration:
For on-demand training related to this tutorial series, check out the free Build a Custom Integration With ZIS training course.
Disclaimer: Zendesk provides this article for instructional purposes only. The integration and examples are not meant for production environments. Zendesk does not provide support for this integration or app. Post any issue in the Zendesk developer community or search for a solution online.
What you'll need
To complete this tutorial, you’ll need the following:
-
A Zendesk account for testing. ZIS is supported on the Zendesk Suite Growth plan or above, and the Support Professional plan or above. To get a free eligible account for testing, see Getting a trial or sponsored account for development.
-
Be an admin on the account or have access to someone who is an admin. The admin can give you admin access. Refer to Setting roles and access in Zendesk Admin Center.
-
A Slack workspace for testing. If you need a workspace, refer to Create a Slack workspace.
-
The Zendesk Command Line Interface (ZCLI). To install or upgrade ZCLI, refer to Installing and updating ZCLI. ZCLI replaces the Zendesk Apps Tools (ZAT), which are in maintenance mode. To use ZAT instead, refer to Installing and using ZAT.
-
Familiarity with ZIS and the Zendesk Apps framework (ZAF). Before starting, we recommend you complete the following tutorials:
-
Familiarity with basic OAuth 2.0 concepts, such as OAuth flows and access tokens. To learn more about OAuth, check out Using OAuth authentication with your application.
Register the integration
First, register the integration's name using the Create Integration endpoint.
Integration names must be globally unique. For this tutorial, use an integration
name of {subdomain}_zendesk_to_slack
. Replace {subdomain}
with your Zendesk
subdomain.
-
In your command-line interface, run:
curl -X POST https://{subdomain}.zendesk.com/api/services/zis/registry/{subdomain}_zendesk_to_slack \
-u {email_address}/token:{api_token} \
-H "Content-type: application/json" \
-d '{"description": "An example integration"}'
The integration uses an OAuth connection to make Zendesk API requests on the admin's behalf. To create the connection, your Zendesk app uses ZIS APIs to start an OAuth flow. To start an OAuth flow, ZIS first requires an OAuth client. The client contains details used to pass data between ZIS and the other system during the OAuth flow.
When you register an integration, the request automatically creates an OAuth client for Zendesk. The client is named "zendesk." The response contains information about your integration and its OAuth client. For example:
{
"description": "An example integration",
"jwt_public_key": "***RSA Public Key to save***",
"zendesk_oauth_client": {
"id": 12345,
"identifier": "zis_{subdomain}_zendesk_to_slack",
"secret": "***secret***"
}
}
-
Save the response securely. You’ll use these details later in this tutorial.
Create a Zendesk app
Next, use ZCLI to create starter files for a Zendesk app named Zendesk to Slack Notifier.
-
In your command-line interface, navigate to the folder you'll use to store the app. For example:
cd projects
-
In the folder, run the following ZCLI command:
zcli apps:new
-
At the prompts, enter the following values:
- Directory name: zendesk_to_slack_app
- Author's name: Your name
- Author's email: Your email address
- Author's website: Leave blank and press Enter.
- App name: Zendesk to Slack Notifier
ZCLI creates app starter files in the zendesk_to_slack_app folder.
Set app location
Update your app to run in the nav bar of the Zendesk Support UI. This location lets admins access the app from any Support page.
-
In the zendesk_to_slack_app folder, open manifest.json in your text editor.
-
Replace the
location
property with the following:"location": {
"support": {
"nav_bar": "assets/iframe.html"
}
},
-
Save manifest.json.
Test the app
Your app doesn't do much yet, but you can already use ZCLI to run it. Run your app often to test changes.
-
In your command-line interface, navigate to the zendesk_to_slack_app folder. For example:
cd projects/zendesk_to_slack_app
-
Start a ZCLI local web server by running the following command:
zcli apps:server
After a moment, a status message appears informing you that the server has started.
Note: To stop the server, press Ctrl+C.
-
In your browser's private or incognito window, sign in to Zendesk Support and go to the Agent Dashboard. The URL should look like this:
https://{subdomain}.zendesk.com/agent/dashboard
-
Append
?zcli_apps=true
to the URL and press Enter. The URL should now look like this:https://{subdomain}.zendesk.com/agent/dashboard?zcli_apps=true
An app icon is displayed in the left nav bar.
-
Click the icon to launch the app.
The app displays a "Hello, World!" heading.
Connect to Zendesk
The app's UI should include a Connect to Zendesk button. When an admin clicks the button, the app uses ZIS APIs to start an OAuth flow with Zendesk. When done, the OAuth flow sends a Zendesk access token to ZIS for storage.
Add a "Connect to Zendesk" button
-
In the app's assets folder, open iframe.html. Replace the file's contents with the following:
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Loads Zendesk Garden CSS components -->
<link
href="https://cdn.jsdelivr.net/combine/npm/@zendeskgarden/css-bedrock,npm/@zendeskgarden/css-grid,npm/@zendeskgarden/css-buttons,npm/@zendeskgarden/css-forms,npm/@zendeskgarden/css-utilities"
rel="stylesheet"
/>
</head>
<body>
<div class="u-m u-fg-grey-800">
<div class="u-mb">
<div class="row">
<div class="col-6">
<div class="c-txt u-mb">
<button id="btnConnect" class="c-btn c-btn--primary">
Connect to Zendesk
</button>
</div>
</div>
</div>
</div>
</div>
<script
type="text/javascript"
src="https://static.zdassets.com/zendesk_app_framework_sdk/2.0/zaf_sdk.min.js"
></script>
<!-- Bootstrap the app -->
<script type="text/javascript" src="bootstrap.js"></script>
<!-- Establish OAuth connections -->
<script type="text/javascript" src="connect.js"></script>
</body>
</html>
The HTML includes the following:
-
A stylesheet for the app's UI. This app uses Garden, Zendesk's design system. For simplicity, the app uses Zendesk Garden's CSS components. For a real-world app, we recommend using Garden's React components.
-
Markup for the Connect to Zendesk button.
-
A
<script>
tag that imports the ZAF SDK library. -
<script>
tags that load bootstrap.js and connect.js. You'll create these files in the next steps.
-
-
In the assets folder, create a bootstrap.js file. Paste the following into the file:
// Bootstrap the app when the DOM is ready
(function () {
// Initialize the Zendesk JavaScript API client
// https://developer.zendesk.com/apps/docs/developer-guide/getting_started
window.client = ZAFClient.init();
// OAuth flow kick-off requires a subdomain
let subdomain = undefined;
// Integration name is the unique identifier for your integration app
let integrationName = undefined;
client
.context()
.then(function (context) {
// Derive subdomain & integration name
subdomain = context["account"]["subdomain"];
integrationName = subdomain + "_zendesk_to_slack";
})
.then(function () {
// Bind button to start a Zendesk OAuth flow
document
.getElementById("btnConnect")
.addEventListener("click", function () {
startOAuth(integrationName, subdomain);
});
});
})();
The code contains an anonymous, self-invoking function. This function runs when the app loads. The top part of the function initializes a ZAF client. The ZAF client lets your app use the current browser session to authenticate Zendesk API requests.
The second part of the function binds the Connect to Zendesk button to the
startOAuth
function. When an admin clicks the button, the code calls the function. You'll define the function in the next step. -
In the assets folder, create a connect.js file. Paste the following into the file:
// Starts a Zendesk OAuth flow
function startOAuth(integrationName, subdomain) {
// Human-readable name for the Zendesk OAuth client
// ZIS creates this client when you register an integration
const zendeskOAuthClientName = "zendesk";
// Human-readable name for the Zendesk OAuth connection
const zendeskConnectionName = "zendesk";
let data = JSON.stringify({
name: zendeskConnectionName,
oauth_client_name: zendeskOAuthClientName,
oauth_url_subdomain: subdomain,
origin_oauth_redirect_url: window.location.href,
permission_scopes: "read write",
});
let request = {
type: "POST",
url: "/api/services/zis/connections/oauth/start/" + integrationName,
contentType: "application/json",
data: data,
};
client.request(request).then(
function (response) {
console.log("Zendesk OAuth started");
authorize(response.redirect_url);
},
function (response) {
console.log("Failed to start Zendesk OAuth: ", response);
}
);
}
function authorize(redirectURL) {
let authWindow = window.open(redirectURL, "_blank");
setTimeout(watchToken, 1500);
// Poll token from the newly opened window
function watchToken() {
try {
let params = new URL(authWindow.location.href).searchParams;
// Cross-origin access will cause an error.
// When the OAuth flow completes, the authWindow's location
// redirects back to the same origin.
// This lets ZIS get the verification token.
let verificationToken = params.get("verification_token");
console.log("Established connection");
authWindow.close();
} catch (err) {
console.log(
"DOM error expected during cross domain authorization: " + err
);
setTimeout(watchToken, 500);
}
}
}
The code defines the
startOAuth
function. When called,startOAuth
makes a Start OAuth Flow request to kick off an OAuth flow with Zendesk. The request uses the "zendesk" client you created earlier. When the OAuth flow completes, ZIS stores the resulting access token in an OAuth connection.The Start OAuth Flow endpoint requires a name for the connection.
startOAuth
uses a connection name of "zendesk." -
Save iframe.html, bootstrap.js, and connect.js. To review your changes, click the refresh icon above the app.
Your app now displays a Connect to Zendesk button.
Get a Zendesk access token
Next, it's time to test your app. Use the Connect to Zendesk button to start a Zendesk OAuth flow in the same way an admin would.
-
In your app, click Connect to Zendesk.
A Zendesk OAuth page opens in a new tab.
-
Click Allow.
The OAuth page closes and redirects back to the app.
Behind the scenes, ZIS creates a "zendesk" OAuth connection. The connection contains an access token for your Zendesk instance.
Verify the Zendesk access token
Next, use a Show OAuth Connection request to get the "zendesk" connection you created. This lets you verify that your integration can use the connection to authenticate Zendesk API requests.
-
The Show OAuth Connection endpoint requires an OAuth access token for authentication.
To get an OAuth access token, follow the steps in Obtaining a ZIS OAuth token. Provide the client identifier and secret you saved when you registered the integration. Then return here.
-
In your command-line interface, run:
curl -X GET https://{subdomain}.zendesk.com/api/services/zis/connections/{subdomain}_zendesk_to_slack?name=zendesk \
-H "Authorization: Bearer {access_token}"
The response contains details about the "zendesk" OAuth connection, including its access token. For example:
{
"uuid": "***uuid***",
"name": "zendesk",
"zendesk_account_id": 12345678,
"integration": "example_zendesk_to_slack",
"permission_scope": "read write",
"access_token": "***access token***",
"token_type": "bearer",
"refresh_token": "",
"token_expiry": "0001-01-01T00:00:00Z",
"oauth_access_token_response_body": "",
"oauth_url_subdomain": "example",
"created_by": "1234567890123",
"created_at": "2099-05-16T15:33:19Z"
}
In the next tutorial, you'll add a Connect to Slack button to your app. Refer to Part 2: Connect to Slack.