Sendgrid-nodejs: inbound-mail-parserを使用して受信メールを解析する例

作成日 2017年10月13日  ·  35コメント  ·  ソース: sendgrid/sendgrid-nodejs

問題の概要

問題の要約とそれが発生する環境。 必要に応じて、バグを再現するために必要な手順を含めます。 スクリーンショット、スクリーンキャスト、コード例を自由に含めてください。

@ 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は「未定義」です。
したがって、生の電子メールデータにアクセスする方法、後でそのデータをどう処理するか、およびinbound-mail-parserをインスタンス化する方法がわかりません。

報告されている問題に関連する、共有したいその他の情報。 特に、なぜこれをバグだと思いますか? 代わりに何が起こると思いますか?

技術的な詳細:

  • sendgrid-nodejsバージョン:6.1.4(最新のコミット:4c6d1cc)
  • Node.jsバージョン:4.1.2
    "@ sendgrid / inbound-mail-parser": "^ 6.1.4"、
    "@ sendgrid / mail": "^ 6.1.4"、
easy help wanted docs update

最も参考になるコメント

こんにちは@ZeroCho

ここにパッケージがありますが、残念ながら、適切な使用法のドキュメントはありません。 そのためには、 Python InboundParserを確認することをお勧めします。

敬具、

エルマー

したがって、ドキュメントを作成する必要があります。

全てのコメント35件

こんにちは@machinshin

これを報告するために時間を割いていただきありがとうございます。 さらなる調査のために、これをバックログに追加しました。

例の更新はありますか? 私は本当にこのパーサーを使用する必要がありますが、その方法がわかりません。

こんにちは@ZeroCho

ここにパッケージがありますが、残念ながら、適切な使用法のドキュメントはありません。 そのためには、 Python InboundParserを確認することをお勧めします。

敬具、

エルマー

SendGridは、JSONインバウンド解析データをフォーム/マルチパートデータとして送信します。 body-parserはその形式を処理しないため、これはreq.bodyによってすぐにはアクセスされません。 代わりにmulterを使用します。

@ shishido92それを行う方法の良い例を拡張して

@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👍

遅くなるより遅く;)
更新していただきありがとうございます。この問題を解決します

これがクローズされたことは知っていますが、この問題を発見したばかりで、inbound-mail-parserが機能していることを表明しました。 私がしなければならなかった主なことは、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);
応答=解析します。keyValues();
let to = response.to;
let from = response.from;
サブジェクト= response.subject;
messageBody = response.textとします
console.log( 'これはメールの件名です:'、件名);
}

それがお役に立てば幸いです。

みなさん、こんにちは。誰かが添付ファイルを解析する方法の例を共有できますか? 同じ設定を使用していますが、添付ファイルが判読できない文字列になっています


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 InboundParserを確認することをお勧めします。

敬具、

エルマー

したがって、ドキュメントを作成する必要があります。

これはまだ文書化されていないのですか

それでもnodejsexpressではそれを理解できません...

ドキュメントにこの例がまだないため、再度開きます。

この機能を追加するプルリクエストは歓迎されており、優先度に基づいてレビューされますが、TwilioSendGridはライブラリの新しい機能を積極的に構築していません。

添付ファイルを受信しようとしていますが、それでも運がありません...

添付ファイルを受信しようとしていますが、それでも運がありません...

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設定で「raw」の選択を解除する)ことは非常にうまく機能していますが、mailparserを使おうとする1つの問題を除いて...

Sendgridは、次のように「charsets」フィールドにさまざまなエンコーディングを一覧表示します。
Gmailからのメール:
{"to": "UTF-8"、 "html": "UTF-8"、 "subject": "UTF-8"、 "from": "UTF-8"、 "text": "UTF-8" }
Outlookからのメール:
{"to": "UTF-8"、 "html": "iso-8859-1"、 "subject": "UTF-8"、 "from": "UTF-8"、 "text": "iso- 8859-1 "}

電子メールに国際文字(ÆØÅなど)が含まれていると、テキストフィールドとhtmlフィールドに実際の北欧文字ではなく疑問符が含まれることになります。

busboyのdefCharsetをWindows-1252に変更すると、テキストとhtmlの値は正しく表示されますが、他のフィールドは正しく表示されません。

これはメールパーサーでも問題になりますか、それともメールパーサーはフィールドで異なるエンコーディングを処理しますか?

興味のある人のためにbusboyを使用して解析するための私のコード:
(誰かが私がbusboyを使って上記の問題をどのように解決するか教えてくれるなら、私は感謝するでしょう..)

exports.sendgridparse = Functions.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 = {};
画像をアップロードする= [];
imageFileName;

busboy.on( 'file'、(fieldname、file、filename、encoding、mimetype)=> {
console.log(フィールド名、ファイル、ファイル名、エンコーディング、mimetype);

file.on( 'data'、function(data){
console.log( 'File [' + fieldname + '] got' + data.length + 'bytes');
});
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 = {filepath、mimetype、imageFileName、imageExtension、url};
imagestobeuploaded.push(imageToBeUploaded);
file.pipe(fs.createWriteStream(filepath));
});

busboy.on( 'finish'、async()=> {
//すべてのフィールド(アップロードされる画像とフィールド)が利用可能であり、dbに保存できます
res.send(200);
});
busboy.end(req.rawBody);
});

@hhetlandでは、

@ matheustavaresdev-はい、busboyを使用してファイルを取得しています。

まず、busboy.on( 'file')のtmpフォルダーに保存し、次に変数 "imagestobeuploaded"の情報を使用して、busboy.on( 'finish')のfirebaseのストレージバケットに保存します。

素晴らしいです、ありがとう!!!!!!!!!!!!

2020年4月、まだ公式ドキュメントはありませんよね?

これがクローズされたことは知っていますが、この問題を発見したばかりで、inbound-mail-parserが機能していることを表明しました。 私がしなければならなかった主なことは、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);
応答=解析します。keyValues();
let to = response.to;
let from = response.from;
サブジェクト= response.subject;
messageBody = response.textとします
console.log( 'これはメールの件名です:'、件名);
}

それがお役に立てば幸いです。

私が見つけたのは、request.bodyがform-dataにあり、エラーが表示されていることです。
[ネスト] 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の使い方がわかりません。

outside.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] {}

beforeは、マルチフォームデータを出力します。

サーバーレス(Googleクラウド機能またはFirebase)を使用している場合

これは役立つかもしれません: https

これはbusboyを使用しています: https ://stackoverflow.com/questions/51484307/how-to-parse-multipart-form-data-on-firebase-cloud-functions

サーバーレスでマルチパートを解析するには、Formidableを使用します: https

またはこれ: https

multerを使用できるようにするために必要な変更は次のとおりです。

app.use(express.json())
app.use(express.urlencoded({extended:true}));
const upload = multer();
app.use(upload.none());

これを行うと、multerを使用してWebhookデータを解析して
構造化キー、値のペア。

16:51デンマークモハの日、2020年5月24日には[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、PhD | プリンシパルソフトウェアエンジニア

[email protected]

https://hicleo.com/
hicleo.com | Linkedin https://www.linkedin.com/company/hicleo/ | ツイッター
https://twitter.com/hi_cleo/ | インスタグラム
https://www.instagram.com/hicleo.co/ | フェイスブック
https://www.facebook.com/hicleolabs

-

このメッセージには、機密、専有、または保護されている可能性があります情報。
このメッセージを誤って受信した場合は、返信メールで送信者に通知し、このメッセージを削除してください。

これをBusboyを使用してGoogleCloud Functionsで機能させるために多くの時間を費やしましたが、どのチュートリアルやポインタを使用しても、これを実現できませんでした。

ですから、少し柔軟性がある同様の状況にある次の人のために、これをここに残しておきます。Pythonインバウンドパーサーを使用します。 それは彼らが提供するコードからのコピー/貼り付けの仕事であり、それを実行するのに1時間もかかりませんでした。

これで問題が解決しないことはわかっていますが、他の人のヘッドバンギングの時間を節約できることを願っています。

このチケットを見つけてよかったです...これに関するいくつかのドキュメントを見つけようとして夢中になりましたが、どういうわけか何もありません

私は実際に困惑しています。 標準のドキュメントがあると思いました。特に、これはオープンソースですが、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ミドルウェアを使用して、 POSTするmultipart / form-dataを解析します。

ミドルウェアフロー内ではmulter().any()同じくらい簡単です。

乾杯

生の完全なMIMEメッセージを使用して、simpleParserで機能させましたが、simpleParserはMIMEをテキストとhtmlにうまく変換しないため、処理済みバージョンに切り替えて、sengridのinbound-mail-parserを使用しています。

ただし、確かにいくつかのドキュメントが必要です。

@theweiweiway 2つの方法のテキストとHTMLの違いの例を投稿してもよろしいですか? 違いに気づかなかったので気になります。

テキスト用

Hi 123 Hi 123 Hi 123 www.hello.com

vs

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>

vs

<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パッケージと関係があると思います

これが、express / multerを使用した私のリポジトリ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クラウド機能でこれを試しました。
絶対に働かないでください。
他の解決策はありますか?

このページは役に立ちましたか?
0 / 5 - 0 評価

関連する問題

nicoasp picture nicoasp  ·  3コメント

Chrischuck picture Chrischuck  ·  3コメント

polkhovsky picture polkhovsky  ·  3コメント

prasoonjalan picture prasoonjalan  ·  3コメント

amlcodes picture amlcodes  ·  4コメント