Sendgrid-nodejs: Пример использования парсера входящей почты для анализа входящих писем

Созданный на 13 окт. 2017  ·  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 к своему веб-перехватчику следующим образом:

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 - undefined.
Таким образом, я не понимаю, как получить доступ к необработанным данным электронной почты, что делать с этими данными впоследствии и как создать экземпляр анализатора входящей почты.

Любая другая информация, имеющая отношение к сообщаемой проблеме, которой вы хотите поделиться. В частности, почему вы считаете это ошибкой? Что вы ожидаете вместо этого?

Технические подробности:

  • 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 Inbound Parser .

С наилучшими пожеланиями,

Элмер

Так что тогда вам следует написать документацию.

Все 35 Комментарий

Привет @machinshin ,

Спасибо, что нашли время сообщить об этом. Я добавил это в наш список для дальнейшего расследования.

Есть обновления на примере? Мне действительно нужно использовать этот парсер, но я не знаю, как это сделать.

Привет @ZeroCho!

У нас есть пакет здесь , но , к сожалению , нет никакой документации , использования хорошо. Для этого вы можете попробовать Python Inbound Parser .

С наилучшими пожеланиями,

Элмер

SendGrid отправляет свои входящие данные синтаксического анализа JSON в виде данных формы / нескольких частей. Req.body не получит немедленного доступа к нему, так как body-parser не работает с этим форматом. Я бы использовал мультер как альтернативу.

@ 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, а затем использовать метод keyValues ​​() библиотеки @ sendgrid / inbound-mail-parser, как показано ниже.

требуется в multer и Sendgrid:

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

в моем объявлении маршрутизатора для метода POST используйте метод upload.none (), поскольку я только что получал текст (без вложений):

router.post ('/ mail', upload.none (), функция (req, res, next)

Затем в этом определении POST я использую метод keyValues ​​() для получения соответствующих частей электронного письма:

пытаться {
const config = {ключи: ['к', 'от', 'тема', 'текст',]};
const parsing = новый mailParse (config, req.body);
let response = parsing.keyValues ​​();
пусть = response.to;
пусть 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 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 (и отмена выбора "raw" в настройках Sendgrid) работает достаточно хорошо, за исключением одной проблемы, которая заставила меня попробовать использовать mailparser ...

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

Когда электронные письма содержат международные символы (например, ØÅ), в результате поля text и html содержат вопросительные знаки вместо фактических нордических символов.

Если я изменю defCharset на busboy на Windows-1252, значения текста и html будут отображаться правильно, но другие поля будут отображаться неправильно.

Будет ли это проблемой также для почтового парсера, или почтовый парсер обрабатывает разные кодировки в полях?

Мой код для разбора с помощью busboy для всех, кто интересуется:
(Если кто-нибудь может сказать мне, как решить проблему с помощью помощника по телефону, я был бы признателен ..)

exports.sendgridparse = functions.https.onRequest ((req, res) => {
const path = require ('путь');
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;
});

let imageToBeUploaded = {};
пусть imagestobeuploaded = [];
let imageFileName;

busboy.on ('файл', (имя поля, файл, имя файла, кодировка, mimetype) => {
console.log (имя поля, файл, имя файла, кодировка, mimetype);

file.on ('данные', функция (данные) {
console.log ('Файл [' + имя поля + '] получил' + длина данных + 'байты');
});
file.on ('конец', 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 (путь к файлу));
});

busboy.on ('finish', async () => {
// все поля доступны (загружаемые изображения и поля) и могут быть сохранены в db
res.send (200);
});
busboy.end (req.rawBody);
});

@hhetland, так тебе удалось получить файлы с помощью busboy? Я также использую его для получения других данных из электронной почты, но не смог получить файлы ... Получение файлов работает для вас?

@matheustavaresdev - Да, я получаю файлы с помощью busboy.

Сначала они сохраняются в папке tmp в busboy.on ('file'), а затем, используя информацию в переменной "imagestobeuploaded", я сохраняю ее в хранилище в firebase в busboy.on ('finish').

офигенное спасибо !!!!!!!!!!!!

Апрель 2020, официальных документов по-прежнему нет, верно?

Я знаю, что это было закрыто, но я только что заметил эту проблему, и у меня есть экспресс с работающим парсером входящей почты. Главное, что мне нужно было сделать, это использовать библиотеку multer для обработки ввода multipart / form-data, а затем использовать метод keyValues ​​() библиотеки @ sendgrid / inbound-mail-parser, как показано ниже.

требуется в multer и Sendgrid:

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

в моем объявлении маршрутизатора для метода POST используйте метод upload.none (), поскольку я только что получал текст (без вложений):

router.post ('/ mail', upload.none (), функция (req, res, next)

Затем в этом определении POST я использую метод keyValues ​​() для получения соответствующих частей электронного письма:

пытаться {
const config = {ключи: ['к', 'от', 'тема', 'текст',]};
const parsing = новый mailParse (config, req.body);
let response = parsing.keyValues ​​();
пусть = response.to;
пусть from = response.from;
пусть тема = response.subject;
пусть messageBody = response.text
console.log ('Это тема письма:', тема);
}

Надеюсь, что это будет полезно.

Я обнаружил, что request.body находится в форме-данных и вижу ошибку:
[Nest] 24687 - 01.05.2020, 13:29:51 [ExceptionsHandler] Уменьшение пустого массива без начального значения
TypeError: уменьшение пустого массива без начального значения
в Array.reduce ()

Код:
keyValues ​​() {
вернуть this.keys
.filter (ключ => this.payload [ключ])
.map (key => ({[ключ]: this.payload [ключ]}))
.reduce ((keyValues, keyPayload) => Object.assign (keyValues, keyPayload));
}

возвращает ошибку, поскольку this.payload не является структурированными данными, а представляет собой данные, состоящие из нескольких частей.

Мне не удалось заставить это работать с nest-js. Данные веб-перехватчика, которые я получаю в контроллере NestJS, представляют собой данные в нескольких формах. Я не знаю, как использовать Multer в таком случае.

external.post ('/ mail', upload.none (), функция (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] {}

До распечатывает многоформатные данные.

Если вы используете бессерверную версию (облачные функции Google или firebase)

это может помочь: https://stackoverflow.com/questions/47242340/how-to-perform-an-http-file-upload-using-express-on-cloud-functions-for-firebase/48648805#48648805

Это с использованием busboy: https://stackoverflow.com/questions/51484307/how-to-parse-multipart-form-data-on-firebase-cloud-functions

Используйте Formidable для разбора multipart без сервера: https://github.com/DanisHack/formidable-serverless

Или это: https://github.com/cristovao-trevisan/express-multipart-file-parser

Вот изменения, которые мне пришлось внести, чтобы я мог использовать multer:

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

Как только я это сделал, я смог использовать multer для синтаксического анализа данных веб-перехватчика в
структурированный ключ, пара значений.

ВС, 24 мая 2020 г., в 16:51, датский 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 для разбора multipart на бессерверном сервере:
https://github.com/DanisHack/formidable-serverless

-
Вы получили это, потому что оставили комментарий.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/sendgrid/sendgrid-nodejs/issues/482#issuecomment-633312295 ,
или отписаться
https://github.com/notifications/unsubscribe-auth/AB2ATHHFKBRZZDGGJ2D7SOLRTGQHNANCNFSM4D67CVZQ
.

-

Светлана Бхандаре, доктор философии | Главный инженер-программист

[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

-

Это сообщение может содержать конфиденциальные, служебные или защищенныеИнформация.
Если вы получили это сообщение по ошибке,пожалуйста, сообщите отправителю ответным письмом и удалите это сообщение.

Мы потратили много времени, пытаясь заставить это работать в Google Cloud Functions с Busboy, и не могли этого сделать, независимо от того, какое руководство или указатели мы использовали.

Так что я оставлю это здесь для следующего человека в аналогичной ситуации, когда у вас есть немного гибкости: используйте Python Inbound Parser . Это было в значительной степени копирование / вставка кода, который они предоставили, и потребовалось менее часа, чтобы запустить его.

Я знаю, что это не решает проблему, но я надеюсь, что это поможет кому-то еще несколько часов трясти головой.

Я рад, что нашел этот билет ... Я сходил с ума, пытаясь найти какую-то документацию по этому поводу, но почему- то ее нет .

Я действительно сбит с толку. Я просто предположил, что будет стандартная документация - особенно потому, что, хотя это открытый исходный код, он поддерживается SendGrid (и, в конечном итоге, Twilio, у которого есть фантастическая документация).

Можно подумать, что для чего-то столь же простого, по крайней мере, есть пример.

Тем не менее, для всех, кто сталкивается с этим ...

Вместо этого я рекомендую использовать

Я почти уверен, что он использует его под капотом, но, по крайней мере, у MailParser есть множество документации. Просто убедитесь, что в настройках входящего синтаксического анализа вы отметили POST the raw, full MIME message как показано ниже (_уа, пример_).

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 для анализа данных multipart / form, которые SendGrid отправляет на мою конечную точку.

Это так же просто, как multer().any() в потоке промежуточного программного обеспечения.

Ура

Я использовал необработанное полное сообщение MIME и заставил его работать с simpleParser, но я возвращаюсь к обработанной версии и использую анализатор входящей почты sengrid, потому что 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, хотя

Вот мой репозиторий express-sendgrid-inbound-parse с использованием express / multer. Это простое приложение, с которого можно начать. Я рекомендую не устанавливать флажок 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 рейтинги

Смежные вопросы

amlcodes picture amlcodes  ·  4Комментарии

thinkingserious picture thinkingserious  ·  4Комментарии

egges picture egges  ·  3Комментарии

polkhovsky picture polkhovsky  ·  3Комментарии

Chrischuck picture Chrischuck  ·  3Комментарии