Scheduling Tasks In Node.js With Node Cron

Automate sending emails in your node.js application with node-cron

Scheduling Tasks In Node.js With Node Cron

INTRODUCTION

The essence of technology is to make productiveness faster and easier. Have you ever wanted to automate some tasks on your application? Then this tutorial is for you.

In this article, you would learn how to automate scheduling emails in your node.js application using node-cron.

Even if you are not interested in scheduling a job in node.js, you may still find the knowledge of the cron syntax from this article very useful, so stick around👌

PREREQUISITES

This tutorial is a hands-on demonstration of how you can automate scheduled emails. Before proceeding, ensure you have the Javascript runtime environment Node.js on your local computer.

WHAT IS SCHEDULING AND WHY NODE-CRON?

According to Oxford Dictionary, Scheduling refers to “plan an activity at a specific date or time in the future”. This tutorial is based on the words that are being highlighted.

In node.js, we can plan(referred to as function) an activity(referred to as job) to run at a specific date or time(referred to as expression) in the future. This is paramount as you cannot schedule a task to run at a past time.

Node cron is an npm package used to schedule jobs that runs at specific time or date intervals. Instances of jobs that can be scheduled include logging at intervals, backing up a database, and sending out scheduled emails and email notifications. Node-cron is based on cron, the time-based job scheduler in Unix-like systems.

There are several npm packages that handle scheduling in node.js, such as node-schedule, node-cron , Agenda, Bree, Cron, and Bull, but for the purpose of this tutorial, we would be working with node-cron because it is quite mature and stable. It is also preferable because we are making a simple job scheduling.

PROJECT SETUP

To get started, we need to go to our terminal and create a project directory using the following command:

mkdir email-node-cron

We can then move into the created directory using the cd command

cd  email-node-cron

We need to create a new file index.js in the email-node-cron directory

touch index.js

The following command initializes the project and creates a package.json file in the root folder.

npm init -y

The -y suffix is a shortened form of the -yes flag. It is used to accept the prompts that come from npm init automatically. It will populate all the options automatically with the default npm init values.

  • Install dependencies

As stated earlier, node-cron is an npm package, so we need to install it as a package dependency in our project.

npm install node-cron

We also need to install the nodemailer and dotenv package dependency. Nodemailer is an npm package that allows you to send emails.

Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env.

npm install nodemailer
npm install dotenv

After setting up our project and installing dependencies, our folder structure should be like this.

Screenshot 2022-05-04 at 11.30.23 AM.png

SCHEDULING AN EMAIL AUTOMATION JOB

Let us start writing codes for our job and the code snippet below requires the node-cron package in our index.js file

// index.js
const cron = require('node-cron');

To schedule a task, the node cron package has a schedule method that takes in three arguments.

const cronJob = cron.schedule(expression, function, options)
  • The first argument known as cron expression specifies the date and time at which the job should execute.
  • The second argument specifies the function that executes at intervals.
  • The third argument is an optional configuration of the node cron job.

  1. NODE CRON EXPRESSION

The cron expression which is the first argument is a string that specifies the date and time interval of a job. It comes in the format * * * * * *. Each * is a field and the representation of each field with the values is illustrated in the image below.

The seconds field is an optional field and can be omitted when writing an expression.

Screenshot 2022-05-04 at 11.58.58 AM.png There are various ways to populate a cron expression, but, in this tutorial, we would be populating the cron expression with single integer values.

For instance, if we want to send an email to our subscribers every Thursday at 9:50:10 AM, our expression would be like 10 50 9 * * 4

This would run the node-cron job at the tenth second of the fiftieth minute of the ninth hour. Since we did not specify a value for the day of the month and month field, it interprets * to mean every month. But we specified the fourth day of the week, thus this job would run every Thursday at 9:50:10 AM.

Can we attempt writing a cron expression for sending an email to our subscribers on the 15th of every month at 2:30 pm? 😊


2. NODE CRON FUNCTION

The function is the second argument of the schedule method and it specifies the function that should execute. In our case, the function would be sending emails to our subscribers.

Here, we would require the nodemailer package and then create a mail transporter transporter that sets the username and password of our email account.

It is considered a good software development practice to always store credentials in an environment variable (.env) file.

So let us create a .env file in the root folder

touch .env

Run the following code snippets to add your credentials to the .env file.

//.env file
EMAIL=youremailaddress@gmail.com
PASSWORD=youremailpassword

You need to configure the index.js file so that it can have access to your .env file variables.

const nodemailer = require('nodemailer');
const dotenv = require('dotenv');

// .env configuration
dotenv.config()

In the index.js file, the code snippet above requires the dependencies nodemailer and dotenv installed earlier. It is then configured using the .config() method. In order to use nodemailer, we are expected to do the following:

  • Create a Transporter object transporter
// creates a mail transporter here
let transporter = nodemailer.createTransport({
   service: "gmail",
   auth: {
      user: process.env.EMAIL,
      pass: process.env.PASSWORD,
   },
});
  • Create an object MailOptions
let mailOptions = {
      from: 'EMAIL NODE CRON APP',
      to: process.env.EMAIL,
      subject: "Scheduled Email",
      html: `<p>Hello there,</p>
      <p> You have an email scheduled from <b>EMAIL NODE CRON APP</b> </p>
      <p>Keep learning👌👌</p>
      Kind regards, <br>
      <h4> EMAIL NODE CRON APP</h4>`
   };
  • Use the sendMail method on the object transporter
transporter.sendMail(mailOptions, (error, info) => {
      if (error) {
         console.log("Email error application", error.message);
      } else {
         console.log(`${new Date().toLocaleString()} - Email sent successfully:`  + info.response);
      }
   });

In the index.js file, we have the function that needs to execute to send emails to our subscribers. We would take a quick look at the optional argument before we set up our cron job properly.

3. NODE CRON OPTION

The option is the third argument of the cron schedule method and it is an optional configuration for the job scheduling. It is an object that contains the following:

  • scheduled: This is a boolean to set if the created task is scheduled. The default value is set to true. When scheduled is set to true, the job runs automatically when the cron expression is fulfilled, however when set to false, you need to invoke a start() method to the job object like this job.start()

  • timezone: This is the timezone that is used for job scheduling. The default timezone is that of the system used in scheduling the cron job. You can check out moment-timezone for valid timezone values.

An instance of this is:

{ 
scheduled: false, 
timezone: “Asia/Tokyo”
}

Now, we have a pretty good understanding of what each argument means and how they are important in creating a good cron job. We would set up our cron job and executes the job too.

In the code snippet below, we would create a node cron job that schedules emails sent to our subscribers every minute.

Our index.js file should be like this:

const cronJob = require('node-cron');
const nodemailer = require('nodemailer');
const dotenv = require('dotenv');

// .env configuration
dotenv.config();

// creates a mail transporter here
let transporter = nodemailer.createTransport({
   service: "gmail",
   auth: {
      user: process.env.EMAIL,
      pass: process.env.PASSWORD,
   },
});

// Sending emails every minute
cronJob.schedule('59 * * * * *', () => {
   let mailOptions = {
      from: 'EMAIL NODE CRON APP',
      to: process.env.EMAIL,
      subject: "Scheduled Email",
      html: `<p>Hello there,</p>
      <p> You have an email scheduled from <b>EMAIL NODE CRON APP</b> </p>
      <p>Keep learning👌👌</p>
      Kind regards, <br>
      <h4> EMAIL NODE CRON APP</h4>`
   };

   transporter.sendMail(mailOptions, (error, info) => {
      if (error) {
         console.log("Email error application", error.message);
      } else {
         console.log(`${new Date().toLocaleString()} - Email sent successfully:`  + info.response);
      }
   });
});

console.log('Application started.....');

In your terminal, type in the code snippet node index.js to start your application.

NB: If you are having an error message of

Email error application Invalid login: 535-5.7.8 Username and Password not accepted.

You might need to allow less secured apps to test if you are using a Gmail address.

This is a screenshot of my terminal and the email delivered to my inbox.

  • Terminal

Screenshot 2022-05-08 at 5.28.41 PM.png

  • Email Inbox

Screenshot 2022-05-08 at 5.29.29 PM.png


CONCLUSION

In this tutorial, you have learned how to automate scheduling emails in your node.js application using node-cron. This knowledge can be applied in your future projects to be more productive and also avoid repetitive tasks that node-cron can handle.

You can access the GitHub repository for the sample code used in this tutorial.

REFERENCES

A quick and simple editor for cron schedule expressions by Cronitor

freecodecamp.org/news/schedule-a-job-in-nod..

digitalocean.com/community/tutorials/nodejs..