日期: 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} //禁用对证书有效性的检查 });

  1. //imap 就绪事件 的 回调
  2. imap.once('ready', function () {
  3. //首先获取BoxList,这关系到你要读取哪个邮箱,此处回调函数比较阴间,第一个参数是err,第二个才是boxes
  4. imap.getBoxes('', (err, res) => {
  5. console.log("获取所有信箱")
  6. console.log(Object.keys(res))
  7. })
  8. //打开一个box,收件箱是INBOX,这里我是打开的发件箱
  9. imap.openBox('INBOX', true, function (err, box) {
  10. console.log('===',box)
  11. console.log("打开邮箱")
  12. if (err) throw err;
  13. //这里就是阴间的 search条件了。具体参考node-imap的文档,flag可选项在box对象的flags里看
  14. //已知 SINCE + BEFORE是能识别的,日期格式支持好多种,目前在用yyyy-MM-dd
  15. let searchParam = ['ALL', ['SINCE', start], ['BEFORE', end]]
  16. imap.search(searchParam, function (err, results) {
  17. console.log(results)
  18. if (err) throw err;
  19. const f = imap.fetch(results, {bodies: ''});//抓取邮件
  20. f.on('message', function (msg, seqNo) {
  21. //这里就是我们的Parser了,亲测streamAttachments开了读到的流是空的,建议别开
  22. let mailParser = new MailParser({
  23. // streamAttachments: true
  24. });
  25. msg.on('body', async function (stream, info) {
  26. stream.pipe(mailParser)
  27. //邮件头内容
  28. mailParser.on("headers", function (headers) {
  29. console.log("邮件头信息>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
  30. console.log("邮件主题: " + headers.subject);
  31. console.log("发件人: " + headers.from);
  32. console.log("收件人: " + headers.to);
  33. console.log("x-qq-mid: " + headers['x-qq-mid']);
  34. console.log("date:" + headers.date)
  35. });
  36. //邮件内容
  37. mailParser.on('end', async function (mail) {
  38. /*
  39. 做一些判断,不满满足的就return
  40. */
  41. //从发件者中取第一位
  42. let sender = mail.from[0].address.match(/^.+(?=@)/).join('')
  43. let path = 'mail/' + sender
  44. let dir = await createDir(path)
  45. if (mail.attachments && mail.attachments.length > 0) {
  46. mail.attachments.forEach((data, i) => {
  47. //把主题和文件名拼起来,替换非法字符为_
  48. let filename = `${mail.subject}_${data.fileName}`.replace(/[\x00\/\\:*?"<>|]/g, '_')
  49. //把buffer存文件,注意使用附件文件的transferEncoding
  50. writeFile(dir, filename, data.content, data.transferEncoding)
  51. })
  52. }
  53. })
  54. });
  55. msg.once('end', function () {
  56. console.log(seqNo + '完成');
  57. });
  58. });
  59. f.once('error', function (err) {
  60. console.log('抓取出现错误: ' + err);
  61. });
  62. f.once('end', function () {
  63. console.log('所有邮件抓取完成!');
  64. imap.end();
  65. });
  66. });
  67. });
  68. });
  69. imap.once('error', function (err) {
  70. console.log(err);
  71. reject()
  72. });
  73. imap.once('end', function () {
  74. console.log('Connection ended');
  75. resolve()
  76. });
  77. //开始启动imap链接
  78. imap.connect()
  79. })
  80. },
  81. getUserName(username = '') {
  82. return username.match(/^.+(?=@)/).join('')
  83. },

} 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}); }

  1. - request.js
  2. ```javascript
  3. const mailTool = require('./test').mailTool
  4. const user = {
  5. user:"qinianqing@banu.cn", // 自己的企业邮箱
  6. pwd:"xxxx" // 密码
  7. }
  8. //异步无阻塞
  9. mailTool.downloadAttachment(user,'2021-09-22','2021-09-24').finally()
  10. //同步阻塞
  11. // 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 = {}

  1. //imap 就绪事件 的 回调
  2. imap.once('ready', function () {
  3. //打开一个box,收件箱是INBOX,这里我是打开的发件箱
  4. imap.openBox('INBOX', true, function (err, box) {
  5. if (err) throw err;
  6. //这里就是阴间的 search条件了。具体参考node-imap的文档,flag可选项在box对象的flags里看
  7. //已知 SINCE + BEFORE是能识别的,日期格式支持好多种,目前在用yyyy-MM-dd
  8. let searchParam = ['ALL', ['SINCE', start], ['BEFORE', end]]
  9. imap.search(searchParam, function (err, results) {
  10. console.log(results)
  11. if (err) throw err;
  12. const f = imap.fetch(results, {bodies: ''});//抓取邮件
  13. f.on('message', function (msg, seqNo) {
  14. //这里就是我们的Parser了,亲测streamAttachments开了读到的流是空的,建议别开
  15. let mailParser = new MailParser({
  16. // streamAttachments: true
  17. });
  18. msg.on('body', async function (stream, info) {
  19. stream.pipe(mailParser)
  20. mailParser.on('end', async function (mail) {
  21. let sender = mail.from[0].address.match(/^.+(?=@)/).join('')
  22. if (mail.subject === '银联商务集团商户对账单' && mail.attachments && mail.attachments.length > 0) {
  23. await Promise.map(mail.attachments,async (data,i)=>{
  24. const dataString = data.fileName.split('_')[1].split('.')[0]
  25. // 从流读取
  26. const workbook = new excel.Workbook();
  27. const conteht = await workbook.xlsx.load(data.content)
  28. const sheet = conteht.worksheets[0];
  29. const list = []
  30. sheet.eachRow((row, rowNum) => {
  31. const data = {};
  32. excelLine.forEach(ele => {
  33. if (rowNum === 1) {
  34. keys[ele] = sheet.getCell(`${ele}${rowNum}`).text
  35. } else {
  36. data[keys[ele]] = sheet.getCell(`${ele}${rowNum}`).text
  37. }
  38. })
  39. if(rowNum !== 1) list.push(data)
  40. });
  41. returnData[dataString] = list
  42. })
  43. // mail.attachments.forEach( async (data, i) => {
  44. // const dataString = data.fileName.split('_')[1].split('.')[0]
  45. // // 从流读取
  46. // const workbook = new excel.Workbook();
  47. // const conteht = await workbook.xlsx.load(data.content)
  48. // const sheet = conteht.worksheets[0];
  49. // const list = []
  50. // sheet.eachRow((row, rowNum) => {
  51. // const data = {};
  52. // excelLine.forEach(ele => {
  53. // if (rowNum === 1) {
  54. // keys[ele] = sheet.getCell(`${ele}${rowNum}`).text
  55. // } else {
  56. // data[keys[ele]] = sheet.getCell(`${ele}${rowNum}`).text
  57. // }
  58. // })
  59. // if(rowNum !== 1) list.push(data)
  60. // });
  61. // returnData[dataString] = list
  62. // })
  63. resolve(returnData['20211115'].length)
  64. }
  65. })
  66. });
  67. msg.once('end', function () {
  68. console.log(seqNo + '完成');
  69. });
  70. });
  71. f.once('error', function (err) {
  72. console.log('抓取出现错误: ' + err);
  73. });
  74. f.once('end', function () {
  75. console.log('所有邮件抓取完成!');
  76. imap.end();
  77. });
  78. });
  79. });
  80. });
  81. imap.once('error', function (err) {
  82. console.log(err);
  83. reject()
  84. });
  85. imap.once('end', function () {
  86. console.log('Connection ended');
  87. resolve(returnData)
  88. });
  89. //开始启动imap链接
  90. imap.connect()
  91. })
  92. },
  93. getUserName(username = '') {
  94. return username.match(/^.+(?=@)/).join('')
  95. },

} 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}); }

  1. - request.js
  2. ```javascript
  3. const mailTool = require('./test').mailTool
  4. const { readFile, utils } = require('xlsx');
  5. const fs = require('fs')
  6. const user = {
  7. user: 'szhnlzx@banu.cn', // 自己的企业邮箱
  8. pwd: 'Bn@20212021' // 密码
  9. }
  10. //同步阻塞
  11. async function mail(){
  12. const file = await mailTool.downloadAttachment(user,'2021-11-16','2021-11-17')
  13. }
  14. mail()