Sendgrid-nodejs: Exemplo de uso do analisador de e-mail recebido para analisar e-mails recebidos

Criado em 13 out. 2017  ·  35Comentários  ·  Fonte: sendgrid/sendgrid-nodejs

Resumo do problema

Um resumo do problema e do ambiente em que ocorre. Se adequado, inclua as etapas necessárias para reproduzir o bug. Fique à vontade para incluir capturas de tela, screencasts, exemplos de código.

Não consigo descobrir como usar o pacote @ sendgrid / inbound-mail-parser para analisar emails de entrada. precisa de algum código de exemplo

Passos para reproduzir

Configure uma rota de análise em sendgrid (link aqui:
https://www.dropbox.com/s/cb6lwrmon9qwjzq/Screenshot%202017-10-12%2016.03.49.png?dl=0)
este é o conteúdo de um exemplo de e-mail para a rota em ngrok:
https://gist.github.com/machinshin/e38cf7d20ec6319edcfda63ff7aca594

Eu conectei o parseroute ao meu webhook assim:

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

}

{}

Indefinido

Como você pode ver, req.body está vazio e req.rawBody está 'indefinido'
Assim, não estou certo sobre como obter acesso aos dados brutos de email, nem o que fazer com esses dados depois e como instanciar o analisador de email de entrada

Qualquer outra informação que você queira compartilhar que seja relevante para o problema que está sendo relatado. Principalmente, por que você considera isso um bug? O que você espera que aconteça?

Detalhes técnicos:

  • sendgrid-nodejs Versão: 6.1.4 (último commit: 4c6d1cc)
  • Versão Node.js: 4.1.2
    "@ sendgrid / inbound-mail-parser": "^ 6.1.4",
    "@ sendgrid / mail": "^ 6.1.4",
easy help wanted docs update

Comentários muito úteis

Olá @ZeroCho ,

Temos um pacote aqui , mas infelizmente não existe uma boa documentação de uso. Para isso, você pode querer verificar o Python Inbound Parser .

Obrigado pela atenção,

Elmer

Então você deve escrever a documentação.

Todos 35 comentários

Olá @machinshin ,

Obrigado por dedicar seu tempo para relatar isso. Eu adicionei isso ao nosso backlog para uma investigação mais aprofundada.

Alguma atualização no exemplo? Eu realmente preciso usar esse analisador, mas não sei como.

Olá @ZeroCho ,

Temos um pacote aqui , mas infelizmente não existe uma boa documentação de uso. Para isso, você pode querer verificar o Python Inbound Parser .

Obrigado pela atenção,

Elmer

SendGrid envia seus dados de análise de entrada JSON como dados de formulário / várias partes. Isso não será acessado imediatamente por req.body, pois o analisador de corpo não lida com esse formato. Eu usaria o multer como alternativa.

@ shishido92 Você poderia expandir um bom exemplo de como fazer isso. Parece que a documentação para qualquer análise de e-mails de entrada com nodejs é simplesmente inexistente. Obrigado!

@stephenfjohnson @machinshin Se você estiver usando expressjs, isso pode ajudar

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

Isso fornecerá o conteúdo da solicitação no corpo da solicitação.
No entanto, isso ignora os anexos.

@nathfreder Usamos

@ infantil-sambino, @satyajeetjadhav 👍

Mais tarde, tarde do que nunca;)
Obrigado pela atualização, fechando este problema

Sei que isso foi fechado, mas acabei de detectar esse problema e expressei com o analisador de e-mail de entrada funcionando. A principal coisa que eu precisava fazer era usar a biblioteca multer para lidar com a entrada multipart / form-data e, em seguida, usar o método keyValues ​​() da biblioteca @ sendgrid / inbound-mail-parser como abaixo

exigir em multer e Sendgrid:

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

na declaração do meu roteador para o método POST, use o método upload.none () porque eu estava apenas recebendo o texto (sem anexos):

router.post ('/ mail', upload.none (), função (req, res, próximo)

Dentro dessa definição POST, uso o método keyValues ​​() para obter as partes relevantes do e-mail:

tentar {
const config = {keys: ['para', 'de', 'assunto', 'texto',]};
const parsing = new mailParse (config, req.body);
deixe a resposta = parsing.keyValues ​​();
let to = response.to;
deixe de = resposta.de;
let subject = response.subject;
deixe messageBody = response.text
console.log ('Este é o assunto do e-mail:', assunto);
}

Espero que tenha alguma utilidade.

Oi pessoal, alguém pode compartilhar um exemplo de como analisar anexos? estou usando as mesmas configurações, mas o anexo vem em uma string inacreditável


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

O código postado por @ jhorsfield-tw foi muito útil, já que @sendgrid/inbound-mail-parser não tem documentação, no entanto, não funcionou muito bem para mim. O construtor de mailParse usa request como parâmetro, não o corpo da solicitação.

const parsing = new mailParse(config, req);

Olá @ZeroCho ,

Temos um pacote aqui , mas infelizmente não existe uma boa documentação de uso. Para isso, você pode querer verificar o Python Inbound Parser .

Obrigado pela atenção,

Elmer

Então você deve escrever a documentação.

Como isso ainda não está documentado

ainda não consigo descobrir com nodejs express ...

Reabrindo pois ainda não há exemplo para isso nos documentos.

Solicitações pull para adicionar este recurso são bem-vindas e serão revisadas com base na prioridade, mas Twilio SendGrid não está construindo ativamente novas funcionalidades para a biblioteca.

Tentando receber anexos, mas ainda sem sorte com isso ...

Tentando receber anexos, mas ainda sem sorte com isso ...

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

Estou tentando fazer isso, mas sem sorte ... ele retorna um objeto vazio e quando faço .attachments() também obtenho um array vazio.

Estou usando as funções de nuvem do Firebase, não tive nenhum sucesso usando o analisador de e-mail de entrada e estou ansioso por alguma documentação que pode me ajudar a usar a biblioteca ...

Mas usar o busboy (e desmarcar "raw" nas configurações do Sendgrid) está funcionando muito bem, exceto por um problema que me levou a tentar usar o mailparser ...

Sendgrid lista as diferentes codificações no campo "charsets" como este:
Um e-mail do Gmail:
{"para": "UTF-8", "html": "UTF-8", "assunto": "UTF-8", "de": "UTF-8", "texto": "UTF-8" }
Um e-mail do Outlook:
{"para": "UTF-8", "html": "iso-8859-1", "assunto": "UTF-8", "de": "UTF-8", "texto": "iso- 8859-1 "}

Quando os e-mails contêm caracteres internacionais (como ÆØÅ), o resultado é que os campos de texto e html contêm pontos de interrogação em vez dos caracteres nórdicos reais.

Se eu alterar o defCharset no busboy para Windows-1252, os valores de texto e html serão exibidos corretamente, mas os outros campos serão exibidos incorretamente.

Isso também será um problema no analisador de correio ou o analisador de correio lida com codificações diferentes nos campos?

Meu código para análise usando busboy para qualquer pessoa interessada:
(Se alguém puder me dizer como resolvo o problema acima usando o busboy, ficaria muito grato ..)

exportações.sendgridparse = functions.https.onRequest ((req, res) => {
const path = require ('path');
const os = require ('os');
const fs = require ('fs');
const Busboy = requer ('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 = {};
deixe imagestobeuploaded = [];
let imageFileName;

busboy.on ('arquivo', (nome do campo, arquivo, nome do arquivo, codificação, tipo MIME) => {
console.log (nome do campo, arquivo, nome do arquivo, codificação, tipo MIME);

file.on ('dados', função (dados) {
console.log ('Arquivo [' + nomedocampo + '] obtido' + data.length + 'bytes');
});
file.on ('end', function () {
console.log ('Arquivo [' + nomedocampo + '] Concluído');
});

const imageExtension = filename.split ('.') [filename.split ('.'). length - 1];
imageFileName = ${Math.round(Math.random() * 1000000000000).toString()}.${imageExtension} ;
const filepath = path.join (os.tmpdir (), imageFileName);
url const = 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 ('terminar', assíncrono () => {
// todos os campos estão disponíveis (imagestobeuploaded e campos) e podem ser salvos no banco de dados
res.send (200);
});
busboy.end (req.rawBody);
});

@hhetland então, você conseguiu obter os arquivos usando o busboy? Também estou usando para obter os outros dados do e-mail, mas não consegui obter os arquivos ... Obter os arquivos funciona para você?

@matheustavaresdev - Sim, estou obtendo os arquivos usando o busboy.

Primeiro, eles são salvos em uma pasta tmp em busboy.on ('arquivo') e, em seguida, usando as informações na variável "imagestobeuploaded", estou salvando em um balde de armazenamento no firebase em busboy.on ('terminar').

muito obrigado !!!!!!!!!!!!

Abril de 2020, ainda sem documentos oficiais, certo?

Sei que isso foi fechado, mas acabei de detectar esse problema e expressei com o analisador de e-mail de entrada funcionando. A principal coisa que eu precisava fazer era usar a biblioteca multer para lidar com a entrada multipart / form-data e, em seguida, usar o método keyValues ​​() da biblioteca @ sendgrid / inbound-mail-parser como abaixo

exigir em multer e Sendgrid:

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

na declaração do meu roteador para o método POST, use o método upload.none () porque eu estava apenas recebendo o texto (sem anexos):

router.post ('/ mail', upload.none (), função (req, res, próximo)

Dentro dessa definição POST, uso o método keyValues ​​() para obter as partes relevantes do e-mail:

tentar {
const config = {keys: ['para', 'de', 'assunto', 'texto',]};
const parsing = new mailParse (config, req.body);
deixe a resposta = parsing.keyValues ​​();
let to = response.to;
deixe de = resposta.de;
let subject = response.subject;
deixe messageBody = response.text
console.log ('Este é o assunto do e-mail:', assunto);
}

Espero que tenha alguma utilidade.

O que descobri é que request.body está em form-data e vejo um erro:
[Nest] 24687 - 05/01/2020, 1:29:51 PM [ExceptionsHandler] Redução de matriz vazia sem valor inicial
TypeError: Redução de array vazio sem valor inicial
em Array.reduce ()

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

retorna um erro porque this.payload não é um dado estruturado, mas sim um formulário com várias partes.

Eu não fui capaz de fazer isso funcionar com nest-js. Os dados do webhook que recebo no controlador NestJS são dados multiformes. Não tenho certeza de como usar Multer nesse caso.

outer.post ('/ mail', upload.none (), função (req, res, próximo)

Eu tentei fazer isso:

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

No entanto, o req.body retorna:
request: [Object: null prototype] {}

O antes imprime dados multiformes.

Aqui estão as alterações que tive de fazer para poder usar o multer:

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

Depois de fazer isso, consegui usar o multer para analisar os dados do webhook em um
chave estruturada, par de valores.

Domingo, 24 de maio de 2020 às 4:51 PM Danish Mohd [email protected]
escrevi:

Se você estiver sem servidor (google cloud functions ou firebase)
isso pode ajudar:
https://stackoverflow.com/questions/47242340/how-to-perform-an-http-file-upload-using-express-on-cloud-functions-for-firebase/48648805#48648805

Use Formidable para analisar multiparte sem servidor:
https://github.com/DanisHack/formidable-serverless

-
Você está recebendo isto porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/sendgrid/sendgrid-nodejs/issues/482#issuecomment-633312295 ,
ou cancelar
https://github.com/notifications/unsubscribe-auth/AB2ATHHFKBRZZDGGJ2D7SOLRTGQHNANCNFSM4D67CVZQ
.

-

Shweta Bhandare, PhD | Engenheiro de software 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

-

Esta mensagem pode conter informações confidenciais, proprietárias ou protegidasem formação.
Se você recebeu esta mensagem por engano,notifique o remetente por e-mail de resposta e exclua esta mensagem.

Gastamos muito tempo tentando fazer isso funcionar no Google Cloud Functions com Busboy e não conseguimos fazer isso acontecer, independentemente do tutorial ou das dicas que seguíssemos.

Portanto, deixarei isso aqui para a próxima pessoa em uma situação semelhante em que você tenha um pouco de flexibilidade: use o Python Inbound Parser . Era basicamente um trabalho de copiar / colar do código fornecido e levou menos de uma hora para colocá-lo em execução.

Sei que isso não resolve o problema aqui, mas espero que possa poupar horas de bate-cabeça de alguém.

Estou feliz por ter encontrado este tíquete ... Eu estava ficando louco tentando encontrar alguma documentação sobre isso, e de alguma forma não há nenhuma .

Estou realmente perplexo. Eu apenas presumi que haveria documentação padrão - especialmente porque embora seja um código-fonte aberto, é apoiado pelo SendGrid (e, por fim, pelo Twilio, que tem uma documentação fantástica).

Para algo tão simples como isso, você imaginaria que haveria pelo menos um exemplo.

No entanto, para quem se depara com isso ...

Eu recomendo usar o MailParser .

Tenho certeza que isso o usa por baixo do capô, mas pelo menos o MailParser tem muita documentação. Apenas certifique-se de que em suas configurações de análise de entrada você tenha POST the raw, full MIME message marcado conforme mostrado abaixo (_wow, um exemplo_).

Example

Lendo os documentos do MailParser, resolvo isso em minutos:

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

Todos os dados estão como você gostaria.

Eu também uso o middleware Multer para analisar os dados multipart / form que o SendGrid faz POST em meu endpoint.

É tão simples quanto multer().any() em seu fluxo de middleware.

Felicidades

Usei a mensagem MIME completa bruta e a fiz funcionar com o simpleParser, mas estou voltando para a versão processada e usando o analisador de e-mail de entrada da sengrid porque o simpleParser não converte o MIME em texto e html tão bem.

Definitivamente preciso de alguma documentação.

@theweiweiway Você se importa em postar um exemplo da diferença em texto e html entre os dois métodos? Não notei nenhuma diferença e estou curioso.

para texto

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

^ não sei porque isso aconteceu

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

Acho que tem mais a ver com o pacote simpleParser que

Aqui está meu repo express-sendgrid-inbound-parse usando express / multer. É um aplicativo fácil para você começar. Recomendo deixar POST the raw, full MIME message desmarcado, pois você pode acessar mais dados de e-mail.

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

tentei isso na função de nuvem do Firebase.
Não funcione definitivamente.
Alguma outra solução?

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

metalshan picture metalshan  ·  3Comentários

TobiahRex picture TobiahRex  ·  3Comentários

amlcodes picture amlcodes  ·  4Comentários

Loriot-n picture Loriot-n  ·  4Comentários

umarhussain15 picture umarhussain15  ·  3Comentários