#!/usr/bin/env node /** * 测试邮件发送功能 * 验证 SMTP 配置是否正确 */ const nodemailer = require('nodemailer'); const fs = require('fs'); const path = require('path'); require('dotenv').config(); async function testEmailSend() { console.log('📧 测试邮件发送功能\n'); // 检查配置 if (!process.env.SMTP_HOST || !process.env.SMTP_USER || !process.env.SMTP_PASS) { console.error('❌ 缺少 SMTP 配置,请检查 .env 文件'); process.exit(1); } // 创建测试会话 const testToken = 'TEST' + Date.now().toString(36).toUpperCase(); const sessionMapPath = process.env.SESSION_MAP_PATH || path.join(__dirname, 'src/data/session-map.json'); // 确保目录存在 const dir = path.dirname(sessionMapPath); if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } // 创建会话 const sessions = fs.existsSync(sessionMapPath) ? JSON.parse(fs.readFileSync(sessionMapPath, 'utf8')) : {}; sessions[testToken] = { type: 'pty', createdAt: Math.floor(Date.now() / 1000), expiresAt: Math.floor((Date.now() + 3600000) / 1000), // 1小时后过期 cwd: process.cwd(), description: '测试会话' }; fs.writeFileSync(sessionMapPath, JSON.stringify(sessions, null, 2)); console.log(`✅ 创建测试会话: ${testToken}\n`); // 创建邮件传输器 const transporter = nodemailer.createTransport({ host: process.env.SMTP_HOST, port: parseInt(process.env.SMTP_PORT || '465'), secure: process.env.SMTP_SECURE === 'true', auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS } }); // 准备邮件内容 const mailOptions = { from: `${process.env.EMAIL_FROM_NAME || 'TaskPing'} <${process.env.EMAIL_FROM || process.env.SMTP_USER}>`, to: process.env.EMAIL_TO || 'jiaxicui446@gmail.com', subject: `[TaskPing #${testToken}] 测试邮件 - 等待您的指令`, html: `

🔔 TaskPing 测试通知

这是一封测试邮件,用于验证邮件配置是否正确。

会话信息:

Token: ${testToken}

创建时间: ${new Date().toLocaleString('zh-CN')}

过期时间: ${new Date(Date.now() + 3600000).toLocaleString('zh-CN')}

📝 如何回复测试指令:

方式1(推荐):直接回复此邮件,内容输入:

方式2:从任何邮箱发送邮件到 noreply@pandalla.ai

主题必须包含:[TaskPing #${testToken}]

💡 多邮箱支持:

您可以从以下任意邮箱发送回复到 noreply@pandalla.ai

回复路径:您的邮箱 → noreply@pandalla.ai → TaskPing系统处理


会话ID: ${testToken}
发送自: ${process.env.SMTP_USER}
通知邮箱: ${process.env.EMAIL_TO}
回复邮箱: ${process.env.SMTP_USER}
系统支持任意邮箱回复

`, text: `TaskPing 测试通知\n\n` + `这是一封测试邮件,用于验证邮件配置是否正确。\n\n` + `会话Token: ${testToken}\n` + `创建时间: ${new Date().toLocaleString('zh-CN')}\n\n` + `请回复任意命令来测试,例如: echo "Hello from email"\n\n` + `会话ID: ${testToken}`, headers: { 'X-TaskPing-Session-ID': testToken, 'X-TaskPing-Type': 'test' } }; // 发送邮件 try { console.log('🚀 正在发送测试邮件...'); console.log(` 发件人: ${mailOptions.from}`); console.log(` 收件人: ${mailOptions.to}`); console.log(` 主题: ${mailOptions.subject}\n`); const info = await transporter.sendMail(mailOptions); console.log('✅ 邮件发送成功!'); console.log(` Message ID: ${info.messageId}`); console.log(` Response: ${info.response}\n`); console.log('📋 下一步操作:'); console.log('1. 检查收件箱是否收到邮件'); console.log('2. 确保 Gmail 已配置应用专用密码'); console.log('3. 启动邮件监听服务: npm run relay:pty'); console.log('4. 回复邮件测试命令注入功能'); console.log(`\n💡 回复时主题保持: [TaskPing #${testToken}]`); } catch (error) { console.error('❌ 邮件发送失败:', error.message); if (error.code === 'EAUTH') { console.log('\n可能的原因:'); console.log('1. SMTP 密码错误'); console.log('2. 邮箱未开启 SMTP 服务'); console.log('3. 需要使用应用专用密码而非账号密码'); } if (error.code === 'ECONNECTION') { console.log('\n可能的原因:'); console.log('1. SMTP 服务器地址或端口错误'); console.log('2. 网络连接问题'); console.log('3. 防火墙阻止了连接'); } process.exit(1); } } // 主函数 async function main() { console.log('╔══════════════════════════════════════════════════════════╗'); console.log('║ TaskPing Email Send Test ║'); console.log('╚══════════════════════════════════════════════════════════╝\n'); await testEmailSend(); } // 运行 main().catch(console.error);