// ═══════════════════════════════════════ // 铸渊开发Agent · 邮件通知模块 // QQ邮箱 SMTP · smtp.qq.com:465 // ═══════════════════════════════════════ const nodemailer = require("nodemailer"); let transporter = null; function getTransporter() { if (transporter) return transporter; const user = process.env.ZY_SMTP_USER; const pass = process.env.ZY_SMTP_PASS; if (!user || !pass) { console.warn("[EmailNotify] ZY_SMTP_USER 或 ZY_SMTP_PASS 未配置,邮件功能不可用"); return null; } transporter = nodemailer.createTransport({ host: "smtp.qq.com", port: 465, secure: true, auth: { user, pass } }); console.log("[EmailNotify] SMTP 已连接 · " + user); return transporter; } /** * 发送通知邮件 * @param {string} to - 收件人邮箱 * @param {string} planId - 规划ID * @param {string} status - 状态: started / completed / failed * @param {object} summary - { task_count, done_count, failed_count, errors, log_url } */ async function sendNotification(to, planId, status, summary = {}) { const t = getTransporter(); if (!t) return { sent: false, reason: "SMTP未配置" }; const statusEmoji = { started: "🚀", completed: "✅", failed: "❌" }; const emoji = statusEmoji[status] || "📋"; const subject = emoji + " 铸渊DevAgent · " + planId + " · " + status; const lines = [ "铸渊开发Agent · 任务执行报告", "══════════════════════════════", "", "规划ID: " + planId, "状态: " + status, "时间: " + new Date().toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" }), "", ]; if (summary.task_count !== undefined) { lines.push("任务总数: " + summary.task_count); lines.push("已完成: " + (summary.done_count || 0)); lines.push("失败: " + (summary.failed_count || 0)); } if (summary.errors && summary.errors.length > 0) { lines.push("", "错误详情:"); summary.errors.forEach(function(e, i) { lines.push(" " + (i + 1) + ". " + e); }); } lines.push("", "══════════════════════════════", "铸渊 ICE-GL-ZY001 · 国作登字-2026-A-00037559"); const mailOptions = { from: process.env.ZY_SMTP_USER, to: to, subject: subject, text: lines.join("\n") }; try { const info = await t.sendMail(mailOptions); console.log("[EmailNotify] 邮件已发送: " + info.messageId); return { sent: true, messageId: info.messageId }; } catch (err) { console.error("[EmailNotify] 发送失败:", err.message); return { sent: false, reason: err.message }; } } module.exports = { sendNotification };