socialight
socialight

Reputation: 517

Meteor: Using setInterval() To Run Function Once Per Day

I am trying to run a function that will search for certain parameters and will email users only once a day.

I am finding many ways that can be done. It seems that setInterval() can be a way to do that.

 setInterval(function () {
    var date = new Date();
    if (date.getDate() === 12 && date.getHours() === 10 && date.getMinutes === 0) {
        alert("Surprise!!")
    }
}, 1000)

For example the above would trigger every day at 10 am.

I also found there is a package that runs cron jobs. https://github.com/percolatestudio/meteor-synced-cron

It seems that I could set a cron job to send email every day. I have never used cron jobs so I think this option would be much more difficult for me at this moment.

Lastly, I also found this way to do it: Call function once on day change

With just a regular function.

It seems that perhaps setTimeout() is the easiest way to get it done. But are there any setbacks? I don't want to miss emails, or worse email users many times. My site is live and growing so I would hate to find out the hard way.

Any help is appreciated.

Upvotes: 0

Views: 1659

Answers (3)

socialight
socialight

Reputation: 517

So, to finish the subject and maybe help anyone in the same situation. This is how I did it. I added the package 'percolate:synced-cron'. Then on the server side I created a file 'cron.js'. And this is the code I used. I removed the rest of my action part of function for privacy, but the important parts are here. The parser.text makes it really easy to pick a time. 'every 5 seconds' (does action every 5 seconds).. or ('at 10 am') will take action every day at 10 am. Keep in mind mongo is set in UTC time as standard so you have to do the conversion.

    if (Meteor.isServer) {
  // optionally set the collection's name that synced cron will use
  SyncedCron.config({
    collectionName: 'somethingDifferent'
  });

  SyncedCron.add({
    name: 'Crunch some important numbers for the marketing department',
    schedule: function(parser) {
      // parser is a later.parse object
      // return parser.text('every 5 seconds');

      return parser.text('at 3:00 am');
      // midnight is at 5pm LA time ... 10 am LA time is 3 am UTC
    },
    job: function(intendedAt) {
      var today = new Date();
      var yesterday = new Date()
      var dayBeforeYesterday = new Date()
      yesterday.setDate(today.getDate() - 1)
      dayBeforeYesterday.setDate(today.getDate() - 2)


      var todaysUsers = Meteor.users.find({   createdAt: {    $lt: (yesterday), $gt: dayBeforeYesterday   } }).fetch()
      //rest of function here

      }
    }
  });

  Meteor.startup(function () {
    // code to run on server at startup
    SyncedCron.start();

    // Stop jobs after 15 seconds
    // Meteor.setTimeout(function() { SyncedCron.stop(); }, 7 * 1000);
  });
}

Upvotes: 1

ergusto
ergusto

Reputation: 1256

I would recommend using a package such as percolate:synced-cron to achieve this.

Upvotes: 0

Kris
Kris

Reputation: 201

I think you'll have to use Meteor.setInterval() rather than setInterval() to get it to work correctly on the server. However, I use this for functions I need to run every second; for longer periods any sort of cron job package would also work fine, such as synced-cron.

Upvotes: 4

Related Questions