suyeonme

[Nest.js] nodemailer로 이메일 보내기 본문

프로그래밍👩🏻‍💻/Node.js

[Nest.js] nodemailer로 이메일 보내기

suyeonme 2024. 2. 9. 17:27

서론

진행중인 토이프로젝트에서 사용자가 회원가입을 한 경우, 가입 축하 이메일을 보내는 기능을 구현하였습니다. 여러 종류의 라이브러리가 있지만 nodemailer가 대체로 많이 사용되기도 하고 사용법이 매우 간단해서 nodemailer를 이용해서 적용하였습니다.

자세한 내용은 이 문서에서 확인하실 수 있습니다.

 

nodemailer 라이브러리 설치

pnpm install --save @nestjs-modules/mailer nodemailer

MailModule 생성 및 nodemailer 설정

패스워드등의 민감한 정보는 환경변수로 저장해야합니다. ConfigService를 이용해서 환경변수를 사용하였습니다. 제 경우 Gmail을 통해서 이메일을 보내기 위해서 host는 gmail로 작성했습니다. 

  • MAIL_HOST: smtp.gmail.com
  • MAIL_PORT: 587 (default)
  • MAIL_USER: 서버 인증을 위해서 사용할 본인/회사의 지메일 계정 (ex. suyeon@gmail.com)
  • MAIL_PASSWORD: 지메일에서 설정한 App Password (Sign in with app passwords 문서 참고)
import { Module } from '@nestjs/common';
import { MailerModule } from '@nestjs-modules/mailer';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { MailService } from './mail.service';

@Module({
    imports: [
        MailerModule.forRootAsync({
            imports: [ConfigModule],
            inject: [ConfigService],
            useFactory: (config: ConfigService) => ({
                transport: {
                    host: config.get<string>('MAIL_HOST'), // 이메일을 보낼 SMTP 서버의 주소
                    port: config.get<string>('MAIL_PORT'), // SMTP 서버의 포트 번호
                    auth: {
                        user: config.get<string>('MAIL_USER'), // SMTP 서버 인증을 위한 이메일
                        pass: config.get<string>('MAIL_PASSWORD') // SMTP 서버 인증을 위한 비밀번호
                    }
                },
                defaults: {
                    from: '"nest-modules" <modules@nestjs.com>'
                }
            })
        })
    ],
    providers: [MailService],
    exports: [MailService]
})
export class MailModule {}

MailService 로직 작성

text, html등의 형태로 자유롭게 메일 보낼 내용을 작성할 수 있습니다. 템플릿 엔진을 사용할 수도 있습니다.

import { Injectable } from '@nestjs/common';
import { MailerService } from '@nestjs-modules/mailer';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class MailService {
    constructor(
        private readonly mailerService: MailerService,
        private configService: ConfigService
    ) {}

    public sendSignUpCongratMail(to: string): void {
        this.mailerService
            .sendMail({
                to,
                from: this.configService.get<string>('MAIL_USER'),
                subject:
                    '[tellmeaboutyourcareer] Congratulations on signing up for Our service!',
                text: 'welcome'
                // html: '<b>welcome</b>' // HTML body content
            })
            .then((result) => {
                console.log(result);
            })
            .catch((error) => {
                console.log(error);
            });
    }
}

회원가입시 MailService의 함수 호출

MailService를 사용하는 곳의 의존성으로 추가한 뒤 앞서 작성한 함수를 적용했습니다.

export class AuthService {
    constructor(
        private usersService: UserService,
        private jwtService: JwtService
        private mailService: MailService // * 
    ) {}

	async signup(signupUserDto: SignupUserDto): Promise<User & {
            refreshToken: string;
            accessToken: string;
		}> {
        ...
        this.mailService.sendSignUpCongratMail(signupUserDto.email); // * 
	}
}

결과

짜잔! 메일이 회원가입 성공시 메일이 도착하였습니다. 

짜잔!

Comments