How to send emails via Gmail in NestJs

Anuj SinghAnuj Singh
3 min read

Recently, I've been working on an application that required the integration of an email service. Typically, I've used SendGrid for such integrations, but this time I had different requirements, and I needed to utilize Gmail and its SMTP server. So, I decided to write a simple post explaining how to go about it.

If you have Google Workspace, you can leverage Google's SMTP relay service to send emails. Using SMTP relay is considered a good practice. Google allows you to send up to 10,000 messages per day through this service while using the Gmail SMTP server restricts you to sending only 2,000 messages per day.

To begin, we'll install all the necessary packages required for this setup.

npm i @nestjs-modules/mailer nodemailer
npm install --save-dev @types/nodemailer

Now let's look at how we can configure it to send messages.

// First we will create a module in nestjs that would 
// be responsible for dealing with mail related services.
import { Module } from '@nestjs/common';
import { MailService } from './mail.service';
import { MailerModule } from '@nestjs-modules/mailer';
import { HandlebarsAdapter } from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter';
import { MailController } from './mail.controller';
import { ConfigService } from '@nestjs/config';

@Module({
  imports: [
    MailerModule.forRootAsync({
      useFactory: (configService: ConfigService) => ({
        transport: {
          // For relay SMTP server set the host to smtp-relay.gmail.com
          // and for Gmail STMO server set it to smtp.gmail.com
          host: configService.get('MAIL_HOST'),
          // For SSL and TLS connection
          secure: true,
          port: 465,
          auth: {
            // Account gmail address
            user: configService.get('MAIL_USER'),
            pass: configService.get('MAIL_PASS')
          },
        },
      }),
      inject: [ConfigService],
    }),
  ],
  providers: [MailService],
  controllers: [MailController],
})
export class MailModule {}

In the code snippet provided above, there is an important we need to address before proceeding to the service section, and that is the 'MAIL_PASS' variable.

Google has stringent security measures in place, which is why they do not permit the use of your standard password directly. Instead, they offer an alternative solution known as 'APP_PASSWORD.' You'll need to create an 'APP_PASSWORD' specifically for your application to access your account-related services.

To generate an 'APP_PASSWORD,' you must first enable 2-factor authentication on your Google account. Once that's set up, follow these steps:

  1. Visit the myaccount page.

  2. Navigate to the 'Security' tab.

  3. Select '2-factor authentication.'

  4. Scroll to the bottom of the screen, where you'll find the 'APP_PASSWORD' option.

Choose this option, and it will prompt you to specify your application's name. Provide the necessary details, and you will receive a unique code. This code should be used in place of your actual password when registering the module

Let's write the service!

In the service class, there isn't much to do. All that's required is to call the sendMail method provided by the MailerService class, supplying the necessary information about the message.

import { Injectable } from '@nestjs/common';
import { MailerService } from '@nestjs-modules/mailer';

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

  async sendMail() {
    try {
      await this.mailerService.sendMail({
        to: 'opensource@is.best',
        from: '"Welcome to the fold" <linux@over.windows>', // sender address
        subject: 'Quotes', // Subject line
        text: '', // plaintext body
        html: '<p>How many programmers does it take to change a light bulb? 
               None, that’s a hardware problem.</p>',
      });
      return {
        success: true,
      };
    } catch (error) {
      return {
        success: false,
      };
    }
  }
}

And that's it! However, if you wish to customize the configuration further, you can pass additional parameters, and for this reason, we have detailed documentation available for Nodemailer.

P.S., If you are looking to use this service, consider building a newsletter application (Could leverage cloud functions for convenience). You can also integrate this service with your personal blog page.

1
Subscribe to my newsletter

Read articles from Anuj Singh directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Anuj Singh
Anuj Singh