0

I am having problem sending a booking reminder email. I use nodemailer and node-cron. It works good. I would like to read date from database and e.g. send email one week before reservation. I have no idea how to do it. My model:

  start_time: {
    type: String,
    required: true,
  },
  hour: {
    type: String,
    required: true,
  },
  courtId: {
    type: String,
    required: true,
  },
  userId: {
    type: ObjectId,
    ref: 'userModel',
    required: true,
  },
});

enter image description here

const cron = require('node-cron');
const nodemailer = require('nodemailer');
const { getMaxListeners } = require('../config/database');

const sendEmail = function () {
  const transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
      user: `${process.env.EMAIL_ADDRESS}`,
      pass: `${process.env.EMAIL_PASSWORD}`,
    },
  });

  const mailOptions = {
    from: `${process.env.EMAIL_ADDRESS}`,
    to: `${''}`,
    subject: 'Link To Reset Password',
    text:
      'wiadomosć',
  };

  transporter.sendMail(mailOptions, function (error, info) {
    if (error) {
      console.log(error);
    } else {
      console.log('Email sent: ' + info.response);
    }
  });
};

module.exports.task = function () {
  cron.schedule('00 * * * * *', () => {
    console.log('send');
    //sendEmail();
  });
};

I think start time parse to date? How read only this reservation which will be in a week?

LOL
  • 29
  • 6
  • inside the ```cron.schedule('00 * * * * *', () => {}``` you need to include if statement and check if date now is greater than the start date, also i will suggest after sending to add to the model sended: true. so you can check if email sent, if not to send. if you need and example let me know i will write an answer – Elna Haim Jan 09 '21 at 20:33
  • if You can please write example. – LOL Jan 09 '21 at 20:39

2 Answers2

0

model: ***(i changed start_time to type: Date and i added email_sent)

  start_time: {
    type: Date,
    required: true,
  },
  email_sent: {
   type:Boolean,
   default:"false",
   required:true
   },
  hour: {
    type: String,
    required: true,
  },
  courtId: {
    type: String,
    required: true,
  },
  userId: {
    type: ObjectId,
    ref: 'userModel',
    required: true,
  },
});

Server:

cron.schedule('00 * * * * *', () => {
Modal.find({}).
  then(allUsers => {
   for(let user of allUsers){              
    if(Date.now() < (user.start_time - (24*60*60*1000) * 7) && user.email_sent === false){
     //sendEmail();
     // here you need to update user.email_sent: true. and save.
    }
   }
  })
});

*Also i will suggest to do, find only email_sent : false. you can check how to do it with mongoose. (then you dont need to check it in the if statement) *Model.find({ email_sent: "false" })

i just did it out of my mind, i didnt check, errors you can face:

  1. you will need to convert the start_time
  2. check the boolean email_sent how you get it (as a string or boolen) it will affect the if statement.

this is just the idea how to achieve it. i didnt test the code. Please try the code and let me know if you face any issues

Elna Haim
  • 545
  • 1
  • 5
  • 19
  • (user.start_time - (24*60*60*1000) * 7) i don't understand this fragment. How it works? – LOL Jan 10 '21 at 10:18
  • im taking the start time and i do it minus a week (24*60*60*1000*7) = a week. notice that i changed the start_time type to date, so you will store it as a date, therefore you can minus a week from it and check if the time now is greater than start time minus a week. (you want to check a week before the start time and if true to send email) – Elna Haim Jan 10 '21 at 13:22
  • yes, but now sends an email when bookings are due in a week, two, three. I only want the email sent one week before. Remind the user – LOL Jan 10 '21 at 13:28
  • thats why after you send the email you update the modal to email_sent: true, so next time the cron is running it will check if the email sent, if true it will not send again. so you send only to the users with email_sent : false – Elna Haim Jan 10 '21 at 14:14
  • but when I have reservation to 26.01.2021 I don't want to send then. Only when the reservation will be in a week. Today email will be send only to users which have reseervation 17.01. Tommorow 18.01 ... – LOL Jan 10 '21 at 16:23
0

I'm parsing String to DATE. 2021-1-16 to 2021-01-15T23:00:00.000Z

const nodemailer = require('nodemailer');
const { getMaxListeners } = require('../config/database');
const reservationModel = require('../models/reservationModel');

const sendEmail = function () {
  const transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
      user: `${process.env.EMAIL_ADDRESS}`,
      pass: `${process.env.EMAIL_PASSWORD}`,
    },
  });

  const mailOptions = {
    from: `${process.env.EMAIL_ADDRESS}`,
    to: `${''}`,
    subject: 'Link To Reset Password',
    text: 'wiadomosć',
  };

  transporter.sendMail(mailOptions, function (error, info) {
    if (error) {
      console.log(error);
    } else {
      console.log('Email sent: ' + info.response);
    }
  });
};

module.exports.task = function () {
  cron.schedule('00 * * * * *', () => {
    console.log('scheduled');
    reservationModel.find({ email_sent: false }).then(allReservation => {
      for (let result of allReservation) {
        let date = new Date(result.start_time);
        console.log(date);
        if (Date.now() < date - 24 * 60 * 60 * 1000 * 7) {
          console.log('send');
          sendEmail();
        }
      }
    });
  });
};

mail was never sent 2021-01-15T23:00:00.000Z - String to Date 1610277840044 Date.now()

LOL
  • 29
  • 6