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,1844 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: messaging
|
|
3
|
+
description: "Intercom JavaScript SDK for customer messaging and chat support"
|
|
4
|
+
metadata:
|
|
5
|
+
languages: "javascript"
|
|
6
|
+
versions: "6.4.0"
|
|
7
|
+
updated-on: "2026-03-02"
|
|
8
|
+
source: maintainer
|
|
9
|
+
tags: "intercom,messaging,customer,chat,support"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Intercom JavaScript SDK (v6.4.0)
|
|
13
|
+
|
|
14
|
+
## Golden Rule
|
|
15
|
+
|
|
16
|
+
**ALWAYS use `intercom-client` version 6.4.0 or later.**
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install intercom-client
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**DO NOT use these deprecated or unofficial packages:**
|
|
23
|
+
- `intercom.io` (deprecated)
|
|
24
|
+
- `@ludovicbret/intercom-client` (community fork)
|
|
25
|
+
- Any package not named exactly `intercom-client`
|
|
26
|
+
|
|
27
|
+
The official Intercom TypeScript/JavaScript SDK is `intercom-client`, maintained by Intercom at https://github.com/intercom/intercom-node
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install intercom-client
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
For TypeScript projects, types are included in the package.
|
|
36
|
+
|
|
37
|
+
**Environment Setup:**
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# .env file
|
|
41
|
+
INTERCOM_ACCESS_TOKEN=your_access_token_here
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Loading environment variables:**
|
|
45
|
+
|
|
46
|
+
```javascript
|
|
47
|
+
// Using dotenv
|
|
48
|
+
import 'dotenv/config';
|
|
49
|
+
// or
|
|
50
|
+
require('dotenv').config();
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Initialization
|
|
54
|
+
|
|
55
|
+
**Basic Client Setup:**
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
import { IntercomClient } from 'intercom-client';
|
|
59
|
+
|
|
60
|
+
const client = new IntercomClient({
|
|
61
|
+
token: process.env.INTERCOM_ACCESS_TOKEN
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**TypeScript with explicit typing:**
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { IntercomClient, Intercom } from 'intercom-client';
|
|
69
|
+
|
|
70
|
+
const client: IntercomClient = new IntercomClient({
|
|
71
|
+
token: process.env.INTERCOM_ACCESS_TOKEN
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**With custom configuration:**
|
|
76
|
+
|
|
77
|
+
```javascript
|
|
78
|
+
const client = new IntercomClient({
|
|
79
|
+
token: process.env.INTERCOM_ACCESS_TOKEN,
|
|
80
|
+
timeoutInSeconds: 120, // Default is 60
|
|
81
|
+
maxRetries: 3, // Default is 2
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**API Version Selection:**
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
// Use specific API version
|
|
89
|
+
const client = new IntercomClient({
|
|
90
|
+
token: process.env.INTERCOM_ACCESS_TOKEN,
|
|
91
|
+
apiVersion: '2.11', // Default is latest stable (2.11)
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Core API Surfaces
|
|
96
|
+
|
|
97
|
+
### Contacts
|
|
98
|
+
|
|
99
|
+
Contacts represent users, leads, and visitors in Intercom. They are the primary entities for customer communication.
|
|
100
|
+
|
|
101
|
+
**Create a contact:**
|
|
102
|
+
|
|
103
|
+
```javascript
|
|
104
|
+
const contact = await client.contacts.create({
|
|
105
|
+
email: '[email protected]',
|
|
106
|
+
name: 'John Doe',
|
|
107
|
+
phone: '+1234567890',
|
|
108
|
+
role: 'user', // 'user' or 'lead'
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
console.log(contact.id);
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Create with custom attributes:**
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
const contact = await client.contacts.create({
|
|
118
|
+
email: '[email protected]',
|
|
119
|
+
name: 'Jane Smith',
|
|
120
|
+
role: 'user',
|
|
121
|
+
custom_attributes: {
|
|
122
|
+
plan: 'premium',
|
|
123
|
+
signup_date: '2025-01-15',
|
|
124
|
+
total_spend: 599.99,
|
|
125
|
+
active: true,
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Retrieve a contact:**
|
|
131
|
+
|
|
132
|
+
```javascript
|
|
133
|
+
const contact = await client.contacts.find({
|
|
134
|
+
id: '65f9a5e4f5e5b40001234567',
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
console.log(contact.email, contact.name);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Update a contact:**
|
|
141
|
+
|
|
142
|
+
```javascript
|
|
143
|
+
const updated = await client.contacts.update({
|
|
144
|
+
id: '65f9a5e4f5e5b40001234567',
|
|
145
|
+
name: 'John Updated',
|
|
146
|
+
custom_attributes: {
|
|
147
|
+
plan: 'enterprise',
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Search contacts:**
|
|
153
|
+
|
|
154
|
+
```javascript
|
|
155
|
+
const results = await client.contacts.search({
|
|
156
|
+
query: {
|
|
157
|
+
field: 'email',
|
|
158
|
+
operator: '=',
|
|
159
|
+
value: '[email protected]',
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
for (const contact of results.data) {
|
|
164
|
+
console.log(contact.name, contact.email);
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Search with filters:**
|
|
169
|
+
|
|
170
|
+
```javascript
|
|
171
|
+
const results = await client.contacts.search({
|
|
172
|
+
query: {
|
|
173
|
+
operator: 'AND',
|
|
174
|
+
value: [
|
|
175
|
+
{
|
|
176
|
+
field: 'role',
|
|
177
|
+
operator: '=',
|
|
178
|
+
value: 'user',
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
field: 'created_at',
|
|
182
|
+
operator: '>',
|
|
183
|
+
value: 1704067200, // Unix timestamp
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
},
|
|
187
|
+
pagination: {
|
|
188
|
+
per_page: 50,
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**List all contacts:**
|
|
194
|
+
|
|
195
|
+
```javascript
|
|
196
|
+
const response = await client.contacts.list({
|
|
197
|
+
per_page: 150,
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// Iterate through paginated results
|
|
201
|
+
for await (const contact of response) {
|
|
202
|
+
console.log(contact.email);
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**Delete a contact:**
|
|
207
|
+
|
|
208
|
+
```javascript
|
|
209
|
+
await client.contacts.delete({
|
|
210
|
+
id: '65f9a5e4f5e5b40001234567',
|
|
211
|
+
});
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Archive a contact:**
|
|
215
|
+
|
|
216
|
+
```javascript
|
|
217
|
+
const archived = await client.contacts.archive({
|
|
218
|
+
id: '65f9a5e4f5e5b40001234567',
|
|
219
|
+
});
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**Unarchive a contact:**
|
|
223
|
+
|
|
224
|
+
```javascript
|
|
225
|
+
const unarchived = await client.contacts.unarchive({
|
|
226
|
+
id: '65f9a5e4f5e5b40001234567',
|
|
227
|
+
});
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**Merge contacts:**
|
|
231
|
+
|
|
232
|
+
```javascript
|
|
233
|
+
const merged = await client.contacts.merge({
|
|
234
|
+
from: '65f9a5e4f5e5b40001234567',
|
|
235
|
+
into: '65f9a5e4f5e5b40009876543',
|
|
236
|
+
});
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Companies
|
|
240
|
+
|
|
241
|
+
Companies group contacts together by organization. They're useful for B2B use cases.
|
|
242
|
+
|
|
243
|
+
**Create a company:**
|
|
244
|
+
|
|
245
|
+
```javascript
|
|
246
|
+
const company = await client.companies.create({
|
|
247
|
+
company_id: 'company_123',
|
|
248
|
+
name: 'Acme Corporation',
|
|
249
|
+
website: 'https://acme.com',
|
|
250
|
+
industry: 'Technology',
|
|
251
|
+
size: 500,
|
|
252
|
+
custom_attributes: {
|
|
253
|
+
plan_level: 'enterprise',
|
|
254
|
+
mrr: 50000,
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
**Retrieve a company:**
|
|
260
|
+
|
|
261
|
+
```javascript
|
|
262
|
+
const company = await client.companies.find({
|
|
263
|
+
company_id: 'company_123',
|
|
264
|
+
});
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Update a company:**
|
|
268
|
+
|
|
269
|
+
```javascript
|
|
270
|
+
const updated = await client.companies.update({
|
|
271
|
+
company_id: 'company_123',
|
|
272
|
+
name: 'Acme Corp',
|
|
273
|
+
size: 600,
|
|
274
|
+
custom_attributes: {
|
|
275
|
+
mrr: 60000,
|
|
276
|
+
},
|
|
277
|
+
});
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**List companies:**
|
|
281
|
+
|
|
282
|
+
```javascript
|
|
283
|
+
const response = await client.companies.list({
|
|
284
|
+
per_page: 50,
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
for await (const company of response) {
|
|
288
|
+
console.log(company.name, company.company_id);
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**Attach contact to company:**
|
|
293
|
+
|
|
294
|
+
```javascript
|
|
295
|
+
await client.contacts.update({
|
|
296
|
+
id: '65f9a5e4f5e5b40001234567',
|
|
297
|
+
companies: [
|
|
298
|
+
{
|
|
299
|
+
company_id: 'company_123',
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
});
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
**List company contacts:**
|
|
306
|
+
|
|
307
|
+
```javascript
|
|
308
|
+
const contacts = await client.companies.listContacts({
|
|
309
|
+
company_id: 'company_123',
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
for await (const contact of contacts) {
|
|
313
|
+
console.log(contact.email);
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
**Delete a company:**
|
|
318
|
+
|
|
319
|
+
```javascript
|
|
320
|
+
await client.companies.delete({
|
|
321
|
+
company_id: 'company_123',
|
|
322
|
+
});
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Conversations
|
|
326
|
+
|
|
327
|
+
Conversations are threads of communication between contacts and your team.
|
|
328
|
+
|
|
329
|
+
**Create a conversation:**
|
|
330
|
+
|
|
331
|
+
```javascript
|
|
332
|
+
const conversation = await client.conversations.create({
|
|
333
|
+
from: {
|
|
334
|
+
type: 'user',
|
|
335
|
+
id: '65f9a5e4f5e5b40001234567',
|
|
336
|
+
},
|
|
337
|
+
body: 'Hello, I need help with my account.',
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
console.log(conversation.id);
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**Create conversation with user:**
|
|
344
|
+
|
|
345
|
+
```javascript
|
|
346
|
+
const conversation = await client.conversations.createConversation({
|
|
347
|
+
userId: '65f9a5e4f5e5b40001234567',
|
|
348
|
+
body: 'I have a question about billing.',
|
|
349
|
+
});
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
**Retrieve a conversation:**
|
|
353
|
+
|
|
354
|
+
```javascript
|
|
355
|
+
const conversation = await client.conversations.find({
|
|
356
|
+
id: '123456',
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
console.log(conversation.state); // 'open', 'closed', 'snoozed'
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
**Reply to conversation as admin:**
|
|
363
|
+
|
|
364
|
+
```javascript
|
|
365
|
+
const reply = await client.conversations.reply({
|
|
366
|
+
id: '123456',
|
|
367
|
+
message_type: 'comment',
|
|
368
|
+
type: 'admin',
|
|
369
|
+
admin_id: '987654',
|
|
370
|
+
body: 'Thanks for reaching out! How can I help?',
|
|
371
|
+
});
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
**Reply with attachment:**
|
|
375
|
+
|
|
376
|
+
```javascript
|
|
377
|
+
const reply = await client.conversations.reply({
|
|
378
|
+
id: '123456',
|
|
379
|
+
message_type: 'comment',
|
|
380
|
+
type: 'admin',
|
|
381
|
+
admin_id: '987654',
|
|
382
|
+
body: 'Here is the document you requested.',
|
|
383
|
+
attachment_urls: [
|
|
384
|
+
'https://example.com/document.pdf',
|
|
385
|
+
],
|
|
386
|
+
});
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
**Reply as user:**
|
|
390
|
+
|
|
391
|
+
```javascript
|
|
392
|
+
const reply = await client.conversations.reply({
|
|
393
|
+
id: '123456',
|
|
394
|
+
message_type: 'comment',
|
|
395
|
+
type: 'user',
|
|
396
|
+
user_id: '65f9a5e4f5e5b40001234567',
|
|
397
|
+
body: 'Thank you for your help!',
|
|
398
|
+
});
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
**Search conversations:**
|
|
402
|
+
|
|
403
|
+
```javascript
|
|
404
|
+
const results = await client.conversations.search({
|
|
405
|
+
query: {
|
|
406
|
+
field: 'state',
|
|
407
|
+
operator: '=',
|
|
408
|
+
value: 'open',
|
|
409
|
+
},
|
|
410
|
+
pagination: {
|
|
411
|
+
per_page: 50,
|
|
412
|
+
},
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
for (const conv of results.conversations) {
|
|
416
|
+
console.log(conv.id, conv.created_at);
|
|
417
|
+
}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
**Search with multiple filters:**
|
|
421
|
+
|
|
422
|
+
```javascript
|
|
423
|
+
const results = await client.conversations.search({
|
|
424
|
+
query: {
|
|
425
|
+
operator: 'AND',
|
|
426
|
+
value: [
|
|
427
|
+
{
|
|
428
|
+
field: 'state',
|
|
429
|
+
operator: '=',
|
|
430
|
+
value: 'open',
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
field: 'updated_at',
|
|
434
|
+
operator: '>',
|
|
435
|
+
value: 1704067200,
|
|
436
|
+
},
|
|
437
|
+
],
|
|
438
|
+
},
|
|
439
|
+
sort: {
|
|
440
|
+
field: 'updated_at',
|
|
441
|
+
order: 'descending',
|
|
442
|
+
},
|
|
443
|
+
});
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
**List conversations:**
|
|
447
|
+
|
|
448
|
+
```javascript
|
|
449
|
+
const response = await client.conversations.list();
|
|
450
|
+
|
|
451
|
+
for await (const conversation of response) {
|
|
452
|
+
console.log(conversation.id, conversation.state);
|
|
453
|
+
}
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
**Close a conversation:**
|
|
457
|
+
|
|
458
|
+
```javascript
|
|
459
|
+
const closed = await client.conversations.close({
|
|
460
|
+
id: '123456',
|
|
461
|
+
type: 'admin',
|
|
462
|
+
admin_id: '987654',
|
|
463
|
+
});
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
**Open a conversation:**
|
|
467
|
+
|
|
468
|
+
```javascript
|
|
469
|
+
const opened = await client.conversations.open({
|
|
470
|
+
id: '123456',
|
|
471
|
+
type: 'admin',
|
|
472
|
+
admin_id: '987654',
|
|
473
|
+
});
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
**Snooze a conversation:**
|
|
477
|
+
|
|
478
|
+
```javascript
|
|
479
|
+
const snoozed = await client.conversations.snooze({
|
|
480
|
+
id: '123456',
|
|
481
|
+
type: 'admin',
|
|
482
|
+
admin_id: '987654',
|
|
483
|
+
snoozed_until: 1704153600, // Unix timestamp
|
|
484
|
+
});
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
**Assign conversation to admin:**
|
|
488
|
+
|
|
489
|
+
```javascript
|
|
490
|
+
const assigned = await client.conversations.assign({
|
|
491
|
+
id: '123456',
|
|
492
|
+
type: 'admin',
|
|
493
|
+
admin_id: '987654',
|
|
494
|
+
assignee_id: '111222',
|
|
495
|
+
});
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
**Assign to team:**
|
|
499
|
+
|
|
500
|
+
```javascript
|
|
501
|
+
const assigned = await client.conversations.assign({
|
|
502
|
+
id: '123456',
|
|
503
|
+
type: 'admin',
|
|
504
|
+
admin_id: '987654',
|
|
505
|
+
assignee_id: '333444',
|
|
506
|
+
assignment_type: 'team',
|
|
507
|
+
});
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
**Convert conversation to ticket:**
|
|
511
|
+
|
|
512
|
+
```javascript
|
|
513
|
+
const ticket = await client.conversations.convertToTicket({
|
|
514
|
+
id: '123456',
|
|
515
|
+
ticket_type_id: '100',
|
|
516
|
+
});
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
**Add tag to conversation:**
|
|
520
|
+
|
|
521
|
+
```javascript
|
|
522
|
+
await client.conversations.attachTag({
|
|
523
|
+
conversationId: '123456',
|
|
524
|
+
id: 'tag_789',
|
|
525
|
+
adminId: '987654',
|
|
526
|
+
});
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
**Remove tag from conversation:**
|
|
530
|
+
|
|
531
|
+
```javascript
|
|
532
|
+
await client.conversations.detachTag({
|
|
533
|
+
conversationId: '123456',
|
|
534
|
+
id: 'tag_789',
|
|
535
|
+
adminId: '987654',
|
|
536
|
+
});
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
### Messages
|
|
540
|
+
|
|
541
|
+
Send messages to contacts via Intercom.
|
|
542
|
+
|
|
543
|
+
**Send a message to contact:**
|
|
544
|
+
|
|
545
|
+
```javascript
|
|
546
|
+
const message = await client.messages.create({
|
|
547
|
+
message_type: 'email',
|
|
548
|
+
from: {
|
|
549
|
+
type: 'admin',
|
|
550
|
+
id: '987654',
|
|
551
|
+
},
|
|
552
|
+
to: {
|
|
553
|
+
type: 'user',
|
|
554
|
+
id: '65f9a5e4f5e5b40001234567',
|
|
555
|
+
},
|
|
556
|
+
subject: 'Welcome to our platform',
|
|
557
|
+
body: 'Thanks for signing up! Here are some tips to get started.',
|
|
558
|
+
});
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
**Send message by email:**
|
|
562
|
+
|
|
563
|
+
```javascript
|
|
564
|
+
const message = await client.messages.create({
|
|
565
|
+
message_type: 'email',
|
|
566
|
+
from: {
|
|
567
|
+
type: 'admin',
|
|
568
|
+
id: '987654',
|
|
569
|
+
},
|
|
570
|
+
to: {
|
|
571
|
+
type: 'user',
|
|
572
|
+
email: '[email protected]',
|
|
573
|
+
},
|
|
574
|
+
subject: 'Your monthly report',
|
|
575
|
+
body: 'Here is your activity summary for January.',
|
|
576
|
+
});
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
**Send in-app message:**
|
|
580
|
+
|
|
581
|
+
```javascript
|
|
582
|
+
const message = await client.messages.create({
|
|
583
|
+
message_type: 'inapp',
|
|
584
|
+
from: {
|
|
585
|
+
type: 'admin',
|
|
586
|
+
id: '987654',
|
|
587
|
+
},
|
|
588
|
+
to: {
|
|
589
|
+
type: 'user',
|
|
590
|
+
id: '65f9a5e4f5e5b40001234567',
|
|
591
|
+
},
|
|
592
|
+
body: 'Check out our new features!',
|
|
593
|
+
});
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
**Send message with custom data:**
|
|
597
|
+
|
|
598
|
+
```javascript
|
|
599
|
+
const message = await client.messages.create({
|
|
600
|
+
message_type: 'email',
|
|
601
|
+
from: {
|
|
602
|
+
type: 'admin',
|
|
603
|
+
id: '987654',
|
|
604
|
+
},
|
|
605
|
+
to: {
|
|
606
|
+
type: 'user',
|
|
607
|
+
id: '65f9a5e4f5e5b40001234567',
|
|
608
|
+
},
|
|
609
|
+
subject: 'Order confirmation',
|
|
610
|
+
body: 'Your order has been confirmed.',
|
|
611
|
+
template: 'plain',
|
|
612
|
+
create_conversation_without_contact_reply: false,
|
|
613
|
+
});
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
### Data Events
|
|
617
|
+
|
|
618
|
+
Track user behavior and custom events.
|
|
619
|
+
|
|
620
|
+
**Submit a data event:**
|
|
621
|
+
|
|
622
|
+
```javascript
|
|
623
|
+
await client.events.create({
|
|
624
|
+
event_name: 'purchased_item',
|
|
625
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
626
|
+
user_id: '65f9a5e4f5e5b40001234567',
|
|
627
|
+
metadata: {
|
|
628
|
+
item_name: 'Premium Plan',
|
|
629
|
+
item_price: 99.99,
|
|
630
|
+
currency: 'USD',
|
|
631
|
+
quantity: 1,
|
|
632
|
+
},
|
|
633
|
+
});
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
**Event with email identifier:**
|
|
637
|
+
|
|
638
|
+
```javascript
|
|
639
|
+
await client.events.create({
|
|
640
|
+
event_name: 'signed_up',
|
|
641
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
642
|
+
email: '[email protected]',
|
|
643
|
+
metadata: {
|
|
644
|
+
source: 'landing_page',
|
|
645
|
+
campaign: 'winter_2025',
|
|
646
|
+
},
|
|
647
|
+
});
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
**Complex event metadata:**
|
|
651
|
+
|
|
652
|
+
```javascript
|
|
653
|
+
await client.events.create({
|
|
654
|
+
event_name: 'completed_onboarding',
|
|
655
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
656
|
+
user_id: '65f9a5e4f5e5b40001234567',
|
|
657
|
+
metadata: {
|
|
658
|
+
steps_completed: 5,
|
|
659
|
+
time_taken_seconds: 320,
|
|
660
|
+
skipped_steps: ['profile_picture'],
|
|
661
|
+
completion_rate: 0.95,
|
|
662
|
+
device: 'mobile',
|
|
663
|
+
},
|
|
664
|
+
});
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
**List events for user:**
|
|
668
|
+
|
|
669
|
+
```javascript
|
|
670
|
+
const events = await client.events.list({
|
|
671
|
+
type: 'user',
|
|
672
|
+
user_id: '65f9a5e4f5e5b40001234567',
|
|
673
|
+
});
|
|
674
|
+
|
|
675
|
+
for (const event of events.events) {
|
|
676
|
+
console.log(event.event_name, event.created_at);
|
|
677
|
+
}
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
**Event summaries:**
|
|
681
|
+
|
|
682
|
+
```javascript
|
|
683
|
+
const summary = await client.events.summaries({
|
|
684
|
+
user_id: '65f9a5e4f5e5b40001234567',
|
|
685
|
+
event_name: 'purchased_item',
|
|
686
|
+
});
|
|
687
|
+
|
|
688
|
+
console.log(summary.count, summary.first, summary.last);
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
### Tags
|
|
692
|
+
|
|
693
|
+
Organize and categorize contacts, companies, and conversations.
|
|
694
|
+
|
|
695
|
+
**Create a tag:**
|
|
696
|
+
|
|
697
|
+
```javascript
|
|
698
|
+
const tag = await client.tags.create({
|
|
699
|
+
name: 'VIP Customer',
|
|
700
|
+
});
|
|
701
|
+
|
|
702
|
+
console.log(tag.id);
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
**Retrieve a tag:**
|
|
706
|
+
|
|
707
|
+
```javascript
|
|
708
|
+
const tag = await client.tags.find({
|
|
709
|
+
id: 'tag_789',
|
|
710
|
+
});
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
**List all tags:**
|
|
714
|
+
|
|
715
|
+
```javascript
|
|
716
|
+
const tags = await client.tags.list();
|
|
717
|
+
|
|
718
|
+
for (const tag of tags.data) {
|
|
719
|
+
console.log(tag.name, tag.id);
|
|
720
|
+
}
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
**Tag a contact:**
|
|
724
|
+
|
|
725
|
+
```javascript
|
|
726
|
+
await client.contacts.tag({
|
|
727
|
+
contactId: '65f9a5e4f5e5b40001234567',
|
|
728
|
+
id: 'tag_789',
|
|
729
|
+
});
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
**Tag a company:**
|
|
733
|
+
|
|
734
|
+
```javascript
|
|
735
|
+
await client.companies.tag({
|
|
736
|
+
companyId: 'company_123',
|
|
737
|
+
id: 'tag_789',
|
|
738
|
+
});
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
**Untag a contact:**
|
|
742
|
+
|
|
743
|
+
```javascript
|
|
744
|
+
await client.contacts.untag({
|
|
745
|
+
contactId: '65f9a5e4f5e5b40001234567',
|
|
746
|
+
id: 'tag_789',
|
|
747
|
+
});
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
**Delete a tag:**
|
|
751
|
+
|
|
752
|
+
```javascript
|
|
753
|
+
await client.tags.delete({
|
|
754
|
+
id: 'tag_789',
|
|
755
|
+
});
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
### Data Attributes
|
|
759
|
+
|
|
760
|
+
Define custom attributes for contacts and companies.
|
|
761
|
+
|
|
762
|
+
**Create a contact attribute:**
|
|
763
|
+
|
|
764
|
+
```javascript
|
|
765
|
+
const attribute = await client.dataAttributes.create({
|
|
766
|
+
name: 'subscription_tier',
|
|
767
|
+
model: 'contact',
|
|
768
|
+
data_type: 'string',
|
|
769
|
+
options: ['free', 'pro', 'enterprise'],
|
|
770
|
+
description: 'Customer subscription level',
|
|
771
|
+
});
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
**Create a company attribute:**
|
|
775
|
+
|
|
776
|
+
```javascript
|
|
777
|
+
const attribute = await client.dataAttributes.create({
|
|
778
|
+
name: 'annual_revenue',
|
|
779
|
+
model: 'company',
|
|
780
|
+
data_type: 'float',
|
|
781
|
+
description: 'Company annual revenue in USD',
|
|
782
|
+
});
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
**Create boolean attribute:**
|
|
786
|
+
|
|
787
|
+
```javascript
|
|
788
|
+
const attribute = await client.dataAttributes.create({
|
|
789
|
+
name: 'is_beta_tester',
|
|
790
|
+
model: 'contact',
|
|
791
|
+
data_type: 'boolean',
|
|
792
|
+
description: 'Whether user is enrolled in beta program',
|
|
793
|
+
});
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
**Create date attribute:**
|
|
797
|
+
|
|
798
|
+
```javascript
|
|
799
|
+
const attribute = await client.dataAttributes.create({
|
|
800
|
+
name: 'trial_end_date',
|
|
801
|
+
model: 'contact',
|
|
802
|
+
data_type: 'date',
|
|
803
|
+
description: 'Date when trial period ends',
|
|
804
|
+
});
|
|
805
|
+
```
|
|
806
|
+
|
|
807
|
+
**List data attributes:**
|
|
808
|
+
|
|
809
|
+
```javascript
|
|
810
|
+
const attributes = await client.dataAttributes.list({
|
|
811
|
+
model: 'contact',
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
for (const attr of attributes.data) {
|
|
815
|
+
console.log(attr.name, attr.data_type);
|
|
816
|
+
}
|
|
817
|
+
```
|
|
818
|
+
|
|
819
|
+
**Update an attribute:**
|
|
820
|
+
|
|
821
|
+
```javascript
|
|
822
|
+
const updated = await client.dataAttributes.update({
|
|
823
|
+
id: 'attr_123',
|
|
824
|
+
description: 'Updated description',
|
|
825
|
+
options: ['free', 'pro', 'enterprise', 'custom'],
|
|
826
|
+
});
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
### Notes
|
|
830
|
+
|
|
831
|
+
Add notes to contacts and companies for internal reference.
|
|
832
|
+
|
|
833
|
+
**Create a note for contact:**
|
|
834
|
+
|
|
835
|
+
```javascript
|
|
836
|
+
const note = await client.notes.create({
|
|
837
|
+
contact_id: '65f9a5e4f5e5b40001234567',
|
|
838
|
+
admin_id: '987654',
|
|
839
|
+
body: 'Customer requested custom integration. Follow up next week.',
|
|
840
|
+
});
|
|
841
|
+
```
|
|
842
|
+
|
|
843
|
+
**Create a note for company:**
|
|
844
|
+
|
|
845
|
+
```javascript
|
|
846
|
+
const note = await client.notes.create({
|
|
847
|
+
company_id: 'company_123',
|
|
848
|
+
admin_id: '987654',
|
|
849
|
+
body: 'Contract renewal coming up in Q2 2025.',
|
|
850
|
+
});
|
|
851
|
+
```
|
|
852
|
+
|
|
853
|
+
**Retrieve a note:**
|
|
854
|
+
|
|
855
|
+
```javascript
|
|
856
|
+
const note = await client.notes.find({
|
|
857
|
+
id: 'note_456',
|
|
858
|
+
});
|
|
859
|
+
```
|
|
860
|
+
|
|
861
|
+
**List notes for contact:**
|
|
862
|
+
|
|
863
|
+
```javascript
|
|
864
|
+
const notes = await client.contacts.listNotes({
|
|
865
|
+
id: '65f9a5e4f5e5b40001234567',
|
|
866
|
+
});
|
|
867
|
+
|
|
868
|
+
for (const note of notes.data) {
|
|
869
|
+
console.log(note.body, note.created_at);
|
|
870
|
+
}
|
|
871
|
+
```
|
|
872
|
+
|
|
873
|
+
### Segments
|
|
874
|
+
|
|
875
|
+
Query and retrieve segments (groups of contacts).
|
|
876
|
+
|
|
877
|
+
**List all segments:**
|
|
878
|
+
|
|
879
|
+
```javascript
|
|
880
|
+
const segments = await client.segments.list();
|
|
881
|
+
|
|
882
|
+
for (const segment of segments.segments) {
|
|
883
|
+
console.log(segment.name, segment.count);
|
|
884
|
+
}
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
**Retrieve a segment:**
|
|
888
|
+
|
|
889
|
+
```javascript
|
|
890
|
+
const segment = await client.segments.find({
|
|
891
|
+
id: 'segment_999',
|
|
892
|
+
});
|
|
893
|
+
|
|
894
|
+
console.log(segment.name, segment.person_type);
|
|
895
|
+
```
|
|
896
|
+
|
|
897
|
+
**List contacts in segment:**
|
|
898
|
+
|
|
899
|
+
```javascript
|
|
900
|
+
const contacts = await client.segments.listContacts({
|
|
901
|
+
id: 'segment_999',
|
|
902
|
+
});
|
|
903
|
+
|
|
904
|
+
for await (const contact of contacts) {
|
|
905
|
+
console.log(contact.email);
|
|
906
|
+
}
|
|
907
|
+
```
|
|
908
|
+
|
|
909
|
+
### Tickets
|
|
910
|
+
|
|
911
|
+
Manage customer support tickets.
|
|
912
|
+
|
|
913
|
+
**Create a ticket:**
|
|
914
|
+
|
|
915
|
+
```javascript
|
|
916
|
+
const ticket = await client.tickets.create({
|
|
917
|
+
contact_id: '65f9a5e4f5e5b40001234567',
|
|
918
|
+
ticket_type_id: '100',
|
|
919
|
+
contacts: [
|
|
920
|
+
{
|
|
921
|
+
id: '65f9a5e4f5e5b40001234567',
|
|
922
|
+
},
|
|
923
|
+
],
|
|
924
|
+
ticket_attributes: {
|
|
925
|
+
_default_title_: 'Payment issue',
|
|
926
|
+
_default_description_: 'Customer unable to process payment',
|
|
927
|
+
},
|
|
928
|
+
});
|
|
929
|
+
```
|
|
930
|
+
|
|
931
|
+
**Retrieve a ticket:**
|
|
932
|
+
|
|
933
|
+
```javascript
|
|
934
|
+
const ticket = await client.tickets.find({
|
|
935
|
+
id: 'ticket_888',
|
|
936
|
+
});
|
|
937
|
+
|
|
938
|
+
console.log(ticket.ticket_state);
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
**Update a ticket:**
|
|
942
|
+
|
|
943
|
+
```javascript
|
|
944
|
+
const updated = await client.tickets.update({
|
|
945
|
+
id: 'ticket_888',
|
|
946
|
+
ticket_attributes: {
|
|
947
|
+
_default_title_: 'Payment issue - RESOLVED',
|
|
948
|
+
},
|
|
949
|
+
ticket_state: 'submitted',
|
|
950
|
+
});
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
**Reply to ticket:**
|
|
954
|
+
|
|
955
|
+
```javascript
|
|
956
|
+
const reply = await client.tickets.reply({
|
|
957
|
+
id: 'ticket_888',
|
|
958
|
+
admin_id: '987654',
|
|
959
|
+
message_type: 'comment',
|
|
960
|
+
body: 'Issue has been resolved. Payment processed successfully.',
|
|
961
|
+
});
|
|
962
|
+
```
|
|
963
|
+
|
|
964
|
+
**Search tickets:**
|
|
965
|
+
|
|
966
|
+
```javascript
|
|
967
|
+
const results = await client.tickets.search({
|
|
968
|
+
query: {
|
|
969
|
+
field: 'ticket_state',
|
|
970
|
+
operator: '=',
|
|
971
|
+
value: 'submitted',
|
|
972
|
+
},
|
|
973
|
+
});
|
|
974
|
+
|
|
975
|
+
for (const ticket of results.tickets) {
|
|
976
|
+
console.log(ticket.id, ticket.ticket_attributes);
|
|
977
|
+
}
|
|
978
|
+
```
|
|
979
|
+
|
|
980
|
+
### Admins
|
|
981
|
+
|
|
982
|
+
Manage admin users and teams.
|
|
983
|
+
|
|
984
|
+
**List all admins:**
|
|
985
|
+
|
|
986
|
+
```javascript
|
|
987
|
+
const admins = await client.admins.list();
|
|
988
|
+
|
|
989
|
+
for (const admin of admins.admins) {
|
|
990
|
+
console.log(admin.name, admin.email);
|
|
991
|
+
}
|
|
992
|
+
```
|
|
993
|
+
|
|
994
|
+
**Retrieve an admin:**
|
|
995
|
+
|
|
996
|
+
```javascript
|
|
997
|
+
const admin = await client.admins.find({
|
|
998
|
+
id: '987654',
|
|
999
|
+
});
|
|
1000
|
+
|
|
1001
|
+
console.log(admin.name, admin.away_mode_enabled);
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
**Retrieve current admin:**
|
|
1005
|
+
|
|
1006
|
+
```javascript
|
|
1007
|
+
const me = await client.admins.me();
|
|
1008
|
+
|
|
1009
|
+
console.log(me.name, me.email);
|
|
1010
|
+
```
|
|
1011
|
+
|
|
1012
|
+
**Set away mode:**
|
|
1013
|
+
|
|
1014
|
+
```javascript
|
|
1015
|
+
const updated = await client.admins.setAwayMode({
|
|
1016
|
+
admin_id: '987654',
|
|
1017
|
+
away_mode_enabled: true,
|
|
1018
|
+
away_mode_reassign: true,
|
|
1019
|
+
});
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
**List teams:**
|
|
1023
|
+
|
|
1024
|
+
```javascript
|
|
1025
|
+
const teams = await client.teams.list();
|
|
1026
|
+
|
|
1027
|
+
for (const team of teams.teams) {
|
|
1028
|
+
console.log(team.name, team.id);
|
|
1029
|
+
}
|
|
1030
|
+
```
|
|
1031
|
+
|
|
1032
|
+
**Retrieve a team:**
|
|
1033
|
+
|
|
1034
|
+
```javascript
|
|
1035
|
+
const team = await client.teams.find({
|
|
1036
|
+
id: '333444',
|
|
1037
|
+
});
|
|
1038
|
+
```
|
|
1039
|
+
|
|
1040
|
+
### Articles
|
|
1041
|
+
|
|
1042
|
+
Manage help center articles.
|
|
1043
|
+
|
|
1044
|
+
**Create an article:**
|
|
1045
|
+
|
|
1046
|
+
```javascript
|
|
1047
|
+
const article = await client.articles.create({
|
|
1048
|
+
title: 'Getting Started Guide',
|
|
1049
|
+
description: 'Learn how to use our platform',
|
|
1050
|
+
body: '<h1>Welcome</h1><p>This guide will help you get started...</p>',
|
|
1051
|
+
author_id: 987654,
|
|
1052
|
+
state: 'published',
|
|
1053
|
+
});
|
|
1054
|
+
```
|
|
1055
|
+
|
|
1056
|
+
**Retrieve an article:**
|
|
1057
|
+
|
|
1058
|
+
```javascript
|
|
1059
|
+
const article = await client.articles.find({
|
|
1060
|
+
id: 'article_555',
|
|
1061
|
+
});
|
|
1062
|
+
```
|
|
1063
|
+
|
|
1064
|
+
**Update an article:**
|
|
1065
|
+
|
|
1066
|
+
```javascript
|
|
1067
|
+
const updated = await client.articles.update({
|
|
1068
|
+
id: 'article_555',
|
|
1069
|
+
title: 'Getting Started Guide (Updated)',
|
|
1070
|
+
body: '<h1>Welcome</h1><p>This updated guide...</p>',
|
|
1071
|
+
});
|
|
1072
|
+
```
|
|
1073
|
+
|
|
1074
|
+
**List articles:**
|
|
1075
|
+
|
|
1076
|
+
```javascript
|
|
1077
|
+
const response = await client.articles.list({
|
|
1078
|
+
per_page: 50,
|
|
1079
|
+
});
|
|
1080
|
+
|
|
1081
|
+
for await (const article of response) {
|
|
1082
|
+
console.log(article.title, article.state);
|
|
1083
|
+
}
|
|
1084
|
+
```
|
|
1085
|
+
|
|
1086
|
+
**Delete an article:**
|
|
1087
|
+
|
|
1088
|
+
```javascript
|
|
1089
|
+
await client.articles.delete({
|
|
1090
|
+
id: 'article_555',
|
|
1091
|
+
});
|
|
1092
|
+
```
|
|
1093
|
+
|
|
1094
|
+
### Subscription Types
|
|
1095
|
+
|
|
1096
|
+
Manage subscription preferences for contacts.
|
|
1097
|
+
|
|
1098
|
+
**List subscription types:**
|
|
1099
|
+
|
|
1100
|
+
```javascript
|
|
1101
|
+
const types = await client.subscriptionTypes.list();
|
|
1102
|
+
|
|
1103
|
+
for (const type of types.data) {
|
|
1104
|
+
console.log(type.id, type.content_type);
|
|
1105
|
+
}
|
|
1106
|
+
```
|
|
1107
|
+
|
|
1108
|
+
**Subscribe contact:**
|
|
1109
|
+
|
|
1110
|
+
```javascript
|
|
1111
|
+
await client.contacts.subscribe({
|
|
1112
|
+
id: '65f9a5e4f5e5b40001234567',
|
|
1113
|
+
subscription_type_id: 'sub_123',
|
|
1114
|
+
});
|
|
1115
|
+
```
|
|
1116
|
+
|
|
1117
|
+
**Unsubscribe contact:**
|
|
1118
|
+
|
|
1119
|
+
```javascript
|
|
1120
|
+
await client.contacts.unsubscribe({
|
|
1121
|
+
id: '65f9a5e4f5e5b40001234567',
|
|
1122
|
+
subscription_type_id: 'sub_123',
|
|
1123
|
+
});
|
|
1124
|
+
```
|
|
1125
|
+
|
|
1126
|
+
## Error Handling
|
|
1127
|
+
|
|
1128
|
+
**Basic error handling:**
|
|
1129
|
+
|
|
1130
|
+
```javascript
|
|
1131
|
+
import { IntercomError } from 'intercom-client';
|
|
1132
|
+
|
|
1133
|
+
try {
|
|
1134
|
+
const contact = await client.contacts.find({ id: 'invalid_id' });
|
|
1135
|
+
} catch (err) {
|
|
1136
|
+
if (err instanceof IntercomError) {
|
|
1137
|
+
console.error('Status:', err.statusCode);
|
|
1138
|
+
console.error('Message:', err.message);
|
|
1139
|
+
console.error('Body:', err.body);
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
```
|
|
1143
|
+
|
|
1144
|
+
**Handle specific error codes:**
|
|
1145
|
+
|
|
1146
|
+
```javascript
|
|
1147
|
+
try {
|
|
1148
|
+
await client.contacts.create({ email: '[email protected]' });
|
|
1149
|
+
} catch (err) {
|
|
1150
|
+
if (err instanceof IntercomError) {
|
|
1151
|
+
switch (err.statusCode) {
|
|
1152
|
+
case 400:
|
|
1153
|
+
console.error('Bad request:', err.message);
|
|
1154
|
+
break;
|
|
1155
|
+
case 401:
|
|
1156
|
+
console.error('Unauthorized - check your token');
|
|
1157
|
+
break;
|
|
1158
|
+
case 404:
|
|
1159
|
+
console.error('Resource not found');
|
|
1160
|
+
break;
|
|
1161
|
+
case 429:
|
|
1162
|
+
console.error('Rate limit exceeded');
|
|
1163
|
+
break;
|
|
1164
|
+
default:
|
|
1165
|
+
console.error('Error:', err.message);
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
```
|
|
1170
|
+
|
|
1171
|
+
**Retry on rate limit:**
|
|
1172
|
+
|
|
1173
|
+
```javascript
|
|
1174
|
+
async function createContactWithRetry(data, maxRetries = 3) {
|
|
1175
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
1176
|
+
try {
|
|
1177
|
+
return await client.contacts.create(data);
|
|
1178
|
+
} catch (err) {
|
|
1179
|
+
if (err instanceof IntercomError && err.statusCode === 429) {
|
|
1180
|
+
if (attempt < maxRetries) {
|
|
1181
|
+
const delay = Math.pow(2, attempt) * 1000;
|
|
1182
|
+
console.log(`Rate limited, retrying in ${delay}ms...`);
|
|
1183
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
1184
|
+
continue;
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
throw err;
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
```
|
|
1192
|
+
|
|
1193
|
+
## Pagination
|
|
1194
|
+
|
|
1195
|
+
**Auto-pagination with for-await:**
|
|
1196
|
+
|
|
1197
|
+
```javascript
|
|
1198
|
+
const response = await client.contacts.list();
|
|
1199
|
+
|
|
1200
|
+
for await (const contact of response) {
|
|
1201
|
+
console.log(contact.email);
|
|
1202
|
+
// Automatically fetches next page when needed
|
|
1203
|
+
}
|
|
1204
|
+
```
|
|
1205
|
+
|
|
1206
|
+
**Manual pagination:**
|
|
1207
|
+
|
|
1208
|
+
```javascript
|
|
1209
|
+
let hasMore = true;
|
|
1210
|
+
let startingAfter = null;
|
|
1211
|
+
|
|
1212
|
+
while (hasMore) {
|
|
1213
|
+
const response = await client.contacts.list({
|
|
1214
|
+
per_page: 50,
|
|
1215
|
+
starting_after: startingAfter,
|
|
1216
|
+
});
|
|
1217
|
+
|
|
1218
|
+
for (const contact of response.data) {
|
|
1219
|
+
console.log(contact.email);
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
hasMore = response.pages && response.pages.next;
|
|
1223
|
+
startingAfter = response.pages?.next?.starting_after;
|
|
1224
|
+
}
|
|
1225
|
+
```
|
|
1226
|
+
|
|
1227
|
+
**Get all pages at once:**
|
|
1228
|
+
|
|
1229
|
+
```javascript
|
|
1230
|
+
const allContacts = [];
|
|
1231
|
+
const response = await client.contacts.list();
|
|
1232
|
+
|
|
1233
|
+
for await (const contact of response) {
|
|
1234
|
+
allContacts.push(contact);
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
console.log(`Total contacts: ${allContacts.length}`);
|
|
1238
|
+
```
|
|
1239
|
+
|
|
1240
|
+
## Advanced Features
|
|
1241
|
+
|
|
1242
|
+
**Custom headers:**
|
|
1243
|
+
|
|
1244
|
+
```javascript
|
|
1245
|
+
const contact = await client.contacts.create(
|
|
1246
|
+
{
|
|
1247
|
+
email: '[email protected]',
|
|
1248
|
+
name: 'Test User',
|
|
1249
|
+
},
|
|
1250
|
+
{
|
|
1251
|
+
headers: {
|
|
1252
|
+
'X-Custom-Header': 'custom-value',
|
|
1253
|
+
},
|
|
1254
|
+
}
|
|
1255
|
+
);
|
|
1256
|
+
```
|
|
1257
|
+
|
|
1258
|
+
**Request timeout:**
|
|
1259
|
+
|
|
1260
|
+
```javascript
|
|
1261
|
+
const contact = await client.contacts.find(
|
|
1262
|
+
{ id: '65f9a5e4f5e5b40001234567' },
|
|
1263
|
+
{
|
|
1264
|
+
timeoutInSeconds: 30,
|
|
1265
|
+
}
|
|
1266
|
+
);
|
|
1267
|
+
```
|
|
1268
|
+
|
|
1269
|
+
**Abort requests:**
|
|
1270
|
+
|
|
1271
|
+
```javascript
|
|
1272
|
+
const controller = new AbortController();
|
|
1273
|
+
|
|
1274
|
+
// Cancel after 5 seconds
|
|
1275
|
+
setTimeout(() => controller.abort(), 5000);
|
|
1276
|
+
|
|
1277
|
+
try {
|
|
1278
|
+
const contact = await client.contacts.create(
|
|
1279
|
+
{
|
|
1280
|
+
email: '[email protected]',
|
|
1281
|
+
},
|
|
1282
|
+
{
|
|
1283
|
+
abortSignal: controller.signal,
|
|
1284
|
+
}
|
|
1285
|
+
);
|
|
1286
|
+
} catch (err) {
|
|
1287
|
+
if (err.name === 'AbortError') {
|
|
1288
|
+
console.log('Request was aborted');
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
```
|
|
1292
|
+
|
|
1293
|
+
**Access raw response:**
|
|
1294
|
+
|
|
1295
|
+
```javascript
|
|
1296
|
+
const response = await client.contacts
|
|
1297
|
+
.withRawResponse()
|
|
1298
|
+
.find({ id: '65f9a5e4f5e5b40001234567' });
|
|
1299
|
+
|
|
1300
|
+
console.log('Status:', response.statusCode);
|
|
1301
|
+
console.log('Headers:', response.headers);
|
|
1302
|
+
console.log('Body:', response.body);
|
|
1303
|
+
```
|
|
1304
|
+
|
|
1305
|
+
**Disable automatic retries:**
|
|
1306
|
+
|
|
1307
|
+
```javascript
|
|
1308
|
+
const client = new IntercomClient({
|
|
1309
|
+
token: process.env.INTERCOM_ACCESS_TOKEN,
|
|
1310
|
+
maxRetries: 0, // Disable retries
|
|
1311
|
+
});
|
|
1312
|
+
```
|
|
1313
|
+
|
|
1314
|
+
**Custom retry configuration:**
|
|
1315
|
+
|
|
1316
|
+
```javascript
|
|
1317
|
+
const client = new IntercomClient({
|
|
1318
|
+
token: process.env.INTERCOM_ACCESS_TOKEN,
|
|
1319
|
+
maxRetries: 5,
|
|
1320
|
+
timeoutInSeconds: 90,
|
|
1321
|
+
});
|
|
1322
|
+
```
|
|
1323
|
+
|
|
1324
|
+
## Type Definitions
|
|
1325
|
+
|
|
1326
|
+
**Using request types:**
|
|
1327
|
+
|
|
1328
|
+
```typescript
|
|
1329
|
+
import { Intercom } from 'intercom-client';
|
|
1330
|
+
|
|
1331
|
+
const createRequest: Intercom.ContactCreateRequest = {
|
|
1332
|
+
email: '[email protected]',
|
|
1333
|
+
name: 'Jane Doe',
|
|
1334
|
+
role: 'user',
|
|
1335
|
+
custom_attributes: {
|
|
1336
|
+
plan: 'premium',
|
|
1337
|
+
},
|
|
1338
|
+
};
|
|
1339
|
+
|
|
1340
|
+
const contact = await client.contacts.create(createRequest);
|
|
1341
|
+
```
|
|
1342
|
+
|
|
1343
|
+
**Using response types:**
|
|
1344
|
+
|
|
1345
|
+
```typescript
|
|
1346
|
+
import { Intercom } from 'intercom-client';
|
|
1347
|
+
|
|
1348
|
+
const contact: Intercom.Contact = await client.contacts.find({
|
|
1349
|
+
id: '65f9a5e4f5e5b40001234567',
|
|
1350
|
+
});
|
|
1351
|
+
|
|
1352
|
+
console.log(contact.email, contact.created_at);
|
|
1353
|
+
```
|
|
1354
|
+
|
|
1355
|
+
**Conversation types:**
|
|
1356
|
+
|
|
1357
|
+
```typescript
|
|
1358
|
+
import { Intercom } from 'intercom-client';
|
|
1359
|
+
|
|
1360
|
+
const conversation: Intercom.Conversation = await client.conversations.find({
|
|
1361
|
+
id: '123456',
|
|
1362
|
+
});
|
|
1363
|
+
|
|
1364
|
+
const state: Intercom.ConversationState = conversation.state;
|
|
1365
|
+
// 'open' | 'closed' | 'snoozed'
|
|
1366
|
+
```
|
|
1367
|
+
|
|
1368
|
+
**Event metadata typing:**
|
|
1369
|
+
|
|
1370
|
+
```typescript
|
|
1371
|
+
interface PurchaseMetadata {
|
|
1372
|
+
item_name: string;
|
|
1373
|
+
item_price: number;
|
|
1374
|
+
currency: string;
|
|
1375
|
+
quantity: number;
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
await client.events.create({
|
|
1379
|
+
event_name: 'purchased_item',
|
|
1380
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
1381
|
+
user_id: '65f9a5e4f5e5b40001234567',
|
|
1382
|
+
metadata: {
|
|
1383
|
+
item_name: 'Premium Plan',
|
|
1384
|
+
item_price: 99.99,
|
|
1385
|
+
currency: 'USD',
|
|
1386
|
+
quantity: 1,
|
|
1387
|
+
} as PurchaseMetadata,
|
|
1388
|
+
});
|
|
1389
|
+
```
|
|
1390
|
+
|
|
1391
|
+
## Webhooks
|
|
1392
|
+
|
|
1393
|
+
**Verify webhook signature:**
|
|
1394
|
+
|
|
1395
|
+
```javascript
|
|
1396
|
+
import crypto from 'crypto';
|
|
1397
|
+
|
|
1398
|
+
function verifyWebhook(body, signature, secret) {
|
|
1399
|
+
const hash = crypto
|
|
1400
|
+
.createHmac('sha256', secret)
|
|
1401
|
+
.update(body)
|
|
1402
|
+
.digest('hex');
|
|
1403
|
+
|
|
1404
|
+
return signature === hash;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
// Express example
|
|
1408
|
+
app.post('/webhooks/intercom', (req, res) => {
|
|
1409
|
+
const signature = req.headers['x-hub-signature'];
|
|
1410
|
+
const isValid = verifyWebhook(
|
|
1411
|
+
JSON.stringify(req.body),
|
|
1412
|
+
signature,
|
|
1413
|
+
process.env.INTERCOM_WEBHOOK_SECRET
|
|
1414
|
+
);
|
|
1415
|
+
|
|
1416
|
+
if (!isValid) {
|
|
1417
|
+
return res.status(401).send('Invalid signature');
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
const event = req.body;
|
|
1421
|
+
console.log('Webhook event:', event.topic);
|
|
1422
|
+
|
|
1423
|
+
res.sendStatus(200);
|
|
1424
|
+
});
|
|
1425
|
+
```
|
|
1426
|
+
|
|
1427
|
+
**Handle webhook events:**
|
|
1428
|
+
|
|
1429
|
+
```javascript
|
|
1430
|
+
app.post('/webhooks/intercom', (req, res) => {
|
|
1431
|
+
const { topic, data } = req.body;
|
|
1432
|
+
|
|
1433
|
+
switch (topic) {
|
|
1434
|
+
case 'contact.created':
|
|
1435
|
+
console.log('New contact:', data.item.email);
|
|
1436
|
+
break;
|
|
1437
|
+
|
|
1438
|
+
case 'conversation.user.created':
|
|
1439
|
+
console.log('New conversation:', data.item.id);
|
|
1440
|
+
break;
|
|
1441
|
+
|
|
1442
|
+
case 'conversation.admin.replied':
|
|
1443
|
+
console.log('Admin replied to:', data.item.id);
|
|
1444
|
+
break;
|
|
1445
|
+
|
|
1446
|
+
case 'user.tag.created':
|
|
1447
|
+
console.log('User tagged:', data.item.user.email);
|
|
1448
|
+
break;
|
|
1449
|
+
|
|
1450
|
+
default:
|
|
1451
|
+
console.log('Unknown event:', topic);
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
res.sendStatus(200);
|
|
1455
|
+
});
|
|
1456
|
+
```
|
|
1457
|
+
|
|
1458
|
+
## Rate Limiting
|
|
1459
|
+
|
|
1460
|
+
Intercom enforces rate limits on API requests. The SDK handles retries automatically.
|
|
1461
|
+
|
|
1462
|
+
**Default retry behavior:**
|
|
1463
|
+
|
|
1464
|
+
```javascript
|
|
1465
|
+
// SDK automatically retries on 429 (rate limit) responses
|
|
1466
|
+
// with exponential backoff (2 retries by default)
|
|
1467
|
+
|
|
1468
|
+
const client = new IntercomClient({
|
|
1469
|
+
token: process.env.INTERCOM_ACCESS_TOKEN,
|
|
1470
|
+
maxRetries: 2, // Default
|
|
1471
|
+
});
|
|
1472
|
+
```
|
|
1473
|
+
|
|
1474
|
+
**Rate limit headers:**
|
|
1475
|
+
|
|
1476
|
+
```javascript
|
|
1477
|
+
const response = await client.contacts
|
|
1478
|
+
.withRawResponse()
|
|
1479
|
+
.list();
|
|
1480
|
+
|
|
1481
|
+
console.log('Rate limit:', response.headers['x-ratelimit-limit']);
|
|
1482
|
+
console.log('Remaining:', response.headers['x-ratelimit-remaining']);
|
|
1483
|
+
console.log('Reset:', response.headers['x-ratelimit-reset']);
|
|
1484
|
+
```
|
|
1485
|
+
|
|
1486
|
+
**Handle rate limits manually:**
|
|
1487
|
+
|
|
1488
|
+
```javascript
|
|
1489
|
+
async function makeRequestWithBackoff(requestFn, maxRetries = 5) {
|
|
1490
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
1491
|
+
try {
|
|
1492
|
+
return await requestFn();
|
|
1493
|
+
} catch (err) {
|
|
1494
|
+
if (err instanceof IntercomError && err.statusCode === 429) {
|
|
1495
|
+
const resetHeader = err.headers?.['x-ratelimit-reset'];
|
|
1496
|
+
const resetTime = resetHeader ? parseInt(resetHeader) * 1000 : null;
|
|
1497
|
+
|
|
1498
|
+
if (resetTime && i < maxRetries - 1) {
|
|
1499
|
+
const waitTime = Math.max(resetTime - Date.now(), 0);
|
|
1500
|
+
console.log(`Rate limited. Waiting ${waitTime}ms...`);
|
|
1501
|
+
await new Promise(resolve => setTimeout(resolve, waitTime));
|
|
1502
|
+
continue;
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
throw err;
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
// Usage
|
|
1511
|
+
await makeRequestWithBackoff(() =>
|
|
1512
|
+
client.contacts.create({ email: '[email protected]' })
|
|
1513
|
+
);
|
|
1514
|
+
```
|
|
1515
|
+
|
|
1516
|
+
## Bulk Operations
|
|
1517
|
+
|
|
1518
|
+
**Bulk create contacts:**
|
|
1519
|
+
|
|
1520
|
+
```javascript
|
|
1521
|
+
const contacts = [
|
|
1522
|
+
{ email: '[email protected]', name: 'User 1' },
|
|
1523
|
+
{ email: '[email protected]', name: 'User 2' },
|
|
1524
|
+
{ email: '[email protected]', name: 'User 3' },
|
|
1525
|
+
];
|
|
1526
|
+
|
|
1527
|
+
const results = await Promise.all(
|
|
1528
|
+
contacts.map(data => client.contacts.create(data))
|
|
1529
|
+
);
|
|
1530
|
+
|
|
1531
|
+
console.log(`Created ${results.length} contacts`);
|
|
1532
|
+
```
|
|
1533
|
+
|
|
1534
|
+
**Bulk update with error handling:**
|
|
1535
|
+
|
|
1536
|
+
```javascript
|
|
1537
|
+
const updates = [
|
|
1538
|
+
{ id: '1', name: 'Updated 1' },
|
|
1539
|
+
{ id: '2', name: 'Updated 2' },
|
|
1540
|
+
{ id: '3', name: 'Updated 3' },
|
|
1541
|
+
];
|
|
1542
|
+
|
|
1543
|
+
const results = await Promise.allSettled(
|
|
1544
|
+
updates.map(data => client.contacts.update(data))
|
|
1545
|
+
);
|
|
1546
|
+
|
|
1547
|
+
const succeeded = results.filter(r => r.status === 'fulfilled').length;
|
|
1548
|
+
const failed = results.filter(r => r.status === 'rejected').length;
|
|
1549
|
+
|
|
1550
|
+
console.log(`Success: ${succeeded}, Failed: ${failed}`);
|
|
1551
|
+
```
|
|
1552
|
+
|
|
1553
|
+
**Rate-limited bulk operations:**
|
|
1554
|
+
|
|
1555
|
+
```javascript
|
|
1556
|
+
async function bulkOperationWithRateLimit(items, operation, requestsPerSecond = 5) {
|
|
1557
|
+
const results = [];
|
|
1558
|
+
const delay = 1000 / requestsPerSecond;
|
|
1559
|
+
|
|
1560
|
+
for (const item of items) {
|
|
1561
|
+
try {
|
|
1562
|
+
const result = await operation(item);
|
|
1563
|
+
results.push({ success: true, data: result });
|
|
1564
|
+
} catch (err) {
|
|
1565
|
+
results.push({ success: false, error: err });
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
return results;
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
// Usage
|
|
1575
|
+
const contactData = [
|
|
1576
|
+
{ email: '[email protected]', name: 'User 1' },
|
|
1577
|
+
{ email: '[email protected]', name: 'User 2' },
|
|
1578
|
+
// ... more contacts
|
|
1579
|
+
];
|
|
1580
|
+
|
|
1581
|
+
const results = await bulkOperationWithRateLimit(
|
|
1582
|
+
contactData,
|
|
1583
|
+
data => client.contacts.create(data),
|
|
1584
|
+
5 // 5 requests per second
|
|
1585
|
+
);
|
|
1586
|
+
```
|
|
1587
|
+
|
|
1588
|
+
## Environment-Specific Configuration
|
|
1589
|
+
|
|
1590
|
+
**Development:**
|
|
1591
|
+
|
|
1592
|
+
```javascript
|
|
1593
|
+
const client = new IntercomClient({
|
|
1594
|
+
token: process.env.INTERCOM_ACCESS_TOKEN,
|
|
1595
|
+
timeoutInSeconds: 30,
|
|
1596
|
+
maxRetries: 1,
|
|
1597
|
+
});
|
|
1598
|
+
```
|
|
1599
|
+
|
|
1600
|
+
**Production:**
|
|
1601
|
+
|
|
1602
|
+
```javascript
|
|
1603
|
+
const client = new IntercomClient({
|
|
1604
|
+
token: process.env.INTERCOM_ACCESS_TOKEN,
|
|
1605
|
+
timeoutInSeconds: 120,
|
|
1606
|
+
maxRetries: 3,
|
|
1607
|
+
});
|
|
1608
|
+
```
|
|
1609
|
+
|
|
1610
|
+
**Testing with mock:**
|
|
1611
|
+
|
|
1612
|
+
```javascript
|
|
1613
|
+
// For testing, you can inject a custom httpx client
|
|
1614
|
+
import { IntercomClient } from 'intercom-client';
|
|
1615
|
+
|
|
1616
|
+
const mockClient = new IntercomClient({
|
|
1617
|
+
token: 'test_token',
|
|
1618
|
+
// Use mock HTTP client for tests
|
|
1619
|
+
});
|
|
1620
|
+
```
|
|
1621
|
+
|
|
1622
|
+
## Complete Examples
|
|
1623
|
+
|
|
1624
|
+
**User onboarding workflow:**
|
|
1625
|
+
|
|
1626
|
+
```javascript
|
|
1627
|
+
async function onboardUser(email, name, plan) {
|
|
1628
|
+
try {
|
|
1629
|
+
// Create contact
|
|
1630
|
+
const contact = await client.contacts.create({
|
|
1631
|
+
email,
|
|
1632
|
+
name,
|
|
1633
|
+
role: 'user',
|
|
1634
|
+
custom_attributes: {
|
|
1635
|
+
plan,
|
|
1636
|
+
signup_date: new Date().toISOString(),
|
|
1637
|
+
},
|
|
1638
|
+
});
|
|
1639
|
+
|
|
1640
|
+
// Track signup event
|
|
1641
|
+
await client.events.create({
|
|
1642
|
+
event_name: 'signed_up',
|
|
1643
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
1644
|
+
user_id: contact.id,
|
|
1645
|
+
metadata: {
|
|
1646
|
+
plan,
|
|
1647
|
+
source: 'web',
|
|
1648
|
+
},
|
|
1649
|
+
});
|
|
1650
|
+
|
|
1651
|
+
// Tag as new user
|
|
1652
|
+
const newUserTag = await client.tags.create({
|
|
1653
|
+
name: 'New User',
|
|
1654
|
+
});
|
|
1655
|
+
|
|
1656
|
+
await client.contacts.tag({
|
|
1657
|
+
contactId: contact.id,
|
|
1658
|
+
id: newUserTag.id,
|
|
1659
|
+
});
|
|
1660
|
+
|
|
1661
|
+
// Send welcome message
|
|
1662
|
+
await client.messages.create({
|
|
1663
|
+
message_type: 'email',
|
|
1664
|
+
from: {
|
|
1665
|
+
type: 'admin',
|
|
1666
|
+
id: process.env.ADMIN_ID,
|
|
1667
|
+
},
|
|
1668
|
+
to: {
|
|
1669
|
+
type: 'user',
|
|
1670
|
+
id: contact.id,
|
|
1671
|
+
},
|
|
1672
|
+
subject: 'Welcome to our platform!',
|
|
1673
|
+
body: `Hi ${name}, thanks for signing up!`,
|
|
1674
|
+
});
|
|
1675
|
+
|
|
1676
|
+
console.log('User onboarded successfully:', contact.id);
|
|
1677
|
+
return contact;
|
|
1678
|
+
} catch (err) {
|
|
1679
|
+
console.error('Onboarding failed:', err);
|
|
1680
|
+
throw err;
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
```
|
|
1684
|
+
|
|
1685
|
+
**Customer support workflow:**
|
|
1686
|
+
|
|
1687
|
+
```javascript
|
|
1688
|
+
async function handleSupportRequest(userId, subject, message) {
|
|
1689
|
+
try {
|
|
1690
|
+
// Create conversation
|
|
1691
|
+
const conversation = await client.conversations.create({
|
|
1692
|
+
from: {
|
|
1693
|
+
type: 'user',
|
|
1694
|
+
id: userId,
|
|
1695
|
+
},
|
|
1696
|
+
body: message,
|
|
1697
|
+
});
|
|
1698
|
+
|
|
1699
|
+
// Assign to team
|
|
1700
|
+
await client.conversations.assign({
|
|
1701
|
+
id: conversation.id,
|
|
1702
|
+
type: 'admin',
|
|
1703
|
+
admin_id: process.env.ADMIN_ID,
|
|
1704
|
+
assignee_id: process.env.SUPPORT_TEAM_ID,
|
|
1705
|
+
assignment_type: 'team',
|
|
1706
|
+
});
|
|
1707
|
+
|
|
1708
|
+
// Add priority tag if urgent
|
|
1709
|
+
if (subject.toLowerCase().includes('urgent')) {
|
|
1710
|
+
const urgentTag = await client.tags.create({
|
|
1711
|
+
name: 'Urgent',
|
|
1712
|
+
});
|
|
1713
|
+
|
|
1714
|
+
await client.conversations.attachTag({
|
|
1715
|
+
conversationId: conversation.id,
|
|
1716
|
+
id: urgentTag.id,
|
|
1717
|
+
adminId: process.env.ADMIN_ID,
|
|
1718
|
+
});
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
// Track support event
|
|
1722
|
+
await client.events.create({
|
|
1723
|
+
event_name: 'support_request_created',
|
|
1724
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
1725
|
+
user_id: userId,
|
|
1726
|
+
metadata: {
|
|
1727
|
+
conversation_id: conversation.id,
|
|
1728
|
+
subject,
|
|
1729
|
+
urgent: subject.toLowerCase().includes('urgent'),
|
|
1730
|
+
},
|
|
1731
|
+
});
|
|
1732
|
+
|
|
1733
|
+
return conversation;
|
|
1734
|
+
} catch (err) {
|
|
1735
|
+
console.error('Support request failed:', err);
|
|
1736
|
+
throw err;
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
```
|
|
1740
|
+
|
|
1741
|
+
**Company and contact management:**
|
|
1742
|
+
|
|
1743
|
+
```javascript
|
|
1744
|
+
async function addContactToCompany(contactEmail, companyId) {
|
|
1745
|
+
try {
|
|
1746
|
+
// Find or create contact
|
|
1747
|
+
let contact;
|
|
1748
|
+
try {
|
|
1749
|
+
const searchResults = await client.contacts.search({
|
|
1750
|
+
query: {
|
|
1751
|
+
field: 'email',
|
|
1752
|
+
operator: '=',
|
|
1753
|
+
value: contactEmail,
|
|
1754
|
+
},
|
|
1755
|
+
});
|
|
1756
|
+
contact = searchResults.data[0];
|
|
1757
|
+
} catch (err) {
|
|
1758
|
+
contact = await client.contacts.create({
|
|
1759
|
+
email: contactEmail,
|
|
1760
|
+
role: 'user',
|
|
1761
|
+
});
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
// Attach to company
|
|
1765
|
+
await client.contacts.update({
|
|
1766
|
+
id: contact.id,
|
|
1767
|
+
companies: [
|
|
1768
|
+
{
|
|
1769
|
+
company_id: companyId,
|
|
1770
|
+
},
|
|
1771
|
+
],
|
|
1772
|
+
});
|
|
1773
|
+
|
|
1774
|
+
// Get company details
|
|
1775
|
+
const company = await client.companies.find({
|
|
1776
|
+
company_id: companyId,
|
|
1777
|
+
});
|
|
1778
|
+
|
|
1779
|
+
console.log(`Added ${contactEmail} to ${company.name}`);
|
|
1780
|
+
|
|
1781
|
+
return { contact, company };
|
|
1782
|
+
} catch (err) {
|
|
1783
|
+
console.error('Failed to add contact to company:', err);
|
|
1784
|
+
throw err;
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
```
|
|
1788
|
+
|
|
1789
|
+
**Analytics and reporting:**
|
|
1790
|
+
|
|
1791
|
+
```javascript
|
|
1792
|
+
async function generateUserReport(userId) {
|
|
1793
|
+
try {
|
|
1794
|
+
// Get user details
|
|
1795
|
+
const contact = await client.contacts.find({ id: userId });
|
|
1796
|
+
|
|
1797
|
+
// Get user events
|
|
1798
|
+
const events = await client.events.list({
|
|
1799
|
+
type: 'user',
|
|
1800
|
+
user_id: userId,
|
|
1801
|
+
});
|
|
1802
|
+
|
|
1803
|
+
// Get conversations
|
|
1804
|
+
const conversations = await client.conversations.search({
|
|
1805
|
+
query: {
|
|
1806
|
+
field: 'contact_ids',
|
|
1807
|
+
operator: '=',
|
|
1808
|
+
value: userId,
|
|
1809
|
+
},
|
|
1810
|
+
});
|
|
1811
|
+
|
|
1812
|
+
// Get notes
|
|
1813
|
+
const notes = await client.contacts.listNotes({ id: userId });
|
|
1814
|
+
|
|
1815
|
+
const report = {
|
|
1816
|
+
contact: {
|
|
1817
|
+
email: contact.email,
|
|
1818
|
+
name: contact.name,
|
|
1819
|
+
created_at: contact.created_at,
|
|
1820
|
+
custom_attributes: contact.custom_attributes,
|
|
1821
|
+
},
|
|
1822
|
+
events: events.events.map(e => ({
|
|
1823
|
+
name: e.event_name,
|
|
1824
|
+
created_at: e.created_at,
|
|
1825
|
+
metadata: e.metadata,
|
|
1826
|
+
})),
|
|
1827
|
+
conversations: {
|
|
1828
|
+
total: conversations.total_count,
|
|
1829
|
+
open: conversations.conversations.filter(c => c.state === 'open').length,
|
|
1830
|
+
closed: conversations.conversations.filter(c => c.state === 'closed').length,
|
|
1831
|
+
},
|
|
1832
|
+
notes: notes.data.map(n => ({
|
|
1833
|
+
body: n.body,
|
|
1834
|
+
created_at: n.created_at,
|
|
1835
|
+
})),
|
|
1836
|
+
};
|
|
1837
|
+
|
|
1838
|
+
return report;
|
|
1839
|
+
} catch (err) {
|
|
1840
|
+
console.error('Report generation failed:', err);
|
|
1841
|
+
throw err;
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
```
|