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不在生产中发送电子邮件的主要内容,如果未能解决你的问题,请参考以下文章
Vercel 中的 Next.js 与 Sentry - 在生产中忽略源映射
NextJS <Link> 在生产中不起作用(Vercel)