用Nodejs搭建简单smtp服务器
用Nodejs搭建简单smtp服务器
最近在公司用node写了一个小程序,搭建一个简单的smtp服务器,用来接收邮件,然后根据邮件的收件人地址,再把内容分发到他rtx、手机短信和外网邮箱上。本来这个功能有个用python写的例子,全部代码不过80行。感叹python这门语言确实精练,而且第三方模块和参考资料比node要多,只需简单的import smtpd模块就可以轻松搞定了,对于MIME解析也只需要import email这个模块。
但是python做不到对email流的精准控制(可能是我不懂怎么弄,py高手别喷啊),而且最近一直在搞node,所以打算用node来实现整个工作流程,顺便也测试下1.0版本的rrestjs框架。
要完成作业,我们面临以下问题: 1、如何用node建立一个smtp服务器,监听25端口 2、如何对MIME流做解析,变成我们想要的subject,text,from,to等我们需要的东西 3、如何把邮件转发外网邮箱
问题1、 在谷歌了一阵子之后,我打算使用substack写的node-smtp-protocol模块,这哥们上次在hujs上见过,长头发很腼腆的一个男孩,他写的模块应该挺靠谱,再说万一有什么问题也方便联系的上他。 github地址:https://github.com/substack/node-smtp-protocol 例子挺简单:
var smtp = require('smtp-protocol');
var server = smtp.createServer(function (req) {
req.on('greeting', function (to, ack) {
ack.accept();
});
req.on('from', function (to, ack) {
ack.accept();
});
req.on('to', function (to, ack) {
filter(to, ack);//过滤smtp请求
});
req.on('message', function (stream, ack) {
serial(stream, ack, req.to);
});
});
server.listen(25);
console.log('starting mail server listen port 25.')
这样我们就建立起来了一个smtp服务器了,我们监听了greeting,from,to和message事件,代码中的ack.accept代表返回状态码250,表示成功,而message则表示客户端开发发送email的body流。 如果在message之前的阶段你想阻拦这次回话,只需要调用 ack.reject()方法拦截掉即可。
搭建起来之后,我只需要用telnet ip 25命令连接上node smtp服务器,测试截屏如下:
当中的^[[A这段无视,打错了,我们成功起来了一个smtp服务器了,当然我们可以在触发 to 或者 from 这些事件时做一下限制,只允许特定来源或者特定目标。
问题2、启动了mail服务器,但是我们对于mail的内容处理还停留在最原始的MIME格式流上,如何正确处理MIME流成为我们获取mail内容的关键问题了,很幸运,我找到了MailParser这个模块。 github地址:https://github.com/andris9/mailparser 这个模块使用起来更加简单,因为node-smtp-protocol模块提供了stream流,所以我们只需写如下代码就可以解析它:
var MailParser = require("mailparser").MailParser;
req.on('message', function (stream, ack) {
stream.pipe(mailparser);
mailparser.on("end", function(mail_object){
console.log(mail_object);//这里就是解析好的mail格式
})
ack.accept();
});
下面我们做一个简单例子,我们用outlook填写一份测试邮件发往node smtp服务器
在node smtp服务器端输出如下格式的内容
MailParser做的相当的不错,还根据信息中的GBK编码,转换成了utf-8,防止了乱码的产生。 这样问题2我们也圆满解决了,正确解析了MIME流的内容
问题3、似乎不是问题,就不多介绍了,使用 Nodemailer 可以很轻松的转发一封电子邮件,大家都用的很熟了。 github地址:https://github.com/andris9/Nodemailer
完成作业了,似乎用node搭建一个简单smtp服务器不比python费多少劲,但是代码量比python要多出不少。 另外需要注意,在node smtp监听了25端口之前,可能需要把sendmail服务器关闭,否则会存在端口inuse错误。
用Node.js搭建简单SMTP服务器
最近在公司用Node.js写了一个小程序,搭建一个简单的SMTP服务器,用来接收邮件,然后根据邮件的收件人地址,再把内容分发到他们的RTX、手机短信和外网邮箱上。原本这个功能有个Python写的例子,全部代码不过80行。感叹Python这门语言确实精练,而且第三方模块和参考资料比Node.js要多,只需简单的import smtpd
模块就可以轻松搞定了,对于MIME解析也只需要import email
这个模块。
但是Python做不到对email流的精准控制(可能是我不懂怎么弄,Py高手别喷啊),而且最近一直在搞Node.js,所以打算用Node.js来实现整个工作流程,顺便也测试下1.0版本的Restify框架。
要完成作业,我们面临以下问题:
- 如何用Node.js建立一个SMTP服务器,监听25端口。
- 如何对MIME流进行解析,变成我们想要的subject、text、from、to等我们需要的东西。
- 如何把邮件转发到外网邮箱。
问题1:如何用Node.js建立一个SMTP服务器,监听25端口
在Google了一阵子之后,我打算使用Substack写的node-smtp-protocol
模块。这个模块的作者是一位非常有才华的开发者,他的代码应该比较可靠。此外,万一有什么问题也可以方便联系到他。
GitHub地址:node-smtp-protocol
以下是简单的示例代码:
const smtp = require('smtp-protocol');
const server = smtp.createServer((req) => {
req.on('greeting', (to, ack) => {
ack.accept(); // 返回状态码250,表示成功
});
req.on('from', (to, ack) => {
ack.accept();
});
req.on('to', (to, ack) => {
// 过滤SMTP请求
filter(to, ack);
});
req.on('message', (stream, ack) => {
// 处理邮件内容
stream.pipe(mailparser);
mailparser.on('end', (mail_object) => {
console.log(mail_object); // 解析好的邮件对象
});
ack.accept();
});
});
server.listen(25);
console.log('Starting mail server listening on port 25.');
这样我们就建立起来了了一个SMTP服务器,我们监听了greeting、from、to和message事件。ack.accept()
代表返回状态码250,表示成功,而message
则表示客户端发送邮件的body流。如果在message之前的阶段你想阻拦这次会话,只需要调用ack.reject()
方法拦截掉即可。
问题2:如何对MIME流进行解析
启动了mail服务器,但是我们对于mail的内容处理还停留在最原始的MIME格式流上。如何正确处理MIME流成为我们获取mail内容的关键问题了。很幸运,我找到了MailParser
这个模块。
GitHub地址:MailParser
这个模块使用起来更加简单,因为node-smtp-protocol
模块提供了stream流,所以我们只需写如下代码就可以解析它:
const MailParser = require('mailparser').MailParser;
req.on('message', (stream, ack) => {
const mailparser = new MailParser();
stream.pipe(mailparser);
mailparser.on('end', (mail_object) => {
console.log(mail_object); // 这里就是解析好的mail格式
});
ack.accept();
});
问题3:如何把邮件转发到外网邮箱
似乎不是问题,使用Nodemailer可以很轻松地转发一封电子邮件。大家都用得很熟了。
GitHub地址:Nodemailer
完成作业了,似乎用Node.js搭建一个简单的SMTP服务器不比Python费多少劲,但是代码量比Python要多出不少。另外需要注意,在Node SMTP监听了25端口之前,可能需要把sendmail服务器关闭,否则会存在端口inuse错误。
求封装
哈哈,封装了还不如用python了就3,4行代码
有smtp的module
mark一下,过一阵能用上。
怎么我发不出邮件,又没有报错