133 lines
4.1 KiB
TypeScript
133 lines
4.1 KiB
TypeScript
import { MailProviderError, type MailAttachment, type MailProvider } from "@hivegrid/mail";
|
|
import {
|
|
buildTransactionalMailJob,
|
|
enqueueJob,
|
|
queueNames,
|
|
resolveRedisConnectionOptions,
|
|
resolveRedisConnectionOptionsFromProcessEnv,
|
|
type RedisConnectionEnv,
|
|
type TypedQueue,
|
|
} from "@hivegrid/queue";
|
|
import { requestScopedT as i18nT } from "~/locale/request-scoped-t";
|
|
|
|
export type SendEmailMailjetDependencies = {
|
|
env?: RedisConnectionEnv;
|
|
queue?: TypedQueue<typeof queueNames.email>;
|
|
};
|
|
|
|
export async function sendEmailMailjet(
|
|
{
|
|
data,
|
|
}: {
|
|
data: {
|
|
to: string;
|
|
subject?: string;
|
|
body?: string;
|
|
text?: string;
|
|
alias?: string;
|
|
source?: string;
|
|
data?: {
|
|
[key: string]: any;
|
|
};
|
|
tenantId?: string | null;
|
|
priorityOverride?: "critical" | "high" | "normal" | "low";
|
|
attachments?: readonly MailAttachment[];
|
|
};
|
|
},
|
|
dependencies: SendEmailMailjetDependencies = {}
|
|
) {
|
|
const mailProvider = dependencies.queue
|
|
? createTransactionalQueueProvider(dependencies.queue, data.alias, data.data, data.source)
|
|
: createTransactionalQueueProviderFromEnv(dependencies.env, data.alias, data.data, data.source);
|
|
|
|
return await mailProvider.send({
|
|
to: [data.to],
|
|
subject: data.subject,
|
|
html: data.body,
|
|
text: data.text,
|
|
tenantId: data.tenantId,
|
|
priorityOverride: data.priorityOverride,
|
|
...(data.attachments && data.attachments.length > 0 ? { attachments: data.attachments } : {}),
|
|
});
|
|
}
|
|
|
|
function createTransactionalQueueProviderFromEnv(
|
|
env?: RedisConnectionEnv,
|
|
alias?: string,
|
|
templateData?: Record<string, unknown>,
|
|
source?: string
|
|
): 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 = "@hivegrid/queue/runtime";
|
|
const { createQueue } = (await import(/* @vite-ignore */ queueRuntimeModule)) as typeof import("@hivegrid/queue/runtime");
|
|
const queue = createQueue(queueNames.email, { connection });
|
|
try {
|
|
return await createTransactionalQueueProvider(queue, alias, templateData, source).send(input);
|
|
} finally {
|
|
await queue.close();
|
|
}
|
|
},
|
|
};
|
|
}
|
|
|
|
function createTransactionalQueueProvider(
|
|
queue: TypedQueue<typeof queueNames.email>,
|
|
alias?: string,
|
|
templateData?: Record<string, unknown>,
|
|
source?: string
|
|
): MailProvider {
|
|
return {
|
|
id: "queue",
|
|
async send(input) {
|
|
const descriptor = buildTransactionalMailJob({
|
|
to: input.to.map((recipient) => (typeof recipient === "string" ? recipient : recipient.email)),
|
|
subject: input.subject,
|
|
text: input.text,
|
|
html: input.html,
|
|
templateData,
|
|
// Forward attachments (e.g. AK-P16b booking .ics) — the payload already
|
|
// supports them; only this provider hop was dropping the field.
|
|
...(input.attachments && input.attachments.length > 0 ? { attachments: input.attachments } : {}),
|
|
...(input.tenantId !== undefined && input.tenantId !== null ? { tenantId: input.tenantId } : {}),
|
|
metadata: alias || source ? { ...(alias ? { alias } : {}), ...(source ? { source } : {}) } : undefined,
|
|
});
|
|
const job = await enqueueJob(queue, descriptor, {
|
|
...(input.tenantId !== undefined ? { tenantId: input.tenantId } : {}),
|
|
...(input.priorityOverride !== undefined ? { priorityOverride: input.priorityOverride } : {}),
|
|
});
|
|
|
|
return {
|
|
provider: "queue",
|
|
status: "queued",
|
|
messageId: job.id,
|
|
warnings: {
|
|
queueName: descriptor.queueName,
|
|
jobName: descriptor.jobName,
|
|
},
|
|
};
|
|
},
|
|
};
|
|
}
|
|
|
|
export default {
|
|
send: sendEmailMailjet,
|
|
};
|