Side Project/Troubleshooting

Vercel producton 모드 - nodemailer 이메일 전송 문제

Yepchani 2023. 11. 28. 10:56

들어가며

사이드 프로젝트를 진행하며 겪었던 문제에 대해 얘기해 보고자 합니다.

 

Next.js를 이용한 프로젝트였는데요.

계정 등록을 할 때 해당 유저에 대한 인증이 필요했고, Nodemailor를 이용해 이메일 인증을 진행하기로 했습니다.

 

문제

순조롭게 진행이 되는 거 같았느니 예상치 못한 곳에서 문제가 발생했습니다.

분명 개발 모드에서는 정상적으로 작동했는데 프로덕션 모드에서는 이메일 전송이 안 되는 겁니다.

 

솔루션

구글링을 한 결과 다음과 같은 내용을 발견할 수 있었습니다.

This problem is really confusing indeed. I've managed to fix this by simply adding async/await. This is because streaming responses (fire-and-forget functions) are not supported by Vercel.

 

Next.js에서는 vercel을 통해 배포를 하는데요. vercel에서 스트리밍 응답이 지원되지 않기 때문에 발생하는 문제라는 거였죠.

 

제공받은 코드를 바탕으로 promise를 생성하고 async/await 처리를 해주니 문제가 해결됐습니다.

아래는 수정 후 코드입니다.

 

const nodemailer = require("nodemailer");

export default async (req, res) => {

const { firstName, lastName, email, message } = JSON.parse(req.body);

const transporter = nodemailer.createTransport({
    port: 465,
    host: "smtp.gmail.com",
    auth: {
        user: "myEmail@gmail.com",
        pass: "password",
    },
    secure: true,
});

await new Promise((resolve, reject) => {
    // verify connection configuration
    transporter.verify(function (error, success) {
        if (error) {
            console.log(error);
            reject(error);
        } else {
            console.log("Server is ready to take our messages");
            resolve(success);
        }
    });
});

const mailData = {
    from: {
        name: `${firstName} ${lastName}`,
        address: "myEmail@gmail.com",
    },
    replyTo: email,
    to: "recipient@gmail.com",
    subject: `form message`,
    text: message,
    html: `${message}`,
};

await new Promise((resolve, reject) => {
    // send mail
    transporter.sendMail(mailData, (err, info) => {
        if (err) {
            console.error(err);
            reject(err);
        } else {
            console.log(info);
            resolve(info);
        }
    });
});

res.status(200).json({ status: "OK" });
};

 

마치며

사실 전혀 예상치 못한 부분에서 발생한 문제였는데요.

개발 모드에서 잘 됐기에 당연히 프로덕션 모드에서도 잘 되리라 생각했습니다만.. 그렇지는 않다는 귀중한 교훈을 얻었습니다.

 

지적이나 다른 의견은 언제나 환영합니다 :D

감사합니다.

 

Reference

https://stackoverflow.com/questions/65631481/nodemailer-in-vercel-not-sending-email-in-production

https://vercel.com/docs/limits/overview#streaming-responses