@divyacon/piece-mailchimp 0.0.0-stage → 0.1.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 (148) hide show
  1. package/LICENSE.MIT-AP +24 -0
  2. package/dist/index.d.ts +3 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +80 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/lib/actions/add-member-to-list.d.ts +13 -0
  7. package/dist/lib/actions/add-member-to-list.d.ts.map +1 -0
  8. package/dist/lib/actions/add-member-to-list.js +172 -0
  9. package/dist/lib/actions/add-member-to-list.js.map +1 -0
  10. package/dist/lib/actions/add-note-to-subscriber.d.ts +6 -0
  11. package/dist/lib/actions/add-note-to-subscriber.d.ts.map +1 -0
  12. package/dist/lib/actions/add-note-to-subscriber.js +95 -0
  13. package/dist/lib/actions/add-note-to-subscriber.js.map +1 -0
  14. package/dist/lib/actions/add-subscriber-to-tag.d.ts +6 -0
  15. package/dist/lib/actions/add-subscriber-to-tag.d.ts.map +1 -0
  16. package/dist/lib/actions/add-subscriber-to-tag.js +65 -0
  17. package/dist/lib/actions/add-subscriber-to-tag.js.map +1 -0
  18. package/dist/lib/actions/archive-subscriber.d.ts +5 -0
  19. package/dist/lib/actions/archive-subscriber.d.ts.map +1 -0
  20. package/dist/lib/actions/archive-subscriber.js +66 -0
  21. package/dist/lib/actions/archive-subscriber.js.map +1 -0
  22. package/dist/lib/actions/create-audience.d.ts +23 -0
  23. package/dist/lib/actions/create-audience.d.ts.map +1 -0
  24. package/dist/lib/actions/create-audience.js +196 -0
  25. package/dist/lib/actions/create-audience.js.map +1 -0
  26. package/dist/lib/actions/create-campaign.d.ts +15 -0
  27. package/dist/lib/actions/create-campaign.d.ts.map +1 -0
  28. package/dist/lib/actions/create-campaign.js +157 -0
  29. package/dist/lib/actions/create-campaign.js.map +1 -0
  30. package/dist/lib/actions/create-custom-event.d.ts +7 -0
  31. package/dist/lib/actions/create-custom-event.d.ts.map +1 -0
  32. package/dist/lib/actions/create-custom-event.js +65 -0
  33. package/dist/lib/actions/create-custom-event.js.map +1 -0
  34. package/dist/lib/actions/create-tag.d.ts +5 -0
  35. package/dist/lib/actions/create-tag.d.ts.map +1 -0
  36. package/dist/lib/actions/create-tag.js +56 -0
  37. package/dist/lib/actions/create-tag.js.map +1 -0
  38. package/dist/lib/actions/find-campaign.d.ts +6 -0
  39. package/dist/lib/actions/find-campaign.d.ts.map +1 -0
  40. package/dist/lib/actions/find-campaign.js +70 -0
  41. package/dist/lib/actions/find-campaign.js.map +1 -0
  42. package/dist/lib/actions/find-customer.d.ts +9 -0
  43. package/dist/lib/actions/find-customer.d.ts.map +1 -0
  44. package/dist/lib/actions/find-customer.js +87 -0
  45. package/dist/lib/actions/find-customer.js.map +1 -0
  46. package/dist/lib/actions/find-subscriber.d.ts +7 -0
  47. package/dist/lib/actions/find-subscriber.d.ts.map +1 -0
  48. package/dist/lib/actions/find-subscriber.js +307 -0
  49. package/dist/lib/actions/find-subscriber.js.map +1 -0
  50. package/dist/lib/actions/find-tag.d.ts +5 -0
  51. package/dist/lib/actions/find-tag.d.ts.map +1 -0
  52. package/dist/lib/actions/find-tag.js +57 -0
  53. package/dist/lib/actions/find-tag.js.map +1 -0
  54. package/dist/lib/actions/get-campaign-report.d.ts +6 -0
  55. package/dist/lib/actions/get-campaign-report.d.ts.map +1 -0
  56. package/dist/lib/actions/get-campaign-report.js +206 -0
  57. package/dist/lib/actions/get-campaign-report.js.map +1 -0
  58. package/dist/lib/actions/remove-subscriber-from-tag.d.ts +6 -0
  59. package/dist/lib/actions/remove-subscriber-from-tag.d.ts.map +1 -0
  60. package/dist/lib/actions/remove-subscriber-from-tag.js +98 -0
  61. package/dist/lib/actions/remove-subscriber-from-tag.js.map +1 -0
  62. package/dist/lib/actions/send-campaign.d.ts +4 -0
  63. package/dist/lib/actions/send-campaign.d.ts.map +1 -0
  64. package/dist/lib/actions/send-campaign.js +47 -0
  65. package/dist/lib/actions/send-campaign.js.map +1 -0
  66. package/dist/lib/actions/unsubscribe-email.d.ts +8 -0
  67. package/dist/lib/actions/unsubscribe-email.d.ts.map +1 -0
  68. package/dist/lib/actions/unsubscribe-email.js +90 -0
  69. package/dist/lib/actions/unsubscribe-email.js.map +1 -0
  70. package/dist/lib/actions/update-subscriber-status.d.ts +6 -0
  71. package/dist/lib/actions/update-subscriber-status.d.ts.map +1 -0
  72. package/dist/lib/actions/update-subscriber-status.js +54 -0
  73. package/dist/lib/actions/update-subscriber-status.js.map +1 -0
  74. package/dist/lib/common/index.d.ts +30 -0
  75. package/dist/lib/common/index.d.ts.map +1 -0
  76. package/dist/lib/common/index.js +206 -0
  77. package/dist/lib/common/index.js.map +1 -0
  78. package/dist/lib/common/types.d.ts +362 -0
  79. package/dist/lib/common/types.d.ts.map +1 -0
  80. package/dist/lib/common/types.js +54 -0
  81. package/dist/lib/common/types.js.map +1 -0
  82. package/dist/lib/triggers/email-opened-trigger.d.ts +11 -0
  83. package/dist/lib/triggers/email-opened-trigger.d.ts.map +1 -0
  84. package/dist/lib/triggers/email-opened-trigger.js +199 -0
  85. package/dist/lib/triggers/email-opened-trigger.js.map +1 -0
  86. package/dist/lib/triggers/link-clicked-trigger.d.ts +11 -0
  87. package/dist/lib/triggers/link-clicked-trigger.d.ts.map +1 -0
  88. package/dist/lib/triggers/link-clicked-trigger.js +226 -0
  89. package/dist/lib/triggers/link-clicked-trigger.js.map +1 -0
  90. package/dist/lib/triggers/new-campaign-trigger.d.ts +11 -0
  91. package/dist/lib/triggers/new-campaign-trigger.d.ts.map +1 -0
  92. package/dist/lib/triggers/new-campaign-trigger.js +147 -0
  93. package/dist/lib/triggers/new-campaign-trigger.js.map +1 -0
  94. package/dist/lib/triggers/new-customer-trigger.d.ts +11 -0
  95. package/dist/lib/triggers/new-customer-trigger.d.ts.map +1 -0
  96. package/dist/lib/triggers/new-customer-trigger.js +214 -0
  97. package/dist/lib/triggers/new-customer-trigger.js.map +1 -0
  98. package/dist/lib/triggers/new-order-trigger.d.ts +11 -0
  99. package/dist/lib/triggers/new-order-trigger.d.ts.map +1 -0
  100. package/dist/lib/triggers/new-order-trigger.js +270 -0
  101. package/dist/lib/triggers/new-order-trigger.js.map +1 -0
  102. package/dist/lib/triggers/new-segment-tag-subscriber-trigger.d.ts +19 -0
  103. package/dist/lib/triggers/new-segment-tag-subscriber-trigger.d.ts.map +1 -0
  104. package/dist/lib/triggers/new-segment-tag-subscriber-trigger.js +264 -0
  105. package/dist/lib/triggers/new-segment-tag-subscriber-trigger.js.map +1 -0
  106. package/dist/lib/triggers/subscribe-trigger.d.ts +11 -0
  107. package/dist/lib/triggers/subscribe-trigger.d.ts.map +1 -0
  108. package/dist/lib/triggers/subscribe-trigger.js +150 -0
  109. package/dist/lib/triggers/subscribe-trigger.js.map +1 -0
  110. package/dist/lib/triggers/subscriber-updated-trigger.d.ts +11 -0
  111. package/dist/lib/triggers/subscriber-updated-trigger.d.ts.map +1 -0
  112. package/dist/lib/triggers/subscriber-updated-trigger.js +157 -0
  113. package/dist/lib/triggers/subscriber-updated-trigger.js.map +1 -0
  114. package/dist/lib/triggers/unsubscribe-trigger.d.ts +11 -0
  115. package/dist/lib/triggers/unsubscribe-trigger.d.ts.map +1 -0
  116. package/dist/lib/triggers/unsubscribe-trigger.js +196 -0
  117. package/dist/lib/triggers/unsubscribe-trigger.js.map +1 -0
  118. package/package.json +45 -3
  119. package/src/index.ts +77 -0
  120. package/src/lib/actions/add-member-to-list.ts +180 -0
  121. package/src/lib/actions/add-note-to-subscriber.ts +91 -0
  122. package/src/lib/actions/add-subscriber-to-tag.ts +66 -0
  123. package/src/lib/actions/archive-subscriber.ts +64 -0
  124. package/src/lib/actions/create-audience.ts +192 -0
  125. package/src/lib/actions/create-campaign.ts +155 -0
  126. package/src/lib/actions/create-custom-event.ts +63 -0
  127. package/src/lib/actions/create-tag.ts +51 -0
  128. package/src/lib/actions/find-campaign.ts +68 -0
  129. package/src/lib/actions/find-customer.ts +88 -0
  130. package/src/lib/actions/find-subscriber.ts +307 -0
  131. package/src/lib/actions/find-tag.ts +57 -0
  132. package/src/lib/actions/get-campaign-report.ts +204 -0
  133. package/src/lib/actions/remove-subscriber-from-tag.ts +94 -0
  134. package/src/lib/actions/send-campaign.ts +42 -0
  135. package/src/lib/actions/unsubscribe-email.ts +91 -0
  136. package/src/lib/actions/update-subscriber-status.ts +53 -0
  137. package/src/lib/common/index.ts +267 -0
  138. package/src/lib/common/types.ts +410 -0
  139. package/src/lib/triggers/email-opened-trigger.ts +216 -0
  140. package/src/lib/triggers/link-clicked-trigger.ts +244 -0
  141. package/src/lib/triggers/new-campaign-trigger.ts +149 -0
  142. package/src/lib/triggers/new-customer-trigger.ts +230 -0
  143. package/src/lib/triggers/new-order-trigger.ts +288 -0
  144. package/src/lib/triggers/new-segment-tag-subscriber-trigger.ts +286 -0
  145. package/src/lib/triggers/subscribe-trigger.ts +159 -0
  146. package/src/lib/triggers/subscriber-updated-trigger.ts +165 -0
  147. package/src/lib/triggers/unsubscribe-trigger.ts +212 -0
  148. package/README.md +0 -3
@@ -0,0 +1,94 @@
1
+ import { createAction, Property } from '@agnocon/pieces-framework';
2
+ import { getAccessTokenOrThrow } from '@agnocon/pieces-common';
3
+ import { mailchimpCommon } from '../common';
4
+ import { mailchimpAuth } from '../..';
5
+
6
+ export const removeSubscriberFromTag = createAction({
7
+ auth: mailchimpAuth,
8
+ name: 'remove_subscriber_from_tag',
9
+ displayName: 'Remove Subscriber from Tag',
10
+ description: 'Remove a subscriber from a specific tag in your Mailchimp audience.',
11
+ audience: 'both',
12
+ aiMetadata: { description: 'Deactivates a tag on a subscriber, identified by email within a given audience (list). Use to un-segment or un-label a contact. Idempotent: removing a tag the member does not have leaves the state unchanged.', idempotent: true },
13
+ props: {
14
+ list_id: mailchimpCommon.mailChimpListIdDropdown,
15
+ email: Property.ShortText({
16
+ displayName: 'Email Address',
17
+ description: 'The email address of the subscriber to remove from the tag',
18
+ required: true,
19
+ }),
20
+ tag_name: Property.ShortText({
21
+ displayName: 'Tag Name',
22
+ description: 'The name of the tag to remove the subscriber from',
23
+ required: true,
24
+ }),
25
+ },
26
+ async run(context) {
27
+ const { list_id, email, tag_name } = context.propsValue;
28
+ const accessToken = getAccessTokenOrThrow(context.auth);
29
+
30
+ try {
31
+ const serverPrefix = await mailchimpCommon.getMailChimpServerPrefix(accessToken);
32
+ const subscriberHash = mailchimpCommon.getMD5EmailHash(email);
33
+
34
+ const url = `https://${serverPrefix}.api.mailchimp.com/3.0/lists/${list_id}/members/${subscriberHash}/tags`;
35
+
36
+ const response = await fetch(url, {
37
+ method: 'POST',
38
+ headers: {
39
+ 'Authorization': `Bearer ${accessToken}`,
40
+ 'Content-Type': 'application/json',
41
+ },
42
+ body: JSON.stringify({
43
+ tags: [
44
+ {
45
+ name: tag_name,
46
+ status: 'inactive',
47
+ },
48
+ ],
49
+ }),
50
+ });
51
+
52
+ if (!response.ok) {
53
+ let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
54
+
55
+ try {
56
+ const errorText = await response.text();
57
+ if (errorText && errorText.trim()) {
58
+ const errorData = JSON.parse(errorText);
59
+ errorMessage = errorData.detail || errorData.title || errorData.message || errorText;
60
+ }
61
+ } catch (parseError) {
62
+ const errorText = await response.text();
63
+ if (errorText && errorText.trim()) {
64
+ errorMessage = errorText;
65
+ }
66
+ }
67
+
68
+ throw new Error(`Failed to remove subscriber from tag: ${errorMessage}`);
69
+ }
70
+
71
+ let result;
72
+ try {
73
+ const responseText = await response.text();
74
+ if (responseText && responseText.trim()) {
75
+ result = JSON.parse(responseText);
76
+ } else {
77
+ result = { success: true };
78
+ }
79
+ } catch (parseError) {
80
+ result = { success: true };
81
+ }
82
+
83
+ return {
84
+ success: true,
85
+ message: `Successfully removed subscriber ${email} from tag ${tag_name}`,
86
+ data: result,
87
+ _links: result._links || [],
88
+ };
89
+ } catch (error: any) {
90
+ console.error('Error removing subscriber from tag:', error);
91
+ throw new Error(`Failed to remove subscriber from tag: ${error.message}`);
92
+ }
93
+ },
94
+ });
@@ -0,0 +1,42 @@
1
+ import { createAction } from '@agnocon/pieces-framework';
2
+ import { getAccessTokenOrThrow } from '@agnocon/pieces-common';
3
+ import { mailchimpCommon } from '../common';
4
+ import { mailchimpAuth } from '../..';
5
+ import mailchimp from '@mailchimp/mailchimp_marketing';
6
+ import { MailchimpClient } from '../common/types';
7
+
8
+ export const sendCampaign = createAction({
9
+ auth: mailchimpAuth,
10
+ name: 'send_campaign',
11
+ displayName: 'Send Campaign',
12
+ description: 'Send a draft campaign to the subscribers in its audience, segment, or tag',
13
+ audience: 'both',
14
+ aiMetadata: { description: 'Sends an existing draft campaign to its configured recipients immediately (RSS campaigns follow their schedule instead). Use once the campaign is fully set up; there is no undo, so confirm the campaign content and audience beforehand. Not idempotent: calling again on an already-sent campaign fails.', idempotent: false },
15
+ props: {
16
+ campaign_id: mailchimpCommon.mailChimpDraftCampaignIdDropdown,
17
+ },
18
+ async run(context) {
19
+ const { campaign_id } = context.propsValue;
20
+ const accessToken = getAccessTokenOrThrow(context.auth);
21
+ const server = await mailchimpCommon.getMailChimpServerPrefix(accessToken);
22
+
23
+ const client = mailchimp as unknown as MailchimpClient;
24
+ client.setConfig({
25
+ accessToken: accessToken,
26
+ server: server,
27
+ });
28
+
29
+ try {
30
+ // Docs: https://mailchimp.com/developer/marketing/api/campaigns/send-campaign/
31
+ await client.campaigns.send(campaign_id as string);
32
+
33
+ return {
34
+ success: true,
35
+ message: 'Campaign sent successfully',
36
+ campaign_id,
37
+ };
38
+ } catch (error: any) {
39
+ throw new Error(`Failed to send campaign: ${error.message || JSON.stringify(error)}`);
40
+ }
41
+ },
42
+ });
@@ -0,0 +1,91 @@
1
+ import { createAction, Property } from '@agnocon/pieces-framework';
2
+ import { getAccessTokenOrThrow } from '@agnocon/pieces-common';
3
+ import { mailchimpCommon } from '../common';
4
+ import { mailchimpAuth } from '../..';
5
+ import mailchimp from '@mailchimp/mailchimp_marketing';
6
+ import { MailchimpClient } from '../common/types';
7
+
8
+ export const unsubscribeEmail = createAction({
9
+ auth: mailchimpAuth,
10
+ name: 'unsubscribe_email',
11
+ displayName: 'Unsubscribe Email',
12
+ description: 'Unsubscribe an email address from an audience',
13
+ audience: 'both',
14
+ aiMetadata: { description: 'Sets an email address to unsubscribed status within an audience (list) via a batch upsert; with "update existing" on, it changes an existing member, otherwise it can add the address as unsubscribed. Use to opt a contact out of a specific audience. Idempotent: repeating converges to the same unsubscribed state.', idempotent: true },
15
+ props: {
16
+ list_id: mailchimpCommon.mailChimpListIdDropdown,
17
+ email_address: Property.ShortText({
18
+ displayName: 'Email Address',
19
+ description: 'Email address to unsubscribe',
20
+ required: true,
21
+ }),
22
+ skip_merge_validation: Property.Checkbox({
23
+ displayName: 'Skip Merge Validation',
24
+ description: 'Accept member data without merge field values even if required',
25
+ required: false,
26
+ defaultValue: false,
27
+ }),
28
+ skip_duplicate_check: Property.Checkbox({
29
+ displayName: 'Skip Duplicate Check',
30
+ description: 'Ignore duplicates in the request',
31
+ required: false,
32
+ defaultValue: false,
33
+ }),
34
+ update_existing: Property.Checkbox({
35
+ displayName: 'Update Existing',
36
+ description: 'Change existing members subscription status',
37
+ required: false,
38
+ defaultValue: true,
39
+ }),
40
+ },
41
+ async run(context) {
42
+ const accessToken = getAccessTokenOrThrow(context.auth);
43
+ const server = await mailchimpCommon.getMailChimpServerPrefix(accessToken);
44
+
45
+ const client = mailchimp as unknown as MailchimpClient;
46
+ client.setConfig({
47
+ accessToken: accessToken,
48
+ server: server,
49
+ });
50
+
51
+ try {
52
+ const batchData = {
53
+ members: [
54
+ {
55
+ email_address: context.propsValue.email_address,
56
+ status: 'unsubscribed',
57
+ },
58
+ ],
59
+ update_existing: context.propsValue.update_existing,
60
+ };
61
+
62
+ const queryParams: any = {};
63
+ if (context.propsValue.skip_merge_validation) {
64
+ queryParams.skip_merge_validation = true;
65
+ }
66
+ if (context.propsValue.skip_duplicate_check) {
67
+ queryParams.skip_duplicate_check = true;
68
+ }
69
+
70
+ const result = await client.lists.batchListMembers(
71
+ context.propsValue.list_id!,
72
+ batchData,
73
+ queryParams
74
+ );
75
+
76
+ return {
77
+ success: true,
78
+ message: `Email ${context.propsValue.email_address} has been unsubscribed`,
79
+ new_members: result.new_members,
80
+ updated_members: result.updated_members,
81
+ errors: result.errors,
82
+ total_created: result.total_created,
83
+ total_updated: result.total_updated,
84
+ error_count: result.error_count,
85
+ _links: result._links,
86
+ };
87
+ } catch (error: any) {
88
+ throw new Error(`Failed to unsubscribe email: ${error.message || JSON.stringify(error)}`);
89
+ }
90
+ },
91
+ });
@@ -0,0 +1,53 @@
1
+ import { mailchimpCommon } from '../common';
2
+ import mailchimp from '@mailchimp/mailchimp_marketing';
3
+ import { createAction, Property } from '@agnocon/pieces-framework';
4
+ import { mailchimpAuth } from '../..';
5
+
6
+ export const updateSubscriberInList = createAction({
7
+ auth: mailchimpAuth,
8
+ name: 'update_member_in_list',
9
+ displayName: 'Update Member in an Audience (List)',
10
+ description: 'Update a member in an existing Mailchimp audience (list)',
11
+ audience: 'both',
12
+ aiMetadata: { description: 'Updates the subscription status (subscribed, unsubscribed, cleaned, pending, transactional) of an existing member in an audience (list), identified by email. Use to change a known contact\'s status; the member must already exist, or the call fails. Idempotent: setting the same status repeatedly converges to that state.', idempotent: true },
13
+ props: {
14
+ email: Property.ShortText({
15
+ displayName: 'Email',
16
+ description: 'Email of the new contact',
17
+ required: true,
18
+ }),
19
+ list_id: mailchimpCommon.mailChimpListIdDropdown,
20
+ status: Property.StaticDropdown<
21
+ 'subscribed' | 'unsubscribed' | 'cleaned' | 'pending' | 'transactional'
22
+ >({
23
+ displayName: 'Status',
24
+ required: true,
25
+ options: {
26
+ options: [
27
+ { label: 'Subscribed', value: 'subscribed' },
28
+ { label: 'Unsubscribed', value: 'unsubscribed' },
29
+ { label: 'Cleaned', value: 'cleaned' },
30
+ { label: 'Pending', value: 'pending' },
31
+ { label: 'Transactional', value: 'transactional' },
32
+ ],
33
+ },
34
+ }),
35
+ },
36
+ async run(context) {
37
+ const { list_id, email, status } = context.propsValue;
38
+ const access_token = context.auth.access_token;
39
+ const mailChimpServerPrefix =
40
+ await mailchimpCommon.getMailChimpServerPrefix(access_token);
41
+ mailchimp.setConfig({
42
+ accessToken: access_token,
43
+ server: mailChimpServerPrefix,
44
+ });
45
+ return await mailchimp.lists.updateListMember(
46
+ list_id as string,
47
+ email!,
48
+ {
49
+ status: status!,
50
+ }
51
+ );
52
+ },
53
+ });
@@ -0,0 +1,267 @@
1
+ import { Property, OAuth2PropertyValue } from '@agnocon/pieces-framework';
2
+ import {
3
+ HttpRequest,
4
+ HttpMethod,
5
+ httpClient,
6
+ } from '@agnocon/pieces-common';
7
+ import mailchimp from '@mailchimp/mailchimp_marketing';
8
+ import { AuthenticationType } from '@agnocon/pieces-common';
9
+ import crypto from 'crypto';
10
+ import { mailchimpAuth } from '../..';
11
+
12
+ export const mailchimpCommon = {
13
+ mailChimpListIdDropdown: Property.Dropdown<string,true,typeof mailchimpAuth>({
14
+ auth: mailchimpAuth,
15
+ displayName: 'Audience',
16
+ refreshers: [],
17
+ description: 'Audience you want to add the contact to',
18
+ required: true,
19
+ options: async ({ auth }) => {
20
+ if (!auth) {
21
+ return {
22
+ disabled: true,
23
+ options: [],
24
+ placeholder: 'Please select a connection',
25
+ };
26
+ }
27
+
28
+ const authProp = auth as OAuth2PropertyValue;
29
+ const listResponse = (await mailchimpCommon.getUserLists(
30
+ authProp
31
+ )) as any;
32
+
33
+ const options = listResponse.lists.map((list: any) => ({
34
+ label: list.name,
35
+ value: list.id,
36
+ }));
37
+
38
+ return {
39
+ disabled: false,
40
+ options,
41
+ };
42
+ },
43
+ }),
44
+ getUserLists: async (authProp: OAuth2PropertyValue) => {
45
+ const access_token = authProp.access_token;
46
+ const mailChimpServerPrefix =
47
+ await mailchimpCommon.getMailChimpServerPrefix(access_token!);
48
+ mailchimp.setConfig({
49
+ accessToken: access_token,
50
+ server: mailChimpServerPrefix,
51
+ });
52
+
53
+ // mailchimp types are not complete this is from the docs.
54
+ return await (mailchimp as any).lists.getAllLists({
55
+ fields: ['lists.id', 'lists.name', 'total_items'],
56
+ count: 1000,
57
+ });
58
+ },
59
+
60
+ mailChimpCampaignIdDropdown: Property.Dropdown<string,true,typeof mailchimpAuth >({
61
+ auth: mailchimpAuth,
62
+ displayName: 'Campaign',
63
+ refreshers: [],
64
+ description: 'Select the campaign to get information for',
65
+ required: true,
66
+ options: async ({ auth }) => {
67
+ if (!auth) {
68
+ return {
69
+ disabled: true,
70
+ options: [],
71
+ placeholder: 'Please select a connection',
72
+ };
73
+ }
74
+
75
+ const authProp = auth as OAuth2PropertyValue;
76
+ const campaignResponse = (await mailchimpCommon.getUserCampaigns(
77
+ authProp
78
+ )) as any;
79
+
80
+ const options = campaignResponse.campaigns.map((campaign: any) => ({
81
+ label: `${campaign.settings?.title || campaign.id} (${campaign.status})`,
82
+ value: campaign.id,
83
+ }));
84
+
85
+ return {
86
+ disabled: false,
87
+ options,
88
+ };
89
+ },
90
+ }),
91
+
92
+ getUserCampaigns: async (authProp: OAuth2PropertyValue, options?: { status?: string }) => {
93
+ const access_token = authProp.access_token;
94
+ const mailChimpServerPrefix =
95
+ await mailchimpCommon.getMailChimpServerPrefix(access_token!);
96
+ mailchimp.setConfig({
97
+ accessToken: access_token,
98
+ server: mailChimpServerPrefix,
99
+ });
100
+
101
+ // Get campaigns with essential fields for dropdown
102
+ return await (mailchimp as any).campaigns.list({
103
+ fields: ['campaigns.id', 'campaigns.settings.title', 'campaigns.status', 'total_items'],
104
+ count: 1000,
105
+ ...(options?.status ? { status: options.status } : {}),
106
+ });
107
+ },
108
+
109
+ mailChimpDraftCampaignIdDropdown: Property.Dropdown<string,true,typeof mailchimpAuth >({
110
+ auth: mailchimpAuth,
111
+ displayName: 'Campaign',
112
+ refreshers: [],
113
+ description: 'Select the draft campaign to send',
114
+ required: true,
115
+ options: async ({ auth }) => {
116
+ if (!auth) {
117
+ return {
118
+ disabled: true,
119
+ options: [],
120
+ placeholder: 'Please select a connection',
121
+ };
122
+ }
123
+
124
+ const authProp = auth as OAuth2PropertyValue;
125
+ // Mailchimp only accepts the send action on campaigns in "save" (draft) status.
126
+ const campaignResponse = (await mailchimpCommon.getUserCampaigns(
127
+ authProp,
128
+ { status: 'save' }
129
+ )) as any;
130
+
131
+ const options = campaignResponse.campaigns.map((campaign: any) => ({
132
+ label: `${campaign.settings?.title || campaign.id}`,
133
+ value: campaign.id,
134
+ }));
135
+
136
+ return {
137
+ disabled: false,
138
+ options,
139
+ };
140
+ },
141
+ }),
142
+
143
+ mailChimpStoreIdDropdown: Property.Dropdown<string,true,typeof mailchimpAuth >({
144
+ auth: mailchimpAuth,
145
+ displayName: 'Store',
146
+ refreshers: [],
147
+ description: 'Select the e-commerce store',
148
+ required: true,
149
+ options: async ({ auth }) => {
150
+ if (!auth) {
151
+ return {
152
+ disabled: true,
153
+ options: [],
154
+ placeholder: 'Please select a connection',
155
+ };
156
+ }
157
+
158
+ const authProp = auth as OAuth2PropertyValue;
159
+ const storeResponse = (await mailchimpCommon.getUserStores(
160
+ authProp
161
+ )) as any;
162
+
163
+ const options = storeResponse.stores.map((store: any) => ({
164
+ label: `${store.name} (${store.id})`,
165
+ value: store.id,
166
+ }));
167
+
168
+ return {
169
+ disabled: false,
170
+ options,
171
+ };
172
+ },
173
+ }),
174
+
175
+ getUserStores: async (authProp: OAuth2PropertyValue) => {
176
+ const access_token = authProp.access_token;
177
+ const mailChimpServerPrefix =
178
+ await mailchimpCommon.getMailChimpServerPrefix(access_token!);
179
+ mailchimp.setConfig({
180
+ accessToken: access_token,
181
+ server: mailChimpServerPrefix,
182
+ });
183
+
184
+ // Get stores with essential fields for dropdown
185
+ return await (mailchimp as any).ecommerce.stores({
186
+ fields: ['stores.id', 'stores.name', 'total_items'],
187
+ count: 1000,
188
+ });
189
+ },
190
+ getMailChimpServerPrefix: async (access_token: string) => {
191
+ const mailChimpMetaDataRequest: HttpRequest<{ dc: string }> = {
192
+ method: HttpMethod.GET,
193
+ url: 'https://login.mailchimp.com/oauth2/metadata',
194
+ headers: {
195
+ Authorization: `OAuth ${access_token}`,
196
+ },
197
+ };
198
+ return (await httpClient.sendRequest(mailChimpMetaDataRequest)).body['dc'];
199
+ },
200
+ enableWebhookRequest: async ({
201
+ server,
202
+ token,
203
+ listId,
204
+ webhookUrl,
205
+ events,
206
+ }: EnableTriggerRequestParams): Promise<string> => {
207
+ const response = await httpClient.sendRequest<EnableTriggerResponse>({
208
+ method: HttpMethod.POST,
209
+ url: `https://${server}.api.mailchimp.com/3.0/lists/${listId}/webhooks`,
210
+ authentication: {
211
+ type: AuthenticationType.BEARER_TOKEN,
212
+ token,
213
+ },
214
+ body: {
215
+ url: webhookUrl,
216
+ events,
217
+ sources: {
218
+ user: true,
219
+ admin: true,
220
+ api: true,
221
+ },
222
+ },
223
+ });
224
+
225
+ const { id: webhookId } = response.body;
226
+ return webhookId;
227
+ },
228
+ disableWebhookRequest: async ({
229
+ server,
230
+ token,
231
+ listId,
232
+ webhookId,
233
+ }: DisableTriggerRequestParams): Promise<void> => {
234
+ await httpClient.sendRequest<EnableTriggerResponse>({
235
+ method: HttpMethod.DELETE,
236
+ url: `https://${server}.api.mailchimp.com/3.0/lists/${listId}/webhooks/${webhookId}`,
237
+ authentication: {
238
+ type: AuthenticationType.BEARER_TOKEN,
239
+ token,
240
+ },
241
+ });
242
+ },
243
+ getMD5EmailHash: (email: string) => {
244
+ return crypto.createHash('md5').update(email.toLowerCase()).digest('hex');
245
+ },
246
+ };
247
+
248
+ type TriggerRequestParams = {
249
+ server: string;
250
+ token: string;
251
+ listId: string;
252
+ };
253
+
254
+ type EnableTriggerRequestParams = TriggerRequestParams & {
255
+ webhookUrl: string;
256
+ events: object;
257
+ };
258
+
259
+ type DisableTriggerRequestParams = TriggerRequestParams & {
260
+ webhookId: string;
261
+ };
262
+
263
+ type EnableTriggerResponse = {
264
+ id: string;
265
+ url: string;
266
+ list_id: string;
267
+ };