@infuro/cms-core 1.0.47 → 1.0.50
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/README.md +30 -16
- package/dist/admin.cjs +1172 -38
- package/dist/admin.js +1173 -39
- package/dist/api.cjs +37 -37
- package/dist/api.js +5 -5
- package/dist/auth.cjs +52 -23
- package/dist/auth.d.cts +101 -2
- package/dist/auth.d.ts +101 -2
- package/dist/auth.js +3 -2
- package/dist/chunk-3EOM4V2M.cjs +452 -0
- package/dist/{chunk-2HU5R2JE.js → chunk-AYERBA7I.js} +1 -7
- package/dist/{chunk-YXH2UUEZ.js → chunk-IPDHT2UV.js} +257 -16
- package/dist/{chunk-XUCKZPML.cjs → chunk-JCMOOPNX.cjs} +2696 -2601
- package/dist/{chunk-W42UZLQO.js → chunk-LT2WOPKA.js} +2642 -2540
- package/dist/chunk-RK5ETF2I.js +434 -0
- package/dist/{chunk-4PMK3RNA.cjs → chunk-TJ2MIQUT.cjs} +1 -7
- package/dist/{chunk-LMJ7RKPF.cjs → chunk-UUWAUHUW.cjs} +279 -16
- package/dist/{chunk-YC4NUZCS.js → chunk-WRKV6MHB.js} +414 -2
- package/dist/{chunk-Q3HQEM4R.cjs → chunk-YV5PK4JW.cjs} +421 -1
- package/dist/cli.cjs +13 -22
- package/dist/cli.js +13 -22
- package/dist/{event-order-defaults-7Z3UZOEH.cjs → event-order-defaults-DU7V3YND.cjs} +9 -9
- package/dist/{event-order-defaults-XQ3IDPD7.js → event-order-defaults-H4RT7NMR.js} +1 -1
- package/dist/index.cjs +327 -291
- package/dist/index.d.cts +132 -5
- package/dist/index.d.ts +132 -5
- package/dist/index.js +8 -8
- package/dist/migrations/1782400000000-CreateUserDeviceTokens.ts +36 -0
- package/dist/migrations/1782500000000-AddPushToOrderNotificationBindingsChannelEnum.ts +15 -0
- package/dist/{order-notification-dispatcher-6WNG24NY.js → order-notification-dispatcher-3TA4ETYJ.js} +1 -1
- package/dist/{order-notification-dispatcher-6XSU3AR7.cjs → order-notification-dispatcher-ZEAZ5SHV.cjs} +7 -3
- package/package.json +1 -1
- package/dist/chunk-VUQFARRT.cjs +0 -182
- package/dist/chunk-ZF2RQWXB.js +0 -171
|
@@ -8,11 +8,31 @@ var chunkUSNT2KNT_cjs = require('./chunk-USNT2KNT.cjs');
|
|
|
8
8
|
var clientSes = require('@aws-sdk/client-ses');
|
|
9
9
|
var module$1 = require('module');
|
|
10
10
|
var nodemailer = require('nodemailer');
|
|
11
|
+
var crypto = require('crypto');
|
|
11
12
|
|
|
12
13
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
13
14
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
15
|
|
|
16
|
+
function _interopNamespace(e) {
|
|
17
|
+
if (e && e.__esModule) return e;
|
|
18
|
+
var n = Object.create(null);
|
|
19
|
+
if (e) {
|
|
20
|
+
Object.keys(e).forEach(function (k) {
|
|
21
|
+
if (k !== 'default') {
|
|
22
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
23
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
get: function () { return e[k]; }
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
n.default = e;
|
|
31
|
+
return Object.freeze(n);
|
|
32
|
+
}
|
|
33
|
+
|
|
15
34
|
var nodemailer__default = /*#__PURE__*/_interopDefault(nodemailer);
|
|
35
|
+
var crypto__namespace = /*#__PURE__*/_interopNamespace(crypto);
|
|
16
36
|
|
|
17
37
|
// src/lib/event-order-template-context.ts
|
|
18
38
|
function resolvePublicSiteUrl() {
|
|
@@ -33,12 +53,6 @@ function buildOrderTrackUrl(qrToken, siteUrl, orderNumber) {
|
|
|
33
53
|
return `${base}/track/${token}`;
|
|
34
54
|
}
|
|
35
55
|
chunkUSNT2KNT_cjs.__name(buildOrderTrackUrl, "buildOrderTrackUrl");
|
|
36
|
-
function buildOrderQrImageUrl(trackUrl, size = 200, fallbackData) {
|
|
37
|
-
const data = trackUrl.trim() || fallbackData?.trim() || "";
|
|
38
|
-
if (!data) return "";
|
|
39
|
-
return `https://api.qrserver.com/v1/create-qr-code/?size=${size}x${size}&data=${encodeURIComponent(data)}`;
|
|
40
|
-
}
|
|
41
|
-
chunkUSNT2KNT_cjs.__name(buildOrderQrImageUrl, "buildOrderQrImageUrl");
|
|
42
56
|
function formatOrderDetailsText(input) {
|
|
43
57
|
const { orderNumber, total, currency, lines } = input;
|
|
44
58
|
const header = `Order: ${orderNumber}
|
|
@@ -60,8 +74,6 @@ chunkUSNT2KNT_cjs.__name(formatOrderDetailsHtml, "formatOrderDetailsHtml");
|
|
|
60
74
|
function buildEventOrderTemplateVariables(input) {
|
|
61
75
|
const { event, order, contact, productNames, vendorName = "", orderLines = [], siteUrl } = input;
|
|
62
76
|
const trackUrl = buildOrderTrackUrl(order.qrToken, siteUrl, order.orderNumber);
|
|
63
|
-
const qrImageUrl = buildOrderQrImageUrl(trackUrl, 200, order.orderNumber);
|
|
64
|
-
const ticketQr = qrImageUrl ? `<img src="${qrImageUrl}" alt="Ticket QR Code" width="200" height="200" style="display:block;margin:12px 0;border:1px solid #e5e7eb;border-radius:8px;" />` : "";
|
|
65
77
|
const baseSite = (siteUrl ?? resolvePublicSiteUrl()).replace(/\/+$/, "");
|
|
66
78
|
const invoiceNumber = `INV-${order.orderNumber ?? ""}`;
|
|
67
79
|
const invoiceUrl = baseSite ? `${baseSite}/api/orders/${order.orderNumber ?? ""}/invoice` : `/api/orders/${order.orderNumber ?? ""}/invoice`;
|
|
@@ -85,8 +97,6 @@ function buildEventOrderTemplateVariables(input) {
|
|
|
85
97
|
customerPhone: contact.phone?.trim() || "",
|
|
86
98
|
productNames,
|
|
87
99
|
trackUrl,
|
|
88
|
-
qrImageUrl,
|
|
89
|
-
ticketQr,
|
|
90
100
|
invoiceNumber,
|
|
91
101
|
invoiceUrl,
|
|
92
102
|
orderDetails: formatOrderDetailsText(orderDetailsPayload),
|
|
@@ -504,7 +514,7 @@ var WhatsAppService = class {
|
|
|
504
514
|
let body = opts.body?.trim() ?? "";
|
|
505
515
|
const variables = opts.variables ?? {};
|
|
506
516
|
if (opts.templateKey?.trim() && this.getMessageTemplateRow) {
|
|
507
|
-
const { resolveEventOrderTemplate, EVENT_ORDER_TEMPLATE_KEY } = await import('./event-order-defaults-
|
|
517
|
+
const { resolveEventOrderTemplate, EVENT_ORDER_TEMPLATE_KEY } = await import('./event-order-defaults-DU7V3YND.cjs');
|
|
508
518
|
if (opts.templateKey.trim() === EVENT_ORDER_TEMPLATE_KEY) {
|
|
509
519
|
const resolved = await resolveEventOrderTemplate("whatsapp", async (ch, key) => {
|
|
510
520
|
const row = await this.getMessageTemplateRow(ch, key);
|
|
@@ -1316,7 +1326,7 @@ function renderEmail(templateName, ctx, options) {
|
|
|
1316
1326
|
chunkUSNT2KNT_cjs.__name(renderEmail, "renderEmail");
|
|
1317
1327
|
|
|
1318
1328
|
// src/plugins/email/email-service.ts
|
|
1319
|
-
var require2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-
|
|
1329
|
+
var require2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-UUWAUHUW.cjs', document.baseURI).href)));
|
|
1320
1330
|
var MailComposer = require2("nodemailer/lib/mail-composer");
|
|
1321
1331
|
var SES_REGIONS_WITHOUT_SMTP = /* @__PURE__ */ new Set([
|
|
1322
1332
|
"af-south-1",
|
|
@@ -2068,6 +2078,162 @@ function emailPlugin(config) {
|
|
|
2068
2078
|
};
|
|
2069
2079
|
}
|
|
2070
2080
|
chunkUSNT2KNT_cjs.__name(emailPlugin, "emailPlugin");
|
|
2081
|
+
function base64UrlEncode(str) {
|
|
2082
|
+
const buf = typeof str === "string" ? Buffer.from(str, "utf8") : str;
|
|
2083
|
+
return buf.toString("base64").replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
|
|
2084
|
+
}
|
|
2085
|
+
chunkUSNT2KNT_cjs.__name(base64UrlEncode, "base64UrlEncode");
|
|
2086
|
+
async function getGoogleAccessToken(clientEmail, privateKey) {
|
|
2087
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
2088
|
+
const header = {
|
|
2089
|
+
alg: "RS256",
|
|
2090
|
+
typ: "JWT"
|
|
2091
|
+
};
|
|
2092
|
+
const claimSet = {
|
|
2093
|
+
iss: clientEmail,
|
|
2094
|
+
scope: "https://www.googleapis.com/auth/firebase.messaging",
|
|
2095
|
+
aud: "https://oauth2.googleapis.com/token",
|
|
2096
|
+
exp: now + 3600,
|
|
2097
|
+
iat: now
|
|
2098
|
+
};
|
|
2099
|
+
const encodedHeader = base64UrlEncode(JSON.stringify(header));
|
|
2100
|
+
const encodedClaimSet = base64UrlEncode(JSON.stringify(claimSet));
|
|
2101
|
+
const signatureInput = `${encodedHeader}.${encodedClaimSet}`;
|
|
2102
|
+
const formattedKey = privateKey.replace(/\\n/g, "\n");
|
|
2103
|
+
const signer = crypto__namespace.createSign("RSA-SHA256");
|
|
2104
|
+
signer.update(signatureInput);
|
|
2105
|
+
const signature = signer.sign(formattedKey, "base64");
|
|
2106
|
+
const jwt = `${signatureInput}.${signature.replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_")}`;
|
|
2107
|
+
const tokenRes = await fetch("https://oauth2.googleapis.com/token", {
|
|
2108
|
+
method: "POST",
|
|
2109
|
+
headers: {
|
|
2110
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
2111
|
+
},
|
|
2112
|
+
body: new URLSearchParams({
|
|
2113
|
+
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
|
|
2114
|
+
assertion: jwt
|
|
2115
|
+
}).toString()
|
|
2116
|
+
});
|
|
2117
|
+
if (!tokenRes.ok) {
|
|
2118
|
+
const errText = await tokenRes.text();
|
|
2119
|
+
throw new Error(`Failed to obtain Google access token: ${errText}`);
|
|
2120
|
+
}
|
|
2121
|
+
const tokenData = await tokenRes.json();
|
|
2122
|
+
if (!tokenData.access_token) {
|
|
2123
|
+
throw new Error("Google OAuth token response missing access_token");
|
|
2124
|
+
}
|
|
2125
|
+
return tokenData.access_token;
|
|
2126
|
+
}
|
|
2127
|
+
chunkUSNT2KNT_cjs.__name(getGoogleAccessToken, "getGoogleAccessToken");
|
|
2128
|
+
async function resolveFcmServiceAccount(dataSource, entityMap) {
|
|
2129
|
+
const pushSettings = await getSettingsGroup(dataSource, entityMap, "push");
|
|
2130
|
+
let projectId = pushSettings.firebase_project_id?.trim();
|
|
2131
|
+
let clientEmail = pushSettings.firebase_client_email?.trim();
|
|
2132
|
+
let privateKey = pushSettings.firebase_private_key?.trim();
|
|
2133
|
+
if (pushSettings.firebase_service_account_json?.trim()) {
|
|
2134
|
+
try {
|
|
2135
|
+
const parsed = JSON.parse(pushSettings.firebase_service_account_json.trim());
|
|
2136
|
+
if (parsed.project_id) projectId = parsed.project_id;
|
|
2137
|
+
if (parsed.client_email) clientEmail = parsed.client_email;
|
|
2138
|
+
if (parsed.private_key) privateKey = parsed.private_key;
|
|
2139
|
+
} catch {
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
if (!projectId || !clientEmail || !privateKey) {
|
|
2143
|
+
return {
|
|
2144
|
+
ok: false,
|
|
2145
|
+
error: "Firebase Service Account JSON / credentials are not configured"
|
|
2146
|
+
};
|
|
2147
|
+
}
|
|
2148
|
+
return {
|
|
2149
|
+
ok: true,
|
|
2150
|
+
account: {
|
|
2151
|
+
projectId,
|
|
2152
|
+
clientEmail,
|
|
2153
|
+
privateKey
|
|
2154
|
+
}
|
|
2155
|
+
};
|
|
2156
|
+
}
|
|
2157
|
+
chunkUSNT2KNT_cjs.__name(resolveFcmServiceAccount, "resolveFcmServiceAccount");
|
|
2158
|
+
async function validateFcmCredentials(dataSource, entityMap) {
|
|
2159
|
+
try {
|
|
2160
|
+
const resolved = await resolveFcmServiceAccount(dataSource, entityMap);
|
|
2161
|
+
if (!resolved.ok) {
|
|
2162
|
+
return {
|
|
2163
|
+
success: false,
|
|
2164
|
+
error: resolved.error
|
|
2165
|
+
};
|
|
2166
|
+
}
|
|
2167
|
+
const { projectId, clientEmail, privateKey } = resolved.account;
|
|
2168
|
+
await getGoogleAccessToken(clientEmail, privateKey);
|
|
2169
|
+
return {
|
|
2170
|
+
success: true,
|
|
2171
|
+
projectId,
|
|
2172
|
+
clientEmail
|
|
2173
|
+
};
|
|
2174
|
+
} catch (err) {
|
|
2175
|
+
const errorMsg = err instanceof Error ? err.message : "Unknown credential validation error";
|
|
2176
|
+
console.error("[fcm-push] Exception in validateFcmCredentials", errorMsg);
|
|
2177
|
+
return {
|
|
2178
|
+
success: false,
|
|
2179
|
+
error: errorMsg
|
|
2180
|
+
};
|
|
2181
|
+
}
|
|
2182
|
+
}
|
|
2183
|
+
chunkUSNT2KNT_cjs.__name(validateFcmCredentials, "validateFcmCredentials");
|
|
2184
|
+
async function sendFcmPushNotification(dataSource, entityMap, msg) {
|
|
2185
|
+
try {
|
|
2186
|
+
const resolved = await resolveFcmServiceAccount(dataSource, entityMap);
|
|
2187
|
+
if (!resolved.ok) {
|
|
2188
|
+
return {
|
|
2189
|
+
success: false,
|
|
2190
|
+
error: resolved.error
|
|
2191
|
+
};
|
|
2192
|
+
}
|
|
2193
|
+
const { projectId, clientEmail, privateKey } = resolved.account;
|
|
2194
|
+
const accessToken = await getGoogleAccessToken(clientEmail, privateKey);
|
|
2195
|
+
const fcmEndpoint = `https://fcm.googleapis.com/v1/projects/${projectId}/messages:send`;
|
|
2196
|
+
const fcmPayload = {
|
|
2197
|
+
message: {
|
|
2198
|
+
token: msg.token,
|
|
2199
|
+
notification: {
|
|
2200
|
+
title: msg.title,
|
|
2201
|
+
body: msg.body
|
|
2202
|
+
},
|
|
2203
|
+
data: msg.data || {}
|
|
2204
|
+
}
|
|
2205
|
+
};
|
|
2206
|
+
const response = await fetch(fcmEndpoint, {
|
|
2207
|
+
method: "POST",
|
|
2208
|
+
headers: {
|
|
2209
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
2210
|
+
"Content-Type": "application/json"
|
|
2211
|
+
},
|
|
2212
|
+
body: JSON.stringify(fcmPayload)
|
|
2213
|
+
});
|
|
2214
|
+
const resData = await response.json();
|
|
2215
|
+
if (!response.ok) {
|
|
2216
|
+
const errorMsg = resData.error?.message || "FCM request failed";
|
|
2217
|
+
console.error("[fcm-push] Error sending push notification", errorMsg);
|
|
2218
|
+
return {
|
|
2219
|
+
success: false,
|
|
2220
|
+
error: errorMsg
|
|
2221
|
+
};
|
|
2222
|
+
}
|
|
2223
|
+
return {
|
|
2224
|
+
success: true,
|
|
2225
|
+
messageId: resData.name
|
|
2226
|
+
};
|
|
2227
|
+
} catch (err) {
|
|
2228
|
+
const errorMsg = err instanceof Error ? err.message : "Unknown push error";
|
|
2229
|
+
console.error("[fcm-push] Exception in sendFcmPushNotification", errorMsg);
|
|
2230
|
+
return {
|
|
2231
|
+
success: false,
|
|
2232
|
+
error: errorMsg
|
|
2233
|
+
};
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2236
|
+
chunkUSNT2KNT_cjs.__name(sendFcmPushNotification, "sendFcmPushNotification");
|
|
2071
2237
|
|
|
2072
2238
|
// src/lib/order-notification-dispatcher.ts
|
|
2073
2239
|
var initialized = false;
|
|
@@ -2218,6 +2384,82 @@ async function isAudienceEmailEnabled(dataSource, entityMap, audience) {
|
|
|
2218
2384
|
return settings[key] !== "false" && settings[key] !== "0";
|
|
2219
2385
|
}
|
|
2220
2386
|
chunkUSNT2KNT_cjs.__name(isAudienceEmailEnabled, "isAudienceEmailEnabled");
|
|
2387
|
+
async function isPushNotificationsEnabled(dataSource, entityMap) {
|
|
2388
|
+
const settings = await getSettingsGroup(dataSource, entityMap, "event_notifications");
|
|
2389
|
+
if (settings.enabled === "false" || settings.enabled === "0") return false;
|
|
2390
|
+
return settings.push_enabled !== "false" && settings.push_enabled !== "0";
|
|
2391
|
+
}
|
|
2392
|
+
chunkUSNT2KNT_cjs.__name(isPushNotificationsEnabled, "isPushNotificationsEnabled");
|
|
2393
|
+
async function isAudiencePushEnabled(dataSource, entityMap, audience) {
|
|
2394
|
+
const settings = await getSettingsGroup(dataSource, entityMap, "event_notifications");
|
|
2395
|
+
if (settings.enabled === "false" || settings.enabled === "0") return false;
|
|
2396
|
+
if (settings.push_enabled === "false" || settings.push_enabled === "0") return false;
|
|
2397
|
+
const key = `push_${audience}_enabled`;
|
|
2398
|
+
return settings[key] !== "false" && settings[key] !== "0";
|
|
2399
|
+
}
|
|
2400
|
+
chunkUSNT2KNT_cjs.__name(isAudiencePushEnabled, "isAudiencePushEnabled");
|
|
2401
|
+
async function sendPushNotificationForTrigger(triggerKey, orderId, audienceType, targetId, variables, dataSource, entityMap) {
|
|
2402
|
+
let template = await loadBoundTemplate(triggerKey, "mobile", audienceType, dataSource, entityMap);
|
|
2403
|
+
if (!template) {
|
|
2404
|
+
template = await loadBoundTemplate(triggerKey, "push", audienceType, dataSource, entityMap);
|
|
2405
|
+
}
|
|
2406
|
+
if (!template || !template.body) return;
|
|
2407
|
+
const rawTitle = template.subject?.trim() || "Order Notification";
|
|
2408
|
+
const title = chunkOOTLNH63_cjs.applyTemplateVars(rawTitle, variables);
|
|
2409
|
+
const body = chunkOOTLNH63_cjs.applyTemplateVars(template.body, variables);
|
|
2410
|
+
if (!entityMap.user_device_tokens) return;
|
|
2411
|
+
const tokenRepo = dataSource.getRepository(entityMap.user_device_tokens);
|
|
2412
|
+
let targetTokens = [];
|
|
2413
|
+
try {
|
|
2414
|
+
if (audienceType === "customers") {
|
|
2415
|
+
targetTokens = await tokenRepo.find({
|
|
2416
|
+
where: {
|
|
2417
|
+
userId: targetId,
|
|
2418
|
+
isActive: true
|
|
2419
|
+
},
|
|
2420
|
+
select: [
|
|
2421
|
+
"token"
|
|
2422
|
+
]
|
|
2423
|
+
});
|
|
2424
|
+
} else if (audienceType === "vendors") {
|
|
2425
|
+
targetTokens = await tokenRepo.find({
|
|
2426
|
+
where: {
|
|
2427
|
+
vendorId: targetId,
|
|
2428
|
+
isActive: true
|
|
2429
|
+
},
|
|
2430
|
+
select: [
|
|
2431
|
+
"token"
|
|
2432
|
+
]
|
|
2433
|
+
});
|
|
2434
|
+
} else if (audienceType === "admin") {
|
|
2435
|
+
targetTokens = await tokenRepo.find({
|
|
2436
|
+
where: {
|
|
2437
|
+
isActive: true
|
|
2438
|
+
},
|
|
2439
|
+
select: [
|
|
2440
|
+
"token"
|
|
2441
|
+
]
|
|
2442
|
+
});
|
|
2443
|
+
}
|
|
2444
|
+
} catch (err) {
|
|
2445
|
+
console.error("[order-notifications] Error querying device tokens for push", err);
|
|
2446
|
+
return;
|
|
2447
|
+
}
|
|
2448
|
+
for (const t of targetTokens) {
|
|
2449
|
+
if (t.token?.trim()) {
|
|
2450
|
+
await sendFcmPushNotification(dataSource, entityMap, {
|
|
2451
|
+
token: t.token.trim(),
|
|
2452
|
+
title,
|
|
2453
|
+
body,
|
|
2454
|
+
data: {
|
|
2455
|
+
orderId: String(orderId),
|
|
2456
|
+
triggerKey
|
|
2457
|
+
}
|
|
2458
|
+
});
|
|
2459
|
+
}
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
chunkUSNT2KNT_cjs.__name(sendPushNotificationForTrigger, "sendPushNotificationForTrigger");
|
|
2221
2463
|
async function getOrderVendorEmails(orderId, orderVendorId, dataSource, entityMap) {
|
|
2222
2464
|
const emails = /* @__PURE__ */ new Set();
|
|
2223
2465
|
if (!entityMap.vendors) return [];
|
|
@@ -2480,12 +2722,13 @@ async function handleTrigger(triggerKey, payload, dataSource, entityMap, getCms)
|
|
|
2480
2722
|
return;
|
|
2481
2723
|
}
|
|
2482
2724
|
}
|
|
2483
|
-
const [emailChannelEnabled, whatsappChannelEnabled] = await Promise.all([
|
|
2725
|
+
const [emailChannelEnabled, whatsappChannelEnabled, pushChannelEnabled] = await Promise.all([
|
|
2484
2726
|
isEmailNotificationsEnabled(dataSource, entityMap),
|
|
2485
|
-
isWhatsappNotificationsEnabled(dataSource, entityMap)
|
|
2727
|
+
isWhatsappNotificationsEnabled(dataSource, entityMap),
|
|
2728
|
+
isPushNotificationsEnabled(dataSource, entityMap)
|
|
2486
2729
|
]);
|
|
2487
|
-
if (!emailChannelEnabled && !whatsappChannelEnabled) {
|
|
2488
|
-
console.warn("[order-notifications] skip:
|
|
2730
|
+
if (!emailChannelEnabled && !whatsappChannelEnabled && !pushChannelEnabled) {
|
|
2731
|
+
console.warn("[order-notifications] skip: Email, WhatsApp, and Mobile Push notifications are disabled");
|
|
2489
2732
|
return;
|
|
2490
2733
|
}
|
|
2491
2734
|
const triggerEnabled = await isTriggerCatalogEnabled(triggerKey, dataSource, entityMap);
|
|
@@ -2524,6 +2767,23 @@ async function handleTrigger(triggerKey, payload, dataSource, entityMap, getCms)
|
|
|
2524
2767
|
} else {
|
|
2525
2768
|
console.log("[order-notifications] skip email: Email notifications channel is disabled");
|
|
2526
2769
|
}
|
|
2770
|
+
if (pushChannelEnabled) {
|
|
2771
|
+
const [pushCustomerEnabled, pushVendorEnabled, pushAdminEnabled] = await Promise.all([
|
|
2772
|
+
isAudiencePushEnabled(dataSource, entityMap, "customer"),
|
|
2773
|
+
isAudiencePushEnabled(dataSource, entityMap, "vendor"),
|
|
2774
|
+
isAudiencePushEnabled(dataSource, entityMap, "admin")
|
|
2775
|
+
]);
|
|
2776
|
+
const targetCustomerId = context?.order?.customerContactId || context?.order?.contactId || context?.order?.userId || context?.order?.id;
|
|
2777
|
+
if (pushCustomerEnabled && targetCustomerId) {
|
|
2778
|
+
await sendPushNotificationForTrigger(triggerKey, payload.orderId, "customers", String(targetCustomerId), variables, dataSource, entityMap);
|
|
2779
|
+
}
|
|
2780
|
+
if (pushVendorEnabled && payload.vendorId) {
|
|
2781
|
+
await sendPushNotificationForTrigger(triggerKey, payload.orderId, "vendors", String(payload.vendorId), variables, dataSource, entityMap);
|
|
2782
|
+
}
|
|
2783
|
+
if (pushAdminEnabled) {
|
|
2784
|
+
await sendPushNotificationForTrigger(triggerKey, payload.orderId, "admin", "admin", variables, dataSource, entityMap);
|
|
2785
|
+
}
|
|
2786
|
+
}
|
|
2527
2787
|
if (whatsappChannelEnabled) {
|
|
2528
2788
|
if (contactPhone) {
|
|
2529
2789
|
await sendWhatsAppForTrigger(triggerKey, payload.orderId, contactPhone, variables, dataSource, entityMap, getCms);
|
|
@@ -2610,6 +2870,7 @@ exports.buildTranscriptForLeadEmail = buildTranscriptForLeadEmail;
|
|
|
2610
2870
|
exports.detectChatLeadIntent = detectChatLeadIntent;
|
|
2611
2871
|
exports.emailPlugin = emailPlugin;
|
|
2612
2872
|
exports.emailTemplates = emailTemplates;
|
|
2873
|
+
exports.getSettingsGroup = getSettingsGroup;
|
|
2613
2874
|
exports.initWhatsappTriggerDispatcher = initWhatsappTriggerDispatcher;
|
|
2614
2875
|
exports.isWhatsAppPluginEnabled = isWhatsAppPluginEnabled;
|
|
2615
2876
|
exports.joinRecipientsForSend = joinRecipientsForSend;
|
|
@@ -2623,5 +2884,7 @@ exports.renderLayout = renderLayout;
|
|
|
2623
2884
|
exports.resendOrderNotification = resendOrderNotification;
|
|
2624
2885
|
exports.resolveChatEmailToolSettings = resolveChatEmailToolSettings;
|
|
2625
2886
|
exports.sendChatLeadEmail = sendChatLeadEmail;
|
|
2887
|
+
exports.sendFcmPushNotification = sendFcmPushNotification;
|
|
2626
2888
|
exports.serializeEmailRecipients = serializeEmailRecipients;
|
|
2889
|
+
exports.validateFcmCredentials = validateFcmCredentials;
|
|
2627
2890
|
exports.whatsAppConfigured = whatsAppConfigured;
|