@infuro/cms-core 1.0.64 → 1.0.66
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/dist/admin.cjs +4 -4
- package/dist/admin.js +4 -4
- package/dist/api.cjs +36 -36
- package/dist/api.js +4 -4
- package/dist/{chunk-M25DGZ5J.cjs → chunk-5MZFQRDW.cjs} +242 -45
- package/dist/chunk-FLUF2GZH.js +71 -0
- package/dist/{chunk-OJAYCNE5.js → chunk-NV5IRHI3.js} +240 -43
- package/dist/chunk-PA6YDMFZ.cjs +78 -0
- package/dist/{chunk-FF45VZMM.cjs → chunk-QYRXLURF.cjs} +109 -67
- package/dist/{chunk-DXERXWBR.js → chunk-RCE5SJBA.js} +36 -20
- package/dist/{chunk-K6C3ZSBZ.js → chunk-T33KU5G5.js} +81 -39
- package/dist/chunk-THL5JDWJ.cjs +101 -0
- package/dist/{chunk-PX3BSCIG.cjs → chunk-WMMZZRDJ.cjs} +38 -22
- package/dist/chunk-XJNNOSJR.js +98 -0
- package/dist/{emit-order-notification-trigger-MFCBAE7L.js → emit-order-notification-trigger-EJJZ6XTS.js} +2 -2
- package/dist/{emit-order-notification-trigger-ZRRGCQGB.cjs → emit-order-notification-trigger-ZD5YN3JM.cjs} +4 -4
- package/dist/index.cjs +224 -224
- package/dist/index.d.cts +8 -3
- package/dist/index.d.ts +8 -3
- package/dist/index.js +8 -8
- package/dist/{order-completion-otp-handlers-3W5I3LON.js → order-completion-otp-handlers-LFRHXWK4.js} +2 -2
- package/dist/{order-completion-otp-handlers-RF3DLNV7.cjs → order-completion-otp-handlers-NK65LOLV.cjs} +3 -3
- package/dist/{order-notification-dispatcher-ID2PDEXD.js → order-notification-dispatcher-ECPFI7CD.js} +2 -2
- package/dist/{order-notification-dispatcher-RNEQB3V7.cjs → order-notification-dispatcher-LL7ETKLU.cjs} +7 -7
- package/dist/{pg-boss-service-L6MTF4EQ.cjs → pg-boss-service-BDGOKM2T.cjs} +3 -3
- package/dist/pg-boss-service-WCBJD4JB.js +2 -0
- package/package.json +1 -1
- package/dist/chunk-AYWDQFJZ.js +0 -27
- package/dist/chunk-GO7PPYNU.js +0 -76
- package/dist/chunk-UEE4PTTB.cjs +0 -30
- package/dist/chunk-XQ3QUHWR.cjs +0 -83
- package/dist/pg-boss-service-4XF2TQ2E.js +0 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { queueWhatsApp } from './chunk-GWDI752Q.js';
|
|
2
|
-
import { notificationTriggerEmitter } from './chunk-
|
|
2
|
+
import { notifyLog, logFcmToken, maskNotifyEmail, maskNotifyPhone, notificationTriggerEmitter } from './chunk-FLUF2GZH.js';
|
|
3
3
|
import { sesRegionSupportsSmtp, sesSmtpHost, EmailService, renderLayout } from './chunk-6YOQ7G5O.js';
|
|
4
4
|
import { queueEmail } from './chunk-TU23GJPJ.js';
|
|
5
5
|
import { mergeEmailLayoutCompanyDetails } from './chunk-YRCKEGL2.js';
|
|
@@ -217,7 +217,8 @@ async function loadOrderNotificationContexts(orderId, deps) {
|
|
|
217
217
|
const contact = {
|
|
218
218
|
name: metaBuyerName || rawContact.name,
|
|
219
219
|
email: metaBuyerEmail || metaCheckoutEmail || rawContact.email,
|
|
220
|
-
phone: rawContact.phone
|
|
220
|
+
phone: rawContact.phone,
|
|
221
|
+
userId: rawContact.userId ?? null
|
|
221
222
|
};
|
|
222
223
|
const currency = String(o.currency ?? "INR");
|
|
223
224
|
const siteUrl = resolvePublicSiteUrl();
|
|
@@ -1400,12 +1401,6 @@ var ORDER_NOTIFICATION_DEFAULTS = {
|
|
|
1400
1401
|
|
|
1401
1402
|
// src/lib/order-notification-dispatcher.ts
|
|
1402
1403
|
var initialized = false;
|
|
1403
|
-
function maskPhone2(raw) {
|
|
1404
|
-
const digits = String(raw ?? "").replace(/\D/g, "");
|
|
1405
|
-
if (digits.length <= 4) return "(none)";
|
|
1406
|
-
return `***${digits.slice(-4)}`;
|
|
1407
|
-
}
|
|
1408
|
-
__name(maskPhone2, "maskPhone");
|
|
1409
1404
|
async function getSettingsGroup(dataSource, entityMap, group) {
|
|
1410
1405
|
if (!entityMap.configs) return {};
|
|
1411
1406
|
const rows = await dataSource.getRepository(entityMap.configs).find({
|
|
@@ -1508,7 +1503,17 @@ async function loadBoundTemplate(triggerKey, channel, audienceType = "customers"
|
|
|
1508
1503
|
enabled: true
|
|
1509
1504
|
}
|
|
1510
1505
|
}).catch(() => null);
|
|
1511
|
-
|
|
1506
|
+
let resolvedTemplate = template;
|
|
1507
|
+
if (!resolvedTemplate && (channel === "mobile" || channel === "push")) {
|
|
1508
|
+
resolvedTemplate = await dataSource.getRepository(entityMap.message_templates).findOne({
|
|
1509
|
+
where: {
|
|
1510
|
+
id: templateId,
|
|
1511
|
+
deleted: false,
|
|
1512
|
+
enabled: true
|
|
1513
|
+
}
|
|
1514
|
+
}).catch(() => null);
|
|
1515
|
+
}
|
|
1516
|
+
if (!resolvedTemplate) {
|
|
1512
1517
|
const defChannel = ORDER_NOTIFICATION_DEFAULTS[channel];
|
|
1513
1518
|
const def = defChannel ? defChannel[triggerKey] : null;
|
|
1514
1519
|
if (def) {
|
|
@@ -1533,7 +1538,7 @@ async function loadBoundTemplate(triggerKey, channel, audienceType = "customers"
|
|
|
1533
1538
|
});
|
|
1534
1539
|
return null;
|
|
1535
1540
|
}
|
|
1536
|
-
return
|
|
1541
|
+
return resolvedTemplate;
|
|
1537
1542
|
} catch (err) {
|
|
1538
1543
|
const defChannel = ORDER_NOTIFICATION_DEFAULTS[channel];
|
|
1539
1544
|
const def = defChannel ? defChannel[triggerKey] : null;
|
|
@@ -1615,11 +1620,26 @@ async function sendPushNotificationForTrigger(triggerKey, orderId, audienceType,
|
|
|
1615
1620
|
if (!template) {
|
|
1616
1621
|
template = await loadBoundTemplate(triggerKey, "push", audienceType, dataSource, entityMap);
|
|
1617
1622
|
}
|
|
1618
|
-
if (!template || !template.body)
|
|
1623
|
+
if (!template || !template.body) {
|
|
1624
|
+
notifyLog.skip("PUSH", "no mobile/push template or empty body", {
|
|
1625
|
+
triggerKey,
|
|
1626
|
+
orderId,
|
|
1627
|
+
audienceType,
|
|
1628
|
+
targetId
|
|
1629
|
+
});
|
|
1630
|
+
return;
|
|
1631
|
+
}
|
|
1619
1632
|
const rawTitle = template.subject?.trim() || "Order Notification";
|
|
1620
1633
|
const title = applyTemplateVars(rawTitle, variables);
|
|
1621
1634
|
const body = applyTemplateVars(template.body, variables);
|
|
1622
|
-
if (!entityMap.user_device_tokens)
|
|
1635
|
+
if (!entityMap.user_device_tokens) {
|
|
1636
|
+
notifyLog.skip("PUSH", "user_device_tokens entity not registered", {
|
|
1637
|
+
triggerKey,
|
|
1638
|
+
orderId,
|
|
1639
|
+
audienceType
|
|
1640
|
+
});
|
|
1641
|
+
return;
|
|
1642
|
+
}
|
|
1623
1643
|
const tokenRepo = dataSource.getRepository(entityMap.user_device_tokens);
|
|
1624
1644
|
let targetTokens = [];
|
|
1625
1645
|
try {
|
|
@@ -1654,19 +1674,67 @@ async function sendPushNotificationForTrigger(triggerKey, orderId, audienceType,
|
|
|
1654
1674
|
});
|
|
1655
1675
|
}
|
|
1656
1676
|
} catch (err) {
|
|
1657
|
-
|
|
1677
|
+
notifyLog.error("PUSH", "device token query failed", {
|
|
1678
|
+
triggerKey,
|
|
1679
|
+
orderId,
|
|
1680
|
+
audienceType,
|
|
1681
|
+
targetId,
|
|
1682
|
+
error: err instanceof Error ? err.message : String(err)
|
|
1683
|
+
});
|
|
1658
1684
|
return;
|
|
1659
1685
|
}
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1686
|
+
const tokens = targetTokens.map((t) => t.token?.trim()).filter(Boolean);
|
|
1687
|
+
notifyLog.push("sending", {
|
|
1688
|
+
triggerKey,
|
|
1689
|
+
orderId,
|
|
1690
|
+
audienceType,
|
|
1691
|
+
targetId,
|
|
1692
|
+
title,
|
|
1693
|
+
tokenCount: tokens.length,
|
|
1694
|
+
fcmTokens: tokens.map((t) => logFcmToken(t))
|
|
1695
|
+
});
|
|
1696
|
+
if (tokens.length === 0) {
|
|
1697
|
+
notifyLog.skip("PUSH", "no active FCM tokens for target", {
|
|
1698
|
+
triggerKey,
|
|
1699
|
+
orderId,
|
|
1700
|
+
audienceType,
|
|
1701
|
+
targetId,
|
|
1702
|
+
hint: "App must POST /api/user-device-tokens after login"
|
|
1703
|
+
});
|
|
1704
|
+
return;
|
|
1705
|
+
}
|
|
1706
|
+
for (const token of tokens) {
|
|
1707
|
+
notifyLog.push("FCM target", {
|
|
1708
|
+
triggerKey,
|
|
1709
|
+
orderId,
|
|
1710
|
+
audienceType,
|
|
1711
|
+
targetId,
|
|
1712
|
+
fcmToken: logFcmToken(token)
|
|
1713
|
+
});
|
|
1714
|
+
const res = await sendFcmPushNotification(dataSource, entityMap, {
|
|
1715
|
+
token,
|
|
1716
|
+
title,
|
|
1717
|
+
body,
|
|
1718
|
+
data: {
|
|
1719
|
+
orderId: String(orderId),
|
|
1720
|
+
triggerKey
|
|
1721
|
+
}
|
|
1722
|
+
});
|
|
1723
|
+
if (res.success) {
|
|
1724
|
+
notifyLog.push("FCM sent", {
|
|
1725
|
+
triggerKey,
|
|
1726
|
+
orderId,
|
|
1727
|
+
audienceType,
|
|
1728
|
+
fcmToken: logFcmToken(token),
|
|
1729
|
+
messageId: res.messageId ?? null
|
|
1730
|
+
});
|
|
1731
|
+
} else {
|
|
1732
|
+
notifyLog.error("PUSH", "FCM send failed", {
|
|
1733
|
+
triggerKey,
|
|
1734
|
+
orderId,
|
|
1735
|
+
audienceType,
|
|
1736
|
+
fcmToken: logFcmToken(token),
|
|
1737
|
+
error: res.error ?? "unknown"
|
|
1670
1738
|
});
|
|
1671
1739
|
}
|
|
1672
1740
|
}
|
|
@@ -1810,7 +1878,15 @@ function formatBodyForEmailHtml(body) {
|
|
|
1810
1878
|
__name(formatBodyForEmailHtml, "formatBodyForEmailHtml");
|
|
1811
1879
|
async function sendEmailForTrigger(triggerKey, orderId, audienceType, variables, contactEmail, dataSource, entityMap, getCms) {
|
|
1812
1880
|
const template = await loadBoundTemplate(triggerKey, "email", audienceType, dataSource, entityMap);
|
|
1813
|
-
if (!template)
|
|
1881
|
+
if (!template) {
|
|
1882
|
+
notifyLog.skip("EMAIL", "no bound/default email template", {
|
|
1883
|
+
triggerKey,
|
|
1884
|
+
orderId,
|
|
1885
|
+
audienceType,
|
|
1886
|
+
to: maskNotifyEmail(contactEmail)
|
|
1887
|
+
});
|
|
1888
|
+
return;
|
|
1889
|
+
}
|
|
1814
1890
|
const [branding, emailSettings, storeSettings] = await Promise.all([
|
|
1815
1891
|
getSettingsGroup(dataSource, entityMap, "branding"),
|
|
1816
1892
|
getSettingsGroup(dataSource, entityMap, "email"),
|
|
@@ -1845,22 +1921,31 @@ async function sendEmailForTrigger(triggerKey, orderId, audienceType, variables,
|
|
|
1845
1921
|
attachInvoice: true
|
|
1846
1922
|
} : {}
|
|
1847
1923
|
});
|
|
1848
|
-
|
|
1924
|
+
notifyLog.email("queued", {
|
|
1849
1925
|
triggerKey,
|
|
1850
1926
|
audienceType,
|
|
1851
1927
|
orderId,
|
|
1852
|
-
to: contactEmail,
|
|
1928
|
+
to: maskNotifyEmail(contactEmail),
|
|
1929
|
+
subject,
|
|
1853
1930
|
attachInvoice: shouldAttachInvoice
|
|
1854
1931
|
});
|
|
1855
1932
|
}
|
|
1856
1933
|
__name(sendEmailForTrigger, "sendEmailForTrigger");
|
|
1857
1934
|
async function sendWhatsAppForTrigger(triggerKey, orderId, phone, variables, dataSource, entityMap, getCms) {
|
|
1858
1935
|
const template = await loadBoundTemplate(triggerKey, "whatsapp", "customers", dataSource, entityMap);
|
|
1859
|
-
if (!template)
|
|
1936
|
+
if (!template) {
|
|
1937
|
+
notifyLog.skip("WHATSAPP", "no bound/default WhatsApp template", {
|
|
1938
|
+
triggerKey,
|
|
1939
|
+
orderId,
|
|
1940
|
+
phone: maskNotifyPhone(phone)
|
|
1941
|
+
});
|
|
1942
|
+
return;
|
|
1943
|
+
}
|
|
1860
1944
|
const paramOrder = template.providerMeta?.paramOrder ?? [];
|
|
1861
1945
|
if (paramOrder.length === 0) {
|
|
1862
|
-
|
|
1863
|
-
triggerKey
|
|
1946
|
+
notifyLog.skip("WHATSAPP", "template has no paramOrder \u2014 variables may send blank/wrong", {
|
|
1947
|
+
triggerKey,
|
|
1948
|
+
orderId
|
|
1864
1949
|
});
|
|
1865
1950
|
}
|
|
1866
1951
|
const cms = await getCms();
|
|
@@ -1869,8 +1954,10 @@ async function sendWhatsAppForTrigger(triggerKey, orderId, phone, variables, dat
|
|
|
1869
1954
|
name: template.name
|
|
1870
1955
|
});
|
|
1871
1956
|
if (!metaTemplateName) {
|
|
1872
|
-
|
|
1957
|
+
notifyLog.skip("WHATSAPP", "template has no Meta template name", {
|
|
1873
1958
|
triggerKey,
|
|
1959
|
+
orderId,
|
|
1960
|
+
phone: maskNotifyPhone(phone),
|
|
1874
1961
|
templateId: template.id
|
|
1875
1962
|
});
|
|
1876
1963
|
return;
|
|
@@ -1885,37 +1972,57 @@ async function sendWhatsAppForTrigger(triggerKey, orderId, phone, variables, dat
|
|
|
1885
1972
|
templateParamOrder: paramOrder
|
|
1886
1973
|
});
|
|
1887
1974
|
if (!sent) {
|
|
1888
|
-
|
|
1975
|
+
notifyLog.error("WHATSAPP", "send failed / not queued", {
|
|
1889
1976
|
triggerKey,
|
|
1890
1977
|
orderId,
|
|
1978
|
+
phone: maskNotifyPhone(phone),
|
|
1891
1979
|
hint: "Register whatsappPlugin() + queuePlugin() in getCms(), or set WHATSAPP_ACCESS_TOKEN and WHATSAPP_PHONE_NUMBER_ID"
|
|
1892
1980
|
});
|
|
1893
1981
|
} else {
|
|
1894
|
-
|
|
1982
|
+
notifyLog.whatsapp("queued/sent", {
|
|
1895
1983
|
triggerKey,
|
|
1896
1984
|
orderId,
|
|
1897
|
-
phone:
|
|
1985
|
+
phone: maskNotifyPhone(phone),
|
|
1986
|
+
metaTemplateName
|
|
1898
1987
|
});
|
|
1899
1988
|
}
|
|
1900
1989
|
}
|
|
1901
1990
|
__name(sendWhatsAppForTrigger, "sendWhatsAppForTrigger");
|
|
1902
1991
|
async function handleTrigger(triggerKey, payload, dataSource, entityMap, getCms) {
|
|
1903
|
-
|
|
1992
|
+
notifyLog.trigger("dispatcher received", {
|
|
1904
1993
|
triggerKey,
|
|
1905
1994
|
orderId: payload.orderId,
|
|
1906
|
-
|
|
1995
|
+
orderNumber: payload.orderNumber,
|
|
1996
|
+
phone: maskNotifyPhone(payload.customerPhone),
|
|
1997
|
+
vendorId: payload.vendorId ?? null
|
|
1907
1998
|
});
|
|
1908
1999
|
const [emailChannelEnabled, whatsappChannelEnabled, pushChannelEnabled] = await Promise.all([
|
|
1909
2000
|
isEmailNotificationsEnabled(dataSource, entityMap),
|
|
1910
2001
|
isWhatsappNotificationsEnabled(dataSource, entityMap),
|
|
1911
2002
|
isPushNotificationsEnabled(dataSource, entityMap)
|
|
1912
2003
|
]);
|
|
2004
|
+
notifyLog.trigger("channel switches", {
|
|
2005
|
+
triggerKey,
|
|
2006
|
+
orderId: payload.orderId,
|
|
2007
|
+
email: emailChannelEnabled,
|
|
2008
|
+
whatsapp: whatsappChannelEnabled,
|
|
2009
|
+
push: pushChannelEnabled
|
|
2010
|
+
});
|
|
1913
2011
|
if (!emailChannelEnabled && !whatsappChannelEnabled && !pushChannelEnabled) {
|
|
1914
|
-
|
|
2012
|
+
notifyLog.skip("ALL", "Email, WhatsApp, and Mobile Push are disabled in event_notifications", {
|
|
2013
|
+
triggerKey,
|
|
2014
|
+
orderId: payload.orderId
|
|
2015
|
+
});
|
|
1915
2016
|
return;
|
|
1916
2017
|
}
|
|
1917
2018
|
const triggerEnabled = await isTriggerCatalogEnabled(triggerKey, dataSource, entityMap);
|
|
1918
|
-
if (!triggerEnabled)
|
|
2019
|
+
if (!triggerEnabled) {
|
|
2020
|
+
notifyLog.skip("TRIGGER", "trigger catalog disabled", {
|
|
2021
|
+
triggerKey,
|
|
2022
|
+
orderId: payload.orderId
|
|
2023
|
+
});
|
|
2024
|
+
return;
|
|
2025
|
+
}
|
|
1919
2026
|
const context = await loadOrderNotificationContexts(payload.orderId, {
|
|
1920
2027
|
dataSource,
|
|
1921
2028
|
entityMap
|
|
@@ -1923,37 +2030,86 @@ async function handleTrigger(triggerKey, payload, dataSource, entityMap, getCms)
|
|
|
1923
2030
|
const variables = mergeTriggerVariables(payload, context?.variables);
|
|
1924
2031
|
const contactEmail = context?.contact.email?.trim() || "";
|
|
1925
2032
|
const contactPhone = context?.contact.phone?.trim() || payload.customerPhone?.trim() || "";
|
|
2033
|
+
notifyLog.trigger("recipients resolved", {
|
|
2034
|
+
triggerKey,
|
|
2035
|
+
orderId: payload.orderId,
|
|
2036
|
+
contactEmail: maskNotifyEmail(contactEmail),
|
|
2037
|
+
contactPhone: maskNotifyPhone(contactPhone)
|
|
2038
|
+
});
|
|
1926
2039
|
if (emailChannelEnabled) {
|
|
1927
2040
|
const [customerEnabled, vendorEnabled, adminEnabled] = await Promise.all([
|
|
1928
2041
|
isAudienceEmailEnabled(dataSource, entityMap, "customer"),
|
|
1929
2042
|
isAudienceEmailEnabled(dataSource, entityMap, "vendor"),
|
|
1930
2043
|
isAudienceEmailEnabled(dataSource, entityMap, "admin")
|
|
1931
2044
|
]);
|
|
2045
|
+
notifyLog.email("audience switches", {
|
|
2046
|
+
triggerKey,
|
|
2047
|
+
orderId: payload.orderId,
|
|
2048
|
+
customer: customerEnabled,
|
|
2049
|
+
vendor: vendorEnabled,
|
|
2050
|
+
admin: adminEnabled
|
|
2051
|
+
});
|
|
1932
2052
|
if (triggerKey === "order_assigned_assignee") {
|
|
1933
2053
|
const assigneeEmail = context?.order?.assignedUser?.email?.trim();
|
|
1934
2054
|
if (assigneeEmail) {
|
|
1935
2055
|
await sendEmailForTrigger(triggerKey, payload.orderId, "customers", variables, assigneeEmail, dataSource, entityMap, getCms);
|
|
2056
|
+
} else {
|
|
2057
|
+
notifyLog.skip("EMAIL", "order_assigned_assignee has no assignee email", {
|
|
2058
|
+
triggerKey,
|
|
2059
|
+
orderId: payload.orderId
|
|
2060
|
+
});
|
|
1936
2061
|
}
|
|
1937
2062
|
} else if (customerEnabled && contactEmail) {
|
|
1938
2063
|
await sendEmailForTrigger(triggerKey, payload.orderId, "customers", variables, contactEmail, dataSource, entityMap, getCms);
|
|
2064
|
+
} else if (!customerEnabled) {
|
|
2065
|
+
notifyLog.skip("EMAIL", "customer email audience disabled", {
|
|
2066
|
+
triggerKey,
|
|
2067
|
+
orderId: payload.orderId
|
|
2068
|
+
});
|
|
2069
|
+
} else {
|
|
2070
|
+
notifyLog.skip("EMAIL", "no customer email on order contact", {
|
|
2071
|
+
triggerKey,
|
|
2072
|
+
orderId: payload.orderId
|
|
2073
|
+
});
|
|
1939
2074
|
}
|
|
1940
2075
|
if (vendorEnabled && triggerKey !== "order_assigned_assignee") {
|
|
1941
2076
|
const multiVendorSettings = await getSettingsGroup(dataSource, entityMap, "multi_vendor");
|
|
1942
2077
|
if (multiVendorSettings.enabled !== "false" && multiVendorSettings.enabled !== "0") {
|
|
1943
2078
|
const vendorEmails = await getOrderVendorEmails(payload.orderId, payload.vendorId, dataSource, entityMap);
|
|
2079
|
+
if (vendorEmails.length === 0) {
|
|
2080
|
+
notifyLog.skip("EMAIL", "no vendor emails for order", {
|
|
2081
|
+
triggerKey,
|
|
2082
|
+
orderId: payload.orderId,
|
|
2083
|
+
vendorId: payload.vendorId ?? null
|
|
2084
|
+
});
|
|
2085
|
+
}
|
|
1944
2086
|
for (const vEmail of vendorEmails) {
|
|
1945
2087
|
await sendEmailForTrigger(triggerKey, payload.orderId, "vendors", variables, vEmail, dataSource, entityMap, getCms);
|
|
1946
2088
|
}
|
|
2089
|
+
} else {
|
|
2090
|
+
notifyLog.skip("EMAIL", "multi-vendor off \u2014 skip vendor email", {
|
|
2091
|
+
triggerKey,
|
|
2092
|
+
orderId: payload.orderId
|
|
2093
|
+
});
|
|
1947
2094
|
}
|
|
1948
2095
|
}
|
|
1949
2096
|
if (adminEnabled && triggerKey !== "order_assigned_assignee") {
|
|
1950
2097
|
const adminEmails = await getAdminRecipientEmails(dataSource, entityMap);
|
|
2098
|
+
if (adminEmails.length === 0) {
|
|
2099
|
+
notifyLog.skip("EMAIL", "no admin recipient emails", {
|
|
2100
|
+
triggerKey,
|
|
2101
|
+
orderId: payload.orderId
|
|
2102
|
+
});
|
|
2103
|
+
}
|
|
1951
2104
|
for (const aEmail of adminEmails) {
|
|
1952
2105
|
await sendEmailForTrigger(triggerKey, payload.orderId, "admin", variables, aEmail, dataSource, entityMap, getCms);
|
|
1953
2106
|
}
|
|
1954
2107
|
}
|
|
1955
2108
|
} else {
|
|
1956
|
-
|
|
2109
|
+
notifyLog.skip("EMAIL", "email channel disabled", {
|
|
2110
|
+
triggerKey,
|
|
2111
|
+
orderId: payload.orderId
|
|
2112
|
+
});
|
|
1957
2113
|
}
|
|
1958
2114
|
if (pushChannelEnabled) {
|
|
1959
2115
|
const [pushCustomerEnabled, pushVendorEnabled, pushAdminEnabled] = await Promise.all([
|
|
@@ -1961,29 +2117,59 @@ async function handleTrigger(triggerKey, payload, dataSource, entityMap, getCms)
|
|
|
1961
2117
|
isAudiencePushEnabled(dataSource, entityMap, "vendor"),
|
|
1962
2118
|
isAudiencePushEnabled(dataSource, entityMap, "admin")
|
|
1963
2119
|
]);
|
|
1964
|
-
|
|
2120
|
+
notifyLog.push("audience switches", {
|
|
2121
|
+
triggerKey,
|
|
2122
|
+
orderId: payload.orderId,
|
|
2123
|
+
customer: pushCustomerEnabled,
|
|
2124
|
+
vendor: pushVendorEnabled,
|
|
2125
|
+
admin: pushAdminEnabled
|
|
2126
|
+
});
|
|
2127
|
+
const targetCustomerId = triggerKey === "order_assigned_assignee" ? context?.order?.assignedUser?.id : context?.contact?.userId;
|
|
1965
2128
|
if (pushCustomerEnabled && targetCustomerId) {
|
|
1966
2129
|
await sendPushNotificationForTrigger(triggerKey, payload.orderId, "customers", String(targetCustomerId), variables, dataSource, entityMap);
|
|
2130
|
+
} else if (!pushCustomerEnabled) {
|
|
2131
|
+
notifyLog.skip("PUSH", "customer push audience disabled", {
|
|
2132
|
+
triggerKey,
|
|
2133
|
+
orderId: payload.orderId
|
|
2134
|
+
});
|
|
2135
|
+
} else {
|
|
2136
|
+
notifyLog.skip("PUSH", "no customer user/contact id for push", {
|
|
2137
|
+
triggerKey,
|
|
2138
|
+
orderId: payload.orderId
|
|
2139
|
+
});
|
|
1967
2140
|
}
|
|
1968
2141
|
if (pushVendorEnabled && payload.vendorId && triggerKey !== "order_assigned_assignee") {
|
|
1969
2142
|
await sendPushNotificationForTrigger(triggerKey, payload.orderId, "vendors", String(payload.vendorId), variables, dataSource, entityMap);
|
|
2143
|
+
} else if (pushVendorEnabled && triggerKey !== "order_assigned_assignee" && !payload.vendorId) {
|
|
2144
|
+
notifyLog.skip("PUSH", "no vendorId on order \u2014 skip vendor push", {
|
|
2145
|
+
triggerKey,
|
|
2146
|
+
orderId: payload.orderId
|
|
2147
|
+
});
|
|
1970
2148
|
}
|
|
1971
2149
|
if (pushAdminEnabled && triggerKey !== "order_assigned_assignee") {
|
|
1972
2150
|
await sendPushNotificationForTrigger(triggerKey, payload.orderId, "admin", "admin", variables, dataSource, entityMap);
|
|
1973
2151
|
}
|
|
2152
|
+
} else {
|
|
2153
|
+
notifyLog.skip("PUSH", "push channel disabled", {
|
|
2154
|
+
triggerKey,
|
|
2155
|
+
orderId: payload.orderId
|
|
2156
|
+
});
|
|
1974
2157
|
}
|
|
1975
2158
|
if (whatsappChannelEnabled) {
|
|
1976
2159
|
const targetPhone = triggerKey === "order_assigned_assignee" ? context?.order?.assignedUser?.phone?.trim() : contactPhone;
|
|
1977
2160
|
if (targetPhone) {
|
|
1978
2161
|
await sendWhatsAppForTrigger(triggerKey, payload.orderId, targetPhone, variables, dataSource, entityMap, getCms);
|
|
1979
2162
|
} else {
|
|
1980
|
-
|
|
2163
|
+
notifyLog.skip("WHATSAPP", "no recipient phone", {
|
|
1981
2164
|
triggerKey,
|
|
1982
2165
|
orderId: payload.orderId
|
|
1983
2166
|
});
|
|
1984
2167
|
}
|
|
1985
2168
|
} else {
|
|
1986
|
-
|
|
2169
|
+
notifyLog.skip("WHATSAPP", "WhatsApp channel disabled", {
|
|
2170
|
+
triggerKey,
|
|
2171
|
+
orderId: payload.orderId
|
|
2172
|
+
});
|
|
1987
2173
|
}
|
|
1988
2174
|
}
|
|
1989
2175
|
__name(handleTrigger, "handleTrigger");
|
|
@@ -1997,10 +2183,21 @@ function initWhatsappTriggerDispatcher(deps) {
|
|
|
1997
2183
|
});
|
|
1998
2184
|
notificationTriggerEmitter.onAnyTrigger((triggerKey, payload) => {
|
|
1999
2185
|
void handleTrigger(triggerKey, payload, dataSource, entityMap, getCms).catch((err) => {
|
|
2000
|
-
|
|
2186
|
+
notifyLog.error("TRIGGER", "dispatcher handleTrigger failed", {
|
|
2187
|
+
triggerKey,
|
|
2188
|
+
orderId: payload.orderId,
|
|
2189
|
+
error: err instanceof Error ? err.message : String(err),
|
|
2190
|
+
stack: err instanceof Error ? err.stack : void 0
|
|
2191
|
+
});
|
|
2001
2192
|
});
|
|
2002
2193
|
});
|
|
2003
|
-
|
|
2194
|
+
notifyLog.trigger("dispatcher initialized", {
|
|
2195
|
+
channels: [
|
|
2196
|
+
"email",
|
|
2197
|
+
"whatsapp",
|
|
2198
|
+
"push"
|
|
2199
|
+
]
|
|
2200
|
+
});
|
|
2004
2201
|
}
|
|
2005
2202
|
__name(initWhatsappTriggerDispatcher, "initWhatsappTriggerDispatcher");
|
|
2006
2203
|
async function dispatchOrderNotificationDirectly(triggerKey, payload, dataSource, entityMap, getCms) {
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkUSNT2KNT_cjs = require('./chunk-USNT2KNT.cjs');
|
|
4
|
+
var events = require('events');
|
|
5
|
+
|
|
6
|
+
var KNOWN_NOTIFICATION_TRIGGERS = {
|
|
7
|
+
ORDER_PENDING: "order_pending",
|
|
8
|
+
ORDER_PROCESSING: "order_processing",
|
|
9
|
+
ORDER_COMPLETED: "order_completed",
|
|
10
|
+
ORDER_PLACED: "order_placed",
|
|
11
|
+
ORDER_CANCELLED: "order_cancelled",
|
|
12
|
+
PAYMENT_SUCCESS: "payment_success",
|
|
13
|
+
PAYMENT_FAILED: "payment_failed",
|
|
14
|
+
PAYMENT_REFUND_INITIATED: "payment_refund_initiated"
|
|
15
|
+
};
|
|
16
|
+
var NotificationTriggerEmitter = class NotificationTriggerEmitter2 extends events.EventEmitter {
|
|
17
|
+
static {
|
|
18
|
+
chunkUSNT2KNT_cjs.__name(this, "NotificationTriggerEmitter");
|
|
19
|
+
}
|
|
20
|
+
emitTrigger(triggerKey, payload) {
|
|
21
|
+
this.emit("__any__", triggerKey, payload);
|
|
22
|
+
}
|
|
23
|
+
onAnyTrigger(listener) {
|
|
24
|
+
this.on("__any__", listener);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
var notificationTriggerEmitter = new NotificationTriggerEmitter();
|
|
28
|
+
|
|
29
|
+
// src/lib/notify-log.ts
|
|
30
|
+
function maskNotifyPhone(raw) {
|
|
31
|
+
const digits = String(raw ?? "").replace(/\D/g, "");
|
|
32
|
+
if (digits.length <= 4) return "(none)";
|
|
33
|
+
return `***${digits.slice(-4)}`;
|
|
34
|
+
}
|
|
35
|
+
chunkUSNT2KNT_cjs.__name(maskNotifyPhone, "maskNotifyPhone");
|
|
36
|
+
function maskNotifyEmail(raw) {
|
|
37
|
+
const e = String(raw ?? "").trim();
|
|
38
|
+
if (!e || !e.includes("@")) return "(none)";
|
|
39
|
+
const [user, domain] = e.split("@");
|
|
40
|
+
const u = user.length <= 2 ? "**" : `${user.slice(0, 2)}***`;
|
|
41
|
+
return `${u}@${domain}`;
|
|
42
|
+
}
|
|
43
|
+
chunkUSNT2KNT_cjs.__name(maskNotifyEmail, "maskNotifyEmail");
|
|
44
|
+
function logFcmToken(raw) {
|
|
45
|
+
const s = String(raw ?? "").trim();
|
|
46
|
+
return s || "(none)";
|
|
47
|
+
}
|
|
48
|
+
chunkUSNT2KNT_cjs.__name(logFcmToken, "logFcmToken");
|
|
49
|
+
function write(level, channel, message, data) {
|
|
50
|
+
const banner = `========== [NOTIFY] ${channel} | ${message} ==========`;
|
|
51
|
+
const payload = data ?? {};
|
|
52
|
+
if (level === "error") {
|
|
53
|
+
console.error(`
|
|
54
|
+
${banner}`, payload);
|
|
55
|
+
} else if (level === "warn") {
|
|
56
|
+
console.warn(`
|
|
57
|
+
${banner}`, payload);
|
|
58
|
+
} else {
|
|
59
|
+
console.info(`
|
|
60
|
+
${banner}`, payload);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
chunkUSNT2KNT_cjs.__name(write, "write");
|
|
64
|
+
var notifyLog = {
|
|
65
|
+
trigger: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((message, data) => write("info", "TRIGGER", message, data), "trigger"),
|
|
66
|
+
email: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((message, data) => write("info", "EMAIL", message, data), "email"),
|
|
67
|
+
whatsapp: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((message, data) => write("info", "WHATSAPP", message, data), "whatsapp"),
|
|
68
|
+
push: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((message, data) => write("info", "PUSH", message, data), "push"),
|
|
69
|
+
skip: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((channel, message, data) => write("warn", `SKIP ${channel}`, message, data), "skip"),
|
|
70
|
+
error: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((channel, message, data) => write("error", channel, message, data), "error")
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
exports.KNOWN_NOTIFICATION_TRIGGERS = KNOWN_NOTIFICATION_TRIGGERS;
|
|
74
|
+
exports.logFcmToken = logFcmToken;
|
|
75
|
+
exports.maskNotifyEmail = maskNotifyEmail;
|
|
76
|
+
exports.maskNotifyPhone = maskNotifyPhone;
|
|
77
|
+
exports.notificationTriggerEmitter = notificationTriggerEmitter;
|
|
78
|
+
exports.notifyLog = notifyLog;
|