UNPKG

vpn.email

Version:
220 lines (219 loc) 8.37 kB
"use strict"; const Imap = require("imap"); const Async = require("async"); const mailcomposer = require("mailcomposer"); const mailparser = require("mailparser"); const idleInterval = 1000 * 60 * 60 * 24; const openBox = (imap, mailBox, cb) => { if (imap.imap.state !== 'authenticated') { console.log(imap.imap.state); return setTimeout(() => { openBox(imap, mailBox, cb); }, 1000); } imap.imap.openBox(mailBox, false, err => { if (err) { return imap.imap.addBox(mailBox, err1 => { if (err1) return cb(err); openBox(imap, mailBox, cb); }); } return cb(); }); }; const getImapConnect = (nodeImap, debug, forever) => { const keepalive = (/outlook.com$|/.test(nodeImap.imapServer)); const ret = { user: nodeImap.imapUserName, host: nodeImap.imapServer, password: nodeImap.imapUserPassword, port: parseInt(nodeImap.imapPortNumber), tls: nodeImap.imapSsl, debug: debug ? (err) => { console.log(new Date(), ' = ', err); } : null, keepalive: { interval: 400, idleInterval: idleInterval, forceNoop: true } }; return ret; }; class startImap { constructor(imapAcc, listeningFolder, reConnect, delBox, newMailFunction, CallBack) { this.imapAcc = imapAcc; this.listeningFolder = listeningFolder; this.reConnect = reConnect; this.delBox = delBox; this.newMailFunction = newMailFunction; this.CallBack = CallBack; this.lastNewMail = new Date(); this.checkBusy = null; this.destroy = false; this.reConnectCount = 0; this.connected = false; this.fetching = false; this.fetchWait = false; this.busy = false; this.delayTime = null; this.scanEmail = (imap) => { this.fetching = true; this.fetchWait = false; return imap.search(['UNSEEN'], (err, results) => { if (err) { console.log('imap.search error '); if (this.fetchWait) return this.scanEmail(imap); return this.fetching = false; } if (!results || !results.length) { if (this.fetchWait) return this.scanEmail(imap); return this.fetching = false; } let fetch = imap.fetch(results, { markSeen: true, bodies: '' }); fetch.on('message', msg => { let mp = new mailparser.MailParser(); mp.once('end', (msg) => { if (msg.attachments && msg.attachments.length) { return this.newMailFunction(msg.attachments[0].content); } /* const interval = 100 + Math.random () * 200 this.imap._config.keepalive.interval = interval console.log ( 'have not attachments' ) */ }); msg.on('body', (data) => { return data.pipe(mp); }); msg.once('end', () => { }); }); fetch.once('error', err => { this.fetching = this.busy = false; fetch.removeAllListeners(); fetch = null; return console.log(this.imapAcc.imapUserName, ' fetch error ', err); }); fetch.once('end', () => { return Async.series([ next => imap.addFlags(results, ['\\Deleted'], next), next => imap.expunge(results, next) ], err => { fetch.removeAllListeners(); fetch = null; //console.log ( 'fetch.once END!!' ) if (this.fetchWait) return this.scanEmail(imap); return this.busy = this.fetching = this.fetchWait = false; /* this.lastNewMail = new Date () const interval = 100 + Math.random () * 200 this.imap._config.keepalive.interval = interval //console.log ( ' fetch end set new interval = ', interval ) */ }); }); }); }; this.imap = null; this.save = (enCtypeMessage, writeFolder, CallBack) => { if (this.destroy) return; if (!this.connected) { return setTimeout(() => { this.save(enCtypeMessage, writeFolder, CallBack); }, 1000); } this.busy = true; const email = mailcomposer({ attachments: [{ filename: false, content: enCtypeMessage }] }); return Async.waterfall([ next => email.build(next), (data, next) => { //console.log (`${ new Date().toISOString() }===========>[${jj.uuid}][${jj.serial}]->[${jj.command}][${jj.buffer.toString('hex',0,30)}]`) this.imap.append(data, { mailbox: writeFolder }, next); } ], err => { this.busy = false; if (err) { console.log('imap save got error!', err.message); return CallBack(err); } return CallBack(); }); }; const yyy = getImapConnect(imapAcc, false, true); this.connectImap(yyy); } destroyImap() { if (this.busy) { console.log('this.busy destroy wait 5 seconds!', this.listeningFolder); return setTimeout(() => { this.destroyImap(); }, 5000); } this.destroy = true; if (!this.delBox) { return this.imap.end(); } this.imap.delBox(this.listeningFolder, () => { return this.imap.end(); }); } connectImap(yyy) { this.imap = new Imap(yyy); this.imap.once('ready', err => { return openBox(this, this.listeningFolder, err => { if (err) { this.destroyImap(); } this.delayTime = new Date().getTime() - this.delayTime; this.connected = true; }); }); this.imap.on('mail', mail => { this.busy = true; if (this.fetching) return this.fetchWait = true; return this.scanEmail(this.imap); }); this.imap.on('error', (err) => { console.log('err!', err.message); if (this.reConnect || /^Timed out while authenticating with server$|ECONNRESET/.test(err.message)) return setTimeout(() => { if (this.imap && this.imap.connect) { console.log('try re connect'); return this.imap.connect(); } console.log('dont try again'); this.destroy = true; return this.destroyImap(); }, 3000); console.log('this.imap.on error, stop imap'); this.destroy = true; this.imap.removeAllListeners(); this.imap.destroy(); return this.CallBack(err); }); this.imap.once('end', () => { if (this.reConnect && !this.destroy) { return this.connectImap(yyy); } this.imap.removeAllListeners(); this.imap = null; return this.CallBack(null, this.delayTime); }); this.delayTime = new Date().getTime(); return this.imap.connect(); } } Object.defineProperty(exports, "__esModule", { value: true }); exports.default = startImap;