Skip to content

Commit 7fbb1e4

Browse files
authored
Add Zendesk Auth Provider docs (#354)
* WIP: Add Zendesk Auth Provider docs * Finish writing Zendesk auth provider docs * Add test to Makefile
1 parent 7feb681 commit 7fbb1e4

6 files changed

Lines changed: 317 additions & 0 deletions

File tree

Makefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,21 @@ install: ## Install the dependencies
1212
build: ## Build the docs site
1313
@pnpm build
1414

15+
test: ## Run the tests
16+
@pnpm test -- --run
1517

1618
run: ## Run the docs site locally
1719
@pnpm dev
20+
21+
ruin:
22+
@echo "\033[31m\033[1m💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️\033[0m"
23+
@echo "\033[31m\033[1m👻 👻\033[0m"
24+
@echo "\033[31m\033[1m🔥 With but a single command, the realm 🔥\033[0m"
25+
@echo "\033[31m\033[1m🔥 of order shall collapse into chaos. 🔥\033[0m"
26+
@echo "\033[31m\033[1m👻 👻\033[0m"
27+
@echo "\033[31m\033[1m⚡ Beware, for what is ruined today may ⚡\033[0m"
28+
@echo "\033[31m\033[1m⚡ take an eternity to rebuild. ⚡\033[0m"
29+
@echo "\033[31m\033[1m👻 👻\033[0m"
30+
@echo "\033[31m\033[1m🎃 - The Elders of Makefile 🎃\033[0m"
31+
@echo "\033[31m\033[1m👻 👻\033[0m"
32+
@echo "\033[31m\033[1m💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️💀☠️\033[0m"
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
auth:
2+
providers:
3+
- id: zendesk
4+
description: "Custom Zendesk provider"
5+
enabled: true
6+
type: oauth2
7+
client_id: ${env:ZENDESK_CLIENT_ID}
8+
oauth2:
9+
scope_delimiter: ' '
10+
pkce:
11+
enabled: true
12+
code_challenge_method: S256
13+
authorize_request:
14+
endpoint: 'https://<your-zendesk-subdomain>.zendesk.com/oauth/authorizations/new'
15+
params:
16+
client_id: '{{client_id}}'
17+
redirect_uri: '{{redirect_uri}}'
18+
scope: '{{scopes}} {{existing_scopes}}'
19+
response_type: code
20+
token_request:
21+
endpoint: 'https://<your-zendesk-subdomain>.zendesk.com/oauth/tokens'
22+
params:
23+
grant_type: authorization_code
24+
client_id: '{{client_id}}'
25+
redirect_uri: '{{redirect_uri}}'
26+
response_content_type: application/json
27+
response_map:
28+
access_token: '$.access_token'
29+
refresh_token: '$.refresh_token'
30+
expires_in: '$.expires_in'
31+
scope: '$.scope'
32+
refresh_request:
33+
endpoint: 'https://<your-zendesk-subdomain>.zendesk.com/oauth/tokens'
34+
params:
35+
grant_type: refresh_token
36+
refresh_token: '{{refresh_token}}'
37+
client_id: '{{client_id}}'
38+
response_content_type: application/json
39+
response_map:
40+
access_token: '$.access_token'
41+
refresh_token: '$.refresh_token'
42+
expires_in: '$.expires_in'
43+
scope: '$.scope'
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Arcade } from "@arcadeai/arcadejs";
2+
3+
const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
4+
5+
const userId = "{arcade_user_id}";
6+
7+
// Start the authorization process
8+
let authResponse = await client.auth.start(userId, {
9+
provider: "zendesk",
10+
scopes: ["read_account"],
11+
});
12+
13+
if (authResponse.status !== "completed") {
14+
console.log("Please complete the authorization challenge in your browser:");
15+
console.log(authResponse.url);
16+
}
17+
18+
// Wait for the authorization to complete
19+
authResponse = await client.auth.waitForCompletion(authResponse);
20+
21+
const token = authResponse.context.token;
22+
23+
// Do something interesting with the token...
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from arcadepy import Arcade
2+
3+
client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
4+
5+
# Start the authorization process
6+
auth_response = client.auth.start(
7+
user_id="{arcade_user_id}",
8+
provider="zendesk",
9+
scopes=["read_account"],
10+
)
11+
12+
if auth_response.status != "completed":
13+
print("Please complete the authorization challenge in your browser:")
14+
print(auth_response.url)
15+
16+
# Wait for the authorization to complete
17+
auth_response = client.auth.wait_for_completion(auth_response)
18+
19+
token = auth_response.context.token
20+
21+
# Do something interesting with the token...
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from typing import Annotated, Any
2+
3+
from arcade_tdk import ToolContext, tool
4+
from arcade_tdk.auth import OAuth2
5+
6+
import httpx
7+
8+
9+
@tool(
10+
requires_auth=OAuth2(id="zendesk", scopes=["read"]),
11+
requires_secrets=["ZENDESK_SUBDOMAIN"],
12+
)
13+
async def get_tickets(
14+
context: ToolContext
15+
) -> Annotated[dict[str, Any], "Recent tickets from Zendesk"]:
16+
"""Get recent tickets from Zendesk including basic ticket information"""
17+
token = context.get_auth_token_or_empty()
18+
subdomain = context.get_secret("ZENDESK_SUBDOMAIN")
19+
url = f"https://{subdomain}.zendesk.com/api/v2/tickets.json"
20+
headers = {
21+
"Authorization": f"Bearer {token}",
22+
"Content-Type": "application/json",
23+
"Accept": "application/json",
24+
}
25+
26+
async with httpx.AsyncClient() as client:
27+
resp = await client.get(url, headers=headers)
28+
resp.raise_for_status()
29+
data = resp.json()
30+
31+
return {"tickets": data}
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
import { Tabs } from "nextra/components";
2+
import { SignupLink } from "@/components/Analytics";
3+
4+
# Zendesk Auth Provider
5+
6+
<Note>
7+
Arcade does not offer a default Zendesk Auth Provider. To use Zendesk auth, you must create
8+
a [custom provider configuration](/home/auth-providers/oauth2) as described below.
9+
</Note>
10+
11+
The Zendesk auth provider enables tools and agents to call Zendesk APIs on behalf of a user. Behind the scenes, the Arcade Engine and the Zendesk auth provider seamlessly manage Zendesk OAuth 2.0 authorization for your users.
12+
13+
## What's documented here
14+
15+
This page describes how to use and configure Zendesk auth with Arcade.
16+
17+
This auth provider is used by:
18+
19+
- The [Arcade Zendesk toolkit](/toolkits/customer-support/zendesk), which provides pre-built tools for interacting with Zendesk services
20+
- Your [app code](#using-zendesk-auth-in-app-code) that needs to call Zendesk APIs
21+
- Or, your [custom tools](#using-zendesk-auth-in-custom-tools) that need to call Zendesk APIs
22+
23+
## Create a Zendesk app
24+
25+
### Additional guides
26+
The following two guides from Zendesk will be helpful additional information as you progress through this guide:
27+
1. [Using OAuth authentication with your application](https://support.zendesk.com/hc/en-us/articles/4408845965210-Using-OAuth-authentication-with-your-application)
28+
2. [Set up a global OAuth client](https://developer.zendesk.com/documentation/marketplace/building-a-marketplace-app/set-up-a-global-oauth-client/)
29+
30+
### Creating a Zendesk app for Arcade
31+
1. Create your Organization in the [Zendesk Marketplace portal](https://apps.zendesk.com/).
32+
1. Create a Zendesk support account at https://www.zendesk.com/login . If you need a global OAuth client, then the subdomain MUST begin with "d3v-". You will need a global OAuth client if your app will use integrations/tools for multiple customers with their own Zendesk instances (multiple subdomains).
33+
1. In [the Admin Center](https://support.zendesk.com/hc/en-us/articles/4581766374554#topic_hfg_dyz_1hb), click "Apps and integrations" in the sidebar, then select APIs > OAuth clients > Add OAuth client.
34+
* Ensure your identifier is prefixed with "zdg-" If you will need a global OAuth client.
35+
* Select "Public" for "Client kind".
36+
* Use `https://cloud.arcade.dev/api/v1/oauth/callback` as your "Redirect URL".
37+
1. Copy and store your identifier for later. This will be your **Client ID**.
38+
1. Copy and store your generated secret for later. This will be your **Client Secret**.
39+
1. (Only for Global OAuth client) Request a global OAuth client.
40+
* Sign into the [Zendesk Marketplace portal](https://apps.zendesk.com/)
41+
* Organization > Global OAuth Request and fill out the form. Zendesk will typically review your request within 1 week.
42+
43+
44+
45+
## Get your Zendesk subdomain
46+
47+
Your Zendesk subdomain is the value before the `.zendesk.com` part. For example, if your Zendesk domain is `https://d3v-acme-inc.zendesk.com`, your Zendesk subdomain is `d3v-acme-inc`. Take note of your Zendesk subdomain. You will need this value in the next steps.
48+
49+
## Set the Zendesk Subdomain Secret
50+
51+
Set the `ZENDESK_SUBDOMAIN` secret in the [Arcade Dashboard](https://api.arcade.dev/dashboard/auth/secrets).
52+
53+
## Configuring Zendesk Auth
54+
55+
You can either configure Zendesk auth from the Arcade Dashboard or in the `engine.yaml` file if you are running the Engine yourself. We describe both options below.
56+
57+
<Tabs items={["Dashboard GUI", "Engine Configuration YAML"]}>
58+
<Tabs.Tab>
59+
60+
### Configure Zendesk Auth Using the Arcade Dashboard GUI
61+
62+
<Steps>
63+
64+
#### Access the Arcade Dashboard
65+
66+
Navigate to the [Arcade Dashboard](https://api.arcade.dev/dashboard/auth/oauth) OAuth Providers page.
67+
68+
#### Navigate to the Add Custom Provider page
69+
70+
- Click **Add OAuth Provider** in the top right corner.
71+
- Click the **Custom Provider** tab at the top.
72+
73+
#### Enter the provider details
74+
75+
- ID: `zendesk`
76+
- Description: `<your description>`
77+
- Client ID: `<your identifier>` (This is prefixed with `zdg-` if you are using a global OAuth client)
78+
- Client Secret: `<your client secret>`
79+
- Authorization Endpoint: `https://<your-zendesk-subdomain>.zendesk.com/oauth/authorizations/new`
80+
- Token Endpoint: `https://<your-zendesk-subdomain>.zendesk.com/oauth/tokens`
81+
- PKCE Settings:
82+
- Enable PKCE: `enabled`
83+
- PKCE Method: `S256` (Default)
84+
- Authorization Settings:
85+
- Response Type: `code` (Default)
86+
- Scope: `{{scopes}} {{existing_scopes}}` (Default)
87+
- Token Settings:
88+
- Authentication Method: `Client Secret Basic` (Default)
89+
- Response Content Type: `application/json` (Default)
90+
- Refresh Token Settings:
91+
- Refresh Token Endpoint: `https://<your-zendesk-subdomain>.zendesk.com/oauth/tokens`
92+
- Authentication Method: `Client Secret Basic` (Default)
93+
- Response Content Type: `application/json`
94+
- Token Introspection Settings:
95+
- Enable Token Introspection: `disabled` (Default)
96+
97+
</Steps>
98+
</Tabs.Tab>
99+
100+
<Tabs.Tab>
101+
102+
### Configure Zendesk Auth Using the Engine Configuration YAML
103+
104+
<Tip>
105+
Refer to [Engine configuration](/home/local-deployment/configure/engine) for more information on how to set environment variables and configure the Arcade Engine.
106+
</Tip>
107+
108+
<Tip>
109+
To find where the `engine.yaml` file is located in your OS after installing the Arcade Engine, check the [Engine configuration file](/home/local-deployment/configure/overview#engine-configuration-file) documentation.
110+
</Tip>
111+
112+
<Steps>
113+
114+
#### Set environment variables
115+
116+
Set the following environment variables:
117+
118+
```bash
119+
export ZENDESK_CLIENT_ID="<your client ID>"
120+
export ZENDESK_CLIENT_SECRET="<your client secret>"
121+
```
122+
123+
Or, you can set these values in a `.env` file:
124+
125+
```bash
126+
ZENDESK_CLIENT_ID="<your client ID>"
127+
ZENDESK_CLIENT_SECRET="<your client secret>"
128+
```
129+
130+
#### Edit the Engine configuration
131+
132+
<Note>
133+
In the YAML code demonstrated below, replace `<your-zendesk-subdomain>` in the endpoint URLs with your Zendesk subdomain.
134+
</Note>
135+
136+
Edit the `engine.yaml` file by adding a Zendesk item to the `auth.providers` section:
137+
138+
```yaml file=<rootDir>/examples/code/integrations/zendesk/config_provider.engine.yaml {3-43}
139+
140+
```
141+
142+
#### Restart the Arcade Engine
143+
144+
If the Arcade Engine is already running, you will need to restart it for the changes to take effect.
145+
146+
</Steps>
147+
</Tabs.Tab>
148+
149+
</Tabs>
150+
151+
## Using Zendesk auth in app code
152+
153+
Use the Zendesk auth provider you just created in your own agents and AI apps to get a user token for Zendesk APIs. See [authorizing agents with Arcade](/home/auth/how-arcade-helps) to understand how this works.
154+
155+
Use `client.auth.start()` to get a user token for Zendesk APIs:
156+
157+
<Tabs items={["Python", "JavaScript"]} storageKey="preferredLanguage">
158+
<Tabs.Tab>
159+
160+
```python file=<rootDir>/examples/code/integrations/zendesk/custom_auth.py {6-10}
161+
162+
```
163+
164+
</Tabs.Tab>
165+
166+
<Tabs.Tab>
167+
168+
```javascript file=<rootDir>/examples/code/integrations/zendesk/custom_auth.js {8-11}
169+
170+
```
171+
172+
</Tabs.Tab>
173+
174+
</Tabs>
175+
176+
## Using Zendesk auth in custom tools
177+
178+
If the [Arcade Zendesk toolkit](/toolkits/customer-support/zendesk) does not meet your needs, you can author your own [custom tools](/home/build-tools/create-a-toolkit) that interact with Zendesk APIs.
179+
180+
Use the `OAuth2()` auth class to specify that a tool requires authorization with Zendesk. The `context.authorization.token` field will be automatically populated with the user's Zendesk token:
181+
182+
```python file=<rootDir>/examples/code/integrations/zendesk/custom_tool.py
183+
184+
```

0 commit comments

Comments
 (0)