Timpossible history

Next JS로 Nodemailer 사용하여 이메일 보내기 기능 구현 본문

프론트엔드/Next JS

Next JS로 Nodemailer 사용하여 이메일 보내기 기능 구현

팀파서블 2023. 12. 30. 23:57

이번에는 Next.js 프레임워크에서 Nodemailer를 이용하여 이메일을 보내는 기능을 구현해보았다.

Nodemailer는 Node.js 기반의 라이브러리로, 이메일 전송 작업을 쉽게 처리할 수 있도록 도와준다.

이 기능을 통해서 웹사이트의 회원가입 시, 이메일 인증하는 기능을 구현해보고자 한다.

 

Nodemailer 설치

먼저, Next.js 프로젝터에 nodemailer를 설치한다.

npm install nodemailer

 

 

Nodemailer 설정

 

Nodemailer는 Gmail을 통해서 메일을 보내는 라이브러리이기 때문에 사용하기 위해서는 Gmail 계정에서 '앱 비밀번호'를 생성해야 한다.
'앱 비밀번호' 생성하는 법을 알아보려면 아래 글의 링크를 통해서 알아보자.

 

Nodemailer 이용 시 앱 비밀번호 설정 방법

 

[Node JS] Nodemailer 사용 시 필요한 앱 비밀번호 설정

앱 비밀번호가 필요한 이유 앱 비밀번호 설정 방법 앱 비밀번호가 필요한 이유 Nodemailer를 사용해서 이메일을 보내는 기능을 구현한 웹사이트나 어플리케이션은 보안이 중요하다. 웹사이트든 어

everythingaboutworld.tistory.com

 

API route는 pages 폴더의 api 폴더에서 sendEmail.js 파일 생성

(Next JS 13버전 이상에서는 app 폴더의 api에)

// pages/api/sendEmail.js

import nodemailer from 'nodemailer';

export default async function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).end(); // Method Not Allowed
  }

  try {
    // Nodemailer transporter 생성
    const transporter = nodemailer.createTransport({
      service: 'gmail',
      auth: {
        user: 'your.email@gmail.com',
        pass: 'your-app-password', // Gmail '앱 비밀번호'
      },
    });

    // 전송할 이메일 내용 설정
    const mailOptions = {
      from: 'your.email@gmail.com',
      to: txxxxxxxxx@naver.com', //필자의 naver 계정에 보내보았다.
      subject: '테스트 이메일',
      text: '안녕하세요, 이것은 테스트 이메일입니다.',
    };

    // 이메일 전송
    const info = await transporter.sendMail(mailOptions);

    console.log('이메일 전송 성공:', info.response);
    res.status(200).json({ success: true });
  } catch (error) {
    console.error('이메일 전송 실패:', error.message);
    res.status(500).json({ success: false, error: error.message });
  }
}

 

Front-end 파트에서 api 호출

이제 이메일을 보내는 테스트를 해봐야 한다.

// pages/index.js

import { useState } from 'react';

export default function Home() {
  const [emailSent, setEmailSent] = useState(false);

  const sendEmail = async () => {
    try {
      const response = await fetch('/api/sendEmail', {
        method: 'POST',
      });

      const data = await response.json();

      if (data.success) {
        setEmailSent(true);
      } else {
        console.error('이메일 전송 실패:', data.error);
      }
    } catch (error) {
      console.error('API 호출 실패:', error);
    }
  };

  return (
    <div>
      <h1>Next.js에서 Nodemailer를 사용하여 이메일 보내기</h1>
      {emailSent ? (
        <p>이메일이 성공적으로 전송되었습니다!</p>
      ) : (
        <button onClick={sendEmail}>이메일 보내기</button>
      )}
    </div>
  );
}

 

이렇게 코드를 적어주고 테스트를 돌려보면,

nodemailer로 이메일 보내기 성공!

 

이렇게 성공한 모습을 볼 수 있다.

 

여기서 더 복잡하게, 이메일의 템플릿을 만들어보자.

 

Nodemailer 템플릿 만들기

여기서 Template 컴포넌트를 .jsx든 .tsx 파일의 형태로 만들면 좋겠지만 그렇게 하면

'The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received an instance of Object'

라는 오류가 발생하므로 .js 파일 형태로 만들어 html 스트링을 반환하는 함수를 만들어준다.

// components/EmailTemplate.js

import React from 'react';

const EmailTemplate = ({ message }) => {
  return `
    <div style="font-family: Arial, sans-serif; padding: 20px;">
      <h2>${message.subject}</h2>
      <p>${message.body}</p>
      <p>이 이메일은 Next.js와 Nodemailer를 사용하여 보내졌습니다.</p>
    </div>
  `;
};

export default EmailTemplate;

 

그리고 다시 api route로 돌아와서 

// pages/api/sendEmail.js

import nodemailer from 'nodemailer';
import EmailTemplate from '../../components/EmailTemplate';

export default async function handler(req, res) {


 ...

    const mailOptions = {
      from: 'your.email@gmail.com',
      to: 'recipient.email@example.com',
      subject: '테스트 이메일',
      html: EmailTemplate({ subject: '테스트 이메일', body: '안녕하세요, 이것은 테스트 이메일입니다.' }),
    };

    
}

 

이렇게 mailOptions 안에 html 키의 값으로 EmailTemplate() 함수를 호출해주고 테스트를 진행하면 깔끔하게 성공하는 것을 볼 수 있다.

 

※ Template 컴포넌트를 .jsx 나 .tsx로 만들어서 할 수는 있지만, 다른 라이브러리들을 설치해서 해야하므로 그냥 간편하게 html string을 써주는게 낫다.