NEXT.JS 메일 발송 기능 구현

Hyeongjin Song·2024년 2월 2일

jungle

목록 보기
12/12
post-thumbnail

SMTP(Simple Mail Transfer Protocol, SMTP)

인터넷에서 이메일을 보내기 위해 이용되는 프로토콜

구글 IMAP(Internet Message Access Protocol) 사용하기

IMAP - 인터넷 메시지 접속 프로토콜(IMAP, Internet Message Access Protocol) 응용 계층 인터넷 프로토콜 중 하나로, 원격 서버로부터 TCP/IP 연결을 통해 이메일을 가져오는데 사용된다.

  1. 지메일 홈
    우측 상단의 톱니바퀴 모양 클릭하고 모든 설정 보기 -> 전달 및 POP/IMAP -> IMAP 사용으로 변경 -> 변경사항 저장

  2. 구글 계정 관리
    보안 -> 앱 비밀번호 클릭하여 앱 비밀번호 생성

세팅 끝. 코딩 시작!

세팅은 위 두 과정으로 간단하게 끝난다.

import nodemailer from 'nodemailer';

우리가 사용할 nodemailer는 node 서버에서 동작하므로, nextjs의 서버단에서 위와 관련된 코드를 실행해야 한다.
따라서 어떻게 할지 고민하다가, 클라이언트 컴포넌트에서 api 호출을 통해 구현하기로 하였다.

클라이언트 코드


export const ClientButton: React.FC = () => {
    const onSubmit = () => {
        const sender={
            to : "x1xgudwls@naver.com",
            from : "x2xgudwls@gmail.com",
            html : "<p>안녕하세요. 내용입니다.</p>", // 잘 바꾸면 이쁨
            subject : "안녕하세요. 제목입니다."
        }
        sendContactEmail(sender)
    }

    return (
      <button onClick={onSubmit}>버튼 누르면 메일 가야함</button>
    );
};

버튼을 누르면 온클릭 함수 내부의 sendContactEmail함수가 실행된다.

export async function sendContactEmail(sender: any) {
    const response = await fetch('/api/invite', {
        method: 'POST',
        body: JSON.stringify(sender),
        headers: {
        'Content-Type': 'application/json',
        },
    });

    const data = await response.json();

    if (!response.ok) {
        throw new Error(data.message || '서버 요청에 실패함');
    }

    return data;
}

간단하게 포스트 요청을 통해 api 호출.

서버 코드

import nodemailer from 'nodemailer';

const transporter = nodemailer.createTransport({
    service: 'gmail',  // 사용하고자 하는 서비스
    host: 'smtp.gmail.com', // host를 gmail로 설정
    port: 587,
    secure: false,
    auth: {
      user: process.env.USER_EMAIL, // 세팅에 사용된 Gmail 주소 입력
      pass: process.env.PASS // 세팅 2번에서 얻은 앱 비밀번호 입력
    }
})

async function sendMail({ to, from, html, subject }:{to:string, from:string, html:string,subject:string}) {
    let info = await transporter.sendMail({
        from, // 보낸 사람 
        to, // 받는 사람
        subject, // 메일 제목
        html, // 메일 내용
    })    
}

export async function POST(req: Request) {
    const body = await req.json(); // body = ReadableStream
    console.log("invite : ",body)
    return sendMail(body)
      .then(
        () =>
          new Response(JSON.stringify({ message: '메일을 성공적으로 보냈음' }), {
            status: 200,
          })
      )
      .catch((error) => {
        console.error(error);
        return new Response(JSON.stringify({ message: '메일 전송에 실패함' }), {
          status: 500,
        });
      });
  }

POST함수에서 받은 body에는 sender객체가 저장되어 있다.

profile
first in, last out

0개의 댓글