Netlify部署后Postmark仅发首封邮件问题求助(Node.js)
问题:Netlify部署后Postmark仅发送部分邮件(开发环境正常)
我有一个包含3阶段预订表单的网站,每个阶段需要通过Postmark发送2-3封邮件。该功能在开发环境正常工作,但部署到Netlify后,每个阶段仅发送1封邮件(总共只投递3封,而非预期的7封)。我对Node.js并不精通,怀疑问题出在.then代码部分,恳请提供反馈与建议!
*注:以下是第一阶段代码,所有阶段格式一致。我了解可使用Postmark批量发送,但表单第三阶段需用不同模板,需单独调用client.sendEmailWithTemplate,且邮件数量少,故全阶段采用此方式。
// Require: var postmark = require("postmark"); // Send an email: var client = new postmark.ServerClient(process.env.POSTMARK_AUTH); //function to validate token with google re-captcha async function validateHuman(token){ const secret = process.env.GATSBY_RECAPTCHA_SECRET; const response = await fetch(`https://www.google.com/recaptcha/api/siteverify?secret=${secret}&response=${token}`, { method: "POST", } ) const data = await response.json(); return data.success; } //main function export default async(req, res) => { res.setHeader('Access-Control-Allow-Origin', '*'); console.log(req.body); //call re-captcha validation function const human = await validateHuman(req.body.token); if (!human){ // console.log("this message shows we're getting to the !human part") res.status(400); res.json({errors: ["Please, you're not fooling us, bot."]}) return; } try { let message = { "From": "*clientemail", "To": "*clientemail", "ReplyTo": "*clientemail", "TemplateId" : 36706722, "TemplateModel": { "name": req.body.name, "email": req.body.email, "phone": req.body.phone, "message": req.body.message }, "MessageStream": "outbound" } //send emails if human client.sendEmailWithTemplate(message).then( () => { //I update email template here too in later form stage console.log("customer-support-sent") message.To = "daniel@thoughtfulhq.com" message.ReplyTo = req.body.email client.sendEmailWithTemplate(message) } ).then( () => { console.log("client-support-sent") // message.To = "daniel@thoughtfulhq.com" // console.log(message) // client.sendEmailWithTemplate(message) } ).then( () => { console.log("backup-support-sent") return res.status(200).json({ message: "This is updated", }) } ) } catch (err) { console.log(err) return res.status(500).json({ message: "There was an error", error: err }) } }
问题分析与解决方案
核心问题
- Promise未返回导致流程异步失控:你在
.then回调中调用client.sendEmailWithTemplate时,没有返回这个Promise,导致后续.then会直接执行,而非等待当前邮件发送完成。 - Netlify函数提前终止:最后一个
.then直接返回了响应,Netlify会立即终止函数进程,后续未完成的邮件发送请求会被强制中断,这就是为什么仅第一封邮件能成功发送。
修复方案:用async/await替代链式.then
你的主函数已经是async类型,完全可以利用await让邮件发送顺序执行,确保所有邮件发送完成后再返回响应,避免进程提前终止。
修改后的核心代码:
try { let message = { "From": "*clientemail", "To": "*clientemail", "ReplyTo": "*clientemail", "TemplateId" : 36706722, "TemplateModel": { "name": req.body.name, "email": req.body.email, "phone": req.body.phone, "message": req.body.message }, "MessageStream": "outbound" } // 发送第一封邮件,等待完成 await client.sendEmailWithTemplate(message); console.log("customer-support-sent"); // 修改配置发送第二封,等待完成 message.To = "daniel@thoughtfulhq.com"; message.ReplyTo = req.body.email; await client.sendEmailWithTemplate(message); console.log("client-support-sent"); // 若有第三封,继续用await发送 // message.To = "xxx@example.com"; // await client.sendEmailWithTemplate(message); // console.log("backup-support-sent"); // 所有邮件发送完成后再返回响应 return res.status(200).json({ message: "This is updated", }); } catch (err) { console.log(err); return res.status(500).json({ message: "There was an error", error: err }); }
关键修复点
await会等待每一个邮件发送的Promise完成,保证顺序执行且全部发送完毕。- 仅在所有邮件发送成功后返回响应,避免Netlify提前终止函数。
async/await写法比链式.then更直观,更易排查Promise遗漏问题。
额外建议
- 可将邮件发送逻辑封装为独立函数,减少三个阶段的重复代码。
- 若允许单封邮件失败不影响整体流程,可给单个发送请求添加独立的
try/catch捕获错误。
内容的提问来源于stack exchange,提问作者Daniel Balloch
相关产品推荐
相关产品推荐

