DEV Community

Cover image for SendGrid Mail Service in NestJS
Idris Akintobi
Idris Akintobi

Posted on • Edited on

SendGrid Mail Service in NestJS

This article illustrates how to integrate SendGrid mail service into your NestJS application.


Step 1: Install NestJS CLI
Skip to step 3 if you already have an existing NestJS application. Install the NestJS CLI globally using npm:

npm install -g @nestjs/cli
Enter fullscreen mode Exit fullscreen mode

Step 2: Create a New NestJS Project
Use the NestJS CLI to create a new project. Name it whatever you like; for this article, we'll use "sendgrid-in-nestjs."

nest new sendgrid-in-nestjs
cd sendgrid-in-nestjs
Enter fullscreen mode Exit fullscreen mode

Step 3: Install SendGrid Package
Install the @sendgrid/mail package:

npm install @sendgrid/mail
Enter fullscreen mode Exit fullscreen mode

Step 4: Set up SendGrid API Key
Obtain your SendGrid API key from the SendGrid dashboard and store it in your environment variables or use a configuration service.

SENDGRID_API_KEY=your-sendgrid-api-key
Enter fullscreen mode Exit fullscreen mode

Step 5: Create Email Module
Create an email module that will contain our implementations.

nest generate module email
Enter fullscreen mode Exit fullscreen mode

Step 6: Create SendGrid Client class
Create SendGridClient in sendgrid-client.ts inside the email folder, which will use the API key from the configuration to interact with the SendGrid API using the @sendgrid/mail package:

nest generate class email/sendgrid-client --flat --no-spec
Enter fullscreen mode Exit fullscreen mode

Step 7: Update SendGrid Client
Update sendgrid-client.ts to use the API key from the configuration:

// src/email/sendgrid-client.ts

import { Injectable, Logger } from '@nestjs/common';
import { MailDataRequired, default as SendGrid } from '@sendgrid/mail';

@Injectable()
export class SendGridClient {
  private logger: Logger;
  constructor() {
    //Initialize the logger. This is done for simplicity. You can use a logger service instead
    this.logger = new Logger(SendGridClient.name);
    //Get the API key from config service or environment variable
    SendGrid.setApiKey(process.env.SENDGRID_API_KEY);
  }

  async send(mail: MailDataRequired): Promise<void> {
    try {
      await SendGrid.send(mail);
      this.logger.log(`Email successfully dispatched to ${mail.to as string}`);
    } catch (error) {
      //You can do more with the error
      this.logger.error('Error while sending email', error);
      throw error;
    }
  }
}

//NOTE You have to set "esModuleInterop" to true in your tsconfig file to be able to use the default key in import.
Enter fullscreen mode Exit fullscreen mode

Step 8: Create Email Service
Create email.service.ts file. It will abstract the SendGridClient, so that we can have different method for specific email use case.

nest generate service email/email --flat --no-spec
Enter fullscreen mode Exit fullscreen mode

Step 9: Update Email Service
Our email service class will consist of 2 methods: "sendTestEmail" and "sendEmailWithTemplate".

// src/email/email.service.ts

import { Injectable } from '@nestjs/common';
import { MailDataRequired } from '@sendgrid/mail';
import { SendGridClient } from './sendgrid-client';

@Injectable()
export class EmailService {
  constructor(private readonly sendGridClient: SendGridClient) {}

  async sendTestEmail(recipient: string, body = 'This is a test mail'): Promise<void> {
    const mail: MailDataRequired = {
      to: recipient,
      from: 'noreply@domain.com', //Approved sender ID in Sendgrid
      subject: 'Test email',
      content: [{ type: 'text/plain', value: body }],
    };
    await this.sendGridClient.send(mail);
  }

  async sendEmailWithTemplate(recipient: string, body: string): Promise<void> {
    const mail: MailDataRequired = {
      to: recipient,
      cc: 'example@mail.com', //Assuming you want to send a copy to this email
      from: 'noreply@domain.com', //Approved sender ID in Sendgrid
      templateId: 'Sendgrid_template_ID', //Retrieve from config service or environment variable
      dynamicTemplateData: { body, subject: 'Send Email with template' }, //The data to be used in the template
    };
    await this.sendGridClient.send(mail);
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 10: Update Email Module
Update the email module by adding the SendGridClient class as a provider and exporting the email service.

// src/email/email.module.ts

import { Module } from '@nestjs/common';
import { EmailService } from './email.service';
import { SendGridClient } from './sendgrid-client';

@Module({
  providers: [EmailService, SendGridClient],
  exports: [EmailService],
})
export class EmailModule {}
Enter fullscreen mode Exit fullscreen mode

Step 11: Use Email Service in Controller
Import the email service and make it available in the appropriate controller.

import { Body, Controller, Get, Post } from '@nestjs/common';
import { AppService } from './app.service';
import { EmailService } from './email/email.service';

@Controller()
export class AppController {
  constructor(
    private readonly appService: AppService,
    private readonly emailService: EmailService,
  ) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }

  @Post('send-test-email')
  async sendEmail(
    @Body() sendEmailDTO: { recipient: string; body: string },
  ): Promise<void> {
    await this.emailService.sendTestEmail(
      sendEmailDTO.recipient,
      sendEmailDTO.body,
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 12: Run your NestJS application
Run your NestJS application:

npm run start:dev
Enter fullscreen mode Exit fullscreen mode

Make a POST request to http://localhost:3000/send-test-email using an API testing tool such as Postman. Include the recipient email and optional body parameters in the request body as JSON payload.

Remember to replace placeholders like 'Sendgrid_template_ID', 'SENDGRID_API_KEY', etc., with your actual values.

Conclusion
In summary, this guide has demonstrated the straightforward integration of SendGrid mail service into your NestJS application. By following the provided steps, you've set up the project, configured the SendGrid API key, and created essential modules and classes. With a modular structure and clear instructions, you now have a solid foundation for incorporating efficient email functionality into your NestJS projects. For any questions or issues, don't hesitate to ask. Happy coding!

Top comments (0)