import { useTranslation } from '@/i18n'; import { transporter, loadTemplate } from './mailer'; import handlebars from 'handlebars'; interface SendEmailOptions { to: string; subject: string; template: string; // 템플릿 파일명(확장자 제외) context: Record; // 템플릿에 주입할 데이터 cc?: string | string[]; // cc 필드 추가 - 단일 이메일 또는 이메일 배열 from?: string; // from 필드 추가 - 옵셔널 attachments?: { // NodeMailer "Attachment" 타입 filename?: string path?: string content?: Buffer | string // ... }[] } export async function sendEmail({ to, subject, template, context, cc, // cc 매개변수 추가 from, // from 매개변수 추가 attachments = [] }: SendEmailOptions) { try { // i18n 설정 const { t, i18n } = await useTranslation(context.language ?? "en", "translation"); // t 헬퍼를 언어별로 동적으로 재등록 (기존 헬퍼 덮어쓰기) // 헬퍼가 이미 등록되어 있더라도 안전하게 재등록 handlebars.unregisterHelper('t'); // 기존 헬퍼 제거 handlebars.registerHelper("t", function (key: string, options: any) { // 여기서 i18n은 로컬 인스턴스 return i18n.t(key, options?.hash || {}); }); // 템플릿 데이터에 i18n 인스턴스와 번역 함수 추가 const templateData = { ...context, t: (key: string, options?: any) => i18n.t(key, options || {}), i18n: i18n }; // 템플릿 컴파일 및 HTML 생성 const html = loadTemplate(template, templateData); // from 값 설정 - 매개변수가 있으면 사용, 없으면 기본값 사용 const fromAddress = from || `"${process.env.Email_From_Name}" <${process.env.Email_From_Address}>`; // 이메일 발송 const result = await transporter.sendMail({ from: fromAddress, to, cc, // cc 필드 추가 subject, html, attachments }); console.log(`이메일 발송 성공: ${to}`, result.messageId); return result; } catch (error) { console.error(`이메일 발송 실패: ${to}`, error); throw error; } }