Sendgrid-nodejs: Exemple d'utilisation de l'analyseur de courrier entrant pour analyser les e-mails entrants

Créé le 13 oct. 2017  ·  35Commentaires  ·  Source: sendgrid/sendgrid-nodejs

Résumé de la question

Un résumé du problème et de l'environnement dans lequel il se produit. Le cas échéant, incluez les étapes nécessaires pour reproduire le bogue. N'hésitez pas à inclure des captures d'écran, des captures d'écran, des exemples de code.

Je ne parviens pas à comprendre comment utiliser le package @ sendgrid / inbound-mail-parser pour analyser les e-mails entrants. besoin d'un exemple de code

Étapes à suivre pour reproduire

Configurez une route d'analyse dans sendgrid (lien ici:
https://www.dropbox.com/s/cb6lwrmon9qwjzq/Screenshot%202017-10-12%2016.03.49.png?dl=0)
voici le contenu d'un exemple d'e-mail à la route dans ngrok:
https://gist.github.com/machinshin/e38cf7d20ec6319edcfda63ff7aca594

J'ai connecté le parseroute à mon webhook comme ceci:

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

}

{}

indéfini

Comme vous pouvez le voir, req.body est vide et req.rawBody est 'indéfini'
Ainsi, je ne suis pas clair sur la façon d'accéder aux données de courrier électronique brutes, ni sur ce qu'il faut faire avec ces données par la suite et comment instancier l'analyseur de courrier entrant.

Toute autre information que vous souhaitez partager concernant le problème signalé. Surtout, pourquoi considérez-vous cela comme un bogue? Que pensez-vous qu'il se passe à la place?

Détails techniques:

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

Commentaire le plus utile

Salut @ZeroCho ,

Nous avons un package ici , mais malheureusement, il n'y a pas de bonne documentation d'utilisation. Pour cela, vous voudrez peut-être consulter l' analyseur entrant Python .

Meilleures salutations,

Elmer

Alors vous devriez écrire de la documentation.

Tous les 35 commentaires

Bonjour @machinshin ,

Merci d'avoir pris le temps de le signaler. J'ai ajouté cela à notre arriéré pour une enquête plus approfondie.

Une mise à jour sur l'exemple? J'ai vraiment besoin d'utiliser cet analyseur mais je ne sais pas comment le faire.

Salut @ZeroCho ,

Nous avons un package ici , mais malheureusement, il n'y a pas de bonne documentation d'utilisation. Pour cela, vous voudrez peut-être consulter l' analyseur entrant Python .

Meilleures salutations,

Elmer

SendGrid envoie leurs données d'analyse entrantes JSON sous forme de données de formulaire / en plusieurs parties. Cela ne sera pas accessible immédiatement par req.body car l'analyseur de corps ne gère pas ce format. J'utiliserais multer comme alternative.

@ shishido92 Pourriez-vous développer un bon exemple de la façon de procéder. Il semble que la documentation pour l'analyse des e-mails entrants avec nodejs est tout simplement inexistante. Merci!

@stephenfjohnson @machinshin Si vous utilisez expressjs, cela peut vous aider

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

Cela vous donnera le contenu de la demande dans le corps de la demande.
Cela ignore cependant les pièces jointes.

@nathfreder Nous utilisons des réactions de pouce en l'

@ enfantin-sambino, @satyajeetjadhav 👍

Plus tard tard que jamais;)
Merci pour la mise à jour, clôture de ce problème

Je sais que cela a été fermé mais je viens de repérer ce problème et j'ai express avec inbound-mail-parser fonctionnant. La principale chose que je devais faire était d'utiliser la bibliothèque multer pour gérer l'entrée multipart / form-data, puis d'utiliser la méthode keyValues ​​() de la bibliothèque @ sendgrid / inbound-mail-parser comme ci-dessous

exigent dans multer et Sendgrid:

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

sur ma déclaration de routeur pour la méthode POST, utilisez la méthode upload.none () car je recevais juste du texte (pas de pièces jointes):

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

Dans cette définition POST, j'utilise ensuite la méthode keyValues ​​() pour obtenir les parties pertinentes de l'e-mail:

essayez {
const config = {clés: ['to', 'from', 'subject', 'text',]};
const parsing = new mailParse (config, req.body);
let response = parsing.keyValues ​​();
laissez à = response.to;
laissez de = response.from;
laissez subject = response.subject;
laissez messageBody = response.text
console.log ('Ceci est le sujet du mail:', sujet);
}

J'espère que c'est utile.

Salut à tous, quelqu'un peut-il partager un exemple sur la façon d'analyser les pièces jointes? J'utilise les mêmes configurations, mais la pièce jointe est fournie dans une chaîne illisible


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

Le code posté par @ jhorsfield-tw a été très utile car @sendgrid/inbound-mail-parser n'a pas de documentation, mais cela n'a pas tout à fait fonctionné pour moi. Le constructeur de mailParse prend request comme paramètre et non le corps de la requête.

const parsing = new mailParse(config, req);

Salut @ZeroCho ,

Nous avons un package ici , mais malheureusement, il n'y a pas de bonne documentation d'utilisation. Pour cela, vous voudrez peut-être consulter l' analyseur entrant Python .

Meilleures salutations,

Elmer

Alors vous devriez écrire de la documentation.

Comment est-ce toujours non documenté

ne peut toujours pas le comprendre avec nodejs express ...

Réouverture car il n'y a toujours pas d'exemple pour cela dans la documentation.

Les demandes d'extraction pour ajouter cette fonctionnalité sont les bienvenues et seront examinées en fonction de la priorité, mais Twilio SendGrid ne construit pas activement de nouvelles fonctionnalités pour la bibliothèque.

Essayer de recevoir des pièces jointes mais toujours pas de chance avec ça ...

Essayer de recevoir des pièces jointes mais toujours pas de chance avec ça ...

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

J'essaye mais sans chance ... ça retourne un objet vide et quand je fais .attachments() j'obtiens aussi un tableau vide.

J'utilise les fonctions cloud de Firebase, je n'ai pas réussi à utiliser l'analyseur de courrier entrant et j'attends avec impatience une documentation qui pourra m'aider à utiliser la bibliothèque ...

Mais utiliser busboy (et désélectionner "raw" dans les paramètres Sendgrid) fonctionne plutôt bien, sauf pour un problème qui m'a amené à essayer d'utiliser le mailparser ...

Sendgrid répertorie les différents encodages dans le champ "charsets" comme ceci:
Un e-mail de Gmail:
{"to": "UTF-8", "html": "UTF-8", "subject": "UTF-8", "from": "UTF-8", "text": "UTF-8" }
Un e-mail d'Outlook:
{"to": "UTF-8", "html": "iso-8859-1", "subject": "UTF-8", "from": "UTF-8", "text": "iso- 8859-1 "}

Lorsque les e-mails contiennent des caractères internationaux (comme ÆØÅ), le résultat est que les champs texte et html contiennent des points d'interrogation au lieu des caractères nordiques réels.

Si je change le defCharset sur busboy en Windows-1252, le texte et les valeurs html s'afficheront correctement, mais les autres champs s'afficheront mal.

Cela posera-t-il également un problème sur l'analyseur de courrier ou est-ce que l'analyseur de courrier gère différents encodages sur les champs?

Mon code d'analyse à l'aide de busboy pour toute personne intéressée:
(Si quelqu'un peut me dire comment je résous le problème ci-dessus en utilisant busboy, je serais reconnaissant ..)

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

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

busboy.on ('file', (nom de champ, fichier, nom de fichier, encodage, type MIME) => {
console.log (nom de champ, fichier, nom de fichier, encodage, type MIME);

file.on ('données', fonction (données) {
console.log ('File [' + fieldname + '] a' + data.length + 'bytes');
});
file.on ('fin', fonction () {
console.log ('File [' + fieldname + '] Terminé');
});

const imageExtension = filename.split ('.') [filename.split ('.'). length - 1];
imageFileName = ${Math.round(Math.random() * 1000000000000).toString()}.${imageExtension} ;
const filepath = chemin.join (os.tmpdir (), imageFileName);
url const = https://firebasestorage.googleapis.com/v0/b/${environment.firebase.storageBucket}/o/${imageFileName}?alt=media ;
imageToBeUploaded = {chemin de fichier, type MIME, imageFileName, imageExtension, url};
imagestobeuploaded.push (imageToBeUploaded);
file.pipe (fs.createWriteStream (chemin du fichier));
});

busboy.on ('terminer', async () => {
// tous les champs sont disponibles (imagestobeuploaded et fields) et peuvent être enregistrés dans la base de données
res.send (200);
});
busboy.end (req.rawBody);
});

@hhetland alors, avez-vous pu obtenir les fichiers en utilisant busboy? Je l'utilise également pour obtenir les autres données du courrier électronique, mais je n'ai pas pu obtenir les fichiers ... Est-ce que l'obtention des fichiers fonctionne pour vous?

@matheustavaresdev - Oui, je reçois les fichiers en utilisant busboy.

Tout d'abord, ils sont enregistrés dans un dossier tmp dans busboy.on ('file'), puis en utilisant les informations de la variable "imagestobeuploaded", je l'enregistre dans un seau de stockage dans firebase dans busboy.on ('finish').

super merci!!!!!!!!!!!!

Avril 2020, toujours pas de documentation officielle, non?

Je sais que cela a été fermé mais je viens de repérer ce problème et j'ai express avec inbound-mail-parser fonctionnant. La principale chose que je devais faire était d'utiliser la bibliothèque multer pour gérer l'entrée multipart / form-data, puis d'utiliser la méthode keyValues ​​() de la bibliothèque @ sendgrid / inbound-mail-parser comme ci-dessous

exigent dans multer et Sendgrid:

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

sur ma déclaration de routeur pour la méthode POST, utilisez la méthode upload.none () car je recevais juste du texte (pas de pièces jointes):

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

Dans cette définition POST, j'utilise ensuite la méthode keyValues ​​() pour obtenir les parties pertinentes de l'e-mail:

essayez {
const config = {clés: ['to', 'from', 'subject', 'text',]};
const parsing = new mailParse (config, req.body);
let response = parsing.keyValues ​​();
laissez à = response.to;
laissez de = response.from;
laissez subject = response.subject;
laissez messageBody = response.text
console.log ('Ceci est le sujet du mail:', sujet);
}

J'espère que c'est utile.

Ce que je trouve, c'est que le request.body est dans form-data et voit une erreur:
[Nest] 24687 - 01/05/2020, 13:29:51 [ExceptionsHandler] Réduction du tableau vide sans valeur initiale
TypeError: réduction du tableau vide sans valeur initiale
à Array.reduce ()

Le code:
keyValues ​​() {
renvoyer this.keys
.filter (clé => this.payload [clé])
.map (clé => ({[clé]: this.payload [clé]}))
.reduce ((keyValues, keyPayload) => Object.assign (keyValues, keyPayload));
}

renvoie une erreur car this.payload n'est pas des données structurées mais des données de formulaire en plusieurs parties.

Je n'ai pas pu faire fonctionner cela avec nest-js. Les données de webhook que je reçois dans le contrôleur NestJS sont des données multiformes. Je ne sais pas comment utiliser Multer dans ce cas.

external.post ('/ mail', upload.none (), function (req, res, next)

J'ai essayé de faire ceci:

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

Cependant, le req.body renvoie:
request: [Object: null prototype] {}

L'avant imprime les données multiformes.

Voici les changements que j'ai dû faire pour pouvoir utiliser multer:

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

Une fois que j'ai fait cela, j'ai pu utiliser multer pour analyser les données du webhook dans un
clé structurée, paire de valeurs.

Le dim 24 mai 2020 à 16 h 51 danois Mohd [email protected]
a écrit:

Si vous êtes sur sans serveur (fonctions Google Cloud ou Firebase)
cela pourrait aider:
https://stackoverflow.com/questions/47242340/how-to-perform-an-http-file-upload-using-express-on-cloud-functions-for-firebase/48648805#48648805

Utilisez Formidable pour analyser le multipart sur sans serveur:
https://github.com/DanisHack/formidable-serverless

-
Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, affichez-le sur GitHub
https://github.com/sendgrid/sendgrid-nodejs/issues/482#issuecomment-633312295 ,
ou se désinscrire
https://github.com/notifications/unsubscribe-auth/AB2ATHHFKBRZZDGGJ2D7SOLRTGQHNANCNFSM4D67CVZQ
.

-

Shweta Bhandare, PhD | Ingénieur logiciel principal

[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

-

Ce message peut contenir des informations confidentielles, exclusives ou protégéesinformation.
Si vous avez reçu ce message par erreur,veuillez informer l'expéditeur par e-mail de réponse et supprimer ce message.

Nous avons passé beaucoup de temps à essayer de faire fonctionner cela dans Google Cloud Functions avec Busboy et nous n'avons pas pu y arriver, quel que soit le tutoriel ou les pointeurs que nous suivions.

Je vais donc laisser ceci ici pour la personne suivante dans une situation similaire où vous avez un peu de flexibilité: utilisez le Python Inbound Parser . C'était à peu près un travail de copier / coller à partir du code qu'ils fournissent et il a fallu moins d'une heure pour le faire fonctionner.

Je sais que cela ne résout pas le problème ici, mais j'espère que cela peut sauver quelqu'un d'autre des heures de tête.

Je suis content d'avoir trouvé ce ticket ... Je devenais fou en essayant de trouver de la documentation à ce sujet, et d'une manière ou d'une autre, il n'y en a pas .

Je suis vraiment déconcerté. J'ai juste supposé qu'il y aurait une documentation standard - en particulier parce que, bien que ce soit open source, il est soutenu par SendGrid (et finalement Twilio, qui a une documentation fantastique).

Pour quelque chose d'aussi simple que cela, vous imaginez qu'il y aurait au moins un exemple.

Néanmoins, pour quiconque rencontre cela ...

Je recommande d'utiliser MailParser à la place.

Je suis à peu près sûr que cela l'utilise sous le capot, mais au moins MailParser a beaucoup de documentation. Assurez-vous simplement que dans vos paramètres d'analyse entrante, vous avez coché POST the raw, full MIME message comme indiqué ci-dessous (_wow, un exemple_).

Example

En lisant la documentation de MailParser, je l'ai fait en quelques minutes:

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

Toutes les données sont comme vous le souhaitez.

J'utilise également le middleware Multer pour analyser les données multipart / form que SendGrid POST sur mon point de terminaison.

C'est aussi simple que multer().any() dans votre flux middleware.

À votre santé

J'ai utilisé le message MIME complet brut et je l'ai fait fonctionner avec simpleParser, mais je reviens à la version traitée et j'utilise l'analyseur de courrier entrant de sengrid car simpleParser ne convertit pas aussi bien le MIME en texte et html.

J'ai vraiment besoin de documentation.

@theweiweiway Cela vous dérange-

pour le texte

Hi 123 Hi 123 Hi 123 www.hello.com

contre

Hi 123 Hi 123 Hi 123 www. <http://www.hello.com/>hello <http://www.hello.com/>.com <http://www.hello.com/>

^ je ne sais pas pourquoi c'est arrivé

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

contre

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

Je pense que c'est plus à voir avec le package simpleParser tho

Voici mon repo express-sendgrid-inbound-parse en utilisant express / multer. C'est une application simple pour vous aider à démarrer. Je recommande de ne pas cocher POST the raw, full MIME message car vous pouvez accéder à plus de données de messagerie.

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

essayé ceci sur la fonction cloud Firebase.
Ne fonctionne pas définitivement.
Une autre solution?

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

thinkingserious picture thinkingserious  ·  4Commentaires

zvone187 picture zvone187  ·  4Commentaires

Loriot-n picture Loriot-n  ·  4Commentaires

danielflippance picture danielflippance  ·  4Commentaires

Chrischuck picture Chrischuck  ·  3Commentaires