需求
客户会发送一些信息到邮箱中,但是还需要这些信息录入到另外的一个管理系统中,由于每天都有邮件,所以想把邮件的内容提取到然后推送到管理系统中。(不要问为啥不直接对接... )
处理思路
通过imap
来登录邮箱,然后读取邮箱中未读的邮件,并将邮件内容进行解析获得,然后提交到指定的接口中。
使用模块
- imap
- mailparser
主要就是这两个。
代码
引入及配置
var Imap = require('imap');
var fs = require('fs');
var path = require('path');
var MailParser = require('mailparser').MailParser;
var axios = require('axios');
var moment = require('moment');
//=================信息配置======================================================
//邮箱地址,需要开启imap服务
var emailAccount = '邮箱账户';
//邮箱密码
var emailPwd = '邮箱密码';
//设置的邮件数量判断,不能超过邮箱内所有邮件数量
var emailCount = 3;
//设置多久未链接收件箱进行重启
var delayTime = 10 * 1000;//10s 未连接上,自动重连
//提交到服务器的地址
var posturl = `提交到的接口地址`
经过多次实际使用测试后的代码
var userInfo = {
user: emailAccount,
password: emailPwd,
host: 'imap.qq.com',
port: 993,
tls: true
};
var data = {
start: 0
};
//数据存储。
function store(data) {
var filePath = path.join(__dirname, 'config.json');
fs.writeFileSync(filePath, JSON.stringify(data));
}
var inflag = false;
function start (){
console.log('-----进入启动函数-----'+moment().format('YYYY-MM-DD HH:mm:ss')+'-------------------------------------');
var imap = new Imap(userInfo);
imap.once('ready', function () {
console.log(`已经成功连接服务器.`)
setTimeout(function(){
if(!inflag){
//重启
console.log(`无法连接收件箱,进行重新连接。`)
imap.end();
}
},delayTime)
imap.openBox('INBOX', false, function(){
inflag = true;
console.log('进入邮件收件箱')
imap.once('mail',function(num){
console.log('ddddddddddddd-----'+num)
})
//检查时间,如果当前时间是晚上10点,则进行一次检索,同时把当天的检索记录保留一下。
var d = new Date();
var daystr = moment().format('YYYY-MM-DD');
var dh = d.getHours();
//检查当天是否已经读取过了,如果读取过的话,则调过,没有则继续。
if(dh == 22 && (!data.day || data.day[daystr] == null || data.day[daystr] == undefined || data.day[data.str] == false)){
var timestr = (new Date(+new Date() - (5 * 60 * 1000))).toISOString();
imap.search(['UNSEEN', ['SINCE', timestr]], function (err, results) {
if (err) {
console.log(`当前无邮件${err.message}`)
data.day[daystr] = true;
store(data);
imap.end();
}else{
try{
console.log('检索到结果:'+results);
var f = imap.fetch(results, {
bodies: ''
});
var maxno = 0;
f.on('message', function (msg, seqno) {
console.log(`新邮件:[${seqno}]`)
var prefix = '(#' + seqno + ') ';
msg.on('body', function (stream, info) {
var parser = new MailParser();
stream.pipe(parser);
//当邮件头部流全部传入mailparser后触发
parser.on("data", function (data) {
console.log(`邮件内容:[${data.text}]`)
//读取结束
console.log('--------------------结束检索邮件--------------------')
//提交到服务器。
if(posturl){
axios.post(posturl,{data :data.text}).then(function(rs){
console.log('服务器返回:'+rs.data+moment().format('YYYY-MM-DD HH:mm:ss'));
});
}
});
});
msg.once('end', function () { });
});
f.once('error', function (err) {
console.log(`收取邮件报错:${err.message}`)
imap.end();
});
f.once('end', function () {
data.day[daystr] = true;
store(data);
imap.end();
});
}catch(e){
}
}
});
}
});
});
imap.on('mail',function(num){
console.log(`收到新邮件数量为:`+num)
if(num > emailCount)return;//一次超过10,不算。
var timestr = (new Date(+new Date() - (5 * 60 * 1000))).toISOString();
console.log(timestr);
//开始检索邮件
console.log(`---------开始检索邮件------------`)
imap.search(['UNSEEN', ['SINCE', timestr]], function (err, results) {
if (err) {
console.log(`当前无邮件${err.message}`)
imap.end();
}else{
try{
console.log('检索到结果:'+results);
var f = imap.fetch(results, {
bodies: ''
});
var maxno = 0;
f.on('message', function (msg, seqno) {
maxno = Math.max(seqno,maxno);
if (seqno <= data.start) { //新邮件
} else {
console.log(`新邮件:[${seqno}]`)
var prefix = '(#' + seqno + ') ';
msg.on('body', function (stream, info) {
var parser = new MailParser();
stream.pipe(parser);
//当邮件头部流全部传入mailparser后触发
parser.on("data", function (data) {
console.log(`邮件内容:[${data.text}]`)
//读取结束
console.log('--------------------结束检索邮件--------------------')
//提交到服务器。
if(posturl){
axios.post(posturl,{data :data.text}).then(function(rs){
console.log('服务器返回:'+rs.data+moment().format('YYYY-MM-DD HH:mm:ss'));
});
}
});
});
msg.once('end', function () { });
}
});
f.once('error', function (err) {
console.log(`收取邮件报错:${err.message}`)
imap.end();
});
f.once('end', function () {
data.start = maxno; //更新文件
store(data);
imap.end();
});
}catch(e){
console.log('当前无未读邮件!'+e.message)
imap.end();
}
}
});
})
imap.once('error', function (err) {
console.log(`链接失败,重新链接。${err.message}`);
start();
});
imap.once('end', function () {
console.log('当前轮次连接结束,启动下一次连接。')
start();
});
imap.connect();
//每隔5分钟重新建立连接
setTimeout(function(){
imap.end();//结束连接。
},5 * 60 * 1000)
}
//第一次先读取
var filePath = path.join(__dirname,'config.json');
if(fs.existsSync(filePath)){
data = JSON.parse(fs.readFileSync(filePath));
}
start();
代码写的很简陋,虽然使用一段时间,不过也一直没有做优化,所以看起来比较乱。不过直接拿着代码放在node环境下是可以直接跑的,等后面有时间了,做一个简易的邮箱客户端练练手。顺手练练electron.