Lazy Panda

Developer

Posts
57
Comments
48
Likes
76
Posts
57
Comments
48
Likes
76
sidebar

How to create a Node TypeScript based Scheduled job using node-corn

In a different business scenario, we need to run some scheduled jobs to overcome certain scenarios like processing batch files, taking DB backup, sending an e-mail to multiple recipients, etc. Those scenarios need some specific kind of job to be scheduled with some time intervals and keep running the business. Task scheduling enables you to schedule methods/functions and commands to be executed at a fixed time, at recurring intervals, or once after a specified interval. In Linux operating systems, task scheduling is often handled by utility services such as cron at the OS level. For Node.js apps, cron-like functionalities are leveraged using the node-cron package.

In this article, I am going to create a scheduled task that helps to send emails to recipients.

 

Creating Node TypeScrip application and installing dependencies

I have already built a node & TypeScript based boiler application. Please check this out and install dependencies. 

Linked Tutorial to setup Node with TypeScrip application.

 

On the above codebase, I am going to install following npm packages - 

install corn job packages:

  • npm install node-cron @types/node-cron

Install email packages:

  • npm install nodemailer @types/nodemailer

 

Scheduling Task designed with TypeScript

Now I am going to write an Abstract class "Scheduler" and which has all the configurations. This Abstract class has one abstract method "executeJob()" which will be implemented in Job-specific class. 

typescript abstract class for scheduler

Have a look at the Scheduler.ts file - 

import * as corn from 'node-cron';

 

export interface IScheduler {

success: boolean;

error: Error;

}

 

export abstract class Scheduler {

 

private scheduleTime: string;

private task;

private options: corn.ScheduleOptions = {

scheduled: true

}

 

constructor(timeToExecute: string) {

this.scheduleTime = timeToExecute;

this.initiateScheduler();

}

 

private initiateScheduler() {

const isJobValidated = corn.validate(this.scheduleTime);

if (isJobValidated) {

this.task = corn.schedule(this.scheduleTime, this.taskInitializer, this.options);

}

 

this.task.start();

}

 

taskInitializer = async () => {

const job: IScheduler = await this.executeJob();

 

if (job.success) {

console.log("Job Successfully executed");

} else {

job.error = new Error("Error to execute the scheduled job");

}

}

 

abstract executeJob(): Promise<IScheduler>;

 

}

 

 

So, in scheduler class, I am creating the corn job and passing the interval time to it. Once the time elapsed it will call the executeJob method. 

Now I am having only email scheduler, but based on different scenarios we can have different schedulers like FileSchedular, BackupSchedular, etc, all class should extend Schedular Class and implement different executeJob methods to serve a different purpose. 

Please check the Corn-job npm package reference.

 

Have a look on the EmailScheduler.ts file - 

import { IScheduler, Scheduler } from '../scheduler';

import nodemailer, { Transporter } from "nodemailer";

 

export class EmailScheduler extends Scheduler {

transporter: Transporter;

 

constructor() {

super("*/10 * * * * *");

this.transporter = this.createTransporter();

}

 

private createTransporter() {

return nodemailer.createTransport({

service: 'gmail',

auth: {

user: "<USER_NAME>",

pass: "<USER_PASSWORD>",

},

logger: true

});

}

 

private sendEmail(): Promise<IScheduler> {

return new Promise((resolve, reject) => {

let mailOptions = {

from: '<FORM_EMAIL_ADDRESS>',

to: '<TO_EMAIL_ADDRESS>',

subject: '<EMAIL_SUBJECT>',

text: '<EMAIL_CONTENT_TEXT_OR_HTML>'

};

this.transporter.sendMail(mailOptions, (error, info) => {

if (error) {

const emailStatus: IScheduler = {

success: false,

error: error

};

reject(emailStatus);

} else {

const emailStatus: IScheduler = {

success: true,

error: new Error(undefined)

};

resolve(emailStatus);

}

});

});

}

 

executeJob(): Promise<IScheduler> {

return new Promise(async (resolve, reject) => {

const sendmail = await this.sendEmail();

resolve(sendmail);

});

}

}

 

 


Send Scheduled Emails using node-cron 

To send email, I am leveraging nodemailer package and import (import nodemailer, { Transporter } from "nodemailer";) it in emailSchedular class. Initialize & defines the email client and sets username and password.

transporter: Transporter;

private createTransporter() {

return nodemailer.createTransport({

service: 'gmail',

auth: {

user: "<USER_NAME>",

pass: "<USER_PASSWORD>",

},

logger: true

});

}

Then use the sendEmail() method to send email to previously mentioned recipients. 

You can find the complete codebase from here.


There are other task scheduler tools available. Be sure to evaluate them to identify which tool is best suited for your particular project. Please comment below if you are using any other tools.

Thanks & Happy Coding!