110 lines
3.1 KiB
TypeScript
110 lines
3.1 KiB
TypeScript
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<typeof queueNames.email>;
|
|
};
|
|
|
|
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<string, unknown>): 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<typeof queueNames.email>, alias?: string, templateData?: Record<string, unknown>): 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,
|
|
};
|