最近,我决定在一个小项目中尝试使用 vercel,但在使用 sendgrid 和 vercel 时遇到了问题。我之前已经在heroku上将sendgrid实现到了nodejs/express项目中,没有任何问题,但由于某种原因Vercel无法工作。
更糟糕的是,sendgrid 没有给出任何错误,因此很难排除故障。承诺永远悬而未决。测试时本地一切工作正常,并且我已确认环境变量正确并正在加载。
这是我的代码:
const sgMail = require('@sendgrid/mail');
const { magicLinkTemplate } = require('./templates');
const sendEmail = async (msg) => {
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
try {
await sgMail.send(msg)
} catch (error) {
console.error(error);
if (error.response) {
console.error(error.response.body)
}
}
}
我尝试过多次迭代,但每次都失败了。还有其他人在使用 vercel 和 sendgrid 时遇到过问题吗?
好吧,所以我相信我解决了自己的问题。
问题在于 vercel 如何处理无服务器功能:
以前,我运行电子邮件发送作为副作用,API 响应将返回,而无需等待 sendgrid 履行其承诺。下面是我的原始代码的淡化版本。
router.post('/', checkUser)
async function checkUser(req, res, next) {
const { email } = req.body;
const magicLink = generateMagicLink()
sendMagicLink(email, magicLink)
res.status(200).json({})
}
sendMagicLink 函数是异步的,将继续在本地运行,但在 vercel 中,一旦从 api 返回状态,它就会停止。
新代码看起来像这样...
router.post('/', checkUser)
async function checkUser(req, res, next) {
const { email } = req.body;
const magicLink = generateMagicLink()
await sendMagicLink(email, magicLink)
res.status(200).json({})
}
现在,无服务器函数保持活动状态,因为它等待异步进程完成。
这整件事让我很困惑,因为如果你有一个持久的服务器,原始版本就不会有问题。希望这对某人有帮助!
所以我仍然面临同样的问题,我已经尝试了使用 async/await 来 Promises 的所有方法,但似乎没有任何效果,vercel 日志和 SendGrid 都没有显示问题 -
这是我尝试过的 -
import Handlebars from "handlebars";
import fs from "fs";
const sgMail = require("@sendgrid/mail");
export const sendContactEmail = async (inquiryInfo) => {
sgMail.setApiKey(process.env.MAIL_API_KEY);
// Load email templates
const emailTemplateApplyNow = Handlebars.compile(
fs.readFileSync(process.cwd() + "/emails/applynow-email.html", "utf-8")
);
const emailTemplateContactForm = Handlebars.compile(
fs.readFileSync(process.cwd() + "/emails/contact-email.html", "utf-8")
);
const emailSource = inquiryInfo.emailSource;
const {
custRequest,
clientEmail,
clientPhoneNumber,
contactMessage,
data,
custCreditScore,
custGoal,
custDownPayment,
buyingPlan,
mortgageEnd,
fullName,
} = inquiryInfo;
try {
if (emailSource === "Contact Form") {
const msg = {
to: process.env.TO_EMAIL, // Change to your recipient
from: process.env.SENDER_EMAIL, // Change to your verified sender
subject: "From Website - I want to get in touch",
text: "Client Inquiry from the website",
html: emailTemplateContactForm({
fullName,
clientEmail,
clientPhoneNumber,
contactMessage,
}),
};
await new Promise((resolve, reject) => {
// send mail
sgMail.send(msg, (err, info) => {
if (err) {
console.error(err);
reject(err);
} else {
console.log(info);
resolve(info);
}
});
});
return { success: true };
// const sended = await sgMail.send(msg);
// console.log("sended: ", sended);
} else {
const msg = {
to: process.env.TO_EMAIL, // Change to your recipient
from: process.env.SENDER_EMAIL, // Change to your verified sender
subject: "From Website - I want to get in touch",
text: "Client Inquiry from the website",
html: emailTemplateApplyNow({
custRequest,
clientEmail,
clientPhoneNumber,
data,
custGoal,
custDownPayment,
buyingPlan,
mortgageEnd,
custCreditScore,
fullName,
}),
};
// const sended = await sgMail.send(msg);
// console.log("sended: ", sended);
await new Promise((resolve, reject) => {
// send mail
sgMail.send(msg, (err, info) => {
if (err) {
console.error(err);
reject(err);
} else {
console.log(info);
resolve(info);
}
});
});
return { success: true };
}
} catch (err) {
console.error("Error sending email:", err);
}
};
注释掉的await sgMail.send(msg);也不起作用,我当前尝试使用的承诺代码也不起作用。