/** * 이메일 발송 서비스 (Resend 사용) * AWS SES 대신 Resend API를 사용하여 이메일 발송 */ const { Resend } = require("resend"); /** * Resend 클라이언트 생성 * DB에서 API 키를 가져와 설정 * @returns {Promise<{resend: Resend, from: string}>} */ const createClient = async () => { const SystemConfig = require("../models/SystemConfig"); // DB에서 설정 조회 const configs = await SystemConfig.findAll(); const configMap = {}; configs.forEach((c) => (configMap[c.key] = c.value)); // DB 설정 우선, 없으면 환경 변수 사용 const apiKey = configMap["resend_api_key"] || process.env.RESEND_API_KEY; if (!apiKey) { throw new Error("Resend API 키가 설정되지 않았습니다"); } const resend = new Resend(apiKey); return { resend, from: configMap["mail_from"] || process.env.MAIL_FROM || "admin@caadiq.co.kr", }; }; /** * 이메일 발송 (Resend 사용) * @param {Object} params - 이메일 파라미터 * @param {string} [params.from] - 발신자 (선택, 없으면 기본값 사용) * @param {string} params.to - 수신자 * @param {string} params.subject - 제목 * @param {string} params.html - HTML 본문 * @param {string} [params.text] - 텍스트 본문 (선택) * @param {Array} [params.attachments] - 첨부파일 배열 (선택) * @returns {Promise} Resend 발송 결과 */ exports.sendEmail = async ({ from: senderEmail, to, subject, html, text, attachments = [], }) => { try { const { resend, from: defaultFrom } = await createClient(); // 발신자: 전달된 값 또는 기본값 사용 const actualFrom = senderEmail || defaultFrom; // 첨부파일 변환 (Resend 형식: filename, content as Buffer/base64) const resendAttachments = attachments.map((att) => ({ filename: att.filename, content: Buffer.isBuffer(att.content) ? att.content : Buffer.from(att.content, "base64"), })); console.log(`[Resend] 첨부파일 개수: ${attachments.length}`); if (attachments.length > 0) { console.log( `[Resend] 첨부파일 정보:`, attachments.map((a) => ({ filename: a.filename, contentType: a.contentType, contentLength: a.content?.length || 0, })) ); } // to가 배열이면 그대로, 문자열이면 배열로 변환 const toArray = Array.isArray(to) ? to : to.split(",").map((e) => e.trim()); // html과 text 기본값 처리 (둘 다 없으면 빈 공백이라도 전달) const finalHtml = html || text || " "; const finalText = text || (html ? html.replace(/<[^>]*>/g, "") : " "); const result = await resend.emails.send({ from: actualFrom, to: toArray, subject: subject || "(제목 없음)", html: finalHtml, text: finalText, attachments: resendAttachments.length > 0 ? resendAttachments : undefined, }); if (result.error) { console.error("[Resend] 발송 오류:", result.error); throw new Error(result.error.message); } console.log("[Resend] 메일 발송 완료:", result.data?.id); return { messageId: result.data?.id }; } catch (error) { console.error("[Resend] 발송 오류:", error); throw error; } };