@astralibx/email-rule-engine 1.2.2 → 3.0.1
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 +93 -46
- package/dist/index.d.mts +607 -0
- package/dist/index.d.ts +595 -20
- package/dist/index.js +1731 -65
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1699 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +26 -8
- package/dist/controllers/index.d.ts +0 -5
- package/dist/controllers/index.d.ts.map +0 -1
- package/dist/controllers/index.js +0 -12
- package/dist/controllers/index.js.map +0 -1
- package/dist/controllers/rule.controller.d.ts +0 -13
- package/dist/controllers/rule.controller.d.ts.map +0 -1
- package/dist/controllers/rule.controller.js +0 -142
- package/dist/controllers/rule.controller.js.map +0 -1
- package/dist/controllers/runner.controller.d.ts +0 -8
- package/dist/controllers/runner.controller.d.ts.map +0 -1
- package/dist/controllers/runner.controller.js +0 -22
- package/dist/controllers/runner.controller.js.map +0 -1
- package/dist/controllers/settings.controller.d.ts +0 -7
- package/dist/controllers/settings.controller.d.ts.map +0 -1
- package/dist/controllers/settings.controller.js +0 -56
- package/dist/controllers/settings.controller.js.map +0 -1
- package/dist/controllers/template.controller.d.ts +0 -15
- package/dist/controllers/template.controller.d.ts.map +0 -1
- package/dist/controllers/template.controller.js +0 -169
- package/dist/controllers/template.controller.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/routes/index.d.ts +0 -16
- package/dist/routes/index.d.ts.map +0 -1
- package/dist/routes/index.js +0 -47
- package/dist/routes/index.js.map +0 -1
- package/dist/schemas/index.d.ts +0 -6
- package/dist/schemas/index.d.ts.map +0 -1
- package/dist/schemas/index.js +0 -14
- package/dist/schemas/index.js.map +0 -1
- package/dist/schemas/rule-send.schema.d.ts +0 -25
- package/dist/schemas/rule-send.schema.d.ts.map +0 -1
- package/dist/schemas/rule-send.schema.js +0 -41
- package/dist/schemas/rule-send.schema.js.map +0 -1
- package/dist/schemas/rule.schema.d.ts +0 -22
- package/dist/schemas/rule.schema.d.ts.map +0 -1
- package/dist/schemas/rule.schema.js +0 -81
- package/dist/schemas/rule.schema.js.map +0 -1
- package/dist/schemas/run-log.schema.d.ts +0 -39
- package/dist/schemas/run-log.schema.d.ts.map +0 -1
- package/dist/schemas/run-log.schema.js +0 -47
- package/dist/schemas/run-log.schema.js.map +0 -1
- package/dist/schemas/template.schema.d.ts +0 -24
- package/dist/schemas/template.schema.d.ts.map +0 -1
- package/dist/schemas/template.schema.js +0 -65
- package/dist/schemas/template.schema.js.map +0 -1
- package/dist/schemas/throttle-config.schema.d.ts +0 -19
- package/dist/schemas/throttle-config.schema.d.ts.map +0 -1
- package/dist/schemas/throttle-config.schema.js +0 -32
- package/dist/schemas/throttle-config.schema.js.map +0 -1
- package/dist/services/index.d.ts +0 -5
- package/dist/services/index.d.ts.map +0 -1
- package/dist/services/index.js +0 -12
- package/dist/services/index.js.map +0 -1
- package/dist/services/rule-runner.service.d.ts +0 -31
- package/dist/services/rule-runner.service.d.ts.map +0 -1
- package/dist/services/rule-runner.service.js +0 -279
- package/dist/services/rule-runner.service.js.map +0 -1
- package/dist/services/rule.service.d.ts +0 -27
- package/dist/services/rule.service.d.ts.map +0 -1
- package/dist/services/rule.service.js +0 -127
- package/dist/services/rule.service.js.map +0 -1
- package/dist/services/template-render.service.d.ts +0 -23
- package/dist/services/template-render.service.d.ts.map +0 -1
- package/dist/services/template-render.service.js +0 -178
- package/dist/services/template-render.service.js.map +0 -1
- package/dist/services/template.service.d.ts +0 -42
- package/dist/services/template.service.d.ts.map +0 -1
- package/dist/services/template.service.js +0 -128
- package/dist/services/template.service.js.map +0 -1
- package/dist/types/config.types.d.ts +0 -85
- package/dist/types/config.types.d.ts.map +0 -1
- package/dist/types/config.types.js +0 -3
- package/dist/types/config.types.js.map +0 -1
- package/dist/types/enums.d.ts +0 -43
- package/dist/types/enums.d.ts.map +0 -1
- package/dist/types/enums.js +0 -40
- package/dist/types/enums.js.map +0 -1
- package/dist/types/index.d.ts +0 -6
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -11
- package/dist/types/index.js.map +0 -1
- package/dist/types/rule.types.d.ts +0 -91
- package/dist/types/rule.types.d.ts.map +0 -1
- package/dist/types/rule.types.js +0 -3
- package/dist/types/rule.types.js.map +0 -1
- package/dist/types/template.types.d.ts +0 -43
- package/dist/types/template.types.d.ts.map +0 -1
- package/dist/types/template.types.js +0 -3
- package/dist/types/template.types.js.map +0 -1
- package/dist/types/throttle.types.d.ts +0 -15
- package/dist/types/throttle.types.d.ts.map +0 -1
- package/dist/types/throttle.types.js +0 -3
- package/dist/types/throttle.types.js.map +0 -1
- package/dist/utils/express-helpers.d.ts +0 -4
- package/dist/utils/express-helpers.d.ts.map +0 -1
- package/dist/utils/express-helpers.js +0 -15
- package/dist/utils/express-helpers.js.map +0 -1
- package/dist/utils/redis-lock.d.ts +0 -13
- package/dist/utils/redis-lock.d.ts.map +0 -1
- package/dist/utils/redis-lock.js +0 -36
- package/dist/utils/redis-lock.js.map +0 -1
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
import * as mongoose from 'mongoose';
|
|
2
|
+
import { Connection, Model, HydratedDocument, Schema, Types } from 'mongoose';
|
|
3
|
+
import { Redis } from 'ioredis';
|
|
4
|
+
import { LogAdapter, AlxError } from '@astralibx/core';
|
|
5
|
+
export { LogAdapter } from '@astralibx/core';
|
|
6
|
+
import { Router } from 'express';
|
|
7
|
+
|
|
8
|
+
declare const TEMPLATE_CATEGORY: {
|
|
9
|
+
readonly Onboarding: "onboarding";
|
|
10
|
+
readonly Engagement: "engagement";
|
|
11
|
+
readonly Transactional: "transactional";
|
|
12
|
+
readonly ReEngagement: "re-engagement";
|
|
13
|
+
readonly Announcement: "announcement";
|
|
14
|
+
};
|
|
15
|
+
type TemplateCategory = (typeof TEMPLATE_CATEGORY)[keyof typeof TEMPLATE_CATEGORY];
|
|
16
|
+
declare const TEMPLATE_AUDIENCE: {
|
|
17
|
+
readonly Customer: "customer";
|
|
18
|
+
readonly Provider: "provider";
|
|
19
|
+
readonly All: "all";
|
|
20
|
+
};
|
|
21
|
+
type TemplateAudience = (typeof TEMPLATE_AUDIENCE)[keyof typeof TEMPLATE_AUDIENCE];
|
|
22
|
+
declare const RULE_OPERATOR: {
|
|
23
|
+
readonly Eq: "eq";
|
|
24
|
+
readonly Neq: "neq";
|
|
25
|
+
readonly Gt: "gt";
|
|
26
|
+
readonly Gte: "gte";
|
|
27
|
+
readonly Lt: "lt";
|
|
28
|
+
readonly Lte: "lte";
|
|
29
|
+
readonly Exists: "exists";
|
|
30
|
+
readonly NotExists: "not_exists";
|
|
31
|
+
readonly In: "in";
|
|
32
|
+
readonly NotIn: "not_in";
|
|
33
|
+
readonly Contains: "contains";
|
|
34
|
+
};
|
|
35
|
+
type RuleOperator = (typeof RULE_OPERATOR)[keyof typeof RULE_OPERATOR];
|
|
36
|
+
declare const EMAIL_TYPE: {
|
|
37
|
+
readonly Automated: "automated";
|
|
38
|
+
readonly Transactional: "transactional";
|
|
39
|
+
};
|
|
40
|
+
type EmailType = (typeof EMAIL_TYPE)[keyof typeof EMAIL_TYPE];
|
|
41
|
+
declare const RUN_TRIGGER: {
|
|
42
|
+
readonly Cron: "cron";
|
|
43
|
+
readonly Manual: "manual";
|
|
44
|
+
};
|
|
45
|
+
type RunTrigger = (typeof RUN_TRIGGER)[keyof typeof RUN_TRIGGER];
|
|
46
|
+
declare const THROTTLE_WINDOW: {
|
|
47
|
+
readonly Rolling: "rolling";
|
|
48
|
+
};
|
|
49
|
+
type ThrottleWindow = (typeof THROTTLE_WINDOW)[keyof typeof THROTTLE_WINDOW];
|
|
50
|
+
declare const EMAIL_SEND_STATUS: {
|
|
51
|
+
readonly Sent: "sent";
|
|
52
|
+
readonly Error: "error";
|
|
53
|
+
readonly Skipped: "skipped";
|
|
54
|
+
readonly Invalid: "invalid";
|
|
55
|
+
readonly Throttled: "throttled";
|
|
56
|
+
};
|
|
57
|
+
type EmailSendStatus = (typeof EMAIL_SEND_STATUS)[keyof typeof EMAIL_SEND_STATUS];
|
|
58
|
+
|
|
59
|
+
interface RuleCondition {
|
|
60
|
+
field: string;
|
|
61
|
+
operator: RuleOperator;
|
|
62
|
+
value: unknown;
|
|
63
|
+
}
|
|
64
|
+
interface RuleRunStats {
|
|
65
|
+
matched: number;
|
|
66
|
+
sent: number;
|
|
67
|
+
skipped: number;
|
|
68
|
+
skippedByThrottle: number;
|
|
69
|
+
errors: number;
|
|
70
|
+
}
|
|
71
|
+
interface RuleTarget {
|
|
72
|
+
role: TemplateAudience;
|
|
73
|
+
platform: string;
|
|
74
|
+
conditions: RuleCondition[];
|
|
75
|
+
}
|
|
76
|
+
interface EmailRule {
|
|
77
|
+
_id: string;
|
|
78
|
+
name: string;
|
|
79
|
+
description?: string;
|
|
80
|
+
isActive: boolean;
|
|
81
|
+
sortOrder: number;
|
|
82
|
+
target: RuleTarget;
|
|
83
|
+
templateId: string;
|
|
84
|
+
sendOnce: boolean;
|
|
85
|
+
resendAfterDays?: number;
|
|
86
|
+
cooldownDays?: number;
|
|
87
|
+
autoApprove: boolean;
|
|
88
|
+
maxPerRun?: number;
|
|
89
|
+
bypassThrottle: boolean;
|
|
90
|
+
emailType: EmailType;
|
|
91
|
+
totalSent: number;
|
|
92
|
+
totalSkipped: number;
|
|
93
|
+
lastRunAt?: Date;
|
|
94
|
+
lastRunStats?: RuleRunStats;
|
|
95
|
+
createdAt: Date;
|
|
96
|
+
updatedAt: Date;
|
|
97
|
+
}
|
|
98
|
+
interface CreateEmailRuleInput {
|
|
99
|
+
name: string;
|
|
100
|
+
description?: string;
|
|
101
|
+
target: RuleTarget;
|
|
102
|
+
templateId: string;
|
|
103
|
+
sortOrder?: number;
|
|
104
|
+
sendOnce?: boolean;
|
|
105
|
+
resendAfterDays?: number;
|
|
106
|
+
cooldownDays?: number;
|
|
107
|
+
autoApprove?: boolean;
|
|
108
|
+
maxPerRun?: number;
|
|
109
|
+
bypassThrottle?: boolean;
|
|
110
|
+
emailType?: EmailType;
|
|
111
|
+
}
|
|
112
|
+
interface UpdateEmailRuleInput {
|
|
113
|
+
name?: string;
|
|
114
|
+
description?: string;
|
|
115
|
+
isActive?: boolean;
|
|
116
|
+
sortOrder?: number;
|
|
117
|
+
target?: RuleTarget;
|
|
118
|
+
templateId?: string;
|
|
119
|
+
sendOnce?: boolean;
|
|
120
|
+
resendAfterDays?: number;
|
|
121
|
+
cooldownDays?: number;
|
|
122
|
+
autoApprove?: boolean;
|
|
123
|
+
maxPerRun?: number;
|
|
124
|
+
bypassThrottle?: boolean;
|
|
125
|
+
emailType?: EmailType;
|
|
126
|
+
}
|
|
127
|
+
interface EmailRuleSend {
|
|
128
|
+
_id: string;
|
|
129
|
+
ruleId: string;
|
|
130
|
+
userId: string;
|
|
131
|
+
emailIdentifierId?: string;
|
|
132
|
+
messageId?: string;
|
|
133
|
+
sentAt: Date;
|
|
134
|
+
status?: string;
|
|
135
|
+
accountId?: string;
|
|
136
|
+
senderName?: string;
|
|
137
|
+
subject?: string;
|
|
138
|
+
failureReason?: string;
|
|
139
|
+
}
|
|
140
|
+
interface PerRuleStats extends RuleRunStats {
|
|
141
|
+
ruleId: string;
|
|
142
|
+
ruleName: string;
|
|
143
|
+
}
|
|
144
|
+
interface EmailRuleRunLog {
|
|
145
|
+
_id: string;
|
|
146
|
+
runAt: Date;
|
|
147
|
+
triggeredBy: RunTrigger;
|
|
148
|
+
duration: number;
|
|
149
|
+
rulesProcessed: number;
|
|
150
|
+
totalStats: RuleRunStats;
|
|
151
|
+
perRuleStats: PerRuleStats[];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
interface SendEmailParams {
|
|
155
|
+
identifierId: string;
|
|
156
|
+
contactId: string;
|
|
157
|
+
accountId: string;
|
|
158
|
+
subject: string;
|
|
159
|
+
htmlBody: string;
|
|
160
|
+
textBody: string;
|
|
161
|
+
ruleId: string;
|
|
162
|
+
autoApprove: boolean;
|
|
163
|
+
}
|
|
164
|
+
interface AgentSelection {
|
|
165
|
+
accountId: string;
|
|
166
|
+
}
|
|
167
|
+
interface RecipientIdentifier {
|
|
168
|
+
id: string;
|
|
169
|
+
contactId: string;
|
|
170
|
+
}
|
|
171
|
+
interface EmailRuleEngineConfig {
|
|
172
|
+
db: {
|
|
173
|
+
connection: Connection;
|
|
174
|
+
collectionPrefix?: string;
|
|
175
|
+
};
|
|
176
|
+
redis: {
|
|
177
|
+
connection: Redis;
|
|
178
|
+
keyPrefix?: string;
|
|
179
|
+
};
|
|
180
|
+
adapters: {
|
|
181
|
+
queryUsers: (target: RuleTarget, limit: number) => Promise<Record<string, unknown>[]>;
|
|
182
|
+
resolveData: (user: Record<string, unknown>) => Record<string, unknown>;
|
|
183
|
+
sendEmail: (params: SendEmailParams) => Promise<void>;
|
|
184
|
+
selectAgent: (identifierId: string, context?: {
|
|
185
|
+
ruleId: string;
|
|
186
|
+
templateId: string;
|
|
187
|
+
}) => Promise<AgentSelection | null>;
|
|
188
|
+
findIdentifier: (email: string) => Promise<RecipientIdentifier | null>;
|
|
189
|
+
sendTestEmail?: (to: string, subject: string, html: string, text: string) => Promise<void>;
|
|
190
|
+
};
|
|
191
|
+
platforms?: string[];
|
|
192
|
+
audiences?: string[];
|
|
193
|
+
categories?: string[];
|
|
194
|
+
logger?: LogAdapter;
|
|
195
|
+
options?: {
|
|
196
|
+
lockTTLMs?: number;
|
|
197
|
+
defaultMaxPerRun?: number;
|
|
198
|
+
sendWindow?: {
|
|
199
|
+
startHour: number;
|
|
200
|
+
endHour: number;
|
|
201
|
+
timezone: string;
|
|
202
|
+
};
|
|
203
|
+
delayBetweenSendsMs?: number;
|
|
204
|
+
jitterMs?: number;
|
|
205
|
+
};
|
|
206
|
+
hooks?: {
|
|
207
|
+
onRunStart?: (info: {
|
|
208
|
+
rulesCount: number;
|
|
209
|
+
triggeredBy: string;
|
|
210
|
+
}) => void;
|
|
211
|
+
onRuleStart?: (info: {
|
|
212
|
+
ruleId: string;
|
|
213
|
+
ruleName: string;
|
|
214
|
+
matchedCount: number;
|
|
215
|
+
}) => void;
|
|
216
|
+
onSend?: (info: {
|
|
217
|
+
ruleId: string;
|
|
218
|
+
ruleName: string;
|
|
219
|
+
email: string;
|
|
220
|
+
status: 'sent' | 'error' | 'skipped' | 'invalid' | 'throttled';
|
|
221
|
+
}) => void;
|
|
222
|
+
onRuleComplete?: (info: {
|
|
223
|
+
ruleId: string;
|
|
224
|
+
ruleName: string;
|
|
225
|
+
stats: RuleRunStats;
|
|
226
|
+
}) => void;
|
|
227
|
+
onRunComplete?: (info: {
|
|
228
|
+
duration: number;
|
|
229
|
+
totalStats: RuleRunStats;
|
|
230
|
+
perRuleStats: PerRuleStats[];
|
|
231
|
+
}) => void;
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
interface EmailTemplate {
|
|
236
|
+
_id: string;
|
|
237
|
+
name: string;
|
|
238
|
+
slug: string;
|
|
239
|
+
description?: string;
|
|
240
|
+
category: TemplateCategory;
|
|
241
|
+
audience: TemplateAudience;
|
|
242
|
+
platform: string;
|
|
243
|
+
subject: string;
|
|
244
|
+
body: string;
|
|
245
|
+
textBody?: string;
|
|
246
|
+
variables: string[];
|
|
247
|
+
version: number;
|
|
248
|
+
isActive: boolean;
|
|
249
|
+
createdAt: Date;
|
|
250
|
+
updatedAt: Date;
|
|
251
|
+
}
|
|
252
|
+
interface CreateEmailTemplateInput {
|
|
253
|
+
name: string;
|
|
254
|
+
slug: string;
|
|
255
|
+
description?: string;
|
|
256
|
+
category: TemplateCategory;
|
|
257
|
+
audience: TemplateAudience;
|
|
258
|
+
platform: string;
|
|
259
|
+
subject: string;
|
|
260
|
+
body: string;
|
|
261
|
+
textBody?: string;
|
|
262
|
+
variables?: string[];
|
|
263
|
+
}
|
|
264
|
+
interface UpdateEmailTemplateInput {
|
|
265
|
+
name?: string;
|
|
266
|
+
description?: string;
|
|
267
|
+
category?: TemplateCategory;
|
|
268
|
+
audience?: TemplateAudience;
|
|
269
|
+
platform?: string;
|
|
270
|
+
subject?: string;
|
|
271
|
+
body?: string;
|
|
272
|
+
textBody?: string;
|
|
273
|
+
variables?: string[];
|
|
274
|
+
isActive?: boolean;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
interface IEmailTemplate extends Omit<EmailTemplate, '_id'> {
|
|
278
|
+
}
|
|
279
|
+
type EmailTemplateDocument = HydratedDocument<IEmailTemplate>;
|
|
280
|
+
interface EmailTemplateStatics {
|
|
281
|
+
findBySlug(slug: string): Promise<EmailTemplateDocument | null>;
|
|
282
|
+
findActive(): Promise<EmailTemplateDocument[]>;
|
|
283
|
+
findByCategory(category: TemplateCategory): Promise<EmailTemplateDocument[]>;
|
|
284
|
+
findByAudience(audience: TemplateAudience): Promise<EmailTemplateDocument[]>;
|
|
285
|
+
createTemplate(input: CreateEmailTemplateInput): Promise<EmailTemplateDocument>;
|
|
286
|
+
}
|
|
287
|
+
type EmailTemplateModel = Model<IEmailTemplate> & EmailTemplateStatics;
|
|
288
|
+
declare function createEmailTemplateSchema(platformValues?: string[], audienceValues?: string[], categoryValues?: string[], collectionPrefix?: string): Schema<IEmailTemplate, Model<IEmailTemplate, any, any, any, mongoose.Document<unknown, any, IEmailTemplate, any, {}> & IEmailTemplate & {
|
|
289
|
+
_id: mongoose.Types.ObjectId;
|
|
290
|
+
} & {
|
|
291
|
+
__v: number;
|
|
292
|
+
}, any>, {}, {}, {}, {}, mongoose.DefaultSchemaOptions, IEmailTemplate, mongoose.Document<unknown, {}, mongoose.FlatRecord<IEmailTemplate>, {}, mongoose.DefaultSchemaOptions> & mongoose.FlatRecord<IEmailTemplate> & {
|
|
293
|
+
_id: mongoose.Types.ObjectId;
|
|
294
|
+
} & {
|
|
295
|
+
__v: number;
|
|
296
|
+
}>;
|
|
297
|
+
|
|
298
|
+
interface IEmailRule extends Omit<EmailRule, '_id' | 'templateId'> {
|
|
299
|
+
templateId: Types.ObjectId;
|
|
300
|
+
}
|
|
301
|
+
type EmailRuleDocument = HydratedDocument<IEmailRule>;
|
|
302
|
+
interface EmailRuleStatics {
|
|
303
|
+
findActive(): Promise<EmailRuleDocument[]>;
|
|
304
|
+
findByTemplateId(templateId: string | Types.ObjectId): Promise<EmailRuleDocument[]>;
|
|
305
|
+
createRule(input: CreateEmailRuleInput): Promise<EmailRuleDocument>;
|
|
306
|
+
}
|
|
307
|
+
type EmailRuleModel = Model<IEmailRule> & EmailRuleStatics;
|
|
308
|
+
declare function createEmailRuleSchema(platformValues?: string[], audienceValues?: string[], collectionPrefix?: string): Schema<IEmailRule, Model<IEmailRule, any, any, any, mongoose.Document<unknown, any, IEmailRule, any, {}> & IEmailRule & {
|
|
309
|
+
_id: Types.ObjectId;
|
|
310
|
+
} & {
|
|
311
|
+
__v: number;
|
|
312
|
+
}, any>, {}, {}, {}, {}, mongoose.DefaultSchemaOptions, IEmailRule, mongoose.Document<unknown, {}, mongoose.FlatRecord<IEmailRule>, {}, mongoose.DefaultSchemaOptions> & mongoose.FlatRecord<IEmailRule> & {
|
|
313
|
+
_id: Types.ObjectId;
|
|
314
|
+
} & {
|
|
315
|
+
__v: number;
|
|
316
|
+
}>;
|
|
317
|
+
|
|
318
|
+
interface IEmailRuleSend {
|
|
319
|
+
ruleId: Types.ObjectId;
|
|
320
|
+
userId: Types.ObjectId;
|
|
321
|
+
emailIdentifierId?: Types.ObjectId;
|
|
322
|
+
messageId?: Types.ObjectId;
|
|
323
|
+
sentAt: Date;
|
|
324
|
+
status?: string;
|
|
325
|
+
accountId?: string;
|
|
326
|
+
senderName?: string;
|
|
327
|
+
subject?: string;
|
|
328
|
+
failureReason?: string;
|
|
329
|
+
}
|
|
330
|
+
type EmailRuleSendDocument = HydratedDocument<IEmailRuleSend>;
|
|
331
|
+
interface EmailRuleSendStatics {
|
|
332
|
+
findLatestForUser(ruleId: string | Types.ObjectId, userId: string | Types.ObjectId): Promise<EmailRuleSendDocument | null>;
|
|
333
|
+
findRecentByUserIds(userIds: (string | Types.ObjectId)[], sinceDays: number): Promise<EmailRuleSendDocument[]>;
|
|
334
|
+
logSend(ruleId: string | Types.ObjectId, userId: string | Types.ObjectId, emailIdentifierId?: string | Types.ObjectId, messageId?: string | Types.ObjectId, extra?: {
|
|
335
|
+
status?: string;
|
|
336
|
+
accountId?: string;
|
|
337
|
+
senderName?: string;
|
|
338
|
+
subject?: string;
|
|
339
|
+
failureReason?: string;
|
|
340
|
+
}): Promise<EmailRuleSendDocument>;
|
|
341
|
+
}
|
|
342
|
+
type EmailRuleSendModel = Model<IEmailRuleSend> & EmailRuleSendStatics;
|
|
343
|
+
declare function createEmailRuleSendSchema(collectionPrefix?: string): Schema<IEmailRuleSend, Model<IEmailRuleSend, any, any, any, mongoose.Document<unknown, any, IEmailRuleSend, any, {}> & IEmailRuleSend & {
|
|
344
|
+
_id: Types.ObjectId;
|
|
345
|
+
} & {
|
|
346
|
+
__v: number;
|
|
347
|
+
}, any>, {}, {}, {}, {}, mongoose.DefaultSchemaOptions, IEmailRuleSend, mongoose.Document<unknown, {}, mongoose.FlatRecord<IEmailRuleSend>, {}, mongoose.DefaultSchemaOptions> & mongoose.FlatRecord<IEmailRuleSend> & {
|
|
348
|
+
_id: Types.ObjectId;
|
|
349
|
+
} & {
|
|
350
|
+
__v: number;
|
|
351
|
+
}>;
|
|
352
|
+
|
|
353
|
+
interface IEmailRuleRunLog {
|
|
354
|
+
runAt: Date;
|
|
355
|
+
triggeredBy: string;
|
|
356
|
+
duration: number;
|
|
357
|
+
rulesProcessed: number;
|
|
358
|
+
totalStats: {
|
|
359
|
+
matched: number;
|
|
360
|
+
sent: number;
|
|
361
|
+
skipped: number;
|
|
362
|
+
skippedByThrottle: number;
|
|
363
|
+
errors: number;
|
|
364
|
+
};
|
|
365
|
+
perRuleStats: Array<{
|
|
366
|
+
ruleId: Types.ObjectId;
|
|
367
|
+
ruleName: string;
|
|
368
|
+
matched: number;
|
|
369
|
+
sent: number;
|
|
370
|
+
skipped: number;
|
|
371
|
+
skippedByThrottle: number;
|
|
372
|
+
errors: number;
|
|
373
|
+
}>;
|
|
374
|
+
}
|
|
375
|
+
type EmailRuleRunLogDocument = HydratedDocument<IEmailRuleRunLog>;
|
|
376
|
+
interface EmailRuleRunLogStatics {
|
|
377
|
+
getRecent(limit?: number): Promise<EmailRuleRunLogDocument[]>;
|
|
378
|
+
getByRuleId(ruleId: string | Types.ObjectId, limit?: number): Promise<EmailRuleRunLogDocument[]>;
|
|
379
|
+
}
|
|
380
|
+
type EmailRuleRunLogModel = Model<IEmailRuleRunLog> & EmailRuleRunLogStatics;
|
|
381
|
+
declare function createEmailRuleRunLogSchema(collectionPrefix?: string): Schema<IEmailRuleRunLog, Model<IEmailRuleRunLog, any, any, any, mongoose.Document<unknown, any, IEmailRuleRunLog, any, {}> & IEmailRuleRunLog & {
|
|
382
|
+
_id: Types.ObjectId;
|
|
383
|
+
} & {
|
|
384
|
+
__v: number;
|
|
385
|
+
}, any>, {}, {}, {}, {}, mongoose.DefaultSchemaOptions, IEmailRuleRunLog, mongoose.Document<unknown, {}, mongoose.FlatRecord<IEmailRuleRunLog>, {}, mongoose.DefaultSchemaOptions> & mongoose.FlatRecord<IEmailRuleRunLog> & {
|
|
386
|
+
_id: Types.ObjectId;
|
|
387
|
+
} & {
|
|
388
|
+
__v: number;
|
|
389
|
+
}>;
|
|
390
|
+
|
|
391
|
+
interface EmailThrottleConfig {
|
|
392
|
+
_id: string;
|
|
393
|
+
maxPerUserPerDay: number;
|
|
394
|
+
maxPerUserPerWeek: number;
|
|
395
|
+
minGapDays: number;
|
|
396
|
+
throttleWindow: ThrottleWindow;
|
|
397
|
+
updatedAt: Date;
|
|
398
|
+
}
|
|
399
|
+
interface UpdateEmailThrottleConfigInput {
|
|
400
|
+
maxPerUserPerDay?: number;
|
|
401
|
+
maxPerUserPerWeek?: number;
|
|
402
|
+
minGapDays?: number;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
interface IEmailThrottleConfig extends Omit<EmailThrottleConfig, '_id'> {
|
|
406
|
+
}
|
|
407
|
+
type EmailThrottleConfigDocument = HydratedDocument<IEmailThrottleConfig>;
|
|
408
|
+
interface EmailThrottleConfigStatics {
|
|
409
|
+
getConfig(): Promise<EmailThrottleConfigDocument>;
|
|
410
|
+
}
|
|
411
|
+
type EmailThrottleConfigModel = Model<IEmailThrottleConfig> & EmailThrottleConfigStatics;
|
|
412
|
+
declare function createEmailThrottleConfigSchema(collectionPrefix?: string): Schema<IEmailThrottleConfig, Model<IEmailThrottleConfig, any, any, any, mongoose.Document<unknown, any, IEmailThrottleConfig, any, {}> & IEmailThrottleConfig & {
|
|
413
|
+
_id: mongoose.Types.ObjectId;
|
|
414
|
+
} & {
|
|
415
|
+
__v: number;
|
|
416
|
+
}, any>, {}, {}, {}, {}, mongoose.DefaultSchemaOptions, IEmailThrottleConfig, mongoose.Document<unknown, {}, mongoose.FlatRecord<IEmailThrottleConfig>, {}, mongoose.DefaultSchemaOptions> & mongoose.FlatRecord<IEmailThrottleConfig> & {
|
|
417
|
+
_id: mongoose.Types.ObjectId;
|
|
418
|
+
} & {
|
|
419
|
+
__v: number;
|
|
420
|
+
}>;
|
|
421
|
+
|
|
422
|
+
declare class TemplateService {
|
|
423
|
+
private EmailTemplate;
|
|
424
|
+
private config;
|
|
425
|
+
private renderService;
|
|
426
|
+
constructor(EmailTemplate: EmailTemplateModel, config: EmailRuleEngineConfig);
|
|
427
|
+
list(filters?: {
|
|
428
|
+
category?: TemplateCategory;
|
|
429
|
+
audience?: TemplateAudience;
|
|
430
|
+
platform?: string;
|
|
431
|
+
isActive?: boolean;
|
|
432
|
+
}): Promise<EmailTemplateDocument[]>;
|
|
433
|
+
getById(id: string): Promise<EmailTemplateDocument | null>;
|
|
434
|
+
getBySlug(slug: string): Promise<EmailTemplateDocument | null>;
|
|
435
|
+
create(input: CreateEmailTemplateInput): Promise<EmailTemplateDocument>;
|
|
436
|
+
update(id: string, input: UpdateEmailTemplateInput): Promise<EmailTemplateDocument | null>;
|
|
437
|
+
delete(id: string): Promise<boolean>;
|
|
438
|
+
toggleActive(id: string): Promise<EmailTemplateDocument | null>;
|
|
439
|
+
preview(id: string, sampleData: Record<string, unknown>): Promise<{
|
|
440
|
+
html: string;
|
|
441
|
+
text: string;
|
|
442
|
+
subject: string;
|
|
443
|
+
} | null>;
|
|
444
|
+
previewRaw(subject: string, body: string, sampleData: Record<string, unknown>, textBody?: string): Promise<{
|
|
445
|
+
html: string;
|
|
446
|
+
text: string;
|
|
447
|
+
subject: string;
|
|
448
|
+
}>;
|
|
449
|
+
validate(body: string): Promise<{
|
|
450
|
+
valid: boolean;
|
|
451
|
+
errors: string[];
|
|
452
|
+
variables: string[];
|
|
453
|
+
}>;
|
|
454
|
+
sendTestEmail(id: string, testEmail: string, sampleData: Record<string, unknown>): Promise<{
|
|
455
|
+
success: boolean;
|
|
456
|
+
error?: string;
|
|
457
|
+
}>;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
declare class RuleService {
|
|
461
|
+
private EmailRule;
|
|
462
|
+
private EmailTemplate;
|
|
463
|
+
private EmailRuleRunLog;
|
|
464
|
+
private config;
|
|
465
|
+
constructor(EmailRule: EmailRuleModel, EmailTemplate: EmailTemplateModel, EmailRuleRunLog: EmailRuleRunLogModel, config: EmailRuleEngineConfig);
|
|
466
|
+
list(): Promise<EmailRuleDocument[]>;
|
|
467
|
+
getById(id: string): Promise<EmailRuleDocument | null>;
|
|
468
|
+
create(input: CreateEmailRuleInput): Promise<EmailRuleDocument>;
|
|
469
|
+
update(id: string, input: UpdateEmailRuleInput): Promise<EmailRuleDocument | null>;
|
|
470
|
+
delete(id: string): Promise<{
|
|
471
|
+
deleted: boolean;
|
|
472
|
+
disabled?: boolean;
|
|
473
|
+
}>;
|
|
474
|
+
toggleActive(id: string): Promise<EmailRuleDocument | null>;
|
|
475
|
+
dryRun(id: string): Promise<{
|
|
476
|
+
matchedCount: number;
|
|
477
|
+
ruleId: string;
|
|
478
|
+
}>;
|
|
479
|
+
getRunHistory(limit?: number): Promise<unknown[]>;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
interface UserThrottle {
|
|
483
|
+
today: number;
|
|
484
|
+
thisWeek: number;
|
|
485
|
+
lastSentDate: Date | null;
|
|
486
|
+
}
|
|
487
|
+
declare class RuleRunnerService {
|
|
488
|
+
private EmailRule;
|
|
489
|
+
private EmailTemplate;
|
|
490
|
+
private EmailRuleSend;
|
|
491
|
+
private EmailRuleRunLog;
|
|
492
|
+
private EmailThrottleConfig;
|
|
493
|
+
private config;
|
|
494
|
+
private templateRenderer;
|
|
495
|
+
private lock;
|
|
496
|
+
private logger;
|
|
497
|
+
constructor(EmailRule: EmailRuleModel, EmailTemplate: EmailTemplateModel, EmailRuleSend: EmailRuleSendModel, EmailRuleRunLog: EmailRuleRunLogModel, EmailThrottleConfig: EmailThrottleConfigModel, config: EmailRuleEngineConfig);
|
|
498
|
+
runAllRules(triggeredBy?: RunTrigger): Promise<void>;
|
|
499
|
+
executeRule(rule: any, throttleMap: Map<string, UserThrottle>, throttleConfig: any, templateMap?: Map<string, any>): Promise<RuleRunStats>;
|
|
500
|
+
private checkThrottle;
|
|
501
|
+
private getTodayStart;
|
|
502
|
+
buildThrottleMap(recentSends: any[]): Map<string, UserThrottle>;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
declare class AlxEmailError extends AlxError {
|
|
506
|
+
constructor(message: string, code: string);
|
|
507
|
+
}
|
|
508
|
+
declare class ConfigValidationError extends AlxEmailError {
|
|
509
|
+
readonly field: string;
|
|
510
|
+
constructor(message: string, field: string);
|
|
511
|
+
}
|
|
512
|
+
declare class TemplateNotFoundError extends AlxEmailError {
|
|
513
|
+
readonly templateId: string;
|
|
514
|
+
constructor(templateId: string);
|
|
515
|
+
}
|
|
516
|
+
declare class TemplateSyntaxError extends AlxEmailError {
|
|
517
|
+
readonly errors: string[];
|
|
518
|
+
constructor(message: string, errors: string[]);
|
|
519
|
+
}
|
|
520
|
+
declare class RuleNotFoundError extends AlxEmailError {
|
|
521
|
+
readonly ruleId: string;
|
|
522
|
+
constructor(ruleId: string);
|
|
523
|
+
}
|
|
524
|
+
declare class RuleTemplateIncompatibleError extends AlxEmailError {
|
|
525
|
+
readonly reason: string;
|
|
526
|
+
constructor(reason: string);
|
|
527
|
+
}
|
|
528
|
+
declare class LockAcquisitionError extends AlxEmailError {
|
|
529
|
+
constructor();
|
|
530
|
+
}
|
|
531
|
+
declare class DuplicateSlugError extends AlxEmailError {
|
|
532
|
+
readonly slug: string;
|
|
533
|
+
constructor(slug: string);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
declare function validateConfig(raw: unknown): void;
|
|
537
|
+
|
|
538
|
+
interface RenderResult {
|
|
539
|
+
html: string;
|
|
540
|
+
text: string;
|
|
541
|
+
subject: string;
|
|
542
|
+
}
|
|
543
|
+
interface CompiledTemplate {
|
|
544
|
+
subjectFn: HandlebarsTemplateDelegate;
|
|
545
|
+
bodyFn: HandlebarsTemplateDelegate;
|
|
546
|
+
textBodyFn?: HandlebarsTemplateDelegate;
|
|
547
|
+
}
|
|
548
|
+
declare class TemplateRenderService {
|
|
549
|
+
constructor();
|
|
550
|
+
renderSingle(subject: string, body: string, data: Record<string, unknown>, textBody?: string): RenderResult;
|
|
551
|
+
compileBatch(subject: string, body: string, textBody?: string): CompiledTemplate;
|
|
552
|
+
renderFromCompiled(compiled: CompiledTemplate, data: Record<string, unknown>): RenderResult;
|
|
553
|
+
renderPreview(subject: string, body: string, data: Record<string, unknown>, textBody?: string): RenderResult;
|
|
554
|
+
extractVariables(template: string): string[];
|
|
555
|
+
validateTemplate(body: string): {
|
|
556
|
+
valid: boolean;
|
|
557
|
+
errors: string[];
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
declare class RedisLock {
|
|
562
|
+
private redis;
|
|
563
|
+
private lockKey;
|
|
564
|
+
private ttlMs;
|
|
565
|
+
private logger?;
|
|
566
|
+
private lockValue;
|
|
567
|
+
constructor(redis: Redis, lockKey: string, ttlMs: number, logger?: LogAdapter | undefined);
|
|
568
|
+
acquire(): Promise<boolean>;
|
|
569
|
+
release(): Promise<void>;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Engine instance with Express routes and programmatic service access.
|
|
574
|
+
*/
|
|
575
|
+
interface EmailRuleEngine {
|
|
576
|
+
routes: Router;
|
|
577
|
+
runner: RuleRunnerService;
|
|
578
|
+
templateService: TemplateService;
|
|
579
|
+
ruleService: RuleService;
|
|
580
|
+
models: {
|
|
581
|
+
EmailTemplate: EmailTemplateModel;
|
|
582
|
+
EmailRule: EmailRuleModel;
|
|
583
|
+
EmailRuleSend: EmailRuleSendModel;
|
|
584
|
+
EmailRuleRunLog: EmailRuleRunLogModel;
|
|
585
|
+
EmailThrottleConfig: EmailThrottleConfigModel;
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Creates an email rule engine instance with routes, services, and models.
|
|
590
|
+
*
|
|
591
|
+
* @param config - Engine configuration including DB, Redis, adapters, and options.
|
|
592
|
+
* @returns Engine instance with Express routes and programmatic service access.
|
|
593
|
+
* @throws {ConfigValidationError} If the provided config is invalid.
|
|
594
|
+
*
|
|
595
|
+
* @example
|
|
596
|
+
* ```typescript
|
|
597
|
+
* const engine = createEmailRuleEngine({
|
|
598
|
+
* db: { connection: mongoose.createConnection(uri) },
|
|
599
|
+
* redis: { connection: new Redis() },
|
|
600
|
+
* adapters: { queryUsers, resolveData, sendEmail, selectAgent, findIdentifier },
|
|
601
|
+
* });
|
|
602
|
+
* app.use('/api/email-rules', engine.routes);
|
|
603
|
+
* ```
|
|
604
|
+
*/
|
|
605
|
+
declare function createEmailRuleEngine(config: EmailRuleEngineConfig): EmailRuleEngine;
|
|
606
|
+
|
|
607
|
+
export { type AgentSelection, AlxEmailError, type CompiledTemplate, ConfigValidationError, type CreateEmailRuleInput, type CreateEmailTemplateInput, DuplicateSlugError, EMAIL_SEND_STATUS, EMAIL_TYPE, type EmailRule, type EmailRuleDocument, type EmailRuleEngine, type EmailRuleEngineConfig, type EmailRuleModel, type EmailRuleRunLog, type EmailRuleRunLogDocument, type EmailRuleRunLogModel, type EmailRuleRunLogStatics, type EmailRuleSend, type EmailRuleSendDocument, type EmailRuleSendModel, type EmailRuleSendStatics, type EmailRuleStatics, type EmailSendStatus, type EmailTemplate, type EmailTemplateDocument, type EmailTemplateModel, type EmailTemplateStatics, type EmailThrottleConfig, type EmailThrottleConfigDocument, type EmailThrottleConfigModel, type EmailThrottleConfigStatics, type EmailType, type IEmailRule, type IEmailRuleRunLog, type IEmailRuleSend, type IEmailTemplate, type IEmailThrottleConfig, LockAcquisitionError, type PerRuleStats, RULE_OPERATOR, RUN_TRIGGER, type RecipientIdentifier, RedisLock, type RenderResult, type RuleCondition, RuleNotFoundError, type RuleOperator, type RuleRunStats, RuleRunnerService, RuleService, type RuleTarget, RuleTemplateIncompatibleError, type RunTrigger, type SendEmailParams, TEMPLATE_AUDIENCE, TEMPLATE_CATEGORY, THROTTLE_WINDOW, type TemplateAudience, type TemplateCategory, TemplateNotFoundError, TemplateRenderService, TemplateService, TemplateSyntaxError, type ThrottleWindow, type UpdateEmailRuleInput, type UpdateEmailTemplateInput, type UpdateEmailThrottleConfigInput, createEmailRuleEngine, createEmailRuleRunLogSchema, createEmailRuleSchema, createEmailRuleSendSchema, createEmailTemplateSchema, createEmailThrottleConfigSchema, validateConfig };
|