본문 바로가기
Server/NodeJs

[NodeJS] NestJs nodemailer 모듈로 메일 전송

by kigo23 2023. 6. 5.
반응형

데이터베이스에서 매일 데이터를 추출하여 엑셀화하여 메일로 전송하는 루틴 업무를 자동화하기 위해 개발을 진행하였습니다. DB의 데이터를 엑셀화 하고 메일에 첨부하여 전송하는 API를 생성해 스케줄러를 통해 자동화 하는데 사용하고 있습니다.

 

작업환경

  • node version : 16.19.1
  • nest version : 9.2.0
  • nodemailer : 6.9.3

우선 nodemailer를 설치합니다. (typescript가 아니라면 nodemailer만 설치하셔도 됩니다.)

npm i @types/nodemailer nodemailer

 

mail 관련 컴포넌트들을 생성합니다.

nest g mo mail
nest g s mail
nest g co mail

 

src/mail

생성이 완료되었다면 mail.service.ts에 다음과 같이 세팅합니다.

// mail.service.ts
import { Injectable } from '@nestjs/common';
import * as nodemailer from 'nodemailer';

@Injectable()
export class MailService {
  private transporter;

  constructor() {
    this.transporter = nodemailer.createTransport({
      // SMTP 설정
      host: 'smtp.gmail.com', //smtp 호스트
      port: 587,
      secure: false,
      auth: {
        user: 'kigo23@gmail.com',
        pass: 'kigopassword',
      }
    });
  }

  async sendMail(to: string, subject: string, content: string) {
    try {
      await this.transporter.sendMail({
        from: 'kigo23@kigo.com', 
        to: to, //string or Array
        subject: subject,
        text: content,
        /* 
        html: htmlData, //내용이 html이라면 text 대신 사용
        cc: [ex1@kigo.com, ex2@kigo.com] //참조
        attachments: attachments //첨부파일
        */
      });
      console.log('메일이 전송되었습니다')
    } catch (error) {
      console.error('메일 전송 중 오류가 발생했습니다:', error);
    }
  }
}

저는 DB에서 추출한 데이터를 엑셀화하여 바로 첨부하기 위해 attachments를 추가하였습니다.

exceljs로 생성하여 첨부파일로 전송!

 

도메인에 따라 smtp를 설정하여야 합니다. (ex. google이라면 gmail, ms라면 outlook)

접은글 (gmail smtp 설정)

더보기

gmail smtp 설정하기

 

먼저 톱니바퀴를 누르고 빠른설정의 [모든 설정 보기]에 들어갑니다.

설정 창에서 [전달 및 POP/IMAP] 으로 들어가서 [IMAP 사용]을 선택하고 저장합니다.

변경사항 저장이 완료되었다면 Google 계정관리에서 [보안] -> [2단계 인증]으로 들어갑니다.

저는 2단계 인증이 완료되었지만, 만약 2단계 인증이 없다면 설정하고 맨 밑의 앱 비밀번호를 선택합니다.

앱 비밀번호를 생성합니다. (저는 기기를 (기타) 선택 후 kigo-gmail로 입력했습니다.

제가 모자이크 처리한 부분이 비밀번호로 사용할 부분입니다.

 

앱 비밀번호를 발급 받았다면 auth를 설정해주시면 됩니다.

(저는 직접 입력해두었지만 git에 입력되지 않도록 config 파일에서 관리해주세요)

  constructor() {
    this.transporter = nodemailer.createTransport({
      // SMTP 설정
      host: 'smtp.gmail.com', //smtp 호스트
      port: 587,
      secure: false,
      auth: {
        user: 'kigo23@gmail.com',
        pass: 'kigopassword', //생성한 앱 비밀번호
      }
    });
  }

 

- gmail smtp 설정 end - 

 

mail.controller.ts 파일입니다.

post메소드를 통해 받아온 정보를 입력하여 service에서 만든 sendMail을 호출합니다.

// mail.controller.ts
import { Controller, Post, Body } from '@nestjs/common';
import { MailService } from './mail.service';

@Controller('mail')
export class MailController {
  constructor(private readonly mailService: MailService) {}

  @Post('send')
  async sendMail(
    @Body('to') to: string,
    @Body('subject') subject: string,
    @Body('content') content: string,
  ) {
    await this.mailService.sendMail(to, subject, content);
  }
}

 

Postman을 사용해 생성한 API를 테스트 하고 마무리 합니다.