import { createTransport, Transporter } from "nodemailer"; import { marked } from "marked"; interface SendOptions { to: string; subject: string; markdown: string; footer?: string; inReplyTo?: string; references?: string; attachments?: Array<{ filename: string; content: Buffer; contentType: string }>; } const transports = new Map(); function getTransport(account: string, pass: string): Transporter { if (!transports.has(account)) { transports.set( account, createTransport({ host: "mailserver.purelymail.com", port: 465, secure: true, auth: { user: account, pass }, }) ); } return transports.get(account)!; } export function wrapHtml(body: string, footer?: string, badge?: string): string { const badgeHtml = badge ? `
${badge}
` : ""; const footerText = footer || "Ace · Manglasabang"; return `
Ace
${badgeHtml}
${body}
${footerText}
`; } function htmlToText(html: string): string { return html .replace(/<[^>]+>/g, "") .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, '"') .replace(/'/g, "'") .replace(/\n{3,}/g, "\n\n") .trim(); } export async function sendEmail(account: string, options: SendOptions): Promise { const junwonAccounts = new Set(["junwon@manglasabang.com", "junwon@palacering.com", "junwon@palace.fund"]); const pass = junwonAccounts.has(account) ? process.env.PURELYMAIL_PASS_JUNWON : process.env.PURELYMAIL_PASS; if (!pass) throw new Error(`Missing PURELYMAIL_PASS${junwonAccounts.has(account) ? "_JUNWON" : ""} for ${account}`); const bodyHtml = await marked(options.markdown); const html = wrapHtml(bodyHtml, options.footer); const text = htmlToText(bodyHtml); const transport = getTransport(account, pass); await transport.sendMail({ from: `Ace <${account}>`, to: options.to, subject: options.subject, html, text, inReplyTo: options.inReplyTo, references: options.references, attachments: options.attachments, }); }