※ 本サイトにはプロモーションが含まれています。

Vercel環境でNodemailerを使ってメール送信できない問題

Next.js開発でNodemailerを利用してメールを送信する際に、開発環境では正常に動作するがVercelにデプロイすると動作しないことがありました。その対策について備忘録に残したいと思います。

環境

  • Vercel : Hobby プラン
  • メールサーバー : さくらのレンタルサーバー
  • react : 18
  • next : 14.2.5
  • nodemailer : 6.9.14

変更前

import { createTransport } from "nodemailer";

/**
 * メール送信
 * @param toAddress
 */
export async function sendMail(
    toAddress: string
): Promise<boolean> {
    let isSuccess = false;
    try {
        const transporter = createTransport({
            host: process.env.EMAIL_HOST,
            port: 587,
            secure: false,
            auth: {
                user: process.env.EMAIL_USER, // メールアドレス
                pass: process.env.EMAIL_PASSWORD, // パスワード
            },
        });

        const mailOptions = {
            from: process.env.EMAIL_FROM,
            to: toAddress,
            subject: "(サービス名) 会員登録認証リンクのご案内",
            html:
                `
          <p>下記リンクより会員登録を完了してください。</p>
          <a href="` +
                http://link-url +
                `">` +
                http://link-url +
                `</a>
          `,
        };

        await transporter.sendMail(mailOptions, (erro, info) => {
            if (erro) {
                console.log("メール送信エラー");
                console.log(erro);
            }
            console.log("メール送信完了");
            console.log(info);
        });

        isSuccess = true;
    } catch (error) {
        console.log("メール送信エラー");
        console.log(error);
        isSuccess = false;
    }
    return isSuccess;
}

変更後

import { createTransport } from "nodemailer";

/**
 * メール送信
 * @param toAddress
 */
export async function sendMail(
    toAddress: string
): Promise<boolean> {
    let isSuccess = false;
    try {
        const transporter = createTransport({
            host: process.env.EMAIL_HOST,
            port: 587,
            secure: false,
            auth: {
                user: process.env.EMAIL_USER, // メールアドレス
                pass: process.env.EMAIL_PASSWORD, // パスワード
            },
        });

        const mailOptions = {
            from: process.env.EMAIL_FROM,
            to: toAddress,
            subject: "(サービス名) 会員登録認証リンクのご案内",
            html:
                `
          <p>下記リンクより会員登録を完了してください。</p>
          <a href="` +
                http://link-url +
                `">` +
                http://link-url +
                `</a>
          `,
        };

        // Vercel 上では、Promiseを生成しないと動作しない
        await new Promise((resolve, reject) => {
            // send mail
            transporter.sendMail(mailOptions, (err, info) => {
                if (err) {
                    console.error(err);
                    reject(err);
                } else {
                    console.log(info);
                    console.log("メール送信完了");
                    resolve(info);
                }
            });
        });

        isSuccess = true;
    } catch (error) {
        console.log("メール送信エラー");
        console.log(error);
        isSuccess = false;
    }
    return isSuccess;
}


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

コメント

タイトルとURLをコピーしました