Scheduling Tasks In Node.js With Node Cron
Tags: node, cronjob
Published: 2022-07-27 14:34:06

---
title: Scheduling Tasks In Node.js With Node Cron
published: true
date: 2022-05-09 10:51:23 UTC
tags: #nodejs #cronjob
canonical_url: https://okosunmary.hashnode.dev/scheduling-tasks-in-nodejs-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](https://nodejs.org/en/download/) 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](https://cdn.hashnode.com/res/hashnode/image/upload/v1651660573201/MQcejh9x-.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](https://cdn.hashnode.com/res/hashnode/image/upload/v1651661958134/w3zS4YhpN.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](https://momentjs.com/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](https://cdn.hashnode.com/res/hashnode/image/upload/v1652027414016/B8eknAn74.png)

- Email Inbox

![Screenshot 2022-05-08 at 5.29.29 PM.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1652027505336/pglR5vrCW.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](https://github.com/Marienoir/technical-blog-samples/tree/main/email-node-cron) for the sample code used in this tutorial.

### REFERENCES

[A quick and simple editor for cron schedule expressions by Cronitor](https://crontab.guru/)

https://www.freecodecamp.org/news/schedule-a-job-in-node-with-nodecron/

https://www.digitalocean.com/community/tutorials/nodejs-cron-jobs-by-examples