@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,288 @@
|
|
|
1
|
+
import { createTrigger, TriggerStrategy, Property } from '@agnocon/pieces-framework';
|
|
2
|
+
import { getAccessTokenOrThrow } from '@agnocon/pieces-common';
|
|
3
|
+
import { mailchimpCommon } from '../common';
|
|
4
|
+
import { mailchimpAuth } from '../..';
|
|
5
|
+
|
|
6
|
+
const WEBHOOK_DATA_STORE_KEY = 'mail_chimp_new_order_webhook_data';
|
|
7
|
+
|
|
8
|
+
type WebhookData = {
|
|
9
|
+
id: string;
|
|
10
|
+
storeId: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const getNewOrderEventSummary = (request: any): any => {
|
|
14
|
+
const data = request.data || {};
|
|
15
|
+
return {
|
|
16
|
+
order_id: data.order_id || data.id || 'N/A',
|
|
17
|
+
store_id: data.store_id || 'N/A',
|
|
18
|
+
customer_id: data.customer_id || 'N/A',
|
|
19
|
+
customer_email: data.customer_email || 'N/A',
|
|
20
|
+
order_total: data.order_total || 0,
|
|
21
|
+
currency: data.currency || 'USD',
|
|
22
|
+
order_status: data.order_status || 'pending',
|
|
23
|
+
created_at: data.created_at || request.fired_at || 'N/A',
|
|
24
|
+
items_count: data.items_count || 0,
|
|
25
|
+
shipping_total: data.shipping_total || 0,
|
|
26
|
+
tax_total: data.tax_total || 0,
|
|
27
|
+
discount_total: data.discount_total || 0,
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const extractOrderItems = (items: any[]): any => {
|
|
32
|
+
if (!items || !Array.isArray(items)) return [];
|
|
33
|
+
|
|
34
|
+
return items.map(item => ({
|
|
35
|
+
product_id: item.product_id || 'N/A',
|
|
36
|
+
product_title: item.product_title || 'N/A',
|
|
37
|
+
product_variant_id: item.product_variant_id || 'N/A',
|
|
38
|
+
quantity: item.quantity || 1,
|
|
39
|
+
price: item.price || 0,
|
|
40
|
+
total: item.total || 0,
|
|
41
|
+
category: item.category || 'N/A',
|
|
42
|
+
tags: item.tags || [],
|
|
43
|
+
}));
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const extractOrderAddress = (address: any): any => {
|
|
47
|
+
if (!address) return null;
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
street_address: {
|
|
51
|
+
primary: address.address1 || 'N/A',
|
|
52
|
+
secondary: address.address2 || 'N/A',
|
|
53
|
+
},
|
|
54
|
+
city: address.city || 'N/A',
|
|
55
|
+
state_province: {
|
|
56
|
+
name: address.province || 'N/A',
|
|
57
|
+
code: address.province_code || 'N/A',
|
|
58
|
+
},
|
|
59
|
+
postal_code: address.postal_code || 'N/A',
|
|
60
|
+
country: {
|
|
61
|
+
name: address.country || 'N/A',
|
|
62
|
+
code: address.country_code || 'N/A',
|
|
63
|
+
},
|
|
64
|
+
full_address: [
|
|
65
|
+
address.address1,
|
|
66
|
+
address.address2,
|
|
67
|
+
address.city,
|
|
68
|
+
address.province,
|
|
69
|
+
address.postal_code,
|
|
70
|
+
address.country,
|
|
71
|
+
].filter(Boolean).join(', '),
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const assessOrderValue = (data: any): string => {
|
|
76
|
+
const orderTotal = data.order_total || 0;
|
|
77
|
+
|
|
78
|
+
if (orderTotal >= 500) return 'High Value';
|
|
79
|
+
if (orderTotal >= 100) return 'Medium Value';
|
|
80
|
+
if (orderTotal >= 50) return 'Standard Value';
|
|
81
|
+
return 'Low Value';
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const identifyOrderOpportunities = (data: any): string[] => {
|
|
85
|
+
const opportunities = [];
|
|
86
|
+
|
|
87
|
+
if (data.order_status === 'fulfilled') {
|
|
88
|
+
opportunities.push('Order fulfilled - follow-up opportunity');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (data.order_status === 'shipped') {
|
|
92
|
+
opportunities.push('Order shipped - delivery tracking opportunity');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (data.items_count > 1) {
|
|
96
|
+
opportunities.push('Multiple items - cross-sell opportunity');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (data.order_total > 100) {
|
|
100
|
+
opportunities.push('High-value order - VIP treatment opportunity');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (data.shipping_total > 0) {
|
|
104
|
+
opportunities.push('Shipping paid - loyalty program opportunity');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return opportunities.length > 0 ? opportunities : ['Standard order processing'];
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const calculateOrderMetrics = (data: any): any => {
|
|
111
|
+
const orderTotal = data.order_total || 0;
|
|
112
|
+
const shippingTotal = data.shipping_total || 0;
|
|
113
|
+
const taxTotal = data.tax_total || 0;
|
|
114
|
+
const discountTotal = data.discount_total || 0;
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
subtotal: orderTotal - shippingTotal - taxTotal + discountTotal,
|
|
118
|
+
net_revenue: orderTotal - discountTotal,
|
|
119
|
+
profit_margin: orderTotal > 0 ? ((orderTotal - discountTotal) / orderTotal) * 100 : 0,
|
|
120
|
+
average_item_value: data.items_count > 0 ? orderTotal / data.items_count : 0,
|
|
121
|
+
shipping_percentage: orderTotal > 0 ? (shippingTotal / orderTotal) * 100 : 0,
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export const mailChimpNewOrderTrigger = createTrigger({
|
|
126
|
+
auth: mailchimpAuth,
|
|
127
|
+
name: 'new_order',
|
|
128
|
+
displayName: 'New Order',
|
|
129
|
+
description: 'Fires when a new order is created in the connected store',
|
|
130
|
+
aiMetadata: {
|
|
131
|
+
description: 'Fires when a new e-commerce order is created in the selected connected Mailchimp store. The event carries the order id, customer, total, currency, status, and line items.',
|
|
132
|
+
},
|
|
133
|
+
type: TriggerStrategy.WEBHOOK,
|
|
134
|
+
props: {
|
|
135
|
+
store_id: mailchimpCommon.mailChimpStoreIdDropdown,
|
|
136
|
+
},
|
|
137
|
+
sampleData: {
|
|
138
|
+
type: 'order',
|
|
139
|
+
fired_at: '2024-01-15T10:30:00Z',
|
|
140
|
+
data: {
|
|
141
|
+
id: 'order_123',
|
|
142
|
+
order_id: 'order_123',
|
|
143
|
+
store_id: 'store_456',
|
|
144
|
+
customer_id: 'customer_789',
|
|
145
|
+
customer_email: 'customer@example.com',
|
|
146
|
+
order_total: 299.99,
|
|
147
|
+
currency: 'USD',
|
|
148
|
+
order_status: 'pending',
|
|
149
|
+
created_at: '2024-01-15T10:30:00Z',
|
|
150
|
+
items_count: 3,
|
|
151
|
+
shipping_total: 15.99,
|
|
152
|
+
tax_total: 24.00,
|
|
153
|
+
discount_total: 25.00,
|
|
154
|
+
items: [
|
|
155
|
+
{
|
|
156
|
+
product_id: 'prod_001',
|
|
157
|
+
product_title: 'Premium Widget',
|
|
158
|
+
product_variant_id: 'var_001',
|
|
159
|
+
quantity: 2,
|
|
160
|
+
price: 89.99,
|
|
161
|
+
total: 179.98,
|
|
162
|
+
category: 'Widgets',
|
|
163
|
+
tags: ['premium', 'bestseller'],
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
product_id: 'prod_002',
|
|
167
|
+
product_title: 'Standard Widget',
|
|
168
|
+
product_variant_id: 'var_002',
|
|
169
|
+
quantity: 1,
|
|
170
|
+
price: 119.99,
|
|
171
|
+
total: 119.99,
|
|
172
|
+
category: 'Widgets',
|
|
173
|
+
tags: ['standard'],
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
shipping_address: {
|
|
177
|
+
address1: '123 Main St',
|
|
178
|
+
address2: 'Suite 100',
|
|
179
|
+
city: 'Anytown',
|
|
180
|
+
province: 'California',
|
|
181
|
+
province_code: 'CA',
|
|
182
|
+
postal_code: '12345',
|
|
183
|
+
country: 'United States',
|
|
184
|
+
country_code: 'US',
|
|
185
|
+
},
|
|
186
|
+
billing_address: {
|
|
187
|
+
address1: '123 Main St',
|
|
188
|
+
address2: 'Suite 100',
|
|
189
|
+
city: 'Anytown',
|
|
190
|
+
province: 'California',
|
|
191
|
+
province_code: 'CA',
|
|
192
|
+
postal_code: '12345',
|
|
193
|
+
country: 'United States',
|
|
194
|
+
country_code: 'US',
|
|
195
|
+
},
|
|
196
|
+
customer: {
|
|
197
|
+
first_name: 'John',
|
|
198
|
+
last_name: 'Doe',
|
|
199
|
+
company: 'Example Corp',
|
|
200
|
+
phone: '+1-555-0123',
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
async onEnable(context): Promise<void> {
|
|
206
|
+
try {
|
|
207
|
+
const accessToken = getAccessTokenOrThrow(context.auth);
|
|
208
|
+
const server = await mailchimpCommon.getMailChimpServerPrefix(accessToken);
|
|
209
|
+
|
|
210
|
+
const enabledWebhookId = await mailchimpCommon.enableWebhookRequest({
|
|
211
|
+
server,
|
|
212
|
+
listId: context.propsValue.store_id!,
|
|
213
|
+
token: accessToken,
|
|
214
|
+
webhookUrl: context.webhookUrl!,
|
|
215
|
+
events: {
|
|
216
|
+
order: true,
|
|
217
|
+
customer: true,
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
await context.store?.put<WebhookData>(WEBHOOK_DATA_STORE_KEY, {
|
|
222
|
+
id: enabledWebhookId,
|
|
223
|
+
storeId: context.propsValue.store_id!,
|
|
224
|
+
});
|
|
225
|
+
} catch (error: any) {
|
|
226
|
+
throw new Error(`Failed to enable new order webhook: ${error.message || JSON.stringify(error)}`);
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
|
|
230
|
+
async onDisable(context): Promise<void> {
|
|
231
|
+
try {
|
|
232
|
+
const webhookData = await context.store?.get<WebhookData>(WEBHOOK_DATA_STORE_KEY);
|
|
233
|
+
|
|
234
|
+
if (webhookData === undefined || webhookData === null) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const token = getAccessTokenOrThrow(context.auth);
|
|
239
|
+
const server = await mailchimpCommon.getMailChimpServerPrefix(token);
|
|
240
|
+
|
|
241
|
+
await mailchimpCommon.disableWebhookRequest({
|
|
242
|
+
server,
|
|
243
|
+
token,
|
|
244
|
+
listId: webhookData.storeId,
|
|
245
|
+
webhookId: webhookData.id,
|
|
246
|
+
});
|
|
247
|
+
} catch (error: any) {
|
|
248
|
+
console.error(`Failed to disable new order webhook: ${error.message || JSON.stringify(error)}`);
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
|
|
252
|
+
async run(context): Promise<unknown[]> {
|
|
253
|
+
try {
|
|
254
|
+
const request = context.payload.body as any;
|
|
255
|
+
|
|
256
|
+
if (request === undefined || request.type !== 'order') {
|
|
257
|
+
return [];
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const enhancedRequest = {
|
|
261
|
+
...request,
|
|
262
|
+
trigger_type: 'new_order',
|
|
263
|
+
event_category: 'Order Creation',
|
|
264
|
+
processed_at: new Date().toISOString(),
|
|
265
|
+
order_summary: getNewOrderEventSummary(request),
|
|
266
|
+
business_context: {
|
|
267
|
+
order_management: true,
|
|
268
|
+
ecommerce_tracking: true,
|
|
269
|
+
revenue_tracking: true,
|
|
270
|
+
customer_engagement: true,
|
|
271
|
+
},
|
|
272
|
+
order_insights: {
|
|
273
|
+
order_value: assessOrderValue(request.data),
|
|
274
|
+
order_items: extractOrderItems(request.data?.items),
|
|
275
|
+
shipping_address: extractOrderAddress(request.data?.shipping_address),
|
|
276
|
+
billing_address: extractOrderAddress(request.data?.billing_address),
|
|
277
|
+
automation_opportunities: identifyOrderOpportunities(request.data),
|
|
278
|
+
financial_metrics: calculateOrderMetrics(request.data),
|
|
279
|
+
},
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
return [enhancedRequest];
|
|
283
|
+
} catch (error: any) {
|
|
284
|
+
console.error(`Error processing new order webhook: ${error.message || JSON.stringify(error)}`);
|
|
285
|
+
return [];
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
});
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import { createTrigger, TriggerStrategy, Property } from '@agnocon/pieces-framework';
|
|
2
|
+
import { getAccessTokenOrThrow } from '@agnocon/pieces-common';
|
|
3
|
+
import { mailchimpCommon } from '../common';
|
|
4
|
+
import { mailchimpAuth } from '../..';
|
|
5
|
+
|
|
6
|
+
const WEBHOOK_DATA_STORE_KEY = 'mail_chimp_segment_tag_subscriber_webhook_data';
|
|
7
|
+
|
|
8
|
+
type WebhookData = {
|
|
9
|
+
id: string;
|
|
10
|
+
listId: string;
|
|
11
|
+
segmentId?: string;
|
|
12
|
+
tagName?: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const getSegmentTagEventSummary = (request: any): any => {
|
|
16
|
+
const data = request.data || {};
|
|
17
|
+
return {
|
|
18
|
+
subscriber_id: data.id || 'N/A',
|
|
19
|
+
list_id: data.list_id || 'N/A',
|
|
20
|
+
email: data.email || 'N/A',
|
|
21
|
+
segment_id: data.segment_id || 'N/A',
|
|
22
|
+
segment_name: data.segment_name || 'N/A',
|
|
23
|
+
tag_name: data.tag_name || 'N/A',
|
|
24
|
+
tag_category: data.tag_category || 'N/A',
|
|
25
|
+
event_type: data.event_type || 'segment_join',
|
|
26
|
+
timestamp: data.timestamp || request.fired_at || 'N/A',
|
|
27
|
+
merge_fields: data.merges || {},
|
|
28
|
+
member_rating: data.member_rating || 0,
|
|
29
|
+
vip_status: data.vip || false,
|
|
30
|
+
language: data.language || 'en',
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const extractSegmentInfo = (data: any): any => {
|
|
35
|
+
return {
|
|
36
|
+
segment_id: data.segment_id || 'N/A',
|
|
37
|
+
segment_name: data.segment_name || 'N/A',
|
|
38
|
+
segment_type: data.segment_type || 'static',
|
|
39
|
+
segment_match: data.segment_match || 'any',
|
|
40
|
+
segment_conditions: data.segment_conditions || [],
|
|
41
|
+
segment_count: data.segment_count || 0,
|
|
42
|
+
segment_created: data.segment_created || 'N/A',
|
|
43
|
+
segment_updated: data.segment_updated || 'N/A',
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const extractTagInfo = (data: any): any => {
|
|
48
|
+
return {
|
|
49
|
+
tag_name: data.tag_name || 'N/A',
|
|
50
|
+
tag_category: data.tag_category || 'N/A',
|
|
51
|
+
tag_color: data.tag_color || 'N/A',
|
|
52
|
+
tag_count: data.tag_count || 0,
|
|
53
|
+
tag_created: data.tag_created || 'N/A',
|
|
54
|
+
tag_updated: data.tag_updated || 'N/A',
|
|
55
|
+
tag_notes: data.tag_notes || 'N/A',
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const assessSegmentEngagement = (data: any): string => {
|
|
60
|
+
const rating = data.member_rating || 0;
|
|
61
|
+
const isVip = data.vip || false;
|
|
62
|
+
const segmentCount = data.segment_count || 0;
|
|
63
|
+
|
|
64
|
+
if (isVip || rating >= 4) return 'High Engagement';
|
|
65
|
+
if (rating >= 2 || segmentCount > 1) return 'Medium Engagement';
|
|
66
|
+
return 'New to Segment';
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const identifySegmentOpportunities = (data: any): string[] => {
|
|
70
|
+
const opportunities = [];
|
|
71
|
+
|
|
72
|
+
if (data.event_type === 'segment_join') {
|
|
73
|
+
opportunities.push('New segment member - welcome series opportunity');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (data.event_type === 'tag_added') {
|
|
77
|
+
opportunities.push('New tag applied - targeted content opportunity');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (data.member_rating >= 4) {
|
|
81
|
+
opportunities.push('High engagement - premium content opportunity');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (data.vip) {
|
|
85
|
+
opportunities.push('VIP member - exclusive segment opportunity');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (data.segment_type === 'dynamic') {
|
|
89
|
+
opportunities.push('Dynamic segment - automated targeting opportunity');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return opportunities.length > 0 ? opportunities : ['Standard segment engagement'];
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const calculateSegmentMetrics = (data: any): any => {
|
|
96
|
+
return {
|
|
97
|
+
segment_member_count: data.segment_count || 0,
|
|
98
|
+
segment_growth_rate: data.growth_rate || 0,
|
|
99
|
+
segment_engagement_score: data.engagement_score || 0,
|
|
100
|
+
segment_activity_level: data.activity_level || 'low',
|
|
101
|
+
segment_retention_rate: data.retention_rate || 0,
|
|
102
|
+
segment_conversion_rate: data.conversion_rate || 0,
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const getEventCategory = (eventType: string): string => {
|
|
107
|
+
switch (eventType) {
|
|
108
|
+
case 'segment':
|
|
109
|
+
return 'Segment Membership';
|
|
110
|
+
case 'tag':
|
|
111
|
+
return 'Tag Application';
|
|
112
|
+
case 'profile':
|
|
113
|
+
return 'Profile Update';
|
|
114
|
+
case 'subscribe':
|
|
115
|
+
return 'New Subscription';
|
|
116
|
+
default:
|
|
117
|
+
return 'Unknown Event';
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export const mailChimpNewSegmentTagSubscriberTrigger = createTrigger({
|
|
122
|
+
auth: mailchimpAuth,
|
|
123
|
+
name: 'new_segment_tag_subscriber',
|
|
124
|
+
displayName: 'New Segment Tag Subscriber',
|
|
125
|
+
description: 'Fires when a subscriber joins a specific segment or tag',
|
|
126
|
+
aiMetadata: {
|
|
127
|
+
description: 'Fires when a subscriber in the selected audience (list) joins a segment or is given a tag; an optional segment ID or tag name narrows it to a specific segment/tag, otherwise it monitors all of them. The event carries the subscriber email and segment/tag details.',
|
|
128
|
+
},
|
|
129
|
+
type: TriggerStrategy.WEBHOOK,
|
|
130
|
+
props: {
|
|
131
|
+
list_id: mailchimpCommon.mailChimpListIdDropdown,
|
|
132
|
+
segment_id: Property.ShortText({
|
|
133
|
+
displayName: 'Segment ID (Optional)',
|
|
134
|
+
description: 'The specific segment ID to monitor. Leave empty to monitor all segments.',
|
|
135
|
+
required: false,
|
|
136
|
+
}),
|
|
137
|
+
tag_name: Property.ShortText({
|
|
138
|
+
displayName: 'Tag Name (Optional)',
|
|
139
|
+
description: 'The specific tag name to monitor. Leave empty to monitor all tags.',
|
|
140
|
+
required: false,
|
|
141
|
+
}),
|
|
142
|
+
},
|
|
143
|
+
sampleData: {
|
|
144
|
+
type: 'segment_tag',
|
|
145
|
+
fired_at: '2024-01-15T10:30:00Z',
|
|
146
|
+
data: {
|
|
147
|
+
id: '8a25ff1d98',
|
|
148
|
+
list_id: 'a6b5da1054',
|
|
149
|
+
email: 'subscriber@example.com',
|
|
150
|
+
segment_id: 'segment_123',
|
|
151
|
+
segment_name: 'High Value Customers',
|
|
152
|
+
segment_type: 'static',
|
|
153
|
+
segment_match: 'all',
|
|
154
|
+
segment_conditions: [
|
|
155
|
+
{
|
|
156
|
+
condition_type: 'EmailAddress',
|
|
157
|
+
op: 'is',
|
|
158
|
+
field: 'EMAIL',
|
|
159
|
+
value: 'subscriber@example.com',
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
segment_count: 150,
|
|
163
|
+
segment_created: '2024-01-01T00:00:00Z',
|
|
164
|
+
segment_updated: '2024-01-15T10:30:00Z',
|
|
165
|
+
tag_name: 'premium',
|
|
166
|
+
tag_category: 'customer_type',
|
|
167
|
+
tag_color: '#FF6B6B',
|
|
168
|
+
tag_count: 75,
|
|
169
|
+
tag_created: '2024-01-01T00:00:00Z',
|
|
170
|
+
tag_updated: '2024-01-15T10:30:00Z',
|
|
171
|
+
tag_notes: 'Premium customer segment',
|
|
172
|
+
event_type: 'segment_join',
|
|
173
|
+
timestamp: '2024-01-15T10:30:00Z',
|
|
174
|
+
merges: {
|
|
175
|
+
EMAIL: 'subscriber@example.com',
|
|
176
|
+
FNAME: 'John',
|
|
177
|
+
LNAME: 'Doe',
|
|
178
|
+
COMPANY: 'Example Corp',
|
|
179
|
+
PHONE: '+1-555-0123',
|
|
180
|
+
INTERESTS: 'Premium,High-Value',
|
|
181
|
+
},
|
|
182
|
+
member_rating: 5,
|
|
183
|
+
vip: true,
|
|
184
|
+
language: 'en',
|
|
185
|
+
growth_rate: 0.15,
|
|
186
|
+
engagement_score: 0.85,
|
|
187
|
+
activity_level: 'high',
|
|
188
|
+
retention_rate: 0.92,
|
|
189
|
+
conversion_rate: 0.08,
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
async onEnable(context): Promise<void> {
|
|
194
|
+
try {
|
|
195
|
+
const accessToken = getAccessTokenOrThrow(context.auth);
|
|
196
|
+
const server = await mailchimpCommon.getMailChimpServerPrefix(accessToken);
|
|
197
|
+
|
|
198
|
+
const enabledWebhookId = await mailchimpCommon.enableWebhookRequest({
|
|
199
|
+
server,
|
|
200
|
+
listId: context.propsValue.list_id as string,
|
|
201
|
+
token: accessToken,
|
|
202
|
+
webhookUrl: context.webhookUrl!,
|
|
203
|
+
events: {
|
|
204
|
+
profile: true,
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
await context.store?.put<WebhookData>(WEBHOOK_DATA_STORE_KEY, {
|
|
209
|
+
id: enabledWebhookId,
|
|
210
|
+
listId: context.propsValue.list_id as string,
|
|
211
|
+
segmentId: context.propsValue.segment_id,
|
|
212
|
+
tagName: context.propsValue.tag_name,
|
|
213
|
+
});
|
|
214
|
+
} catch (error: any) {
|
|
215
|
+
throw new Error(`Failed to enable segment tag subscriber webhook: ${error.message || JSON.stringify(error)}`);
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
|
|
219
|
+
async onDisable(context): Promise<void> {
|
|
220
|
+
try {
|
|
221
|
+
const webhookData = await context.store?.get<WebhookData>(WEBHOOK_DATA_STORE_KEY);
|
|
222
|
+
|
|
223
|
+
if (webhookData === undefined || webhookData === null) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const token = getAccessTokenOrThrow(context.auth);
|
|
228
|
+
const server = await mailchimpCommon.getMailChimpServerPrefix(token);
|
|
229
|
+
|
|
230
|
+
await mailchimpCommon.disableWebhookRequest({
|
|
231
|
+
server,
|
|
232
|
+
token,
|
|
233
|
+
listId: webhookData.listId,
|
|
234
|
+
webhookId: webhookData.id,
|
|
235
|
+
});
|
|
236
|
+
} catch (error: any) {
|
|
237
|
+
console.error(`Failed to disable segment tag subscriber webhook: ${error.message || JSON.stringify(error)}`);
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
|
|
241
|
+
async run(context): Promise<unknown[]> {
|
|
242
|
+
try {
|
|
243
|
+
const request = context.payload.body as any;
|
|
244
|
+
|
|
245
|
+
if (request === undefined || !['segment', 'tag', 'profile', 'subscribe'].includes(request.type)) {
|
|
246
|
+
return [];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const webhookData = await context.store?.get<WebhookData>(WEBHOOK_DATA_STORE_KEY);
|
|
250
|
+
if (webhookData) {
|
|
251
|
+
if (webhookData.segmentId && request.data?.segment_id !== webhookData.segmentId) {
|
|
252
|
+
return [];
|
|
253
|
+
}
|
|
254
|
+
if (webhookData.tagName && request.data?.tag_name !== webhookData.tagName) {
|
|
255
|
+
return [];
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const enhancedRequest = {
|
|
260
|
+
...request,
|
|
261
|
+
trigger_type: 'segment_tag_subscriber',
|
|
262
|
+
event_category: getEventCategory(request.type),
|
|
263
|
+
processed_at: new Date().toISOString(),
|
|
264
|
+
segment_tag_summary: getSegmentTagEventSummary(request),
|
|
265
|
+
business_context: {
|
|
266
|
+
audience_segmentation: true,
|
|
267
|
+
targeted_marketing: true,
|
|
268
|
+
automation_trigger: true,
|
|
269
|
+
customer_insights: true,
|
|
270
|
+
},
|
|
271
|
+
segment_tag_insights: {
|
|
272
|
+
segment_info: extractSegmentInfo(request.data),
|
|
273
|
+
tag_info: extractTagInfo(request.data),
|
|
274
|
+
engagement_level: assessSegmentEngagement(request.data),
|
|
275
|
+
automation_opportunities: identifySegmentOpportunities(request.data),
|
|
276
|
+
segment_metrics: calculateSegmentMetrics(request.data),
|
|
277
|
+
},
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
return [enhancedRequest];
|
|
281
|
+
} catch (error: any) {
|
|
282
|
+
console.error(`Error processing segment tag subscriber webhook: ${error.message || JSON.stringify(error)}`);
|
|
283
|
+
return [];
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
});
|