firebase - 带有 Firebase 云函数错误的 SendGrid:“套接字挂起”
问题描述
我有一个由发布/订阅事件触发的云函数。我使用 sendgrid nodejs api。主要想法是向我的客户发送每周统计电子邮件。sendEmail() 函数为每个客户端运行(80 次)。但是当我检查功能日志时,我看到 25-30 封客户电子邮件发送成功,但其余的却给出了错误:“socket hang up”
我缩短了整个代码以显示与发送电子邮件相关的主要部分。这是最后一部分。
// I shortened the whole function as it is a very long function.
// The main and the last part is as below
// I have nearly 80 clients and sendEmail function run for each client.
function calcData(i, data) {
return admin.database().ref('clientUrlClicks/' + data.key)
.orderByChild('date')
.startAt(dateStartEpox)
.endAt(dateEndEpox)
.once('value', urlClickSnap => {
clients[i].clickTotalWeek = urlClickSnap.numChildren();
clients[i].listTotalWeek = 0;
admin.database().ref('clientImpressions/' + data.key)
.orderByKey()
.startAt(dateStart)
.endAt(dateEnd)
.once('value', snap => {
snap.forEach(function(impressionSnap) {
clients[i].listTotalWeek += impressionSnap.val();
})
}).then(resp => {
return sendEmail(i, clients[i]);
}).catch(err => {
console.log(err);
});
}).catch(err => {
clients[i].clickTotalWeek = 0;
console.log(err);
});
}
function sendEmail(i, data) {
var options = {
method: 'POST',
url: 'https://api.sendgrid.com/v3/mail/send',
headers:
{
'content-type': 'application/json',
authorization: 'Bearer ' + sgApiKey
},
body:
{
personalizations:
[{
to: [{ email: data.email, name: data.name }],
dynamic_template_data:
{
dateStart: xxx,
dateEnd: xxx,
}
}],
from: { email: 'info@xxx.com', name: 'xxx' },
reply_to: { email: 'info@xxx.com', name: 'xxx' },
template_id: 'd-f44eeexxxxxxxxxxxxx'
},
json: true
};
request(options, function (error, response, body) {
if (error) {
console.log("err: " + error);
return;
}
return;
});
}
编辑:
除了以下与“正确链接承诺”相关的答案之外,我还将所有电子邮件和个性化添加到“个性化”数组作为“sendEmail”函数的对象。因此,我对每封电子邮件提出一个请求,而不是提出一个请求。现在没问题。
解决方案
您没有正确链接承诺,因此没有在链接结束时返回最终承诺,这对于云函数是强制性的。
下面的一组修改是解决这个问题的第一次尝试。
此外,您如何调用 Sendgrid 并返回 Sendgrid 调用返回的 Promise 也不是很清楚。我建议您使用send()
返回 Promise 的方法,如适用于 Node.js 的 Sendgrid v3 Web API 文档中所述,请参阅https://github.com/sendgrid/sendgrid-nodejs/tree/master/packages /邮件。
function calcData(i, data) {
//Declare clients aray here
return admin.database().ref('clientUrlClicks/' + data.key)
.orderByChild('date')
.startAt(dateStartEpox)
.endAt(dateEndEpox)
.once('value')
.then(urlClickSnap => {
clients[i].clickTotalWeek = urlClickSnap.numChildren();
clients[i].listTotalWeek = 0;
return admin.database().ref('clientImpressions/' + data.key) //Here you didn't return the promise
.orderByKey()
.startAt(dateStart)
.endAt(dateEnd)
.once('value');
.then(snap => {
snap.forEach(function(impressionSnap) {
clients[i].listTotalWeek += impressionSnap.val();
})
return sendEmail(i, clients[i]);
}).catch(err => {
clients[i].clickTotalWeek = 0;
console.log(err);
return null;
});
}
推荐阅读
- java - QAF 3.0.1b | 将 QAF 从 3.0.0 升级到 3.0.1b 后未选择测试
- firebase - 无法在初始化程序中访问实例成员“id”
- esp32 - 为什么我不能在 micropython env esp32 中运行 c++ 代码
- javascript - 如何在导出常量对象之前等待获取 api 值返回
- p5.js - w、a、s、d 键在使用 p5.js 的蛇游戏中不起作用
- r - R中日期之间的增量天数
- python - tkinter:如何按顺序将字符串列表添加到按钮上的文本中?
- mysql - 指定的文件“sql.txt”不包含可用的 HTTP 请求(带参数)
- android - 播放控制台中的 Flutter ClassNotFoundException (java.lang.RuntimeException) 崩溃错误?
- python - 为什么当我想连接到我的数据库时出现此错误 pymysql.err.OperationalError: (1105, 'direct DDL is disabled')