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.
Files changed (139) hide show
  1. package/README.md +55 -0
  2. package/bin/chub-mcp +2 -0
  3. package/dist/airtable/docs/database/javascript/DOC.md +1437 -0
  4. package/dist/airtable/docs/database/python/DOC.md +1735 -0
  5. package/dist/amplitude/docs/analytics/javascript/DOC.md +1282 -0
  6. package/dist/amplitude/docs/analytics/python/DOC.md +1199 -0
  7. package/dist/anthropic/docs/claude-api/javascript/DOC.md +503 -0
  8. package/dist/anthropic/docs/claude-api/python/DOC.md +389 -0
  9. package/dist/asana/docs/tasks/DOC.md +1396 -0
  10. package/dist/assemblyai/docs/transcription/DOC.md +1043 -0
  11. package/dist/atlassian/docs/confluence/javascript/DOC.md +1347 -0
  12. package/dist/atlassian/docs/confluence/python/DOC.md +1604 -0
  13. package/dist/auth0/docs/identity/javascript/DOC.md +968 -0
  14. package/dist/auth0/docs/identity/python/DOC.md +1199 -0
  15. package/dist/aws/docs/s3/javascript/DOC.md +1773 -0
  16. package/dist/aws/docs/s3/python/DOC.md +1807 -0
  17. package/dist/binance/docs/trading/javascript/DOC.md +1315 -0
  18. package/dist/binance/docs/trading/python/DOC.md +1454 -0
  19. package/dist/braintree/docs/gateway/javascript/DOC.md +1278 -0
  20. package/dist/braintree/docs/gateway/python/DOC.md +1179 -0
  21. package/dist/chromadb/docs/embeddings-db/javascript/DOC.md +1263 -0
  22. package/dist/chromadb/docs/embeddings-db/python/DOC.md +1707 -0
  23. package/dist/clerk/docs/auth/javascript/DOC.md +1220 -0
  24. package/dist/clerk/docs/auth/python/DOC.md +274 -0
  25. package/dist/cloudflare/docs/workers/javascript/DOC.md +918 -0
  26. package/dist/cloudflare/docs/workers/python/DOC.md +994 -0
  27. package/dist/cockroachdb/docs/distributed-db/DOC.md +1500 -0
  28. package/dist/cohere/docs/llm/DOC.md +1335 -0
  29. package/dist/datadog/docs/monitoring/javascript/DOC.md +1740 -0
  30. package/dist/datadog/docs/monitoring/python/DOC.md +1815 -0
  31. package/dist/deepgram/docs/speech/javascript/DOC.md +885 -0
  32. package/dist/deepgram/docs/speech/python/DOC.md +685 -0
  33. package/dist/deepl/docs/translation/javascript/DOC.md +887 -0
  34. package/dist/deepl/docs/translation/python/DOC.md +944 -0
  35. package/dist/deepseek/docs/llm/DOC.md +1220 -0
  36. package/dist/directus/docs/headless-cms/javascript/DOC.md +1128 -0
  37. package/dist/directus/docs/headless-cms/python/DOC.md +1276 -0
  38. package/dist/discord/docs/bot/javascript/DOC.md +1090 -0
  39. package/dist/discord/docs/bot/python/DOC.md +1130 -0
  40. package/dist/elasticsearch/docs/search/DOC.md +1634 -0
  41. package/dist/elevenlabs/docs/text-to-speech/javascript/DOC.md +336 -0
  42. package/dist/elevenlabs/docs/text-to-speech/python/DOC.md +552 -0
  43. package/dist/firebase/docs/auth/DOC.md +1015 -0
  44. package/dist/gemini/docs/genai/javascript/DOC.md +691 -0
  45. package/dist/gemini/docs/genai/python/DOC.md +555 -0
  46. package/dist/github/docs/octokit/DOC.md +1560 -0
  47. package/dist/google/docs/bigquery/javascript/DOC.md +1688 -0
  48. package/dist/google/docs/bigquery/python/DOC.md +1503 -0
  49. package/dist/hubspot/docs/crm/javascript/DOC.md +1805 -0
  50. package/dist/hubspot/docs/crm/python/DOC.md +2033 -0
  51. package/dist/huggingface/docs/transformers/DOC.md +948 -0
  52. package/dist/intercom/docs/messaging/javascript/DOC.md +1844 -0
  53. package/dist/intercom/docs/messaging/python/DOC.md +1797 -0
  54. package/dist/jira/docs/issues/javascript/DOC.md +1420 -0
  55. package/dist/jira/docs/issues/python/DOC.md +1492 -0
  56. package/dist/kafka/docs/streaming/javascript/DOC.md +1671 -0
  57. package/dist/kafka/docs/streaming/python/DOC.md +1464 -0
  58. package/dist/landingai-ade/docs/api/DOC.md +620 -0
  59. package/dist/landingai-ade/docs/sdk/python/DOC.md +489 -0
  60. package/dist/landingai-ade/docs/sdk/typescript/DOC.md +542 -0
  61. package/dist/landingai-ade/skills/SKILL.md +489 -0
  62. package/dist/launchdarkly/docs/feature-flags/javascript/DOC.md +1191 -0
  63. package/dist/launchdarkly/docs/feature-flags/python/DOC.md +1671 -0
  64. package/dist/linear/docs/tracker/DOC.md +1554 -0
  65. package/dist/livekit/docs/realtime/javascript/DOC.md +303 -0
  66. package/dist/livekit/docs/realtime/python/DOC.md +163 -0
  67. package/dist/mailchimp/docs/marketing/DOC.md +1420 -0
  68. package/dist/meilisearch/docs/search/DOC.md +1241 -0
  69. package/dist/microsoft/docs/onedrive/javascript/DOC.md +1421 -0
  70. package/dist/microsoft/docs/onedrive/python/DOC.md +1549 -0
  71. package/dist/mongodb/docs/atlas/DOC.md +2041 -0
  72. package/dist/notion/docs/workspace-api/javascript/DOC.md +1435 -0
  73. package/dist/notion/docs/workspace-api/python/DOC.md +1400 -0
  74. package/dist/okta/docs/identity/javascript/DOC.md +1171 -0
  75. package/dist/okta/docs/identity/python/DOC.md +1401 -0
  76. package/dist/openai/docs/chat/javascript/DOC.md +407 -0
  77. package/dist/openai/docs/chat/python/DOC.md +568 -0
  78. package/dist/paypal/docs/checkout/DOC.md +278 -0
  79. package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
  80. package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
  81. package/dist/plaid/docs/banking/javascript/DOC.md +1163 -0
  82. package/dist/plaid/docs/banking/python/DOC.md +1203 -0
  83. package/dist/playwright-community/skills/login-flows/SKILL.md +108 -0
  84. package/dist/postmark/docs/transactional-email/DOC.md +1168 -0
  85. package/dist/prisma/docs/orm/javascript/DOC.md +1419 -0
  86. package/dist/prisma/docs/orm/python/DOC.md +1317 -0
  87. package/dist/qdrant/docs/vector-search/javascript/DOC.md +1221 -0
  88. package/dist/qdrant/docs/vector-search/python/DOC.md +1653 -0
  89. package/dist/rabbitmq/docs/message-queue/javascript/DOC.md +1193 -0
  90. package/dist/rabbitmq/docs/message-queue/python/DOC.md +1243 -0
  91. package/dist/razorpay/docs/payments/javascript/DOC.md +1219 -0
  92. package/dist/razorpay/docs/payments/python/DOC.md +1330 -0
  93. package/dist/redis/docs/key-value/javascript/DOC.md +1851 -0
  94. package/dist/redis/docs/key-value/python/DOC.md +2054 -0
  95. package/dist/registry.json +2817 -0
  96. package/dist/replicate/docs/model-hosting/DOC.md +1318 -0
  97. package/dist/resend/docs/email/DOC.md +1271 -0
  98. package/dist/salesforce/docs/crm/javascript/DOC.md +1241 -0
  99. package/dist/salesforce/docs/crm/python/DOC.md +1183 -0
  100. package/dist/search-index.json +1 -0
  101. package/dist/sendgrid/docs/email-api/javascript/DOC.md +371 -0
  102. package/dist/sendgrid/docs/email-api/python/DOC.md +656 -0
  103. package/dist/sentry/docs/error-tracking/javascript/DOC.md +1073 -0
  104. package/dist/sentry/docs/error-tracking/python/DOC.md +1309 -0
  105. package/dist/shopify/docs/storefront/DOC.md +457 -0
  106. package/dist/slack/docs/workspace/javascript/DOC.md +933 -0
  107. package/dist/slack/docs/workspace/python/DOC.md +271 -0
  108. package/dist/square/docs/payments/javascript/DOC.md +1855 -0
  109. package/dist/square/docs/payments/python/DOC.md +1728 -0
  110. package/dist/stripe/docs/api/DOC.md +1727 -0
  111. package/dist/stripe/docs/payments/DOC.md +1726 -0
  112. package/dist/stytch/docs/auth/javascript/DOC.md +1813 -0
  113. package/dist/stytch/docs/auth/python/DOC.md +1962 -0
  114. package/dist/supabase/docs/client/DOC.md +1606 -0
  115. package/dist/twilio/docs/messaging/python/DOC.md +469 -0
  116. package/dist/twilio/docs/messaging/typescript/DOC.md +946 -0
  117. package/dist/vercel/docs/platform/DOC.md +1940 -0
  118. package/dist/weaviate/docs/vector-db/javascript/DOC.md +1268 -0
  119. package/dist/weaviate/docs/vector-db/python/DOC.md +1388 -0
  120. package/dist/zendesk/docs/support/javascript/DOC.md +2150 -0
  121. package/dist/zendesk/docs/support/python/DOC.md +2297 -0
  122. package/package.json +22 -6
  123. package/skills/get-api-docs/SKILL.md +84 -0
  124. package/src/commands/annotate.js +83 -0
  125. package/src/commands/build.js +12 -1
  126. package/src/commands/feedback.js +150 -0
  127. package/src/commands/get.js +83 -42
  128. package/src/commands/search.js +7 -0
  129. package/src/index.js +43 -17
  130. package/src/lib/analytics.js +90 -0
  131. package/src/lib/annotations.js +57 -0
  132. package/src/lib/bm25.js +170 -0
  133. package/src/lib/cache.js +69 -6
  134. package/src/lib/config.js +8 -3
  135. package/src/lib/identity.js +99 -0
  136. package/src/lib/registry.js +103 -20
  137. package/src/lib/telemetry.js +86 -0
  138. package/src/mcp/server.js +177 -0
  139. package/src/mcp/tools.js +251 -0
@@ -0,0 +1,1420 @@
1
+ ---
2
+ name: marketing
3
+ description: "Mailchimp Marketing API Node.js SDK Coding Guidelines for email marketing, audience management, and campaign management"
4
+ metadata:
5
+ languages: "javascript"
6
+ versions: "3.0.80"
7
+ updated-on: "2026-03-02"
8
+ source: maintainer
9
+ tags: "mailchimp,marketing,email,campaigns,audience"
10
+ ---
11
+
12
+ # Mailchimp Marketing API Node.js SDK Coding Guidelines (JavaScript/TypeScript)
13
+
14
+ You are a Mailchimp Marketing API coding expert. Help me with writing code using the official Mailchimp Marketing Node.js library for email marketing, audience management, campaign management, and e-commerce integrations. Please follow the following guidelines when generating code.
15
+
16
+ You can find the official documentation and code samples here: https://mailchimp.com/developer/marketing/
17
+
18
+ ## Golden Rule: Use the Correct and Current SDK
19
+
20
+ Always use the official Mailchimp Marketing Node.js SDK, which is the standard library for all Mailchimp Marketing API interactions.
21
+
22
+ - **Primary Package:** `@mailchimp/mailchimp_marketing`
23
+ - **GitHub Repository:** https://github.com/mailchimp/mailchimp-marketing-node
24
+ - **Current Version:** 3.0.80
25
+
26
+ **Installation:**
27
+
28
+ ```bash
29
+ npm install @mailchimp/mailchimp_marketing
30
+ ```
31
+
32
+ **APIs and Usage:**
33
+
34
+ - **Correct:** `const mailchimp = require('@mailchimp/mailchimp_marketing')`
35
+ - **Correct:** `mailchimp.setConfig({ apiKey: '...', server: '...' })`
36
+ - **Correct:** `await mailchimp.lists.getAllLists()`
37
+ - **Correct:** `await mailchimp.campaigns.create({ ... })`
38
+ - **Incorrect:** Using legacy or unofficial packages like `mailchimp`, `mailchimp-api-v3`, or `node-mailchimp`
39
+
40
+ ## Prerequisites and Setup
41
+
42
+ Before using the Mailchimp Marketing Node.js library, ensure you have:
43
+
44
+ - Node.js installed (version 12 or higher recommended)
45
+ - A Mailchimp account with an API key
46
+ - Your Mailchimp server prefix (e.g., `us19`, `us6`)
47
+
48
+ ## Finding Your Server Prefix
49
+
50
+ The server prefix is required for API authentication. To find it:
51
+
52
+ 1. Log into your Mailchimp account
53
+ 2. Look at the URL in your browser: `https://us19.admin.mailchimp.com/`
54
+ 3. The `us19` part is your server prefix
55
+
56
+ Alternatively, your API key ends with the server prefix: if your key is `abc123-us6`, then `us6` is your server prefix.
57
+
58
+ ## API Key Configuration
59
+
60
+ **Never hardcode your API key.** Always use environment variables:
61
+
62
+ ```bash
63
+ # .env file
64
+ MAILCHIMP_API_KEY=your_api_key_here
65
+ MAILCHIMP_SERVER_PREFIX=us19
66
+ ```
67
+
68
+ ```javascript
69
+ require('dotenv').config();
70
+
71
+ const mailchimp = require('@mailchimp/mailchimp_marketing');
72
+
73
+ mailchimp.setConfig({
74
+ apiKey: process.env.MAILCHIMP_API_KEY,
75
+ server: process.env.MAILCHIMP_SERVER_PREFIX,
76
+ });
77
+ ```
78
+
79
+ ## Initialization
80
+
81
+ ### Basic Authentication (API Key)
82
+
83
+ ```javascript
84
+ const mailchimp = require('@mailchimp/mailchimp_marketing');
85
+
86
+ mailchimp.setConfig({
87
+ apiKey: process.env.MAILCHIMP_API_KEY,
88
+ server: process.env.MAILCHIMP_SERVER_PREFIX,
89
+ });
90
+
91
+ // Test connection
92
+ async function testConnection() {
93
+ try {
94
+ const response = await mailchimp.ping.get();
95
+ console.log('Connected to Mailchimp:', response);
96
+ } catch (error) {
97
+ console.error('Connection failed:', error);
98
+ }
99
+ }
100
+ ```
101
+
102
+ ### OAuth2 Authentication
103
+
104
+ For applications that access Mailchimp on behalf of other users:
105
+
106
+ ```javascript
107
+ const mailchimp = require('@mailchimp/mailchimp_marketing');
108
+
109
+ mailchimp.setConfig({
110
+ accessToken: process.env.MAILCHIMP_ACCESS_TOKEN,
111
+ server: process.env.MAILCHIMP_SERVER_PREFIX,
112
+ });
113
+ ```
114
+
115
+ ## Audiences (Lists) Management
116
+
117
+ ### Get All Lists
118
+
119
+ ```javascript
120
+ async function getAllLists() {
121
+ try {
122
+ const response = await mailchimp.lists.getAllLists();
123
+ console.log('Total lists:', response.total_items);
124
+
125
+ response.lists.forEach(list => {
126
+ console.log(`List: ${list.name} (ID: ${list.id})`);
127
+ console.log(`Members: ${list.stats.member_count}`);
128
+ });
129
+
130
+ return response.lists;
131
+ } catch (error) {
132
+ console.error('Error fetching lists:', error);
133
+ }
134
+ }
135
+ ```
136
+
137
+ ### Get Specific List Information
138
+
139
+ ```javascript
140
+ async function getListInfo(listId) {
141
+ try {
142
+ const response = await mailchimp.lists.getList(listId);
143
+ console.log('List Name:', response.name);
144
+ console.log('Total Members:', response.stats.member_count);
145
+ console.log('Unsubscribe Count:', response.stats.unsubscribe_count);
146
+ console.log('Open Rate:', response.stats.open_rate);
147
+ console.log('Click Rate:', response.stats.click_rate);
148
+ return response;
149
+ } catch (error) {
150
+ console.error('Error fetching list info:', error);
151
+ }
152
+ }
153
+ ```
154
+
155
+ ### Create a New List
156
+
157
+ ```javascript
158
+ async function createList() {
159
+ try {
160
+ const response = await mailchimp.lists.createList({
161
+ name: 'My New Newsletter',
162
+ contact: {
163
+ company: 'My Company',
164
+ address1: '123 Main St',
165
+ city: 'New York',
166
+ state: 'NY',
167
+ zip: '10001',
168
+ country: 'US',
169
+ },
170
+ permission_reminder: 'You signed up for updates on our website.',
171
+ campaign_defaults: {
172
+ from_name: 'My Company',
173
+ from_email: 'hello@mycompany.com',
174
+ subject: 'Newsletter',
175
+ language: 'en',
176
+ },
177
+ email_type_option: true,
178
+ });
179
+
180
+ console.log('List created:', response.id);
181
+ return response;
182
+ } catch (error) {
183
+ console.error('Error creating list:', error);
184
+ }
185
+ }
186
+ ```
187
+
188
+ ## List Members Management
189
+
190
+ ### Add a Member to a List
191
+
192
+ ```javascript
193
+ async function addMemberToList(listId, email, firstName, lastName) {
194
+ try {
195
+ const response = await mailchimp.lists.addListMember(listId, {
196
+ email_address: email,
197
+ status: 'subscribed',
198
+ merge_fields: {
199
+ FNAME: firstName,
200
+ LNAME: lastName,
201
+ },
202
+ });
203
+
204
+ console.log(`Added ${email} to list`);
205
+ return response;
206
+ } catch (error) {
207
+ console.error('Error adding member:', error);
208
+ if (error.status === 400) {
209
+ console.error('Member might already exist or email is invalid');
210
+ }
211
+ }
212
+ }
213
+ ```
214
+
215
+ ### Add or Update a Member
216
+
217
+ Use this to avoid errors when a member already exists:
218
+
219
+ ```javascript
220
+ const crypto = require('crypto');
221
+
222
+ async function addOrUpdateMember(listId, email, firstName, lastName, tags = []) {
223
+ try {
224
+ // Create MD5 hash of lowercase email for subscriber_hash
225
+ const subscriberHash = crypto
226
+ .createHash('md5')
227
+ .update(email.toLowerCase())
228
+ .digest('hex');
229
+
230
+ const response = await mailchimp.lists.setListMember(
231
+ listId,
232
+ subscriberHash,
233
+ {
234
+ email_address: email,
235
+ status_if_new: 'subscribed',
236
+ merge_fields: {
237
+ FNAME: firstName,
238
+ LNAME: lastName,
239
+ },
240
+ tags: tags,
241
+ }
242
+ );
243
+
244
+ console.log(`Added/Updated ${email}`);
245
+ return response;
246
+ } catch (error) {
247
+ console.error('Error adding/updating member:', error);
248
+ }
249
+ }
250
+ ```
251
+
252
+ ### Get List Members
253
+
254
+ ```javascript
255
+ async function getListMembers(listId, count = 100) {
256
+ try {
257
+ const response = await mailchimp.lists.getListMembersInfo(listId, {
258
+ count: count,
259
+ offset: 0,
260
+ });
261
+
262
+ console.log(`Total members: ${response.total_items}`);
263
+
264
+ response.members.forEach(member => {
265
+ console.log(`${member.email_address} - ${member.status}`);
266
+ });
267
+
268
+ return response.members;
269
+ } catch (error) {
270
+ console.error('Error fetching members:', error);
271
+ }
272
+ }
273
+ ```
274
+
275
+ ### Get Specific Member Information
276
+
277
+ ```javascript
278
+ const crypto = require('crypto');
279
+
280
+ async function getMemberInfo(listId, email) {
281
+ try {
282
+ const subscriberHash = crypto
283
+ .createHash('md5')
284
+ .update(email.toLowerCase())
285
+ .digest('hex');
286
+
287
+ const response = await mailchimp.lists.getListMember(
288
+ listId,
289
+ subscriberHash
290
+ );
291
+
292
+ console.log('Member:', response.email_address);
293
+ console.log('Status:', response.status);
294
+ console.log('Member since:', response.timestamp_opt);
295
+ console.log('Tags:', response.tags);
296
+
297
+ return response;
298
+ } catch (error) {
299
+ console.error('Error fetching member:', error);
300
+ }
301
+ }
302
+ ```
303
+
304
+ ### Update Member Information
305
+
306
+ ```javascript
307
+ const crypto = require('crypto');
308
+
309
+ async function updateMember(listId, email, updates) {
310
+ try {
311
+ const subscriberHash = crypto
312
+ .createHash('md5')
313
+ .update(email.toLowerCase())
314
+ .digest('hex');
315
+
316
+ const response = await mailchimp.lists.updateListMember(
317
+ listId,
318
+ subscriberHash,
319
+ updates
320
+ );
321
+
322
+ console.log('Member updated:', response.email_address);
323
+ return response;
324
+ } catch (error) {
325
+ console.error('Error updating member:', error);
326
+ }
327
+ }
328
+
329
+ // Example usage
330
+ updateMember('list123', 'user@example.com', {
331
+ merge_fields: {
332
+ FNAME: 'Jane',
333
+ LNAME: 'Smith',
334
+ },
335
+ status: 'subscribed',
336
+ });
337
+ ```
338
+
339
+ ### Delete a Member
340
+
341
+ ```javascript
342
+ const crypto = require('crypto');
343
+
344
+ async function deleteMember(listId, email) {
345
+ try {
346
+ const subscriberHash = crypto
347
+ .createHash('md5')
348
+ .update(email.toLowerCase())
349
+ .digest('hex');
350
+
351
+ await mailchimp.lists.deleteListMember(listId, subscriberHash);
352
+ console.log(`Deleted ${email} from list`);
353
+ } catch (error) {
354
+ console.error('Error deleting member:', error);
355
+ }
356
+ }
357
+ ```
358
+
359
+ ### Batch Subscribe or Unsubscribe
360
+
361
+ ```javascript
362
+ async function batchSubscribe(listId, members) {
363
+ try {
364
+ const response = await mailchimp.lists.batchListMembers(listId, {
365
+ members: members.map(member => ({
366
+ email_address: member.email,
367
+ status: 'subscribed',
368
+ merge_fields: {
369
+ FNAME: member.firstName,
370
+ LNAME: member.lastName,
371
+ },
372
+ })),
373
+ update_existing: true,
374
+ });
375
+
376
+ console.log('New members:', response.new_members.length);
377
+ console.log('Updated members:', response.updated_members.length);
378
+ console.log('Errors:', response.errors.length);
379
+
380
+ return response;
381
+ } catch (error) {
382
+ console.error('Error batch subscribing:', error);
383
+ }
384
+ }
385
+
386
+ // Example usage
387
+ batchSubscribe('list123', [
388
+ { email: 'user1@example.com', firstName: 'John', lastName: 'Doe' },
389
+ { email: 'user2@example.com', firstName: 'Jane', lastName: 'Smith' },
390
+ ]);
391
+ ```
392
+
393
+ ## Tags Management
394
+
395
+ ### Add Tags to a Member
396
+
397
+ ```javascript
398
+ const crypto = require('crypto');
399
+
400
+ async function addTagsToMember(listId, email, tags) {
401
+ try {
402
+ const subscriberHash = crypto
403
+ .createHash('md5')
404
+ .update(email.toLowerCase())
405
+ .digest('hex');
406
+
407
+ const response = await mailchimp.lists.updateListMemberTags(
408
+ listId,
409
+ subscriberHash,
410
+ {
411
+ tags: tags.map(tag => ({ name: tag, status: 'active' })),
412
+ }
413
+ );
414
+
415
+ console.log(`Added tags to ${email}`);
416
+ return response;
417
+ } catch (error) {
418
+ console.error('Error adding tags:', error);
419
+ }
420
+ }
421
+
422
+ // Example usage
423
+ addTagsToMember('list123', 'user@example.com', ['VIP', 'Newsletter']);
424
+ ```
425
+
426
+ ### Remove Tags from a Member
427
+
428
+ ```javascript
429
+ const crypto = require('crypto');
430
+
431
+ async function removeTagsFromMember(listId, email, tags) {
432
+ try {
433
+ const subscriberHash = crypto
434
+ .createHash('md5')
435
+ .update(email.toLowerCase())
436
+ .digest('hex');
437
+
438
+ const response = await mailchimp.lists.updateListMemberTags(
439
+ listId,
440
+ subscriberHash,
441
+ {
442
+ tags: tags.map(tag => ({ name: tag, status: 'inactive' })),
443
+ }
444
+ );
445
+
446
+ console.log(`Removed tags from ${email}`);
447
+ return response;
448
+ } catch (error) {
449
+ console.error('Error removing tags:', error);
450
+ }
451
+ }
452
+ ```
453
+
454
+ ## Segments Management
455
+
456
+ ### Get All Segments for a List
457
+
458
+ ```javascript
459
+ async function getSegments(listId) {
460
+ try {
461
+ const response = await mailchimp.lists.listSegments(listId);
462
+
463
+ console.log('Total segments:', response.total_items);
464
+
465
+ response.segments.forEach(segment => {
466
+ console.log(`Segment: ${segment.name} (ID: ${segment.id})`);
467
+ console.log(`Type: ${segment.type}, Members: ${segment.member_count}`);
468
+ });
469
+
470
+ return response.segments;
471
+ } catch (error) {
472
+ console.error('Error fetching segments:', error);
473
+ }
474
+ }
475
+ ```
476
+
477
+ ### Create a Segment
478
+
479
+ ```javascript
480
+ async function createSegment(listId, segmentName, conditions) {
481
+ try {
482
+ const response = await mailchimp.lists.createSegment(listId, {
483
+ name: segmentName,
484
+ static_segment: [],
485
+ });
486
+
487
+ console.log('Segment created:', response.id);
488
+ return response;
489
+ } catch (error) {
490
+ console.error('Error creating segment:', error);
491
+ }
492
+ }
493
+ ```
494
+
495
+ ### Add Members to a Segment
496
+
497
+ ```javascript
498
+ async function addMembersToSegment(listId, segmentId, emails) {
499
+ try {
500
+ const response = await mailchimp.lists.batchSegmentMembers(
501
+ listId,
502
+ segmentId,
503
+ {
504
+ members_to_add: emails,
505
+ }
506
+ );
507
+
508
+ console.log('Members added to segment:', response.members_added.length);
509
+ return response;
510
+ } catch (error) {
511
+ console.error('Error adding members to segment:', error);
512
+ }
513
+ }
514
+ ```
515
+
516
+ ## Campaigns Management
517
+
518
+ ### Get All Campaigns
519
+
520
+ ```javascript
521
+ async function getAllCampaigns(count = 100) {
522
+ try {
523
+ const response = await mailchimp.campaigns.list({
524
+ count: count,
525
+ sort_field: 'create_time',
526
+ sort_dir: 'DESC',
527
+ });
528
+
529
+ console.log('Total campaigns:', response.total_items);
530
+
531
+ response.campaigns.forEach(campaign => {
532
+ console.log(`Campaign: ${campaign.settings.title}`);
533
+ console.log(`Status: ${campaign.status}, Type: ${campaign.type}`);
534
+ });
535
+
536
+ return response.campaigns;
537
+ } catch (error) {
538
+ console.error('Error fetching campaigns:', error);
539
+ }
540
+ }
541
+ ```
542
+
543
+ ### Create a Campaign
544
+
545
+ ```javascript
546
+ async function createCampaign(listId, subject, fromName, replyTo) {
547
+ try {
548
+ const response = await mailchimp.campaigns.create({
549
+ type: 'regular',
550
+ recipients: {
551
+ list_id: listId,
552
+ },
553
+ settings: {
554
+ subject_line: subject,
555
+ title: subject,
556
+ from_name: fromName,
557
+ reply_to: replyTo,
558
+ },
559
+ });
560
+
561
+ console.log('Campaign created:', response.id);
562
+ return response;
563
+ } catch (error) {
564
+ console.error('Error creating campaign:', error);
565
+ }
566
+ }
567
+ ```
568
+
569
+ ### Set Campaign Content
570
+
571
+ ```javascript
572
+ async function setCampaignContent(campaignId, htmlContent) {
573
+ try {
574
+ const response = await mailchimp.campaigns.setContent(campaignId, {
575
+ html: htmlContent,
576
+ });
577
+
578
+ console.log('Campaign content set');
579
+ return response;
580
+ } catch (error) {
581
+ console.error('Error setting campaign content:', error);
582
+ }
583
+ }
584
+ ```
585
+
586
+ ### Send a Campaign
587
+
588
+ ```javascript
589
+ async function sendCampaign(campaignId) {
590
+ try {
591
+ const response = await mailchimp.campaigns.send(campaignId);
592
+ console.log('Campaign sent successfully');
593
+ return response;
594
+ } catch (error) {
595
+ console.error('Error sending campaign:', error);
596
+ }
597
+ }
598
+ ```
599
+
600
+ ### Complete Campaign Workflow
601
+
602
+ ```javascript
603
+ async function createAndSendCampaign(listId, subject, htmlContent) {
604
+ try {
605
+ // 1. Create campaign
606
+ const campaign = await mailchimp.campaigns.create({
607
+ type: 'regular',
608
+ recipients: {
609
+ list_id: listId,
610
+ },
611
+ settings: {
612
+ subject_line: subject,
613
+ title: subject,
614
+ from_name: 'My Company',
615
+ reply_to: 'hello@mycompany.com',
616
+ },
617
+ });
618
+
619
+ console.log('Campaign created:', campaign.id);
620
+
621
+ // 2. Set content
622
+ await mailchimp.campaigns.setContent(campaign.id, {
623
+ html: htmlContent,
624
+ });
625
+
626
+ console.log('Campaign content set');
627
+
628
+ // 3. Send campaign
629
+ await mailchimp.campaigns.send(campaign.id);
630
+
631
+ console.log('Campaign sent successfully');
632
+
633
+ return campaign;
634
+ } catch (error) {
635
+ console.error('Error in campaign workflow:', error);
636
+ }
637
+ }
638
+ ```
639
+
640
+ ### Schedule a Campaign
641
+
642
+ ```javascript
643
+ async function scheduleCampaign(campaignId, scheduleTime) {
644
+ try {
645
+ const response = await mailchimp.campaigns.schedule(campaignId, {
646
+ schedule_time: scheduleTime, // ISO 8601 format: "2024-12-31T10:00:00Z"
647
+ });
648
+
649
+ console.log('Campaign scheduled for:', scheduleTime);
650
+ return response;
651
+ } catch (error) {
652
+ console.error('Error scheduling campaign:', error);
653
+ }
654
+ }
655
+ ```
656
+
657
+ ### Update Campaign Settings
658
+
659
+ ```javascript
660
+ async function updateCampaign(campaignId, updates) {
661
+ try {
662
+ const response = await mailchimp.campaigns.update(campaignId, updates);
663
+ console.log('Campaign updated');
664
+ return response;
665
+ } catch (error) {
666
+ console.error('Error updating campaign:', error);
667
+ }
668
+ }
669
+
670
+ // Example usage
671
+ updateCampaign('campaign123', {
672
+ settings: {
673
+ subject_line: 'Updated Subject Line',
674
+ preview_text: 'Check out our latest updates!',
675
+ },
676
+ });
677
+ ```
678
+
679
+ ### Delete a Campaign
680
+
681
+ ```javascript
682
+ async function deleteCampaign(campaignId) {
683
+ try {
684
+ await mailchimp.campaigns.remove(campaignId);
685
+ console.log('Campaign deleted');
686
+ } catch (error) {
687
+ console.error('Error deleting campaign:', error);
688
+ }
689
+ }
690
+ ```
691
+
692
+ ## Templates Management
693
+
694
+ ### Get All Templates
695
+
696
+ ```javascript
697
+ async function getAllTemplates() {
698
+ try {
699
+ const response = await mailchimp.templates.list({
700
+ count: 100,
701
+ });
702
+
703
+ console.log('Total templates:', response.total_items);
704
+
705
+ response.templates.forEach(template => {
706
+ console.log(`Template: ${template.name} (ID: ${template.id})`);
707
+ console.log(`Type: ${template.type}, Category: ${template.category}`);
708
+ });
709
+
710
+ return response.templates;
711
+ } catch (error) {
712
+ console.error('Error fetching templates:', error);
713
+ }
714
+ }
715
+ ```
716
+
717
+ ### Get Specific Template
718
+
719
+ ```javascript
720
+ async function getTemplate(templateId) {
721
+ try {
722
+ const response = await mailchimp.templates.getTemplate(templateId);
723
+ console.log('Template:', response.name);
724
+ console.log('HTML:', response.html);
725
+ return response;
726
+ } catch (error) {
727
+ console.error('Error fetching template:', error);
728
+ }
729
+ }
730
+ ```
731
+
732
+ ### Create a Template
733
+
734
+ ```javascript
735
+ async function createTemplate(name, htmlContent) {
736
+ try {
737
+ const response = await mailchimp.templates.create({
738
+ name: name,
739
+ html: htmlContent,
740
+ });
741
+
742
+ console.log('Template created:', response.id);
743
+ return response;
744
+ } catch (error) {
745
+ console.error('Error creating template:', error);
746
+ }
747
+ }
748
+ ```
749
+
750
+ ### Use Template in Campaign
751
+
752
+ ```javascript
753
+ async function createCampaignFromTemplate(listId, templateId, subject) {
754
+ try {
755
+ const campaign = await mailchimp.campaigns.create({
756
+ type: 'regular',
757
+ recipients: {
758
+ list_id: listId,
759
+ },
760
+ settings: {
761
+ subject_line: subject,
762
+ title: subject,
763
+ from_name: 'My Company',
764
+ reply_to: 'hello@mycompany.com',
765
+ template_id: templateId,
766
+ },
767
+ });
768
+
769
+ console.log('Campaign created from template:', campaign.id);
770
+ return campaign;
771
+ } catch (error) {
772
+ console.error('Error creating campaign from template:', error);
773
+ }
774
+ }
775
+ ```
776
+
777
+ ## Automation Workflows
778
+
779
+ ### Get All Automations
780
+
781
+ ```javascript
782
+ async function getAllAutomations() {
783
+ try {
784
+ const response = await mailchimp.automations.list({
785
+ count: 100,
786
+ });
787
+
788
+ console.log('Total automations:', response.total_items);
789
+
790
+ response.automations.forEach(automation => {
791
+ console.log(`Automation: ${automation.settings.title}`);
792
+ console.log(`Status: ${automation.status}, Recipients: ${automation.recipients.list_id}`);
793
+ });
794
+
795
+ return response.automations;
796
+ } catch (error) {
797
+ console.error('Error fetching automations:', error);
798
+ }
799
+ }
800
+ ```
801
+
802
+ ### Get Specific Automation
803
+
804
+ ```javascript
805
+ async function getAutomation(workflowId) {
806
+ try {
807
+ const response = await mailchimp.automations.get(workflowId);
808
+ console.log('Automation:', response.settings.title);
809
+ console.log('Status:', response.status);
810
+ console.log('Emails:', response.emails.length);
811
+ return response;
812
+ } catch (error) {
813
+ console.error('Error fetching automation:', error);
814
+ }
815
+ }
816
+ ```
817
+
818
+ ### Pause an Automation
819
+
820
+ ```javascript
821
+ async function pauseAutomation(workflowId) {
822
+ try {
823
+ await mailchimp.automations.pause(workflowId);
824
+ console.log('Automation paused');
825
+ } catch (error) {
826
+ console.error('Error pausing automation:', error);
827
+ }
828
+ }
829
+ ```
830
+
831
+ ### Start an Automation
832
+
833
+ ```javascript
834
+ async function startAutomation(workflowId) {
835
+ try {
836
+ await mailchimp.automations.start(workflowId);
837
+ console.log('Automation started');
838
+ } catch (error) {
839
+ console.error('Error starting automation:', error);
840
+ }
841
+ }
842
+ ```
843
+
844
+ ### Add Subscriber to Automation Email Queue
845
+
846
+ ```javascript
847
+ async function addSubscriberToAutomation(workflowId, workflowEmailId, email) {
848
+ try {
849
+ const response = await mailchimp.automations.addWorkflowEmailSubscriber(
850
+ workflowId,
851
+ workflowEmailId,
852
+ {
853
+ email_address: email,
854
+ }
855
+ );
856
+
857
+ console.log(`Added ${email} to automation queue`);
858
+ return response;
859
+ } catch (error) {
860
+ console.error('Error adding subscriber to automation:', error);
861
+ }
862
+ }
863
+ ```
864
+
865
+ ## Reports and Analytics
866
+
867
+ ### Get Campaign Reports
868
+
869
+ ```javascript
870
+ async function getCampaignReport(campaignId) {
871
+ try {
872
+ const response = await mailchimp.reports.getCampaignReport(campaignId);
873
+
874
+ console.log('Campaign:', response.campaign_title);
875
+ console.log('Emails sent:', response.emails_sent);
876
+ console.log('Opens:', response.opens.opens_total);
877
+ console.log('Unique opens:', response.opens.unique_opens);
878
+ console.log('Open rate:', response.opens.open_rate);
879
+ console.log('Clicks:', response.clicks.clicks_total);
880
+ console.log('Unique clicks:', response.clicks.unique_clicks);
881
+ console.log('Click rate:', response.clicks.click_rate);
882
+ console.log('Unsubscribes:', response.unsubscribed);
883
+
884
+ return response;
885
+ } catch (error) {
886
+ console.error('Error fetching campaign report:', error);
887
+ }
888
+ }
889
+ ```
890
+
891
+ ### Get All Campaign Reports
892
+
893
+ ```javascript
894
+ async function getAllCampaignReports(count = 100) {
895
+ try {
896
+ const response = await mailchimp.reports.getAllCampaignReports({
897
+ count: count,
898
+ });
899
+
900
+ console.log('Total reports:', response.total_items);
901
+
902
+ response.reports.forEach(report => {
903
+ console.log(`Campaign: ${report.campaign_title}`);
904
+ console.log(`Open rate: ${report.opens.open_rate}%`);
905
+ console.log(`Click rate: ${report.clicks.click_rate}%`);
906
+ });
907
+
908
+ return response.reports;
909
+ } catch (error) {
910
+ console.error('Error fetching reports:', error);
911
+ }
912
+ }
913
+ ```
914
+
915
+ ### Get Email Activity for a Member
916
+
917
+ ```javascript
918
+ const crypto = require('crypto');
919
+
920
+ async function getEmailActivity(campaignId, email) {
921
+ try {
922
+ const subscriberHash = crypto
923
+ .createHash('md5')
924
+ .update(email.toLowerCase())
925
+ .digest('hex');
926
+
927
+ const response = await mailchimp.reports.getEmailActivityForSubscriber(
928
+ campaignId,
929
+ subscriberHash
930
+ );
931
+
932
+ console.log(`Email activity for ${email}:`);
933
+ response.activity.forEach(activity => {
934
+ console.log(`${activity.action} at ${activity.timestamp}`);
935
+ });
936
+
937
+ return response;
938
+ } catch (error) {
939
+ console.error('Error fetching email activity:', error);
940
+ }
941
+ }
942
+ ```
943
+
944
+ ### Get List Growth History
945
+
946
+ ```javascript
947
+ async function getListGrowthHistory(listId) {
948
+ try {
949
+ const response = await mailchimp.lists.getListGrowthHistory(listId, {
950
+ count: 100,
951
+ });
952
+
953
+ console.log('Growth history for list:');
954
+ response.history.forEach(history => {
955
+ console.log(`Month: ${history.month}`);
956
+ console.log(`Subscribed: ${history.subscribed}, Unsubscribed: ${history.unsubscribed}`);
957
+ console.log(`Existing: ${history.existing}`);
958
+ });
959
+
960
+ return response.history;
961
+ } catch (error) {
962
+ console.error('Error fetching growth history:', error);
963
+ }
964
+ }
965
+ ```
966
+
967
+ ## E-commerce Integration
968
+
969
+ ### Add a Store
970
+
971
+ ```javascript
972
+ async function addStore(listId, storeId, storeName, currencyCode) {
973
+ try {
974
+ const response = await mailchimp.ecommerce.addStore({
975
+ id: storeId,
976
+ list_id: listId,
977
+ name: storeName,
978
+ currency_code: currencyCode,
979
+ });
980
+
981
+ console.log('Store created:', response.id);
982
+ return response;
983
+ } catch (error) {
984
+ console.error('Error adding store:', error);
985
+ }
986
+ }
987
+ ```
988
+
989
+ ### Get All Stores
990
+
991
+ ```javascript
992
+ async function getAllStores() {
993
+ try {
994
+ const response = await mailchimp.ecommerce.getStores();
995
+
996
+ console.log('Total stores:', response.total_items);
997
+
998
+ response.stores.forEach(store => {
999
+ console.log(`Store: ${store.name} (ID: ${store.id})`);
1000
+ console.log(`Currency: ${store.currency_code}`);
1001
+ });
1002
+
1003
+ return response.stores;
1004
+ } catch (error) {
1005
+ console.error('Error fetching stores:', error);
1006
+ }
1007
+ }
1008
+ ```
1009
+
1010
+ ### Add a Customer
1011
+
1012
+ ```javascript
1013
+ async function addCustomer(storeId, customerId, email, firstName, lastName) {
1014
+ try {
1015
+ const response = await mailchimp.ecommerce.addStoreCustomer(storeId, {
1016
+ id: customerId,
1017
+ email_address: email,
1018
+ opt_in_status: true,
1019
+ first_name: firstName,
1020
+ last_name: lastName,
1021
+ });
1022
+
1023
+ console.log('Customer added:', response.id);
1024
+ return response;
1025
+ } catch (error) {
1026
+ console.error('Error adding customer:', error);
1027
+ }
1028
+ }
1029
+ ```
1030
+
1031
+ ### Add a Product
1032
+
1033
+ ```javascript
1034
+ async function addProduct(storeId, productId, title, price) {
1035
+ try {
1036
+ const response = await mailchimp.ecommerce.addStoreProduct(storeId, {
1037
+ id: productId,
1038
+ title: title,
1039
+ variants: [
1040
+ {
1041
+ id: `${productId}-variant-1`,
1042
+ title: 'Default Variant',
1043
+ price: price,
1044
+ },
1045
+ ],
1046
+ });
1047
+
1048
+ console.log('Product added:', response.id);
1049
+ return response;
1050
+ } catch (error) {
1051
+ console.error('Error adding product:', error);
1052
+ }
1053
+ }
1054
+ ```
1055
+
1056
+ ### Add an Order
1057
+
1058
+ ```javascript
1059
+ async function addOrder(storeId, orderId, customerId, lineItems, total) {
1060
+ try {
1061
+ const response = await mailchimp.ecommerce.addStoreOrder(storeId, {
1062
+ id: orderId,
1063
+ customer: {
1064
+ id: customerId,
1065
+ },
1066
+ lines: lineItems.map(item => ({
1067
+ id: item.id,
1068
+ product_id: item.productId,
1069
+ product_variant_id: item.variantId,
1070
+ quantity: item.quantity,
1071
+ price: item.price,
1072
+ })),
1073
+ currency_code: 'USD',
1074
+ order_total: total,
1075
+ processed_at_foreign: new Date().toISOString(),
1076
+ });
1077
+
1078
+ console.log('Order added:', response.id);
1079
+ return response;
1080
+ } catch (error) {
1081
+ console.error('Error adding order:', error);
1082
+ }
1083
+ }
1084
+
1085
+ // Example usage
1086
+ addOrder('store123', 'order456', 'customer789', [
1087
+ {
1088
+ id: 'line1',
1089
+ productId: 'prod1',
1090
+ variantId: 'prod1-variant-1',
1091
+ quantity: 2,
1092
+ price: 29.99,
1093
+ },
1094
+ ], 59.98);
1095
+ ```
1096
+
1097
+ ### Add a Cart
1098
+
1099
+ ```javascript
1100
+ async function addCart(storeId, cartId, customerId, lineItems) {
1101
+ try {
1102
+ const response = await mailchimp.ecommerce.addStoreCart(storeId, {
1103
+ id: cartId,
1104
+ customer: {
1105
+ id: customerId,
1106
+ },
1107
+ lines: lineItems.map(item => ({
1108
+ id: item.id,
1109
+ product_id: item.productId,
1110
+ product_variant_id: item.variantId,
1111
+ quantity: item.quantity,
1112
+ price: item.price,
1113
+ })),
1114
+ currency_code: 'USD',
1115
+ });
1116
+
1117
+ console.log('Cart added:', response.id);
1118
+ return response;
1119
+ } catch (error) {
1120
+ console.error('Error adding cart:', error);
1121
+ }
1122
+ }
1123
+ ```
1124
+
1125
+ ## Error Handling
1126
+
1127
+ ### Comprehensive Error Handling
1128
+
1129
+ ```javascript
1130
+ async function handleMailchimpRequest() {
1131
+ try {
1132
+ const response = await mailchimp.lists.getAllLists();
1133
+ return response;
1134
+ } catch (error) {
1135
+ console.error('Mailchimp API Error:', error);
1136
+
1137
+ if (error.status) {
1138
+ console.error('Status Code:', error.status);
1139
+ console.error('Error Message:', error.response?.body?.title);
1140
+ console.error('Error Detail:', error.response?.body?.detail);
1141
+
1142
+ switch (error.status) {
1143
+ case 401:
1144
+ console.error('Authentication failed. Check your API key.');
1145
+ break;
1146
+ case 403:
1147
+ console.error('Forbidden. Check your permissions.');
1148
+ break;
1149
+ case 404:
1150
+ console.error('Resource not found.');
1151
+ break;
1152
+ case 400:
1153
+ console.error('Bad request. Check your parameters.');
1154
+ if (error.response?.body?.errors) {
1155
+ console.error('Validation errors:', error.response.body.errors);
1156
+ }
1157
+ break;
1158
+ case 429:
1159
+ console.error('Rate limit exceeded. Wait before retrying.');
1160
+ break;
1161
+ case 500:
1162
+ console.error('Mailchimp server error. Try again later.');
1163
+ break;
1164
+ default:
1165
+ console.error('Unexpected error occurred.');
1166
+ }
1167
+ }
1168
+
1169
+ throw error;
1170
+ }
1171
+ }
1172
+ ```
1173
+
1174
+ ### Retry Logic for Rate Limiting
1175
+
1176
+ ```javascript
1177
+ async function retryRequest(requestFn, maxRetries = 3, delay = 1000) {
1178
+ for (let i = 0; i < maxRetries; i++) {
1179
+ try {
1180
+ return await requestFn();
1181
+ } catch (error) {
1182
+ if (error.status === 429 && i < maxRetries - 1) {
1183
+ console.log(`Rate limited. Retrying in ${delay}ms...`);
1184
+ await new Promise(resolve => setTimeout(resolve, delay));
1185
+ delay *= 2; // Exponential backoff
1186
+ } else {
1187
+ throw error;
1188
+ }
1189
+ }
1190
+ }
1191
+ }
1192
+
1193
+ // Example usage
1194
+ const result = await retryRequest(() => mailchimp.lists.getAllLists());
1195
+ ```
1196
+
1197
+ ## Pagination
1198
+
1199
+ ### Paginate Through Large Result Sets
1200
+
1201
+ ```javascript
1202
+ async function getAllListMembersPaginated(listId) {
1203
+ let offset = 0;
1204
+ const count = 100;
1205
+ const allMembers = [];
1206
+
1207
+ while (true) {
1208
+ try {
1209
+ const response = await mailchimp.lists.getListMembersInfo(listId, {
1210
+ count: count,
1211
+ offset: offset,
1212
+ });
1213
+
1214
+ allMembers.push(...response.members);
1215
+
1216
+ console.log(`Fetched ${offset + response.members.length} of ${response.total_items} members`);
1217
+
1218
+ if (response.members.length < count) {
1219
+ break; // No more results
1220
+ }
1221
+
1222
+ offset += count;
1223
+ } catch (error) {
1224
+ console.error('Error during pagination:', error);
1225
+ break;
1226
+ }
1227
+ }
1228
+
1229
+ return allMembers;
1230
+ }
1231
+ ```
1232
+
1233
+ ## TypeScript Support
1234
+
1235
+ The SDK includes TypeScript definitions:
1236
+
1237
+ ```typescript
1238
+ import mailchimp from '@mailchimp/mailchimp_marketing';
1239
+
1240
+ mailchimp.setConfig({
1241
+ apiKey: process.env.MAILCHIMP_API_KEY as string,
1242
+ server: process.env.MAILCHIMP_SERVER_PREFIX as string,
1243
+ });
1244
+
1245
+ interface ListMember {
1246
+ email_address: string;
1247
+ status: 'subscribed' | 'unsubscribed' | 'cleaned' | 'pending';
1248
+ merge_fields: {
1249
+ FNAME: string;
1250
+ LNAME: string;
1251
+ };
1252
+ }
1253
+
1254
+ async function addTypedMember(listId: string, member: ListMember) {
1255
+ const response = await mailchimp.lists.addListMember(listId, member);
1256
+ return response;
1257
+ }
1258
+ ```
1259
+
1260
+ ## Common Patterns
1261
+
1262
+ ### Bulk Import Subscribers from CSV
1263
+
1264
+ ```javascript
1265
+ const fs = require('fs');
1266
+ const csv = require('csv-parser');
1267
+
1268
+ async function importFromCSV(listId, csvFilePath) {
1269
+ const members = [];
1270
+
1271
+ return new Promise((resolve, reject) => {
1272
+ fs.createReadStream(csvFilePath)
1273
+ .pipe(csv())
1274
+ .on('data', (row) => {
1275
+ members.push({
1276
+ email_address: row.email,
1277
+ status: 'subscribed',
1278
+ merge_fields: {
1279
+ FNAME: row.first_name,
1280
+ LNAME: row.last_name,
1281
+ },
1282
+ });
1283
+ })
1284
+ .on('end', async () => {
1285
+ try {
1286
+ // Batch in groups of 500 (Mailchimp limit)
1287
+ const batchSize = 500;
1288
+ for (let i = 0; i < members.length; i += batchSize) {
1289
+ const batch = members.slice(i, i + batchSize);
1290
+
1291
+ const response = await mailchimp.lists.batchListMembers(listId, {
1292
+ members: batch,
1293
+ update_existing: true,
1294
+ });
1295
+
1296
+ console.log(`Batch ${i / batchSize + 1}: ${response.new_members.length} added, ${response.updated_members.length} updated`);
1297
+ }
1298
+
1299
+ resolve();
1300
+ } catch (error) {
1301
+ reject(error);
1302
+ }
1303
+ });
1304
+ });
1305
+ }
1306
+ ```
1307
+
1308
+ ### Send Welcome Email via Automation
1309
+
1310
+ ```javascript
1311
+ async function setupWelcomeAutomation(listId) {
1312
+ try {
1313
+ // Create a basic automation trigger when someone subscribes
1314
+ const automation = await mailchimp.automations.create({
1315
+ recipients: {
1316
+ list_id: listId,
1317
+ },
1318
+ trigger_settings: {
1319
+ workflow_type: 'welcomeSeries',
1320
+ },
1321
+ settings: {
1322
+ title: 'Welcome Email Series',
1323
+ from_name: 'My Company',
1324
+ reply_to: 'hello@mycompany.com',
1325
+ },
1326
+ });
1327
+
1328
+ console.log('Welcome automation created:', automation.id);
1329
+ return automation;
1330
+ } catch (error) {
1331
+ console.error('Error setting up welcome automation:', error);
1332
+ }
1333
+ }
1334
+ ```
1335
+
1336
+ ### Segment Users by Engagement
1337
+
1338
+ ```javascript
1339
+ async function createEngagementSegment(listId, segmentName) {
1340
+ try {
1341
+ const response = await mailchimp.lists.createSegment(listId, {
1342
+ name: segmentName,
1343
+ options: {
1344
+ match: 'all',
1345
+ conditions: [
1346
+ {
1347
+ condition_type: 'EmailClient',
1348
+ field: 'email_client',
1349
+ op: 'is',
1350
+ value: 'Gmail',
1351
+ },
1352
+ ],
1353
+ },
1354
+ });
1355
+
1356
+ console.log('Engagement segment created:', response.id);
1357
+ return response;
1358
+ } catch (error) {
1359
+ console.error('Error creating segment:', error);
1360
+ }
1361
+ }
1362
+ ```
1363
+
1364
+ ## Webhooks
1365
+
1366
+ ### Process Webhook Events
1367
+
1368
+ ```javascript
1369
+ const express = require('express');
1370
+ const crypto = require('crypto');
1371
+
1372
+ const app = express();
1373
+ app.use(express.json());
1374
+
1375
+ // Verify webhook signature
1376
+ function verifyWebhook(secret, body, signature) {
1377
+ const hash = crypto
1378
+ .createHmac('sha1', secret)
1379
+ .update(JSON.stringify(body))
1380
+ .digest('hex');
1381
+
1382
+ return hash === signature;
1383
+ }
1384
+
1385
+ app.post('/mailchimp-webhook', (req, res) => {
1386
+ const signature = req.headers['x-mailchimp-signature'];
1387
+ const webhookSecret = process.env.MAILCHIMP_WEBHOOK_SECRET;
1388
+
1389
+ if (!verifyWebhook(webhookSecret, req.body, signature)) {
1390
+ return res.status(401).send('Invalid signature');
1391
+ }
1392
+
1393
+ const { type, data } = req.body;
1394
+
1395
+ switch (type) {
1396
+ case 'subscribe':
1397
+ console.log('New subscriber:', data.email);
1398
+ break;
1399
+ case 'unsubscribe':
1400
+ console.log('Unsubscribed:', data.email);
1401
+ break;
1402
+ case 'profile':
1403
+ console.log('Profile updated:', data.email);
1404
+ break;
1405
+ case 'campaign':
1406
+ console.log('Campaign event:', data);
1407
+ break;
1408
+ default:
1409
+ console.log('Unknown webhook type:', type);
1410
+ }
1411
+
1412
+ res.status(200).send('OK');
1413
+ });
1414
+
1415
+ app.listen(3000, () => console.log('Webhook server running on port 3000'));
1416
+ ```
1417
+
1418
+ ## Notes
1419
+
1420
+ The Mailchimp Marketing Node.js SDK is auto-generated from the OpenAPI specification and provides comprehensive access to all Mailchimp Marketing API endpoints. Always use environment variables for API keys and server prefixes. The library supports both Basic Auth (API key) and OAuth2 authentication methods. Rate limits apply: 10 simultaneous connections per account and throttling based on your plan. Use batch operations when adding multiple members to optimize API usage.