@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.
- package/LICENSE.MIT-AP +24 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +80 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/actions/add-member-to-list.d.ts +13 -0
- package/dist/lib/actions/add-member-to-list.d.ts.map +1 -0
- package/dist/lib/actions/add-member-to-list.js +172 -0
- package/dist/lib/actions/add-member-to-list.js.map +1 -0
- package/dist/lib/actions/add-note-to-subscriber.d.ts +6 -0
- package/dist/lib/actions/add-note-to-subscriber.d.ts.map +1 -0
- package/dist/lib/actions/add-note-to-subscriber.js +95 -0
- package/dist/lib/actions/add-note-to-subscriber.js.map +1 -0
- package/dist/lib/actions/add-subscriber-to-tag.d.ts +6 -0
- package/dist/lib/actions/add-subscriber-to-tag.d.ts.map +1 -0
- package/dist/lib/actions/add-subscriber-to-tag.js +65 -0
- package/dist/lib/actions/add-subscriber-to-tag.js.map +1 -0
- package/dist/lib/actions/archive-subscriber.d.ts +5 -0
- package/dist/lib/actions/archive-subscriber.d.ts.map +1 -0
- package/dist/lib/actions/archive-subscriber.js +66 -0
- package/dist/lib/actions/archive-subscriber.js.map +1 -0
- package/dist/lib/actions/create-audience.d.ts +23 -0
- package/dist/lib/actions/create-audience.d.ts.map +1 -0
- package/dist/lib/actions/create-audience.js +196 -0
- package/dist/lib/actions/create-audience.js.map +1 -0
- package/dist/lib/actions/create-campaign.d.ts +15 -0
- package/dist/lib/actions/create-campaign.d.ts.map +1 -0
- package/dist/lib/actions/create-campaign.js +157 -0
- package/dist/lib/actions/create-campaign.js.map +1 -0
- package/dist/lib/actions/create-custom-event.d.ts +7 -0
- package/dist/lib/actions/create-custom-event.d.ts.map +1 -0
- package/dist/lib/actions/create-custom-event.js +65 -0
- package/dist/lib/actions/create-custom-event.js.map +1 -0
- package/dist/lib/actions/create-tag.d.ts +5 -0
- package/dist/lib/actions/create-tag.d.ts.map +1 -0
- package/dist/lib/actions/create-tag.js +56 -0
- package/dist/lib/actions/create-tag.js.map +1 -0
- package/dist/lib/actions/find-campaign.d.ts +6 -0
- package/dist/lib/actions/find-campaign.d.ts.map +1 -0
- package/dist/lib/actions/find-campaign.js +70 -0
- package/dist/lib/actions/find-campaign.js.map +1 -0
- package/dist/lib/actions/find-customer.d.ts +9 -0
- package/dist/lib/actions/find-customer.d.ts.map +1 -0
- package/dist/lib/actions/find-customer.js +87 -0
- package/dist/lib/actions/find-customer.js.map +1 -0
- package/dist/lib/actions/find-subscriber.d.ts +7 -0
- package/dist/lib/actions/find-subscriber.d.ts.map +1 -0
- package/dist/lib/actions/find-subscriber.js +307 -0
- package/dist/lib/actions/find-subscriber.js.map +1 -0
- package/dist/lib/actions/find-tag.d.ts +5 -0
- package/dist/lib/actions/find-tag.d.ts.map +1 -0
- package/dist/lib/actions/find-tag.js +57 -0
- package/dist/lib/actions/find-tag.js.map +1 -0
- package/dist/lib/actions/get-campaign-report.d.ts +6 -0
- package/dist/lib/actions/get-campaign-report.d.ts.map +1 -0
- package/dist/lib/actions/get-campaign-report.js +206 -0
- package/dist/lib/actions/get-campaign-report.js.map +1 -0
- package/dist/lib/actions/remove-subscriber-from-tag.d.ts +6 -0
- package/dist/lib/actions/remove-subscriber-from-tag.d.ts.map +1 -0
- package/dist/lib/actions/remove-subscriber-from-tag.js +98 -0
- package/dist/lib/actions/remove-subscriber-from-tag.js.map +1 -0
- package/dist/lib/actions/send-campaign.d.ts +4 -0
- package/dist/lib/actions/send-campaign.d.ts.map +1 -0
- package/dist/lib/actions/send-campaign.js +47 -0
- package/dist/lib/actions/send-campaign.js.map +1 -0
- package/dist/lib/actions/unsubscribe-email.d.ts +8 -0
- package/dist/lib/actions/unsubscribe-email.d.ts.map +1 -0
- package/dist/lib/actions/unsubscribe-email.js +90 -0
- package/dist/lib/actions/unsubscribe-email.js.map +1 -0
- package/dist/lib/actions/update-subscriber-status.d.ts +6 -0
- package/dist/lib/actions/update-subscriber-status.d.ts.map +1 -0
- package/dist/lib/actions/update-subscriber-status.js +54 -0
- package/dist/lib/actions/update-subscriber-status.js.map +1 -0
- package/dist/lib/common/index.d.ts +30 -0
- package/dist/lib/common/index.d.ts.map +1 -0
- package/dist/lib/common/index.js +206 -0
- package/dist/lib/common/index.js.map +1 -0
- package/dist/lib/common/types.d.ts +362 -0
- package/dist/lib/common/types.d.ts.map +1 -0
- package/dist/lib/common/types.js +54 -0
- package/dist/lib/common/types.js.map +1 -0
- package/dist/lib/triggers/email-opened-trigger.d.ts +11 -0
- package/dist/lib/triggers/email-opened-trigger.d.ts.map +1 -0
- package/dist/lib/triggers/email-opened-trigger.js +199 -0
- package/dist/lib/triggers/email-opened-trigger.js.map +1 -0
- package/dist/lib/triggers/link-clicked-trigger.d.ts +11 -0
- package/dist/lib/triggers/link-clicked-trigger.d.ts.map +1 -0
- package/dist/lib/triggers/link-clicked-trigger.js +226 -0
- package/dist/lib/triggers/link-clicked-trigger.js.map +1 -0
- package/dist/lib/triggers/new-campaign-trigger.d.ts +11 -0
- package/dist/lib/triggers/new-campaign-trigger.d.ts.map +1 -0
- package/dist/lib/triggers/new-campaign-trigger.js +147 -0
- package/dist/lib/triggers/new-campaign-trigger.js.map +1 -0
- package/dist/lib/triggers/new-customer-trigger.d.ts +11 -0
- package/dist/lib/triggers/new-customer-trigger.d.ts.map +1 -0
- package/dist/lib/triggers/new-customer-trigger.js +214 -0
- package/dist/lib/triggers/new-customer-trigger.js.map +1 -0
- package/dist/lib/triggers/new-order-trigger.d.ts +11 -0
- package/dist/lib/triggers/new-order-trigger.d.ts.map +1 -0
- package/dist/lib/triggers/new-order-trigger.js +270 -0
- package/dist/lib/triggers/new-order-trigger.js.map +1 -0
- package/dist/lib/triggers/new-segment-tag-subscriber-trigger.d.ts +19 -0
- package/dist/lib/triggers/new-segment-tag-subscriber-trigger.d.ts.map +1 -0
- package/dist/lib/triggers/new-segment-tag-subscriber-trigger.js +264 -0
- package/dist/lib/triggers/new-segment-tag-subscriber-trigger.js.map +1 -0
- package/dist/lib/triggers/subscribe-trigger.d.ts +11 -0
- package/dist/lib/triggers/subscribe-trigger.d.ts.map +1 -0
- package/dist/lib/triggers/subscribe-trigger.js +150 -0
- package/dist/lib/triggers/subscribe-trigger.js.map +1 -0
- package/dist/lib/triggers/subscriber-updated-trigger.d.ts +11 -0
- package/dist/lib/triggers/subscriber-updated-trigger.d.ts.map +1 -0
- package/dist/lib/triggers/subscriber-updated-trigger.js +157 -0
- package/dist/lib/triggers/subscriber-updated-trigger.js.map +1 -0
- package/dist/lib/triggers/unsubscribe-trigger.d.ts +11 -0
- package/dist/lib/triggers/unsubscribe-trigger.d.ts.map +1 -0
- package/dist/lib/triggers/unsubscribe-trigger.js +196 -0
- package/dist/lib/triggers/unsubscribe-trigger.js.map +1 -0
- package/package.json +45 -3
- package/src/index.ts +77 -0
- package/src/lib/actions/add-member-to-list.ts +180 -0
- package/src/lib/actions/add-note-to-subscriber.ts +91 -0
- package/src/lib/actions/add-subscriber-to-tag.ts +66 -0
- package/src/lib/actions/archive-subscriber.ts +64 -0
- package/src/lib/actions/create-audience.ts +192 -0
- package/src/lib/actions/create-campaign.ts +155 -0
- package/src/lib/actions/create-custom-event.ts +63 -0
- package/src/lib/actions/create-tag.ts +51 -0
- package/src/lib/actions/find-campaign.ts +68 -0
- package/src/lib/actions/find-customer.ts +88 -0
- package/src/lib/actions/find-subscriber.ts +307 -0
- package/src/lib/actions/find-tag.ts +57 -0
- package/src/lib/actions/get-campaign-report.ts +204 -0
- package/src/lib/actions/remove-subscriber-from-tag.ts +94 -0
- package/src/lib/actions/send-campaign.ts +42 -0
- package/src/lib/actions/unsubscribe-email.ts +91 -0
- package/src/lib/actions/update-subscriber-status.ts +53 -0
- package/src/lib/common/index.ts +267 -0
- package/src/lib/common/types.ts +410 -0
- package/src/lib/triggers/email-opened-trigger.ts +216 -0
- package/src/lib/triggers/link-clicked-trigger.ts +244 -0
- package/src/lib/triggers/new-campaign-trigger.ts +149 -0
- package/src/lib/triggers/new-customer-trigger.ts +230 -0
- package/src/lib/triggers/new-order-trigger.ts +288 -0
- package/src/lib/triggers/new-segment-tag-subscriber-trigger.ts +286 -0
- package/src/lib/triggers/subscribe-trigger.ts +159 -0
- package/src/lib/triggers/subscriber-updated-trigger.ts +165 -0
- package/src/lib/triggers/unsubscribe-trigger.ts +212 -0
- package/README.md +0 -3
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { createAction, Property } from '@agnocon/pieces-framework';
|
|
2
|
+
import { getAccessTokenOrThrow } from '@agnocon/pieces-common';
|
|
3
|
+
import { mailchimpCommon } from '../common';
|
|
4
|
+
import { MailchimpClient } from '../common/types';
|
|
5
|
+
import { mailchimpAuth } from '../..';
|
|
6
|
+
import mailchimp from '@mailchimp/mailchimp_marketing';
|
|
7
|
+
|
|
8
|
+
export const addSubscriberToTag = createAction({
|
|
9
|
+
auth: mailchimpAuth,
|
|
10
|
+
name: 'add_subscriber_to_tag',
|
|
11
|
+
displayName: 'Add Subscriber to Tag',
|
|
12
|
+
description: 'Add a subscriber to a specific tag in your Mailchimp audience.',
|
|
13
|
+
audience: 'both',
|
|
14
|
+
aiMetadata: { description: 'Activates a tag on a subscriber, identified by email within a given audience (list); the tag is created if it does not already exist. Use to segment or label a contact. Idempotent: re-applying an already-active tag leaves the member state unchanged.', idempotent: true },
|
|
15
|
+
props: {
|
|
16
|
+
list_id: mailchimpCommon.mailChimpListIdDropdown,
|
|
17
|
+
email: Property.ShortText({
|
|
18
|
+
displayName: 'Email Address',
|
|
19
|
+
description: 'The email address of the subscriber to add to the tag',
|
|
20
|
+
required: true,
|
|
21
|
+
}),
|
|
22
|
+
tag_name: Property.ShortText({
|
|
23
|
+
displayName: 'Tag Name',
|
|
24
|
+
description: 'The name of the tag to add the subscriber to',
|
|
25
|
+
required: true,
|
|
26
|
+
}),
|
|
27
|
+
},
|
|
28
|
+
async run(context) {
|
|
29
|
+
const { list_id, email, tag_name } = context.propsValue;
|
|
30
|
+
const accessToken = getAccessTokenOrThrow(context.auth);
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const serverPrefix = await mailchimpCommon.getMailChimpServerPrefix(accessToken);
|
|
34
|
+
const subscriberHash = mailchimpCommon.getMD5EmailHash(email);
|
|
35
|
+
|
|
36
|
+
mailchimp.setConfig({
|
|
37
|
+
accessToken: accessToken,
|
|
38
|
+
server: serverPrefix,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const client = mailchimp as unknown as MailchimpClient;
|
|
42
|
+
|
|
43
|
+
const result = await client.lists.updateListMemberTags(
|
|
44
|
+
list_id as string,
|
|
45
|
+
subscriberHash,
|
|
46
|
+
{
|
|
47
|
+
tags: [
|
|
48
|
+
{
|
|
49
|
+
name: tag_name,
|
|
50
|
+
status: 'active',
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
success: true,
|
|
58
|
+
message: `Successfully added subscriber ${email} to tag ${tag_name}`,
|
|
59
|
+
data: result,
|
|
60
|
+
};
|
|
61
|
+
} catch (error: any) {
|
|
62
|
+
console.error('Error adding subscriber to tag:', error);
|
|
63
|
+
throw new Error(`Failed to add subscriber to tag: ${error.message}`);
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
import crypto from 'crypto';
|
|
8
|
+
|
|
9
|
+
export const archiveSubscriber = createAction({
|
|
10
|
+
auth: mailchimpAuth,
|
|
11
|
+
name: 'archive_subscriber',
|
|
12
|
+
displayName: 'Archive Subscriber',
|
|
13
|
+
description: 'Archive an existing audience member',
|
|
14
|
+
audience: 'both',
|
|
15
|
+
aiMetadata: { description: 'Archives a member from an audience (list); the identifier accepts an MD5 hash of the lowercase email, the raw email (auto-hashed), or a contact_id. Use to remove a contact from active sending while preserving their record. Idempotent: archiving an already-archived or absent member converges to the same state.', idempotent: true },
|
|
16
|
+
props: {
|
|
17
|
+
list_id: mailchimpCommon.mailChimpListIdDropdown,
|
|
18
|
+
subscriber_hash: Property.ShortText({
|
|
19
|
+
displayName: 'Subscriber Hash or Email',
|
|
20
|
+
description: 'MD5 hash of the lowercase email address, email address, or contact_id',
|
|
21
|
+
required: true,
|
|
22
|
+
}),
|
|
23
|
+
},
|
|
24
|
+
async run(context) {
|
|
25
|
+
const accessToken = getAccessTokenOrThrow(context.auth);
|
|
26
|
+
const server = await mailchimpCommon.getMailChimpServerPrefix(accessToken);
|
|
27
|
+
|
|
28
|
+
const client = mailchimp as unknown as MailchimpClient;
|
|
29
|
+
client.setConfig({
|
|
30
|
+
accessToken: accessToken,
|
|
31
|
+
server: server,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
let subscriberHash = context.propsValue.subscriber_hash;
|
|
36
|
+
|
|
37
|
+
// If it looks like an email, convert to MD5 hash
|
|
38
|
+
if (subscriberHash.includes('@')) {
|
|
39
|
+
subscriberHash = crypto.createHash('md5').update(subscriberHash.toLowerCase()).digest('hex');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
await client.lists.deleteListMember(context.propsValue.list_id!, subscriberHash);
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
success: true,
|
|
46
|
+
message: 'Subscriber archived successfully',
|
|
47
|
+
list_id: context.propsValue.list_id,
|
|
48
|
+
subscriber_hash: subscriberHash,
|
|
49
|
+
archived_at: new Date().toISOString(),
|
|
50
|
+
};
|
|
51
|
+
} catch (error: any) {
|
|
52
|
+
if (error.status === 404) {
|
|
53
|
+
return {
|
|
54
|
+
success: false,
|
|
55
|
+
error: 'Subscriber not found',
|
|
56
|
+
message: 'The subscriber could not be found in the specified list.',
|
|
57
|
+
detail: error.detail || 'The requested resource could not be found',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
throw new Error(`Failed to archive subscriber: ${error.message || JSON.stringify(error)}`);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
});
|
|
@@ -0,0 +1,192 @@
|
|
|
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 createAudience = createAction({
|
|
9
|
+
auth: mailchimpAuth,
|
|
10
|
+
name: 'create_audience',
|
|
11
|
+
displayName: 'Create Audience',
|
|
12
|
+
description: 'Create a new audience (list) in your Mailchimp account',
|
|
13
|
+
audience: 'both',
|
|
14
|
+
aiMetadata: { description: 'Creates a new audience (list) in the Mailchimp account, including the required physical contact address, permission reminder, and default campaign sender settings. Use to provision a brand-new list to hold subscribers. Not idempotent: each call creates a separate audience even with identical input.', idempotent: false },
|
|
15
|
+
props: {
|
|
16
|
+
name: Property.ShortText({
|
|
17
|
+
displayName: 'List Name',
|
|
18
|
+
description: 'The name of the list',
|
|
19
|
+
required: true,
|
|
20
|
+
}),
|
|
21
|
+
company: Property.ShortText({
|
|
22
|
+
displayName: 'Company',
|
|
23
|
+
description: 'Company name for list contact information',
|
|
24
|
+
required: true,
|
|
25
|
+
}),
|
|
26
|
+
address1: Property.ShortText({
|
|
27
|
+
displayName: 'Address Line 1',
|
|
28
|
+
description: 'Street address for list contact information',
|
|
29
|
+
required: true,
|
|
30
|
+
}),
|
|
31
|
+
address2: Property.ShortText({
|
|
32
|
+
displayName: 'Address Line 2',
|
|
33
|
+
description: 'Additional address information (optional)',
|
|
34
|
+
required: false,
|
|
35
|
+
}),
|
|
36
|
+
city: Property.ShortText({
|
|
37
|
+
displayName: 'City',
|
|
38
|
+
description: 'City for list contact information',
|
|
39
|
+
required: true,
|
|
40
|
+
}),
|
|
41
|
+
state: Property.ShortText({
|
|
42
|
+
displayName: 'State/Province',
|
|
43
|
+
description: 'State or province for list contact information',
|
|
44
|
+
required: false,
|
|
45
|
+
}),
|
|
46
|
+
zip: Property.ShortText({
|
|
47
|
+
displayName: 'ZIP/Postal Code',
|
|
48
|
+
description: 'ZIP or postal code for list contact information',
|
|
49
|
+
required: false,
|
|
50
|
+
}),
|
|
51
|
+
country: Property.ShortText({
|
|
52
|
+
displayName: 'Country',
|
|
53
|
+
description: 'Country for list contact information',
|
|
54
|
+
required: true,
|
|
55
|
+
}),
|
|
56
|
+
phone: Property.ShortText({
|
|
57
|
+
displayName: 'Phone',
|
|
58
|
+
description: 'Phone number for list contact information (optional)',
|
|
59
|
+
required: false,
|
|
60
|
+
}),
|
|
61
|
+
permission_reminder: Property.LongText({
|
|
62
|
+
displayName: 'Permission Reminder',
|
|
63
|
+
description: 'The permission reminder for the list',
|
|
64
|
+
required: true,
|
|
65
|
+
defaultValue: 'You are receiving this email because you signed up for updates from us.',
|
|
66
|
+
}),
|
|
67
|
+
from_name: Property.ShortText({
|
|
68
|
+
displayName: 'Default From Name',
|
|
69
|
+
description: 'Default from name for campaigns',
|
|
70
|
+
required: true,
|
|
71
|
+
}),
|
|
72
|
+
from_email: Property.ShortText({
|
|
73
|
+
displayName: 'Default From Email',
|
|
74
|
+
description: 'Default from email address for campaigns',
|
|
75
|
+
required: true,
|
|
76
|
+
}),
|
|
77
|
+
subject: Property.ShortText({
|
|
78
|
+
displayName: 'Default Subject',
|
|
79
|
+
description: 'Default subject line for campaigns',
|
|
80
|
+
required: true,
|
|
81
|
+
}),
|
|
82
|
+
language: Property.ShortText({
|
|
83
|
+
displayName: 'Language',
|
|
84
|
+
description: 'Default language for campaigns (e.g., "en", "es", "fr")',
|
|
85
|
+
required: true,
|
|
86
|
+
defaultValue: 'en',
|
|
87
|
+
}),
|
|
88
|
+
email_type_option: Property.Checkbox({
|
|
89
|
+
displayName: 'Email Type Option',
|
|
90
|
+
description: 'Whether the list supports multiple email formats (HTML/plain text)',
|
|
91
|
+
required: false,
|
|
92
|
+
defaultValue: true,
|
|
93
|
+
}),
|
|
94
|
+
use_archive_bar: Property.Checkbox({
|
|
95
|
+
displayName: 'Use Archive Bar',
|
|
96
|
+
description: 'Whether campaigns use the Archive Bar in archives by default',
|
|
97
|
+
required: false,
|
|
98
|
+
defaultValue: false,
|
|
99
|
+
}),
|
|
100
|
+
notify_on_subscribe: Property.ShortText({
|
|
101
|
+
displayName: 'Notify on Subscribe',
|
|
102
|
+
description: 'Email address to send subscribe notifications to (optional)',
|
|
103
|
+
required: false,
|
|
104
|
+
}),
|
|
105
|
+
notify_on_unsubscribe: Property.ShortText({
|
|
106
|
+
displayName: 'Notify on Unsubscribe',
|
|
107
|
+
description: 'Email address to send unsubscribe notifications to (optional)',
|
|
108
|
+
required: false,
|
|
109
|
+
}),
|
|
110
|
+
double_optin: Property.Checkbox({
|
|
111
|
+
displayName: 'Double Opt-in',
|
|
112
|
+
description: 'Whether to require subscriber confirmation via email',
|
|
113
|
+
required: false,
|
|
114
|
+
defaultValue: false,
|
|
115
|
+
}),
|
|
116
|
+
marketing_permissions: Property.Checkbox({
|
|
117
|
+
displayName: 'Marketing Permissions',
|
|
118
|
+
description: 'Whether the list has marketing permissions (GDPR) enabled',
|
|
119
|
+
required: false,
|
|
120
|
+
defaultValue: false,
|
|
121
|
+
}),
|
|
122
|
+
},
|
|
123
|
+
async run(context) {
|
|
124
|
+
const accessToken = getAccessTokenOrThrow(context.auth);
|
|
125
|
+
const server = await mailchimpCommon.getMailChimpServerPrefix(accessToken);
|
|
126
|
+
|
|
127
|
+
const client = mailchimp as unknown as MailchimpClient;
|
|
128
|
+
client.setConfig({
|
|
129
|
+
accessToken: accessToken,
|
|
130
|
+
server: server,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
try {
|
|
134
|
+
const listData = {
|
|
135
|
+
name: context.propsValue.name,
|
|
136
|
+
contact: {
|
|
137
|
+
company: context.propsValue.company,
|
|
138
|
+
address1: context.propsValue.address1,
|
|
139
|
+
address2: context.propsValue.address2 || '',
|
|
140
|
+
city: context.propsValue.city,
|
|
141
|
+
state: context.propsValue.state || '',
|
|
142
|
+
zip: context.propsValue.zip || '',
|
|
143
|
+
country: context.propsValue.country,
|
|
144
|
+
phone: context.propsValue.phone || '',
|
|
145
|
+
},
|
|
146
|
+
permission_reminder: context.propsValue.permission_reminder,
|
|
147
|
+
campaign_defaults: {
|
|
148
|
+
from_name: context.propsValue.from_name,
|
|
149
|
+
from_email: context.propsValue.from_email,
|
|
150
|
+
subject: context.propsValue.subject,
|
|
151
|
+
language: context.propsValue.language,
|
|
152
|
+
},
|
|
153
|
+
email_type_option: context.propsValue.email_type_option,
|
|
154
|
+
use_archive_bar: context.propsValue.use_archive_bar,
|
|
155
|
+
notify_on_subscribe: context.propsValue.notify_on_subscribe || '',
|
|
156
|
+
notify_on_unsubscribe: context.propsValue.notify_on_unsubscribe || '',
|
|
157
|
+
double_optin: context.propsValue.double_optin,
|
|
158
|
+
marketing_permissions: context.propsValue.marketing_permissions,
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const list = await client.lists.createList(listData);
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
success: true,
|
|
165
|
+
id: list.id,
|
|
166
|
+
web_id: list.web_id,
|
|
167
|
+
name: list.name,
|
|
168
|
+
contact: list.contact,
|
|
169
|
+
permission_reminder: list.permission_reminder,
|
|
170
|
+
use_archive_bar: list.use_archive_bar,
|
|
171
|
+
campaign_defaults: list.campaign_defaults,
|
|
172
|
+
notify_on_subscribe: list.notify_on_subscribe,
|
|
173
|
+
notify_on_unsubscribe: list.notify_on_unsubscribe,
|
|
174
|
+
date_created: list.date_created,
|
|
175
|
+
list_rating: list.list_rating,
|
|
176
|
+
email_type_option: list.email_type_option,
|
|
177
|
+
subscribe_url_short: list.subscribe_url_short,
|
|
178
|
+
subscribe_url_long: list.subscribe_url_long,
|
|
179
|
+
beamer_address: list.beamer_address,
|
|
180
|
+
visibility: list.visibility,
|
|
181
|
+
double_optin: list.double_optin,
|
|
182
|
+
has_welcome: list.has_welcome,
|
|
183
|
+
marketing_permissions: list.marketing_permissions,
|
|
184
|
+
modules: list.modules,
|
|
185
|
+
stats: list.stats,
|
|
186
|
+
_links: list._links,
|
|
187
|
+
};
|
|
188
|
+
} catch (error: any) {
|
|
189
|
+
throw new Error(`Failed to create list: ${error.message || JSON.stringify(error)}`);
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
});
|
|
@@ -0,0 +1,155 @@
|
|
|
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, CampaignCreateData, CampaignContentData } from '../common/types';
|
|
7
|
+
|
|
8
|
+
export const createCampaign = createAction({
|
|
9
|
+
auth: mailchimpAuth,
|
|
10
|
+
name: 'create_campaign',
|
|
11
|
+
displayName: 'Create Campaign',
|
|
12
|
+
description: 'Create a new Mailchimp campaign',
|
|
13
|
+
audience: 'both',
|
|
14
|
+
aiMetadata: { description: 'Creates a new draft campaign of a chosen type (regular, plain-text, A/B, RSS, or variate) targeting an audience (list), and optionally sets its content from inline HTML, a hosted URL, or a template depending on the selected content type. Use to set up a campaign for later sending; this does not send it. Not idempotent: each call creates a distinct campaign.', idempotent: false },
|
|
15
|
+
props: {
|
|
16
|
+
campaign_type: Property.StaticDropdown({
|
|
17
|
+
displayName: 'Campaign Type',
|
|
18
|
+
description: 'The type of campaign to create',
|
|
19
|
+
required: true,
|
|
20
|
+
options: {
|
|
21
|
+
options: [
|
|
22
|
+
{ label: 'Regular', value: 'regular' },
|
|
23
|
+
{ label: 'Plain Text', value: 'plaintext' },
|
|
24
|
+
{ label: 'A/B Test', value: 'ab' },
|
|
25
|
+
{ label: 'RSS', value: 'rss' },
|
|
26
|
+
{ label: 'Variate', value: 'variate' },
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
}),
|
|
30
|
+
list_id: mailchimpCommon.mailChimpListIdDropdown,
|
|
31
|
+
subject_line: Property.ShortText({
|
|
32
|
+
displayName: 'Subject Line',
|
|
33
|
+
description: 'The subject line for the campaign',
|
|
34
|
+
required: true,
|
|
35
|
+
}),
|
|
36
|
+
title: Property.ShortText({
|
|
37
|
+
displayName: 'Campaign Title',
|
|
38
|
+
description: 'The title of the campaign',
|
|
39
|
+
required: true,
|
|
40
|
+
}),
|
|
41
|
+
from_name: Property.ShortText({
|
|
42
|
+
displayName: 'From Name',
|
|
43
|
+
description: 'The name that will appear in the "From" field',
|
|
44
|
+
required: true,
|
|
45
|
+
}),
|
|
46
|
+
from_email: Property.ShortText({
|
|
47
|
+
displayName: 'From Email',
|
|
48
|
+
description: 'The email address that will appear in the "From" field',
|
|
49
|
+
required: true,
|
|
50
|
+
}),
|
|
51
|
+
reply_to: Property.ShortText({
|
|
52
|
+
displayName: 'Reply To Email',
|
|
53
|
+
description: 'The email address that will receive replies',
|
|
54
|
+
required: true,
|
|
55
|
+
}),
|
|
56
|
+
to_name: Property.ShortText({
|
|
57
|
+
displayName: 'To Name',
|
|
58
|
+
description: 'The name that will appear in the "To" field (e.g., *|FNAME|*)',
|
|
59
|
+
required: false,
|
|
60
|
+
}),
|
|
61
|
+
content_type: Property.StaticDropdown({
|
|
62
|
+
displayName: 'Content Type',
|
|
63
|
+
description: 'How the campaign content is put together',
|
|
64
|
+
required: true,
|
|
65
|
+
options: {
|
|
66
|
+
options: [
|
|
67
|
+
{ label: 'Template', value: 'template' },
|
|
68
|
+
{ label: 'HTML', value: 'html' },
|
|
69
|
+
{ label: 'URL', value: 'url' },
|
|
70
|
+
{ label: 'Multichannel', value: 'multichannel' },
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
}),
|
|
74
|
+
content_url: Property.ShortText({
|
|
75
|
+
displayName: 'Content URL',
|
|
76
|
+
description: 'The URL where the campaign content is hosted (required if content_type is "url")',
|
|
77
|
+
required: false,
|
|
78
|
+
}),
|
|
79
|
+
template_id: Property.ShortText({
|
|
80
|
+
displayName: 'Template ID',
|
|
81
|
+
description: 'The ID of the template to use (required if content_type is "template")',
|
|
82
|
+
required: false,
|
|
83
|
+
}),
|
|
84
|
+
html_content: Property.LongText({
|
|
85
|
+
displayName: 'HTML Content',
|
|
86
|
+
description: 'The HTML content for the campaign (required if content_type is "html")',
|
|
87
|
+
required: false,
|
|
88
|
+
}),
|
|
89
|
+
},
|
|
90
|
+
async run(context) {
|
|
91
|
+
const accessToken = getAccessTokenOrThrow(context.auth);
|
|
92
|
+
const server = await mailchimpCommon.getMailChimpServerPrefix(accessToken);
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
const client = mailchimp as unknown as MailchimpClient;
|
|
96
|
+
client.setConfig({
|
|
97
|
+
accessToken: accessToken,
|
|
98
|
+
server: server,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
const campaignData: CampaignCreateData = {
|
|
102
|
+
type: context.propsValue.campaign_type,
|
|
103
|
+
recipients: {
|
|
104
|
+
list_id: context.propsValue.list_id as string,
|
|
105
|
+
},
|
|
106
|
+
settings: {
|
|
107
|
+
subject_line: context.propsValue.subject_line,
|
|
108
|
+
title: context.propsValue.title,
|
|
109
|
+
from_name: context.propsValue.from_name,
|
|
110
|
+
from_email: context.propsValue.from_email,
|
|
111
|
+
reply_to: context.propsValue.reply_to,
|
|
112
|
+
to_name: context.propsValue.to_name || '',
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
const campaign = await client.campaigns.create(campaignData);
|
|
119
|
+
|
|
120
|
+
// Set campaign content based on content type
|
|
121
|
+
const contentData: CampaignContentData = {};
|
|
122
|
+
|
|
123
|
+
if (context.propsValue.content_type === 'html' && context.propsValue.html_content) {
|
|
124
|
+
contentData.html = context.propsValue.html_content;
|
|
125
|
+
} else if (context.propsValue.content_type === 'url' && context.propsValue.content_url) {
|
|
126
|
+
contentData.url = context.propsValue.content_url;
|
|
127
|
+
} else if (context.propsValue.content_type === 'template' && context.propsValue.template_id) {
|
|
128
|
+
contentData.template = {
|
|
129
|
+
id: context.propsValue.template_id,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Set content if any content data is provided
|
|
134
|
+
if (Object.keys(contentData).length > 0) {
|
|
135
|
+
await client.campaigns.setContent(campaign.id, contentData);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
success: true,
|
|
140
|
+
campaign_id: campaign.id,
|
|
141
|
+
campaign_web_id: campaign.web_id,
|
|
142
|
+
campaign_title: campaign.settings?.title,
|
|
143
|
+
campaign_subject: campaign.settings?.subject_line,
|
|
144
|
+
campaign_status: campaign.status,
|
|
145
|
+
campaign_type: campaign.type,
|
|
146
|
+
created_at: campaign.create_time,
|
|
147
|
+
archive_url: campaign.archive_url,
|
|
148
|
+
_links: campaign._links || [],
|
|
149
|
+
};
|
|
150
|
+
} catch (error: any) {
|
|
151
|
+
console.error('Error creating campaign:', error);
|
|
152
|
+
throw new Error(`Failed to create campaign: ${error.message || JSON.stringify(error)}`);
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
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 createCustomEvent = createAction({
|
|
9
|
+
auth: mailchimpAuth,
|
|
10
|
+
name: 'create_custom_event',
|
|
11
|
+
displayName: 'Create Custom Event',
|
|
12
|
+
description: 'Log a custom event for an existing subscriber, for use in automations and segmentation',
|
|
13
|
+
audience: 'both',
|
|
14
|
+
aiMetadata: { description: 'Records a named event (with optional properties) against an existing subscriber, identified by email, in an audience (list). Use to feed subscriber behavior into automations or segments. Not idempotent: each call logs a new, distinct event occurrence.', idempotent: false },
|
|
15
|
+
props: {
|
|
16
|
+
list_id: mailchimpCommon.mailChimpListIdDropdown,
|
|
17
|
+
email: Property.ShortText({
|
|
18
|
+
displayName: 'Email Address',
|
|
19
|
+
description: 'The email address of the subscriber to log the event for',
|
|
20
|
+
required: true,
|
|
21
|
+
}),
|
|
22
|
+
name: Property.ShortText({
|
|
23
|
+
displayName: 'Event Name',
|
|
24
|
+
description: 'The name of the event (lowercase letters, numbers, and underscores only, e.g. "purchased_item")',
|
|
25
|
+
required: true,
|
|
26
|
+
}),
|
|
27
|
+
properties: Property.Object({
|
|
28
|
+
displayName: 'Properties',
|
|
29
|
+
description: 'Optional key/value data to attach to the event',
|
|
30
|
+
required: false,
|
|
31
|
+
}),
|
|
32
|
+
},
|
|
33
|
+
async run(context) {
|
|
34
|
+
const { list_id, email, name, properties } = context.propsValue;
|
|
35
|
+
const accessToken = getAccessTokenOrThrow(context.auth);
|
|
36
|
+
const server = await mailchimpCommon.getMailChimpServerPrefix(accessToken);
|
|
37
|
+
const subscriberHash = mailchimpCommon.getMD5EmailHash(email);
|
|
38
|
+
|
|
39
|
+
const client = mailchimp as unknown as MailchimpClient;
|
|
40
|
+
client.setConfig({
|
|
41
|
+
accessToken: accessToken,
|
|
42
|
+
server: server,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
// Docs: https://mailchimp.com/developer/marketing/api/list-member-events/add-event/
|
|
47
|
+
await client.lists.createListMemberEvent(list_id as string, subscriberHash, {
|
|
48
|
+
name,
|
|
49
|
+
...(properties ? { properties } : {}),
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
success: true,
|
|
54
|
+
message: `Successfully created event "${name}" for ${email}`,
|
|
55
|
+
list_id,
|
|
56
|
+
email,
|
|
57
|
+
name,
|
|
58
|
+
};
|
|
59
|
+
} catch (error: any) {
|
|
60
|
+
throw new Error(`Failed to create custom event: ${error.message || JSON.stringify(error)}`);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
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 createTag = createAction({
|
|
9
|
+
auth: mailchimpAuth,
|
|
10
|
+
name: 'create_tag',
|
|
11
|
+
displayName: 'Create Tag',
|
|
12
|
+
description: 'Create a new tag in a Mailchimp audience',
|
|
13
|
+
audience: 'both',
|
|
14
|
+
aiMetadata: { description: 'Creates a new tag on an audience (list) so it can later be applied to subscribers. Use to set up a tag ahead of tagging contacts. Not idempotent: calling again with the same name creates a duplicate tag.', idempotent: false },
|
|
15
|
+
props: {
|
|
16
|
+
list_id: mailchimpCommon.mailChimpListIdDropdown,
|
|
17
|
+
name: Property.ShortText({
|
|
18
|
+
displayName: 'Tag Name',
|
|
19
|
+
description: 'The name of the tag to create',
|
|
20
|
+
required: true,
|
|
21
|
+
}),
|
|
22
|
+
},
|
|
23
|
+
async run(context) {
|
|
24
|
+
const { list_id, name } = context.propsValue;
|
|
25
|
+
const accessToken = getAccessTokenOrThrow(context.auth);
|
|
26
|
+
const server = await mailchimpCommon.getMailChimpServerPrefix(accessToken);
|
|
27
|
+
|
|
28
|
+
const client = mailchimp as unknown as MailchimpClient;
|
|
29
|
+
client.setConfig({
|
|
30
|
+
accessToken: accessToken,
|
|
31
|
+
server: server,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
// Tags are static segments with no members yet.
|
|
36
|
+
// Docs: https://mailchimp.com/developer/marketing/api/list-segments/add-segment/
|
|
37
|
+
const segment = await client.lists.createSegment(list_id as string, {
|
|
38
|
+
name,
|
|
39
|
+
static_segment: [],
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
success: true,
|
|
44
|
+
message: `Successfully created tag "${name}"`,
|
|
45
|
+
tag: segment,
|
|
46
|
+
};
|
|
47
|
+
} catch (error: any) {
|
|
48
|
+
throw new Error(`Failed to create tag: ${error.message || JSON.stringify(error)}`);
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
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, CampaignGetOptions } from '../common/types';
|
|
7
|
+
|
|
8
|
+
export const findCampaign = createAction({
|
|
9
|
+
auth: mailchimpAuth,
|
|
10
|
+
name: 'find_campaign',
|
|
11
|
+
displayName: 'Find Campaign',
|
|
12
|
+
description: 'Search all campaigns for the specified query terms',
|
|
13
|
+
audience: 'both',
|
|
14
|
+
aiMetadata: { description: 'Searches all campaigns in the account by a free-text query (matching titles, subject lines, and related fields) and returns the matches. Use to locate a campaign by name or wording before reading or acting on it. Read-only and idempotent; a query is required.', idempotent: true },
|
|
15
|
+
props: {
|
|
16
|
+
query: Property.ShortText({
|
|
17
|
+
displayName: 'Search Query',
|
|
18
|
+
description: 'Search terms to find campaigns',
|
|
19
|
+
required: true,
|
|
20
|
+
}),
|
|
21
|
+
fields: Property.LongText({
|
|
22
|
+
displayName: 'Fields',
|
|
23
|
+
description: 'Comma-separated list of fields to return',
|
|
24
|
+
required: false,
|
|
25
|
+
}),
|
|
26
|
+
exclude_fields: Property.LongText({
|
|
27
|
+
displayName: 'Exclude Fields',
|
|
28
|
+
description: 'Comma-separated list of fields to exclude',
|
|
29
|
+
required: false,
|
|
30
|
+
}),
|
|
31
|
+
},
|
|
32
|
+
async run(context) {
|
|
33
|
+
const accessToken = getAccessTokenOrThrow(context.auth);
|
|
34
|
+
const server = await mailchimpCommon.getMailChimpServerPrefix(accessToken);
|
|
35
|
+
|
|
36
|
+
const client = mailchimp as unknown as MailchimpClient;
|
|
37
|
+
client.setConfig({
|
|
38
|
+
accessToken: accessToken,
|
|
39
|
+
server: server,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
const searchParams: any = {
|
|
44
|
+
query: context.propsValue.query,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
if (context.propsValue.fields) {
|
|
48
|
+
searchParams.fields = context.propsValue.fields.split(',').map(f => f.trim());
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (context.propsValue.exclude_fields) {
|
|
52
|
+
searchParams.exclude_fields = context.propsValue.exclude_fields.split(',').map(f => f.trim());
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const searchResult = await client.searchCampaigns.search(searchParams);
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
success: true,
|
|
59
|
+
query: context.propsValue.query,
|
|
60
|
+
results: searchResult.results,
|
|
61
|
+
total_items: searchResult.total_items,
|
|
62
|
+
_links: searchResult._links,
|
|
63
|
+
};
|
|
64
|
+
} catch (error: any) {
|
|
65
|
+
throw new Error(`Failed to search campaigns: ${error.message || JSON.stringify(error)}`);
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
});
|