feature/IO-3492-FCM-Queue-For-Notifications: Finalize
This commit is contained in:
@@ -27,6 +27,16 @@ let emailConsolidateQueue;
|
||||
let emailAddWorker;
|
||||
let emailConsolidateWorker;
|
||||
|
||||
const seconds = (ms) => Math.max(1, Math.ceil(ms / 1000));
|
||||
|
||||
const escapeHtml = (s = "") =>
|
||||
String(s)
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
|
||||
/**
|
||||
* Initializes the email notification queues and workers.
|
||||
*
|
||||
@@ -65,19 +75,21 @@ const loadEmailQueue = async ({ pubClient, logger }) => {
|
||||
|
||||
const redisKeyPrefix = `email:${devKey}:notifications:${jobId}`;
|
||||
|
||||
for (const recipient of recipients) {
|
||||
for (const recipient of recipients || []) {
|
||||
const { user, firstName, lastName } = recipient;
|
||||
if (!user) continue;
|
||||
const userKey = `${redisKeyPrefix}:${user}`;
|
||||
await pubClient.rpush(userKey, body);
|
||||
await pubClient.expire(userKey, NOTIFICATION_EXPIRATION / 1000);
|
||||
await pubClient.expire(userKey, seconds(NOTIFICATION_EXPIRATION));
|
||||
const detailsKey = `email:${devKey}:recipientDetails:${jobId}:${user}`;
|
||||
await pubClient.hsetnx(detailsKey, "firstName", firstName || "");
|
||||
await pubClient.hsetnx(detailsKey, "lastName", lastName || "");
|
||||
await pubClient.hsetnx(detailsKey, "bodyShopTimezone", bodyShopTimezone);
|
||||
await pubClient.expire(detailsKey, NOTIFICATION_EXPIRATION / 1000);
|
||||
const tzValue = bodyShopTimezone || "UTC";
|
||||
await pubClient.hsetnx(detailsKey, "bodyShopTimezone", tzValue);
|
||||
await pubClient.expire(detailsKey, seconds(NOTIFICATION_EXPIRATION));
|
||||
const recipientsSetKey = `email:${devKey}:recipients:${jobId}`;
|
||||
await pubClient.sadd(recipientsSetKey, user);
|
||||
await pubClient.expire(recipientsSetKey, NOTIFICATION_EXPIRATION / 1000);
|
||||
await pubClient.expire(recipientsSetKey, seconds(NOTIFICATION_EXPIRATION));
|
||||
devDebugLogger(`Stored message for ${user} under ${userKey}: ${body}`);
|
||||
}
|
||||
|
||||
@@ -95,7 +107,7 @@ const loadEmailQueue = async ({ pubClient, logger }) => {
|
||||
}
|
||||
);
|
||||
devDebugLogger(`Scheduled email consolidation for jobId ${jobId}`);
|
||||
await pubClient.expire(consolidateKey, CONSOLIDATION_KEY_EXPIRATION / 1000);
|
||||
await pubClient.expire(consolidateKey, seconds(CONSOLIDATION_KEY_EXPIRATION));
|
||||
} else {
|
||||
devDebugLogger(`Email consolidation already scheduled for jobId ${jobId}`);
|
||||
}
|
||||
@@ -115,7 +127,7 @@ const loadEmailQueue = async ({ pubClient, logger }) => {
|
||||
devDebugLogger(`Consolidating emails for jobId ${jobId}`);
|
||||
|
||||
const lockKey = `lock:${devKey}:emailConsolidate:${jobId}`;
|
||||
const lockAcquired = await pubClient.set(lockKey, "locked", "NX", "EX", LOCK_EXPIRATION / 1000);
|
||||
const lockAcquired = await pubClient.set(lockKey, "locked", "NX", "EX", seconds(LOCK_EXPIRATION));
|
||||
if (lockAcquired) {
|
||||
try {
|
||||
const recipientsSet = `email:${devKey}:recipients:${jobId}`;
|
||||
@@ -141,7 +153,7 @@ const loadEmailQueue = async ({ pubClient, logger }) => {
|
||||
<table class="row" style="border-spacing: 0; border-collapse: collapse; padding-top: 0; padding-right: 0; padding-bottom: 0; padding-left: 0; vertical-align: top; text-align: left; font-family: 'Montserrat', 'Montserrat Alternates', sans-serif; padding: 0; width: 100%; position: relative; display: table;"><tbody style="font-family: 'Montserrat', 'Montserrat Alternates', sans-serif; display: table-row-group;"><tr style="padding-top: 0; padding-right: 0; padding-bottom: 0; padding-left: 0; vertical-align: top; text-align: left; font-family: 'Montserrat', 'Montserrat Alternates', sans-serif;">
|
||||
<th class="small-12 large-12 columns first last" style="word-wrap: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; vertical-align: top; color: #0a0a0a; font-weight: normal; padding-top: 0; text-align: left; font-family: 'Montserrat', 'Montserrat Alternates', sans-serif; font-size: 15px; line-height: 1.2; margin: 0 auto; Margin: 0 auto; padding-bottom: 16px; width: 734px; padding-left: 8px; padding-right: 8px; border-collapse: collapse;"><table style="border-spacing: 0; border-collapse: collapse; padding-top: 0; padding-right: 0; padding-bottom: 0; padding-left: 0; vertical-align: top; text-align: left; font-family: 'Montserrat', 'Montserrat Alternates', sans-serif; width: 100%;"><tr style="padding-top: 0; padding-right: 0; padding-bottom: 0; padding-left: 0; vertical-align: top; text-align: left; font-family: 'Montserrat', 'Montserrat Alternates', sans-serif;"><td style="word-wrap: break-word; vertical-align: top; color: #0a0a0a; font-weight: normal; padding-top: 0; padding-right: 0; padding-bottom: 0; padding-left: 0; margin: 0; Margin: 0; text-align: left; font-family: 'Montserrat', 'Montserrat Alternates', sans-serif; font-size: 15px; word-break: keep-all; -moz-hyphens: none; -ms-hyphens: none; -webkit-hyphens: none; hyphens: none; line-height: 1.2; border-collapse: collapse;">
|
||||
<ul style="font-family: 'Montserrat', 'Montserrat Alternates', sans-serif; margin: 1%; padding-left: 30px;">
|
||||
${messages.map((msg) => `<li style="font-family: 'Montserrat', 'Montserrat Alternates', sans-serif; font-size: 90%;">${msg}</li>`).join("")}
|
||||
${messages.map((msg) => `<li style="font-family: 'Montserrat', 'Montserrat Alternates', sans-serif; font-size: 90%;">${escapeHtml(msg)}</li>`).join("")}
|
||||
</ul>
|
||||
</td></tr></table></th>
|
||||
</tr><tbody></table>
|
||||
|
||||
Reference in New Issue
Block a user