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

Posted

技术标签:

【中文标题】Vercel中的Nodemailer不在生产中发送电子邮件【英文标题】:Nodemailer in vercel not sending email in production 【发布时间】:2021-04-14 07:22:41 【问题描述】:

我正在使用 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");
    
);

更新

我更改为 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)
);

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

【问题讨论】:

您找到解决方案了吗?我遇到了同样的问题,当每件事情在开发中都能正常工作但在生产中产生问题时,这令人沮丧 我最终使用了 sendgrid。尝试使父函数异步并将等待添加到 sendgrid,如下所示:await sgMail.send(msg) ......让我知道它是否适合你。 是的,我也是这样做的,从 nodemailer 转移到 sendgrid,它工作正常,而不是我使用的异步等待,然后按照他们的文档捕获 sendgrid 【参考方案1】:

我已经遇到过同样的问题,nodemailer 没有在 vercel 上工作,但在 heroku 上一切正常。在文档中指定 vercel 不会阻止 stmp 连接,但根据我的经验,实际上 stmp 连接被阻止。你可以做的是使用 nodemailer 的替代品。使用 sendgrid,它工作正常

An article on how integrating Sendgrid with Next.js

【讨论】:

所以我听从了您的建议,在 SendGrid 上创建了一个帐户,创建了一个 APIKey,而不是上面的代码,我写了这个:github.com/sendgrid/sendgrid-nodejs/tree/main/packages/…。同样的事情,没有错误,一切正常,但没有收到邮件。即使在 SendGrid 仪表板中,我也找不到任何活动。你知道发生了什么吗?我正在更新我最初的帖子,以便您更好地理解... 您能否在 api 上通过控制台记录该响应并查看发生了什么? @DanielIoanitescu 我建议您从 SendGrid 仪表板检查 IP 访问管理部分,SendGrid 必须阻止您的生产部署的 IP,因此它可能无法发送电子邮件,您需要允许所有 IP从 SendGrid 仪表板发送电子邮件以使 vercel 的部署按预期工作,因为 vercel 部署没有静态 IP,它可以随着您的应用程序扩展而随时更改。【参考方案2】:

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

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

【讨论】:

是的,我不久前还为 sendGrid 示例添加了 async/await。问题是 sendGrid 在垃圾邮件文件夹中发送电子邮件。 Nodemailer 发送到收件箱,但不能与 Vercel 一起使用。现在不知道该做什么,该选择什么,可能我会尝试其他服务,直到找到可以正常工作的东西。【参考方案3】:

我遇到了这个问题并设法修复它并通过添加带有 async/await 的 Promise 继续使用 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" );
;

【讨论】:

它对我有用,谢谢:)【参考方案4】:

我在使用 Nodemailer 时遇到了类似的问题,但我通过首先在 Vercel 中添加环境变量然后提交到 github 来修复它(它将自动上传到 vercel)。所以先将变量添加到vercel中才能生效

【讨论】:

这是对我有用的解决方案,很高兴你分享了它。在 Varcel 仪表板中添加 env 变量而不是使用 (.env) 将允许 API 获取值,因为它们对 API 是隐藏的,因为它没有被推送到 git,这就是 Varcel 无法访问这些变量的原因。

以上是关于Vercel中的Nodemailer不在生产中发送电子邮件的主要内容,如果未能解决你的问题,请参考以下文章

使用 nodemailer 的 Cpanel 电子邮件

Vercel 中的 Next.js 与 Sentry - 在生产中忽略源映射

无法在 vercel 生产中验证 spotify

NextJS <Link> 在生产中不起作用(Vercel)

防病毒软件正在阻止 nodemailer - 错误:证书链中的自签名证书

将变量传递给nodemailer中的html模板