Assist_Design/apps/bff/src/common/email/providers/sendgrid.provider.ts

52 lines
1.8 KiB
TypeScript
Raw Normal View History

import { Injectable, Inject } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { Logger } from "nestjs-pino";
import sgMail from "@sendgrid/mail";
import type { SendEmailOptions } from "../email.service";
@Injectable()
export class SendGridEmailProvider {
private readonly fromEmail: string;
private readonly fromName?: string;
constructor(
private readonly config: ConfigService,
@Inject(Logger) private readonly logger: Logger
) {
const apiKey = this.config.get<string>("SENDGRID_API_KEY");
if (apiKey) {
sgMail.setApiKey(apiKey);
}
const sandbox = this.config.get("SENDGRID_SANDBOX", "false") === "true";
sgMail.setSubstitutionWrappers("{{", "}}");
(sgMail as any).setClient({ mailSettings: { sandboxMode: { enable: sandbox } } });
this.fromEmail = this.config.get<string>("EMAIL_FROM", "no-reply@example.com");
this.fromName = this.config.get<string>("EMAIL_FROM_NAME");
}
async send(options: SendEmailOptions): Promise<void> {
const to = Array.isArray(options.to) ? options.to : [options.to];
const msg: sgMail.MailDataRequired = {
to,
from: this.fromName ? { email: this.fromEmail, name: this.fromName } : this.fromEmail,
subject: options.subject,
text: options.text,
html: options.html,
templateId: options.templateId,
dynamicTemplateData: options.dynamicTemplateData,
} as sgMail.MailDataRequired;
try {
await sgMail.send(msg);
this.logger.log("SendGrid email sent", { to, subject: options.subject });
} catch (error) {
this.logger.error("SendGrid send failed", {
error:
error instanceof Error ? { name: error.name, message: error.message } : String(error),
});
throw error;
}
}
}