Sling Academy
Home/Node.js/How to Automatically Send Emails in NestJS

How to Automatically Send Emails in NestJS

Last updated: December 31, 2023

Introduction

Sending emails automatically is an essential feature for modern web applications. NestJS, a progressive Node.js framework for building server-side applications, comes with powerful features for this task. This tutorial will guide you through setting up an automated email system in NestJS, ensuring you can implement this functionality with ease.

Setting Up Your NestJS Project

To start, make sure you have NestJS CLI installed:

npm i -g @nestjs/cli
nestjs new email-service

Now, navigate into your project directory and install the necessary packages for sending emails:

cd email-service
npm install nodemailer @nestjs-modules/mailer

Configuring the Mailer Module

The ‘@nestjs-modules/mailer’ module provides a wrapper around Nodemailer for easy integration:

// mail.module.ts
import { Module } from '@nestjs/common';
import { MailerModule } from '@nestjs-modules/mailer';

@Module({
  imports: [
    MailerModule.forRoot({
      transport: {
        host: 'smtp.example.com',
        port: 587,
        secure: false, // upgrade later with STARTTLS
        auth: {
          user: '[email protected]',
          pass: 'password'
        }
      },
      defaults: {
        from: '"No Reply" <[email protected]>'
      }
    })
  ]
})
export class MailModule {}

You’ll need to update the configuration with your specific SMTP server details.

Creating an Email Service

Let’s create a service to encapsulate email functionality:

// email.service.ts
import { Injectable } from '@nestjs/common';
import { MailerService } from '@nestjs-modules/mailer';

@Injectable()
export class EmailService {
  constructor(private readonly mailerService: MailerService) {}

  async sendWelcomeEmail(email: string): Promise {
    await this.mailerService.sendMail({
      to: email, // list of receivers
      subject: 'Welcome to Our Service', // Subject line
      template: './welcome', // The `.hbs` template file
      context: {
        // Data to be sent to template engine.
      }
    });
  }
}

This service method can now be called from within any controller or other service in your NestJS application.

Creating a Template Engine

Utilize a template engine like Handlebars to create dynamic email templates:

npm install handlebars

Then, update your MailerModule configuration to use this:

// Update in mail.module.ts
...
MailerModule.forRoot({
  ...
  template: {
    dir: process.cwd() + '/templates/',
    adapter: new HandlebarsAdapter(),
    options: {
      strict: true,
    },
  },
})
...

Create a ‘templates’ directory in your project’s root and add ‘welcome.hbs’ with your email HTML and Handlebars syntax.

Testing Email Functionality

Create a controller to test sending emails via an HTTP request:

// email.controller.ts
import { Controller, Get, Query } from '@nestjs/common';
import { EmailService } from './email.service';

@Controller('email')
export class EmailController {
  constructor(private readonly emailService: EmailService) {}

  @Get('send')
  async sendEmail(@Query('to') to: string) {
    await this.emailService.sendWelcomeEmail(to);
    return { message: 'Email sent!' };
  }
}

Now you can test this by navigating to ‘http://localhost:3000/email/[email protected]’ to trigger the email sending.

Advanced Use Cases

We’ll explore how to automate periodic email sending, handle attachments, and manage multiple templates.

To automate sending emails at specific intervals, investigate using the ‘@nestjs/schedule’ module combined with CRON jobs within your service.

Handling Attachments

To include attachments, modify your sendMail call:

/.../
await this.mailerService.sendMail({
  /.../
  attachments: [
    {
      filename: 'attachment.pdf',
      path: '/path/to/attachment.pdf'
    }
  ]
});
/.../

Be cautious about the file paths and storage when working with attachments, especially in a production setting.

Managing Multiple Email Templates

Create a method that can switch between various templates depending on the email type sent:

// email.service.ts
/.../
async sendUserNotification(email: string, notificationType: 'alert' | 'reminder') {
  const templates = {
    alert: './alert',
    reminder: './reminder'
  };

  await this.mailerService.sendMail({
    /.../
    template: templates[notificationType],
    context: {
      // Notification-specific data
    }
  });
}
/.../

Conclusion

Automating emails in NestJS is made straightforward with the ‘@nestjs-modules/mailer’ module. By leveraging this module and template engines like Handlebars, you can create a robust email service that serves various application needs. Always ensure to maintain security best practices by protecting sensitive credentials and handling user data responsibly.

Next Article: NestJS: Validate request body based on one property

Previous Article: How to Automatically Generate Swagger Docs in NestJS

Series: Nest.js Tutorials: From Basics to Advanced

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates