52 lines
1.8 KiB
TypeScript
52 lines
1.8 KiB
TypeScript
|
|
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;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|