【问题标题】:Node cron job sending email every 2 seconds after caching节点 cron 作业在缓存后每 2 秒发送一次电子邮件
【发布时间】:2018-08-20 14:53:56
【问题描述】:

我正在尝试创建一个机器人,该机器人每次将 AskReddit 帖子发布到 Reddit 时都会向我发送通知。我有这个应用程序每 2 秒在 Heroku 上轮询 Reddit。

问题

每次有新帖子时,都会向我发送一封电子邮件。应该发生的是,新帖子应该被缓存,直到新帖子被放在 Reddit 上。相反,一旦发布了新帖子,就会每两秒发送一封电子邮件;重复与以前相同的电子邮件,直到发布新帖子。

我的尝试

我已尝试创建一个名为 latestCache 的缓存变量,如下所示以缓存最后一篇文章。我还尝试将 API 调用减慢到每 5 秒一次。两者都没有工作。

有人知道我哪里出错了吗?

'use strict';

const snoostorm = require('snoostorm');
const snoowrap = require('snoowrap');
const nodemailer = require('nodemailer');

// NOTE: The following examples illustrate how to use snoowrap. However, hardcoding
// credentials directly into your source code is generally a bad idea in practice (especially
// if you're also making your source code public). Instead, it's better to either (a) use a separate
// config file that isn't committed into version control, or (b) use environment variables.

// Alternatively, just pass in a username and password for script-type apps.
const r = new snoowrap({
    userAgent: 'NodeJS',
    clientId: '******',
    clientSecret: '*****',
    username: '******',
    password: '******'
});

var latestCache;

var client = new snoostorm(new snoowrap(r));


var transporter = nodemailer.createTransport('smtps://******@gmail.com:******@smtp.gmail.com');


var submissionStream = client.SubmissionStream({
    "subreddit": "AskReddit",
    "results": 1
});

submissionStream.on("submission", function(post) {
    if(post.title != latestCache.title){
        latestCache = post;

            var mailOptions = {
                from: '"Test message" <test@test.com>', // sender address
                to: '******@gmail.com', // list of receivers
                subject: 'Reddit post', // Subject line
                html: '' +
                '<table width="600" align="center" cellpadding="0" cellspacing="0">' +
                '<tr><td colspan="2"><h1>New Reddit AskReddit post from ' + post.author.name + '</h1></td></tr>' +
                '<tr><td><strong>Post Link</strong></td><td> <a href="' + post.url + '">Post Link</a></td></tr>' +
                '<tr><td>&nbsp;</td><td> <a href="http://www.reddit.com/message/compose?to=' + post.author.name + '&subject=Response+to+loan+request">Reply to loan request</a></td></tr>' +
                '</table>'
            };

            // send mail with defined transport object
            transporter.sendMail(mailOptions, function (error, info) {
                if (error) {
                    return console.log(error);
                }
                console.log('Message sent: ' + info.response);
            });
    }
});

【问题讨论】:

    标签: javascript node.js cron nodemailer reddit


    【解决方案1】:

    我愿意

    1. 保留超过 1 个过往帖子的缓存,最多可达 10-20 个。这样它就可以每隔固定的分钟批量发送一次。

    2. 将新帖子推送到缓存中,并触发一个单独且受限制的sendMail 函数

      const { throttle } = require('lodash')
      
      let posts = []
      
      submissionStream.on("submission", function(post) {
        posts.push({post})
        sendMail()
      })
      
      const sendMail = throttle(() => {
        // send mail here
        transporter.sendMail({
          subject: `${posts.length} new posts submitted`
        })
        // Either clear the cache
        posts = []
      }, 2000)
      
    3. 我不确定submissionStream API 是如何工作的,但如果你说它是

      重复相同的电子邮件

      然后我将过去的帖子标记为sent,而不是完全清除缓存并过滤掉未发送的帖子并发送这些帖子。

      const sendMail = throttle(() => {
      
        const postsToBeSent = posts.filter(p => !p.sent)
      
        transporter.sendMail({
          // ...
        })
      
        postsToBeSent.forEach(p => p.sent = true)
      
      }, 2000)
      

    【讨论】:

      猜你喜欢
      • 2011-04-26
      • 2016-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-13
      • 1970-01-01
      • 2012-11-15
      • 1970-01-01
      相关资源
      最近更新 更多