【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-adapter
npm i -D @types/nodemailer
2. Gmailパスワードの発行
Googleアカウントのセキュリティ設定から「2段階認証プロセス」を有効にし、「アプリパスワード」から16桁のパスワードを発行する。
3. メールサーバの設定
.envMAIL_HOST=smtp.gmail.com
MAIL_FROM=xxx@gmail.com
MAIL_USER=xxx@gmail.com
MAIL_PASSWORD=xxxxxxxxxxxxxxxx
今回はGmailアカウントから送信したいので、上記のように環境変数としてメールサーバのオプションを設定する。
パスワードは先ほど取得した「アプリパスワード」のものを指定。
4. MailModuleの実装
nest g module mail
nest g service mail --no-spec
mail/mail.module.tsimport { 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/templates
touch src/mail/templates/test.tsx
mail/templates/test.tsximport 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.tsimport { 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/**/*"]
}
}
テンプレートファイルをビルドの対象にする。
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。