日期: 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,第二个才是boxesimap.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-ddlet 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/' + senderlet 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存文件,注意使用附件文件的transferEncodingwriteFile(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```javascriptconst mailTool = require('./test').mailToolconst 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-ddlet 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```javascriptconst mailTool = require('./test').mailToolconst { 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()
