Search code examples
javascriptnode.jsmongodbnodemailernode-cron

Booking reminder Nodemailer node-cron MongoDB


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?


Solution

  • 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