import { MailProviderError, type MailProvider } from "@toolctrl/mail"; import { buildTransactionalMailJob, enqueueJob, queueNames, resolveRedisConnectionOptions, resolveRedisConnectionOptionsFromProcessEnv, type RedisConnectionEnv, type TypedQueue, } from "@toolctrl/queue"; import { t as i18nT } from "i18next"; export type SendEmailMailjetDependencies = { env?: RedisConnectionEnv; queue?: TypedQueue; }; export async function sendEmailMailjet( { data, }: { data: { to: string; subject?: string; body?: string; alias?: string; data?: { [key: string]: any; }; tenantId?: string | null; priorityOverride?: "critical" | "high" | "normal" | "low"; }; }, dependencies: SendEmailMailjetDependencies = {} ) { const mailProvider = dependencies.queue ? createTransactionalQueueProvider(dependencies.queue, data.alias, data.data) : createTransactionalQueueProviderFromEnv(dependencies.env, data.alias, data.data); return await mailProvider.send({ to: [data.to], subject: data.subject, html: data.body, tenantId: data.tenantId, priorityOverride: data.priorityOverride, }); } function createTransactionalQueueProviderFromEnv(env?: RedisConnectionEnv, alias?: string, templateData?: Record): MailProvider { const connection = env ? resolveRedisConnectionOptions({ env }) : resolveRedisConnectionOptionsFromProcessEnv(); if (!connection) { return { id: "queue", async send() { const warning = { code: "missing_redis_connection", message: i18nT("mail.queue.errors.missingRedisConnection"), requiredEnv: ["BULLMQ_REDIS_URL", "REDIS_URL"], }; throw new MailProviderError(warning.message, { provider: "queue", responseBody: warning }); }, }; } return { id: "queue", async send(input) { const queueRuntimeModule = "@toolctrl/queue/runtime"; const { createQueue } = (await import(/* @vite-ignore */ queueRuntimeModule)) as typeof import("@toolctrl/queue/runtime"); const queue = createQueue(queueNames.email, { connection }); try { return await createTransactionalQueueProvider(queue, alias, templateData).send(input); } finally { await queue.close(); } }, }; } function createTransactionalQueueProvider(queue: TypedQueue, alias?: string, templateData?: Record): MailProvider { return { id: "queue", async send(input) { const descriptor = buildTransactionalMailJob({ to: input.to.map((recipient) => (typeof recipient === "string" ? recipient : recipient.email)), subject: input.subject, html: input.html, templateData, metadata: alias ? { alias } : undefined, }); const job = await enqueueJob(queue, descriptor); return { provider: "queue", status: "queued", messageId: job.id, warnings: { queueName: descriptor.queueName, jobName: descriptor.jobName, }, }; }, }; } export default { send: sendEmailMailjet, };