日期: 2021/09/27 天气:多云
读取邮件
- test.js ```javascript const Imap = require(‘imap’); const MailParser = require(“mailparser-mit”).MailParser; const fs = require(“fs”); const Path = require(“path”) const pathPrefix = Path.join(__dirname, ‘../uploads/‘)
exports.mailTool = { downloadAttachment: (user, start, end) => { return new Promise((resolve, reject) => { //构建一个Imap let imap = new Imap({ user: user.user, //你的邮箱账号 password: user.pwd, //你的邮箱密码 host: ‘imap.exmail.qq.com’, //邮箱服务器的主机地址 以腾讯企业邮箱为例子 port: 993, //邮箱服务器的端口地址 tls: true, //使用安全传输协议 tlsOptions: {rejectUnauthorized: false} //禁用对证书有效性的检查 });
//imap 就绪事件 的 回调
imap.once('ready', function () {
//首先获取BoxList,这关系到你要读取哪个邮箱,此处回调函数比较阴间,第一个参数是err,第二个才是boxes
imap.getBoxes('', (err, res) => {
console.log("获取所有信箱")
console.log(Object.keys(res))
})
//打开一个box,收件箱是INBOX,这里我是打开的发件箱
imap.openBox('INBOX', true, function (err, box) {
console.log('===',box)
console.log("打开邮箱")
if (err) throw err;
//这里就是阴间的 search条件了。具体参考node-imap的文档,flag可选项在box对象的flags里看
//已知 SINCE + BEFORE是能识别的,日期格式支持好多种,目前在用yyyy-MM-dd
let searchParam = ['ALL', ['SINCE', start], ['BEFORE', end]]
imap.search(searchParam, function (err, results) {
console.log(results)
if (err) throw err;
const f = imap.fetch(results, {bodies: ''});//抓取邮件
f.on('message', function (msg, seqNo) {
//这里就是我们的Parser了,亲测streamAttachments开了读到的流是空的,建议别开
let mailParser = new MailParser({
// streamAttachments: true
});
msg.on('body', async function (stream, info) {
stream.pipe(mailParser)
//邮件头内容
mailParser.on("headers", function (headers) {
console.log("邮件头信息>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
console.log("邮件主题: " + headers.subject);
console.log("发件人: " + headers.from);
console.log("收件人: " + headers.to);
console.log("x-qq-mid: " + headers['x-qq-mid']);
console.log("date:" + headers.date)
});
//邮件内容
mailParser.on('end', async function (mail) {
/*
做一些判断,不满满足的就return
*/
//从发件者中取第一位
let sender = mail.from[0].address.match(/^.+(?=@)/).join('')
let path = 'mail/' + sender
let dir = await createDir(path)
if (mail.attachments && mail.attachments.length > 0) {
mail.attachments.forEach((data, i) => {
//把主题和文件名拼起来,替换非法字符为_
let filename = `${mail.subject}_${data.fileName}`.replace(/[\x00\/\\:*?"<>|]/g, '_')
//把buffer存文件,注意使用附件文件的transferEncoding
writeFile(dir, filename, data.content, data.transferEncoding)
})
}
})
});
msg.once('end', function () {
console.log(seqNo + '完成');
});
});
f.once('error', function (err) {
console.log('抓取出现错误: ' + err);
});
f.once('end', function () {
console.log('所有邮件抓取完成!');
imap.end();
});
});
});
});
imap.once('error', function (err) {
console.log(err);
reject()
});
imap.once('end', function () {
console.log('Connection ended');
resolve()
});
//开始启动imap链接
imap.connect()
})
},
getUserName(username = '') {
return username.match(/^.+(?=@)/).join('')
},
}
function createDir(path) {
let dir = pathPrefix + path + “/“
return new Promise((resolve, reject) => {
const exists = fs.existsSync(dir);
if (!exists) {
fs.mkdir(dir, {recursive: true},function (err) {
if (err) {
reject(err);
} else {
console.log(目录创建${dir}成功。
);
resolve(dir)
}
});
} else {
resolve(dir)
}
})
}
function writeFile(path,name,file,type = ‘binary’){ return fs.writeFileSync(path + name,file,{encoding:type}); }
- request.js
```javascript
const mailTool = require('./test').mailTool
const user = {
user:"qinianqing@banu.cn", // 自己的企业邮箱
pwd:"xxxx" // 密码
}
//异步无阻塞
mailTool.downloadAttachment(user,'2021-09-22','2021-09-24').finally()
//同步阻塞
// await mailTool.downloadAttachment(user,'2019-05-01','2019-07-01')
读出邮件中的Excal
- test.js ```javascript const Imap = require(‘imap’); const MailParser = require(“mailparser-mit”).MailParser; const fs = require(“fs”); const stream = require(‘stream’) const Path = require(“path”) const pathPrefix = Path.join(__dirname, “./mail”); const Promise = require(‘bluebird’);
const excel = require(‘exceljs’)
const excelLine = [‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘H’, ‘I’, ‘K’, ‘L’, ‘M’, ‘N’, ‘O’, ‘P’, ‘Q’, ‘R’, ‘S’]
exports.mailTool = { downloadAttachment: (user, start, end) => { return new Promise((resolve, reject) => { //构建一个Imap let imap = new Imap({ user: user.user, //你的邮箱账号 password: user.pwd, //你的邮箱密码 host: ‘imap.exmail.qq.com’, //邮箱服务器的主机地址 以腾讯企业邮箱为例子 port: 993, //邮箱服务器的端口地址 tls: true, //使用安全传输协议 tlsOptions: {rejectUnauthorized: false} //禁用对证书有效性的检查 }); const returnData= {} const keys = {}
//imap 就绪事件 的 回调
imap.once('ready', function () {
//打开一个box,收件箱是INBOX,这里我是打开的发件箱
imap.openBox('INBOX', true, function (err, box) {
if (err) throw err;
//这里就是阴间的 search条件了。具体参考node-imap的文档,flag可选项在box对象的flags里看
//已知 SINCE + BEFORE是能识别的,日期格式支持好多种,目前在用yyyy-MM-dd
let searchParam = ['ALL', ['SINCE', start], ['BEFORE', end]]
imap.search(searchParam, function (err, results) {
console.log(results)
if (err) throw err;
const f = imap.fetch(results, {bodies: ''});//抓取邮件
f.on('message', function (msg, seqNo) {
//这里就是我们的Parser了,亲测streamAttachments开了读到的流是空的,建议别开
let mailParser = new MailParser({
// streamAttachments: true
});
msg.on('body', async function (stream, info) {
stream.pipe(mailParser)
mailParser.on('end', async function (mail) {
let sender = mail.from[0].address.match(/^.+(?=@)/).join('')
if (mail.subject === '银联商务集团商户对账单' && mail.attachments && mail.attachments.length > 0) {
await Promise.map(mail.attachments,async (data,i)=>{
const dataString = data.fileName.split('_')[1].split('.')[0]
// 从流读取
const workbook = new excel.Workbook();
const conteht = await workbook.xlsx.load(data.content)
const sheet = conteht.worksheets[0];
const list = []
sheet.eachRow((row, rowNum) => {
const data = {};
excelLine.forEach(ele => {
if (rowNum === 1) {
keys[ele] = sheet.getCell(`${ele}${rowNum}`).text
} else {
data[keys[ele]] = sheet.getCell(`${ele}${rowNum}`).text
}
})
if(rowNum !== 1) list.push(data)
});
returnData[dataString] = list
})
// mail.attachments.forEach( async (data, i) => {
// const dataString = data.fileName.split('_')[1].split('.')[0]
// // 从流读取
// const workbook = new excel.Workbook();
// const conteht = await workbook.xlsx.load(data.content)
// const sheet = conteht.worksheets[0];
// const list = []
// sheet.eachRow((row, rowNum) => {
// const data = {};
// excelLine.forEach(ele => {
// if (rowNum === 1) {
// keys[ele] = sheet.getCell(`${ele}${rowNum}`).text
// } else {
// data[keys[ele]] = sheet.getCell(`${ele}${rowNum}`).text
// }
// })
// if(rowNum !== 1) list.push(data)
// });
// returnData[dataString] = list
// })
resolve(returnData['20211115'].length)
}
})
});
msg.once('end', function () {
console.log(seqNo + '完成');
});
});
f.once('error', function (err) {
console.log('抓取出现错误: ' + err);
});
f.once('end', function () {
console.log('所有邮件抓取完成!');
imap.end();
});
});
});
});
imap.once('error', function (err) {
console.log(err);
reject()
});
imap.once('end', function () {
console.log('Connection ended');
resolve(returnData)
});
//开始启动imap链接
imap.connect()
})
},
getUserName(username = '') {
return username.match(/^.+(?=@)/).join('')
},
}
function createDir(path) {
let dir = pathPrefix + path + “/“
return new Promise((resolve, reject) => {
const exists = fs.existsSync(dir);
if (!exists) {
fs.mkdir(dir, {recursive: true},function (err) {
if (err) {
reject(err);
} else {
console.log(目录创建${dir}成功。
);
resolve(dir)
}
});
} else {
resolve(dir)
}
})
}
function writeFile(path,name,file,type = ‘binary’){ return fs.writeFileSync(path + name,file,{encoding:type}); }
- request.js
```javascript
const mailTool = require('./test').mailTool
const { readFile, utils } = require('xlsx');
const fs = require('fs')
const user = {
user: 'szhnlzx@banu.cn', // 自己的企业邮箱
pwd: 'Bn@20212021' // 密码
}
//同步阻塞
async function mail(){
const file = await mailTool.downloadAttachment(user,'2021-11-16','2021-11-17')
}
mail()