Sendgrid 电子邮件在部署到 Vercel 时不会发送

问题描述 投票:0回答:2

最近,我决定在一个小项目中尝试使用 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 时遇到过问题吗?

javascript node.js email sendgrid vercel
2个回答
9
投票

好吧,所以我相信我解决了自己的问题。

问题在于 vercel 如何处理无服务器功能:

  • 如果您使用免费套餐,每个请求必须在 10 秒内解决(专业版为 60 秒)
  • 一旦返回响应,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({})

}

现在,无服务器函数保持活动状态,因为它等待异步进程完成。

这整件事让我很困惑,因为如果你有一个持久的服务器,原始版本就不会有问题。希望这对某人有帮助!


0
投票

所以我仍然面临同样的问题,我已经尝试了使用 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);也不起作用,我当前尝试使用的承诺代码也不起作用。

© www.soinside.com 2019 - 2024. All rights reserved.