chub-dev 0.1.0 → 0.1.2-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -0
- package/bin/chub-mcp +2 -0
- package/dist/airtable/docs/database/javascript/DOC.md +1437 -0
- package/dist/airtable/docs/database/python/DOC.md +1735 -0
- package/dist/amplitude/docs/analytics/javascript/DOC.md +1282 -0
- package/dist/amplitude/docs/analytics/python/DOC.md +1199 -0
- package/dist/anthropic/docs/claude-api/javascript/DOC.md +503 -0
- package/dist/anthropic/docs/claude-api/python/DOC.md +389 -0
- package/dist/asana/docs/tasks/DOC.md +1396 -0
- package/dist/assemblyai/docs/transcription/DOC.md +1043 -0
- package/dist/atlassian/docs/confluence/javascript/DOC.md +1347 -0
- package/dist/atlassian/docs/confluence/python/DOC.md +1604 -0
- package/dist/auth0/docs/identity/javascript/DOC.md +968 -0
- package/dist/auth0/docs/identity/python/DOC.md +1199 -0
- package/dist/aws/docs/s3/javascript/DOC.md +1773 -0
- package/dist/aws/docs/s3/python/DOC.md +1807 -0
- package/dist/binance/docs/trading/javascript/DOC.md +1315 -0
- package/dist/binance/docs/trading/python/DOC.md +1454 -0
- package/dist/braintree/docs/gateway/javascript/DOC.md +1278 -0
- package/dist/braintree/docs/gateway/python/DOC.md +1179 -0
- package/dist/chromadb/docs/embeddings-db/javascript/DOC.md +1263 -0
- package/dist/chromadb/docs/embeddings-db/python/DOC.md +1707 -0
- package/dist/clerk/docs/auth/javascript/DOC.md +1220 -0
- package/dist/clerk/docs/auth/python/DOC.md +274 -0
- package/dist/cloudflare/docs/workers/javascript/DOC.md +918 -0
- package/dist/cloudflare/docs/workers/python/DOC.md +994 -0
- package/dist/cockroachdb/docs/distributed-db/DOC.md +1500 -0
- package/dist/cohere/docs/llm/DOC.md +1335 -0
- package/dist/datadog/docs/monitoring/javascript/DOC.md +1740 -0
- package/dist/datadog/docs/monitoring/python/DOC.md +1815 -0
- package/dist/deepgram/docs/speech/javascript/DOC.md +885 -0
- package/dist/deepgram/docs/speech/python/DOC.md +685 -0
- package/dist/deepl/docs/translation/javascript/DOC.md +887 -0
- package/dist/deepl/docs/translation/python/DOC.md +944 -0
- package/dist/deepseek/docs/llm/DOC.md +1220 -0
- package/dist/directus/docs/headless-cms/javascript/DOC.md +1128 -0
- package/dist/directus/docs/headless-cms/python/DOC.md +1276 -0
- package/dist/discord/docs/bot/javascript/DOC.md +1090 -0
- package/dist/discord/docs/bot/python/DOC.md +1130 -0
- package/dist/elasticsearch/docs/search/DOC.md +1634 -0
- package/dist/elevenlabs/docs/text-to-speech/javascript/DOC.md +336 -0
- package/dist/elevenlabs/docs/text-to-speech/python/DOC.md +552 -0
- package/dist/firebase/docs/auth/DOC.md +1015 -0
- package/dist/gemini/docs/genai/javascript/DOC.md +691 -0
- package/dist/gemini/docs/genai/python/DOC.md +555 -0
- package/dist/github/docs/octokit/DOC.md +1560 -0
- package/dist/google/docs/bigquery/javascript/DOC.md +1688 -0
- package/dist/google/docs/bigquery/python/DOC.md +1503 -0
- package/dist/hubspot/docs/crm/javascript/DOC.md +1805 -0
- package/dist/hubspot/docs/crm/python/DOC.md +2033 -0
- package/dist/huggingface/docs/transformers/DOC.md +948 -0
- package/dist/intercom/docs/messaging/javascript/DOC.md +1844 -0
- package/dist/intercom/docs/messaging/python/DOC.md +1797 -0
- package/dist/jira/docs/issues/javascript/DOC.md +1420 -0
- package/dist/jira/docs/issues/python/DOC.md +1492 -0
- package/dist/kafka/docs/streaming/javascript/DOC.md +1671 -0
- package/dist/kafka/docs/streaming/python/DOC.md +1464 -0
- package/dist/landingai-ade/docs/api/DOC.md +620 -0
- package/dist/landingai-ade/docs/sdk/python/DOC.md +489 -0
- package/dist/landingai-ade/docs/sdk/typescript/DOC.md +542 -0
- package/dist/landingai-ade/skills/SKILL.md +489 -0
- package/dist/launchdarkly/docs/feature-flags/javascript/DOC.md +1191 -0
- package/dist/launchdarkly/docs/feature-flags/python/DOC.md +1671 -0
- package/dist/linear/docs/tracker/DOC.md +1554 -0
- package/dist/livekit/docs/realtime/javascript/DOC.md +303 -0
- package/dist/livekit/docs/realtime/python/DOC.md +163 -0
- package/dist/mailchimp/docs/marketing/DOC.md +1420 -0
- package/dist/meilisearch/docs/search/DOC.md +1241 -0
- package/dist/microsoft/docs/onedrive/javascript/DOC.md +1421 -0
- package/dist/microsoft/docs/onedrive/python/DOC.md +1549 -0
- package/dist/mongodb/docs/atlas/DOC.md +2041 -0
- package/dist/notion/docs/workspace-api/javascript/DOC.md +1435 -0
- package/dist/notion/docs/workspace-api/python/DOC.md +1400 -0
- package/dist/okta/docs/identity/javascript/DOC.md +1171 -0
- package/dist/okta/docs/identity/python/DOC.md +1401 -0
- package/dist/openai/docs/chat/javascript/DOC.md +407 -0
- package/dist/openai/docs/chat/python/DOC.md +568 -0
- package/dist/paypal/docs/checkout/DOC.md +278 -0
- package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
- package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
- package/dist/plaid/docs/banking/javascript/DOC.md +1163 -0
- package/dist/plaid/docs/banking/python/DOC.md +1203 -0
- package/dist/playwright-community/skills/login-flows/SKILL.md +108 -0
- package/dist/postmark/docs/transactional-email/DOC.md +1168 -0
- package/dist/prisma/docs/orm/javascript/DOC.md +1419 -0
- package/dist/prisma/docs/orm/python/DOC.md +1317 -0
- package/dist/qdrant/docs/vector-search/javascript/DOC.md +1221 -0
- package/dist/qdrant/docs/vector-search/python/DOC.md +1653 -0
- package/dist/rabbitmq/docs/message-queue/javascript/DOC.md +1193 -0
- package/dist/rabbitmq/docs/message-queue/python/DOC.md +1243 -0
- package/dist/razorpay/docs/payments/javascript/DOC.md +1219 -0
- package/dist/razorpay/docs/payments/python/DOC.md +1330 -0
- package/dist/redis/docs/key-value/javascript/DOC.md +1851 -0
- package/dist/redis/docs/key-value/python/DOC.md +2054 -0
- package/dist/registry.json +2817 -0
- package/dist/replicate/docs/model-hosting/DOC.md +1318 -0
- package/dist/resend/docs/email/DOC.md +1271 -0
- package/dist/salesforce/docs/crm/javascript/DOC.md +1241 -0
- package/dist/salesforce/docs/crm/python/DOC.md +1183 -0
- package/dist/search-index.json +1 -0
- package/dist/sendgrid/docs/email-api/javascript/DOC.md +371 -0
- package/dist/sendgrid/docs/email-api/python/DOC.md +656 -0
- package/dist/sentry/docs/error-tracking/javascript/DOC.md +1073 -0
- package/dist/sentry/docs/error-tracking/python/DOC.md +1309 -0
- package/dist/shopify/docs/storefront/DOC.md +457 -0
- package/dist/slack/docs/workspace/javascript/DOC.md +933 -0
- package/dist/slack/docs/workspace/python/DOC.md +271 -0
- package/dist/square/docs/payments/javascript/DOC.md +1855 -0
- package/dist/square/docs/payments/python/DOC.md +1728 -0
- package/dist/stripe/docs/api/DOC.md +1727 -0
- package/dist/stripe/docs/payments/DOC.md +1726 -0
- package/dist/stytch/docs/auth/javascript/DOC.md +1813 -0
- package/dist/stytch/docs/auth/python/DOC.md +1962 -0
- package/dist/supabase/docs/client/DOC.md +1606 -0
- package/dist/twilio/docs/messaging/python/DOC.md +469 -0
- package/dist/twilio/docs/messaging/typescript/DOC.md +946 -0
- package/dist/vercel/docs/platform/DOC.md +1940 -0
- package/dist/weaviate/docs/vector-db/javascript/DOC.md +1268 -0
- package/dist/weaviate/docs/vector-db/python/DOC.md +1388 -0
- package/dist/zendesk/docs/support/javascript/DOC.md +2150 -0
- package/dist/zendesk/docs/support/python/DOC.md +2297 -0
- package/package.json +22 -6
- package/skills/get-api-docs/SKILL.md +84 -0
- package/src/commands/annotate.js +83 -0
- package/src/commands/build.js +12 -1
- package/src/commands/feedback.js +150 -0
- package/src/commands/get.js +83 -42
- package/src/commands/search.js +7 -0
- package/src/index.js +43 -17
- package/src/lib/analytics.js +90 -0
- package/src/lib/annotations.js +57 -0
- package/src/lib/bm25.js +170 -0
- package/src/lib/cache.js +69 -6
- package/src/lib/config.js +8 -3
- package/src/lib/identity.js +99 -0
- package/src/lib/registry.js +103 -20
- package/src/lib/telemetry.js +86 -0
- package/src/mcp/server.js +177 -0
- package/src/mcp/tools.js +251 -0
|
@@ -0,0 +1,2150 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: support
|
|
3
|
+
description: "Zendesk API JavaScript/Node.js SDK (node-zendesk) for helpdesk, tickets, and customer service integration"
|
|
4
|
+
metadata:
|
|
5
|
+
languages: "javascript"
|
|
6
|
+
versions: "6.0.1"
|
|
7
|
+
updated-on: "2026-03-02"
|
|
8
|
+
source: maintainer
|
|
9
|
+
tags: "zendesk,support,helpdesk,tickets,customer-service"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Zendesk API - JavaScript/Node.js SDK (node-zendesk)
|
|
13
|
+
|
|
14
|
+
## Golden Rule
|
|
15
|
+
|
|
16
|
+
**ALWAYS use the `node-zendesk` package (version 6.0.1 or later) for Zendesk API integration in JavaScript/Node.js projects.**
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install node-zendesk
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**DO NOT use:**
|
|
23
|
+
- `zendesk-node-api` (community alternative)
|
|
24
|
+
- `zendesk-node` (outdated)
|
|
25
|
+
- `@zendesk/client` (non-existent)
|
|
26
|
+
- Direct HTTP requests to Zendesk API endpoints (use the SDK instead)
|
|
27
|
+
|
|
28
|
+
The `node-zendesk` library is the officially recommended and most actively maintained Node.js client for the Zendesk API, with 10+ years of continuous support.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install node-zendesk
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
For TypeScript projects, the package includes TypeScript definitions:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install node-zendesk
|
|
42
|
+
# TypeScript definitions are included in the package
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Authentication & Initialization
|
|
48
|
+
|
|
49
|
+
### API Token Authentication (Recommended)
|
|
50
|
+
|
|
51
|
+
The most common authentication method uses username, API token, and subdomain:
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
const zendesk = require('node-zendesk');
|
|
55
|
+
|
|
56
|
+
const client = zendesk.createClient({
|
|
57
|
+
username: 'your_email@example.com',
|
|
58
|
+
token: 'your_api_token',
|
|
59
|
+
subdomain: 'your_subdomain'
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Environment Variables Example:**
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
require('dotenv').config();
|
|
67
|
+
const zendesk = require('node-zendesk');
|
|
68
|
+
|
|
69
|
+
const client = zendesk.createClient({
|
|
70
|
+
username: process.env.ZENDESK_USERNAME,
|
|
71
|
+
token: process.env.ZENDESK_API_TOKEN,
|
|
72
|
+
subdomain: process.env.ZENDESK_SUBDOMAIN
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**.env file:**
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
ZENDESK_USERNAME=your_email@example.com
|
|
80
|
+
ZENDESK_API_TOKEN=your_api_token_here
|
|
81
|
+
ZENDESK_SUBDOMAIN=your_company
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### OAuth Token Authentication
|
|
85
|
+
|
|
86
|
+
For OAuth-based authentication:
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
const zendesk = require('node-zendesk');
|
|
90
|
+
|
|
91
|
+
const client = zendesk.createClient({
|
|
92
|
+
token: 'your_oauth_access_token',
|
|
93
|
+
oauth: true,
|
|
94
|
+
subdomain: 'your_subdomain'
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**With Environment Variables:**
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
const client = zendesk.createClient({
|
|
102
|
+
token: process.env.ZENDESK_OAUTH_TOKEN,
|
|
103
|
+
oauth: true,
|
|
104
|
+
subdomain: process.env.ZENDESK_SUBDOMAIN
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### TypeScript/ES6 Import
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { createClient } from 'node-zendesk';
|
|
112
|
+
|
|
113
|
+
const client = createClient({
|
|
114
|
+
username: process.env.ZENDESK_USERNAME!,
|
|
115
|
+
token: process.env.ZENDESK_API_TOKEN!,
|
|
116
|
+
subdomain: process.env.ZENDESK_SUBDOMAIN!
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### User Impersonation
|
|
121
|
+
|
|
122
|
+
Make requests on behalf of end users (requires proper OAuth scopes):
|
|
123
|
+
|
|
124
|
+
```javascript
|
|
125
|
+
const client = zendesk.createClient({
|
|
126
|
+
username: process.env.ZENDESK_USERNAME,
|
|
127
|
+
token: process.env.ZENDESK_API_TOKEN,
|
|
128
|
+
subdomain: process.env.ZENDESK_SUBDOMAIN,
|
|
129
|
+
asUser: 'end-user@example.com'
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Custom Configuration
|
|
134
|
+
|
|
135
|
+
```javascript
|
|
136
|
+
const client = zendesk.createClient({
|
|
137
|
+
username: process.env.ZENDESK_USERNAME,
|
|
138
|
+
token: process.env.ZENDESK_API_TOKEN,
|
|
139
|
+
subdomain: process.env.ZENDESK_SUBDOMAIN,
|
|
140
|
+
remoteUri: 'https://custom.zendesk.com/api/v2', // Custom API endpoint
|
|
141
|
+
debug: true, // Enable debug logging
|
|
142
|
+
disableGlobalState: true, // Disable global state (for serverless)
|
|
143
|
+
retry: true, // Enable automatic retries
|
|
144
|
+
timeout: 30000 // Request timeout in ms (default: 60000)
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Core API Surfaces
|
|
151
|
+
|
|
152
|
+
### Tickets API
|
|
153
|
+
|
|
154
|
+
#### List All Tickets
|
|
155
|
+
|
|
156
|
+
**Basic Example:**
|
|
157
|
+
|
|
158
|
+
```javascript
|
|
159
|
+
// List all tickets
|
|
160
|
+
client.tickets.list()
|
|
161
|
+
.then(tickets => {
|
|
162
|
+
console.log('Total tickets:', tickets.length);
|
|
163
|
+
tickets.forEach(ticket => {
|
|
164
|
+
console.log(`#${ticket.id}: ${ticket.subject}`);
|
|
165
|
+
});
|
|
166
|
+
})
|
|
167
|
+
.catch(error => {
|
|
168
|
+
console.error('Error:', error.message);
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Advanced Example with Pagination:**
|
|
173
|
+
|
|
174
|
+
```javascript
|
|
175
|
+
// List tickets with pagination
|
|
176
|
+
async function listAllTickets() {
|
|
177
|
+
let page = 1;
|
|
178
|
+
let hasMore = true;
|
|
179
|
+
|
|
180
|
+
while (hasMore) {
|
|
181
|
+
const result = await client.tickets.list(page);
|
|
182
|
+
|
|
183
|
+
result.forEach(ticket => {
|
|
184
|
+
console.log(`Ticket #${ticket.id}: ${ticket.subject}`);
|
|
185
|
+
console.log(`Status: ${ticket.status}, Priority: ${ticket.priority}`);
|
|
186
|
+
console.log(`Created: ${ticket.created_at}`);
|
|
187
|
+
console.log('---');
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
hasMore = result.nextPage !== null;
|
|
191
|
+
page++;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
listAllTickets().catch(console.error);
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
#### Show Single Ticket
|
|
199
|
+
|
|
200
|
+
**Basic Example:**
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
const ticketId = 12345;
|
|
204
|
+
|
|
205
|
+
client.tickets.show(ticketId)
|
|
206
|
+
.then(ticket => {
|
|
207
|
+
console.log('Subject:', ticket.subject);
|
|
208
|
+
console.log('Status:', ticket.status);
|
|
209
|
+
console.log('Requester ID:', ticket.requester_id);
|
|
210
|
+
})
|
|
211
|
+
.catch(error => {
|
|
212
|
+
console.error('Error:', error.message);
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**Advanced Example:**
|
|
217
|
+
|
|
218
|
+
```javascript
|
|
219
|
+
async function getTicketDetails(ticketId) {
|
|
220
|
+
try {
|
|
221
|
+
const ticket = await client.tickets.show(ticketId);
|
|
222
|
+
|
|
223
|
+
console.log('=== Ticket Details ===');
|
|
224
|
+
console.log(`ID: ${ticket.id}`);
|
|
225
|
+
console.log(`Subject: ${ticket.subject}`);
|
|
226
|
+
console.log(`Description: ${ticket.description}`);
|
|
227
|
+
console.log(`Status: ${ticket.status}`);
|
|
228
|
+
console.log(`Priority: ${ticket.priority}`);
|
|
229
|
+
console.log(`Type: ${ticket.type}`);
|
|
230
|
+
console.log(`Requester ID: ${ticket.requester_id}`);
|
|
231
|
+
console.log(`Assignee ID: ${ticket.assignee_id}`);
|
|
232
|
+
console.log(`Group ID: ${ticket.group_id}`);
|
|
233
|
+
console.log(`Created: ${ticket.created_at}`);
|
|
234
|
+
console.log(`Updated: ${ticket.updated_at}`);
|
|
235
|
+
console.log(`Tags: ${ticket.tags.join(', ')}`);
|
|
236
|
+
|
|
237
|
+
// Custom fields
|
|
238
|
+
if (ticket.custom_fields && ticket.custom_fields.length > 0) {
|
|
239
|
+
console.log('Custom Fields:');
|
|
240
|
+
ticket.custom_fields.forEach(field => {
|
|
241
|
+
console.log(` ${field.id}: ${field.value}`);
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return ticket;
|
|
246
|
+
} catch (error) {
|
|
247
|
+
console.error('Failed to fetch ticket:', error.message);
|
|
248
|
+
throw error;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
getTicketDetails(12345);
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
#### Create Ticket
|
|
256
|
+
|
|
257
|
+
**Basic Example:**
|
|
258
|
+
|
|
259
|
+
```javascript
|
|
260
|
+
const newTicket = {
|
|
261
|
+
subject: 'Help with product installation',
|
|
262
|
+
comment: {
|
|
263
|
+
body: 'I need assistance installing the product on my system.'
|
|
264
|
+
},
|
|
265
|
+
requester: {
|
|
266
|
+
name: 'John Doe',
|
|
267
|
+
email: 'john.doe@example.com'
|
|
268
|
+
},
|
|
269
|
+
priority: 'normal',
|
|
270
|
+
status: 'new'
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
client.tickets.create(newTicket)
|
|
274
|
+
.then(ticket => {
|
|
275
|
+
console.log('Ticket created successfully!');
|
|
276
|
+
console.log('Ticket ID:', ticket.id);
|
|
277
|
+
console.log('Subject:', ticket.subject);
|
|
278
|
+
})
|
|
279
|
+
.catch(error => {
|
|
280
|
+
console.error('Error creating ticket:', error.message);
|
|
281
|
+
});
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
**Advanced Example with Custom Fields:**
|
|
285
|
+
|
|
286
|
+
```javascript
|
|
287
|
+
async function createDetailedTicket() {
|
|
288
|
+
const ticket = {
|
|
289
|
+
subject: 'Technical Support Request',
|
|
290
|
+
comment: {
|
|
291
|
+
body: 'Detailed description of the issue...\n\nSteps to reproduce:\n1. Step one\n2. Step two',
|
|
292
|
+
public: true
|
|
293
|
+
},
|
|
294
|
+
requester: {
|
|
295
|
+
name: 'Jane Smith',
|
|
296
|
+
email: 'jane.smith@example.com',
|
|
297
|
+
locale_id: 1 // English (United States)
|
|
298
|
+
},
|
|
299
|
+
assignee_id: 67890,
|
|
300
|
+
group_id: 11111,
|
|
301
|
+
priority: 'high',
|
|
302
|
+
status: 'open',
|
|
303
|
+
type: 'problem',
|
|
304
|
+
tags: ['technical', 'urgent', 'product-bug'],
|
|
305
|
+
custom_fields: [
|
|
306
|
+
{ id: 12345, value: 'Custom value 1' },
|
|
307
|
+
{ id: 67890, value: 'Custom value 2' }
|
|
308
|
+
],
|
|
309
|
+
due_at: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString() // 7 days from now
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
try {
|
|
313
|
+
const createdTicket = await client.tickets.create(ticket);
|
|
314
|
+
console.log('Ticket created:', createdTicket.id);
|
|
315
|
+
return createdTicket;
|
|
316
|
+
} catch (error) {
|
|
317
|
+
console.error('Failed to create ticket:', error.message);
|
|
318
|
+
throw error;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
createDetailedTicket();
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
#### Update Ticket
|
|
326
|
+
|
|
327
|
+
**Basic Example:**
|
|
328
|
+
|
|
329
|
+
```javascript
|
|
330
|
+
const ticketId = 12345;
|
|
331
|
+
const updates = {
|
|
332
|
+
status: 'solved',
|
|
333
|
+
comment: {
|
|
334
|
+
body: 'This issue has been resolved.',
|
|
335
|
+
public: true
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
client.tickets.update(ticketId, updates)
|
|
340
|
+
.then(ticket => {
|
|
341
|
+
console.log('Ticket updated successfully!');
|
|
342
|
+
console.log('New status:', ticket.status);
|
|
343
|
+
})
|
|
344
|
+
.catch(error => {
|
|
345
|
+
console.error('Error updating ticket:', error.message);
|
|
346
|
+
});
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
**Advanced Example:**
|
|
350
|
+
|
|
351
|
+
```javascript
|
|
352
|
+
async function updateTicketWithComment(ticketId) {
|
|
353
|
+
const updates = {
|
|
354
|
+
status: 'pending',
|
|
355
|
+
priority: 'high',
|
|
356
|
+
assignee_id: 98765,
|
|
357
|
+
tags: ['escalated', 'requires-attention'],
|
|
358
|
+
comment: {
|
|
359
|
+
body: 'This ticket has been escalated to senior support.',
|
|
360
|
+
author_id: 12345,
|
|
361
|
+
public: false // Internal comment
|
|
362
|
+
},
|
|
363
|
+
custom_fields: [
|
|
364
|
+
{ id: 11111, value: 'Updated value' }
|
|
365
|
+
]
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
try {
|
|
369
|
+
const updatedTicket = await client.tickets.update(ticketId, updates);
|
|
370
|
+
console.log('Ticket updated:', updatedTicket.id);
|
|
371
|
+
console.log('New status:', updatedTicket.status);
|
|
372
|
+
console.log('New priority:', updatedTicket.priority);
|
|
373
|
+
return updatedTicket;
|
|
374
|
+
} catch (error) {
|
|
375
|
+
console.error('Failed to update ticket:', error.message);
|
|
376
|
+
throw error;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
updateTicketWithComment(12345);
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
#### Delete Ticket
|
|
384
|
+
|
|
385
|
+
**Basic Example:**
|
|
386
|
+
|
|
387
|
+
```javascript
|
|
388
|
+
const ticketId = 12345;
|
|
389
|
+
|
|
390
|
+
client.tickets.delete(ticketId)
|
|
391
|
+
.then(() => {
|
|
392
|
+
console.log('Ticket deleted successfully');
|
|
393
|
+
})
|
|
394
|
+
.catch(error => {
|
|
395
|
+
console.error('Error deleting ticket:', error.message);
|
|
396
|
+
});
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**Advanced Example with Confirmation:**
|
|
400
|
+
|
|
401
|
+
```javascript
|
|
402
|
+
async function deleteTicketSafely(ticketId) {
|
|
403
|
+
try {
|
|
404
|
+
// First, verify the ticket exists
|
|
405
|
+
const ticket = await client.tickets.show(ticketId);
|
|
406
|
+
console.log(`About to delete ticket #${ticket.id}: ${ticket.subject}`);
|
|
407
|
+
|
|
408
|
+
// Delete the ticket
|
|
409
|
+
await client.tickets.delete(ticketId);
|
|
410
|
+
console.log('Ticket deleted successfully');
|
|
411
|
+
|
|
412
|
+
return true;
|
|
413
|
+
} catch (error) {
|
|
414
|
+
if (error.statusCode === 404) {
|
|
415
|
+
console.log('Ticket not found');
|
|
416
|
+
} else {
|
|
417
|
+
console.error('Failed to delete ticket:', error.message);
|
|
418
|
+
}
|
|
419
|
+
return false;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
deleteTicketSafely(12345);
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
#### List Ticket Comments
|
|
427
|
+
|
|
428
|
+
**Basic Example:**
|
|
429
|
+
|
|
430
|
+
```javascript
|
|
431
|
+
const ticketId = 12345;
|
|
432
|
+
|
|
433
|
+
client.tickets.getComments(ticketId)
|
|
434
|
+
.then(comments => {
|
|
435
|
+
console.log(`Found ${comments.length} comments`);
|
|
436
|
+
comments.forEach(comment => {
|
|
437
|
+
console.log(`Author: ${comment.author_id}`);
|
|
438
|
+
console.log(`Body: ${comment.body}`);
|
|
439
|
+
console.log(`Public: ${comment.public}`);
|
|
440
|
+
console.log('---');
|
|
441
|
+
});
|
|
442
|
+
})
|
|
443
|
+
.catch(error => {
|
|
444
|
+
console.error('Error:', error.message);
|
|
445
|
+
});
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
**Advanced Example:**
|
|
449
|
+
|
|
450
|
+
```javascript
|
|
451
|
+
async function analyzeTicketConversation(ticketId) {
|
|
452
|
+
try {
|
|
453
|
+
const comments = await client.tickets.getComments(ticketId);
|
|
454
|
+
|
|
455
|
+
const publicComments = comments.filter(c => c.public);
|
|
456
|
+
const privateComments = comments.filter(c => !c.public);
|
|
457
|
+
|
|
458
|
+
console.log('=== Ticket Conversation Analysis ===');
|
|
459
|
+
console.log(`Total comments: ${comments.length}`);
|
|
460
|
+
console.log(`Public comments: ${publicComments.length}`);
|
|
461
|
+
console.log(`Private/Internal notes: ${privateComments.length}`);
|
|
462
|
+
|
|
463
|
+
console.log('\n=== Comment History ===');
|
|
464
|
+
comments.forEach((comment, index) => {
|
|
465
|
+
console.log(`\n[Comment ${index + 1}]`);
|
|
466
|
+
console.log(`ID: ${comment.id}`);
|
|
467
|
+
console.log(`Author ID: ${comment.author_id}`);
|
|
468
|
+
console.log(`Created: ${comment.created_at}`);
|
|
469
|
+
console.log(`Type: ${comment.public ? 'Public' : 'Internal'}`);
|
|
470
|
+
console.log(`Body: ${comment.body.substring(0, 100)}...`);
|
|
471
|
+
|
|
472
|
+
if (comment.attachments && comment.attachments.length > 0) {
|
|
473
|
+
console.log('Attachments:');
|
|
474
|
+
comment.attachments.forEach(att => {
|
|
475
|
+
console.log(` - ${att.file_name} (${att.size} bytes)`);
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
return comments;
|
|
481
|
+
} catch (error) {
|
|
482
|
+
console.error('Error fetching comments:', error.message);
|
|
483
|
+
throw error;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
analyzeTicketConversation(12345);
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
---
|
|
491
|
+
|
|
492
|
+
### Users API
|
|
493
|
+
|
|
494
|
+
#### List Users
|
|
495
|
+
|
|
496
|
+
**Basic Example:**
|
|
497
|
+
|
|
498
|
+
```javascript
|
|
499
|
+
client.users.list()
|
|
500
|
+
.then(users => {
|
|
501
|
+
console.log('Total users:', users.length);
|
|
502
|
+
users.forEach(user => {
|
|
503
|
+
console.log(`${user.name} (${user.email})`);
|
|
504
|
+
});
|
|
505
|
+
})
|
|
506
|
+
.catch(error => {
|
|
507
|
+
console.error('Error:', error.message);
|
|
508
|
+
});
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
**Advanced Example with Filtering:**
|
|
512
|
+
|
|
513
|
+
```javascript
|
|
514
|
+
async function listActiveAgents() {
|
|
515
|
+
try {
|
|
516
|
+
const users = await client.users.list();
|
|
517
|
+
|
|
518
|
+
// Filter for active agents
|
|
519
|
+
const agents = users.filter(user =>
|
|
520
|
+
user.role === 'agent' && user.active === true
|
|
521
|
+
);
|
|
522
|
+
|
|
523
|
+
console.log(`Found ${agents.length} active agents:`);
|
|
524
|
+
agents.forEach(agent => {
|
|
525
|
+
console.log(`\nName: ${agent.name}`);
|
|
526
|
+
console.log(`Email: ${agent.email}`);
|
|
527
|
+
console.log(`Role: ${agent.role}`);
|
|
528
|
+
console.log(`Timezone: ${agent.time_zone}`);
|
|
529
|
+
console.log(`Locale: ${agent.locale}`);
|
|
530
|
+
console.log(`Last Login: ${agent.last_login_at}`);
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
return agents;
|
|
534
|
+
} catch (error) {
|
|
535
|
+
console.error('Error fetching users:', error.message);
|
|
536
|
+
throw error;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
listActiveAgents();
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
#### Show User
|
|
544
|
+
|
|
545
|
+
**Basic Example:**
|
|
546
|
+
|
|
547
|
+
```javascript
|
|
548
|
+
const userId = 67890;
|
|
549
|
+
|
|
550
|
+
client.users.show(userId)
|
|
551
|
+
.then(user => {
|
|
552
|
+
console.log('Name:', user.name);
|
|
553
|
+
console.log('Email:', user.email);
|
|
554
|
+
console.log('Role:', user.role);
|
|
555
|
+
})
|
|
556
|
+
.catch(error => {
|
|
557
|
+
console.error('Error:', error.message);
|
|
558
|
+
});
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
**Advanced Example:**
|
|
562
|
+
|
|
563
|
+
```javascript
|
|
564
|
+
async function getUserProfile(userId) {
|
|
565
|
+
try {
|
|
566
|
+
const user = await client.users.show(userId);
|
|
567
|
+
|
|
568
|
+
console.log('=== User Profile ===');
|
|
569
|
+
console.log(`ID: ${user.id}`);
|
|
570
|
+
console.log(`Name: ${user.name}`);
|
|
571
|
+
console.log(`Email: ${user.email}`);
|
|
572
|
+
console.log(`Phone: ${user.phone || 'N/A'}`);
|
|
573
|
+
console.log(`Role: ${user.role}`);
|
|
574
|
+
console.log(`Active: ${user.active}`);
|
|
575
|
+
console.log(`Verified: ${user.verified}`);
|
|
576
|
+
console.log(`Timezone: ${user.time_zone}`);
|
|
577
|
+
console.log(`Locale: ${user.locale}`);
|
|
578
|
+
console.log(`Organization ID: ${user.organization_id}`);
|
|
579
|
+
console.log(`Created: ${user.created_at}`);
|
|
580
|
+
console.log(`Updated: ${user.updated_at}`);
|
|
581
|
+
console.log(`Last Login: ${user.last_login_at}`);
|
|
582
|
+
console.log(`Tags: ${user.tags.join(', ')}`);
|
|
583
|
+
|
|
584
|
+
if (user.user_fields) {
|
|
585
|
+
console.log('Custom User Fields:', user.user_fields);
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
return user;
|
|
589
|
+
} catch (error) {
|
|
590
|
+
console.error('Error fetching user:', error.message);
|
|
591
|
+
throw error;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
getUserProfile(67890);
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
#### Create User
|
|
599
|
+
|
|
600
|
+
**Basic Example:**
|
|
601
|
+
|
|
602
|
+
```javascript
|
|
603
|
+
const newUser = {
|
|
604
|
+
name: 'John Doe',
|
|
605
|
+
email: 'john.doe@example.com',
|
|
606
|
+
role: 'end-user'
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
client.users.create(newUser)
|
|
610
|
+
.then(user => {
|
|
611
|
+
console.log('User created successfully!');
|
|
612
|
+
console.log('User ID:', user.id);
|
|
613
|
+
console.log('Name:', user.name);
|
|
614
|
+
})
|
|
615
|
+
.catch(error => {
|
|
616
|
+
console.error('Error creating user:', error.message);
|
|
617
|
+
});
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
**Advanced Example:**
|
|
621
|
+
|
|
622
|
+
```javascript
|
|
623
|
+
async function createAgentUser() {
|
|
624
|
+
const user = {
|
|
625
|
+
name: 'Sarah Agent',
|
|
626
|
+
email: 'sarah.agent@company.com',
|
|
627
|
+
role: 'agent',
|
|
628
|
+
phone: '+1-555-123-4567',
|
|
629
|
+
time_zone: 'America/New_York',
|
|
630
|
+
locale: 'en-US',
|
|
631
|
+
verified: true,
|
|
632
|
+
tags: ['support-team', 'tier-2'],
|
|
633
|
+
user_fields: {
|
|
634
|
+
department: 'Technical Support',
|
|
635
|
+
employee_id: 'EMP-12345'
|
|
636
|
+
},
|
|
637
|
+
organization_id: 98765
|
|
638
|
+
};
|
|
639
|
+
|
|
640
|
+
try {
|
|
641
|
+
const createdUser = await client.users.create(user);
|
|
642
|
+
console.log('Agent created:', createdUser.id);
|
|
643
|
+
console.log('Name:', createdUser.name);
|
|
644
|
+
console.log('Email:', createdUser.email);
|
|
645
|
+
return createdUser;
|
|
646
|
+
} catch (error) {
|
|
647
|
+
console.error('Failed to create user:', error.message);
|
|
648
|
+
throw error;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
createAgentUser();
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
#### Update User
|
|
656
|
+
|
|
657
|
+
**Basic Example:**
|
|
658
|
+
|
|
659
|
+
```javascript
|
|
660
|
+
const userId = 67890;
|
|
661
|
+
const updates = {
|
|
662
|
+
name: 'Jane Smith',
|
|
663
|
+
phone: '+1-555-999-8888'
|
|
664
|
+
};
|
|
665
|
+
|
|
666
|
+
client.users.update(userId, updates)
|
|
667
|
+
.then(user => {
|
|
668
|
+
console.log('User updated successfully!');
|
|
669
|
+
console.log('Name:', user.name);
|
|
670
|
+
console.log('Phone:', user.phone);
|
|
671
|
+
})
|
|
672
|
+
.catch(error => {
|
|
673
|
+
console.error('Error updating user:', error.message);
|
|
674
|
+
});
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
**Advanced Example:**
|
|
678
|
+
|
|
679
|
+
```javascript
|
|
680
|
+
async function updateUserProfile(userId) {
|
|
681
|
+
const updates = {
|
|
682
|
+
name: 'Jane Smith-Johnson',
|
|
683
|
+
phone: '+1-555-987-6543',
|
|
684
|
+
time_zone: 'Pacific/Auckland',
|
|
685
|
+
locale: 'en-GB',
|
|
686
|
+
tags: ['vip', 'premium-support'],
|
|
687
|
+
user_fields: {
|
|
688
|
+
department: 'Engineering',
|
|
689
|
+
location: 'Remote'
|
|
690
|
+
},
|
|
691
|
+
organization_id: 11111
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
try {
|
|
695
|
+
const updatedUser = await client.users.update(userId, updates);
|
|
696
|
+
console.log('User updated:', updatedUser.id);
|
|
697
|
+
console.log('New name:', updatedUser.name);
|
|
698
|
+
console.log('New timezone:', updatedUser.time_zone);
|
|
699
|
+
return updatedUser;
|
|
700
|
+
} catch (error) {
|
|
701
|
+
console.error('Failed to update user:', error.message);
|
|
702
|
+
throw error;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
updateUserProfile(67890);
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
#### Delete User
|
|
710
|
+
|
|
711
|
+
**Basic Example:**
|
|
712
|
+
|
|
713
|
+
```javascript
|
|
714
|
+
const userId = 67890;
|
|
715
|
+
|
|
716
|
+
client.users.delete(userId)
|
|
717
|
+
.then(() => {
|
|
718
|
+
console.log('User deleted successfully');
|
|
719
|
+
})
|
|
720
|
+
.catch(error => {
|
|
721
|
+
console.error('Error deleting user:', error.message);
|
|
722
|
+
});
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
#### Search Users
|
|
726
|
+
|
|
727
|
+
**Basic Example:**
|
|
728
|
+
|
|
729
|
+
```javascript
|
|
730
|
+
client.users.search({ query: 'john@example.com' })
|
|
731
|
+
.then(users => {
|
|
732
|
+
console.log('Found users:', users.length);
|
|
733
|
+
users.forEach(user => {
|
|
734
|
+
console.log(`${user.name} - ${user.email}`);
|
|
735
|
+
});
|
|
736
|
+
})
|
|
737
|
+
.catch(error => {
|
|
738
|
+
console.error('Error:', error.message);
|
|
739
|
+
});
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
**Advanced Example:**
|
|
743
|
+
|
|
744
|
+
```javascript
|
|
745
|
+
async function searchUsersByName(searchTerm) {
|
|
746
|
+
try {
|
|
747
|
+
const users = await client.users.search({
|
|
748
|
+
query: `name:${searchTerm}`
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
console.log(`Found ${users.length} users matching "${searchTerm}"`);
|
|
752
|
+
|
|
753
|
+
users.forEach(user => {
|
|
754
|
+
console.log('\n---');
|
|
755
|
+
console.log(`ID: ${user.id}`);
|
|
756
|
+
console.log(`Name: ${user.name}`);
|
|
757
|
+
console.log(`Email: ${user.email}`);
|
|
758
|
+
console.log(`Role: ${user.role}`);
|
|
759
|
+
console.log(`Organization: ${user.organization_id}`);
|
|
760
|
+
});
|
|
761
|
+
|
|
762
|
+
return users;
|
|
763
|
+
} catch (error) {
|
|
764
|
+
console.error('Search failed:', error.message);
|
|
765
|
+
throw error;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
searchUsersByName('John');
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
#### Get Current User
|
|
773
|
+
|
|
774
|
+
**Basic Example:**
|
|
775
|
+
|
|
776
|
+
```javascript
|
|
777
|
+
client.users.me()
|
|
778
|
+
.then(user => {
|
|
779
|
+
console.log('Current user:', user.name);
|
|
780
|
+
console.log('Email:', user.email);
|
|
781
|
+
console.log('Role:', user.role);
|
|
782
|
+
})
|
|
783
|
+
.catch(error => {
|
|
784
|
+
console.error('Error:', error.message);
|
|
785
|
+
});
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
---
|
|
789
|
+
|
|
790
|
+
### Organizations API
|
|
791
|
+
|
|
792
|
+
#### List Organizations
|
|
793
|
+
|
|
794
|
+
**Basic Example:**
|
|
795
|
+
|
|
796
|
+
```javascript
|
|
797
|
+
client.organizations.list()
|
|
798
|
+
.then(organizations => {
|
|
799
|
+
console.log('Total organizations:', organizations.length);
|
|
800
|
+
organizations.forEach(org => {
|
|
801
|
+
console.log(`${org.name} (ID: ${org.id})`);
|
|
802
|
+
});
|
|
803
|
+
})
|
|
804
|
+
.catch(error => {
|
|
805
|
+
console.error('Error:', error.message);
|
|
806
|
+
});
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
**Advanced Example:**
|
|
810
|
+
|
|
811
|
+
```javascript
|
|
812
|
+
async function analyzeOrganizations() {
|
|
813
|
+
try {
|
|
814
|
+
const organizations = await client.organizations.list();
|
|
815
|
+
|
|
816
|
+
console.log(`Total organizations: ${organizations.length}`);
|
|
817
|
+
|
|
818
|
+
organizations.forEach(org => {
|
|
819
|
+
console.log('\n=== Organization ===');
|
|
820
|
+
console.log(`ID: ${org.id}`);
|
|
821
|
+
console.log(`Name: ${org.name}`);
|
|
822
|
+
console.log(`Domain Names: ${org.domain_names?.join(', ') || 'None'}`);
|
|
823
|
+
console.log(`Details: ${org.details || 'N/A'}`);
|
|
824
|
+
console.log(`Notes: ${org.notes || 'N/A'}`);
|
|
825
|
+
console.log(`Tags: ${org.tags?.join(', ') || 'None'}`);
|
|
826
|
+
console.log(`Created: ${org.created_at}`);
|
|
827
|
+
|
|
828
|
+
if (org.organization_fields) {
|
|
829
|
+
console.log('Custom Fields:', org.organization_fields);
|
|
830
|
+
}
|
|
831
|
+
});
|
|
832
|
+
|
|
833
|
+
return organizations;
|
|
834
|
+
} catch (error) {
|
|
835
|
+
console.error('Error fetching organizations:', error.message);
|
|
836
|
+
throw error;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
analyzeOrganizations();
|
|
841
|
+
```
|
|
842
|
+
|
|
843
|
+
#### Show Organization
|
|
844
|
+
|
|
845
|
+
**Basic Example:**
|
|
846
|
+
|
|
847
|
+
```javascript
|
|
848
|
+
const orgId = 98765;
|
|
849
|
+
|
|
850
|
+
client.organizations.show(orgId)
|
|
851
|
+
.then(org => {
|
|
852
|
+
console.log('Name:', org.name);
|
|
853
|
+
console.log('Details:', org.details);
|
|
854
|
+
})
|
|
855
|
+
.catch(error => {
|
|
856
|
+
console.error('Error:', error.message);
|
|
857
|
+
});
|
|
858
|
+
```
|
|
859
|
+
|
|
860
|
+
**Advanced Example:**
|
|
861
|
+
|
|
862
|
+
```javascript
|
|
863
|
+
async function getOrganizationDetails(orgId) {
|
|
864
|
+
try {
|
|
865
|
+
const org = await client.organizations.show(orgId);
|
|
866
|
+
|
|
867
|
+
console.log('=== Organization Details ===');
|
|
868
|
+
console.log(`ID: ${org.id}`);
|
|
869
|
+
console.log(`Name: ${org.name}`);
|
|
870
|
+
console.log(`Domain Names: ${org.domain_names?.join(', ') || 'None'}`);
|
|
871
|
+
console.log(`Details: ${org.details || 'N/A'}`);
|
|
872
|
+
console.log(`Notes: ${org.notes || 'N/A'}`);
|
|
873
|
+
console.log(`Group ID: ${org.group_id || 'N/A'}`);
|
|
874
|
+
console.log(`Tags: ${org.tags?.join(', ') || 'None'}`);
|
|
875
|
+
console.log(`Created: ${org.created_at}`);
|
|
876
|
+
console.log(`Updated: ${org.updated_at}`);
|
|
877
|
+
|
|
878
|
+
if (org.organization_fields) {
|
|
879
|
+
console.log('\nCustom Organization Fields:');
|
|
880
|
+
Object.entries(org.organization_fields).forEach(([key, value]) => {
|
|
881
|
+
console.log(` ${key}: ${value}`);
|
|
882
|
+
});
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
return org;
|
|
886
|
+
} catch (error) {
|
|
887
|
+
console.error('Error fetching organization:', error.message);
|
|
888
|
+
throw error;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
getOrganizationDetails(98765);
|
|
893
|
+
```
|
|
894
|
+
|
|
895
|
+
#### Create Organization
|
|
896
|
+
|
|
897
|
+
**Basic Example:**
|
|
898
|
+
|
|
899
|
+
```javascript
|
|
900
|
+
const newOrg = {
|
|
901
|
+
name: 'Acme Corporation',
|
|
902
|
+
domain_names: ['acme.com']
|
|
903
|
+
};
|
|
904
|
+
|
|
905
|
+
client.organizations.create(newOrg)
|
|
906
|
+
.then(org => {
|
|
907
|
+
console.log('Organization created!');
|
|
908
|
+
console.log('ID:', org.id);
|
|
909
|
+
console.log('Name:', org.name);
|
|
910
|
+
})
|
|
911
|
+
.catch(error => {
|
|
912
|
+
console.error('Error creating organization:', error.message);
|
|
913
|
+
});
|
|
914
|
+
```
|
|
915
|
+
|
|
916
|
+
**Advanced Example:**
|
|
917
|
+
|
|
918
|
+
```javascript
|
|
919
|
+
async function createOrganization() {
|
|
920
|
+
const organization = {
|
|
921
|
+
name: 'TechStart Solutions Inc.',
|
|
922
|
+
domain_names: ['techstart.com', 'techstart.io'],
|
|
923
|
+
details: 'Premium enterprise customer',
|
|
924
|
+
notes: 'VIP support tier, 24/7 coverage',
|
|
925
|
+
tags: ['enterprise', 'vip', 'priority-support'],
|
|
926
|
+
group_id: 12345,
|
|
927
|
+
organization_fields: {
|
|
928
|
+
industry: 'Technology',
|
|
929
|
+
account_tier: 'Enterprise',
|
|
930
|
+
annual_revenue: '10M+'
|
|
931
|
+
}
|
|
932
|
+
};
|
|
933
|
+
|
|
934
|
+
try {
|
|
935
|
+
const createdOrg = await client.organizations.create(organization);
|
|
936
|
+
console.log('Organization created:', createdOrg.id);
|
|
937
|
+
console.log('Name:', createdOrg.name);
|
|
938
|
+
console.log('Domains:', createdOrg.domain_names.join(', '));
|
|
939
|
+
return createdOrg;
|
|
940
|
+
} catch (error) {
|
|
941
|
+
console.error('Failed to create organization:', error.message);
|
|
942
|
+
throw error;
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
createOrganization();
|
|
947
|
+
```
|
|
948
|
+
|
|
949
|
+
#### Update Organization
|
|
950
|
+
|
|
951
|
+
**Basic Example:**
|
|
952
|
+
|
|
953
|
+
```javascript
|
|
954
|
+
const orgId = 98765;
|
|
955
|
+
const updates = {
|
|
956
|
+
name: 'Acme Corporation Ltd.',
|
|
957
|
+
details: 'Updated company details'
|
|
958
|
+
};
|
|
959
|
+
|
|
960
|
+
client.organizations.update(orgId, updates)
|
|
961
|
+
.then(org => {
|
|
962
|
+
console.log('Organization updated!');
|
|
963
|
+
console.log('Name:', org.name);
|
|
964
|
+
})
|
|
965
|
+
.catch(error => {
|
|
966
|
+
console.error('Error updating organization:', error.message);
|
|
967
|
+
});
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
**Advanced Example:**
|
|
971
|
+
|
|
972
|
+
```javascript
|
|
973
|
+
async function updateOrganization(orgId) {
|
|
974
|
+
const updates = {
|
|
975
|
+
name: 'Acme Global Corporation',
|
|
976
|
+
domain_names: ['acme.com', 'acme.global', 'acmeglobal.com'],
|
|
977
|
+
details: 'Global enterprise customer with multiple subsidiaries',
|
|
978
|
+
notes: 'Upgraded to platinum tier - assign dedicated account manager',
|
|
979
|
+
tags: ['enterprise', 'platinum', 'global', 'strategic-account'],
|
|
980
|
+
organization_fields: {
|
|
981
|
+
account_tier: 'Platinum',
|
|
982
|
+
contract_renewal: '2025-12-31',
|
|
983
|
+
dedicated_support: 'yes'
|
|
984
|
+
}
|
|
985
|
+
};
|
|
986
|
+
|
|
987
|
+
try {
|
|
988
|
+
const updatedOrg = await client.organizations.update(orgId, updates);
|
|
989
|
+
console.log('Organization updated:', updatedOrg.id);
|
|
990
|
+
console.log('New name:', updatedOrg.name);
|
|
991
|
+
console.log('Tags:', updatedOrg.tags.join(', '));
|
|
992
|
+
return updatedOrg;
|
|
993
|
+
} catch (error) {
|
|
994
|
+
console.error('Failed to update organization:', error.message);
|
|
995
|
+
throw error;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
updateOrganization(98765);
|
|
1000
|
+
```
|
|
1001
|
+
|
|
1002
|
+
#### Delete Organization
|
|
1003
|
+
|
|
1004
|
+
**Basic Example:**
|
|
1005
|
+
|
|
1006
|
+
```javascript
|
|
1007
|
+
const orgId = 98765;
|
|
1008
|
+
|
|
1009
|
+
client.organizations.delete(orgId)
|
|
1010
|
+
.then(() => {
|
|
1011
|
+
console.log('Organization deleted successfully');
|
|
1012
|
+
})
|
|
1013
|
+
.catch(error => {
|
|
1014
|
+
console.error('Error deleting organization:', error.message);
|
|
1015
|
+
});
|
|
1016
|
+
```
|
|
1017
|
+
|
|
1018
|
+
---
|
|
1019
|
+
|
|
1020
|
+
### Search API
|
|
1021
|
+
|
|
1022
|
+
#### Basic Search
|
|
1023
|
+
|
|
1024
|
+
**Basic Example:**
|
|
1025
|
+
|
|
1026
|
+
```javascript
|
|
1027
|
+
client.search.query('type:ticket status:open')
|
|
1028
|
+
.then(results => {
|
|
1029
|
+
console.log('Found tickets:', results.length);
|
|
1030
|
+
results.forEach(ticket => {
|
|
1031
|
+
console.log(`#${ticket.id}: ${ticket.subject}`);
|
|
1032
|
+
});
|
|
1033
|
+
})
|
|
1034
|
+
.catch(error => {
|
|
1035
|
+
console.error('Error:', error.message);
|
|
1036
|
+
});
|
|
1037
|
+
```
|
|
1038
|
+
|
|
1039
|
+
**Advanced Example:**
|
|
1040
|
+
|
|
1041
|
+
```javascript
|
|
1042
|
+
async function searchOpenTickets() {
|
|
1043
|
+
try {
|
|
1044
|
+
const query = 'type:ticket status:open priority:high';
|
|
1045
|
+
const results = await client.search.query(query);
|
|
1046
|
+
|
|
1047
|
+
console.log(`Found ${results.length} high-priority open tickets`);
|
|
1048
|
+
|
|
1049
|
+
results.forEach(ticket => {
|
|
1050
|
+
console.log('\n---');
|
|
1051
|
+
console.log(`Ticket #${ticket.id}`);
|
|
1052
|
+
console.log(`Subject: ${ticket.subject}`);
|
|
1053
|
+
console.log(`Priority: ${ticket.priority}`);
|
|
1054
|
+
console.log(`Status: ${ticket.status}`);
|
|
1055
|
+
console.log(`Created: ${ticket.created_at}`);
|
|
1056
|
+
console.log(`Assignee: ${ticket.assignee_id || 'Unassigned'}`);
|
|
1057
|
+
});
|
|
1058
|
+
|
|
1059
|
+
return results;
|
|
1060
|
+
} catch (error) {
|
|
1061
|
+
console.error('Search failed:', error.message);
|
|
1062
|
+
throw error;
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
searchOpenTickets();
|
|
1067
|
+
```
|
|
1068
|
+
|
|
1069
|
+
#### Search Tickets
|
|
1070
|
+
|
|
1071
|
+
**Basic Example:**
|
|
1072
|
+
|
|
1073
|
+
```javascript
|
|
1074
|
+
client.search.query('type:ticket subject:login')
|
|
1075
|
+
.then(tickets => {
|
|
1076
|
+
console.log('Tickets mentioning "login":', tickets.length);
|
|
1077
|
+
})
|
|
1078
|
+
.catch(error => {
|
|
1079
|
+
console.error('Error:', error.message);
|
|
1080
|
+
});
|
|
1081
|
+
```
|
|
1082
|
+
|
|
1083
|
+
**Advanced Example with Multiple Filters:**
|
|
1084
|
+
|
|
1085
|
+
```javascript
|
|
1086
|
+
async function advancedTicketSearch() {
|
|
1087
|
+
const searchParams = {
|
|
1088
|
+
type: 'ticket',
|
|
1089
|
+
status: 'open',
|
|
1090
|
+
priority: 'urgent',
|
|
1091
|
+
tags: 'bug',
|
|
1092
|
+
created_at: '>2025-01-01'
|
|
1093
|
+
};
|
|
1094
|
+
|
|
1095
|
+
// Build query string
|
|
1096
|
+
const query = Object.entries(searchParams)
|
|
1097
|
+
.map(([key, value]) => `${key}:${value}`)
|
|
1098
|
+
.join(' ');
|
|
1099
|
+
|
|
1100
|
+
try {
|
|
1101
|
+
const tickets = await client.search.query(query);
|
|
1102
|
+
|
|
1103
|
+
console.log(`Search Query: ${query}`);
|
|
1104
|
+
console.log(`Results: ${tickets.length} tickets\n`);
|
|
1105
|
+
|
|
1106
|
+
tickets.forEach(ticket => {
|
|
1107
|
+
console.log(`#${ticket.id}: ${ticket.subject}`);
|
|
1108
|
+
console.log(` Status: ${ticket.status} | Priority: ${ticket.priority}`);
|
|
1109
|
+
console.log(` Tags: ${ticket.tags.join(', ')}`);
|
|
1110
|
+
console.log(` Created: ${ticket.created_at}`);
|
|
1111
|
+
});
|
|
1112
|
+
|
|
1113
|
+
return tickets;
|
|
1114
|
+
} catch (error) {
|
|
1115
|
+
console.error('Search error:', error.message);
|
|
1116
|
+
throw error;
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
advancedTicketSearch();
|
|
1121
|
+
```
|
|
1122
|
+
|
|
1123
|
+
#### Search Users
|
|
1124
|
+
|
|
1125
|
+
**Basic Example:**
|
|
1126
|
+
|
|
1127
|
+
```javascript
|
|
1128
|
+
client.search.query('type:user email:*@example.com')
|
|
1129
|
+
.then(users => {
|
|
1130
|
+
console.log('Found users:', users.length);
|
|
1131
|
+
users.forEach(user => {
|
|
1132
|
+
console.log(`${user.name} - ${user.email}`);
|
|
1133
|
+
});
|
|
1134
|
+
})
|
|
1135
|
+
.catch(error => {
|
|
1136
|
+
console.error('Error:', error.message);
|
|
1137
|
+
});
|
|
1138
|
+
```
|
|
1139
|
+
|
|
1140
|
+
**Advanced Example:**
|
|
1141
|
+
|
|
1142
|
+
```javascript
|
|
1143
|
+
async function findAgentsByOrganization(orgId) {
|
|
1144
|
+
const query = `type:user role:agent organization_id:${orgId}`;
|
|
1145
|
+
|
|
1146
|
+
try {
|
|
1147
|
+
const agents = await client.search.query(query);
|
|
1148
|
+
|
|
1149
|
+
console.log(`Found ${agents.length} agents in organization ${orgId}`);
|
|
1150
|
+
|
|
1151
|
+
agents.forEach(agent => {
|
|
1152
|
+
console.log('\n---');
|
|
1153
|
+
console.log(`Name: ${agent.name}`);
|
|
1154
|
+
console.log(`Email: ${agent.email}`);
|
|
1155
|
+
console.log(`Role: ${agent.role}`);
|
|
1156
|
+
console.log(`Active: ${agent.active}`);
|
|
1157
|
+
console.log(`Last Login: ${agent.last_login_at || 'Never'}`);
|
|
1158
|
+
});
|
|
1159
|
+
|
|
1160
|
+
return agents;
|
|
1161
|
+
} catch (error) {
|
|
1162
|
+
console.error('User search failed:', error.message);
|
|
1163
|
+
throw error;
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
findAgentsByOrganization(98765);
|
|
1168
|
+
```
|
|
1169
|
+
|
|
1170
|
+
#### Search Organizations
|
|
1171
|
+
|
|
1172
|
+
**Basic Example:**
|
|
1173
|
+
|
|
1174
|
+
```javascript
|
|
1175
|
+
client.search.query('type:organization name:Acme')
|
|
1176
|
+
.then(orgs => {
|
|
1177
|
+
console.log('Found organizations:', orgs.length);
|
|
1178
|
+
orgs.forEach(org => {
|
|
1179
|
+
console.log(`${org.name} (ID: ${org.id})`);
|
|
1180
|
+
});
|
|
1181
|
+
})
|
|
1182
|
+
.catch(error => {
|
|
1183
|
+
console.error('Error:', error.message);
|
|
1184
|
+
});
|
|
1185
|
+
```
|
|
1186
|
+
|
|
1187
|
+
**Advanced Example:**
|
|
1188
|
+
|
|
1189
|
+
```javascript
|
|
1190
|
+
async function searchOrganizationsByDomain(domain) {
|
|
1191
|
+
const query = `type:organization ${domain}`;
|
|
1192
|
+
|
|
1193
|
+
try {
|
|
1194
|
+
const organizations = await client.search.query(query);
|
|
1195
|
+
|
|
1196
|
+
console.log(`Found ${organizations.length} organizations with domain "${domain}"`);
|
|
1197
|
+
|
|
1198
|
+
organizations.forEach(org => {
|
|
1199
|
+
console.log('\n=== Organization ===');
|
|
1200
|
+
console.log(`ID: ${org.id}`);
|
|
1201
|
+
console.log(`Name: ${org.name}`);
|
|
1202
|
+
console.log(`Domains: ${org.domain_names?.join(', ') || 'None'}`);
|
|
1203
|
+
console.log(`Details: ${org.details || 'N/A'}`);
|
|
1204
|
+
console.log(`Created: ${org.created_at}`);
|
|
1205
|
+
});
|
|
1206
|
+
|
|
1207
|
+
return organizations;
|
|
1208
|
+
} catch (error) {
|
|
1209
|
+
console.error('Organization search failed:', error.message);
|
|
1210
|
+
throw error;
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
searchOrganizationsByDomain('acme.com');
|
|
1215
|
+
```
|
|
1216
|
+
|
|
1217
|
+
---
|
|
1218
|
+
|
|
1219
|
+
### Groups API
|
|
1220
|
+
|
|
1221
|
+
#### List Groups
|
|
1222
|
+
|
|
1223
|
+
**Basic Example:**
|
|
1224
|
+
|
|
1225
|
+
```javascript
|
|
1226
|
+
client.groups.list()
|
|
1227
|
+
.then(groups => {
|
|
1228
|
+
console.log('Total groups:', groups.length);
|
|
1229
|
+
groups.forEach(group => {
|
|
1230
|
+
console.log(`${group.name} (ID: ${group.id})`);
|
|
1231
|
+
});
|
|
1232
|
+
})
|
|
1233
|
+
.catch(error => {
|
|
1234
|
+
console.error('Error:', error.message);
|
|
1235
|
+
});
|
|
1236
|
+
```
|
|
1237
|
+
|
|
1238
|
+
**Advanced Example:**
|
|
1239
|
+
|
|
1240
|
+
```javascript
|
|
1241
|
+
async function listAllGroups() {
|
|
1242
|
+
try {
|
|
1243
|
+
const groups = await client.groups.list();
|
|
1244
|
+
|
|
1245
|
+
console.log(`Found ${groups.length} groups\n`);
|
|
1246
|
+
|
|
1247
|
+
groups.forEach(group => {
|
|
1248
|
+
console.log('=== Group ===');
|
|
1249
|
+
console.log(`ID: ${group.id}`);
|
|
1250
|
+
console.log(`Name: ${group.name}`);
|
|
1251
|
+
console.log(`Description: ${group.description || 'N/A'}`);
|
|
1252
|
+
console.log(`Created: ${group.created_at}`);
|
|
1253
|
+
console.log(`Updated: ${group.updated_at}`);
|
|
1254
|
+
console.log('---');
|
|
1255
|
+
});
|
|
1256
|
+
|
|
1257
|
+
return groups;
|
|
1258
|
+
} catch (error) {
|
|
1259
|
+
console.error('Error fetching groups:', error.message);
|
|
1260
|
+
throw error;
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
listAllGroups();
|
|
1265
|
+
```
|
|
1266
|
+
|
|
1267
|
+
#### Show Group
|
|
1268
|
+
|
|
1269
|
+
**Basic Example:**
|
|
1270
|
+
|
|
1271
|
+
```javascript
|
|
1272
|
+
const groupId = 12345;
|
|
1273
|
+
|
|
1274
|
+
client.groups.show(groupId)
|
|
1275
|
+
.then(group => {
|
|
1276
|
+
console.log('Group:', group.name);
|
|
1277
|
+
console.log('Description:', group.description);
|
|
1278
|
+
})
|
|
1279
|
+
.catch(error => {
|
|
1280
|
+
console.error('Error:', error.message);
|
|
1281
|
+
});
|
|
1282
|
+
```
|
|
1283
|
+
|
|
1284
|
+
#### Create Group
|
|
1285
|
+
|
|
1286
|
+
**Basic Example:**
|
|
1287
|
+
|
|
1288
|
+
```javascript
|
|
1289
|
+
const newGroup = {
|
|
1290
|
+
name: 'Technical Support Team'
|
|
1291
|
+
};
|
|
1292
|
+
|
|
1293
|
+
client.groups.create(newGroup)
|
|
1294
|
+
.then(group => {
|
|
1295
|
+
console.log('Group created!');
|
|
1296
|
+
console.log('ID:', group.id);
|
|
1297
|
+
console.log('Name:', group.name);
|
|
1298
|
+
})
|
|
1299
|
+
.catch(error => {
|
|
1300
|
+
console.error('Error creating group:', error.message);
|
|
1301
|
+
});
|
|
1302
|
+
```
|
|
1303
|
+
|
|
1304
|
+
**Advanced Example:**
|
|
1305
|
+
|
|
1306
|
+
```javascript
|
|
1307
|
+
async function createSupportGroup() {
|
|
1308
|
+
const group = {
|
|
1309
|
+
name: 'Enterprise Support Team',
|
|
1310
|
+
description: 'Dedicated support team for enterprise customers'
|
|
1311
|
+
};
|
|
1312
|
+
|
|
1313
|
+
try {
|
|
1314
|
+
const createdGroup = await client.groups.create(group);
|
|
1315
|
+
console.log('Group created:', createdGroup.id);
|
|
1316
|
+
console.log('Name:', createdGroup.name);
|
|
1317
|
+
console.log('Description:', createdGroup.description);
|
|
1318
|
+
return createdGroup;
|
|
1319
|
+
} catch (error) {
|
|
1320
|
+
console.error('Failed to create group:', error.message);
|
|
1321
|
+
throw error;
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
createSupportGroup();
|
|
1326
|
+
```
|
|
1327
|
+
|
|
1328
|
+
#### Update Group
|
|
1329
|
+
|
|
1330
|
+
**Basic Example:**
|
|
1331
|
+
|
|
1332
|
+
```javascript
|
|
1333
|
+
const groupId = 12345;
|
|
1334
|
+
const updates = {
|
|
1335
|
+
name: 'Updated Group Name',
|
|
1336
|
+
description: 'Updated description'
|
|
1337
|
+
};
|
|
1338
|
+
|
|
1339
|
+
client.groups.update(groupId, updates)
|
|
1340
|
+
.then(group => {
|
|
1341
|
+
console.log('Group updated!');
|
|
1342
|
+
console.log('Name:', group.name);
|
|
1343
|
+
})
|
|
1344
|
+
.catch(error => {
|
|
1345
|
+
console.error('Error updating group:', error.message);
|
|
1346
|
+
});
|
|
1347
|
+
```
|
|
1348
|
+
|
|
1349
|
+
#### Delete Group
|
|
1350
|
+
|
|
1351
|
+
**Basic Example:**
|
|
1352
|
+
|
|
1353
|
+
```javascript
|
|
1354
|
+
const groupId = 12345;
|
|
1355
|
+
|
|
1356
|
+
client.groups.delete(groupId)
|
|
1357
|
+
.then(() => {
|
|
1358
|
+
console.log('Group deleted successfully');
|
|
1359
|
+
})
|
|
1360
|
+
.catch(error => {
|
|
1361
|
+
console.error('Error deleting group:', error.message);
|
|
1362
|
+
});
|
|
1363
|
+
```
|
|
1364
|
+
|
|
1365
|
+
---
|
|
1366
|
+
|
|
1367
|
+
### Attachments API
|
|
1368
|
+
|
|
1369
|
+
#### Upload Attachment
|
|
1370
|
+
|
|
1371
|
+
**Basic Example:**
|
|
1372
|
+
|
|
1373
|
+
```javascript
|
|
1374
|
+
const fs = require('fs');
|
|
1375
|
+
const path = require('path');
|
|
1376
|
+
|
|
1377
|
+
const filePath = path.resolve('./documents/file.pdf');
|
|
1378
|
+
|
|
1379
|
+
client.attachments.upload(filePath, { filename: 'file.pdf' })
|
|
1380
|
+
.then(upload => {
|
|
1381
|
+
console.log('File uploaded successfully!');
|
|
1382
|
+
console.log('Upload token:', upload.token);
|
|
1383
|
+
console.log('Attachment:', upload.attachment);
|
|
1384
|
+
})
|
|
1385
|
+
.catch(error => {
|
|
1386
|
+
console.error('Error uploading file:', error.message);
|
|
1387
|
+
});
|
|
1388
|
+
```
|
|
1389
|
+
|
|
1390
|
+
**Advanced Example with Ticket Creation:**
|
|
1391
|
+
|
|
1392
|
+
```javascript
|
|
1393
|
+
const fs = require('fs');
|
|
1394
|
+
const path = require('path');
|
|
1395
|
+
|
|
1396
|
+
async function createTicketWithAttachment() {
|
|
1397
|
+
try {
|
|
1398
|
+
// Step 1: Upload the file
|
|
1399
|
+
const filePath = path.resolve('./screenshots/bug-screenshot.png');
|
|
1400
|
+
const upload = await client.attachments.upload(filePath, {
|
|
1401
|
+
filename: 'bug-screenshot.png'
|
|
1402
|
+
});
|
|
1403
|
+
|
|
1404
|
+
console.log('File uploaded. Token:', upload.token);
|
|
1405
|
+
|
|
1406
|
+
// Step 2: Create ticket with attachment
|
|
1407
|
+
const ticket = {
|
|
1408
|
+
subject: 'Bug Report: UI Issue',
|
|
1409
|
+
comment: {
|
|
1410
|
+
body: 'Please see the attached screenshot showing the UI bug.',
|
|
1411
|
+
uploads: [upload.token] // Reference the upload token
|
|
1412
|
+
},
|
|
1413
|
+
requester: {
|
|
1414
|
+
name: 'Bug Reporter',
|
|
1415
|
+
email: 'reporter@example.com'
|
|
1416
|
+
},
|
|
1417
|
+
priority: 'high',
|
|
1418
|
+
tags: ['bug', 'ui']
|
|
1419
|
+
};
|
|
1420
|
+
|
|
1421
|
+
const createdTicket = await client.tickets.create(ticket);
|
|
1422
|
+
|
|
1423
|
+
console.log('Ticket created with attachment!');
|
|
1424
|
+
console.log('Ticket ID:', createdTicket.id);
|
|
1425
|
+
console.log('Subject:', createdTicket.subject);
|
|
1426
|
+
|
|
1427
|
+
return createdTicket;
|
|
1428
|
+
} catch (error) {
|
|
1429
|
+
console.error('Error:', error.message);
|
|
1430
|
+
throw error;
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
createTicketWithAttachment();
|
|
1435
|
+
```
|
|
1436
|
+
|
|
1437
|
+
#### Upload Multiple Attachments
|
|
1438
|
+
|
|
1439
|
+
**Advanced Example:**
|
|
1440
|
+
|
|
1441
|
+
```javascript
|
|
1442
|
+
const fs = require('fs');
|
|
1443
|
+
const path = require('path');
|
|
1444
|
+
|
|
1445
|
+
async function createTicketWithMultipleAttachments() {
|
|
1446
|
+
try {
|
|
1447
|
+
// Upload multiple files
|
|
1448
|
+
const files = [
|
|
1449
|
+
'./documents/report.pdf',
|
|
1450
|
+
'./screenshots/screen1.png',
|
|
1451
|
+
'./screenshots/screen2.png'
|
|
1452
|
+
];
|
|
1453
|
+
|
|
1454
|
+
const uploadPromises = files.map(file => {
|
|
1455
|
+
const filePath = path.resolve(file);
|
|
1456
|
+
const filename = path.basename(file);
|
|
1457
|
+
return client.attachments.upload(filePath, { filename });
|
|
1458
|
+
});
|
|
1459
|
+
|
|
1460
|
+
const uploads = await Promise.all(uploadPromises);
|
|
1461
|
+
const tokens = uploads.map(u => u.token);
|
|
1462
|
+
|
|
1463
|
+
console.log(`Uploaded ${tokens.length} files`);
|
|
1464
|
+
|
|
1465
|
+
// Create ticket with all attachments
|
|
1466
|
+
const ticket = {
|
|
1467
|
+
subject: 'Detailed Bug Report',
|
|
1468
|
+
comment: {
|
|
1469
|
+
body: 'Please find the attached report and screenshots.',
|
|
1470
|
+
uploads: tokens
|
|
1471
|
+
},
|
|
1472
|
+
requester: {
|
|
1473
|
+
name: 'QA Tester',
|
|
1474
|
+
email: 'qa@example.com'
|
|
1475
|
+
},
|
|
1476
|
+
priority: 'normal'
|
|
1477
|
+
};
|
|
1478
|
+
|
|
1479
|
+
const createdTicket = await client.tickets.create(ticket);
|
|
1480
|
+
|
|
1481
|
+
console.log('Ticket created with multiple attachments!');
|
|
1482
|
+
console.log('Ticket ID:', createdTicket.id);
|
|
1483
|
+
|
|
1484
|
+
return createdTicket;
|
|
1485
|
+
} catch (error) {
|
|
1486
|
+
console.error('Error:', error.message);
|
|
1487
|
+
throw error;
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
createTicketWithMultipleAttachments();
|
|
1492
|
+
```
|
|
1493
|
+
|
|
1494
|
+
#### Show Attachment
|
|
1495
|
+
|
|
1496
|
+
**Basic Example:**
|
|
1497
|
+
|
|
1498
|
+
```javascript
|
|
1499
|
+
const attachmentId = 123456789;
|
|
1500
|
+
|
|
1501
|
+
client.attachments.show(attachmentId)
|
|
1502
|
+
.then(attachment => {
|
|
1503
|
+
console.log('Filename:', attachment.file_name);
|
|
1504
|
+
console.log('Size:', attachment.size, 'bytes');
|
|
1505
|
+
console.log('Content Type:', attachment.content_type);
|
|
1506
|
+
console.log('URL:', attachment.content_url);
|
|
1507
|
+
})
|
|
1508
|
+
.catch(error => {
|
|
1509
|
+
console.error('Error:', error.message);
|
|
1510
|
+
});
|
|
1511
|
+
```
|
|
1512
|
+
|
|
1513
|
+
#### Delete Attachment Upload
|
|
1514
|
+
|
|
1515
|
+
**Basic Example:**
|
|
1516
|
+
|
|
1517
|
+
```javascript
|
|
1518
|
+
const uploadToken = 'upload_token_here';
|
|
1519
|
+
|
|
1520
|
+
client.attachments.deleteUpload(uploadToken)
|
|
1521
|
+
.then(() => {
|
|
1522
|
+
console.log('Upload deleted successfully');
|
|
1523
|
+
})
|
|
1524
|
+
.catch(error => {
|
|
1525
|
+
console.error('Error deleting upload:', error.message);
|
|
1526
|
+
});
|
|
1527
|
+
```
|
|
1528
|
+
|
|
1529
|
+
---
|
|
1530
|
+
|
|
1531
|
+
### Macros API
|
|
1532
|
+
|
|
1533
|
+
#### List Macros
|
|
1534
|
+
|
|
1535
|
+
**Basic Example:**
|
|
1536
|
+
|
|
1537
|
+
```javascript
|
|
1538
|
+
client.macros.list()
|
|
1539
|
+
.then(macros => {
|
|
1540
|
+
console.log('Total macros:', macros.length);
|
|
1541
|
+
macros.forEach(macro => {
|
|
1542
|
+
console.log(`${macro.title} (ID: ${macro.id})`);
|
|
1543
|
+
});
|
|
1544
|
+
})
|
|
1545
|
+
.catch(error => {
|
|
1546
|
+
console.error('Error:', error.message);
|
|
1547
|
+
});
|
|
1548
|
+
```
|
|
1549
|
+
|
|
1550
|
+
**Advanced Example:**
|
|
1551
|
+
|
|
1552
|
+
```javascript
|
|
1553
|
+
async function listActiveMacros() {
|
|
1554
|
+
try {
|
|
1555
|
+
const macros = await client.macros.list();
|
|
1556
|
+
|
|
1557
|
+
const activeMacros = macros.filter(m => m.active);
|
|
1558
|
+
|
|
1559
|
+
console.log(`Found ${activeMacros.length} active macros\n`);
|
|
1560
|
+
|
|
1561
|
+
activeMacros.forEach(macro => {
|
|
1562
|
+
console.log('=== Macro ===');
|
|
1563
|
+
console.log(`ID: ${macro.id}`);
|
|
1564
|
+
console.log(`Title: ${macro.title}`);
|
|
1565
|
+
console.log(`Description: ${macro.description || 'N/A'}`);
|
|
1566
|
+
console.log(`Active: ${macro.active}`);
|
|
1567
|
+
console.log(`Created: ${macro.created_at}`);
|
|
1568
|
+
console.log('---');
|
|
1569
|
+
});
|
|
1570
|
+
|
|
1571
|
+
return activeMacros;
|
|
1572
|
+
} catch (error) {
|
|
1573
|
+
console.error('Error fetching macros:', error.message);
|
|
1574
|
+
throw error;
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
listActiveMacros();
|
|
1579
|
+
```
|
|
1580
|
+
|
|
1581
|
+
#### Show Macro
|
|
1582
|
+
|
|
1583
|
+
**Basic Example:**
|
|
1584
|
+
|
|
1585
|
+
```javascript
|
|
1586
|
+
const macroId = 54321;
|
|
1587
|
+
|
|
1588
|
+
client.macros.show(macroId)
|
|
1589
|
+
.then(macro => {
|
|
1590
|
+
console.log('Title:', macro.title);
|
|
1591
|
+
console.log('Description:', macro.description);
|
|
1592
|
+
console.log('Actions:', macro.actions);
|
|
1593
|
+
})
|
|
1594
|
+
.catch(error => {
|
|
1595
|
+
console.error('Error:', error.message);
|
|
1596
|
+
});
|
|
1597
|
+
```
|
|
1598
|
+
|
|
1599
|
+
#### Apply Macro to Ticket
|
|
1600
|
+
|
|
1601
|
+
**Advanced Example:**
|
|
1602
|
+
|
|
1603
|
+
```javascript
|
|
1604
|
+
async function applyMacroToTicket(ticketId, macroId) {
|
|
1605
|
+
try {
|
|
1606
|
+
const result = await client.macros.applyTicket(ticketId, macroId);
|
|
1607
|
+
|
|
1608
|
+
console.log('Macro applied successfully!');
|
|
1609
|
+
console.log('Result:', result);
|
|
1610
|
+
|
|
1611
|
+
// Update the ticket with the macro's changes
|
|
1612
|
+
const updates = result.ticket;
|
|
1613
|
+
const updatedTicket = await client.tickets.update(ticketId, updates);
|
|
1614
|
+
|
|
1615
|
+
console.log('Ticket updated with macro actions');
|
|
1616
|
+
console.log('New status:', updatedTicket.status);
|
|
1617
|
+
|
|
1618
|
+
return updatedTicket;
|
|
1619
|
+
} catch (error) {
|
|
1620
|
+
console.error('Error applying macro:', error.message);
|
|
1621
|
+
throw error;
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
applyMacroToTicket(12345, 54321);
|
|
1626
|
+
```
|
|
1627
|
+
|
|
1628
|
+
---
|
|
1629
|
+
|
|
1630
|
+
### Views API
|
|
1631
|
+
|
|
1632
|
+
#### List Views
|
|
1633
|
+
|
|
1634
|
+
**Basic Example:**
|
|
1635
|
+
|
|
1636
|
+
```javascript
|
|
1637
|
+
client.views.list()
|
|
1638
|
+
.then(views => {
|
|
1639
|
+
console.log('Total views:', views.length);
|
|
1640
|
+
views.forEach(view => {
|
|
1641
|
+
console.log(`${view.title} (ID: ${view.id})`);
|
|
1642
|
+
});
|
|
1643
|
+
})
|
|
1644
|
+
.catch(error => {
|
|
1645
|
+
console.error('Error:', error.message);
|
|
1646
|
+
});
|
|
1647
|
+
```
|
|
1648
|
+
|
|
1649
|
+
**Advanced Example:**
|
|
1650
|
+
|
|
1651
|
+
```javascript
|
|
1652
|
+
async function listActiveViews() {
|
|
1653
|
+
try {
|
|
1654
|
+
const views = await client.views.list();
|
|
1655
|
+
|
|
1656
|
+
const activeViews = views.filter(v => v.active);
|
|
1657
|
+
|
|
1658
|
+
console.log(`Found ${activeViews.length} active views\n`);
|
|
1659
|
+
|
|
1660
|
+
activeViews.forEach(view => {
|
|
1661
|
+
console.log('=== View ===');
|
|
1662
|
+
console.log(`ID: ${view.id}`);
|
|
1663
|
+
console.log(`Title: ${view.title}`);
|
|
1664
|
+
console.log(`Description: ${view.description || 'N/A'}`);
|
|
1665
|
+
console.log(`Active: ${view.active}`);
|
|
1666
|
+
console.log(`Position: ${view.position}`);
|
|
1667
|
+
console.log('---');
|
|
1668
|
+
});
|
|
1669
|
+
|
|
1670
|
+
return activeViews;
|
|
1671
|
+
} catch (error) {
|
|
1672
|
+
console.error('Error fetching views:', error.message);
|
|
1673
|
+
throw error;
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
listActiveViews();
|
|
1678
|
+
```
|
|
1679
|
+
|
|
1680
|
+
#### Execute View
|
|
1681
|
+
|
|
1682
|
+
**Basic Example:**
|
|
1683
|
+
|
|
1684
|
+
```javascript
|
|
1685
|
+
const viewId = 11111;
|
|
1686
|
+
|
|
1687
|
+
client.views.execute(viewId)
|
|
1688
|
+
.then(result => {
|
|
1689
|
+
console.log('View executed!');
|
|
1690
|
+
console.log('Tickets:', result.rows.length);
|
|
1691
|
+
result.rows.forEach(ticket => {
|
|
1692
|
+
console.log(`#${ticket.id}: ${ticket.subject}`);
|
|
1693
|
+
});
|
|
1694
|
+
})
|
|
1695
|
+
.catch(error => {
|
|
1696
|
+
console.error('Error:', error.message);
|
|
1697
|
+
});
|
|
1698
|
+
```
|
|
1699
|
+
|
|
1700
|
+
**Advanced Example:**
|
|
1701
|
+
|
|
1702
|
+
```javascript
|
|
1703
|
+
async function executeViewAndAnalyze(viewId) {
|
|
1704
|
+
try {
|
|
1705
|
+
const result = await client.views.execute(viewId);
|
|
1706
|
+
|
|
1707
|
+
console.log('=== View Execution Results ===');
|
|
1708
|
+
console.log(`Total tickets: ${result.rows.length}`);
|
|
1709
|
+
console.log(`Columns: ${result.columns.map(c => c.title).join(', ')}`);
|
|
1710
|
+
|
|
1711
|
+
// Analyze ticket statuses
|
|
1712
|
+
const statusCounts = {};
|
|
1713
|
+
result.rows.forEach(ticket => {
|
|
1714
|
+
const status = ticket.status;
|
|
1715
|
+
statusCounts[status] = (statusCounts[status] || 0) + 1;
|
|
1716
|
+
});
|
|
1717
|
+
|
|
1718
|
+
console.log('\n=== Status Distribution ===');
|
|
1719
|
+
Object.entries(statusCounts).forEach(([status, count]) => {
|
|
1720
|
+
console.log(`${status}: ${count}`);
|
|
1721
|
+
});
|
|
1722
|
+
|
|
1723
|
+
// Show first 10 tickets
|
|
1724
|
+
console.log('\n=== Tickets ===');
|
|
1725
|
+
result.rows.slice(0, 10).forEach(ticket => {
|
|
1726
|
+
console.log(`#${ticket.id}: ${ticket.subject}`);
|
|
1727
|
+
console.log(` Status: ${ticket.status} | Priority: ${ticket.priority}`);
|
|
1728
|
+
});
|
|
1729
|
+
|
|
1730
|
+
return result;
|
|
1731
|
+
} catch (error) {
|
|
1732
|
+
console.error('Error executing view:', error.message);
|
|
1733
|
+
throw error;
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
executeViewAndAnalyze(11111);
|
|
1738
|
+
```
|
|
1739
|
+
|
|
1740
|
+
---
|
|
1741
|
+
|
|
1742
|
+
### Triggers API
|
|
1743
|
+
|
|
1744
|
+
#### List Triggers
|
|
1745
|
+
|
|
1746
|
+
**Basic Example:**
|
|
1747
|
+
|
|
1748
|
+
```javascript
|
|
1749
|
+
client.triggers.list()
|
|
1750
|
+
.then(triggers => {
|
|
1751
|
+
console.log('Total triggers:', triggers.length);
|
|
1752
|
+
triggers.forEach(trigger => {
|
|
1753
|
+
console.log(`${trigger.title} (ID: ${trigger.id})`);
|
|
1754
|
+
});
|
|
1755
|
+
})
|
|
1756
|
+
.catch(error => {
|
|
1757
|
+
console.error('Error:', error.message);
|
|
1758
|
+
});
|
|
1759
|
+
```
|
|
1760
|
+
|
|
1761
|
+
**Advanced Example:**
|
|
1762
|
+
|
|
1763
|
+
```javascript
|
|
1764
|
+
async function listActiveTriggers() {
|
|
1765
|
+
try {
|
|
1766
|
+
const triggers = await client.triggers.list();
|
|
1767
|
+
|
|
1768
|
+
const activeTriggers = triggers.filter(t => t.active);
|
|
1769
|
+
|
|
1770
|
+
console.log(`Found ${activeTriggers.length} active triggers\n`);
|
|
1771
|
+
|
|
1772
|
+
activeTriggers.forEach(trigger => {
|
|
1773
|
+
console.log('=== Trigger ===');
|
|
1774
|
+
console.log(`ID: ${trigger.id}`);
|
|
1775
|
+
console.log(`Title: ${trigger.title}`);
|
|
1776
|
+
console.log(`Description: ${trigger.description || 'N/A'}`);
|
|
1777
|
+
console.log(`Active: ${trigger.active}`);
|
|
1778
|
+
console.log(`Position: ${trigger.position}`);
|
|
1779
|
+
console.log(`Conditions:`, JSON.stringify(trigger.conditions, null, 2));
|
|
1780
|
+
console.log(`Actions:`, JSON.stringify(trigger.actions, null, 2));
|
|
1781
|
+
console.log('---');
|
|
1782
|
+
});
|
|
1783
|
+
|
|
1784
|
+
return activeTriggers;
|
|
1785
|
+
} catch (error) {
|
|
1786
|
+
console.error('Error fetching triggers:', error.message);
|
|
1787
|
+
throw error;
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
listActiveTriggers();
|
|
1792
|
+
```
|
|
1793
|
+
|
|
1794
|
+
---
|
|
1795
|
+
|
|
1796
|
+
### Automations API
|
|
1797
|
+
|
|
1798
|
+
#### List Automations
|
|
1799
|
+
|
|
1800
|
+
**Basic Example:**
|
|
1801
|
+
|
|
1802
|
+
```javascript
|
|
1803
|
+
client.automations.list()
|
|
1804
|
+
.then(automations => {
|
|
1805
|
+
console.log('Total automations:', automations.length);
|
|
1806
|
+
automations.forEach(automation => {
|
|
1807
|
+
console.log(`${automation.title} (ID: ${automation.id})`);
|
|
1808
|
+
});
|
|
1809
|
+
})
|
|
1810
|
+
.catch(error => {
|
|
1811
|
+
console.error('Error:', error.message);
|
|
1812
|
+
});
|
|
1813
|
+
```
|
|
1814
|
+
|
|
1815
|
+
**Advanced Example:**
|
|
1816
|
+
|
|
1817
|
+
```javascript
|
|
1818
|
+
async function listActiveAutomations() {
|
|
1819
|
+
try {
|
|
1820
|
+
const automations = await client.automations.list();
|
|
1821
|
+
|
|
1822
|
+
const activeAutomations = automations.filter(a => a.active);
|
|
1823
|
+
|
|
1824
|
+
console.log(`Found ${activeAutomations.length} active automations\n`);
|
|
1825
|
+
|
|
1826
|
+
activeAutomations.forEach(automation => {
|
|
1827
|
+
console.log('=== Automation ===');
|
|
1828
|
+
console.log(`ID: ${automation.id}`);
|
|
1829
|
+
console.log(`Title: ${automation.title}`);
|
|
1830
|
+
console.log(`Active: ${automation.active}`);
|
|
1831
|
+
console.log(`Position: ${automation.position}`);
|
|
1832
|
+
console.log(`Conditions:`, JSON.stringify(automation.conditions, null, 2));
|
|
1833
|
+
console.log(`Actions:`, JSON.stringify(automation.actions, null, 2));
|
|
1834
|
+
console.log('---');
|
|
1835
|
+
});
|
|
1836
|
+
|
|
1837
|
+
return activeAutomations;
|
|
1838
|
+
} catch (error) {
|
|
1839
|
+
console.error('Error fetching automations:', error.message);
|
|
1840
|
+
throw error;
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
listActiveAutomations();
|
|
1845
|
+
```
|
|
1846
|
+
|
|
1847
|
+
---
|
|
1848
|
+
|
|
1849
|
+
### Brands API
|
|
1850
|
+
|
|
1851
|
+
#### List Brands
|
|
1852
|
+
|
|
1853
|
+
**Basic Example:**
|
|
1854
|
+
|
|
1855
|
+
```javascript
|
|
1856
|
+
client.brands.list()
|
|
1857
|
+
.then(brands => {
|
|
1858
|
+
console.log('Total brands:', brands.length);
|
|
1859
|
+
brands.forEach(brand => {
|
|
1860
|
+
console.log(`${brand.name} (ID: ${brand.id})`);
|
|
1861
|
+
});
|
|
1862
|
+
})
|
|
1863
|
+
.catch(error => {
|
|
1864
|
+
console.error('Error:', error.message);
|
|
1865
|
+
});
|
|
1866
|
+
```
|
|
1867
|
+
|
|
1868
|
+
**Advanced Example:**
|
|
1869
|
+
|
|
1870
|
+
```javascript
|
|
1871
|
+
async function listAllBrands() {
|
|
1872
|
+
try {
|
|
1873
|
+
const brands = await client.brands.list();
|
|
1874
|
+
|
|
1875
|
+
console.log(`Found ${brands.length} brands\n`);
|
|
1876
|
+
|
|
1877
|
+
brands.forEach(brand => {
|
|
1878
|
+
console.log('=== Brand ===');
|
|
1879
|
+
console.log(`ID: ${brand.id}`);
|
|
1880
|
+
console.log(`Name: ${brand.name}`);
|
|
1881
|
+
console.log(`Subdomain: ${brand.subdomain}`);
|
|
1882
|
+
console.log(`Host Mapping: ${brand.host_mapping || 'N/A'}`);
|
|
1883
|
+
console.log(`Active: ${brand.active}`);
|
|
1884
|
+
console.log(`Default: ${brand.default}`);
|
|
1885
|
+
console.log(`Created: ${brand.created_at}`);
|
|
1886
|
+
console.log('---');
|
|
1887
|
+
});
|
|
1888
|
+
|
|
1889
|
+
return brands;
|
|
1890
|
+
} catch (error) {
|
|
1891
|
+
console.error('Error fetching brands:', error.message);
|
|
1892
|
+
throw error;
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
listAllBrands();
|
|
1897
|
+
```
|
|
1898
|
+
|
|
1899
|
+
---
|
|
1900
|
+
|
|
1901
|
+
## Error Handling
|
|
1902
|
+
|
|
1903
|
+
### Basic Error Handling
|
|
1904
|
+
|
|
1905
|
+
```javascript
|
|
1906
|
+
client.tickets.show(99999)
|
|
1907
|
+
.then(ticket => {
|
|
1908
|
+
console.log('Ticket:', ticket.subject);
|
|
1909
|
+
})
|
|
1910
|
+
.catch(error => {
|
|
1911
|
+
console.error('Error occurred:', error.message);
|
|
1912
|
+
console.error('Status code:', error.statusCode);
|
|
1913
|
+
});
|
|
1914
|
+
```
|
|
1915
|
+
|
|
1916
|
+
### Advanced Error Handling
|
|
1917
|
+
|
|
1918
|
+
```javascript
|
|
1919
|
+
async function handleZendeskErrors() {
|
|
1920
|
+
try {
|
|
1921
|
+
const ticket = await client.tickets.show(99999);
|
|
1922
|
+
return ticket;
|
|
1923
|
+
} catch (error) {
|
|
1924
|
+
// Check error type
|
|
1925
|
+
if (error.statusCode === 404) {
|
|
1926
|
+
console.error('Ticket not found');
|
|
1927
|
+
} else if (error.statusCode === 401) {
|
|
1928
|
+
console.error('Authentication failed - check credentials');
|
|
1929
|
+
} else if (error.statusCode === 403) {
|
|
1930
|
+
console.error('Forbidden - insufficient permissions');
|
|
1931
|
+
} else if (error.statusCode === 429) {
|
|
1932
|
+
console.error('Rate limit exceeded - retry after:', error.retry);
|
|
1933
|
+
} else if (error.statusCode >= 500) {
|
|
1934
|
+
console.error('Zendesk server error - try again later');
|
|
1935
|
+
} else {
|
|
1936
|
+
console.error('Unknown error:', error.message);
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1939
|
+
// Log full error details
|
|
1940
|
+
console.error('Error details:', {
|
|
1941
|
+
statusCode: error.statusCode,
|
|
1942
|
+
message: error.message,
|
|
1943
|
+
stack: error.stack
|
|
1944
|
+
});
|
|
1945
|
+
|
|
1946
|
+
throw error;
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1949
|
+
```
|
|
1950
|
+
|
|
1951
|
+
### Retry Logic
|
|
1952
|
+
|
|
1953
|
+
```javascript
|
|
1954
|
+
async function fetchTicketWithRetry(ticketId, maxRetries = 3) {
|
|
1955
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
1956
|
+
try {
|
|
1957
|
+
const ticket = await client.tickets.show(ticketId);
|
|
1958
|
+
return ticket;
|
|
1959
|
+
} catch (error) {
|
|
1960
|
+
if (error.statusCode === 429 && attempt < maxRetries) {
|
|
1961
|
+
// Rate limited - wait and retry
|
|
1962
|
+
const waitTime = Math.pow(2, attempt) * 1000; // Exponential backoff
|
|
1963
|
+
console.log(`Rate limited. Retrying in ${waitTime}ms...`);
|
|
1964
|
+
await new Promise(resolve => setTimeout(resolve, waitTime));
|
|
1965
|
+
} else if (attempt === maxRetries) {
|
|
1966
|
+
console.error(`Failed after ${maxRetries} attempts`);
|
|
1967
|
+
throw error;
|
|
1968
|
+
} else if (error.statusCode >= 500 && attempt < maxRetries) {
|
|
1969
|
+
// Server error - retry
|
|
1970
|
+
console.log(`Server error. Attempt ${attempt}/${maxRetries}`);
|
|
1971
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
1972
|
+
} else {
|
|
1973
|
+
throw error;
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1978
|
+
```
|
|
1979
|
+
|
|
1980
|
+
---
|
|
1981
|
+
|
|
1982
|
+
## Complete Working Examples
|
|
1983
|
+
|
|
1984
|
+
### Basic Support Ticket System
|
|
1985
|
+
|
|
1986
|
+
```javascript
|
|
1987
|
+
require('dotenv').config();
|
|
1988
|
+
const zendesk = require('node-zendesk');
|
|
1989
|
+
|
|
1990
|
+
const client = zendesk.createClient({
|
|
1991
|
+
username: process.env.ZENDESK_USERNAME,
|
|
1992
|
+
token: process.env.ZENDESK_API_TOKEN,
|
|
1993
|
+
subdomain: process.env.ZENDESK_SUBDOMAIN
|
|
1994
|
+
});
|
|
1995
|
+
|
|
1996
|
+
async function createSupportTicket(customerEmail, subject, description) {
|
|
1997
|
+
try {
|
|
1998
|
+
// Check if user exists
|
|
1999
|
+
let user;
|
|
2000
|
+
const users = await client.users.search({ query: customerEmail });
|
|
2001
|
+
|
|
2002
|
+
if (users.length > 0) {
|
|
2003
|
+
user = users[0];
|
|
2004
|
+
console.log('Found existing user:', user.name);
|
|
2005
|
+
} else {
|
|
2006
|
+
// Create new user
|
|
2007
|
+
user = await client.users.create({
|
|
2008
|
+
name: customerEmail.split('@')[0],
|
|
2009
|
+
email: customerEmail,
|
|
2010
|
+
role: 'end-user'
|
|
2011
|
+
});
|
|
2012
|
+
console.log('Created new user:', user.name);
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
// Create ticket
|
|
2016
|
+
const ticket = await client.tickets.create({
|
|
2017
|
+
subject: subject,
|
|
2018
|
+
comment: {
|
|
2019
|
+
body: description
|
|
2020
|
+
},
|
|
2021
|
+
requester_id: user.id,
|
|
2022
|
+
priority: 'normal',
|
|
2023
|
+
status: 'new'
|
|
2024
|
+
});
|
|
2025
|
+
|
|
2026
|
+
console.log('Ticket created successfully!');
|
|
2027
|
+
console.log('Ticket ID:', ticket.id);
|
|
2028
|
+
console.log('Subject:', ticket.subject);
|
|
2029
|
+
|
|
2030
|
+
return ticket;
|
|
2031
|
+
} catch (error) {
|
|
2032
|
+
console.error('Error creating support ticket:', error.message);
|
|
2033
|
+
throw error;
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
|
|
2037
|
+
// Usage
|
|
2038
|
+
createSupportTicket(
|
|
2039
|
+
'customer@example.com',
|
|
2040
|
+
'Cannot access my account',
|
|
2041
|
+
'I am unable to log into my account. I keep getting an error message.'
|
|
2042
|
+
);
|
|
2043
|
+
```
|
|
2044
|
+
|
|
2045
|
+
### Ticket Management Dashboard
|
|
2046
|
+
|
|
2047
|
+
```javascript
|
|
2048
|
+
require('dotenv').config();
|
|
2049
|
+
const zendesk = require('node-zendesk');
|
|
2050
|
+
|
|
2051
|
+
const client = zendesk.createClient({
|
|
2052
|
+
username: process.env.ZENDESK_USERNAME,
|
|
2053
|
+
token: process.env.ZENDESK_API_TOKEN,
|
|
2054
|
+
subdomain: process.env.ZENDESK_SUBDOMAIN
|
|
2055
|
+
});
|
|
2056
|
+
|
|
2057
|
+
async function getDashboardStats() {
|
|
2058
|
+
try {
|
|
2059
|
+
// Search for different ticket categories
|
|
2060
|
+
const openTickets = await client.search.query('type:ticket status:open');
|
|
2061
|
+
const pendingTickets = await client.search.query('type:ticket status:pending');
|
|
2062
|
+
const solvedTickets = await client.search.query('type:ticket status:solved created>2025-01-01');
|
|
2063
|
+
const urgentTickets = await client.search.query('type:ticket priority:urgent status<solved');
|
|
2064
|
+
|
|
2065
|
+
console.log('=== Support Dashboard ===');
|
|
2066
|
+
console.log(`Open Tickets: ${openTickets.length}`);
|
|
2067
|
+
console.log(`Pending Tickets: ${pendingTickets.length}`);
|
|
2068
|
+
console.log(`Solved This Year: ${solvedTickets.length}`);
|
|
2069
|
+
console.log(`Urgent Tickets: ${urgentTickets.length}`);
|
|
2070
|
+
|
|
2071
|
+
// List urgent tickets
|
|
2072
|
+
if (urgentTickets.length > 0) {
|
|
2073
|
+
console.log('\n=== Urgent Tickets Requiring Attention ===');
|
|
2074
|
+
urgentTickets.forEach(ticket => {
|
|
2075
|
+
console.log(`#${ticket.id}: ${ticket.subject}`);
|
|
2076
|
+
console.log(` Status: ${ticket.status} | Created: ${ticket.created_at}`);
|
|
2077
|
+
console.log(` Assignee: ${ticket.assignee_id || 'Unassigned'}`);
|
|
2078
|
+
});
|
|
2079
|
+
}
|
|
2080
|
+
|
|
2081
|
+
return {
|
|
2082
|
+
open: openTickets.length,
|
|
2083
|
+
pending: pendingTickets.length,
|
|
2084
|
+
solved: solvedTickets.length,
|
|
2085
|
+
urgent: urgentTickets.length
|
|
2086
|
+
};
|
|
2087
|
+
} catch (error) {
|
|
2088
|
+
console.error('Error fetching dashboard stats:', error.message);
|
|
2089
|
+
throw error;
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2093
|
+
getDashboardStats();
|
|
2094
|
+
```
|
|
2095
|
+
|
|
2096
|
+
### Bulk Ticket Operations
|
|
2097
|
+
|
|
2098
|
+
```javascript
|
|
2099
|
+
require('dotenv').config();
|
|
2100
|
+
const zendesk = require('node-zendesk');
|
|
2101
|
+
|
|
2102
|
+
const client = zendesk.createClient({
|
|
2103
|
+
username: process.env.ZENDESK_USERNAME,
|
|
2104
|
+
token: process.env.ZENDESK_API_TOKEN,
|
|
2105
|
+
subdomain: process.env.ZENDESK_SUBDOMAIN
|
|
2106
|
+
});
|
|
2107
|
+
|
|
2108
|
+
async function bulkUpdateTickets(ticketIds, updates) {
|
|
2109
|
+
try {
|
|
2110
|
+
console.log(`Updating ${ticketIds.length} tickets...`);
|
|
2111
|
+
|
|
2112
|
+
const updatePromises = ticketIds.map(async (ticketId) => {
|
|
2113
|
+
try {
|
|
2114
|
+
const ticket = await client.tickets.update(ticketId, updates);
|
|
2115
|
+
console.log(`✓ Updated ticket #${ticketId}`);
|
|
2116
|
+
return { success: true, ticketId, ticket };
|
|
2117
|
+
} catch (error) {
|
|
2118
|
+
console.error(`✗ Failed to update ticket #${ticketId}:`, error.message);
|
|
2119
|
+
return { success: false, ticketId, error: error.message };
|
|
2120
|
+
}
|
|
2121
|
+
});
|
|
2122
|
+
|
|
2123
|
+
const results = await Promise.all(updatePromises);
|
|
2124
|
+
|
|
2125
|
+
const successful = results.filter(r => r.success).length;
|
|
2126
|
+
const failed = results.filter(r => !r.success).length;
|
|
2127
|
+
|
|
2128
|
+
console.log(`\n=== Bulk Update Complete ===`);
|
|
2129
|
+
console.log(`Successful: ${successful}`);
|
|
2130
|
+
console.log(`Failed: ${failed}`);
|
|
2131
|
+
|
|
2132
|
+
return results;
|
|
2133
|
+
} catch (error) {
|
|
2134
|
+
console.error('Bulk update error:', error.message);
|
|
2135
|
+
throw error;
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2139
|
+
// Usage: Close multiple tickets at once
|
|
2140
|
+
const ticketIds = [12345, 12346, 12347];
|
|
2141
|
+
const updates = {
|
|
2142
|
+
status: 'solved',
|
|
2143
|
+
comment: {
|
|
2144
|
+
body: 'This ticket has been resolved and closed.',
|
|
2145
|
+
public: false
|
|
2146
|
+
}
|
|
2147
|
+
};
|
|
2148
|
+
|
|
2149
|
+
bulkUpdateTickets(ticketIds, updates);
|
|
2150
|
+
```
|