简体   繁体   English

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

[英]Sendgrid emails won't send when deployed to Vercel

Recently, I decided to try out vercel for a small project and ran into issues using sendgrid with vercel.最近,我决定为一个小项目尝试 vercel,但在使用 sendgrid 和 vercel 时遇到了问题。 I've implemented sendgrid into nodejs/express projects before on heroku with no issues, but for some reason Vercel just doesn't work.我之前在 heroku 上将 sendgrid 实现到 nodejs/express 项目中没有问题,但由于某种原因 Vercel 无法正常工作。

Even worse, sendgrid gives no errors whatsoever so its been difficult to troubleshoot.更糟糕的是,sendgrid 没有给出任何错误,因此很难排除故障。 The promise just hangs forever. promise 永远挂起。 Everything works fine locally when testing and I've confirmed that env variables are correct and loading.测试时在本地一切正常,我已经确认 env 变量是正确的并且正在加载。

Here's my code:这是我的代码:

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)
        }
    }
}

I've tried a number of iterations, and failed every time.我已经尝试了多次迭代,但每次都失败了。 Has anyone else run into issues using vercel with sendgrid?有没有其他人在使用带有 sendgrid 的 vercel 时遇到问题?

Alright, so I believe I solved my own problem.好吧,所以我相信我解决了自己的问题。

The issue lies in how vercel handles serverless functions:问题在于 vercel 如何处理无服务器功能:

  • If you're on free tier, each request must resolve in 10 seconds (for pro its 60)如果您使用免费套餐,则每个请求必须在 10 秒内解决(专业版 60 秒)
  • Vercel seems to instantly terminate a serverless function once a response is returned, aka side effects that are not finished will cease to run.一旦返回响应,Vercel 似乎会立即终止无服务器 function,即未完成的副作用将停止运行。

Previously, I was running the email sends as a side effect and the api response would return without waiting for sendgrid to fullfil its promise.以前,我运行 email 作为副作用发送,api 响应将返回,而无需等待 sendgrid 完成其 promise。 Below is a watered down version of my original code.下面是我原始代码的淡化版本。


router.post('/', checkUser)

async function checkUser(req, res, next) {
  const { email } = req.body;

  const magicLink = generateMagicLink()

  sendMagicLink(email, magicLink)
  res.status(200).json({})

}

The sendMagicLink function is async and would continue to run locally, but in vercel it would cease once a status was returned from the api. sendMagicLink function 是异步的,将继续在本地运行,但实际上,一旦从 api 返回状态,它将停止。

New code looks like this...新代码看起来像这样......


router.post('/', checkUser)

async function checkUser(req, res, next) {
  const { email } = req.body;

  const magicLink = generateMagicLink()

  await sendMagicLink(email, magicLink)
  res.status(200).json({})

}

Now the serverless function stays alive because it waits for the async process to finish.现在无服务器 function 保持活动状态,因为它等待异步进程完成。

This whole thing tripped me up because if you have a persistent server, there would be no issues with the original version.这整件事让我大吃一惊,因为如果你有一个持久服务器,那么原始版本就不会有问题。 Hope this helps someone!希望这对某人有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM