NodeJS延迟发送电子邮件

我正在使用Nodemailer在我的NodeJS / Express服务器中发送邮件。 发送邮件之前,我想等20分钟,而不是直接发送邮件。 我觉得这个感觉更直接发送邮件。

但我不知道如何做到这一点。 我想我不需要像NodeCron这样的NodeJS cronjob,或者我需要?

router.post('/', (req, res) => { const transporter = nodemailer.createTransport(smtpTransport({ host: 'smtp.gmail.com', port: 465, auth: { user: 'noreply@domain.nl', pass: 'pass123' } })); const mailOptions = { from: `"${req.body.name}" <${req.body.email}>`, to: 'info@domain.nl', subject: 'Form send', html: `Content` }; transporter.sendMail(mailOptions, (error, info) => { if (error) res.status(500).json({ responseText: error }); res.status(200).json({ responseText: 'Message send!' }); }); } }); 

我的路由器如上所示。 所以如果post被叫,我想这个请求等待20分钟。 而不是与一个cronjob我只想执行一次,但有点延迟。 任何build议如何做到这一点?

我认为查理布朗的答案是正确的,因为在阅读这个问题的时候我有两个答案,所以我感谢他简化了我的答案,成为他的另一个答案。

setTimeout实际上是一个好主意,但它有一个缺点:在有任何理由停止服务器代码(服务器重启,模块安装,文件pipe理等)的情况下,你的callback计划在setTimeout结束时时间参数将不被执行,有些用户不会收到电子邮件。

如果上面的问题严重,那么您可能希望将定期发送的电子邮件存储在数据库或Redis中,并使用cron作业定期检查电子邮件设置,并在发送电子邮件时发送电子邮件。

我认为,这个答案或查理布朗应该满足于你,根据你的喜好和需求。

那么有些人可能会来这里告诉你使用一个外部队列系统和bla bla …但是你可以简单地使用普通的旧的Javascript来安排发送20 * 60 * 1000毫秒到未来的东西开始。 🙂

你的代码存在一个问题:你在发送200个“发送消息”响应给用户之前等待邮件发送成功。 叫我疯子,但我敢肯定用户不会盯着浏览器窗口20分钟,所以你可能需要尽快回答,然后安排邮件。 修改你的代码:

 router.post('/', (req, res) => { const DELAY = 20*60*1000 // min * secs * milliseconds const transporter = nodemailer.createTransport(smtpTransport({ host: 'smtp.gmail.com', port: 465, auth: { user: 'noreply@domain.nl', pass: 'pass123' } })); const mailOptions = { from: `"${req.body.name}" <${req.body.email}>`, to: 'info@domain.nl', subject: 'Form send', html: `Content` }; res.status(200).json({ responseText: 'Message queued for delivery' }); setTimeout(function(){ transporter.sendMail(mailOptions, (error, info) => { if (error) console.log('Mail failed!! :(') else console.log('Mail sent to ' + mailOptions.to) }), DELAY ); } }); 

然而,这个解决scheme有许多可能的缺陷。 如果你期望在该端点上有很大的stream量,那么你可能会遇到很多预定的callback,它们会吃掉堆栈。 另外,如果某件事失败,用户当然不会知道。

如果这是一个大的/严重的项目,考虑使用该cronjob包或使用外部存储机制,在这里你可以排队这个“挂起”的消息(Redis会做,这是令人难以置信的简单),并从那里有不同的进程读取任务电子邮件发送。

编辑:在你的代码上看到更多的东西。

1)您可能不需要在POST处理程序中创build一个新的transport在外部创build它并重用它。

2)除了上面提到的问题,如果你的服务器崩溃,将不会发送电子邮件。

3)如果你仍然想在一个Node.js应用程序中做,而不是每个请求到这个端点安排一个电子邮件,你最好将电子邮件数据(从,到,主体,正文)存储在某个地方和时间表每20分钟一个function,将获得所有未决电子邮件,逐个发送,然后重新安排自己重新运行20分钟后。 这会使你的内存使用率降低。 服务器崩溃仍然会使所有电子邮件丢失,但如果您将REDIS添加到组合中,则只需在应用程序启动时从REDIS获取所有待处理的电子邮件即可。

可能太多的答案,对不起,如果这是不需要的! 🙂