2016-01-14 7 views
0

Недавно мне пришлось скрыть свой IP-адрес с помощью CloudFlare, но с моей записью MX, указывающей на мой собственный домен, я не могу.Проблемы с отправкой входящего письма Mailgun на собственный SMTP-сервер с использованием HTTP-маршрута POST

Я знаю, что Mailgun может пересылать все письма на адрес [email protected] в Gmail, но я этого не хочу. Я надеюсь, что письмо может быть отправлено собственным SMTP-сервером example.com.

Я решил использовать Mailgun catch_all() и forward("https://exmaple.com/incoming-email?key=SECRET_KEY") и написал для этого код node.js.

var nodemailer = require('nodemailer'); 
var express = require('express'); 
var multer = require('multer'); 
var router = express.Router(); 

var KEY = 'SECRET_KEY'; 
var ADDITIONAL_HEADERS = ['timestamp', 'token', 'signature', 'mime-version']; 
var transporter = nodemailer.createTransport('smtp://127.0.0.1'); 

var storage = multer.memoryStorage(); 
var upload = multer({ 
    storage: storage 
}); 

router.post('/', upload.any(), function (req, res, next) { 
    if (!req.query.key || req.query.key !== KEY) { 
    res.sendStatus(403); 
    return; 
    } 
    console.log('Incoming mail: ', req.body.From); 
    req.body.to = req.body.To; 
    req.body.cc = req.body.Cc; 
    req.body.from = req.body.From; 
    req.body.date = req.body.Date; 
    req.body.references = req.body.References; 
    req.body.replyTo = req.body['Reply-To']; 
    req.body.inReplyTo = req.body['In-Reply-To']; 
    req.body.messageId = req.body['Message-Id']; 
    req.body.html = req.body['body-html']; 
    req.body.text = req.body['body-plain']; 
    req.body.headers = {}; 
    for (var key in req.body) { 
    if (key.toLowerCase().indexOf('X-') !== -1 || 
     ADDITIONAL_HEADERS.indexOf(key.toLowerCase()) !== -1) { 
     req.body.headers[key] = req.body[key]; 
    } 
    } 
    if (req.files) { 
    req.body.attachments = req.files; 
    req.body.attachments.forEach(function (attachment) { 
     attachment.filename = attachment.originalname; 
     attachment.contentType = attachment.mimetype; 
     attachment.content = attachment.buffer; 
    }); 
    } 
    transporter.sendMail(req.body, function (err, info) { 
    if (err) { 
     console.log(err); 
     res.status(400).send(err); 
     return; 
    } 
    console.log(info); 
    res.send(info); 
    }); 
}); 

module.exports = router; 

Как вы можете видеть, код способен пересылать любые входящие сообщения на SMTP-сервер localhost. Используя код, я могу получать электронные письма с помощью [email protected] Получаемое электронное письмо будет иметь правильное значение от, до, cc, темы и тела и даже вложений.

Однако, через день я вынужден отказаться от подписки на списки рассылки Arch Linux, и человек по электронной почте мне, что:

Похоже, что ваш почтовый сервер настроен неправильно, и посылает по крайней мере несколько писем он получает от наших списков рассылки обратно в список. Он также удаляет некоторые заголовки в процессе, которые помогают mailman обнаруживать такое поведение . Поскольку эти заголовки отсутствуют, почтальон отправит почту еще раз всем, что приведет к бесконечному циклу.

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

Почему это может пойти не так? Каковы «некоторые заголовки» в электронном письме, удаленные в процессе пересылки/переноса? Это проблема Mailgun или моя собственная проблема? Если это моя проблема, что можно добавить в код выше? Благодарю.

+0

Попробуйте рабочий пример: https://www.noodl.io/market/product/P201601221424994/email-composer-send-emails-with-nodejs-and-mailgun – JohnAndrews

ответ

1

Я обнаружил, что, когда электронная почта Bcc к вам, то почта будет рассматриваться как:

Так что при использовании кода в вопросе, почта будет обращаться по Node.js кода, то почта будет отправлена ​​обратно в [email protected] с помощью smtp://127.0.0.1, вызывая бесконечное петля.

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

Например, список получателей будет следующим: [email protected], [email protected], поэтому я нахожу все адреса электронной почты, заканчивающиеся на @example.com, и сделаю их To.

Предостережение: некоторая информация будет отсутствовать, хотя я больше не могу видеть исходное поле To. Однако вы можете добавить исходное поле To в любое поле, например subject.

var nodemailer = require('nodemailer'); 
var express = require('express'); 
var multer = require('multer'); 
var router = express.Router(); 

var MY_DOMAIN = 'example.com'; 
var KEY = 'SECRET_KEY; 
var ADDITIONAL_HEADERS = ['timestamp', 'token', 'signature', 'mime-version', 
    'return-path', 'dkim-signature' 
]; 
var transporter = nodemailer.createTransport('smtp://127.0.0.1'); 

var storage = multer.memoryStorage(); 
var upload = multer({ 
    storage: storage 
}); 

router.post('/', upload.any(), function (req, res, next) { 
    if (!req.query.key || req.query.key !== KEY) { 
    res.sendStatus(403); 
    return; 
    } 
    console.log('Incoming mail: ', req.body.From); 
    req.body.to = req.body.recipient.split(', ').filter(email => email.indexOf('@' + MY_DOMAIN) !== -1); 
    req.body.from = req.body.From; 
    req.body.date = req.body.Date; 
    req.body.references = req.body.References; 
    req.body.replyTo = req.body['Reply-To']; 
    req.body.inReplyTo = req.body['In-Reply-To']; 
    req.body.messageId = req.body['Message-Id']; 
    req.body.html = req.body['body-html']; 
    req.body.text = req.body['body-plain']; 
    req.body.headers = {}; 
    for (var key in req.body) { 
    if (key.toLowerCase().indexOf('x-') !== -1 || 
     ADDITIONAL_HEADERS.indexOf(key.toLowerCase()) !== -1) { 
     req.body.headers[key] = req.body[key]; 
    } 
    } 
    console.log('Params: ' + JSON.stringify(req.body)); 
    if (req.files) { 
    req.body.attachments = req.files; 
    req.body.attachments.forEach(function (attachment) { 
     attachment.filename = attachment.originalname; 
     attachment.contentType = attachment.mimetype; 
     attachment.content = attachment.buffer; 
    }); 
    } 
    transporter.sendMail(req.body, function (err, info) { 
    if (err) { 
     console.log(err); 
     res.status(400).send(err); 
     return; 
    } 
    console.log(info); 
    res.send(info); 
    }); 
}); 

module.exports = router; 
0

Письмо электронной почты не только имеет заголовок To, но также имеет значение SMTP RCPT TO. Это значение может отличаться от заголовка To, который содержится внутри электронного письма.

См: In SMTP, must the RCPT TO: and TO: match?

Ваш код, кажется, использует содержание почты и не появляется для обработки транспортного получателя (SMTP RCPT TO) отдельно. Я не знаю, поддерживает ли mailgun это значение.

Просто отправьте письмо на ваш SMTP-сервер, а некоторые библиотеки, вероятно, извлекут получателя из заголовка To, однако в случае списков рассылки это часто неверно.

+0

спасибо! Когда я буду дома, я снова посмотрю форму Mailgun POST. –

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

  • Нет связанных вопросов^_^