问题及其发生环境的摘要。 如果合适,请包含重现该错误所需的步骤。 请随意提供屏幕截图,截屏视频和代码示例。
我无法弄清楚如何使用@ sendgrid / inbound-mail-parser程序包解析入站电子邮件。 需要一些示例代码
在sendgrid中设置解析路由(在此处链接:
https://www.dropbox.com/s/cb6lwrmon9qwjzq/Screenshot%202017-10-12%2016.03.49.png?dl=0)
这是发送给ngrok中路线的示例电子邮件的内容:
https://gist.github.com/machinshin/e38cf7d20ec6319edcfda63ff7aca594
我已经将parseroute连接到我的webhook,如下所示:
router.post('/api/email/parseroute', (req, res, next) => {
// have also tried:
router.post('/api/email/parseroute', bodyParser.raw(), (req, res, next) => {
console.log(`-------------`)
console.log(req.body)
console.log(`-------------`)
console.log(req.rawBody)
console.log(`-------------`)
}
如您所见,req.body为空,而req.rawBody为“未定义”
因此,我不清楚如何访问原始电子邮件数据,也不清楚如何处理该数据以及如何实例化入站邮件解析器。
您要共享的与报告的问题有关的任何其他信息。 特别是,为什么您认为这是一个错误? 您期望发生什么呢?
你好@machinshin ,
感谢您抽出宝贵时间报告此问题。 我已将此添加到我们的积压待进一步调查。
例子有更新吗? 我确实需要使用此解析器,但是我不知道该怎么做。
SendGrid将其JSON入站解析数据作为表单/多部分数据发送。 由于body-parser不会处理该格式,因此req.body不会立即访问它。 我会用multer作为替代。
@ shishido92您能否扩展一个很好的示例。 似乎没有使用nodejs解析任何入站电子邮件的文档。 谢谢!
@stephenfjohnson @machinshin如果您使用expressjs,这可能会有所帮助
app.use(express.json({limit: '10mb'}));
app.use(express.urlencoded({
extended: true,
type: "multipart/form-data",
limit: '10mb'
}));
app.post('/endpoint', function (req, res, next) {
// req.body contains the text fields
console.log(req.body);
console.log('body' + req.body);
res.status(200).json('ok');
})
这样做将在请求正文中为您提供请求的内容。
但是,这会忽略附件。
@nathfreder我们在问题摘要中使用竖起大拇指的反应作为优先级的一部分。 请在顶部加👍。
@ childish-sambino, @ satyajeetjadhav👍
迟到比从来没有迟到;)
感谢您的更新,关闭此问题
我知道这个问题已经解决,但是我已经发现了这个问题,并且表示对入站邮件解析器的工作表示满意。 我需要做的主要事情是使用multer库处理multipart / form-data输入,然后使用@ sendgrid / inbound-mail-parser库的keyValues()方法,如下所示
在multer和Sendgrid中要求:
const multer = require('multer');
const upload = multer();
const mailParse = require('@ sendgrid / inbound-mail-parser');
在我的路由器声明中的POST方法中,使用upload.none()方法,因为我只是在获取文本(无附件):
router.post('/ mail',upload.none(),function(req,res,next)
然后,在该POST定义中,我使用keyValues()方法获取电子邮件的相关部分:
尝试{
const config = {keys:['to','from','subject','text',]};
const parsing = new mailParse(config,req.body);
让响应= parsing.keyValues();
让到= response.to;
让来自= response.from;
让subject = response.subject;
让messageBody = response.text
console.log('这是邮件的主题:',subject);
}
希望这是有用的。
大家好,有人可以分享一个如何解析附件的示例吗? 我使用的是相同的配置,但是附件来自无法读取的字符串
const app = express();
app.use(cors);
app.use(busboy());
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies.
app.use(bodyParser.json({limit: '5mb'}));
router.post('', upload.any(),function(req, res) {
// console.log(req.body);
// console.log(req.files);
// res.send(req.body);
const config = {keys: ['to', 'from', 'subject', 'text','attachments']};
const parsing = new mailParse(config, req.body);
let response = parsing.keyValues();
let to = response.to;
let from = response.from;
let subject = response.subject;
let messageBody = response.text
console.log('This is the subject from the mail: ', response);
res.send(200);
});
@ jhorsfield-tw发布的代码非常有帮助,因为@sendgrid/inbound-mail-parser
没有文档,但是对我来说并不起作用。 mailParse
的构造函数将request
作为参数而不是请求正文。
const parsing = new mailParse(config, req);
嗨@ZeroCho ,
我们确实有一个包裹在这里,但遗憾的是没有很好的使用文档。 为此,您可能想签出Python Inbound Parser 。
最诚挚的问候,
埃尔默
因此,您应该然后编写文档。
怎么还没有记载
仍然无法通过nodejs express解决...
重新打开,因为在文档中仍然没有此示例。
欢迎添加此功能的请求请求,并将根据优先级进行审查,但是Twilio SendGrid并未积极为该库构建新功能。
试图接收附件,但仍然没有运气...
试图接收附件,但仍然没有运气...
使用RAW
const config = {
keys: ['to', 'from', 'subject', 'text', 'attachments']
};
const parsedMail = new parse(config, req); // req is https.Request type
parsedMail.getRawEmail((rawMail: any) => {
console.log(rawMail); // returns null or {}
}
parsedMail.attachments((attachmentData: Attachment[]) => {
console.log('attachments1:'); // returns [ ]
console.log(attachmentData);
console.log(JSON.stringify(attachmentData));
});
我正在尝试但没有运气...它返回一个空对象,当我做.attachments()
我也得到一个空数组。
我正在使用Firebase云功能,使用入站邮件解析器没有任何成功,并且我希望有一些文档可以帮助我使用该库...
但是使用busboy(并在Sendgrid设置中取消选择“原始”)运行良好,除了一个导致我尝试使用mailparser的问题...
Sendgrid会在“字符集”字段中列出不同的编码,如下所示:
来自Gmail的电子邮件:
{“至”:“ UTF-8”,“ html”:“ UTF-8”,“主题”:“ UTF-8”,“来自”:“ UTF-8”,“文本”:“ UTF-8” }
来自Outlook的电子邮件:
{“ to”:“ UTF-8”,“ html”:“ iso-8859-1”,“ subject”:“ UTF-8”,“ from”:“ UTF-8”,“ text”:“ iso- 8859-1“}
当电子邮件包含国际字符(例如ÆØÅ)时,结果是text和html字段包含问号而不是实际的北欧字符。
如果我将busboy上的defCharset更改为Windows-1252,则文本和html值将正确显示,但其他字段将显示错误。
邮件解析器还会出现问题吗?还是邮件解析器会处理字段上的不同编码?
我对有兴趣的人使用busboy进行解析的代码:
(如果有人能告诉我我如何使用busboy解决上述问题,我将不胜感激。)
Exports.sendgridparse =函数。https.onRequest((req,res)=> {
const path = require('path');
const os = require('os');
const fs = require('fs');
const Busboy = require('busboy');
if (req.method !== 'POST') {
// Return a "method not allowed" error
return res.status(405).end();
}
const busboy = new Busboy({ headers: req.headers });
const fields = {};
busboy.on('field', function(fieldname, value, fieldnameTruncated, valTruncated, encoding, mimetype){
console.log('Busboy fild [' + fieldname + ']: value: ' + val);
fields[fieldname] = value;
});
让imageToBeUploaded = {};
让imagestoupuped = [];
让imageFileName;
busboy.on('file',(fieldname,file,filename,encoding,mimetype)=> {
console.log(字段名,文件,文件名,编码,mimetype);
file.on('data',function(data){
console.log('文件['+字段名+']得到了'+ data.length +'字节');
});
file.on('end',function(){
console.log('文件['+字段名+']已完成');
});
const imageExtension = filename.split('。')[filename.split('。')。length-1];
imageFileName = ${Math.round(Math.random() * 1000000000000).toString()}.${imageExtension}
;
const filepath = path.join(os.tmpdir(),imageFileName);
const url = https://firebasestorage.googleapis.com/v0/b/${environment.firebase.storageBucket}/o/${imageFileName}?alt=media
;
imageToBeUploaded = {文件路径,mimetype,imageFileName,imageExtension,url};
imagestobeuploaded.push(imageToBeUploaded);
file.pipe(fs.createWriteStream(filepath));
});
busboy.on('finish',async()=> {
//所有字段都可用(imagestobeuploaded和字段)并且可以保存到数据库
res.send(200);
});
busboy.end(req.rawBody);
});
@hhetland那么,您能够使用
@matheustavaresdev-是的,我正在使用
首先,将它们保存到busboy.on('file')中的tmp文件夹中,然后使用变量“ imagestobeuploaded”中的信息,将其保存到busboy.on('finish')中的firebase中的存储桶中。
太好了,谢谢!!!!!!!!!!!!
2020年4月,仍然没有官方文档,对不对?
我知道这个问题已经解决,但是我已经发现了这个问题,并且表示对入站邮件解析器的工作表示满意。 我需要做的主要事情是使用multer库处理multipart / form-data输入,然后使用@ sendgrid / inbound-mail-parser库的keyValues()方法,如下所示
在multer和Sendgrid中要求:
const multer = require('multer');
const upload = multer();
const mailParse = require('@ sendgrid / inbound-mail-parser');在我的路由器声明中的POST方法中,使用upload.none()方法,因为我只是在获取文本(无附件):
router.post('/ mail',upload.none(),function(req,res,next)
然后,在该POST定义中,我使用keyValues()方法获取电子邮件的相关部分:
尝试{
const config = {keys:['to','from','subject','text',]};
const parsing = new mailParse(config,req.body);
让响应= parsing.keyValues();
让到= response.to;
让来自= response.from;
让subject = response.subject;
让messageBody = response.text
console.log('这是邮件的主题:',subject);
}希望这是有用的。
我发现,request.body位于表单数据中,并看到一个错误:
[嵌套] 24687-2020年5月1日,下午1:29:51 [ExceptionsHandler]减少没有初始值的空数组
TypeError:减少没有初始值的空数组
在Array.reduce(
代码:
keyValues(){
返回this.keys
.filter(key => this.payload [key])
.map(key =>({[key]:this.payload [key]}))
.reduce((keyValues,keyPayload)=> Object.assign(keyValues,keyPayload));
}
返回错误,因为this.payload不是结构化数据,而是多部分表单数据。
我无法使用nest-js进行此操作。 我在NestJS控制器中收到的webhook数据是多格式数据。 我不确定在这种情况下如何使用Multer。
external.post('/ mail',upload.none(),function(req,res,next)
我尝试这样做:
export class MultiformParser implements NestMiddleware {
async use(req: Request, res: Response, next: Function) {
console.log("before: ", req.body)
var upload = multer();
await new Promise((resolve, reject) => {
upload.none()(req, res, err => {
if (err) {
console.log(err)
reject(err)
} else {
resolve()
console.log("request: ", req.body)
}
});
});
console.log("after: ", req.body)
next();
}
}
但是,req.body返回:
request: [Object: null prototype] {}
之前会打印出多种格式的数据。
这是我必须进行的更改,以便可以使用multer:
app.use(express.json())
app.use(express.urlencoded({extended:true}));
const upload = multer();
app.use(upload.none());
完成此操作后,便可以使用multer将webhook数据解析为
结构化键,值对。
2020年5月24日星期日,下午4:51 Danish Mohd [email protected]
写道:
如果您使用的是无服务器(Google云功能或Firebase)
这可能会有所帮助:
https://stackoverflow.com/questions/47242340/how-to-perform-an-http-file-upload-using-express-on-cloud-functions-for-firebase/48648805#48648805使用Formidable在无服务器上解析多部分:
https://github.com/DanisHack/formidable-serverless—
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub上查看
https://github.com/sendgrid/sendgrid-nodejs/issues/482#issuecomment-633312295 ,
或退订
https://github.com/notifications/unsubscribe-auth/AB2ATHHFKBRZZDGGJ2D7SOLRTGQHNANCNFSM4D67CVZQ
。
-
Shweta Bhandare博士| 首席软件工程师
https://hicleo.com/
hicleo.com | Linkedin https://www.linkedin.com/company/hicleo/ | 推特
https://twitter.com/hi_cleo/ | Instagram的
https://www.instagram.com/hicleo.co/ | 脸书
https://www.facebook.com/hicleolabs
-
此消息可能包含机密,专有或受保护的信息。
如果您错误地收到此消息,请通过回复电子邮件通知发件人并删除此消息。
我们花了很多时间试图使它与Busboy一起在Google Cloud Functions中工作,无论我们遵循什么教程或指针,都无法实现。
因此,在有一定灵活性的情况下,我将把这个留给下一个人:使用Python Inbound Parser 。 他们提供的代码几乎是一份复制/粘贴工作,并且花费了不到一个小时的时间才能使其运行。
我知道这并不能解决这里的问题,但是我希望它可以节省其他人的麻烦。
我很高兴,我发现这张票......我快要疯了试图找到一些这方面的资料,并以某种方式是没有的。
我真的很困惑。 我只是假设会有标准的文档-特别是因为它是开源的,但它由SendGrid(并且最终是Twilio,它具有出色的文档)支持。
对于这样简单的事情,您可能会想到至少会有一个例子。
尽管如此,对于遇到这个问题的任何人...
我建议改用MailParser 。
我很确定这是在后台使用的,但是至少MailParser拥有大量文档。 只需确保在入站解析设置中已检查POST the raw, full MIME message
,如下所示(_wow,一个example_)。
通过阅读MailParser文档,我在几分钟内就完成了:
import { Request, Response } from "express";
import { simpleParser } from "mailparser";
export const inboundEmails = async (req: Request, res: Response) => {
const parsedEmail = await simpleParser(req.body.email);
console.log("subject", parsedEmail.subject);
console.log("from", parsedEmail.from);
console.log("to", parsedEmail.to);
console.log("cc", parsedEmail.cc);
console.log("bcc", parsedEmail.bcc);
console.log("date", parsedEmail.date);
console.log("messageId", parsedEmail.messageId);
console.log("inReplyTo", parsedEmail.inReplyTo);
console.log("replyTo", parsedEmail.replyTo);
console.log("references", parsedEmail.references);
console.log("html", parsedEmail.html);
console.log("text", parsedEmail.text);
console.log("textAsHtml", parsedEmail.textAsHtml);
console.log("attachments", parsedEmail.attachments);
res.sendStatus(200);
};
所有数据都是您想要的。
我还使用Multer中间件来分析SendGrid POST到我的端点的多部分/表单数据。
在您的中间件流中,它就像multer().any()
一样简单。
干杯
我使用了原始的完整MIME消息,并使其与simpleParser一起使用,但是我切换回了已处理的版本,并使用了sengrid的inbound-mail-parser,因为simpleParser不能很好地将MIME转换为文本和html。
绝对需要一些文档。
@theweiweiway您是否介意发布一个示例,说明这两种方法在文本和html方面的区别? 我没有发现任何差异,我很好奇。
用于文字
Hi 123 Hi 123 Hi 123 www.hello.com
与
Hi 123 Hi 123 Hi 123 www. <http://www.hello.com/>hello <http://www.hello.com/>.com <http://www.hello.com/>
^不知道为什么会这样
对于html
<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi 123<div class=""><b class="">Hi 123</b></div><div class=""><b class=""><u class="">Hi 123</u></b></div><div class=""><b class=""><u class="">www.</u>hello</b>.com</div></body></html>
与
<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">Hi 123</span><div class="" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);"><b class="">Hi 123</b></div><div class="" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);"><b class=""><u class="">Hi 123</u></b></div><div class="" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);"><b class=""><u class=""><a href="http://www.hello.com" class="">www.</a></u><a href="http://www.hello.com" class="">hello</a></b><a href="http://www.hello.com" class="">.com</a></div></body></html>
我认为这与simpleParser软件包有关
这是我使用repress / multer的repo express-sendgrid-inbound-parse 。 这是一个易于上手的应用程序。 我建议不要选中POST the raw, full MIME message
因为您可以访问更多电子邮件数据。
console.log('dkim: ', body.dkim)
console.log('to: ', body.to)
console.log('cc: ', body.cc)
console.log('from: ', body.from)
console.log('subject: ', body.subject)
console.log('sender_ip: ', body.sender_ip)
console.log('spam_report: ', body.spam_report)
console.log('envelope: ', body.envelope)
console.log('charsets: ', body.charsets)
console.log('SPF: ', body.SPF)
console.log('spam_score: ', body.spam_score)
if (rawFullMimeMessageChecked) {
console.log('email: ', body.email)
} else {
console.log('headers: ', body.headers)
console.log('html: ', body.html)
console.log('text: ', body.text)
console.log('attachments: ', body.attachments)
console.log('attachment-info: ', body['attachment-info'])
console.log('content-ids: ', body['content-ids'])
}
在firebase的云功能上尝试了这个。
绝对不要工作。
还有其他解决方案吗?
最有用的评论
因此,您应该然后编写文档。