Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/app/modules/emails/services/MailjetEmailService.ts
T

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,
};