vercel 中的 Nodemailer 不在生产中发送电子邮件

Dan*_*scu 17 sendgrid nodemailer next.js vercel

我正在使用 Nodemailer 在我的无服务器 Next.js 项目中发送电子邮件,该项目部署在 Vercel 中,该项目在开发模式下完美运行。但我在生产中遇到了问题。没有返回错误,一切都与开发模式相同,只是我没有收到任何电子邮件。

我有另一个用 React 构建的项目,并部署在 Heroku 中,我以相同的方式发送电子邮件,并且它在开发和生产方面工作正常,所以我知道问题出在 Vercel 上。

是的,我在 Google 帐户中启用了“允许安全程度较低的应用程序”,并且是的,我启用了验证码。

我也读过这篇文章https://vercel.com/docs/solutions/email但它并没有真正让我明白在我的情况下我应该做什么。我可以看到这是 SMTP 的问题,但我不知道到底是什么。

有人遇到过这种问题吗?我怎样才能解决这个问题?

const transporter = nodemailer.createTransport({
    host: "smtp.gmail.com",
    port: 465,
    auth: {
        user: myEmail@gmail.com,
        pass: myEmailPass
    }
});
            
const mailOptions = {
    from: `${req.body.name} ${req.body.email}`,
    to: myEmail@gmail.com,
    subject: `${req.body.subject}`,
    text: `Text: ${req.body.text}`
}
            
transporter.sendMail(mailOptions, (err, res) => {
    if(err) {
          console.log(err);
    } else {
          console.log("success");
    }
});
Run Code Online (Sandbox Code Playgroud)

更新

我更改为 SendGrid:创建了一个帐户,创建了一个 API 密钥,并像这样更改了代码(而不是上面的代码):

sgMail.setApiKey(process.env.SENDGRID_API_KEY);
const msg = {
    to: `myEmail@gmail.com`,
    from: `myEmail@gmail.com`,
    subject: `${req.body.subject}`,
    text: `${req.body.text}`
};
sgMail
.send(msg)
.then(() => {
     console.log('email sent')
})
.catch((error) => {
     console.error("error", error)
});
Run Code Online (Sandbox Code Playgroud)

它注销“电子邮件已发送”,但我没有收到任何电子邮件。这与 Nodemailer 的问题相同。我现在很困惑...

小智 45

我遇到了这个问题并设法修复它并通过添加 async/await 的承诺来继续使用 nodemailer。

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" });
};
Run Code Online (Sandbox Code Playgroud)


小智 7

这个问题确实让人很困惑。我已经通过简单地添加 async/await 来解决这个问题。这是因为 Vercel 不支持流式响应(即发即忘功能)。

来源: https: //vercel.com/docs/platform/limits#streaming-responses


eno*_*och 2

我已经遇到了同样的问题,nodemailer 无法在 vercel 上工作,但在 heroku 上一切正常。文档中指定 vercel 不会阻止 stmp 连接,但根据我的经验,实际上 stmp 连接被阻止。你能做的就是使用nodemailer的替代品。使用sendgrid,效果很好

关于如何将 Sendgrid 与 Next.js 集成的文章

  • @DanielIoanitescu 我建议您检查 SendGrid 仪表板中的 IP 访问管理部分,SendGrid 必须阻止您的生产部署的 IP,因此可能无法发送电子邮件,您需要允许所有 IP 从 SendGrid 仪表板发送电子邮件以进行 vercel 的部署按预期工作,因为 vercel 部署没有静态 IP,它可以随着应用程序的扩展随时更改。 (2认同)