organify-email 1.0.0 → 1.1.2
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/brevo-client.d.ts +26 -3
- package/dist/brevo-client.d.ts.map +1 -1
- package/dist/brevo-client.js +178 -17
- package/dist/brevo-client.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/brevo-client.ts +215 -19
- package/src/index.ts +4 -0
package/dist/brevo-client.d.ts
CHANGED
|
@@ -1,13 +1,30 @@
|
|
|
1
1
|
import { type EmailTemplateName } from './templates';
|
|
2
2
|
export interface BrevoEmailConfig {
|
|
3
3
|
apiKey: string;
|
|
4
|
+
mailerSendApiKey?: string;
|
|
4
5
|
senderName?: string;
|
|
5
6
|
senderEmail?: string;
|
|
7
|
+
mailerSendSenderName?: string;
|
|
8
|
+
mailerSendSenderEmail?: string;
|
|
6
9
|
/** Daily send limit (default: 300) */
|
|
7
10
|
dailyLimit?: number;
|
|
8
11
|
/** Enable sending (set false for dev/test to just log) */
|
|
9
12
|
enabled?: boolean;
|
|
10
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Hardcoded Brevo provider configuration for package-level local/demo usage.
|
|
16
|
+
* Replace apiKey with a valid Brevo key before using in real sends.
|
|
17
|
+
*/
|
|
18
|
+
export declare const HARDCODED_BREVO_PROVIDER: Readonly<{
|
|
19
|
+
apiKey: string;
|
|
20
|
+
senderName: string;
|
|
21
|
+
senderEmail: string;
|
|
22
|
+
dailyLimit: number;
|
|
23
|
+
enabled: boolean;
|
|
24
|
+
}>;
|
|
25
|
+
export type OrganifyEmailService = 'users' | 'workspaces' | 'notifications' | 'reports';
|
|
26
|
+
export declare const ORGANIFY_EMAIL_DAILY_LIMITS: Readonly<Record<OrganifyEmailService, number>>;
|
|
27
|
+
export declare function createOrganifyEmailClient(service: OrganifyEmailService): BrevoEmailClient;
|
|
11
28
|
export interface EmailRecipient {
|
|
12
29
|
email: string;
|
|
13
30
|
name?: string;
|
|
@@ -53,17 +70,23 @@ export interface DailyStats {
|
|
|
53
70
|
};
|
|
54
71
|
}
|
|
55
72
|
export declare class BrevoEmailClient {
|
|
56
|
-
private readonly
|
|
57
|
-
private readonly
|
|
58
|
-
private readonly
|
|
73
|
+
private readonly brevoApiKey;
|
|
74
|
+
private readonly mailerSendApiKey;
|
|
75
|
+
private readonly brevoSenderName;
|
|
76
|
+
private readonly brevoSenderEmail;
|
|
77
|
+
private readonly mailerSendSenderName;
|
|
78
|
+
private readonly mailerSendSenderEmail;
|
|
59
79
|
private readonly dailyLimit;
|
|
60
80
|
private readonly enabled;
|
|
61
81
|
private dailySent;
|
|
62
82
|
private dailyDate;
|
|
63
83
|
private dailyByPriority;
|
|
64
84
|
private static readonly API_URL;
|
|
85
|
+
private static readonly MAILERSEND_API_URL;
|
|
65
86
|
constructor(config: BrevoEmailConfig);
|
|
66
87
|
send(options: SendEmailOptions): Promise<SendResult>;
|
|
88
|
+
private sendViaBrevo;
|
|
89
|
+
private sendViaMailerSend;
|
|
67
90
|
sendBatch(recipients: EmailRecipient[], options: Omit<SendEmailOptions, 'to'>): Promise<SendResult[]>;
|
|
68
91
|
getStats(): DailyStats;
|
|
69
92
|
private checkDayReset;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brevo-client.d.ts","sourceRoot":"","sources":["../src/brevo-client.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAkB,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIrE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,cAAc,GAAG,cAAc,EAAE,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IACnD,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0BAA0B;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,UAAU,GAAG,QAAQ,GAAG,KAAK,CAAC;IACzC,wBAAwB;IACxB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,oBAAoB;IACpB,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC;IACtB,qBAAqB;IACrB,GAAG,CAAC,EAAE,cAAc,EAAE,CAAC;IACvB,uBAAuB;IACvB,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/D;AAID,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"brevo-client.d.ts","sourceRoot":"","sources":["../src/brevo-client.ts"],"names":[],"mappings":"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"}
|
package/dist/brevo-client.js
CHANGED
|
@@ -15,13 +15,75 @@
|
|
|
15
15
|
// await client.send({ to, subject, template: 'report-ready', params });
|
|
16
16
|
// ─────────────────────────────────────────────
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.BrevoEmailClient = void 0;
|
|
18
|
+
exports.BrevoEmailClient = exports.ORGANIFY_EMAIL_DAILY_LIMITS = exports.HARDCODED_BREVO_PROVIDER = void 0;
|
|
19
|
+
exports.createOrganifyEmailClient = createOrganifyEmailClient;
|
|
19
20
|
const templates_1 = require("./templates");
|
|
21
|
+
function getEnvVar(name) {
|
|
22
|
+
const value = globalThis?.process?.env?.[name];
|
|
23
|
+
if (typeof value !== 'string')
|
|
24
|
+
return undefined;
|
|
25
|
+
const trimmed = value.trim();
|
|
26
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
27
|
+
}
|
|
28
|
+
function parseBooleanEnv(name) {
|
|
29
|
+
const value = getEnvVar(name)?.toLowerCase();
|
|
30
|
+
if (!value)
|
|
31
|
+
return undefined;
|
|
32
|
+
if (value === 'true' || value === '1' || value === 'yes')
|
|
33
|
+
return true;
|
|
34
|
+
if (value === 'false' || value === '0' || value === 'no')
|
|
35
|
+
return false;
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Hardcoded Brevo provider configuration for package-level local/demo usage.
|
|
40
|
+
* Replace apiKey with a valid Brevo key before using in real sends.
|
|
41
|
+
*/
|
|
42
|
+
exports.HARDCODED_BREVO_PROVIDER = {
|
|
43
|
+
// Legacy fallback only. Prefer env-based configuration in createOrganifyEmailClient.
|
|
44
|
+
apiKey: '',
|
|
45
|
+
senderName: 'Organify',
|
|
46
|
+
senderEmail: 'noreply@organify.studio',
|
|
47
|
+
dailyLimit: 300,
|
|
48
|
+
enabled: false,
|
|
49
|
+
};
|
|
50
|
+
exports.ORGANIFY_EMAIL_DAILY_LIMITS = {
|
|
51
|
+
users: 50,
|
|
52
|
+
workspaces: 50,
|
|
53
|
+
notifications: 150,
|
|
54
|
+
reports: 300,
|
|
55
|
+
};
|
|
56
|
+
function createOrganifyEmailClient(service) {
|
|
57
|
+
const apiKey = getEnvVar('BREVO_API_KEY') || exports.HARDCODED_BREVO_PROVIDER.apiKey;
|
|
58
|
+
const mailerSendApiKey = getEnvVar('MAILERSEND_API_KEY');
|
|
59
|
+
const senderName = getEnvVar('BREVO_SENDER_NAME') || exports.HARDCODED_BREVO_PROVIDER.senderName;
|
|
60
|
+
const senderEmail = getEnvVar('BREVO_SENDER_EMAIL') || exports.HARDCODED_BREVO_PROVIDER.senderEmail;
|
|
61
|
+
const mailerSendSenderName = getEnvVar('MAILERSEND_SENDER_NAME') || senderName;
|
|
62
|
+
const mailerSendSenderEmail = getEnvVar('MAILERSEND_SENDER_EMAIL') || senderEmail;
|
|
63
|
+
const forcedEnabled = parseBooleanEnv('BREVO_ENABLED');
|
|
64
|
+
const enabled = forcedEnabled ?? Boolean(apiKey || mailerSendApiKey);
|
|
65
|
+
if (!apiKey && !mailerSendApiKey) {
|
|
66
|
+
console.warn(`[Email] BREVO_API_KEY and MAILERSEND_API_KEY are missing for service "${service}". Running in DRY RUN mode (emails not sent).`);
|
|
67
|
+
}
|
|
68
|
+
return new BrevoEmailClient({
|
|
69
|
+
apiKey,
|
|
70
|
+
mailerSendApiKey,
|
|
71
|
+
senderName,
|
|
72
|
+
senderEmail,
|
|
73
|
+
mailerSendSenderName,
|
|
74
|
+
mailerSendSenderEmail,
|
|
75
|
+
dailyLimit: exports.ORGANIFY_EMAIL_DAILY_LIMITS[service],
|
|
76
|
+
enabled,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
20
79
|
// ─── Client ─────────────────────────────────
|
|
21
80
|
class BrevoEmailClient {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
81
|
+
brevoApiKey;
|
|
82
|
+
mailerSendApiKey;
|
|
83
|
+
brevoSenderName;
|
|
84
|
+
brevoSenderEmail;
|
|
85
|
+
mailerSendSenderName;
|
|
86
|
+
mailerSendSenderEmail;
|
|
25
87
|
dailyLimit;
|
|
26
88
|
enabled;
|
|
27
89
|
// Daily counter (in-memory, resets on restart)
|
|
@@ -29,10 +91,14 @@ class BrevoEmailClient {
|
|
|
29
91
|
dailyDate = '';
|
|
30
92
|
dailyByPriority = { critical: 0, normal: 0, low: 0 };
|
|
31
93
|
static API_URL = 'https://api.brevo.com/v3/smtp/email';
|
|
94
|
+
static MAILERSEND_API_URL = 'https://api.mailersend.com/v1/email';
|
|
32
95
|
constructor(config) {
|
|
33
|
-
this.
|
|
34
|
-
this.
|
|
35
|
-
this.
|
|
96
|
+
this.brevoApiKey = config.apiKey;
|
|
97
|
+
this.mailerSendApiKey = config.mailerSendApiKey || '';
|
|
98
|
+
this.brevoSenderName = config.senderName || 'Organify Team';
|
|
99
|
+
this.brevoSenderEmail = config.senderEmail || 'noreply@organify.studio';
|
|
100
|
+
this.mailerSendSenderName = config.mailerSendSenderName || this.brevoSenderName;
|
|
101
|
+
this.mailerSendSenderEmail = config.mailerSendSenderEmail || this.brevoSenderEmail;
|
|
36
102
|
this.dailyLimit = config.dailyLimit || 300;
|
|
37
103
|
this.enabled = config.enabled !== false;
|
|
38
104
|
}
|
|
@@ -78,15 +144,55 @@ class BrevoEmailClient {
|
|
|
78
144
|
this.incrementCounter(priority);
|
|
79
145
|
return { success: true, messageId: `dry-run-${Date.now()}`, skipped: false };
|
|
80
146
|
}
|
|
81
|
-
// Build Brevo payload
|
|
147
|
+
// Build Brevo/MailerSend payload basis
|
|
82
148
|
const recipients = Array.isArray(options.to) ? options.to : [options.to];
|
|
149
|
+
const recipientPayload = recipients.map((r) => ({ email: r.email, name: r.name }));
|
|
150
|
+
if (!this.brevoApiKey && !this.mailerSendApiKey) {
|
|
151
|
+
return { success: false, error: 'No email provider key configured (BREVO_API_KEY or MAILERSEND_API_KEY)' };
|
|
152
|
+
}
|
|
153
|
+
if (this.brevoApiKey) {
|
|
154
|
+
const brevoResult = await this.sendViaBrevo({
|
|
155
|
+
recipients: recipientPayload,
|
|
156
|
+
subject: options.subject,
|
|
157
|
+
htmlContent,
|
|
158
|
+
textContent: options.textContent,
|
|
159
|
+
params: options.params,
|
|
160
|
+
tags: options.tags,
|
|
161
|
+
cc: options.cc,
|
|
162
|
+
bcc: options.bcc,
|
|
163
|
+
replyTo: options.replyTo,
|
|
164
|
+
});
|
|
165
|
+
if (brevoResult.success) {
|
|
166
|
+
this.incrementCounter(priority);
|
|
167
|
+
return brevoResult;
|
|
168
|
+
}
|
|
169
|
+
console.warn(`[Email] Brevo send failed; trying MailerSend fallback: ${brevoResult.error || 'unknown error'}`);
|
|
170
|
+
}
|
|
171
|
+
if (this.mailerSendApiKey) {
|
|
172
|
+
const mailerSendResult = await this.sendViaMailerSend({
|
|
173
|
+
recipients: recipientPayload,
|
|
174
|
+
subject: options.subject,
|
|
175
|
+
htmlContent,
|
|
176
|
+
textContent: options.textContent,
|
|
177
|
+
cc: options.cc,
|
|
178
|
+
bcc: options.bcc,
|
|
179
|
+
replyTo: options.replyTo,
|
|
180
|
+
});
|
|
181
|
+
if (mailerSendResult.success) {
|
|
182
|
+
this.incrementCounter(priority);
|
|
183
|
+
}
|
|
184
|
+
return mailerSendResult;
|
|
185
|
+
}
|
|
186
|
+
return { success: false, error: 'Brevo failed and MAILERSEND_API_KEY is not configured for fallback' };
|
|
187
|
+
}
|
|
188
|
+
async sendViaBrevo(options) {
|
|
83
189
|
const payload = {
|
|
84
|
-
sender: { name: this.
|
|
85
|
-
to: recipients
|
|
190
|
+
sender: { name: this.brevoSenderName, email: this.brevoSenderEmail },
|
|
191
|
+
to: options.recipients,
|
|
86
192
|
subject: options.subject,
|
|
87
193
|
};
|
|
88
|
-
if (htmlContent)
|
|
89
|
-
payload.htmlContent = htmlContent;
|
|
194
|
+
if (options.htmlContent)
|
|
195
|
+
payload.htmlContent = options.htmlContent;
|
|
90
196
|
else if (options.textContent)
|
|
91
197
|
payload.textContent = options.textContent;
|
|
92
198
|
if (options.params)
|
|
@@ -103,8 +209,8 @@ class BrevoEmailClient {
|
|
|
103
209
|
const response = await fetch(BrevoEmailClient.API_URL, {
|
|
104
210
|
method: 'POST',
|
|
105
211
|
headers: {
|
|
106
|
-
|
|
107
|
-
'api-key': this.
|
|
212
|
+
accept: 'application/json',
|
|
213
|
+
'api-key': this.brevoApiKey,
|
|
108
214
|
'content-type': 'application/json',
|
|
109
215
|
},
|
|
110
216
|
body: JSON.stringify(payload),
|
|
@@ -112,15 +218,70 @@ class BrevoEmailClient {
|
|
|
112
218
|
if (!response.ok) {
|
|
113
219
|
const body = await response.text();
|
|
114
220
|
console.error(`[BrevoEmail] API error ${response.status}: ${body}`);
|
|
221
|
+
if (response.status === 401) {
|
|
222
|
+
console.error('[BrevoEmail] Check BREVO_API_KEY in env and ensure it is enabled for Transactional API/SMTP.');
|
|
223
|
+
}
|
|
115
224
|
return { success: false, error: `Brevo API error: ${response.status} — ${body}` };
|
|
116
225
|
}
|
|
117
226
|
const data = await response.json();
|
|
118
|
-
this.incrementCounter(priority);
|
|
119
227
|
return { success: true, messageId: data.messageId };
|
|
120
228
|
}
|
|
121
229
|
catch (err) {
|
|
122
|
-
|
|
123
|
-
|
|
230
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
231
|
+
console.error(`[BrevoEmail] Network error: ${message}`);
|
|
232
|
+
return { success: false, error: `Brevo network error: ${message}` };
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
async sendViaMailerSend(options) {
|
|
236
|
+
const payload = {
|
|
237
|
+
from: { email: this.mailerSendSenderEmail, name: this.mailerSendSenderName },
|
|
238
|
+
to: options.recipients,
|
|
239
|
+
subject: options.subject,
|
|
240
|
+
};
|
|
241
|
+
if (options.htmlContent)
|
|
242
|
+
payload.html = options.htmlContent;
|
|
243
|
+
if (options.textContent)
|
|
244
|
+
payload.text = options.textContent;
|
|
245
|
+
if (!options.textContent && options.htmlContent) {
|
|
246
|
+
payload.text = 'Mensagem enviada pelo Organify.';
|
|
247
|
+
}
|
|
248
|
+
if (options.cc)
|
|
249
|
+
payload.cc = options.cc;
|
|
250
|
+
if (options.bcc)
|
|
251
|
+
payload.bcc = options.bcc;
|
|
252
|
+
if (options.replyTo) {
|
|
253
|
+
payload.reply_to = {
|
|
254
|
+
email: options.replyTo.email,
|
|
255
|
+
name: options.replyTo.name,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
payload.reply_to = {
|
|
260
|
+
email: this.mailerSendSenderEmail,
|
|
261
|
+
name: this.mailerSendSenderName,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
try {
|
|
265
|
+
const response = await fetch(BrevoEmailClient.MAILERSEND_API_URL, {
|
|
266
|
+
method: 'POST',
|
|
267
|
+
headers: {
|
|
268
|
+
Authorization: `Bearer ${this.mailerSendApiKey}`,
|
|
269
|
+
'Content-Type': 'application/json',
|
|
270
|
+
},
|
|
271
|
+
body: JSON.stringify(payload),
|
|
272
|
+
});
|
|
273
|
+
if (!response.ok) {
|
|
274
|
+
const body = await response.text();
|
|
275
|
+
console.error(`[MailerSendEmail] API error ${response.status}: ${body}`);
|
|
276
|
+
return { success: false, error: `MailerSend API error: ${response.status} — ${body}` };
|
|
277
|
+
}
|
|
278
|
+
const messageId = response.headers.get('x-message-id') || undefined;
|
|
279
|
+
return { success: true, messageId };
|
|
280
|
+
}
|
|
281
|
+
catch (err) {
|
|
282
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
283
|
+
console.error(`[MailerSendEmail] Network error: ${message}`);
|
|
284
|
+
return { success: false, error: `MailerSend network error: ${message}` };
|
|
124
285
|
}
|
|
125
286
|
}
|
|
126
287
|
// ─── Batch Send (same template, multiple recipients) ──
|
package/dist/brevo-client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brevo-client.js","sourceRoot":"","sources":["../src/brevo-client.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"brevo-client.js","sourceRoot":"","sources":["../src/brevo-client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { BrevoEmailClient, type BrevoEmailConfig, type EmailRecipient, type SendEmailOptions, type SendResult, type DailyStats, } from './brevo-client';
|
|
1
|
+
export { BrevoEmailClient, HARDCODED_BREVO_PROVIDER, ORGANIFY_EMAIL_DAILY_LIMITS, createOrganifyEmailClient, type OrganifyEmailService, type BrevoEmailConfig, type EmailRecipient, type SendEmailOptions, type SendResult, type DailyStats, } from './brevo-client';
|
|
2
2
|
export { emailTemplates, type EmailTemplateName, } from './templates';
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,UAAU,GAChB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,cAAc,EACd,KAAK,iBAAiB,GACvB,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,2BAA2B,EAC3B,yBAAyB,EACzB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,UAAU,GAChB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,cAAc,EACd,KAAK,iBAAiB,GACvB,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
// organify-email — Public API
|
|
4
4
|
// ─────────────────────────────────────────────
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.emailTemplates = exports.BrevoEmailClient = void 0;
|
|
6
|
+
exports.emailTemplates = exports.createOrganifyEmailClient = exports.ORGANIFY_EMAIL_DAILY_LIMITS = exports.HARDCODED_BREVO_PROVIDER = exports.BrevoEmailClient = void 0;
|
|
7
7
|
var brevo_client_1 = require("./brevo-client");
|
|
8
8
|
Object.defineProperty(exports, "BrevoEmailClient", { enumerable: true, get: function () { return brevo_client_1.BrevoEmailClient; } });
|
|
9
|
+
Object.defineProperty(exports, "HARDCODED_BREVO_PROVIDER", { enumerable: true, get: function () { return brevo_client_1.HARDCODED_BREVO_PROVIDER; } });
|
|
10
|
+
Object.defineProperty(exports, "ORGANIFY_EMAIL_DAILY_LIMITS", { enumerable: true, get: function () { return brevo_client_1.ORGANIFY_EMAIL_DAILY_LIMITS; } });
|
|
11
|
+
Object.defineProperty(exports, "createOrganifyEmailClient", { enumerable: true, get: function () { return brevo_client_1.createOrganifyEmailClient; } });
|
|
9
12
|
var templates_1 = require("./templates");
|
|
10
13
|
Object.defineProperty(exports, "emailTemplates", { enumerable: true, get: function () { return templates_1.emailTemplates; } });
|
|
11
14
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,gDAAgD;AAChD,8BAA8B;AAC9B,gDAAgD;;;AAEhD,+
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,gDAAgD;AAChD,8BAA8B;AAC9B,gDAAgD;;;AAEhD,+CAWwB;AAVtB,gHAAA,gBAAgB,OAAA;AAChB,wHAAA,wBAAwB,OAAA;AACxB,2HAAA,2BAA2B,OAAA;AAC3B,yHAAA,yBAAyB,OAAA;AAS3B,yCAGqB;AAFnB,2GAAA,cAAc,OAAA"}
|
package/package.json
CHANGED
package/src/brevo-client.ts
CHANGED
|
@@ -20,14 +20,88 @@ import { emailTemplates, type EmailTemplateName } from './templates';
|
|
|
20
20
|
|
|
21
21
|
export interface BrevoEmailConfig {
|
|
22
22
|
apiKey: string;
|
|
23
|
+
mailerSendApiKey?: string;
|
|
23
24
|
senderName?: string;
|
|
24
25
|
senderEmail?: string;
|
|
26
|
+
mailerSendSenderName?: string;
|
|
27
|
+
mailerSendSenderEmail?: string;
|
|
25
28
|
/** Daily send limit (default: 300) */
|
|
26
29
|
dailyLimit?: number;
|
|
27
30
|
/** Enable sending (set false for dev/test to just log) */
|
|
28
31
|
enabled?: boolean;
|
|
29
32
|
}
|
|
30
33
|
|
|
34
|
+
function getEnvVar(name: string): string | undefined {
|
|
35
|
+
const value = (globalThis as any)?.process?.env?.[name];
|
|
36
|
+
if (typeof value !== 'string') return undefined;
|
|
37
|
+
const trimmed = value.trim();
|
|
38
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function parseBooleanEnv(name: string): boolean | undefined {
|
|
42
|
+
const value = getEnvVar(name)?.toLowerCase();
|
|
43
|
+
if (!value) return undefined;
|
|
44
|
+
if (value === 'true' || value === '1' || value === 'yes') return true;
|
|
45
|
+
if (value === 'false' || value === '0' || value === 'no') return false;
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Hardcoded Brevo provider configuration for package-level local/demo usage.
|
|
51
|
+
* Replace apiKey with a valid Brevo key before using in real sends.
|
|
52
|
+
*/
|
|
53
|
+
export const HARDCODED_BREVO_PROVIDER: Readonly<{
|
|
54
|
+
apiKey: string;
|
|
55
|
+
senderName: string;
|
|
56
|
+
senderEmail: string;
|
|
57
|
+
dailyLimit: number;
|
|
58
|
+
enabled: boolean;
|
|
59
|
+
}> = {
|
|
60
|
+
// Legacy fallback only. Prefer env-based configuration in createOrganifyEmailClient.
|
|
61
|
+
apiKey: '',
|
|
62
|
+
senderName: 'Organify',
|
|
63
|
+
senderEmail: 'noreply@organify.studio',
|
|
64
|
+
dailyLimit: 300,
|
|
65
|
+
enabled: false,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export type OrganifyEmailService = 'users' | 'workspaces' | 'notifications' | 'reports';
|
|
69
|
+
|
|
70
|
+
export const ORGANIFY_EMAIL_DAILY_LIMITS: Readonly<Record<OrganifyEmailService, number>> = {
|
|
71
|
+
users: 50,
|
|
72
|
+
workspaces: 50,
|
|
73
|
+
notifications: 150,
|
|
74
|
+
reports: 300,
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export function createOrganifyEmailClient(service: OrganifyEmailService): BrevoEmailClient {
|
|
78
|
+
const apiKey = getEnvVar('BREVO_API_KEY') || HARDCODED_BREVO_PROVIDER.apiKey;
|
|
79
|
+
const mailerSendApiKey = getEnvVar('MAILERSEND_API_KEY');
|
|
80
|
+
const senderName = getEnvVar('BREVO_SENDER_NAME') || HARDCODED_BREVO_PROVIDER.senderName;
|
|
81
|
+
const senderEmail = getEnvVar('BREVO_SENDER_EMAIL') || HARDCODED_BREVO_PROVIDER.senderEmail;
|
|
82
|
+
const mailerSendSenderName = getEnvVar('MAILERSEND_SENDER_NAME') || senderName;
|
|
83
|
+
const mailerSendSenderEmail = getEnvVar('MAILERSEND_SENDER_EMAIL') || senderEmail;
|
|
84
|
+
const forcedEnabled = parseBooleanEnv('BREVO_ENABLED');
|
|
85
|
+
const enabled = forcedEnabled ?? Boolean(apiKey || mailerSendApiKey);
|
|
86
|
+
|
|
87
|
+
if (!apiKey && !mailerSendApiKey) {
|
|
88
|
+
console.warn(
|
|
89
|
+
`[Email] BREVO_API_KEY and MAILERSEND_API_KEY are missing for service "${service}". Running in DRY RUN mode (emails not sent).`,
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return new BrevoEmailClient({
|
|
94
|
+
apiKey,
|
|
95
|
+
mailerSendApiKey,
|
|
96
|
+
senderName,
|
|
97
|
+
senderEmail,
|
|
98
|
+
mailerSendSenderName,
|
|
99
|
+
mailerSendSenderEmail,
|
|
100
|
+
dailyLimit: ORGANIFY_EMAIL_DAILY_LIMITS[service],
|
|
101
|
+
enabled,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
31
105
|
export interface EmailRecipient {
|
|
32
106
|
email: string;
|
|
33
107
|
name?: string;
|
|
@@ -75,9 +149,12 @@ export interface DailyStats {
|
|
|
75
149
|
// ─── Client ─────────────────────────────────
|
|
76
150
|
|
|
77
151
|
export class BrevoEmailClient {
|
|
78
|
-
private readonly
|
|
79
|
-
private readonly
|
|
80
|
-
private readonly
|
|
152
|
+
private readonly brevoApiKey: string;
|
|
153
|
+
private readonly mailerSendApiKey: string;
|
|
154
|
+
private readonly brevoSenderName: string;
|
|
155
|
+
private readonly brevoSenderEmail: string;
|
|
156
|
+
private readonly mailerSendSenderName: string;
|
|
157
|
+
private readonly mailerSendSenderEmail: string;
|
|
81
158
|
private readonly dailyLimit: number;
|
|
82
159
|
private readonly enabled: boolean;
|
|
83
160
|
|
|
@@ -87,11 +164,15 @@ export class BrevoEmailClient {
|
|
|
87
164
|
private dailyByPriority = { critical: 0, normal: 0, low: 0 };
|
|
88
165
|
|
|
89
166
|
private static readonly API_URL = 'https://api.brevo.com/v3/smtp/email';
|
|
167
|
+
private static readonly MAILERSEND_API_URL = 'https://api.mailersend.com/v1/email';
|
|
90
168
|
|
|
91
169
|
constructor(config: BrevoEmailConfig) {
|
|
92
|
-
this.
|
|
93
|
-
this.
|
|
94
|
-
this.
|
|
170
|
+
this.brevoApiKey = config.apiKey;
|
|
171
|
+
this.mailerSendApiKey = config.mailerSendApiKey || '';
|
|
172
|
+
this.brevoSenderName = config.senderName || 'Organify Team';
|
|
173
|
+
this.brevoSenderEmail = config.senderEmail || 'noreply@organify.studio';
|
|
174
|
+
this.mailerSendSenderName = config.mailerSendSenderName || this.brevoSenderName;
|
|
175
|
+
this.mailerSendSenderEmail = config.mailerSendSenderEmail || this.brevoSenderEmail;
|
|
95
176
|
this.dailyLimit = config.dailyLimit || 300;
|
|
96
177
|
this.enabled = config.enabled !== false;
|
|
97
178
|
}
|
|
@@ -146,17 +227,71 @@ export class BrevoEmailClient {
|
|
|
146
227
|
return { success: true, messageId: `dry-run-${Date.now()}`, skipped: false };
|
|
147
228
|
}
|
|
148
229
|
|
|
149
|
-
// Build Brevo payload
|
|
230
|
+
// Build Brevo/MailerSend payload basis
|
|
150
231
|
const recipients = Array.isArray(options.to) ? options.to : [options.to];
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
232
|
+
const recipientPayload = recipients.map((r) => ({ email: r.email, name: r.name }));
|
|
233
|
+
|
|
234
|
+
if (!this.brevoApiKey && !this.mailerSendApiKey) {
|
|
235
|
+
return { success: false, error: 'No email provider key configured (BREVO_API_KEY or MAILERSEND_API_KEY)' };
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (this.brevoApiKey) {
|
|
239
|
+
const brevoResult = await this.sendViaBrevo({
|
|
240
|
+
recipients: recipientPayload,
|
|
241
|
+
subject: options.subject,
|
|
242
|
+
htmlContent,
|
|
243
|
+
textContent: options.textContent,
|
|
244
|
+
params: options.params,
|
|
245
|
+
tags: options.tags,
|
|
246
|
+
cc: options.cc,
|
|
247
|
+
bcc: options.bcc,
|
|
248
|
+
replyTo: options.replyTo,
|
|
249
|
+
});
|
|
250
|
+
if (brevoResult.success) {
|
|
251
|
+
this.incrementCounter(priority);
|
|
252
|
+
return brevoResult;
|
|
253
|
+
}
|
|
254
|
+
console.warn(`[Email] Brevo send failed; trying MailerSend fallback: ${brevoResult.error || 'unknown error'}`);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (this.mailerSendApiKey) {
|
|
258
|
+
const mailerSendResult = await this.sendViaMailerSend({
|
|
259
|
+
recipients: recipientPayload,
|
|
260
|
+
subject: options.subject,
|
|
261
|
+
htmlContent,
|
|
262
|
+
textContent: options.textContent,
|
|
263
|
+
cc: options.cc,
|
|
264
|
+
bcc: options.bcc,
|
|
265
|
+
replyTo: options.replyTo,
|
|
266
|
+
});
|
|
267
|
+
if (mailerSendResult.success) {
|
|
268
|
+
this.incrementCounter(priority);
|
|
269
|
+
}
|
|
270
|
+
return mailerSendResult;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return { success: false, error: 'Brevo failed and MAILERSEND_API_KEY is not configured for fallback' };
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
private async sendViaBrevo(options: {
|
|
277
|
+
recipients: Array<{ email: string; name?: string }>;
|
|
278
|
+
subject: string;
|
|
279
|
+
htmlContent?: string;
|
|
280
|
+
textContent?: string;
|
|
281
|
+
params?: Record<string, string | number | boolean>;
|
|
282
|
+
tags?: string[];
|
|
283
|
+
cc?: EmailRecipient[];
|
|
284
|
+
bcc?: EmailRecipient[];
|
|
285
|
+
replyTo?: EmailRecipient;
|
|
286
|
+
}): Promise<SendResult> {
|
|
287
|
+
const payload: Record<string, unknown> = {
|
|
288
|
+
sender: { name: this.brevoSenderName, email: this.brevoSenderEmail },
|
|
289
|
+
to: options.recipients,
|
|
154
290
|
subject: options.subject,
|
|
155
291
|
};
|
|
156
292
|
|
|
157
|
-
if (htmlContent) payload.htmlContent = htmlContent;
|
|
293
|
+
if (options.htmlContent) payload.htmlContent = options.htmlContent;
|
|
158
294
|
else if (options.textContent) payload.textContent = options.textContent;
|
|
159
|
-
|
|
160
295
|
if (options.params) payload.params = options.params;
|
|
161
296
|
if (options.tags) payload.tags = options.tags;
|
|
162
297
|
if (options.cc) payload.cc = options.cc;
|
|
@@ -167,8 +302,8 @@ export class BrevoEmailClient {
|
|
|
167
302
|
const response = await fetch(BrevoEmailClient.API_URL, {
|
|
168
303
|
method: 'POST',
|
|
169
304
|
headers: {
|
|
170
|
-
|
|
171
|
-
'api-key': this.
|
|
305
|
+
accept: 'application/json',
|
|
306
|
+
'api-key': this.brevoApiKey,
|
|
172
307
|
'content-type': 'application/json',
|
|
173
308
|
},
|
|
174
309
|
body: JSON.stringify(payload),
|
|
@@ -177,16 +312,77 @@ export class BrevoEmailClient {
|
|
|
177
312
|
if (!response.ok) {
|
|
178
313
|
const body = await response.text();
|
|
179
314
|
console.error(`[BrevoEmail] API error ${response.status}: ${body}`);
|
|
315
|
+
if (response.status === 401) {
|
|
316
|
+
console.error('[BrevoEmail] Check BREVO_API_KEY in env and ensure it is enabled for Transactional API/SMTP.');
|
|
317
|
+
}
|
|
180
318
|
return { success: false, error: `Brevo API error: ${response.status} — ${body}` };
|
|
181
319
|
}
|
|
182
320
|
|
|
183
321
|
const data = await response.json() as { messageId?: string };
|
|
184
|
-
this.incrementCounter(priority);
|
|
185
|
-
|
|
186
322
|
return { success: true, messageId: data.messageId };
|
|
187
|
-
} catch (err:
|
|
188
|
-
|
|
189
|
-
|
|
323
|
+
} catch (err: unknown) {
|
|
324
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
325
|
+
console.error(`[BrevoEmail] Network error: ${message}`);
|
|
326
|
+
return { success: false, error: `Brevo network error: ${message}` };
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
private async sendViaMailerSend(options: {
|
|
331
|
+
recipients: Array<{ email: string; name?: string }>;
|
|
332
|
+
subject: string;
|
|
333
|
+
htmlContent?: string;
|
|
334
|
+
textContent?: string;
|
|
335
|
+
cc?: EmailRecipient[];
|
|
336
|
+
bcc?: EmailRecipient[];
|
|
337
|
+
replyTo?: EmailRecipient;
|
|
338
|
+
}): Promise<SendResult> {
|
|
339
|
+
const payload: Record<string, unknown> = {
|
|
340
|
+
from: { email: this.mailerSendSenderEmail, name: this.mailerSendSenderName },
|
|
341
|
+
to: options.recipients,
|
|
342
|
+
subject: options.subject,
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
if (options.htmlContent) payload.html = options.htmlContent;
|
|
346
|
+
if (options.textContent) payload.text = options.textContent;
|
|
347
|
+
if (!options.textContent && options.htmlContent) {
|
|
348
|
+
payload.text = 'Mensagem enviada pelo Organify.';
|
|
349
|
+
}
|
|
350
|
+
if (options.cc) payload.cc = options.cc;
|
|
351
|
+
if (options.bcc) payload.bcc = options.bcc;
|
|
352
|
+
if (options.replyTo) {
|
|
353
|
+
payload.reply_to = {
|
|
354
|
+
email: options.replyTo.email,
|
|
355
|
+
name: options.replyTo.name,
|
|
356
|
+
};
|
|
357
|
+
} else {
|
|
358
|
+
payload.reply_to = {
|
|
359
|
+
email: this.mailerSendSenderEmail,
|
|
360
|
+
name: this.mailerSendSenderName,
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
try {
|
|
365
|
+
const response = await fetch(BrevoEmailClient.MAILERSEND_API_URL, {
|
|
366
|
+
method: 'POST',
|
|
367
|
+
headers: {
|
|
368
|
+
Authorization: `Bearer ${this.mailerSendApiKey}`,
|
|
369
|
+
'Content-Type': 'application/json',
|
|
370
|
+
},
|
|
371
|
+
body: JSON.stringify(payload),
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
if (!response.ok) {
|
|
375
|
+
const body = await response.text();
|
|
376
|
+
console.error(`[MailerSendEmail] API error ${response.status}: ${body}`);
|
|
377
|
+
return { success: false, error: `MailerSend API error: ${response.status} — ${body}` };
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const messageId = response.headers.get('x-message-id') || undefined;
|
|
381
|
+
return { success: true, messageId };
|
|
382
|
+
} catch (err: unknown) {
|
|
383
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
384
|
+
console.error(`[MailerSendEmail] Network error: ${message}`);
|
|
385
|
+
return { success: false, error: `MailerSend network error: ${message}` };
|
|
190
386
|
}
|
|
191
387
|
}
|
|
192
388
|
|