@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,88 @@
|
|
|
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 findCustomer = createAction({
|
|
9
|
+
auth: mailchimpAuth,
|
|
10
|
+
name: 'find_customer',
|
|
11
|
+
displayName: 'Find Customer',
|
|
12
|
+
description: 'Find a customer by email address in a store',
|
|
13
|
+
audience: 'both',
|
|
14
|
+
aiMetadata: { description: 'Looks up e-commerce customers in a specified connected store by email address, with optional pagination and field filtering. Use to retrieve a store customer record before referencing or syncing it. Requires a store and email; read-only and idempotent.', idempotent: true },
|
|
15
|
+
props: {
|
|
16
|
+
store_id: mailchimpCommon.mailChimpStoreIdDropdown,
|
|
17
|
+
email_address: Property.ShortText({
|
|
18
|
+
displayName: 'Email Address',
|
|
19
|
+
description: 'Email address to search for',
|
|
20
|
+
required: true,
|
|
21
|
+
}),
|
|
22
|
+
fields: Property.LongText({
|
|
23
|
+
displayName: 'Include Fields',
|
|
24
|
+
description: 'Comma-separated list of fields to return',
|
|
25
|
+
required: false,
|
|
26
|
+
}),
|
|
27
|
+
exclude_fields: Property.LongText({
|
|
28
|
+
displayName: 'Exclude Fields',
|
|
29
|
+
description: 'Comma-separated list of fields to exclude',
|
|
30
|
+
required: false,
|
|
31
|
+
}),
|
|
32
|
+
count: Property.Number({
|
|
33
|
+
displayName: 'Count',
|
|
34
|
+
description: 'Number of records to return (max 1000)',
|
|
35
|
+
required: false,
|
|
36
|
+
defaultValue: 10,
|
|
37
|
+
}),
|
|
38
|
+
offset: Property.Number({
|
|
39
|
+
displayName: 'Offset',
|
|
40
|
+
description: 'Number of records to skip for pagination',
|
|
41
|
+
required: false,
|
|
42
|
+
defaultValue: 0,
|
|
43
|
+
}),
|
|
44
|
+
},
|
|
45
|
+
async run(context) {
|
|
46
|
+
const accessToken = getAccessTokenOrThrow(context.auth);
|
|
47
|
+
const server = await mailchimpCommon.getMailChimpServerPrefix(accessToken);
|
|
48
|
+
|
|
49
|
+
const client = mailchimp as unknown as MailchimpClient;
|
|
50
|
+
client.setConfig({
|
|
51
|
+
accessToken: accessToken,
|
|
52
|
+
server: server,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
const options: any = {
|
|
57
|
+
email_address: context.propsValue.email_address,
|
|
58
|
+
count: context.propsValue.count || 10,
|
|
59
|
+
offset: context.propsValue.offset || 0,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
if (context.propsValue.fields) {
|
|
63
|
+
options.fields = context.propsValue.fields.split(',').map(f => f.trim());
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (context.propsValue.exclude_fields) {
|
|
67
|
+
options.exclude_fields = context.propsValue.exclude_fields.split(',').map(f => f.trim());
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const result = await client.ecommerce.getAllStoreCustomers(
|
|
71
|
+
context.propsValue.store_id!,
|
|
72
|
+
options
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
success: true,
|
|
77
|
+
store_id: result.store_id,
|
|
78
|
+
customers: result.customers,
|
|
79
|
+
total_items: result.total_items,
|
|
80
|
+
search_email: context.propsValue.email_address,
|
|
81
|
+
found_customers: result.customers.length,
|
|
82
|
+
_links: result._links,
|
|
83
|
+
};
|
|
84
|
+
} catch (error: any) {
|
|
85
|
+
throw new Error(`Failed to find customer: ${error.message || JSON.stringify(error)}`);
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
});
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { createAction, Property } from '@agnocon/pieces-framework';
|
|
2
|
+
import { mailchimpAuth } from '../..';
|
|
3
|
+
import { mailchimpCommon } from '../common';
|
|
4
|
+
import mailchimp from '@mailchimp/mailchimp_marketing';
|
|
5
|
+
|
|
6
|
+
export const findSubscriber = createAction({
|
|
7
|
+
auth: mailchimpAuth,
|
|
8
|
+
name: 'find_subscriber',
|
|
9
|
+
displayName: 'Find Subscriber',
|
|
10
|
+
description: 'Search for subscribers across all lists or within a specific list. This action provides comprehensive subscriber information including merge fields, interests, and activity data.',
|
|
11
|
+
audience: 'both',
|
|
12
|
+
aiMetadata: { description: 'Looks up a subscriber by exact email, returning merge fields, interests, and activity data: when an audience (list) is specified it checks that one list, and when left empty it searches every list in the account. Use to find a contact and inspect their profile or status. Requires the email; read-only and idempotent.', idempotent: true },
|
|
13
|
+
props: {
|
|
14
|
+
list_id: mailchimpCommon.mailChimpListIdDropdown,
|
|
15
|
+
email: Property.ShortText({
|
|
16
|
+
displayName: 'Email Address',
|
|
17
|
+
description: 'Email address of the subscriber to search for',
|
|
18
|
+
required: true,
|
|
19
|
+
}),
|
|
20
|
+
include_fields: Property.Array({
|
|
21
|
+
displayName: 'Include Fields',
|
|
22
|
+
description: 'Fields to include in the response (leave empty for all fields). Use dot notation for nested fields (e.g., "merge_fields.FNAME")',
|
|
23
|
+
required: false,
|
|
24
|
+
}),
|
|
25
|
+
exclude_fields: Property.Array({
|
|
26
|
+
displayName: 'Exclude Fields',
|
|
27
|
+
description: 'Fields to exclude from the response. Use dot notation for nested fields',
|
|
28
|
+
required: false,
|
|
29
|
+
}),
|
|
30
|
+
},
|
|
31
|
+
async run(context) {
|
|
32
|
+
const access_token = context.auth.access_token;
|
|
33
|
+
const mailChimpServerPrefix = await mailchimpCommon.getMailChimpServerPrefix(access_token);
|
|
34
|
+
|
|
35
|
+
mailchimp.setConfig({
|
|
36
|
+
accessToken: access_token,
|
|
37
|
+
server: mailChimpServerPrefix,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
const searchEmail = context.propsValue.email!;
|
|
42
|
+
const listId = context.propsValue.list_id;
|
|
43
|
+
|
|
44
|
+
const options: any = {};
|
|
45
|
+
|
|
46
|
+
if (context.propsValue.include_fields && context.propsValue.include_fields.length > 0) {
|
|
47
|
+
options.fields = context.propsValue.include_fields.join(',');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (context.propsValue.exclude_fields && context.propsValue.exclude_fields.length > 0) {
|
|
51
|
+
options.exclude_fields = context.propsValue.exclude_fields.join(',');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (listId) {
|
|
55
|
+
try {
|
|
56
|
+
const subscriberHash = mailchimpCommon.getMD5EmailHash(searchEmail);
|
|
57
|
+
const subscriber = await (mailchimp as any).lists.getListMember(listId, subscriberHash, options);
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
success: true,
|
|
61
|
+
found: true,
|
|
62
|
+
match_type: 'exact',
|
|
63
|
+
search_query: searchEmail,
|
|
64
|
+
search_scope: `List: ${listId}`,
|
|
65
|
+
total_matches: 1,
|
|
66
|
+
subscribers: [{
|
|
67
|
+
id: subscriber.id,
|
|
68
|
+
email_address: subscriber.email_address,
|
|
69
|
+
unique_email_id: subscriber.unique_email_id,
|
|
70
|
+
email_type: subscriber.email_type,
|
|
71
|
+
status: subscriber.status,
|
|
72
|
+
merge_fields: subscriber.merge_fields,
|
|
73
|
+
interests: subscriber.interests,
|
|
74
|
+
stats: subscriber.stats,
|
|
75
|
+
ip_signup: subscriber.ip_signup,
|
|
76
|
+
timestamp_signup: subscriber.timestamp_signup,
|
|
77
|
+
ip_opt: subscriber.ip_opt,
|
|
78
|
+
timestamp_opt: subscriber.timestamp_opt,
|
|
79
|
+
member_rating: subscriber.member_rating,
|
|
80
|
+
last_changed: subscriber.last_changed,
|
|
81
|
+
language: subscriber.language,
|
|
82
|
+
vip: subscriber.vip,
|
|
83
|
+
email_client: subscriber.email_client,
|
|
84
|
+
location: subscriber.location,
|
|
85
|
+
tags_count: subscriber.tags_count,
|
|
86
|
+
list_id: subscriber.list_id,
|
|
87
|
+
}],
|
|
88
|
+
primary_subscriber: {
|
|
89
|
+
id: subscriber.id,
|
|
90
|
+
email_address: subscriber.email_address,
|
|
91
|
+
status: subscriber.status,
|
|
92
|
+
list_id: subscriber.list_id,
|
|
93
|
+
full_name: subscriber.merge_fields?.FNAME && subscriber.merge_fields?.LNAME ?
|
|
94
|
+
`${subscriber.merge_fields.FNAME} ${subscriber.merge_fields.LNAME}` :
|
|
95
|
+
subscriber.merge_fields?.FNAME || subscriber.merge_fields?.LNAME || 'N/A',
|
|
96
|
+
company: subscriber.merge_fields?.COMPANY || 'N/A',
|
|
97
|
+
phone: subscriber.merge_fields?.PHONE || 'N/A',
|
|
98
|
+
member_since: subscriber.timestamp_signup ?
|
|
99
|
+
new Date(subscriber.timestamp_signup).toLocaleDateString() : 'N/A',
|
|
100
|
+
last_activity: subscriber.last_changed ?
|
|
101
|
+
new Date(subscriber.last_changed).toLocaleDateString() : 'N/A',
|
|
102
|
+
member_rating: subscriber.member_rating || 0,
|
|
103
|
+
vip_status: subscriber.vip ? 'VIP' : 'Standard',
|
|
104
|
+
email_type: subscriber.email_type || 'html',
|
|
105
|
+
language: subscriber.language || 'en',
|
|
106
|
+
},
|
|
107
|
+
search_summary: {
|
|
108
|
+
query: searchEmail,
|
|
109
|
+
scope: `Limited to list: ${listId}`,
|
|
110
|
+
exact_matches: 1,
|
|
111
|
+
partial_matches: 0,
|
|
112
|
+
total_results: 1,
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
} catch (listError: any) {
|
|
116
|
+
if (listError.status === 404) {
|
|
117
|
+
return {
|
|
118
|
+
success: true,
|
|
119
|
+
found: false,
|
|
120
|
+
match_type: 'none',
|
|
121
|
+
search_query: searchEmail,
|
|
122
|
+
search_scope: `List: ${listId}`,
|
|
123
|
+
message: `Subscriber with email "${searchEmail}" not found in the specified list`,
|
|
124
|
+
search_summary: {
|
|
125
|
+
query: searchEmail,
|
|
126
|
+
scope: `Limited to list: ${listId}`,
|
|
127
|
+
exact_matches: 0,
|
|
128
|
+
partial_matches: 0,
|
|
129
|
+
total_results: 0,
|
|
130
|
+
suggestions: [
|
|
131
|
+
'Verify the email address is spelled correctly',
|
|
132
|
+
'Check if the subscriber exists in a different list',
|
|
133
|
+
'Ensure the subscriber has not been unsubscribed or deleted',
|
|
134
|
+
'Try searching without specifying a list ID to search across all lists',
|
|
135
|
+
],
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
throw listError;
|
|
140
|
+
}
|
|
141
|
+
} else {
|
|
142
|
+
const allLists = await (mailchimp as any).lists.getAllLists({
|
|
143
|
+
fields: ['lists.id', 'lists.name'],
|
|
144
|
+
count: 1000,
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
const foundSubscribers: any[] = [];
|
|
148
|
+
const searchPromises = allLists.lists.map(async (list: any) => {
|
|
149
|
+
try {
|
|
150
|
+
const subscriberHash = mailchimpCommon.getMD5EmailHash(searchEmail);
|
|
151
|
+
const subscriber = await (mailchimp as any).lists.getListMember(list.id, subscriberHash, options);
|
|
152
|
+
|
|
153
|
+
return {
|
|
154
|
+
id: subscriber.id,
|
|
155
|
+
email_address: subscriber.email_address,
|
|
156
|
+
unique_email_id: subscriber.unique_email_id,
|
|
157
|
+
email_type: subscriber.email_type,
|
|
158
|
+
status: subscriber.status,
|
|
159
|
+
merge_fields: subscriber.merge_fields,
|
|
160
|
+
interests: subscriber.interests,
|
|
161
|
+
stats: subscriber.stats,
|
|
162
|
+
ip_signup: subscriber.ip_signup,
|
|
163
|
+
timestamp_signup: subscriber.timestamp_signup,
|
|
164
|
+
ip_opt: subscriber.ip_opt,
|
|
165
|
+
timestamp_opt: subscriber.timestamp_opt,
|
|
166
|
+
member_rating: subscriber.member_rating,
|
|
167
|
+
last_changed: subscriber.last_changed,
|
|
168
|
+
language: subscriber.language,
|
|
169
|
+
vip: subscriber.vip,
|
|
170
|
+
email_client: subscriber.email_client,
|
|
171
|
+
location: subscriber.location,
|
|
172
|
+
tags_count: subscriber.tags_count,
|
|
173
|
+
list_id: subscriber.list_id,
|
|
174
|
+
list_name: list.name,
|
|
175
|
+
};
|
|
176
|
+
} catch (error: any) {
|
|
177
|
+
if (error.status === 404) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
list_id: list.id,
|
|
182
|
+
list_name: list.name,
|
|
183
|
+
error: `Failed to check list: ${error.message}`,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
const results = await Promise.all(searchPromises);
|
|
189
|
+
const validSubscribers = results.filter(result => result && !result.error);
|
|
190
|
+
const errors = results.filter(result => result && result.error);
|
|
191
|
+
|
|
192
|
+
if (validSubscribers.length > 0) {
|
|
193
|
+
return {
|
|
194
|
+
success: true,
|
|
195
|
+
found: true,
|
|
196
|
+
match_type: 'exact',
|
|
197
|
+
search_query: searchEmail,
|
|
198
|
+
search_scope: 'All Lists',
|
|
199
|
+
total_matches: validSubscribers.length,
|
|
200
|
+
subscribers: validSubscribers,
|
|
201
|
+
primary_subscriber: {
|
|
202
|
+
id: validSubscribers[0].id,
|
|
203
|
+
email_address: validSubscribers[0].email_address,
|
|
204
|
+
status: validSubscribers[0].status,
|
|
205
|
+
list_id: validSubscribers[0].list_id,
|
|
206
|
+
list_name: validSubscribers[0].list_name,
|
|
207
|
+
full_name: validSubscribers[0].merge_fields?.FNAME && validSubscribers[0].merge_fields?.LNAME ?
|
|
208
|
+
`${validSubscribers[0].merge_fields.FNAME} ${validSubscribers[0].merge_fields.LNAME}` :
|
|
209
|
+
validSubscribers[0].merge_fields?.FNAME || validSubscribers[0].merge_fields?.LNAME || 'N/A',
|
|
210
|
+
company: validSubscribers[0].merge_fields?.COMPANY || 'N/A',
|
|
211
|
+
phone: validSubscribers[0].merge_fields?.PHONE || 'N/A',
|
|
212
|
+
member_since: validSubscribers[0].timestamp_signup ?
|
|
213
|
+
new Date(validSubscribers[0].timestamp_signup).toLocaleDateString() : 'N/A',
|
|
214
|
+
last_activity: validSubscribers[0].last_changed ?
|
|
215
|
+
new Date(validSubscribers[0].last_changed).toLocaleDateString() : 'N/A',
|
|
216
|
+
member_rating: validSubscribers[0].member_rating || 0,
|
|
217
|
+
vip_status: validSubscribers[0].vip ? 'VIP' : 'Standard',
|
|
218
|
+
email_type: validSubscribers[0].email_type || 'html',
|
|
219
|
+
language: validSubscribers[0].language || 'en',
|
|
220
|
+
},
|
|
221
|
+
search_summary: {
|
|
222
|
+
query: searchEmail,
|
|
223
|
+
scope: 'Searched across all lists',
|
|
224
|
+
exact_matches: validSubscribers.length,
|
|
225
|
+
partial_matches: 0,
|
|
226
|
+
total_results: validSubscribers.length,
|
|
227
|
+
lists_searched: allLists.lists.length,
|
|
228
|
+
search_errors: errors.length > 0 ? errors : undefined,
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
} else {
|
|
232
|
+
return {
|
|
233
|
+
success: true,
|
|
234
|
+
found: false,
|
|
235
|
+
match_type: 'none',
|
|
236
|
+
search_query: searchEmail,
|
|
237
|
+
search_scope: 'All Lists',
|
|
238
|
+
message: `No subscribers found matching the email: ${searchEmail}`,
|
|
239
|
+
search_summary: {
|
|
240
|
+
query: searchEmail,
|
|
241
|
+
scope: 'Searched across all lists',
|
|
242
|
+
exact_matches: 0,
|
|
243
|
+
partial_matches: 0,
|
|
244
|
+
total_results: 0,
|
|
245
|
+
lists_searched: allLists.lists.length,
|
|
246
|
+
search_errors: errors.length > 0 ? errors : undefined,
|
|
247
|
+
suggestions: [
|
|
248
|
+
'Verify the email address is spelled correctly',
|
|
249
|
+
'Check if the subscriber exists in a different list',
|
|
250
|
+
'Ensure the subscriber has not been unsubscribed or deleted',
|
|
251
|
+
'Consider checking if the email was entered with different capitalization',
|
|
252
|
+
'Verify the subscriber is not in an archived or deleted list',
|
|
253
|
+
],
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
} catch (error: any) {
|
|
259
|
+
if (error.status === 400) {
|
|
260
|
+
return {
|
|
261
|
+
success: false,
|
|
262
|
+
error: 'Invalid search request',
|
|
263
|
+
message: 'The search request was invalid. This could be due to malformed search parameters or invalid list ID.',
|
|
264
|
+
detail: error.detail || 'Bad request',
|
|
265
|
+
suggestions: [
|
|
266
|
+
'Verify the email address format is correct',
|
|
267
|
+
'Check that the list ID (if provided) is valid',
|
|
268
|
+
'Ensure all required parameters are provided',
|
|
269
|
+
'Validate the field names in include/exclude fields',
|
|
270
|
+
],
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (error.status === 403) {
|
|
275
|
+
return {
|
|
276
|
+
success: false,
|
|
277
|
+
error: 'Access denied',
|
|
278
|
+
message: 'You do not have permission to search for subscribers. Check your API key permissions.',
|
|
279
|
+
detail: error.detail || 'Forbidden',
|
|
280
|
+
suggestions: [
|
|
281
|
+
'Verify your API key has the necessary permissions',
|
|
282
|
+
'Check that you have access to the specified list (if provided)',
|
|
283
|
+
'Ensure your account is active and in good standing',
|
|
284
|
+
'Confirm you have subscriber read permissions enabled',
|
|
285
|
+
],
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (error.status === 404 && context.propsValue.list_id) {
|
|
290
|
+
return {
|
|
291
|
+
success: false,
|
|
292
|
+
error: 'List not found',
|
|
293
|
+
message: `The list with ID "${context.propsValue.list_id}" could not be found.`,
|
|
294
|
+
detail: error.detail || 'The requested resource could not be found',
|
|
295
|
+
suggestions: [
|
|
296
|
+
'Verify the list ID is correct and exists in your Mailchimp account',
|
|
297
|
+
'Check that you have access to the specified list',
|
|
298
|
+
'Ensure the list has not been deleted or archived',
|
|
299
|
+
'Try searching without specifying a list ID to search across all lists',
|
|
300
|
+
],
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
throw new Error(`Failed to search for subscriber: ${error.message || JSON.stringify(error)}`);
|
|
305
|
+
}
|
|
306
|
+
},
|
|
307
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
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 findTag = createAction({
|
|
9
|
+
auth: mailchimpAuth,
|
|
10
|
+
name: 'find_tag',
|
|
11
|
+
displayName: 'Find Tag',
|
|
12
|
+
description: 'Search for tags on a list by name',
|
|
13
|
+
audience: 'both',
|
|
14
|
+
aiMetadata: { description: 'Searches the tags defined on an audience (list): an empty tag-name fetches all tags, while a provided name filters to matching tags. Use to discover available tags or confirm a tag exists before tagging contacts. Requires the target list; read-only and idempotent.', idempotent: true },
|
|
15
|
+
props: {
|
|
16
|
+
list_id: mailchimpCommon.mailChimpListIdDropdown,
|
|
17
|
+
name: Property.ShortText({
|
|
18
|
+
displayName: 'Tag Name',
|
|
19
|
+
description: 'Search query to filter tags (optional - if empty, returns all tags)',
|
|
20
|
+
required: false,
|
|
21
|
+
}),
|
|
22
|
+
},
|
|
23
|
+
async run(context) {
|
|
24
|
+
const accessToken = getAccessTokenOrThrow(context.auth);
|
|
25
|
+
const server = await mailchimpCommon.getMailChimpServerPrefix(accessToken);
|
|
26
|
+
|
|
27
|
+
const client = mailchimp as unknown as MailchimpClient;
|
|
28
|
+
client.setConfig({
|
|
29
|
+
accessToken: accessToken,
|
|
30
|
+
server: server,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
const options: any = {};
|
|
35
|
+
|
|
36
|
+
if (context.propsValue.name) {
|
|
37
|
+
options.name = context.propsValue.name;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const result = await client.lists.tagSearch(
|
|
41
|
+
context.propsValue.list_id!,
|
|
42
|
+
options
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
success: true,
|
|
47
|
+
list_id: context.propsValue.list_id,
|
|
48
|
+
search_query: context.propsValue.name || 'All tags',
|
|
49
|
+
tags: result.tags,
|
|
50
|
+
total_items: result.total_items,
|
|
51
|
+
found_tags: result.tags.length,
|
|
52
|
+
};
|
|
53
|
+
} catch (error: any) {
|
|
54
|
+
throw new Error(`Failed to find tag: ${error.message || JSON.stringify(error)}`);
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
});
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { createAction, Property } from '@agnocon/pieces-framework';
|
|
2
|
+
import { getAccessTokenOrThrow } from '@agnocon/pieces-common';
|
|
3
|
+
import { mailchimpAuth } from '../..';
|
|
4
|
+
import { mailchimpCommon } from '../common';
|
|
5
|
+
import mailchimp from '@mailchimp/mailchimp_marketing';
|
|
6
|
+
import { MailchimpClient, CampaignReportOptions } from '../common/types';
|
|
7
|
+
|
|
8
|
+
export const getCampaignReport = createAction({
|
|
9
|
+
auth: mailchimpAuth,
|
|
10
|
+
name: 'get_campaign_report',
|
|
11
|
+
displayName: 'Get Campaign Report',
|
|
12
|
+
description: 'Get comprehensive report details for a specific sent campaign including opens, clicks, bounces, and performance metrics',
|
|
13
|
+
audience: 'both',
|
|
14
|
+
aiMetadata: { description: 'Retrieves the analytics report for a single sent campaign by campaign ID, covering opens, clicks, bounces, unsubscribes, and engagement metrics; optional field include/exclude lists narrow the payload. Use to read performance for a campaign that has already been sent. Read-only and idempotent. Returns a not-found result if the campaign has not been sent or the ID is wrong.', idempotent: true },
|
|
15
|
+
props: {
|
|
16
|
+
campaign_id: mailchimpCommon.mailChimpCampaignIdDropdown,
|
|
17
|
+
fields: Property.LongText({
|
|
18
|
+
displayName: 'Include Fields',
|
|
19
|
+
description: 'Comma-separated list of fields to return (e.g., "opens.unique_opens,clicks.click_rate")',
|
|
20
|
+
required: false,
|
|
21
|
+
}),
|
|
22
|
+
exclude_fields: Property.LongText({
|
|
23
|
+
displayName: 'Exclude Fields',
|
|
24
|
+
description: 'Comma-separated list of fields to exclude (e.g., "timeseries,_links")',
|
|
25
|
+
required: false,
|
|
26
|
+
}),
|
|
27
|
+
},
|
|
28
|
+
async run(context) {
|
|
29
|
+
const accessToken = getAccessTokenOrThrow(context.auth);
|
|
30
|
+
const server = await mailchimpCommon.getMailChimpServerPrefix(accessToken);
|
|
31
|
+
|
|
32
|
+
const client = mailchimp as unknown as MailchimpClient;
|
|
33
|
+
client.setConfig({
|
|
34
|
+
accessToken: accessToken,
|
|
35
|
+
server: server,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const options: CampaignReportOptions = {};
|
|
40
|
+
|
|
41
|
+
if (context.propsValue.fields && context.propsValue.fields.trim()) {
|
|
42
|
+
options.fields = context.propsValue.fields.trim();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (context.propsValue.exclude_fields && context.propsValue.exclude_fields.trim()) {
|
|
46
|
+
options.exclude_fields = context.propsValue.exclude_fields.trim();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const report = await client.reports.getCampaignReport(context.propsValue.campaign_id!, options);
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
success: true,
|
|
53
|
+
report: {
|
|
54
|
+
id: report.id,
|
|
55
|
+
campaign_title: report.campaign_title,
|
|
56
|
+
type: report.type,
|
|
57
|
+
list_id: report.list_id,
|
|
58
|
+
list_is_active: report.list_is_active,
|
|
59
|
+
list_name: report.list_name,
|
|
60
|
+
subject_line: report.subject_line,
|
|
61
|
+
preview_text: report.preview_text,
|
|
62
|
+
emails_sent: report.emails_sent,
|
|
63
|
+
abuse_reports: report.abuse_reports,
|
|
64
|
+
unsubscribed: report.unsubscribed,
|
|
65
|
+
send_time: report.send_time,
|
|
66
|
+
rss_last_send: report.rss_last_send,
|
|
67
|
+
bounces: report.bounces,
|
|
68
|
+
forwards: report.forwards,
|
|
69
|
+
opens: report.opens,
|
|
70
|
+
clicks: report.clicks,
|
|
71
|
+
facebook_likes: report.facebook_likes,
|
|
72
|
+
industry_stats: report.industry_stats,
|
|
73
|
+
list_stats: report.list_stats,
|
|
74
|
+
ab_split: report.ab_split,
|
|
75
|
+
timewarp: report.timewarp,
|
|
76
|
+
timeseries: report.timeseries,
|
|
77
|
+
share_report: report.share_report,
|
|
78
|
+
ecommerce: report.ecommerce,
|
|
79
|
+
delivery_status: report.delivery_status,
|
|
80
|
+
_links: report._links,
|
|
81
|
+
},
|
|
82
|
+
summary: {
|
|
83
|
+
campaign_title: report.campaign_title,
|
|
84
|
+
subject_line: report.subject_line,
|
|
85
|
+
emails_sent: report.emails_sent,
|
|
86
|
+
unique_opens: report.opens?.unique_opens || 0,
|
|
87
|
+
unique_clicks: report.clicks?.unique_clicks || 0,
|
|
88
|
+
open_rate: report.opens?.open_rate || 0,
|
|
89
|
+
click_rate: report.clicks?.click_rate || 0,
|
|
90
|
+
bounce_rate: report.bounces ? ((report.bounces.hard_bounces + report.bounces.soft_bounces) / report.emails_sent * 100) : 0,
|
|
91
|
+
unsub_rate: report.unsubscribed ? (report.unsubscribed / report.emails_sent * 100) : 0,
|
|
92
|
+
abuse_rate: report.abuse_reports ? (report.abuse_reports / report.emails_sent * 100) : 0,
|
|
93
|
+
},
|
|
94
|
+
performance_metrics: {
|
|
95
|
+
opens: {
|
|
96
|
+
total: report.opens?.opens_total || 0,
|
|
97
|
+
unique: report.opens?.unique_opens || 0,
|
|
98
|
+
rate: report.opens?.open_rate || 0,
|
|
99
|
+
last_open: report.opens?.last_open,
|
|
100
|
+
proxy_excluded: {
|
|
101
|
+
total: report.opens?.proxy_excluded_opens || 0,
|
|
102
|
+
unique: report.opens?.proxy_excluded_unique_opens || 0,
|
|
103
|
+
rate: report.opens?.proxy_excluded_open_rate || 0,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
clicks: {
|
|
107
|
+
total: report.clicks?.clicks_total || 0,
|
|
108
|
+
unique: report.clicks?.unique_clicks || 0,
|
|
109
|
+
unique_subscribers: report.clicks?.unique_subscriber_clicks || 0,
|
|
110
|
+
rate: report.clicks?.click_rate || 0,
|
|
111
|
+
last_click: report.clicks?.last_click,
|
|
112
|
+
},
|
|
113
|
+
bounces: {
|
|
114
|
+
hard: report.bounces?.hard_bounces || 0,
|
|
115
|
+
soft: report.bounces?.soft_bounces || 0,
|
|
116
|
+
syntax_errors: report.bounces?.syntax_errors || 0,
|
|
117
|
+
total: (report.bounces?.hard_bounces || 0) + (report.bounces?.soft_bounces || 0) + (report.bounces?.syntax_errors || 0),
|
|
118
|
+
},
|
|
119
|
+
engagement: {
|
|
120
|
+
forwards: {
|
|
121
|
+
count: report.forwards?.forwards_count || 0,
|
|
122
|
+
opens: report.forwards?.forwards_opens || 0,
|
|
123
|
+
},
|
|
124
|
+
facebook_likes: {
|
|
125
|
+
recipient_likes: report.facebook_likes?.recipient_likes || 0,
|
|
126
|
+
unique_likes: report.facebook_likes?.unique_likes || 0,
|
|
127
|
+
facebook_likes: report.facebook_likes?.facebook_likes || 0,
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
industry_comparison: report.industry_stats ? {
|
|
132
|
+
industry_type: report.industry_stats.type,
|
|
133
|
+
open_rate: report.industry_stats.open_rate,
|
|
134
|
+
click_rate: report.industry_stats.click_rate,
|
|
135
|
+
bounce_rate: report.industry_stats.bounce_rate,
|
|
136
|
+
unopen_rate: report.industry_stats.unopen_rate,
|
|
137
|
+
unsub_rate: report.industry_stats.unsub_rate,
|
|
138
|
+
abuse_rate: report.industry_stats.abuse_rate,
|
|
139
|
+
} : null,
|
|
140
|
+
list_performance: report.list_stats ? {
|
|
141
|
+
subscription_rate: report.list_stats.sub_rate,
|
|
142
|
+
unsubscription_rate: report.list_stats.unsub_rate,
|
|
143
|
+
open_rate: report.list_stats.open_rate,
|
|
144
|
+
proxy_excluded_open_rate: report.list_stats.proxy_excluded_open_rate,
|
|
145
|
+
click_rate: report.list_stats.click_rate,
|
|
146
|
+
} : null,
|
|
147
|
+
ecommerce_data: report.ecommerce ? {
|
|
148
|
+
total_orders: report.ecommerce.total_orders,
|
|
149
|
+
total_spent: report.ecommerce.total_spent,
|
|
150
|
+
total_revenue: report.ecommerce.total_revenue,
|
|
151
|
+
currency_code: report.ecommerce.currency_code,
|
|
152
|
+
} : null,
|
|
153
|
+
delivery_status: report.delivery_status ? {
|
|
154
|
+
enabled: report.delivery_status.enabled,
|
|
155
|
+
can_cancel: report.delivery_status.can_cancel,
|
|
156
|
+
status: report.delivery_status.status,
|
|
157
|
+
emails_sent: report.delivery_status.emails_sent,
|
|
158
|
+
emails_canceled: report.delivery_status.emails_canceled,
|
|
159
|
+
} : null,
|
|
160
|
+
ab_split_data: report.ab_split ? {
|
|
161
|
+
group_a: {
|
|
162
|
+
bounces: report.ab_split.a?.bounces || 0,
|
|
163
|
+
abuse_reports: report.ab_split.a?.abuse_reports || 0,
|
|
164
|
+
unsubs: report.ab_split.a?.unsubs || 0,
|
|
165
|
+
recipient_clicks: report.ab_split.a?.recipient_clicks || 0,
|
|
166
|
+
forwards: report.ab_split.a?.forwards || 0,
|
|
167
|
+
forwards_opens: report.ab_split.a?.forwards_opens || 0,
|
|
168
|
+
opens: report.ab_split.a?.opens || 0,
|
|
169
|
+
last_open: report.ab_split.a?.last_open,
|
|
170
|
+
unique_opens: report.ab_split.a?.unique_opens || 0,
|
|
171
|
+
},
|
|
172
|
+
group_b: {
|
|
173
|
+
bounces: report.ab_split.b?.bounces || 0,
|
|
174
|
+
abuse_reports: report.ab_split.b?.abuse_reports || 0,
|
|
175
|
+
unsubs: report.ab_split.b?.unsubs || 0,
|
|
176
|
+
recipient_clicks: report.ab_split.b?.recipient_clicks || 0,
|
|
177
|
+
forwards: report.ab_split.b?.forwards || 0,
|
|
178
|
+
forwards_opens: report.ab_split.b?.forwards_opens || 0,
|
|
179
|
+
opens: report.ab_split.b?.opens || 0,
|
|
180
|
+
last_open: report.ab_split.b?.last_open,
|
|
181
|
+
unique_opens: report.ab_split.b?.unique_opens || 0,
|
|
182
|
+
},
|
|
183
|
+
} : null,
|
|
184
|
+
timewarp_data: report.timewarp || [],
|
|
185
|
+
timeseries_data: report.timeseries || [],
|
|
186
|
+
share_report: report.share_report ? {
|
|
187
|
+
share_url: report.share_report.share_url,
|
|
188
|
+
share_password: report.share_report.share_password,
|
|
189
|
+
} : null,
|
|
190
|
+
};
|
|
191
|
+
} catch (error: any) {
|
|
192
|
+
if (error.status === 404) {
|
|
193
|
+
return {
|
|
194
|
+
success: false,
|
|
195
|
+
error: 'Campaign report not found',
|
|
196
|
+
message: 'The requested campaign report could not be found. Make sure the campaign has been sent and the campaign ID is correct.',
|
|
197
|
+
detail: error.detail || 'The requested resource could not be found',
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
throw new Error(`Failed to get campaign report: ${error.message || JSON.stringify(error)}`);
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
});
|