개발일지
[NestJS] 메일 전송 하기 - SES, Nodemailer , EJS 본문
Amazon SES (Amazon Simple Email Service)
Amazon SES란 아마존에서 제공하는 이메일 전송 플랫폼을 말합니다.
사전 준비
- AWS 계정의 Access key, Secret key가 필요합니다.
- Amazon SES verifed email를 생성합니다.
패키지 설치
- aws-sdk와 nodemailer(ses transport)를 사용합니다.
// 1. nodemailer
$ yarn add nodemailer
// 2. @aws-sdk/credential-provider-node (aws-sdk v3 사용할 경우)
$ yarn add @aws-sdk/credential-provider-node
// 3. @aws-sdk/client-ses
$ yarn add @aws-sdk/client-ses
구현
1. nodemailer SES transporter 생성
// email.service.ts
import * as aws from '@aws-sdk/client-ses';
import * as nodemailer from 'nodemailer';
import { AwsConfig } from '../../config';
@Injectable()
export class EmailService {
private readonly transporter;
constructor(private readonly logService: LogService) {
const ses = new aws.SES({
apiVersion: AwsConfig.AWS_SES_API_VERSION,
region: AwsConfig.AWS_SES_REGION,
credentials: {
accessKeyId: AwsConfig.AWS_ACCESS_KEY_ID,
secretAccessKey: AwsConfig.AWS_SECRET_KEY,
},
});
this.transporter = nodemailer.createTransport({
SES: { ses, aws },
});
}
...
}
// config
export class AwsConfig {
static readonly AWS_ACCESS_KEY_ID = 'access-key';
static readonly AWS_SECRET_KEY = 'secret-key';
// AWS SES
static readonly EMAIL_SENDER_EMAIL_ADDRESS = 'send@email.com';
static readonly AWS_SES_API_VERSION = '2010-12-01';
static readonly AWS_SES_REGION = 'ap-northeast-2';
}
2. 이메일 발송
transporter.sendMail(data[, callback])
으로 메일을 발송할 수 있습니다. callback을 설정하지 않은 경우 Promise 객체를 반환합니다. 자세한 내용은 여기를 참고하세요.
// class EmailService
private async requestMailTransport({ to, subject, html }: IEmailMessage) {
return this.transporter
.sendMail({
from: AwsConfig.EMAIL_SENDER_EMAIL_ADDRESS, // 발신 이메일
to, // 수신 이메일
subject, // 제목
html, // 본문
})
.then((res) => {
// logic...
})
.catch((err) => {
throw new HttpException(
exceptionMessagesAuth.FAILED_TO_SEND_EMAIL,
400
);
});
}
템플릿 렌더링
🔗 EJS 를 사용했습니다.
$ yarn add ejs --save
구현
// class EmailService
private async renderToString(ejsFileOrStrHtml: string, data: object) {
const path = join(EmailConfig.TEMPLATE_DIR_PATH, ejsFileOrStrHtml); // ejs 파일 경로
let html;
// 1. .ejs file일 경우
await ejs.renderFile(path, data, async (err, res) => {
if (err) {
// 2. string 타입일 경우 ex) `<h2><%= email %></h2>`
html = await ejs
.render(ejsFileOrStrHtml, data, { async: true })
.catch((err) => {
throw new HttpException(
exceptionMessagesAuth.FAILED_TO_SEND_EMAIL,
400
);
});
} else {
html = res;
}
});
return html;
}
ejsFileOrStrHtml
에는 ejs 파일 또는 string 으로 변환한 html이 들어갑니다.{ async: true }
: true일 경우 비동기 함수를 사용합니다.
사용 예시
// email.ejs
<html>
<head> </head>
<body>
<div><%= email %></div>
</body>
</html>
@Injectable()
export class SendEmailService {
constructor(private readonly emailService: EmailService) {}
async sendEmailTest() {
const ejs = 'email.ejs';
// 또는 `<html> <head></head> <body> <div><%= email %></div> </body> </html>`;
const html = await this.renderToString(ejs, { email: 'to@email.com', });
return await this.requestMailTransport({
to: toEmail,
subject: '메일 테스트',
html,
});
}
}
'NestJS, Node.js > #02 NestJS' 카테고리의 다른 글
[NestJS] Guard, Decorator로 역할 기반 접근 제어(RBAC) 구현하기 (0) | 2024.11.10 |
---|---|
대용량 객체 파일 안전하게 업로드하기 - AWS 멀티 파트 업로드 with.NestJS (0) | 2024.10.26 |
[devlog] 객체지향 구조로 데이터 불일치 해결하고 개발 생산성 개선하기 (0) | 2024.05.25 |
[NestJS] Passport+JWT+Guard 검증 로직 커스텀하기 (1) | 2024.01.06 |
[NestJS] PASETO로 인증/인가 구현하기 (0) | 2022.11.25 |