Scheduling Cron Jobs in Node.js with Node-Cron

Scheduling Cron Jobs in Node.js with Node-Cron

ยท

6 min read

We as developers often run across situations where we want some process to happen on a certain schedule. It could be clearing out error logs every Monday evening, emailing users who haven't checked in to an event the day before their event takes place, archiving old data, etc...

In situations like these, we look to cron jobs! In Node.js, setting up a Cron job is simple with the help of node-cron. Let's take a look at what it can do.


What We Are Going To Build

Perhaps you wish someone would complement you every day, praising your productivity and progress that day. With node-cron that is possible!

backpat.gif

In this tutorial, we will set up an Express server on Node.js to give an under-appreciated developer (or yourself...) some well deserved praise every day. This server will schedule a task to run every evening at 5:30pm congratulating its developer on a productive day at work. Let's get started!

This tutorial assumes you have Node.js installed on your machine


Setting Things Up

The first step here will be to get a simple Express server up and running. We'll need a directory to hold the project:

mkdir <project-name> 
cd <project-name>

Installing The Modules

Now we'll want to initialize NPM in this directory so we can get to installing the packages we need:

npm init

Our package.json file has been generated, now let's install those packages. We're going to need:

npm i --save express node-cron nodemailer

Building out the basic server

The entry file to our server will be named index.js. Create it by running:

touch index.js

And we will start a simple express server with the following:

const express = require('express'),
      app = express(),
      nodemailer = require('nodemailer'),
      cron = require('node-cron'),
      PORT = 3001

app.listen(PORT, () =>  
    console.log(`Listening on ${PORT}`)
)

Here we are importing all the packages we will need at the top, instantiating an express app, and starting the server on port 3000.

Our express server is all set up! We can start our server by running this command:

node index.js

Scheduling Our Task

With our server set, we are now ready to get to scheduling! node-cron has one main function called schedule() that is the starting point for every job. schedule() can take in three parameters:

  1. expression - This is the cron expression that defines when the task should run. It follows the standard cron syntax, along with a few extra options specific to the library, defined here
  2. function - This is the function that will be run on the specified time-interval
  3. options - This is an object that takes in configuration options. These options are described here. We will not be setting any extra options in this tutorial so I will be omitting this parameter.

Here's a simple example:

carbon (3).png

Here, we are scheduling a task to run according to this expression: * * * * *, which evaluates to every minute. Every time this task is run, the message running every minute will be logged to the console.

Here are a few more examples of expressions:

  • * * * * Fri runs every Friday
  • 1 * * * * runs every time the minute of a date is 1. (12:01, 3:01, 4:01)
  • 45 7 * * * runs every day at 7:45am (uses a 24-hour clock)

The expression we will be looking for in our scenario (5:30pm every day) will be: 30 17 * * *

So let's schedule it!

const express = require('express'),
      app = express(),
      nodemailer = require('nodemailer'),
      cron = require('node-cron'),
      PORT = 3001

cron.schedule('30 17 * * *', () => 
    console.log('Running at 5:30pm every day')
)

app.listen(PORT, () =>  
    console.log(`Listening on ${PORT}`)
)

Awesome! We have an express server scheduling a task to run at 5:30pm every day. node-cron made it super simple to set that up. Now we can finish this project off and start sending ourselves the encouragement we need!

Sending The Emails

I will be using a Gmail account to set up our send mail request. If you receive some sort of authentication error while trying to send emails, it may be because Gmail has blocked Less Secure Apps. You will need to switch this setting on to Allow Less Secure Apps here

NOTE: It is recommended you switch this setting back off once you are done testing

Set up our transporter

We will first need to set up what is called a transporter. This holds info on your authentication details and email host.

const transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
        user: 'your-email@gmail.com',
        pass: 'password'
    }
})

Note: In a real-world scenario the auth details should be stored as secrets or in some sort of environment variable to avoid storing credentials in the source-code.

This sets up a transport that is ready to start sending emails. Within our scheduled task, let's send an email

const express = require('express'),
      app = express(),
      nodemailer = require('nodemailer'),
      cron = require('node-cron'),
      PORT = 3001

const transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
        user: 'your-email@gmail.com',
        pass: 'password'
    }
})

cron.schedule('30 17 * * *', async () => 
    transporter.sendMail({
        from: 'your-email@gmail.com',
        to: 'recipient@hey.com',
        subject: 'You are awesome',
        text: 'You did SUCH A GOOD JOB TODAY. CONGRATS!! ๐ŸŽ‰๐ŸŽ‰๐ŸŽ‰'
    }, (error, info) => {
        if (error) {
            console.log(error);
        } else {
            console.log('Email sent: ' + info.response);
        }
    })
)

app.listen(PORT, () =>  
    console.log(`Listening on ${PORT}`)
)

And that'll do it! Every day at 5:30pm an email will get sent from your-email@gmail.com to recipient@hey.com with a subject of You are awesome and a very encouraging message ๐Ÿ˜


Conclusion

With our application complete, we can now send ourselves much-needed encouragement on a daily basis (or more frequently depending on how you configure the task and how needy you're feeling ๐Ÿ˜œ).

node-cron makes it super easy to schedule a task on a desired time-interval. It also has a lot of other configurations that give it some pretty cool use-cases. I'd highly recommend reading through their docs to see what all it can do with its various configuration options.

Hope this has helped, thanks for the read!

Calendar vector created by freepik - www.freepik.com

ย