mail-listener2-updated
Version:
Updated Mail listener library for node.js. Get notification when new email arrived.
187 lines (166 loc) • 5.78 kB
JavaScript
var Imap = require('imap');
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var MailParser = require("mailparser").MailParser;
var fs = require("fs");
var path = require('path');
var async = require('async');
module.exports = MailListener;
function MailListener(options) {
this.haveNewEmails = false;
this.parsingUnread = false;
this.markSeen = !!options.markSeen;
this.mailbox = options.mailbox || "INBOX";
if ('string' === typeof options.searchFilter) {
this.searchFilter = [options.searchFilter];
} else {
this.searchFilter = options.searchFilter || ["UNSEEN"];
}
this.fetchUnreadOnStart = !! options.fetchUnreadOnStart;
this.mailParserOptions = options.mailParserOptions || {};
if (options.attachments && options.attachmentOptions && options.attachmentOptions.stream) {
this.mailParserOptions.streamAttachments = true;
}
this.attachmentOptions = options.attachmentOptions || {};
this.attachments = options.attachments || false;
this.attachmentOptions.directory = (this.attachmentOptions.directory ? this.attachmentOptions.directory : '');
this.imap = new Imap({
xoauth2: options.xoauth2,
user: options.username,
password: options.password,
host: options.host,
port: options.port,
tls: options.tls,
tlsOptions: options.tlsOptions || {},
connTimeout: options.connTimeout || null,
authTimeout: options.authTimeout || null,
debug: options.debug || null,
keepalive: options.keepalive || true
});
this.imap.on('ready', imapReady.bind(this));
this.imap.on('close', imapClose.bind(this));
this.imap.on('error', imapError.bind(this));
}
util.inherits(MailListener, EventEmitter);
MailListener.prototype.start = function() {
this.imap.connect();
};
MailListener.prototype.stop = function() {
this.imap.end();
};
MailListener.prototype.restart = function() {
console.log('detaching existing listener');
this.imap.removeAllListeners('mail');
this.imap.removeAllListeners('update');
console.log('calling imap connect');
this.imap.connect();
};
function imapReady() {
var self = this;
this.imap.openBox(this.mailbox, false, function(err, mailbox) {
if (err) {
self.emit('error', err);
} else {
self.emit('server:connected');
if (self.fetchUnreadOnStart) {
parseUnread.call(self);
}
var listener = imapMail.bind(self);
self.imap.on('mail', listener);
self.imap.on('update', listener);
}
});
}
function imapClose() {
this.emit('server:disconnected');
}
function imapError(err) {
this.emit('error', err);
}
function imapMail() {
if (!this.haveNewEmails && !this.parsingUnread) {
parseUnread.call(this);
this.parsingUnread = true;
} else if (this.parsingUnread) {
this.haveNewEmails = true;
}
}
function parseUnread() {
var self = this;
this.imap.search(self.searchFilter, function(err, results) {
if (err) {
self.emit('error', err);
} else if (results.length > 0) {
self.imap.setFlags(results, ['\\Seen'], function (err) {
if (err) {
console.log(JSON.stringify(err, null, 2));
}
});
async.each(results, function (result, callback) {
var f = self.imap.fetch(result, {
bodies: '',
markSeen: self.markSeen
});
f.on('message', function(msg, seqno) {
var parser = new MailParser(self.mailParserOptions);
var attributes = null;
var emlbuffer = new Buffer('');
parser.on("end", function(mail) {
mail.eml = emlbuffer.toString('utf-8');
if (!self.mailParserOptions.streamAttachments && mail.attachments && self.attachments) {
async.each(mail.attachments, function( attachment, callback) {
fs.writeFile(self.attachmentOptions.directory + attachment.generatedFileName, attachment.content, function(err) {
if(err) {
self.emit('error', err);
callback()
} else {
attachment.path = path.resolve(self.attachmentOptions.directory + attachment.generatedFileName);
self.emit('attachment', attachment);
callback()
}
});
}, function(err){
self.emit('mail', mail, seqno, attributes);
callback()
});
} else {
self.emit('mail',mail,seqno,attributes);
callback();
}
});
parser.on("attachment", function (attachment, email) {
self.emit('attachment', attachment, email);
});
msg.on('body', function(stream, info) {
stream.on('data', function(chunk) {
emlbuffer = Buffer.concat([emlbuffer, chunk]);
});
stream.once('end', function() {
parser.write(emlbuffer);
parser.end();
});
});
msg.on('attributes', function(attrs) {
attributes = attrs;
});
});
f.once('error', function(err) {
self.emit('error', err);
});
}, function (err) {
console.log('all process');
if (err) {
self.emit('error', err);
}
if (self.haveNewEmails) {
self.haveNewEmails = false;
parseUnread.call(self);
} else {
self.parsingUnread = false;
}
});
} else {
self.parsingUnread = false;
}
});
}