如何在 firebase 函数上获取传入的 sendgrid 电子邮件
How to get incoming sendgrid email on firebase functions
我有一个 firebase 函数,我将其用作 sendgrid 的入站解析 webhook 的 webhook。因此,这意味着无论何时向我的域发送电子邮件,它都会调用 webhook。我知道正在调用 webhook,但我无法获取 Sendgrid 发送的数据。 This link 声明所有信息(文本、发件人等)都应该在 headers 中。但是,当我打印出 req.headers
时,我得到了这个:
{ host: 'us-central1-project-name.cloudfunctions.net',
'user-agent': 'Sendlib/1.0 server.sendgrid.net',
'transfer-encoding': 'chunked',
'content-type': 'multipart/form-data; boundary=xYzZY',
forwarded: 'for="ip";proto=https',
'function-execution-id': 'id',
'x-appengine-city': '?',
'x-appengine-citylatlong': '0.000000,0.000000',
'x-appengine-country': 'US',
'x-appengine-default-version-hostname': ~~~~~~~~~~~~~.appspot.com',
'x-appengine-https': 'on',
'x-appengine-region': '?',
'x-appengine-request-log-id': 'super-long-id',
'x-appengine-user-ip': 'ip',
'x-cloud-trace-context': 'id/number;o=1',
'x-forwarded-for': 'ip',
'x-forwarded-proto': 'https',
'accept-encoding': 'gzip',
connection: 'close' }'
(显然我替换了所有 ID 和所有内容)
电子邮件信息在哪里?我已尝试执行以下所有操作,其中 none 生成了有关电子邮件的任何信息。
exports.reciever = functions.https.onRequest((req, res) => {
try {
console.log("Email recieved");
console.log(req);
console.log(req.headers);
console.log(req.header.to);
console.log(req.body);
console.log(req.get('to'));
console.log(req.body.to);
console.log(req.rawBody);
console.log(req.query);
console.log(req.query.to);
console.log(req.params);
console.log(req.path);
console.log(req.rawBody);
} catch (e) {}
finally {
res.send("2xx");
}
})
所以,事实证明它其实非常非常简单。添加
.toString()
在 req.body
或 req.rawBody
对象的末尾。
该问题是关于在无服务器环境(AWS Lambda、Firebase/Google Cloud Functions 等)和已处理请求的环境中使用。使用 MIME 解析电子邮件不是一个好主意。
因此,这是我的解决方案:
import * as functions from 'firebase-functions';
import * as express from 'express';
const formidable = require('formidable-serverless');
export class InboundEmail {
constructor(from, subject, text, html, to) {}
doStrategy() {
//Store inbound email
//Send outbound email
//...
}
}
export class EmailPostWebHook {
private form = new formidable.IncomingForm();
private incomeEmail: IncomeEmail;
async run(request: express.Request, res: express.Response) {
try {
this.parse(request);
await this.incomeEmail.doStrategy();
} catch (e) {
console.log(e);
}
return res.sendStatus(200);
}
private parse(request: express.Request) {
this.form.parse(request, (errors: any, fields: any) => {
this.incomeEmail = new IncomeEmail(
fields.from
fields.subject,
fiels.text
fields.html,
fields.to
);
});
}
}
const app = express();
const emailPostWebHook = new EmailPostWebHook();
app.post('/', emailPostWebHook.run.bind(emailPostWebHook));
export const InboundEmailHook = functions
.runWith({
timeoutSeconds: 30,
memory: '2GB',
})
.https.onRequest(app);
package.json
{
"name": "temp",
"main": "lib/index.js",
"dependencies": {
"express": "^4.17.1",
"firebase": "^7.15.1",
"firebase-admin": "^8.12.1",
"firebase-functions": "^3.7.0",
"formidable-serverless": "^1.0.3"
},
"devDependencies": {
"@firebase/firestore-types": "^1.11.0",
"@types/node": "^14.0.13",
"@types/express": "^4.17.6",
"tslint": "^6.1.2",
"typescript": "^3.9.5"
},
"engines": {
"node": "10"
},
"private": true
}
参考文献:
我终于设法通过在 functions-directory 中安装 Busboy 然后使用此处提供的代码来让它工作:
我有一个 firebase 函数,我将其用作 sendgrid 的入站解析 webhook 的 webhook。因此,这意味着无论何时向我的域发送电子邮件,它都会调用 webhook。我知道正在调用 webhook,但我无法获取 Sendgrid 发送的数据。 This link 声明所有信息(文本、发件人等)都应该在 headers 中。但是,当我打印出 req.headers
时,我得到了这个:
{ host: 'us-central1-project-name.cloudfunctions.net',
'user-agent': 'Sendlib/1.0 server.sendgrid.net',
'transfer-encoding': 'chunked',
'content-type': 'multipart/form-data; boundary=xYzZY',
forwarded: 'for="ip";proto=https',
'function-execution-id': 'id',
'x-appengine-city': '?',
'x-appengine-citylatlong': '0.000000,0.000000',
'x-appengine-country': 'US',
'x-appengine-default-version-hostname': ~~~~~~~~~~~~~.appspot.com',
'x-appengine-https': 'on',
'x-appengine-region': '?',
'x-appengine-request-log-id': 'super-long-id',
'x-appengine-user-ip': 'ip',
'x-cloud-trace-context': 'id/number;o=1',
'x-forwarded-for': 'ip',
'x-forwarded-proto': 'https',
'accept-encoding': 'gzip',
connection: 'close' }'
(显然我替换了所有 ID 和所有内容)
电子邮件信息在哪里?我已尝试执行以下所有操作,其中 none 生成了有关电子邮件的任何信息。
exports.reciever = functions.https.onRequest((req, res) => {
try {
console.log("Email recieved");
console.log(req);
console.log(req.headers);
console.log(req.header.to);
console.log(req.body);
console.log(req.get('to'));
console.log(req.body.to);
console.log(req.rawBody);
console.log(req.query);
console.log(req.query.to);
console.log(req.params);
console.log(req.path);
console.log(req.rawBody);
} catch (e) {}
finally {
res.send("2xx");
}
})
所以,事实证明它其实非常非常简单。添加
.toString()
在 req.body
或 req.rawBody
对象的末尾。
该问题是关于在无服务器环境(AWS Lambda、Firebase/Google Cloud Functions 等)和已处理请求的环境中使用。使用 MIME 解析电子邮件不是一个好主意。 因此,这是我的解决方案:
import * as functions from 'firebase-functions';
import * as express from 'express';
const formidable = require('formidable-serverless');
export class InboundEmail {
constructor(from, subject, text, html, to) {}
doStrategy() {
//Store inbound email
//Send outbound email
//...
}
}
export class EmailPostWebHook {
private form = new formidable.IncomingForm();
private incomeEmail: IncomeEmail;
async run(request: express.Request, res: express.Response) {
try {
this.parse(request);
await this.incomeEmail.doStrategy();
} catch (e) {
console.log(e);
}
return res.sendStatus(200);
}
private parse(request: express.Request) {
this.form.parse(request, (errors: any, fields: any) => {
this.incomeEmail = new IncomeEmail(
fields.from
fields.subject,
fiels.text
fields.html,
fields.to
);
});
}
}
const app = express();
const emailPostWebHook = new EmailPostWebHook();
app.post('/', emailPostWebHook.run.bind(emailPostWebHook));
export const InboundEmailHook = functions
.runWith({
timeoutSeconds: 30,
memory: '2GB',
})
.https.onRequest(app);
package.json
{
"name": "temp",
"main": "lib/index.js",
"dependencies": {
"express": "^4.17.1",
"firebase": "^7.15.1",
"firebase-admin": "^8.12.1",
"firebase-functions": "^3.7.0",
"formidable-serverless": "^1.0.3"
},
"devDependencies": {
"@firebase/firestore-types": "^1.11.0",
"@types/node": "^14.0.13",
"@types/express": "^4.17.6",
"tslint": "^6.1.2",
"typescript": "^3.9.5"
},
"engines": {
"node": "10"
},
"private": true
}
参考文献:
我终于设法通过在 functions-directory 中安装 Busboy 然后使用此处提供的代码来让它工作: