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

55 lines
1.4 KiB
TypeScript
Raw Normal View History

import { Injectable, Inject } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { Logger } from "nestjs-pino";
2025-08-27 10:54:05 +09:00
import sgMail, { MailDataRequired } from "@sendgrid/mail";
export interface ProviderSendOptions {
to: string | string[];
from?: string;
2025-08-27 10:54:05 +09:00
subject: string;
text?: string;
html?: string;
templateId?: string;
dynamicTemplateData?: Record<string, unknown>;
}
@Injectable()
export class SendGridEmailProvider {
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);
}
}
2025-08-27 10:54:05 +09:00
async send(options: ProviderSendOptions): Promise<void> {
const from = options.from || this.config.get<string>("EMAIL_FROM");
2025-08-27 10:54:05 +09:00
if (!from) {
this.logger.warn("EMAIL_FROM is not configured; email not sent");
return;
}
2025-08-27 10:54:05 +09:00
const message: MailDataRequired = {
to: options.to,
from,
subject: options.subject,
text: options.text,
html: options.html,
templateId: options.templateId,
dynamicTemplateData: options.dynamicTemplateData,
2025-08-27 10:54:05 +09:00
} as MailDataRequired;
try {
2025-08-27 10:54:05 +09:00
await sgMail.send(message);
} catch (error) {
2025-08-27 10:54:05 +09:00
this.logger.error("Failed to send email via SendGrid", {
error: error instanceof Error ? error.message : String(error),
});
throw error;
}
}
}