SendGrid Mail Service in NestJS
Idris Akintobi
Posted on December 20, 2023
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
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
Step 3: Install SendGrid Package
Install the @sendgrid/mail package:
npm install @sendgrid/mail
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
Step 5: Create Email Module
Create an email module that will contain our implementations.
nest generate module email
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
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.
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
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);
}
}
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 {}
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,
);
}
}
Step 12: Run your NestJS application
Run your NestJS application:
npm run start:dev
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!
Posted on December 20, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.