@astralibx/email-rule-engine 12.1.0 → 12.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +29 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.mjs +29 -29
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -263,27 +263,39 @@ interface EmailRuleEngineConfig {
|
|
|
263
263
|
onRunStart?: (info: {
|
|
264
264
|
rulesCount: number;
|
|
265
265
|
triggeredBy: string;
|
|
266
|
+
runId: string;
|
|
266
267
|
}) => void;
|
|
267
268
|
onRuleStart?: (info: {
|
|
268
269
|
ruleId: string;
|
|
269
270
|
ruleName: string;
|
|
270
271
|
matchedCount: number;
|
|
272
|
+
templateId: string;
|
|
273
|
+
runId: string;
|
|
271
274
|
}) => void;
|
|
272
275
|
onSend?: (info: {
|
|
273
276
|
ruleId: string;
|
|
274
277
|
ruleName: string;
|
|
275
278
|
email: string;
|
|
276
279
|
status: 'sent' | 'error' | 'skipped' | 'invalid' | 'throttled';
|
|
280
|
+
accountId: string;
|
|
281
|
+
templateId: string;
|
|
282
|
+
runId: string;
|
|
283
|
+
subjectIndex: number;
|
|
284
|
+
bodyIndex: number;
|
|
285
|
+
failureReason?: string;
|
|
277
286
|
}) => void;
|
|
278
287
|
onRuleComplete?: (info: {
|
|
279
288
|
ruleId: string;
|
|
280
289
|
ruleName: string;
|
|
281
290
|
stats: RuleRunStats;
|
|
291
|
+
templateId: string;
|
|
292
|
+
runId: string;
|
|
282
293
|
}) => void;
|
|
283
294
|
onRunComplete?: (info: {
|
|
284
295
|
duration: number;
|
|
285
296
|
totalStats: RuleRunStats;
|
|
286
297
|
perRuleStats: PerRuleStats[];
|
|
298
|
+
runId: string;
|
|
287
299
|
}) => void;
|
|
288
300
|
beforeSend?: (params: BeforeSendParams) => Promise<BeforeSendResult>;
|
|
289
301
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -263,27 +263,39 @@ interface EmailRuleEngineConfig {
|
|
|
263
263
|
onRunStart?: (info: {
|
|
264
264
|
rulesCount: number;
|
|
265
265
|
triggeredBy: string;
|
|
266
|
+
runId: string;
|
|
266
267
|
}) => void;
|
|
267
268
|
onRuleStart?: (info: {
|
|
268
269
|
ruleId: string;
|
|
269
270
|
ruleName: string;
|
|
270
271
|
matchedCount: number;
|
|
272
|
+
templateId: string;
|
|
273
|
+
runId: string;
|
|
271
274
|
}) => void;
|
|
272
275
|
onSend?: (info: {
|
|
273
276
|
ruleId: string;
|
|
274
277
|
ruleName: string;
|
|
275
278
|
email: string;
|
|
276
279
|
status: 'sent' | 'error' | 'skipped' | 'invalid' | 'throttled';
|
|
280
|
+
accountId: string;
|
|
281
|
+
templateId: string;
|
|
282
|
+
runId: string;
|
|
283
|
+
subjectIndex: number;
|
|
284
|
+
bodyIndex: number;
|
|
285
|
+
failureReason?: string;
|
|
277
286
|
}) => void;
|
|
278
287
|
onRuleComplete?: (info: {
|
|
279
288
|
ruleId: string;
|
|
280
289
|
ruleName: string;
|
|
281
290
|
stats: RuleRunStats;
|
|
291
|
+
templateId: string;
|
|
292
|
+
runId: string;
|
|
282
293
|
}) => void;
|
|
283
294
|
onRunComplete?: (info: {
|
|
284
295
|
duration: number;
|
|
285
296
|
totalStats: RuleRunStats;
|
|
286
297
|
perRuleStats: PerRuleStats[];
|
|
298
|
+
runId: string;
|
|
287
299
|
}) => void;
|
|
288
300
|
beforeSend?: (params: BeforeSendParams) => Promise<BeforeSendResult>;
|
|
289
301
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -1014,7 +1014,7 @@ var RuleRunnerService = class {
|
|
|
1014
1014
|
}
|
|
1015
1015
|
return true;
|
|
1016
1016
|
});
|
|
1017
|
-
this.config.hooks?.onRunStart?.({ rulesCount: activeRules.length, triggeredBy });
|
|
1017
|
+
this.config.hooks?.onRunStart?.({ rulesCount: activeRules.length, triggeredBy, runId });
|
|
1018
1018
|
await this.updateRunProgress(runId, {
|
|
1019
1019
|
progress: { rulesTotal: activeRules.length, rulesCompleted: 0, sent: 0, failed: 0, skipped: 0, invalid: 0 }
|
|
1020
1020
|
});
|
|
@@ -1103,7 +1103,7 @@ var RuleRunnerService = class {
|
|
|
1103
1103
|
status: runStatus
|
|
1104
1104
|
});
|
|
1105
1105
|
await this.updateRunProgress(runId, { status: runStatus, currentRule: "", elapsed: Date.now() - runStartTime });
|
|
1106
|
-
this.config.hooks?.onRunComplete?.({ duration: Date.now() - runStartTime, totalStats, perRuleStats });
|
|
1106
|
+
this.config.hooks?.onRunComplete?.({ duration: Date.now() - runStartTime, totalStats, perRuleStats, runId });
|
|
1107
1107
|
this.logger.info("Rule run completed", {
|
|
1108
1108
|
triggeredBy,
|
|
1109
1109
|
rulesProcessed: activeRules.length,
|
|
@@ -1142,7 +1142,7 @@ var RuleRunnerService = class {
|
|
|
1142
1142
|
stats.matched = emailsToProcess.length;
|
|
1143
1143
|
const ruleId = rule._id.toString();
|
|
1144
1144
|
const templateId = rule.templateId.toString();
|
|
1145
|
-
this.config.hooks?.onRuleStart?.({ ruleId, ruleName: rule.name, matchedCount: emailsToProcess.length });
|
|
1145
|
+
this.config.hooks?.onRuleStart?.({ ruleId, ruleName: rule.name, matchedCount: emailsToProcess.length, templateId, runId: runId || "" });
|
|
1146
1146
|
if (emailsToProcess.length === 0) return stats;
|
|
1147
1147
|
const identifierResults = await processInChunks(
|
|
1148
1148
|
emailsToProcess,
|
|
@@ -1187,7 +1187,7 @@ var RuleRunnerService = class {
|
|
|
1187
1187
|
const identifier = identifierMap.get(email);
|
|
1188
1188
|
if (!identifier) {
|
|
1189
1189
|
stats.skipped++;
|
|
1190
|
-
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "invalid" });
|
|
1190
|
+
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "invalid", accountId: "", templateId, runId: runId || "", subjectIndex: -1, bodyIndex: -1, failureReason: "invalid email" });
|
|
1191
1191
|
continue;
|
|
1192
1192
|
}
|
|
1193
1193
|
const dedupKey = identifier.id;
|
|
@@ -1195,27 +1195,27 @@ var RuleRunnerService = class {
|
|
|
1195
1195
|
if (lastSend) {
|
|
1196
1196
|
if (rule.sendOnce && !rule.resendAfterDays) {
|
|
1197
1197
|
stats.skipped++;
|
|
1198
|
-
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "skipped" });
|
|
1198
|
+
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "skipped", accountId: "", templateId, runId: runId || "", subjectIndex: -1, bodyIndex: -1, failureReason: "send once" });
|
|
1199
1199
|
continue;
|
|
1200
1200
|
}
|
|
1201
1201
|
if (rule.resendAfterDays) {
|
|
1202
1202
|
const daysSince = (Date.now() - new Date(lastSend.sentAt).getTime()) / MS_PER_DAY;
|
|
1203
1203
|
if (daysSince < rule.resendAfterDays) {
|
|
1204
1204
|
stats.skipped++;
|
|
1205
|
-
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "skipped" });
|
|
1205
|
+
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "skipped", accountId: "", templateId, runId: runId || "", subjectIndex: -1, bodyIndex: -1, failureReason: "resend too soon" });
|
|
1206
1206
|
continue;
|
|
1207
1207
|
}
|
|
1208
1208
|
} else {
|
|
1209
1209
|
stats.skipped++;
|
|
1210
|
-
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "skipped" });
|
|
1210
|
+
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "skipped", accountId: "", templateId, runId: runId || "", subjectIndex: -1, bodyIndex: -1, failureReason: "send once" });
|
|
1211
1211
|
continue;
|
|
1212
1212
|
}
|
|
1213
1213
|
}
|
|
1214
|
-
if (!this.checkThrottle(rule, dedupKey, email, throttleMap, throttleConfig, stats)) continue;
|
|
1214
|
+
if (!this.checkThrottle(rule, dedupKey, email, throttleMap, throttleConfig, stats, templateId, runId)) continue;
|
|
1215
1215
|
const agentSelection = await this.config.adapters.selectAgent(identifier.id, { ruleId, templateId });
|
|
1216
1216
|
if (!agentSelection) {
|
|
1217
1217
|
stats.skipped++;
|
|
1218
|
-
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "skipped" });
|
|
1218
|
+
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "skipped", accountId: "", templateId, runId: runId || "", subjectIndex: -1, bodyIndex: -1, failureReason: "no account available" });
|
|
1219
1219
|
continue;
|
|
1220
1220
|
}
|
|
1221
1221
|
const user = { _id: identifier.id, email };
|
|
@@ -1266,7 +1266,7 @@ var RuleRunnerService = class {
|
|
|
1266
1266
|
} catch (hookErr) {
|
|
1267
1267
|
this.logger.error(`beforeSend hook failed for email ${email}: ${hookErr.message}`);
|
|
1268
1268
|
stats.errorCount++;
|
|
1269
|
-
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "error" });
|
|
1269
|
+
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "error", accountId: agentSelection.accountId, templateId, runId: runId || "", subjectIndex: si, bodyIndex: bi, failureReason: hookErr.message });
|
|
1270
1270
|
continue;
|
|
1271
1271
|
}
|
|
1272
1272
|
}
|
|
@@ -1294,7 +1294,7 @@ var RuleRunnerService = class {
|
|
|
1294
1294
|
lastSentDate: /* @__PURE__ */ new Date()
|
|
1295
1295
|
});
|
|
1296
1296
|
stats.sent++;
|
|
1297
|
-
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "sent" });
|
|
1297
|
+
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "sent", accountId: agentSelection.accountId, templateId, runId: runId || "", subjectIndex: si, bodyIndex: bi });
|
|
1298
1298
|
totalProcessed++;
|
|
1299
1299
|
if (runId && totalProcessed % 10 === 0) {
|
|
1300
1300
|
await this.updateRunSendProgress(runId, stats);
|
|
@@ -1309,7 +1309,7 @@ var RuleRunnerService = class {
|
|
|
1309
1309
|
}
|
|
1310
1310
|
} catch (err) {
|
|
1311
1311
|
stats.errorCount++;
|
|
1312
|
-
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "error" });
|
|
1312
|
+
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "error", accountId: "", templateId, runId: runId || "", subjectIndex: -1, bodyIndex: -1, failureReason: err.message || "unknown error" });
|
|
1313
1313
|
this.logger.error(`Rule "${rule.name}" failed for identifier ${email}`, { error: err });
|
|
1314
1314
|
}
|
|
1315
1315
|
}
|
|
@@ -1332,7 +1332,7 @@ var RuleRunnerService = class {
|
|
|
1332
1332
|
this.logger.info(`Rule '${rule.name}' auto-disabled \u2014 all identifiers processed`);
|
|
1333
1333
|
}
|
|
1334
1334
|
}
|
|
1335
|
-
this.config.hooks?.onRuleComplete?.({ ruleId, ruleName: rule.name, stats });
|
|
1335
|
+
this.config.hooks?.onRuleComplete?.({ ruleId, ruleName: rule.name, stats, templateId, runId: runId || "" });
|
|
1336
1336
|
return stats;
|
|
1337
1337
|
}
|
|
1338
1338
|
async executeQueryMode(rule, template, throttleMap, throttleConfig, stats, runId) {
|
|
@@ -1345,7 +1345,7 @@ var RuleRunnerService = class {
|
|
|
1345
1345
|
return stats;
|
|
1346
1346
|
}
|
|
1347
1347
|
stats.matched = users.length;
|
|
1348
|
-
this.config.hooks?.onRuleStart?.({ ruleId: rule._id.toString(), ruleName: rule.name, matchedCount: users.length });
|
|
1348
|
+
this.config.hooks?.onRuleStart?.({ ruleId: rule._id.toString(), ruleName: rule.name, matchedCount: users.length, templateId: rule.templateId.toString(), runId: runId || "" });
|
|
1349
1349
|
if (users.length === 0) return stats;
|
|
1350
1350
|
const userIds = users.map((u) => u._id?.toString()).filter(Boolean);
|
|
1351
1351
|
const emails = users.map((u) => u.email).filter(Boolean);
|
|
@@ -1394,40 +1394,40 @@ var RuleRunnerService = class {
|
|
|
1394
1394
|
const email = user.email;
|
|
1395
1395
|
if (!userId || !email) {
|
|
1396
1396
|
stats.skipped++;
|
|
1397
|
-
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email: email || "unknown", status: "invalid" });
|
|
1397
|
+
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email: email || "unknown", status: "invalid", accountId: "", templateId, runId: runId || "", subjectIndex: -1, bodyIndex: -1, failureReason: "invalid email" });
|
|
1398
1398
|
continue;
|
|
1399
1399
|
}
|
|
1400
1400
|
const lastSend = sendMap.get(userId);
|
|
1401
1401
|
if (lastSend) {
|
|
1402
1402
|
if (rule.sendOnce && !rule.resendAfterDays) {
|
|
1403
1403
|
stats.skipped++;
|
|
1404
|
-
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "skipped" });
|
|
1404
|
+
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "skipped", accountId: "", templateId, runId: runId || "", subjectIndex: -1, bodyIndex: -1, failureReason: "send once" });
|
|
1405
1405
|
continue;
|
|
1406
1406
|
}
|
|
1407
1407
|
if (rule.resendAfterDays) {
|
|
1408
1408
|
const daysSince = (Date.now() - new Date(lastSend.sentAt).getTime()) / MS_PER_DAY;
|
|
1409
1409
|
if (daysSince < rule.resendAfterDays) {
|
|
1410
1410
|
stats.skipped++;
|
|
1411
|
-
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "skipped" });
|
|
1411
|
+
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "skipped", accountId: "", templateId, runId: runId || "", subjectIndex: -1, bodyIndex: -1, failureReason: "resend too soon" });
|
|
1412
1412
|
continue;
|
|
1413
1413
|
}
|
|
1414
1414
|
} else {
|
|
1415
1415
|
stats.skipped++;
|
|
1416
|
-
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "skipped" });
|
|
1416
|
+
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "skipped", accountId: "", templateId, runId: runId || "", subjectIndex: -1, bodyIndex: -1, failureReason: "send once" });
|
|
1417
1417
|
continue;
|
|
1418
1418
|
}
|
|
1419
1419
|
}
|
|
1420
1420
|
const identifier = identifierMap.get(email.toLowerCase().trim());
|
|
1421
1421
|
if (!identifier) {
|
|
1422
1422
|
stats.skipped++;
|
|
1423
|
-
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "invalid" });
|
|
1423
|
+
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "invalid", accountId: "", templateId, runId: runId || "", subjectIndex: -1, bodyIndex: -1, failureReason: "invalid email" });
|
|
1424
1424
|
continue;
|
|
1425
1425
|
}
|
|
1426
|
-
if (!this.checkThrottle(rule, userId, email, throttleMap, throttleConfig, stats)) continue;
|
|
1426
|
+
if (!this.checkThrottle(rule, userId, email, throttleMap, throttleConfig, stats, templateId, runId)) continue;
|
|
1427
1427
|
const agentSelection = await this.config.adapters.selectAgent(identifier.id, { ruleId, templateId });
|
|
1428
1428
|
if (!agentSelection) {
|
|
1429
1429
|
stats.skipped++;
|
|
1430
|
-
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "skipped" });
|
|
1430
|
+
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "skipped", accountId: "", templateId, runId: runId || "", subjectIndex: -1, bodyIndex: -1, failureReason: "no account available" });
|
|
1431
1431
|
continue;
|
|
1432
1432
|
}
|
|
1433
1433
|
const resolvedData = this.config.adapters.resolveData(user);
|
|
@@ -1477,7 +1477,7 @@ var RuleRunnerService = class {
|
|
|
1477
1477
|
} catch (hookErr) {
|
|
1478
1478
|
this.logger.error(`beforeSend hook failed for email ${email}: ${hookErr.message}`);
|
|
1479
1479
|
stats.errorCount++;
|
|
1480
|
-
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "error" });
|
|
1480
|
+
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "error", accountId: agentSelection.accountId, templateId, runId: runId || "", subjectIndex: si, bodyIndex: bi, failureReason: hookErr.message });
|
|
1481
1481
|
continue;
|
|
1482
1482
|
}
|
|
1483
1483
|
}
|
|
@@ -1505,7 +1505,7 @@ var RuleRunnerService = class {
|
|
|
1505
1505
|
lastSentDate: /* @__PURE__ */ new Date()
|
|
1506
1506
|
});
|
|
1507
1507
|
stats.sent++;
|
|
1508
|
-
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "sent" });
|
|
1508
|
+
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email, status: "sent", accountId: agentSelection.accountId, templateId, runId: runId || "", subjectIndex: si, bodyIndex: bi });
|
|
1509
1509
|
totalProcessed++;
|
|
1510
1510
|
if (runId && totalProcessed % 10 === 0) {
|
|
1511
1511
|
await this.updateRunSendProgress(runId, stats);
|
|
@@ -1520,7 +1520,7 @@ var RuleRunnerService = class {
|
|
|
1520
1520
|
}
|
|
1521
1521
|
} catch (err) {
|
|
1522
1522
|
stats.errorCount++;
|
|
1523
|
-
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email: user.email || "unknown", status: "error" });
|
|
1523
|
+
this.config.hooks?.onSend?.({ ruleId, ruleName: rule.name, email: user.email || "unknown", status: "error", accountId: "", templateId, runId: runId || "", subjectIndex: -1, bodyIndex: -1, failureReason: err.message || "unknown error" });
|
|
1524
1524
|
this.logger.error(`Rule "${rule.name}" failed for user ${user._id?.toString()}`, { error: err });
|
|
1525
1525
|
}
|
|
1526
1526
|
}
|
|
@@ -1528,27 +1528,27 @@ var RuleRunnerService = class {
|
|
|
1528
1528
|
$set: { lastRunAt: /* @__PURE__ */ new Date(), lastRunStats: stats },
|
|
1529
1529
|
$inc: { totalSent: stats.sent, totalSkipped: stats.skipped }
|
|
1530
1530
|
});
|
|
1531
|
-
this.config.hooks?.onRuleComplete?.({ ruleId, ruleName: rule.name, stats });
|
|
1531
|
+
this.config.hooks?.onRuleComplete?.({ ruleId, ruleName: rule.name, stats, templateId, runId: runId || "" });
|
|
1532
1532
|
return stats;
|
|
1533
1533
|
}
|
|
1534
|
-
checkThrottle(rule, userId, email, throttleMap, config, stats) {
|
|
1534
|
+
checkThrottle(rule, userId, email, throttleMap, config, stats, templateId, runId) {
|
|
1535
1535
|
if (rule.emailType === EMAIL_TYPE.Transactional || rule.bypassThrottle) return true;
|
|
1536
1536
|
const userThrottle = throttleMap.get(userId) || { today: 0, thisWeek: 0, lastSentDate: null };
|
|
1537
1537
|
if (userThrottle.today >= config.maxPerUserPerDay) {
|
|
1538
1538
|
stats.skippedByThrottle++;
|
|
1539
|
-
this.config.hooks?.onSend?.({ ruleId: rule._id.toString(), ruleName: rule.name, email, status: "throttled" });
|
|
1539
|
+
this.config.hooks?.onSend?.({ ruleId: rule._id.toString(), ruleName: rule.name, email, status: "throttled", accountId: "", templateId: templateId || "", runId: runId || "", subjectIndex: -1, bodyIndex: -1, failureReason: "daily throttle limit" });
|
|
1540
1540
|
return false;
|
|
1541
1541
|
}
|
|
1542
1542
|
if (userThrottle.thisWeek >= config.maxPerUserPerWeek) {
|
|
1543
1543
|
stats.skippedByThrottle++;
|
|
1544
|
-
this.config.hooks?.onSend?.({ ruleId: rule._id.toString(), ruleName: rule.name, email, status: "throttled" });
|
|
1544
|
+
this.config.hooks?.onSend?.({ ruleId: rule._id.toString(), ruleName: rule.name, email, status: "throttled", accountId: "", templateId: templateId || "", runId: runId || "", subjectIndex: -1, bodyIndex: -1, failureReason: "weekly throttle limit" });
|
|
1545
1545
|
return false;
|
|
1546
1546
|
}
|
|
1547
1547
|
if (userThrottle.lastSentDate) {
|
|
1548
1548
|
const daysSinceLastSend = (Date.now() - userThrottle.lastSentDate.getTime()) / MS_PER_DAY;
|
|
1549
1549
|
if (daysSinceLastSend < config.minGapDays) {
|
|
1550
1550
|
stats.skippedByThrottle++;
|
|
1551
|
-
this.config.hooks?.onSend?.({ ruleId: rule._id.toString(), ruleName: rule.name, email, status: "throttled" });
|
|
1551
|
+
this.config.hooks?.onSend?.({ ruleId: rule._id.toString(), ruleName: rule.name, email, status: "throttled", accountId: "", templateId: templateId || "", runId: runId || "", subjectIndex: -1, bodyIndex: -1, failureReason: "min gap days" });
|
|
1552
1552
|
return false;
|
|
1553
1553
|
}
|
|
1554
1554
|
}
|