rhanziy

Next.js14 - nodemailer 라이브러리를 통해 이메일 전송(vercel) 본문

Next.js

Next.js14 - nodemailer 라이브러리를 통해 이메일 전송(vercel)

rhanziy 2024. 7. 9. 15:54

 

프로젝트에 간단하게 문의하기 기능을 넣기위해 nodemailer 라이브러리를 설치했다.

https://nodemailer.com/

 

Nodemailer :: Nodemailer

Nodemailer Nodemailer is a module for Node.js applications to allow easy as cake email sending. The project got started back in 2010 when there was no sane option to send email messages, today it is the solution most Node.js users turn to by default. npm i

nodemailer.com

npm install nodemailer
yarn add nodemailer

 

 

사용 방법. 

1. 어떤 메일호스트를 사용할 건지에 따라 달라지겠지만 구글을 사용했고, 구글 계정 설정에 들어가 앱 비밀번호를 발급받으면 된다.

2. env.local 파일에 smtp를 위해 사용할 mail 주소와 app key를 작성해줬다.

 

작성형식은 prefix에 NEXT_PUBLIC_ 을 붙여주고 사용할 변수명

NEXT_PUBLIC_GMAIL_USER='메일 주소'

process.env.NEXT_PUBLIC_GMAIL_APP_KEY='16자리 코드'

 

구글 APP_KEY를 발급받으면 0000 0000 0000 0000 형식의 16자리 코드를 주는데, 붙여서 env파일에 작성해준다.

"use server";

import nodemailer from "nodemailer";
import { getCategoryString } from "../components/ReviewComponent";
import { FormData } from "../types";

const transporter = nodemailer.createTransport({
  host: "smtp.gmail.com",
  port: 465,
  secure: true,
  auth: {
    user: process.env.NEXT_PUBLIC_GMAIL_USER,
    pass: process.env.NEXT_PUBLIC_GMAIL_APP_KEY,
  },
});

export const sendEmail = async (formData: FormData) => {
  const { category, name, telecom, phoneNumber, ssn, text } = formData;

  let mailOptions = {
    from: process.env.NEXT_PUBLIC_GMAIL_USER, // 보내는 메일 주소
    to: process.env.NEXT_PUBLIC_GMAIL_USER, // 받는 메일 주소
    subject: getCategoryString({ name: category }), // 메일 제목
     // html 태그로 넘길 메일 내용
    html: `<p>${name} / ${ssn}</p> 
    <p>${telecom} ${phoneNumber}</p>
    <p>${text}</p>`,
  };

  try {
    transporter.sendMail(mailOptions, function (error, info) {
      if (error) {
        console.error(error);
      } else {
        console.info("Email sent: " + info.response);
      }
    });

    return { message: "이메일 전송 성공" };
  } catch (error) {
    console.error(error);
  }
};

 

이후 form submit 함수를 통해 formData를 넘겨주면 됨. 끄읏

const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();

	// 유효성검사 코드 생략
    
    try {
      await sendEmail(formData);
      alert("문의가 접수되었습니다!");
      window.location.reload();
    } catch (error) {
      console.error(error);
      alert("다시 시도해주세요.");
    }
  };

 

 

오. vercel로 배포하는 페이지는 코드를 수정해줘야 한다.

option에 tls 추가, sendEmail 함수 try catch => await promise 로.

const transporter = nodemailer.createTransport({
  host: "smtp.gmail.com",
  port: 465,
  secure: true,
  auth: {
    user: process.env.NEXT_PUBLIC_GMAIL_USER,
    pass: process.env.NEXT_PUBLIC_GMAIL_APP_KEY,
  },
  
  //추가
    tls: {
    rejectUnauthorized: false,
  },
});



export const sendEmail = async (formData: FormData) => {
  const { category, name, telecom, phoneNumber, ssn, text } = formData;

  let mailOptions = {
    from: process.env.NEXT_PUBLIC_GMAIL_USER,
    to: process.env.NEXT_PUBLIC_GMAIL_USER,
    subject: getCategoryString({ name: category }),
    html: `<p>${name} / ${ssn}</p>
    <p>${telecom} ${phoneNumber}</p>
    <p>${text}</p>`,
  };

  // 변경
  return await new Promise((resolve, reject) => {
    transporter.sendMail(mailOptions, (err, info) => {
      if (err) {
        reject(err);
      } else {
        resolve(info.response);
        return { message: "이메일 전송 성공" };
      }
    });
  });
};

 

잊지말고 vercel setting에다가 env.local에 입력한 환경변수도 잘 추가해주자.

Comments