简体   繁体   中英

How to get Email.send to send emails in the future (7 days, 14 days from now, etc)

I need to send email reminders to people in the future. I have implemented MomentJS and I can get dates I'd need my email to send, I just couldn't find anything in meteor docs for Email.send(options) to have anything there. Is there a different package you can recommend?

Here is some of my code as per @richsilv 's advice

createTransfer.js (client)

Template.createTransfer.events({
  'submit form': function (event, template) {
    event.preventDefault();

    Transfers.insert(transfer, function (error, id) {
      if (error) {
        showError(error);
      } else {
        Session.set('files');
        showAlert('Transfers sent!');
        transfer._id = id;
        Meteor.call('sendEmail', transfer);
        scheduleEmail(transfer); // send reminder email
        Router.go('viewTransfer', {_id: id});
      }
    });
    // scheduleEmail(transfer);


    console.log(transfer);

function scheduleEmail(transfer) {

  if (transfer.invoice.due == "7 Days"){
    console.log('its due in 7 days');
    if (moment(transfer.date).add(7, 'days').calendar() == moment(new Date()).format("MM/DD/YYYY")) {
      Meteor.call('sendMail',transfer);
      }
  } else if (transfer.invoice.due == "14 Days") {
    if (moment(transfer.date).add(14, 'days').calendar() == moment(new Date()).format("MM/DD/YYYY")) {
      Meteor.call('sendMail',transfer);
    }
  } else if (transfer.invoice.due == "30 Days") {
    if (moment(transfer.date).add(30, 'days').calendar() == moment(new Date()).format("MM/DD/YYYY")) {
      Meteor.call('sendMail',transfer);
    }
  } else if (transfer.invoice.due == "90 Days") {
    if (moment(transfer.date).add(90, 'days').calendar() == moment(new Date()).format("MM/DD/YYYY")) {
      Meteor.call('sendMail',transfer);
    }
  } else {
    console.log('need to initiate cron!');
    var thisId = FutureEmails.insert(transfer);
    console.log('inserted into db');
    Meteor.call('addCronMail',thisId, transfer);
  }

}

methods.js (lib)

Meteor.methods({

  sendMail: function(transfer) {

    check([transfer.senderEmail,
      transfer.recipientEmail,
      transfer.message,
      // transfer.invoice.total
      ], [String]);

      // Let other method calls from the same client start running,
      // without waiting for the email sending to complete.
      this.unblock();

      transfer.url = Meteor.absoluteUrl() +'transfer/' + transfer._id;

      var template = 'invoice-due';

      Email.send({
        to: transfer.recipientEmail,
        bcc: transfer.senderEmail,
        from: transfer.senderEmail,
        subject: transfer.senderEmail + ' sent you files!',
        html: Handlebars.templates[template](transfer)
      });

    },

    addCronMail: function(id, transfer) {

      SyncedCron.add({
        name: id,
        schedule: function(parser) {
          return parser.recur().on(transfer.date).fullDate();
        },
        job: function() {
          sendMail(transfer);
          FutureEmails.remove(id);
          SyncedCron.remove(id);
          return id;
        }
      });

    }
});

cron.js (server)

Meteor.startup(function() {

  FutureEmails.find().forEach(function(mail) {
    if (moment(mail.date).format("MMM Do YY") == moment(new Date()).format("MMM Do YY")) {
      sendMail(mail)
    } else {
      addCronMail(mail._id, mail);
    }
  });
  SyncedCron.start();

});

As requested, although note that this is not tested, so you might have to play around with it.

$ meteor add percolatestudio:synced-cron

Then something like this on the server:

FutureEmails = new Meteor.Collection('future_emails'); // server-side only

// "details" should be an object containing a date, plus required e-mail details (recipient, content, etc.)

function sendMail(details) {

    Email.send({
        from: details.from,
        to: details.to,
        etc....
    });

}

function addCronMail(id, details) {

    SyncedCron.add({
        name: id,
        schedule: function(parser) {
            return parser.recur().on(details.date).fullDate();
        },
        job: function() {
            sendMail(details);
            FutureEmails.remove(id);
            SyncedCron.remove(id);
            return id;
        }
    });

}

function scheduleEmail(details) { 

    if (details.date < new Date()) {
        sendMail(details);
    } else {
        var thisId = FutureEmails.insert(details);
        addCronMail(thisId, details);       
    }

}

Meteor.startup(function() {

    FutureEmails.find().forEach(function(mail) {
        if (mail.date < new Date()) {
            sendMail(mail)
        } else {
            addCronMail(mail._id, mail);
        }
    });
    SyncedCron.start();

});

Then just call scheduleEmail(details) whenever you want to schedule a new mail.

Hope that's helpful!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM