@kb0912/notification-brevo 1.0.16 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/.medusa/server/src/admin/index.js +1004 -3
  2. package/.medusa/server/src/admin/index.mjs +1004 -3
  3. package/.medusa/server/src/api/admin/brevo-plugin-settings/analytics/route.js +78 -0
  4. package/.medusa/server/src/api/admin/brevo-plugin-settings/route.js +27 -0
  5. package/.medusa/server/src/api/hooks/brevo-webhook/route.js +40 -0
  6. package/.medusa/server/src/jobs/abandoned-cart.js +5 -11
  7. package/.medusa/server/src/jobs/promotion-expiry-reminder.js +122 -0
  8. package/.medusa/server/src/jobs/review-request.js +106 -0
  9. package/.medusa/server/src/jobs/winback.js +108 -0
  10. package/.medusa/server/src/modules/brevo-settings/index.js +13 -0
  11. package/.medusa/server/src/modules/brevo-settings/migrations/Migration20260306173214.js +15 -0
  12. package/.medusa/server/src/modules/brevo-settings/migrations/Migration20260307045432.js +14 -0
  13. package/.medusa/server/src/modules/brevo-settings/migrations/Migration20260307075811.js +14 -0
  14. package/.medusa/server/src/modules/brevo-settings/models/brevo-settings.js +79 -0
  15. package/.medusa/server/src/modules/brevo-settings/service.js +114 -0
  16. package/.medusa/server/src/providers/notifications-brevo/services.js +321 -176
  17. package/.medusa/server/src/workflows/index.js +25 -0
  18. package/.medusa/server/src/workflows/send-abandoned-cart.js +37 -8
  19. package/.medusa/server/src/workflows/send-customer-created.js +159 -4
  20. package/.medusa/server/src/workflows/send-order-canceled.js +27 -3
  21. package/.medusa/server/src/workflows/send-order-confirmation.js +63 -10
  22. package/.medusa/server/src/workflows/send-order-delivered.js +52 -0
  23. package/.medusa/server/src/workflows/send-review-request.js +37 -0
  24. package/.medusa/server/src/workflows/send-shipment-confirmation.js +33 -10
  25. package/.medusa/server/src/workflows/send-winback.js +34 -0
  26. package/.medusa/server/src/workflows/steps/check-abandoned-carts.js +184 -58
  27. package/.medusa/server/src/workflows/steps/resolve-locale.js +25 -0
  28. package/.medusa/server/src/workflows/steps/send-multi-channel.js +81 -0
  29. package/.medusa/server/src/workflows/steps/send-notification.js +1 -1
  30. package/.medusa/server/src/workflows/steps/sync-brevo-contact.js +57 -0
  31. package/.medusa/server/src/workflows/steps/track-brevo-event.js +47 -0
  32. package/README.md +315 -60
  33. package/package.json +21 -23
  34. package/.medusa/server/src/api/admin/plugin/route.js +0 -7
  35. package/.medusa/server/src/config.js +0 -12
  36. package/.medusa/server/src/loaders/brevo.js +0 -13
  37. package/.medusa/server/src/subscribers/password-reset.js +0 -18
  38. package/.medusa/server/src/subscribers/promotion-new-customer-created.js +0 -21
  39. package/.medusa/server/src/workflows/send-password-reset.js +0 -30
  40. package/.medusa/server/src/workflows/send-promotion-notification.js +0 -24
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendWinbackWorkflow = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const send_notification_1 = require("./steps/send-notification");
6
+ const brevo_settings_1 = require("../modules/brevo-settings");
7
+ const loadSettingsForWinback = (0, workflows_sdk_1.createStep)("load-settings-for-winback", async (_, { container }) => {
8
+ try {
9
+ const svc = container.resolve(brevo_settings_1.BREVO_SETTINGS_MODULE);
10
+ return new workflows_sdk_1.StepResponse(await svc.getSettings());
11
+ }
12
+ catch {
13
+ return new workflows_sdk_1.StepResponse({});
14
+ }
15
+ });
16
+ exports.sendWinbackWorkflow = (0, workflows_sdk_1.createWorkflow)("send-winback", (input) => {
17
+ const settings = loadSettingsForWinback();
18
+ const notification = (0, send_notification_1.sendNotificationStep)([
19
+ {
20
+ to: input.email,
21
+ channel: "email",
22
+ template: "winback",
23
+ data: {
24
+ customer_name: input.customerName,
25
+ last_order_date: input.lastOrderDate,
26
+ days_inactive: input.daysInactive,
27
+ _settings: settings,
28
+ _locale: input.locale,
29
+ },
30
+ },
31
+ ]);
32
+ return new workflows_sdk_1.WorkflowResponse(notification);
33
+ });
34
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VuZC13aW5iYWNrLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9zZW5kLXdpbmJhY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBSzBDO0FBQzFDLGlFQUFnRTtBQUNoRSw4REFBaUU7QUFFakUsTUFBTSxzQkFBc0IsR0FBRyxJQUFBLDBCQUFVLEVBQ3JDLDJCQUEyQixFQUMzQixLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRTtJQUN2QixJQUFJLENBQUM7UUFDRCxNQUFNLEdBQUcsR0FBUSxTQUFTLENBQUMsT0FBTyxDQUFDLHNDQUFxQixDQUFDLENBQUE7UUFDekQsT0FBTyxJQUFJLDRCQUFZLENBQUMsTUFBTSxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQTtJQUNwRCxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ0wsT0FBTyxJQUFJLDRCQUFZLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDL0IsQ0FBQztBQUNMLENBQUMsQ0FDSixDQUFBO0FBRVksUUFBQSxtQkFBbUIsR0FBRyxJQUFBLDhCQUFjLEVBQzdDLGNBQWMsRUFDZCxDQUFDLEtBTUEsRUFBRSxFQUFFO0lBQ0QsTUFBTSxRQUFRLEdBQUcsc0JBQXNCLEVBQUUsQ0FBQTtJQUV6QyxNQUFNLFlBQVksR0FBRyxJQUFBLHdDQUFvQixFQUFDO1FBQ3RDO1lBQ0ksRUFBRSxFQUFFLEtBQUssQ0FBQyxLQUFLO1lBQ2YsT0FBTyxFQUFFLE9BQU87WUFDaEIsUUFBUSxFQUFFLFNBQVM7WUFDbkIsSUFBSSxFQUFFO2dCQUNGLGFBQWEsRUFBRSxLQUFLLENBQUMsWUFBWTtnQkFDakMsZUFBZSxFQUFFLEtBQUssQ0FBQyxhQUFhO2dCQUNwQyxhQUFhLEVBQUUsS0FBSyxDQUFDLFlBQVk7Z0JBQ2pDLFNBQVMsRUFBRSxRQUFRO2dCQUNuQixPQUFPLEVBQUUsS0FBSyxDQUFDLE1BQU07YUFDeEI7U0FDSjtLQUNKLENBQUMsQ0FBQTtJQUVGLE9BQU8sSUFBSSxnQ0FBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQTtBQUM3QyxDQUFDLENBQ0osQ0FBQSJ9
@@ -2,70 +2,196 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.checkAbandonedCartsWorkflow = void 0;
4
4
  const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
- const utils_1 = require("@medusajs/framework/utils");
5
+ const brevo_settings_1 = require("../../modules/brevo-settings");
6
6
  const send_abandoned_cart_1 = require("../send-abandoned-cart");
7
- const config_1 = require("../../config");
8
- exports.checkAbandonedCartsWorkflow = (0, workflows_sdk_1.createWorkflow)("check-abandoned-carts", ({ container }) => {
9
- const checkCartsStep = (0, workflows_sdk_1.createStep)("check-abandoned-carts-step", async (_, { container: stepContainer }) => {
10
- const cartModuleService = stepContainer.resolve(utils_1.Modules.CART);
11
- const logger = stepContainer.resolve("logger");
12
- const query = stepContainer.resolve("query");
13
- if (!config_1.abandonedCartConfig.abandoned_carts) {
14
- logger.info("Abandoned carts feature is disabled in config.");
15
- return new workflows_sdk_1.StepResponse(null);
16
- }
17
- if (!config_1.abandonedCartConfig.checks.length) {
18
- logger.info("No abandoned cart checks configured.");
19
- return new workflows_sdk_1.StepResponse(null);
20
- }
21
- logger.info("Running check-abandoned-carts scheduled job...");
22
- const now = new Date();
23
- const seventyTwoHoursAgo = new Date(now.getTime() - 72 * 60 * 60 * 1000);
24
- const checkTimes = config_1.abandonedCartConfig.checks.map(check => new Date(now.getTime() - parseInt(check.delay) * 60 * 60 * 1000));
25
- const { data: carts } = await query.graph({
26
- entity: "cart",
27
- fields: [
28
- "id", "email", "created_at", "updated_at", "completed_at", "metadata",
29
- "items.id", "items.updated_at"
30
- ],
31
- filters: {
32
- completed_at: null,
33
- email: { $ne: null },
34
- updated_at: { $gte: seventyTwoHoursAgo.toISOString() },
35
- },
36
- });
37
- logger.info(`Found ${carts.length} carts to check`);
38
- for (const cart of carts) {
39
- if (!cart.items?.length) {
40
- logger.info(`Cart ${cart.id} skipped: No items in cart`);
7
+ const utils_1 = require("@medusajs/framework/utils");
8
+ /**
9
+ * Step: Check all incomplete carts for abandoned cart conditions and send emails.
10
+ * On the FINAL interval, optionally creates a discount code.
11
+ */
12
+ const checkAbandonedCartsStep = (0, workflows_sdk_1.createStep)("check-abandoned-carts-step", async (_, { container }) => {
13
+ const cartModuleService = container.resolve(utils_1.Modules.CART);
14
+ const logger = container.resolve("logger");
15
+ const query = container.resolve("query");
16
+ let settings;
17
+ try {
18
+ const brevoSettingsService = container.resolve(brevo_settings_1.BREVO_SETTINGS_MODULE);
19
+ settings = await brevoSettingsService.getSettings();
20
+ }
21
+ catch (error) {
22
+ logger.warn("[Brevo] Could not load settings, abandoned cart check skipped.");
23
+ return new workflows_sdk_1.StepResponse({ checked: 0, sent: 0 });
24
+ }
25
+ if (!settings.abandoned_cart_enabled) {
26
+ return new workflows_sdk_1.StepResponse({ checked: 0, sent: 0 });
27
+ }
28
+ const intervals = Array.isArray(settings.abandoned_cart_intervals)
29
+ ? settings.abandoned_cart_intervals
30
+ : [];
31
+ if (!intervals.length) {
32
+ return new workflows_sdk_1.StepResponse({ checked: 0, sent: 0 });
33
+ }
34
+ const sortedIntervals = [...intervals].sort((a, b) => a - b);
35
+ const maxInterval = sortedIntervals[sortedIntervals.length - 1];
36
+ const maxHours = maxInterval + 24;
37
+ logger.info(`[Brevo] Checking abandoned carts | intervals=[${sortedIntervals.join(", ")}]h`);
38
+ const now = new Date();
39
+ const cutoffDate = new Date(now.getTime() - maxHours * 60 * 60 * 1000);
40
+ const checkTimes = sortedIntervals.map((hours) => new Date(now.getTime() - hours * 60 * 60 * 1000));
41
+ const { data: carts } = await query.graph({
42
+ entity: "cart",
43
+ fields: [
44
+ "id", "email", "created_at", "updated_at", "completed_at", "metadata",
45
+ "currency_code", "items.id", "items.updated_at",
46
+ "customer.id", "customer.first_name", "customer.last_name",
47
+ ],
48
+ filters: {
49
+ completed_at: null,
50
+ email: { $ne: null },
51
+ updated_at: { $lte: cutoffDate.toISOString() },
52
+ },
53
+ });
54
+ logger.info(`[Brevo] Found ${carts.length} incomplete carts`);
55
+ let sentCount = 0;
56
+ for (const cart of carts) {
57
+ if (!cart.items?.length || !cart.email)
58
+ continue;
59
+ const latestItemUpdate = cart.items
60
+ .map((item) => new Date(item.updated_at).getTime())
61
+ .reduce((max, t) => Math.max(max, t), 0);
62
+ const lastActivity = new Date(latestItemUpdate);
63
+ const notifiedFlags = cart.metadata || {};
64
+ for (let i = 0; i < sortedIntervals.length; i++) {
65
+ const flagKey = `abandonedcart_mail_${i + 1}`;
66
+ const discountFlagKey = `abandonedcart_discount_${i + 1}`;
67
+ if (notifiedFlags[flagKey])
41
68
  continue;
42
- }
43
- const latestItemUpdate = cart.items.sort((a, b) => new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime())[0].updated_at;
44
- const check = new Date(latestItemUpdate);
45
- const hoursSinceUpdate = Math.floor((now.getTime() - check.getTime()) / (1000 * 60 * 60));
46
- const notifiedFlags = cart.metadata || {};
47
- let actionIndex = -1;
48
- for (let i = checkTimes.length - 1; i >= 0; i--) {
49
- if (check < checkTimes[i] && !notifiedFlags[`abandonedcart_mail_${i + 1}`]) {
50
- actionIndex = i;
51
- break;
69
+ if (lastActivity >= checkTimes[i])
70
+ continue;
71
+ const emailsSent = Object.keys(notifiedFlags)
72
+ .filter((k) => k.startsWith("abandonedcart_mail_"))
73
+ .filter((k) => notifiedFlags[k] === true).length;
74
+ if (emailsSent >= (settings.abandoned_cart_max_emails || sortedIntervals.length))
75
+ continue;
76
+ const isFinalEmail = (i === sortedIntervals.length - 1);
77
+ const shouldCreateDiscount = isFinalEmail && settings.abandoned_cart_discount_enabled;
78
+ logger.info(`[Brevo] Sending abandoned cart email #${i + 1} to ${cart.email} ` +
79
+ `(cart=${cart.id}, interval=${sortedIntervals[i]}h${shouldCreateDiscount ? ", +discount" : ""})`);
80
+ try {
81
+ let discountData = {};
82
+ // Create discount code on final email if enabled
83
+ // BUT skip if discount was already created (flag set from a previous failed email attempt)
84
+ if (shouldCreateDiscount && !notifiedFlags[discountFlagKey]) {
85
+ try {
86
+ const promotionService = container.resolve("promotion");
87
+ const expiresHours = settings.abandoned_cart_discount_expires_hours || 48;
88
+ const discountType = settings.abandoned_cart_discount_type || "percentage";
89
+ const discountValue = settings.abandoned_cart_discount_value || 10;
90
+ const isPercentage = discountType === "percentage";
91
+ const excludedCurrencies = Array.isArray(settings.abandoned_cart_discount_excluded_currencies)
92
+ ? settings.abandoned_cart_discount_excluded_currencies : [];
93
+ const codePrefix = (settings.abandoned_cart_discount_code_prefix || "COMEBACK").toUpperCase();
94
+ // Generate unique 8-char alphanumeric suffix
95
+ const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
96
+ let suffix = "";
97
+ for (let j = 0; j < 8; j++)
98
+ suffix += chars[Math.floor(Math.random() * chars.length)];
99
+ const code = `${codePrefix}-${suffix}`;
100
+ const startsAt = new Date();
101
+ const expiresAt = new Date(Date.now() + expiresHours * 60 * 60 * 1000);
102
+ // Build promotion rules
103
+ const rules = [];
104
+ if (cart.customer?.id) {
105
+ rules.push({ attribute: "customer_id", operator: "eq", values: [cart.customer.id] });
106
+ }
107
+ for (const cur of excludedCurrencies) {
108
+ rules.push({ attribute: "currency_code", operator: "ne", values: [cur] });
109
+ }
110
+ await promotionService.createPromotions({
111
+ code,
112
+ type: "standard",
113
+ is_automatic: true,
114
+ status: "active",
115
+ rules: rules.length > 0 ? rules : undefined,
116
+ campaign: {
117
+ name: `Comeback - ${cart.email}`,
118
+ campaign_identifier: `comeback-${code}`,
119
+ starts_at: startsAt,
120
+ ends_at: expiresAt,
121
+ budget: {
122
+ type: "usage",
123
+ limit: settings.abandoned_cart_discount_max_uses || 1,
124
+ },
125
+ },
126
+ application_method: {
127
+ type: isPercentage ? "percentage" : "fixed",
128
+ value: discountValue,
129
+ target_type: "order",
130
+ max_quantity: 1,
131
+ currency_code: isPercentage ? undefined : (cart.currency_code || "usd"),
132
+ },
133
+ });
134
+ discountData = {
135
+ promotion_code: code,
136
+ discount_value: discountValue,
137
+ discount_type: discountType,
138
+ discount_expires_at: new Date(Date.now() + expiresHours * 60 * 60 * 1000).toISOString(),
139
+ };
140
+ // Save discount flag immediately — prevents duplicate discount creation
141
+ await cartModuleService.updateCarts(cart.id, {
142
+ metadata: {
143
+ ...notifiedFlags,
144
+ [discountFlagKey]: true,
145
+ last_discount_code: code,
146
+ },
147
+ });
148
+ // Refresh notifiedFlags for the email flag update below
149
+ notifiedFlags[discountFlagKey] = true;
150
+ notifiedFlags.last_discount_code = code;
151
+ logger.info(`[Brevo] Created discount code ${code} for cart ${cart.id}`);
152
+ }
153
+ catch (discountErr) {
154
+ logger.error(`[Brevo] Failed to create discount: ${discountErr?.message}`);
155
+ }
52
156
  }
53
- }
54
- if (actionIndex >= 0) {
55
- const delay = config_1.abandonedCartConfig.checks[actionIndex].delay;
56
- const flagKey = `abandonedcart_mail_${actionIndex + 1}`;
57
- logger.info(`Cart ${cart.id}: check = ${check}, hoursSinceUpdate = ${hoursSinceUpdate}`);
58
- logger.info(`Sending abandoned cart email #${actionIndex + 1} to ${cart.email} after ${delay} hours`);
59
- await (0, send_abandoned_cart_1.sendAbandonedCartWorkflow)(stepContainer).run({ input: { cartId: cart.id } });
157
+ else if (shouldCreateDiscount && notifiedFlags[discountFlagKey]) {
158
+ // Discount was already created in a previous run (email failed last time)
159
+ // Re-use the existing discount code
160
+ discountData = {
161
+ promotion_code: notifiedFlags.last_discount_code,
162
+ };
163
+ logger.info(`[Brevo] Re-using existing discount ${notifiedFlags.last_discount_code} for cart ${cart.id}`);
164
+ }
165
+ // Send email
166
+ await (0, send_abandoned_cart_1.sendAbandonedCartWorkflow)(container).run({
167
+ input: {
168
+ cartId: cart.id,
169
+ ...discountData,
170
+ _useDiscountTemplate: shouldCreateDiscount && !!discountData.promotion_code,
171
+ },
172
+ });
173
+ // Email sent successfully — mark email flag
60
174
  await cartModuleService.updateCarts(cart.id, {
61
- metadata: { ...notifiedFlags, [flagKey]: true },
175
+ metadata: {
176
+ ...notifiedFlags,
177
+ [flagKey]: true,
178
+ },
62
179
  });
180
+ sentCount++;
63
181
  }
182
+ catch (error) {
183
+ logger.error(`[Brevo] Failed abandoned cart email for cart ${cart.id}: ${error.message}`);
184
+ // Email failed — but discount flag is already saved if discount was created
185
+ // Next run will retry email WITHOUT creating a new discount
186
+ }
187
+ break; // Only send one email per cart per job run
64
188
  }
65
- logger.info("Finished checking abandoned carts");
66
- return new workflows_sdk_1.StepResponse(null);
67
- });
68
- const result = checkCartsStep();
189
+ }
190
+ logger.info(`[Brevo] Abandoned cart check complete. Sent ${sentCount} emails.`);
191
+ return new workflows_sdk_1.StepResponse({ checked: carts.length, sent: sentCount });
192
+ });
193
+ exports.checkAbandonedCartsWorkflow = (0, workflows_sdk_1.createWorkflow)("check-abandoned-carts", () => {
194
+ const result = checkAbandonedCartsStep();
69
195
  return new workflows_sdk_1.WorkflowResponse(result);
70
196
  });
71
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2stYWJhbmRvbmVkLWNhcnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9zdGVwcy9jaGVjay1hYmFuZG9uZWQtY2FydHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBQStHO0FBQy9HLHFEQUFvRDtBQUNwRCxnRUFBbUU7QUFDbkUseUNBQW1EO0FBTXRDLFFBQUEsMkJBQTJCLEdBQUcsSUFBQSw4QkFBYyxFQUN2RCx1QkFBdUIsRUFDdkIsQ0FBQyxFQUFFLFNBQVMsRUFBaUIsRUFBRSxFQUFFO0lBQy9CLE1BQU0sY0FBYyxHQUFHLElBQUEsMEJBQVUsRUFDL0IsNEJBQTRCLEVBQzVCLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLEVBQUUsRUFBRTtRQUN4QyxNQUFNLGlCQUFpQixHQUFHLGFBQWEsQ0FBQyxPQUFPLENBQUMsZUFBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzlELE1BQU0sTUFBTSxHQUFHLGFBQWEsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDL0MsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUU3QyxJQUFJLENBQUMsNEJBQW1CLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDekMsTUFBTSxDQUFDLElBQUksQ0FBQyxnREFBZ0QsQ0FBQyxDQUFDO1lBQzlELE9BQU8sSUFBSSw0QkFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hDLENBQUM7UUFFRCxJQUFJLENBQUMsNEJBQW1CLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3ZDLE1BQU0sQ0FBQyxJQUFJLENBQUMsc0NBQXNDLENBQUMsQ0FBQztZQUNwRCxPQUFPLElBQUksNEJBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNoQyxDQUFDO1FBRUQsTUFBTSxDQUFDLElBQUksQ0FBQyxnREFBZ0QsQ0FBQyxDQUFDO1FBRTlELE1BQU0sR0FBRyxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFDdkIsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7UUFFekUsTUFBTSxVQUFVLEdBQUcsNEJBQW1CLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUN4RCxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUNqRSxDQUFDO1FBRUYsTUFBTSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUM7WUFDeEMsTUFBTSxFQUFFLE1BQU07WUFDZCxNQUFNLEVBQUU7Z0JBQ04sSUFBSSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLGNBQWMsRUFBRSxVQUFVO2dCQUNyRSxVQUFVLEVBQUUsa0JBQWtCO2FBQy9CO1lBQ0QsT0FBTyxFQUFFO2dCQUNQLFlBQVksRUFBRSxJQUFJO2dCQUNsQixLQUFLLEVBQUUsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFO2dCQUNwQixVQUFVLEVBQUUsRUFBRSxJQUFJLEVBQUUsa0JBQWtCLENBQUMsV0FBVyxFQUFFLEVBQUU7YUFDdkQ7U0FDRixDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsS0FBSyxDQUFDLE1BQU0saUJBQWlCLENBQUMsQ0FBQztRQUVwRCxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxDQUFDO2dCQUN4QixNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLEVBQUUsNEJBQTRCLENBQUMsQ0FBQztnQkFDekQsU0FBUztZQUNYLENBQUM7WUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQztZQUN0SSxNQUFNLEtBQUssR0FBRyxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ3pDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUUxRixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsUUFBUSxJQUFJLEVBQUUsQ0FBQztZQUUxQyxJQUFJLFdBQVcsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNyQixLQUFLLElBQUksQ0FBQyxHQUFHLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDaEQsSUFBSSxLQUFLLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLHNCQUFzQixDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO29CQUMzRSxXQUFXLEdBQUcsQ0FBQyxDQUFDO29CQUNoQixNQUFNO2dCQUNSLENBQUM7WUFDSCxDQUFDO1lBRUQsSUFBSSxXQUFXLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ3JCLE1BQU0sS0FBSyxHQUFHLDRCQUFtQixDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxLQUFLLENBQUM7Z0JBQzVELE1BQU0sT0FBTyxHQUFHLHNCQUFzQixXQUFXLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3hELE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsRUFBRSxhQUFhLEtBQUssd0JBQXdCLGdCQUFnQixFQUFFLENBQUMsQ0FBQztnQkFDekYsTUFBTSxDQUFDLElBQUksQ0FBQyxpQ0FBaUMsV0FBVyxHQUFHLENBQUMsT0FBTyxJQUFJLENBQUMsS0FBSyxVQUFVLEtBQUssUUFBUSxDQUFDLENBQUM7Z0JBQ3RHLE1BQU0sSUFBQSwrQ0FBeUIsRUFBQyxhQUFhLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDbkYsTUFBTSxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRTtvQkFDM0MsUUFBUSxFQUFFLEVBQUUsR0FBRyxhQUFhLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxJQUFJLEVBQUU7aUJBQ2hELENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDO1FBRUQsTUFBTSxDQUFDLElBQUksQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDO1FBQ2pELE9BQU8sSUFBSSw0QkFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2hDLENBQUMsQ0FDRixDQUFDO0lBRUYsTUFBTSxNQUFNLEdBQUcsY0FBYyxFQUFFLENBQUM7SUFDaEMsT0FBTyxJQUFJLGdDQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3RDLENBQUMsQ0FDRixDQUFDIn0=
197
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2stYWJhbmRvbmVkLWNhcnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9zdGVwcy9jaGVjay1hYmFuZG9uZWQtY2FydHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBQThHO0FBQzlHLGlFQUFvRTtBQUNwRSxnRUFBa0U7QUFDbEUscURBQW1EO0FBRW5EOzs7R0FHRztBQUNILE1BQU0sdUJBQXVCLEdBQUcsSUFBQSwwQkFBVSxFQUN4Qyw0QkFBNEIsRUFDNUIsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUU7SUFDekIsTUFBTSxpQkFBaUIsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLGVBQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUN6RCxNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBQzFDLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUE7SUFFeEMsSUFBSSxRQUFhLENBQUE7SUFDakIsSUFBSSxDQUFDO1FBQ0gsTUFBTSxvQkFBb0IsR0FBUSxTQUFTLENBQUMsT0FBTyxDQUFDLHNDQUFxQixDQUFDLENBQUE7UUFDMUUsUUFBUSxHQUFHLE1BQU0sb0JBQW9CLENBQUMsV0FBVyxFQUFFLENBQUE7SUFDckQsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixNQUFNLENBQUMsSUFBSSxDQUFDLGdFQUFnRSxDQUFDLENBQUE7UUFDN0UsT0FBTyxJQUFJLDRCQUFZLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBQ2xELENBQUM7SUFFRCxJQUFJLENBQUMsUUFBUSxDQUFDLHNCQUFzQixFQUFFLENBQUM7UUFDckMsT0FBTyxJQUFJLDRCQUFZLENBQUMsRUFBRSxPQUFPLEVB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
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveLocaleStep = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ /**
6
+ * Step: Extract the customer's preferred locale from order/customer/cart data.
7
+ *
8
+ * Priority:
9
+ * 1. customer.metadata.preferred_locale (set by storefront)
10
+ * 2. cart.metadata.locale (set by storefront on cart)
11
+ * 3. null (use default template)
12
+ *
13
+ * Storefront should set this when user selects language:
14
+ * POST /store/customers/me { metadata: { preferred_locale: "zh" } }
15
+ * or
16
+ * POST /store/carts/:id { metadata: { locale: "vi" } }
17
+ */
18
+ exports.resolveLocaleStep = (0, workflows_sdk_1.createStep)("resolve-locale", async (input) => {
19
+ const locale = input.customerMetadata?.preferred_locale ||
20
+ input.cartMetadata?.locale ||
21
+ input.orderMetadata?.locale ||
22
+ null;
23
+ return new workflows_sdk_1.StepResponse(locale);
24
+ });
25
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb2x2ZS1sb2NhbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvd29ya2Zsb3dzL3N0ZXBzL3Jlc29sdmUtbG9jYWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFFQUE0RTtBQUU1RTs7Ozs7Ozs7Ozs7O0dBWUc7QUFDVSxRQUFBLGlCQUFpQixHQUFHLElBQUEsMEJBQVUsRUFDdkMsZ0JBQWdCLEVBQ2hCLEtBQUssRUFBRSxLQUlOLEVBQUUsRUFBRTtJQUNELE1BQU0sTUFBTSxHQUNSLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxnQkFBZ0I7UUFDeEMsS0FBSyxDQUFDLFlBQVksRUFBRSxNQUFNO1FBQzFCLEtBQUssQ0FBQyxhQUFhLEVBQUUsTUFBTTtRQUMzQixJQUFJLENBQUE7SUFFUixPQUFPLElBQUksNEJBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQTtBQUNuQyxDQUFDLENBQ0osQ0FBQSJ9
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendMultiChannelStep = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const brevo_settings_1 = require("../../modules/brevo-settings");
6
+ /**
7
+ * Step: Send SMS and/or WhatsApp notification via Brevo.
8
+ * Loads settings internally from the container — avoids proxy issues.
9
+ */
10
+ exports.sendMultiChannelStep = (0, workflows_sdk_1.createStep)("send-multi-channel", async (input, { container }) => {
11
+ const logger = container.resolve("logger");
12
+ if (!input.phone) {
13
+ return new workflows_sdk_1.StepResponse({ sms: false, whatsapp: false });
14
+ }
15
+ let settings;
16
+ try {
17
+ const svc = container.resolve(brevo_settings_1.BREVO_SETTINGS_MODULE);
18
+ settings = await svc.getSettings();
19
+ }
20
+ catch {
21
+ return new workflows_sdk_1.StepResponse({ sms: false, whatsapp: false });
22
+ }
23
+ let smsSent = false;
24
+ let whatsappSent = false;
25
+ // Resolve Brevo provider
26
+ let brevoProvider = null;
27
+ try {
28
+ const notificationService = container.resolve("notification");
29
+ // Try multiple patterns to find the provider
30
+ if (notificationService.retrieveProvider) {
31
+ brevoProvider = notificationService.retrieveProvider("brevo");
32
+ }
33
+ }
34
+ catch {
35
+ // Provider not available, skip silently
36
+ return new workflows_sdk_1.StepResponse({ sms: false, whatsapp: false });
37
+ }
38
+ if (!brevoProvider) {
39
+ return new workflows_sdk_1.StepResponse({ sms: false, whatsapp: false });
40
+ }
41
+ // Resolve SMS content from settings
42
+ const smsContentMap = {
43
+ order_placed: settings.sms_order_placed_content || `Your order #${input.displayId || ""} has been placed!`,
44
+ shipment_created: settings.sms_shipment_content || `Your order #${input.displayId || ""} has been shipped!`,
45
+ };
46
+ // Resolve WhatsApp template name from settings
47
+ const whatsappTemplateMap = {
48
+ order_placed: settings.whatsapp_order_placed_template || "",
49
+ shipment_created: settings.whatsapp_shipment_template || "",
50
+ };
51
+ // Send SMS
52
+ if (settings?.sms_enabled && smsContentMap[input.event] && brevoProvider.sendSms) {
53
+ try {
54
+ await brevoProvider.sendSms({
55
+ to: input.phone,
56
+ content: smsContentMap[input.event],
57
+ sender: settings.sms_sender || undefined,
58
+ });
59
+ smsSent = true;
60
+ }
61
+ catch (err) {
62
+ logger.warn(`[Brevo] SMS failed: ${err?.message}`);
63
+ }
64
+ }
65
+ // Send WhatsApp
66
+ if (settings?.whatsapp_enabled && whatsappTemplateMap[input.event] && brevoProvider.sendWhatsApp) {
67
+ try {
68
+ await brevoProvider.sendWhatsApp({
69
+ to: input.phone,
70
+ templateName: whatsappTemplateMap[input.event],
71
+ params: { display_id: String(input.displayId || "") },
72
+ });
73
+ whatsappSent = true;
74
+ }
75
+ catch (err) {
76
+ logger.warn(`[Brevo] WhatsApp failed: ${err?.message}`);
77
+ }
78
+ }
79
+ return new workflows_sdk_1.StepResponse({ sms: smsSent, whatsapp: whatsappSent });
80
+ });
81
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VuZC1tdWx0aS1jaGFubmVsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9zdGVwcy9zZW5kLW11bHRpLWNoYW5uZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBQTRFO0FBQzVFLGlFQUFvRTtBQUVwRTs7O0dBR0c7QUFDVSxRQUFBLG9CQUFvQixHQUFHLElBQUEsMEJBQVUsRUFDMUMsb0JBQW9CLEVBQ3BCLEtBQUssRUFBRSxLQUtOLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFO0lBQ2hCLE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUE7SUFFMUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNmLE9BQU8sSUFBSSw0QkFBWSxDQUFDLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQTtJQUM1RCxDQUFDO0lBRUQsSUFBSSxRQUFhLENBQUE7SUFDakIsSUFBSSxDQUFDO1FBQ0QsTUFBTSxHQUFHLEdBQVEsU0FBUyxDQUFDLE9BQU8sQ0FBQyxzQ0FBcUIsQ0FBQyxDQUFBO1FBQ3pELFFBQVEsR0FBRyxNQUFNLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQTtJQUN0QyxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ0wsT0FBTyxJQUFJLDRCQUFZLENBQUMsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFBO0lBQzVELENBQUM7SUFFRCxJQUFJLE9BQU8sR0FBRyxLQUFLLENBQUE7SUFDbkIsSUFBSSxZQUFZLEdBQUcsS0FBSyxDQUFBO0lBRXhCLHlCQUF5QjtJQUN6QixJQUFJLGFBQWEsR0FBUSxJQUFJLENBQUE7SUFDN0IsSUFBSSxDQUFDO1FBQ0QsTUFBTSxtQkFBbUIsR0FBUSxTQUFTLENBQUMsT0FBTyxDQUFD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
@@ -8,4 +8,4 @@ exports.sendNotificationStep = (0, workflows_sdk_1.createStep)("send-notificatio
8
8
  const notification = await notificationModuleService.createNotifications(data);
9
9
  return new workflows_sdk_1.StepResponse(notification);
10
10
  });
11
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VuZC1ub3RpZmljYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvd29ya2Zsb3dzL3N0ZXBzL3NlbmQtbm90aWZpY2F0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFEQUFtRDtBQUNuRCxxRUFBNEU7QUFJL0QsUUFBQSxvQkFBb0IsR0FBRyxJQUFBLDBCQUFVLEVBQzVDLG1CQUFtQixFQUNuQixLQUFLLEVBQUUsSUFBNkIsRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUU7SUFDckQsTUFBTSx5QkFBeUIsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUNqRCxlQUFPLENBQUMsWUFBWSxDQUNyQixDQUFBO0lBSUQsTUFBTSxZQUFZLEdBQUcsTUFBTSx5QkFBeUIsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUM5RSxPQUFPLElBQUksNEJBQVksQ0FBQyxZQUFZLENBQUMsQ0FBQTtBQUN2QyxDQUFDLENBQ0YsQ0FBQSJ9
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VuZC1ub3RpZmljYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvd29ya2Zsb3dzL3N0ZXBzL3NlbmQtbm90aWZpY2F0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFEQUFtRDtBQUNuRCxxRUFBNEU7QUFHL0QsUUFBQSxvQkFBb0IsR0FBRyxJQUFBLDBCQUFVLEVBQzVDLG1CQUFtQixFQUNuQixLQUFLLEVBQUUsSUFBNkIsRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUU7SUFDckQsTUFBTSx5QkFBeUIsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUNqRCxlQUFPLENBQUMsWUFBWSxDQUNyQixDQUFBO0lBRUQsTUFBTSxZQUFZLEdBQUcsTUFBTSx5QkFBeUIsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUM5RSxPQUFPLElBQUksNEJBQVksQ0FBQyxZQUFZLENBQUMsQ0FBQTtBQUN2QyxDQUFDLENBQ0YsQ0FBQSJ9
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.syncBrevoContactStep = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const brevo_settings_1 = require("../../modules/brevo-settings");
6
+ /**
7
+ * Step: Sync a contact to Brevo when customer is created or places an order.
8
+ */
9
+ exports.syncBrevoContactStep = (0, workflows_sdk_1.createStep)("sync-brevo-contact", async (input, { container }) => {
10
+ const logger = container.resolve("logger");
11
+ // Check if contact sync is enabled
12
+ let settings;
13
+ try {
14
+ const brevoSettingsService = container.resolve(brevo_settings_1.BREVO_SETTINGS_MODULE);
15
+ settings = await brevoSettingsService.getSettings();
16
+ }
17
+ catch {
18
+ settings = {};
19
+ }
20
+ if (!settings?.contact_sync_enabled) {
21
+ logger.info("[Brevo] Contact sync disabled, skipping.");
22
+ return new workflows_sdk_1.StepResponse({ synced: false });
23
+ }
24
+ try {
25
+ const notificationService = container.resolve("notification");
26
+ // Access the brevo provider directly
27
+ const providers = notificationService.providersMap_ || notificationService.providers_;
28
+ let brevoProvider = null;
29
+ // Try to find the brevo provider
30
+ if (providers) {
31
+ for (const [, provider] of providers) {
32
+ if (provider?.constructor?.identifier === "brevo" || provider?.syncContact) {
33
+ brevoProvider = provider;
34
+ break;
35
+ }
36
+ }
37
+ }
38
+ if (brevoProvider?.syncContact) {
39
+ await brevoProvider.syncContact({
40
+ email: input.email,
41
+ firstName: input.firstName,
42
+ lastName: input.lastName,
43
+ phone: input.phone,
44
+ listIds: settings.contact_sync_list_id ? [settings.contact_sync_list_id] : undefined,
45
+ attributes: input.orderId ? { LAST_ORDER_ID: input.orderId } : undefined,
46
+ });
47
+ }
48
+ else {
49
+ logger.warn("[Brevo] Could not find Brevo provider for contact sync");
50
+ }
51
+ }
52
+ catch (error) {
53
+ logger.warn(`[Brevo] Contact sync error: ${error?.message}`);
54
+ }
55
+ return new workflows_sdk_1.StepResponse({ synced: true });
56
+ });
57
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1icmV2by1jb250YWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9zdGVwcy9zeW5jLWJyZXZvLWNvbnRhY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBQTRFO0FBQzVFLGlFQUFvRTtBQUVwRTs7R0FFRztBQUNVLFFBQUEsb0JBQW9CLEdBQUcsSUFBQSwwQkFBVSxFQUMxQyxvQkFBb0IsRUFDcEIsS0FBSyxFQUFFLEtBTU4sRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUU7SUFDaEIsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQTtJQUUxQyxtQ0FBbUM7SUFDbkMsSUFBSSxRQUFhLENBQUE7SUFDakIsSUFBSSxDQUFDO1FBQ0QsTUFBTSxvQkFBb0IsR0FBUSxTQUFTLENBQUMsT0FBTyxDQUFDLHNDQUFxQixDQUFDLENBQUE7UUFDMUUsUUFBUSxHQUFHLE1BQU0sb0JBQW9CLENBQUMsV0FBVyxFQUFFLENBQUE7SUFDdkQsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNMLFFBQVEsR0FBRyxFQUFFLENBQUE7SUFDakIsQ0FBQztJQUVELElBQUksQ0FBQyxRQUFRLEVBQUUsb0JBQW9CLEVBQUUsQ0FBQztRQUNsQyxNQUFNLENBQUMsSUFBSSxDQUFDLDBDQUEwQyxDQUFDLENBQUE7UUFDdkQsT0FBTyxJQUFJLDRCQUFZLENBQUMsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQTtJQUM5QyxDQUFDO0lBRUQsSUFBSSxDQUFDO1FBQ0QsTUFBTSxtQkFBbUIsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFBO1FBQzdELHFDQUFxQztRQUNyQyxNQUFNLFNBQVMsR0FBSSxtQkFBMkIsQ0FBQyxhQUFhLElBQUssbUJBQTJCLENBQUMsVUFBVSxDQUFBO1FBQ3ZHLElBQUksYUFBYSxHQUFRLElBQUksQ0FBQTtRQUU3QixpQ0FBaUM7UUFDakMsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUNaLEtBQUssTUFBTSxDQUFDLEVBQUUsUUFBUSxDQUFDLElBQUksU0FBUyxFQUFFLENBQUM7Z0JBQ25DLElBQUksUUFBUSxFQUFFLFdBQVcsRUFBRSxVQUFVLEtBQUssT0FBTyxJQUFJLFFBQVEsRUFBRSxXQUFXLEVBQUUsQ0FBQztvQkFDekUsYUFBYSxHQUFHLFFBQVEsQ0FBQTtvQkFDeEIsTUFBSztnQkFDVCxDQUFDO1lBQ0wsQ0FBQztRQUNMLENBQUM7UUFFRCxJQUFJLGFBQWEsRUFBRSxXQUFXLEVBQUUsQ0FBQztZQUM3QixNQUFNLGFBQWEsQ0FBQyxXQUFXLENBQUM7Z0JBQzVCLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSztnQkFDbEIsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTO2dCQUMxQixRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVE7Z0JBQ3hCLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSztnQkFDbEIsT0FBTyxFQUFFLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztnQkFDcEYsVUFBVSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUzthQUMzRSxDQUFDLENBQUE7UUFDTixDQUFDO2FBQU0sQ0FBQztZQUNKLE1BQU0sQ0FBQyxJQUFJLENBQUMsd0RBQXdELENBQUMsQ0FBQTtRQUN6RSxDQUFDO0lBQ0wsQ0FBQztJQUFDLE9BQU8sS0FBVSxFQUFFLENBQUM7UUFDbEIsTUFBTSxDQUFDLElBQUksQ0FBQywrQkFBK0IsS0FBSyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUE7SUFDaEUsQ0FBQztJQUVELE9BQU8sSUFBSSw0QkFBWSxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7QUFDN0MsQ0FBQyxDQUNKLENBQUEifQ==
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.trackBrevoEventStep = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const brevo_settings_1 = require("../../modules/brevo-settings");
6
+ /**
7
+ * Step: Track an event in Brevo for automation triggers.
8
+ */
9
+ exports.trackBrevoEventStep = (0, workflows_sdk_1.createStep)("track-brevo-event", async (input, { container }) => {
10
+ const logger = container.resolve("logger");
11
+ let settings;
12
+ try {
13
+ const brevoSettingsService = container.resolve(brevo_settings_1.BREVO_SETTINGS_MODULE);
14
+ settings = await brevoSettingsService.getSettings();
15
+ }
16
+ catch {
17
+ settings = {};
18
+ }
19
+ if (!settings?.event_tracking_enabled) {
20
+ return new workflows_sdk_1.StepResponse({ tracked: false });
21
+ }
22
+ try {
23
+ const notificationService = container.resolve("notification");
24
+ const providers = notificationService.providersMap_ || notificationService.providers_;
25
+ let brevoProvider = null;
26
+ if (providers) {
27
+ for (const [, provider] of providers) {
28
+ if (provider?.constructor?.identifier === "brevo" || provider?.trackEvent) {
29
+ brevoProvider = provider;
30
+ break;
31
+ }
32
+ }
33
+ }
34
+ if (brevoProvider?.trackEvent) {
35
+ await brevoProvider.trackEvent({
36
+ email: input.email,
37
+ event: input.event,
38
+ eventdata: input.eventdata,
39
+ });
40
+ }
41
+ }
42
+ catch (error) {
43
+ logger.warn(`[Brevo] Event tracking error: ${error?.message}`);
44
+ }
45
+ return new workflows_sdk_1.StepResponse({ tracked: true });
46
+ });
47
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2stYnJldm8tZXZlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvd29ya2Zsb3dzL3N0ZXBzL3RyYWNrLWJyZXZvLWV2ZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFFQUE0RTtBQUM1RSxpRUFBb0U7QUFFcEU7O0dBRUc7QUFDVSxRQUFBLG1CQUFtQixHQUFHLElBQUEsMEJBQVUsRUFDekMsbUJBQW1CLEVBQ25CLEtBQUssRUFBRSxLQUlOLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFO0lBQ2hCLE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUE7SUFFMUMsSUFBSSxRQUFhLENBQUE7SUFDakIsSUFBSSxDQUFDO1FBQ0QsTUFBTSxvQkFBb0IsR0FBUSxTQUFTLENBQUMsT0FBTyxDQUFDLHNDQUFxQixDQUFDLENBQUE7UUFDMUUsUUFBUSxHQUFHLE1BQU0sb0JBQW9CLENBQUMsV0FBVyxFQUFFLENBQUE7SUFDdkQsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNMLFFBQVEsR0FBRyxFQUFFLENBQUE7SUFDakIsQ0FBQztJQUVELElBQUksQ0FBQyxRQUFRLEVBQUUsc0JBQXNCLEVBQUUsQ0FBQztRQUNwQyxPQUFPLElBQUksNEJBQVksQ0FBQyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFBO0lBQy9DLENBQUM7SUFFRCxJQUFJLENBQUM7UUFDRCxNQUFNLG1CQUFtQixHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUE7UUFDN0QsTUFBTSxTQUFTLEdBQUksbUJBQTJCLENBQUMsYUFBYSxJQUFLLG1CQUEyQixDQUFDLFVBQVUsQ0FBQTtRQUN2RyxJQUFJLGFBQWEsR0FBUSxJQUFJLENBQUE7UUFFN0IsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUNaLEtBQUssTUFBTSxDQUFDLEVBQUUsUUFBUSxDQUFDLElBQUksU0FBUyxFQUFFLENBQUM7Z0JBQ25DLElBQUksUUFBUSxFQUFFLFdBQVcsRUFBRSxVQUFVLEtBQUssT0FBTyxJQUFJLFFBQVEsRUFBRSxVQUFVLEVBQUUsQ0FBQztvQkFDeEUsYUFBYSxHQUFHLFFBQVEsQ0FBQTtvQkFDeEIsTUFBSztnQkFDVCxDQUFDO1lBQ0wsQ0FBQztRQUNMLENBQUM7UUFFRCxJQUFJLGFBQWEsRUFBRSxVQUFVLEVBQUUsQ0FBQztZQUM1QixNQUFNLGFBQWEsQ0FBQyxVQUFVLENBQUM7Z0JBQzNCLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSztnQkFDbEIsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLO2dCQUNsQixTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7YUFDN0IsQ0FBQyxDQUFBO1FBQ04sQ0FBQztJQUNMLENBQUM7SUFBQyxPQUFPLEtBQVUsRUFBRSxDQUFDO1FBQ2xCLE1BQU0sQ0FBQyxJQUFJLENBQUMsaUNBQWlDLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFBO0lBQ2xFLENBQUM7SUFFRCxPQUFPLElBQUksNEJBQVksQ0FBQyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFBO0FBQzlDLENBQUMsQ0FDSixDQUFBIn0=