Sendgrid-nodejs: Beispiel für die Verwendung des Inbound-Mail-Parsers zum Parsen eingehender E-Mails

Erstellt am 13. Okt. 2017  ·  35Kommentare  ·  Quelle: sendgrid/sendgrid-nodejs

Problemzusammenfassung

Eine Zusammenfassung des Problems und der Umgebung, in der es auftritt. Geben Sie gegebenenfalls die Schritte an, die zum Reproduzieren des Fehlers erforderlich sind. Bitte fügen Sie Screenshots, Screencasts und Codebeispiele hinzu.

Ich kann nicht herausfinden, wie das Paket @ sendgrid / inbound-mail-parser zum Parsen eingehender E-Mails verwendet wird. brauche einen Beispielcode

Schritte zum Reproduzieren

Richten Sie eine Analyseroute in sendgrid ein (hier verlinkt:
https://www.dropbox.com/s/cb6lwrmon9qwjzq/Screenshot%202017-10-12%2016.03.49.png?dl=0)
Dies ist der Inhalt einer Beispiel-E-Mail an die Route in ngrok:
https://gist.github.com/machinshin/e38cf7d20ec6319edcfda63ff7aca594

Ich habe die Parseroute wie folgt mit meinem Webhook verbunden:

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(`-------------`)

}

{}

nicht definiert

Wie Sie sehen können, ist req.body leer und req.rawBody ist 'undefiniert'.
Daher ist mir nicht klar, wie ich auf die E-Mail-Rohdaten zugreifen soll, was ich danach mit diesen Daten tun soll und wie ich den Parser für eingehende E-Mails instanziieren soll

Alle anderen Informationen, die Sie weitergeben möchten und die für das gemeldete Problem relevant sind. Warum halten Sie das für einen Fehler? Was erwarten Sie stattdessen?

Technische Details:

  • sendgrid-nodejs Version: 6.1.4 (letztes Commit: 4c6d1cc)
  • Node.js Version: 4.1.2
    "@ sendgrid / inbound-mail-parser": "^ 6.1.4",
    "@ sendgrid / mail": "^ 6.1.4",
easy help wanted docs update

Hilfreichster Kommentar

Hallo @ZeroCho ,

Wir haben ein Paket haben hier , aber leider gibt es keine gute Nutzung Dokumentation. Schauen Sie sich dazu möglicherweise den Python Inbound Parser an .

Mit besten Empfehlungen,

Elmer

Sie sollten also eine Dokumentation schreiben.

Alle 35 Kommentare

Hallo @machinshin ,

Vielen Dank, dass Sie sich die Zeit genommen haben, dies zu melden. Ich habe dies zu unserem Rückstand hinzugefügt, um weitere Untersuchungen durchzuführen.

Irgendein Update am Beispiel? Ich muss diesen Parser wirklich verwenden, weiß aber nicht, wie.

Hallo @ZeroCho ,

Wir haben ein Paket haben hier , aber leider gibt es keine gute Nutzung Dokumentation. Schauen Sie sich dazu möglicherweise den Python Inbound Parser an .

Mit besten Empfehlungen,

Elmer

SendGrid sendet seine eingehenden JSON-Analysedaten als Formular- / mehrteilige Daten. Auf req.body wird nicht sofort zugegriffen, da der Body-Parser dieses Format nicht verarbeitet. Ich würde Multer als Alternative verwenden.

@ shishido92 Könnten Sie ein gutes Beispiel dafür

@stephenfjohnson @machinshin Wenn Sie Expressjs verwenden, kann dies hilfreich sein

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');
})

Auf diese Weise erhalten Sie den Inhalt der Anfrage im Anfragetext.
Dies ignoriert jedoch Anhänge.

@nathfreder Im Rahmen unserer Priorisierung Problemzusammenfassung . Bitte geben Sie oben ein 👍 an.

@ childish-sambino, @satyajeetjadhav 👍

Später spät als nie;)
Vielen Dank für das Update, das dieses Problem schließt

Ich weiß, dass dies geschlossen wurde, aber ich habe gerade dieses Problem entdeckt und ich habe Express mit Inbound-Mail-Parser funktioniert. Die Hauptsache, die ich tun musste, war, die Multer-Bibliothek zu verwenden, um die mehrteilige / Formulardateneingabe zu verarbeiten, und dann die keyValues ​​() -Methode der @ sendgrid / inbound-mail-parser-Bibliothek wie unten zu verwenden

erfordern in multer und Sendgrid:

const multer = require ('multer');
const upload = multer ();
const mailParse = require ('@ sendgrid / inbound-mail-parser');

Verwenden Sie in meiner Router-Deklaration für die POST-Methode die Methode upload.none (), da ich gerade Text erhalten habe (keine Anhänge):

router.post ('/ mail', upload.none (), Funktion (req, res, next)

Innerhalb dieser POST-Definition verwende ich dann die keyValues ​​() -Methode, um die relevanten Teile der E-Mail abzurufen:

Versuchen {
const config = {keys: ['to', 'from', 'subject', 'text',]};
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 ('Dies ist der Betreff aus der Mail:', Betreff);
}}

Hoffe, das nützt etwas.

Hallo zusammen, kann jemand ein Beispiel für das Parsen von Anhängen geben? Ich benutze die gleichen Konfigurationen, aber Anhang kommt in unreadeble Zeichenfolge


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);
});

Der von @ jhorsfield-tw gepostete Code war sehr hilfreich, da @sendgrid/inbound-mail-parser keine Dokumentation hat, aber für mich nicht ganz funktioniert hat. Der Konstruktor für mailParse nimmt request als Parameter und nicht als Anforderungshauptteil.

const parsing = new mailParse(config, req);

Hallo @ZeroCho ,

Wir haben ein Paket haben hier , aber leider gibt es keine gute Nutzung Dokumentation. Schauen Sie sich dazu möglicherweise den Python Inbound Parser an .

Mit besten Empfehlungen,

Elmer

Sie sollten also eine Dokumentation schreiben.

Wie ist das noch undokumentiert

kann es immer noch nicht mit nodejs express herausfinden ...

Erneutes Öffnen, da es in den Dokumenten noch kein Beispiel dafür gibt.

Pull-Anfragen zum Hinzufügen dieser Funktion sind willkommen und werden nach Priorität überprüft. Twilio SendGrid erstellt jedoch keine aktiven neuen Funktionen für die Bibliothek.

Der Versuch, Anhänge zu erhalten, aber immer noch kein Glück damit ...

Der Versuch, Anhänge zu erhalten, aber immer noch kein Glück damit ...

Verwenden Sie 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));
            });

Ich versuche das, aber ohne Glück ... es gibt ein leeres Objekt zurück und wenn ich .attachments() mache, bekomme ich auch ein leeres Array.

Ich verwende Firebase-Cloud-Funktionen, habe mit dem Parser für eingehende E-Mails keinen Erfolg gehabt und freue mich auf eine Dokumentation, die mir bei der Verwendung der Bibliothek helfen kann ...

Die Verwendung von Busboy (und die Deaktivierung von "raw" in den Sendgrid-Einstellungen) funktioniert jedoch recht gut, mit Ausnahme eines Problems, das mich dazu veranlasst hat, den Mailparser zu verwenden ...

Sendgrid listet die verschiedenen Codierungen im Feld "Zeichensätze" folgendermaßen auf:
Eine E-Mail von Google Mail:
{"bis": "UTF-8", "html": "UTF-8", "Betreff": "UTF-8", "von": "UTF-8", "Text": "UTF-8" }}
Eine E-Mail von Outlook:
{"to": "UTF-8", "html": "iso-8859-1", "subject": "UTF-8", "from": "UTF-8", "text": "iso- 8859-1 "}

Wenn die E-Mails internationale Zeichen enthalten (wie z. B. ÆØÅ), enthält das Text- und das HTML-Feld anstelle der eigentlichen nordischen Zeichen Fragezeichen.

Wenn ich das defCharset auf dem Busboy auf Windows-1252 ändere, werden die Text- und HTML-Werte korrekt angezeigt, die anderen Felder werden jedoch falsch angezeigt.

Wird dies auch beim Mail-Parser ein Problem sein, oder verarbeitet der Mail-Parser unterschiedliche Codierungen in den Feldern?

Mein Code zum Parsen mit Busboy für alle Interessierten:
(Wenn mir jemand sagen kann, wie ich das oben genannte Problem mit Busboy löse, wäre ich dankbar.)

exports.sendgridparse = functions.https.onRequest ((req, res) => {
const path = require ('path');
const os = require ('os');
const fs = require ('fs');
const Busboy = erfordern ('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;
});

let imageToBeUploaded = {};
let imagestobeuploaded = [];
let imageFileName;

busboy.on ('Datei', (Feldname, Datei, Dateiname, Codierung, Mimetyp) => {
console.log (Feldname, Datei, Dateiname, Codierung, Mimetyp);

file.on ('Daten', Funktion (Daten) {
console.log ('Datei [' + Feldname + '] hat' + Datenlänge + 'Bytes');
});
file.on ('end', function () {
console.log ('Datei [' + Feldname + '] Fertig');
});

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 = {Dateipfad, Mimetyp, imageFileName, imageExtension, url};
imagestobeuploaded.push (imageToBeUploaded);
file.pipe (fs.createWriteStream (Dateipfad));
});

busboy.on ('finish', async () => {
// Alle Felder sind verfügbar (imagestobeuploaded und Felder) und können in db gespeichert werden
res.send (200);
});
busboy.end (req.rawBody);
});

@hhetland Also , konnten Sie die Dateien mit Busboy bekommen? Ich verwende es auch, um die anderen Daten aus der E-Mail abzurufen, konnte aber die Dateien nicht abrufen ... Funktioniert das Abrufen der Dateien für Sie?

@matheustavaresdev - Ja, ich erhalte die Dateien mit Busboy.

Zuerst werden sie in einem tmp-Ordner in busboy.on ('Datei') gespeichert und dann unter Verwendung der Informationen in der Variablen "imagestobeuploaded" in einem Speicherbereich in firebase in busboy.on ('finish') gespeichert.

super danke !!!!!!!!!!!!

April 2020, noch keine offiziellen Dokumente, oder?

Ich weiß, dass dies geschlossen wurde, aber ich habe gerade dieses Problem entdeckt und ich habe Express mit Inbound-Mail-Parser funktioniert. Die Hauptsache, die ich tun musste, war, die Multer-Bibliothek zu verwenden, um die mehrteilige / Formulardateneingabe zu verarbeiten, und dann die keyValues ​​() -Methode der @ sendgrid / inbound-mail-parser-Bibliothek wie unten zu verwenden

erfordern in multer und Sendgrid:

const multer = require ('multer');
const upload = multer ();
const mailParse = require ('@ sendgrid / inbound-mail-parser');

Verwenden Sie in meiner Router-Deklaration für die POST-Methode die Methode upload.none (), da ich gerade Text erhalten habe (keine Anhänge):

router.post ('/ mail', upload.none (), Funktion (req, res, next)

Innerhalb dieser POST-Definition verwende ich dann die keyValues ​​() -Methode, um die relevanten Teile der E-Mail abzurufen:

Versuchen {
const config = {keys: ['to', 'from', 'subject', 'text',]};
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 ('Dies ist der Betreff aus der Mail:', Betreff);
}}

Hoffe, das nützt etwas.

Was ich finde ist, dass die request.body in Formulardaten ist und einen Fehler sieht:
[Nest] 24687 - 05/01/2020, 1:29:51 PM [ExceptionsHandler] Reduzierung des leeren Arrays ohne Anfangswert
TypeError: Reduzierung des leeren Arrays ohne Anfangswert
bei Array.reduce ()

Der Code:
keyValues ​​() {
return this.keys
.filter (key => this.payload [key])
.map (key => ({[key]: this.payload [key]}))
.reduce ((keyValues, keyPayload) => Object.assign (keyValues, keyPayload));
}}

Gibt einen Fehler zurück, da this.payload keine strukturierten Daten sind, sondern mehrteilige Formulardaten.

Ich konnte das nicht mit nest-js zum Laufen bringen. Die Webhook-Daten, die ich im NestJS-Controller erhalte, sind Multiform-Daten. Ich bin mir nicht sicher, wie ich Multer in diesem Fall verwenden soll.

Outer.post ('/ mail', upload.none (), Funktion (req, res, next)

Ich habe es versucht:

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(); } }

Der req.body gibt jedoch Folgendes zurück:
request: [Object: null prototype] {}

Das Vorher druckt vielgestaltige Daten aus.

Hier sind die Änderungen, die ich vornehmen musste, damit ich multer verwenden konnte:

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

Nachdem ich dies getan hatte, konnte ich multer verwenden, um die Webhook-Daten in a zu analysieren
strukturierter Schlüssel, Wertepaar.

Am Sonntag, 24. Mai 2020, um 16:51 Uhr Danish Mohd [email protected]
schrieb:

Wenn Sie ohne Server sind (Google Cloud-Funktionen oder Firebase)
das könnte helfen:
https://stackoverflow.com/questions/47242340/how-to-perform-an-http-file-upload-using-express-on-cloud-functions-for-firebase/48648805#48648805

Verwenden Sie Formidable zum Parsen von Multipart auf Serverless:
https://github.com/DanisHack/formidable-serverless

- -
Sie erhalten dies, weil Sie kommentiert haben.
Antworte direkt auf diese E-Mail und sieh sie dir auf GitHub an
https://github.com/sendgrid/sendgrid-nodejs/issues/482#issuecomment-633312295 ,
oder abbestellen
https://github.com/notifications/unsubscribe-auth/AB2ATHHFKBRZZDGGJ2D7SOLRTGQHNANCNFSM4D67CVZQ
.

- -

Shweta Bhandare, PhD | Principal Software Engineer

[email protected]

https://hicleo.com/
hicleo.com | Linkedin https://www.linkedin.com/company/hicleo/ | Twitter
https://twitter.com/hi_cleo/ | Instagram
https://www.instagram.com/hicleo.co/ | Facebook
https://www.facebook.com/hicleolabs

- -

Diese Nachricht kann vertraulich, geschützt oder geschützt seinInformation.
Wenn Sie diese Nachricht irrtümlich erhalten haben,Bitte benachrichtigen Sie den Absender per Antwort-E-Mail und löschen Sie diese Nachricht.

Wir haben viel Zeit damit verbracht, dies in Google Cloud-Funktionen mit Busboy zum Laufen zu bringen, und konnten dies nicht erreichen, unabhängig davon, welchen Lernprogrammen oder Hinweisen wir gefolgt sind.

Ich überlasse dies hier der nächsten Person in einer ähnlichen Situation, in der Sie ein wenig Flexibilität haben: Verwenden Sie den Python Inbound Parser . Es war so ziemlich ein Kopier- / Einfügejob aus dem von ihnen bereitgestellten Code und dauerte weniger als eine Stunde, um ihn zum Laufen zu bringen.

Ich weiß, dass dies das Problem hier nicht löst, aber ich hoffe, es kann jemand anderem stundenlanges Headbangen ersparen.

Ich bin froh, dass ich dieses Ticket gefunden habe ... Ich war verrückt, als ich versuchte, eine Dokumentation dazu zu finden, und irgendwie gibt es keine .

Ich bin wirklich verblüfft. Ich habe nur angenommen, dass es Standarddokumentation geben würde - vor allem, weil dies Open Source ist und von SendGrid (und letztendlich Twilio, das eine fantastische Dokumentation hat) unterstützt wird.

Für so etwas Einfaches würde man sich vorstellen, dass es zumindest ein Beispiel geben würde.

Nichtsdestotrotz für jeden, der darauf stößt ...

Ich empfehle stattdessen MailParser .

Ich bin mir ziemlich sicher, dass dies unter der Haube verwendet wird, aber zumindest MailParser verfügt über eine Menge Dokumentation. Stellen Sie einfach sicher, dass in Ihren Einstellungen für eingehende Analysen POST the raw, full MIME message wie unten gezeigt überprüft wurde (_wow, ein Beispiel_).

Example

Beim Lesen der MailParser-Dokumente habe ich Folgendes in wenigen Minuten erledigt:

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);
};

Alle Daten sind so, wie Sie es möchten.

Ich verwende auch die Multer- Middleware, um die Multipart- / Formulardaten zu analysieren, die SendGrid POSTs an meinen Endpunkt sendet.

Es ist so einfach wie multer().any() in Ihrem Middleware-Flow.

Prost

Ich habe die vollständige MIME-Rohnachricht verwendet und sie mit simpleParser zum Laufen gebracht, aber ich wechsle zurück zur verarbeiteten Version und verwende den Inbound-Mail-Parser von sengrid, da simpleParser das MIME nicht so gut in Text und HTML konvertiert.

Benötigen Sie auf jeden Fall eine Dokumentation.

@theweiweiway Stört es Sie, ein Beispiel für den Unterschied in Text und HTML zwischen den beiden Methoden zu veröffentlichen? Ich habe keine Unterschiede bemerkt und bin neugierig.

für Text

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/>

Ich weiß nicht, warum das passiert ist

für 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>

Ich denke, es hat mehr mit dem simpleParser-Paket zu tun

Hier ist mein Repo Express-Sendgrid-Inbound-Parse mit Express / Multer. Es ist eine einfache App, mit der Sie loslegen können. Ich empfehle, POST the raw, full MIME message aktivieren, da Sie auf weitere E-Mail-Daten zugreifen können.

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'])
}

habe dies auf der Firebase-Cloud-Funktion versucht.
Arbeite definitiv nicht.
Irgendeine andere Lösung?

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

mikemaccana picture mikemaccana  ·  4Kommentare

agostonbonomi picture agostonbonomi  ·  3Kommentare

thidasapankaja picture thidasapankaja  ·  4Kommentare

egges picture egges  ·  3Kommentare

prasoonjalan picture prasoonjalan  ·  3Kommentare