【NestJS】React(jsx)で作成したメールをmailer serviceで送信する

やりたいこと

  • NestJSでメールを送信したい
  • 検証としてGmailアカウントから送信したい
  • メールテンプレートを作成する上で@nestjs-modules/mailerではテンプレートエンジンとしてhandlebars・pug・ejsが使えるようだが、扱いやすさを重視してjsx(React)で書きたい

1. ライブラリのインストール

Terminal window
npm i @nestjs-modules/mailer nodemailer @webtre/nestjs-mailer-react-adapter
npm i -D @types/nodemailer

2. Gmailパスワードの発行

Googleアカウントのセキュリティ設定から「2段階認証プロセス」を有効にし、「アプリパスワード」から16桁のパスワードを発行する。

3. メールサーバの設定

.env
MAIL_HOST=smtp.gmail.com
MAIL_FROM=xxx@gmail.com
MAIL_USER=xxx@gmail.com
MAIL_PASSWORD=xxxxxxxxxxxxxxxx

今回はGmailアカウントから送信したいので、上記のように環境変数としてメールサーバのオプションを設定する。

パスワードは先ほど取得した「アプリパスワード」のものを指定。

4. MailModuleの実装

Terminal window
nest g module mail
nest g service mail --no-spec
mail/mail.module.ts
import { Module } from '@nestjs/common';
import { MailService } from './mail.service';
import { MailerModule } from '@nestjs-modules/mailer';
import { ReactAdapter } from '@webtre/nestjs-mailer-react-adapter';
import { ConfigService } from '@nestjs/config';
import { join } from 'path';
@Module({
imports: [
MailerModule.forRootAsync({
inject: [ConfigService],
useFactory: (configService: ConfigService) => ({
transport: {
host: configService.get<string>('MAIL_HOST'),
auth: {
user: configService.get<string>('MAIL_USER'),
pass: configService.get<string>('MAIL_PASSWORD'),
},
},
defaults: {
from: configService.get<string>('MAIL_FROM'),
},
template: {
dir: join(__dirname, '/templates'),
adapter: new ReactAdapter(),
options: {
strict: true,
},
},
}),
}),
],
providers: [MailService],
exports: [MailService],
})
export class MailModule {}
  • 環境変数から各オプションの値を取得し設定
  • adapter: new ReactAdapter()とすることでテンプレートをjsxで記述できる

5. メールテンプレートの作成

Terminal window
mkdir src/mail/templates
touch src/mail/templates/test.tsx
mail/templates/test.tsx
import type { FC } from 'react';
type Props = {
message: string;
};
export default function Test({ message }: Props): FC<Props> {
return (
<p>{message}</p>
);
}

6. MailServiceの実装

mail/mail.service.ts
import { Injectable } from '@nestjs/common';
import { MailerService } from '@nestjs-modules/mailer';
@Injectable()
export class MailService {
constructor(private readonly mailerService: MailerService) {}
async sendTestMail(message: string) {
await this.mailerService.sendMail({
to: 'xxx@gmail.com',
subject: 'テストメール',
template: './test',
context: { message },
});
}
}
  • MailerServiceをDIしsendMail()でメールを送信
  • templateにはそのメールで使用するテンプレートのパスを指定
  • contextにはtsx側に渡したい値を指定

7. 動作確認

nest-cli.json
{
"compilerOptions": {
"deleteOutDir": true,
"assets": ["mail/templates/**/*"]
}
}

テンプレートファイルをビルドの対象にする。

Terminal window
npm run build

実際にビルドしてみるとdist下にtsxファイルが作成されている。

8. 動作確認

import { Injectable } from '@nestjs/common';
import { MailService } from '../mail/mail.service';
@Injectable()
export class SampleService {
constructor(private readonly mailService: MailService) {
}
async sampleMethod(): Promise<void> {
await this.mailService.sendTestMail('hello!');
}
}

実装したMailServiceをDIしメソッドを呼び出し、メールが送信されていればOK。

12

参考
  1. Send Emails with NestJS

  2. nodemailerでgmailのアカウントを利用して送信する