UNPKG

mail-bridge

Version:

Send email using any email provider.

435 lines (423 loc) 13.1 kB
var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // src/providers/aws.ts import { SendEmailCommand, SESClient } from "@aws-sdk/client-ses"; var sendEmail_AWS_SES = (email, config) => __async(void 0, null, function* () { const sesClient = new SESClient({ region: config == null ? void 0 : config.region }); let to_address; if (typeof email.to === "string") { to_address = [email.to]; } else { to_address = email.to; } const sendEmailCommand = new SendEmailCommand({ Destination: { ToAddresses: to_address }, Message: { Body: { Html: { Charset: "UTF-8", Data: email.text } }, Subject: { Charset: "UTF-8", Data: email.subject } }, Source: email.from }); try { const data = yield sesClient.send(sendEmailCommand); return { provider: "aws_ses", time: /* @__PURE__ */ new Date(), id: data.MessageId, email }; } catch (error) { console.log(error); const msg = { provider: "AWS_SES", time: /* @__PURE__ */ new Date(), error }; throw new Error(JSON.stringify(msg)); } }); // src/utils/smtp.ts import { createTransport } from "nodemailer"; var util_sendEmail_SMTP = (transporter, email) => __async(void 0, null, function* () { const mailTransporter = createTransport(transporter); try { return yield mailTransporter.sendMail(email); } catch (error) { console.error(error); throw new Error("SMTP send failed"); } }); // src/providers/brevo.ts var sendEmail_BREVO = (email, config) => __async(void 0, null, function* () { try { if (!config) throw new Error("BREVO is not configured properly."); const message = yield util_sendEmail_SMTP(config, email); return { provider: "brevo", time: /* @__PURE__ */ new Date(), id: message.messageId, email }; } catch (error) { console.log(error); const msg = { provider: "BREVO", time: /* @__PURE__ */ new Date(), error }; throw new Error(JSON.stringify(msg)); } }); // src/providers/gmail.ts var sendEmail_GMAIL = (email, config) => __async(void 0, null, function* () { try { if (!config) throw new Error("GMAIL is not configured properly."); const message = yield util_sendEmail_SMTP(config, email); return { provider: "gmail", time: /* @__PURE__ */ new Date(), id: message.messageId, email }; } catch (error) { console.log(error); const msg = { provider: "GMAIL", time: /* @__PURE__ */ new Date(), error }; throw new Error(JSON.stringify(msg)); } }); // src/providers/mailgun.ts import FormData from "form-data"; import Mailgun from "mailgun.js"; var sendEmail_MAILGUN = (email, config) => __async(void 0, null, function* () { const mailgun = new Mailgun(FormData); try { const mg = mailgun.client({ username: "api", key: config == null ? void 0 : config.api_key }); const data = yield mg.messages.create(config == null ? void 0 : config.domain, { from: email.from, to: email.to, subject: email.subject, html: email.text }); return { provider: "mailgun", time: /* @__PURE__ */ new Date(), id: data.id, email }; } catch (error) { console.log(error); const msg = { provider: "MAILGUN", time: /* @__PURE__ */ new Date(), error }; throw new Error(JSON.stringify(msg)); } }); // src/providers/outlook.ts var sendEmail_OUTLOOK = (email, config) => __async(void 0, null, function* () { try { if (!config) throw new Error("OUTLOOK is not configured properly."); const message = yield util_sendEmail_SMTP(config, email); return { provider: "outlook", time: /* @__PURE__ */ new Date(), id: message.messageId, email }; } catch (error) { console.log(error); const msg = { provider: "OUTLOOK", time: /* @__PURE__ */ new Date(), error }; throw new Error(JSON.stringify(msg)); } }); // src/providers/resend.ts import { Resend } from "resend"; var sendEmail_RESEND = (email, config) => __async(void 0, null, function* () { var _a; try { const resend = new Resend(config == null ? void 0 : config.api_key); const data = yield resend.emails.send({ from: email.from, to: email.to, subject: email.subject, html: email.text }); return { provider: "resend", time: /* @__PURE__ */ new Date(), id: (_a = data.data) == null ? void 0 : _a.id, email }; } catch (error) { console.log(error); const msg = { provider: "RESEND", time: /* @__PURE__ */ new Date(), error }; throw new Error(JSON.stringify(msg)); } }); // src/providers/smtp.ts var sendEmail_SMTP = (email, config) => __async(void 0, null, function* () { try { if (!config) throw new Error("SMTP is not configured properly."); const message = yield util_sendEmail_SMTP(config, email); return { provider: "smtp", time: /* @__PURE__ */ new Date(), id: message.messageId, email }; } catch (error) { console.log(error); const msg = { provider: "SMTP", time: /* @__PURE__ */ new Date(), error }; throw new Error(JSON.stringify(msg)); } }); // src/sendEmail.ts var sendEmail = (email, config, provider) => __async(void 0, null, function* () { switch (provider) { case "aws_ses": return yield sendEmail_AWS_SES(email, config.aws_ses); case "brevo": return yield sendEmail_BREVO(email, config.brevo); case "gmail": return yield sendEmail_GMAIL(email, config.gmail); case "mailgun": return yield sendEmail_MAILGUN(email, config.mailgun); case "outlook": return yield sendEmail_OUTLOOK(email, config.outlook); case "resend": return yield sendEmail_RESEND(email, config.resend); case "smtp": return yield sendEmail_SMTP(email, config.smtp); default: throw new Error("Invalid provider"); } }); // src/processEmail.ts var processEmail = (email, config, provider_priority) => __async(void 0, null, function* () { const provider = provider_priority.shift(); if (!provider) throw new Error("No providers provided"); try { const response = yield sendEmail(email, config, provider); return response; } catch (error) { if (provider_priority.length === 0) { throw new Error("All providers failed to send email"); } return yield processEmail(email, config, provider_priority); } }); // src/index.ts var MailBridge = class { constructor({ config, defaultFrom, priority, retryCount }) { this.config = config; this.defaultFrom = defaultFrom; if (priority) { this.provider_priority = priority.filter( (provider) => Object.keys(config).includes(provider) ); if (this.provider_priority.length !== Object.keys(config).length) { const allProviders = Object.keys(config); const missingProviders = allProviders.filter( (provider) => !this.provider_priority.includes(provider) ); this.provider_priority = this.provider_priority.concat(missingProviders); } } else { this.provider_priority = Object.keys(config); } this.retryCount = retryCount || this.provider_priority.length; if (retryCount === 0) this.retryCount = 0; console.log("MailBridge initialized"); } send(email, override) { return __async(this, null, function* () { if (!email.from) { email.from = this.defaultFrom; } if ((override == null ? void 0 : override.provider) && this.provider_priority.includes(override.provider)) { this.provider_priority = this.provider_priority.filter( (p) => p !== override.provider ); this.provider_priority.unshift(override.provider); } if (override == null ? void 0 : override.retryCount) { this.provider_priority = this.provider_priority.slice( 0, override.retryCount + 1 ); } else if ((override == null ? void 0 : override.retryCount) === 0) { this.provider_priority = this.provider_priority.slice(0, 1); } else if (this.retryCount === 0) { this.provider_priority = this.provider_priority.slice(0, 1); } else { this.provider_priority = this.provider_priority.slice( 0, this.retryCount + 1 ); } return yield processEmail(email, this.config, this.provider_priority); }); } /** * Check the configuration of the MailBridge */ checkConfig() { let report = { providers: Array(), errors: Array(), defaultFrom: void 0, comment: "" }; for (let provider of this.provider_priority) { report.providers.push(provider); } if (this.provider_priority.includes("aws_ses") && this.config.aws_ses) { const { region: REGION } = this.config.aws_ses; if (!REGION) report.errors.push("aws_ses.region is required"); } if (this.provider_priority.includes("brevo") && this.config.brevo) { const { host, port, auth } = this.config.brevo; if (!host) report.errors.push("brevo.host is required."); if (!port) report.errors.push("brevo.port is required."); if (!(auth == null ? void 0 : auth.user)) report.errors.push("brevo.auth.user is required."); if (!(auth == null ? void 0 : auth.pass)) report.errors.push("brevo.auth.pass is required."); } if (this.provider_priority.includes("gmail") && this.config.gmail) { const { host, port, auth } = this.config.gmail; if (!host) report.errors.push("gmail.host is required."); if (!port) report.errors.push("gmail.port is required."); if (!(auth == null ? void 0 : auth.user)) report.errors.push("gmail.auth.user is required."); if (!(auth == null ? void 0 : auth.pass)) report.errors.push("gmail.auth.pass is required."); } if (this.provider_priority.includes("mailgun") && this.config.mailgun) { const { api_key: MAILGUN_API_KEY, domain: MAILGUN_DOMAIN } = this.config.mailgun; if (!MAILGUN_API_KEY) report.errors.push("mailgun.api_key is required."); if (!MAILGUN_DOMAIN) report.errors.push("mailgun.domain is required."); } if (this.provider_priority.includes("outlook")) { if (this.config.outlook) { const { host, port, auth } = this.config.outlook; if (!host) report.errors.push("outlook.host is required."); if (!port) report.errors.push("outlook.port is required."); if (!(auth == null ? void 0 : auth.user)) report.errors.push("outlook.auth.user is required."); if (!(auth == null ? void 0 : auth.pass)) report.errors.push("outlook.auth.pass is required."); } else { report.errors.push("outlook is not configured properly."); } } if (this.provider_priority.includes("resend") && this.config.resend) { const { api_key: API_KEY } = this.config.resend; if (!API_KEY) report.errors.push("resend.api_key is required"); } if (this.provider_priority.includes("smtp")) { if (this.config.smtp) { const { host, port, auth } = this.config.smtp; if (!host) report.errors.push("smtp.host is required."); if (!port) report.errors.push("smtp.port is required."); if (!(auth == null ? void 0 : auth.user)) report.errors.push("smtp.auth.user is required."); if (!(auth == null ? void 0 : auth.pass)) report.errors.push("smtp.auth.pass is required."); } else { report.errors.push("SMTP is not configured properly."); } } if (!this.defaultFrom) { report.errors.push("Default from address is not configured"); } else { if (!this.defaultFrom.includes("@")) { report.errors.push("Default from address is not a valid email address"); } report.defaultFrom = this.defaultFrom; } if (this.retryCount < 0) { report.errors.push("Retry count cannot be negative"); } if (report.errors.length === 0) { report.comment = "\u2705 Looks good!"; } else { report.comment = "\u274C Errors found in the configuration"; } return report; } }; export { MailBridge };