如何使用nodemailer SMTP实现邮件定时发送及定点送达?
使用Nodemailer SMTP实现指定时间送达邮件的实现方案
针对你凌晨1点生成邮件、需要当天8点正式送达的场景,有两种成熟的实现方案可选:
方案1:基于任务队列实现本地延迟投递
- 适用场景:服务可稳定运行到指定发信时间,不需要依赖SMTP服务商的特殊能力
- 实现逻辑:凌晨1点生成邮件参数后不直接调用发信接口,先存入延迟任务队列,设置8点触发发信
- 示例代码:
const nodemailer = require('nodemailer'); const { Queue } = require('bullmq'); // 初始化SMTP发信实例 const transporter = nodemailer.createTransport({ host: '你的SMTP服务器地址', port: 587, secure: false, auth: { user: '你的发信账号', pass: '你的发信密码' } }); // 初始化延迟任务队列(基于Redis实现) const emailQueue = new Queue('email-delivery', { connection: { host: '你的Redis服务地址', port: 6379 } }); // 凌晨1点调用的发信调度函数 async function scheduleEmail(mailOptions) { // 计算到当天8点的延迟毫秒数 const now = new Date(); const sendTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 8, 0, 0); const delay = sendTime.getTime() - now.getTime(); const finalDelay = delay > 0 ? delay : 0; // 发信任务加入延迟队列 await emailQueue.add('send-email', mailOptions, { delay: finalDelay }); } // 任务消费者,到点自动触发发信 emailQueue.process('send-email', async (job) => { await transporter.sendMail(job.data); });
- 注意事项:需要保证队列服务和消费者进程稳定运行,避免发信失败
方案2:使用SMTP延迟投递扩展实现服务商端托管
- 适用场景:所用SMTP服务商支持
DELIVERYTIME扩展(主流商用SMTP服务如阿里云邮、腾讯企业邮、SendGrid等均支持),不需要自己维护任务队列 - 实现逻辑:直接在邮件参数中添加延迟投递头,SMTP服务商会托管邮件到指定时间再发送
- 示例代码:
const nodemailer = require('nodemailer'); const transporter = nodemailer.createTransport({ host: '你的SMTP服务器地址', port: 587, secure: false, auth: { user: '你的发信账号', pass: '你的发信密码' } }); // 凌晨1点直接调用的发信函数 async function sendDelayedEmail(mailBaseOptions) { // 生成RFC 2822格式的指定送达时间 const sendTime = new Date(); sendTime.setHours(8, 0, 0, 0); const formattedTime = sendTime.toUTCString(); // 合并延迟投递头,不同服务商支持的头字段可查阅对应文档调整 const mailOptions = { ...mailBaseOptions, headers: { 'X-Delayed-Delivery': formattedTime // 部分服务商需使用 'Delivery-Time': formattedTime } }; // 直接提交到SMTP服务商即可,无需本地维护定时逻辑 await transporter.sendMail(mailOptions); }
- 注意事项:不同服务商支持的最大延迟时长、头字段规则有差异,使用前需确认对应服务商的规则
内容的提问来源于stack exchange,提问作者Jakub Bednár
相关产品推荐
相关产品推荐

