【NestJS】React(jsx)で作成したメールをmailer serviceで送信する
やりたいこと
- NestJSでメールを送信したい
- 検証としてGmailアカウントから送信したい
- メールテンプレートを作成する上で@nestjs-modules/mailerではテンプレートエンジンとしてhandlebars・pug・ejsが使えるようだが、扱いやすさを重視してjsx(React)で書きたい
1. ライブラリのインストール
npm i @nestjs-modules/mailer nodemailer @webtre/nestjs-mailer-react-adapternpm i -D @types/nodemailer
2. Gmailパスワードの発行
Googleアカウントのセキュリティ設定から「2段階認証プロセス」を有効にし、「アプリパスワード」から16桁のパスワードを発行する。
3. メールサーバの設定
MAIL_HOST=smtp.gmail.comMAIL_FROM=xxx@gmail.comMAIL_USER=xxx@gmail.comMAIL_PASSWORD=xxxxxxxxxxxxxxxx
今回はGmailアカウントから送信したいので、上記のように環境変数としてメールサーバのオプションを設定する。
パスワードは先ほど取得した「アプリパスワード」のものを指定。
4. MailModuleの実装
nest g module mailnest g service mail --no-spec
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. メールテンプレートの作成
mkdir src/mail/templatestouch src/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の実装
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. 動作確認
{ "compilerOptions": { "deleteOutDir": true, "assets": ["mail/templates/**/*"] }}
テンプレートファイルをビルドの対象にする。
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。
参考