Skip to content

Commit

Permalink
MailCheck Revamp. Fixes #9
Browse files Browse the repository at this point in the history
  • Loading branch information
polonel committed May 11, 2017
1 parent ed4c9e5 commit cf5101e
Show file tree
Hide file tree
Showing 10 changed files with 206 additions and 90 deletions.
31 changes: 21 additions & 10 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
========================================================================
**/

var async = require('async'),
var _ = require('underscore'),
async = require('async'),
path = require('path'),
fs = require('fs'),
winston = require('winston'),
Expand Down Expand Up @@ -178,28 +179,38 @@ function dbCallback(err, db) {
async.series([
function(next) {
require('./src/socketserver')(ws);
next();
return next();
},
function(next) {
//Start Mailer
var mailQueue = require('./src/mailer');
mailQueue.queue();
next();
return next();
},
function(next) {
//Start Check Mail
var mailerEnabled = nconf.get('mailer:enable');
if (mailerEnabled) {
var mailCheck = require('./src/mailer/mailCheck');
mailCheck.init();
}
var settingSchema = require('./src/models/setting');
settingSchema.getSettings(function(err, settings) {
if (err) {
winston.warn(err);
return next();
}

var mailerCheckEnabled = _.find(settings, function(x) { return x.name === 'mailer:check:enable' });
mailerCheckEnabled = (mailerCheckEnabled === undefined) ? {value: false} : mailerCheckEnabled;
if (mailerCheckEnabled.value) {
var mailCheck = require('./src/mailer/mailCheck');
winston.debug('Starting MailCheck...');
mailCheck.init(settings);
}

next();
return next();
});
},
function(next) {
//Start Task Runners
require('./src/taskrunner');
next();
return next();
},
function(next) {
//var pm2 = require('pm2');
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"kerberos": "0.0.21",
"lodash": "^4.17.4",
"logrotate-stream": "0.2.5",
"mailparser": "0.6.1",
"mailparser": "^2.0.5",
"marked": "0.3.5",
"matchdep": "1.0.1",
"moment": "2.10.2",
Expand Down
2 changes: 2 additions & 0 deletions src/controllers/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,14 @@ settingsController.get = function(req, res) {
s.mailerCheckPort = _.find(settings, function(x) { return x.name === 'mailer:check:port' });
s.mailerCheckUsername = _.find(settings, function(x) { return x.name === 'mailer:check:username' });
s.mailerCheckPassword = _.find(settings, function(x) { return x.name === 'mailer:check:password' });
s.mailerCheckTicketType = _.find(settings, function(x) { return x.name === 'mailer:check:ticketype' });

s.mailerCheckEnabled = (s.mailerCheckEnabled === undefined) ? {value: false} : s.mailerCheckEnabled;
s.mailerCheckHost = (s.mailerCheckHost === undefined) ? {value: ''} : s.mailerCheckHost;
s.mailerCheckPort = (s.mailerCheckPort === undefined) ? {value: 143} : s.mailerCheckPort;
s.mailerCheckUsername = (s.mailerCheckUsername === undefined) ? {value: ''} : s.mailerCheckUsername;
s.mailerCheckPassword = (s.mailerCheckPassword === undefined) ? {value: ''} : s.mailerCheckPassword;
s.mailerCheckTicketType = (s.mailerCheckTicketType === undefined) ? {value: ''} : s.mailerCheckTicketType;

s.showTour = _.find(settings, function(x) { return x.name === 'showTour:enable' });
s.showTour = (s.showTour === undefined) ? {value: true} : s.showTour;
Expand Down
128 changes: 89 additions & 39 deletions src/mailer/mailCheck.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,58 @@
var _ = require('underscore');
var async = require('async');
var Imap = require('imap');
//var inspect = require('util').inspect;
//var MailParser = require('mailparser').MailParser;
var winston = require('winston');
var nconf = require('nconf');
var marked = require('marked');
var simpleParser = require('mailparser').simpleParser;

var emitter = require('../emitter');
var userSchema = require('../models/user');
var groupSchema = require('../models/group');
var ticketTypeSchema = require('../models/tickettype');
var Ticket = require('../models/ticket');

var MAILERCHECK_ENABLED = nconf.get('mailer:check:enable');
var MAILERCHECK_USER = nconf.get('mailer:check:user') ? nconf.get('mailer:check:user') : MAILERCHECK_ENABLED = false;
var MAILERCHECK_PASS = nconf.get('mailer:check:pass') ? nconf.get('mailer:check:pass') : MAILERCHECK_ENABLED = false;
var MAILERCHECK_HOST = nconf.get('mailer:check:host') ? nconf.get('mailer:check:host') : MAILERCHECK_ENABLED = false;
var POLLING_INTERVAL = nconf.get('mailer:check:polling') ? nconf.get('mailer:check:polling') : 600000; //10 min
var DEFAULT_TICKET_TYPE = nconf.get('mailer:check:defaultTicketType') ? nconf.get('mailer:check:defaultTicketType') : 'Issue';

var mailCheck = {};
mailCheck.Imap = new Imap({
user: MAILERCHECK_USER,
password: MAILERCHECK_PASS,
host: MAILERCHECK_HOST,
port: 143
});

mailCheck.inbox = [];

mailCheck.init = function() {
mailCheck.init = function(settings) {
var s = {};
s.mailerCheckEnabled = _.find(settings, function(x) { return x.name === 'mailer:check:enable' });
s.mailerCheckHost = _.find(settings, function(x) { return x.name === 'mailer:check:host' });
s.mailerCheckPort = _.find(settings, function(x) { return x.name === 'mailer:check:port' });
s.mailerCheckUsername = _.find(settings, function(x) { return x.name === 'mailer:check:username' });
s.mailerCheckPassword = _.find(settings, function(x) { return x.name === 'mailer:check:password' });
s.mailerCheckTicketType = _.find(settings, function(x) { return x.name === 'mailer:check:ticketype' });

s.mailerCheckEnabled = (s.mailerCheckEnabled === undefined) ? {value: false} : s.mailerCheckEnabled;
s.mailerCheckHost = (s.mailerCheckHost === undefined) ? {value: ''} : s.mailerCheckHost;
s.mailerCheckPort = (s.mailerCheckPort === undefined) ? {value: 143} : s.mailerCheckPort;
s.mailerCheckUsername = (s.mailerCheckUsername === undefined) ? {value: ''} : s.mailerCheckUsername;
s.mailerCheckPassword = (s.mailerCheckPassword === undefined) ? {value: ''} : s.mailerCheckPassword;
s.mailerCheckTicketType = (s.mailerCheckTicketType === undefined) ? {value: 'Issue'} : s.mailerCheckTicketType;

var MAILERCHECK_ENABLED = s.mailerCheckEnabled.value;
var MAILERCHECK_HOST = s.mailerCheckHost.value;
var MAILERCHECK_USER = s.mailerCheckUsername.value;
var MAILERCHECK_PASS = s.mailerCheckPassword.value;
var POLLING_INTERVAL = 600000; //10 min
var DEFAULT_TICKET_TYPE = s.mailerCheckTicketType.value;

if (!MAILERCHECK_ENABLED) return true;

mailCheck.fetchMail();
mailCheck.Imap = new Imap({
user: MAILERCHECK_USER,
password: MAILERCHECK_PASS,
host: MAILERCHECK_HOST,
port: 143
});

mailCheck.fetchMail(DEFAULT_TICKET_TYPE);
setInterval(function() {
mailCheck.fetchMail();
mailCheck.fetchMail(DEFAULT_TICKET_TYPE);
}, POLLING_INTERVAL);
};

mailCheck.fetchMail = function() {
mailCheck.fetchMail = function(DEFAULT_TICKET_TYPE) {
mailCheck.Imap.connect();
mailCheck.Imap.once('error', function(err) {
winston.warn(err);
Expand Down Expand Up @@ -83,7 +96,8 @@ mailCheck.fetchMail = function() {

var f = mailCheck.Imap.fetch(results, {
//markSeen: true,
bodies: ['HEADER.FIELDS (FROM SUBJECT)','TEXT']
// bodies: ['HEADER.FIELDS (FROM SUBJECT CONTENT-TYPE)','TEXT']
bodies: ''
});

f.on('message', function(msg, seqno) {
Expand All @@ -93,17 +107,36 @@ mailCheck.fetchMail = function() {
count += chunk.length;
buffer += chunk.toString('utf8');
});

stream.once('end', function() {
if (info.which !== 'TEXT') {
var header = Imap.parseHeader(buffer);
if (_.isArray(header.subject) && _.size(header.subject) > 0)
message.subject = header.subject[0];
if (_.isArray(header.from) && _.size(header.from) > 0)
message.from = parseEmail(header.from[0]);
} else
message.body = buffer;
simpleParser(buffer, function(err, mail) {
if (err) winston.warn(err);

if (mail.headers.has('from')) {
message.from = mail.headers.get('from').value[0].address;
}
if (mail.subject) {
message.subject = mail.subject;
} else {
message.subject = message.from;
}

message.body = mail.textAsHtml;
});

// if (info.which !== 'TEXT') {
// var header = Imap.parseHeader(buffer);
// if (_.isArray(header.subject) && _.size(header.subject) > 0)
// message.subject = header.subject[0];
// if (_.isArray(header.from) && _.size(header.from) > 0)
// message.from = parseEmail(header.from[0]);
// if (_.isArray(header['content-type']) && _.size(header['content-type']) > 0)
// message.contentType = header['content-type'][0];
// } else
// message.body = buffer;
});
});

async.series([
function(cb) {
msg.once('end', function() {
Expand All @@ -122,8 +155,25 @@ mailCheck.fetchMail = function() {

if (_.size(group) < 1) return cb();

ticketTypeSchema.getTypeByName(DEFAULT_TICKET_TYPE, function(err, type) {
if (err) return cb(err);
async.waterfall([
function(d) {
if (DEFAULT_TICKET_TYPE !== 'Issue') return d(null, null);
ticketTypeSchema.getTypeByName(DEFAULT_TICKET_TYPE, function(err, t) {
if (err) return d(err);

return d(null, t);
});
},
function(type, d) {
if (type !== null) return d(null, type);
ticketTypeSchema.getType(DEFAULT_TICKET_TYPE, function(err, t) {
if (err) return d(err);

return d(null, t);
});
}
], function(err, type) {
if (err || type == null) return cb(err);

var HistoryItem = {
action: 'ticket:created',
Expand All @@ -139,7 +189,7 @@ mailCheck.fetchMail = function() {
status: 0,
priority: 1,
subject: message.subject,
issue: parseBody(message.body),
issue: message.body,
history: [HistoryItem]
}, function(err, t) {
if (err) {
Expand All @@ -149,19 +199,19 @@ mailCheck.fetchMail = function() {

emitter.emit('ticket:created', {socketId: '', ticket: t});

cb();
return cb();
});
});
});

} else
cb();
return cb();

} else {
mailCheck.Imap.seq.addFlags(seqno, '\\Deleted', function(err) {
if (err) winston.warn(err);

cb();
return cb();
});
}
});
Expand All @@ -173,19 +223,19 @@ mailCheck.fetchMail = function() {

f.once('error', function(err) {
winston.error('Fetch error: ' + err);
next(err);
return next(err);
});

f.once('end', function() {
next();
return next();
});
});
});
}
], function(err) {
if (err) winston.warn(err);
mailCheck.Imap.closeBox(true, function(err) {
winston.debug(err);
if (err) winston.debug(err);
mailCheck.Imap.end();
});
});
Expand Down
2 changes: 1 addition & 1 deletion src/models/setting.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ var settingSchema = mongoose.Schema({
* @param {QueryCallback} callback MongoDB Query Callback
*/
settingSchema.statics.getSettings = function(callback) {
var q = this.model(COLLECTION).find({});
var q = this.model(COLLECTION).find({}).select('name value');

return q.exec(callback);
};
Expand Down
16 changes: 16 additions & 0 deletions src/models/tickettype.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@ ticketTypeSchema.statics.getTypes = function(callback) {
return q.exec(callback);
};

/**
* Return Single Ticket Types
*
* @memberof TicketType
* @static
* @method getType
*
* @param {String} id Object Id of ticket type
* @param {QueryCallback} callback MongoDB Query Callback
*/
ticketTypeSchema.statics.getType = function(id, callback) {
var q = this.model(COLLECTION).findOne({_id: id}).lean();

return q.exec(callback);
};

/**
* Return Single Ticket Type based on given type name
*
Expand Down
21 changes: 18 additions & 3 deletions src/public/js/angularjs/controllers/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ define(['angular', 'underscore', 'jquery', 'modules/helpers', 'modules/ui', 'uik
s.addClass('md-input-filled');
}
});

if ($scope.mailerCheckTicketType !== '') {
var $mailerCheckTicketTypeSelect = $('#mailerCheckTicketType');
$mailerCheckTicketTypeSelect.find('option[value="' + $scope.mailerCheckTicketType + '"]').prop('selected', true);
var $selectizeTicketType = $mailerCheckTicketTypeSelect[0].selectize;
$selectizeTicketType.setValue($scope.mailerCheckTicketType, true);
$selectizeTicketType.refreshItems();
}
}, 0);
};

Expand Down Expand Up @@ -118,6 +126,10 @@ define(['angular', 'underscore', 'jquery', 'modules/helpers', 'modules/ui', 'uik
$('input#mailerCheckUsername').attr('disabled', !newVal);
$('input#mailerCheckPassword').attr('disabled', !newVal);
$('button#mailerCheckSubmit').attr('disabled', !newVal);
if (!newVal == true)
$('select#mailerCheckTicketType').selectize()[0].selectize.disable();
else
$('select#mailerCheckTicketType').selectize()[0].selectize.enable();
});

$scope.mailerCheckEnabledChange = function() {
Expand All @@ -140,21 +152,24 @@ define(['angular', 'underscore', 'jquery', 'modules/helpers', 'modules/ui', 'uik

$scope.mailerCheckFormSubmit = function($event) {
$event.preventDefault();

var mailerCheckTicketTypeValue = $('#mailerCheckTicketType option[selected]').val();
$http.put('/api/v1/settings', [
{name: 'mailer:check:host', value: $scope.mailerCheckHost},
{name: 'mailer:check:port', value: $scope.mailerCheckPort},
{name: 'mailer:check:username', value: $scope.mailerCheckUsername},
{name: 'mailer:check:password', value: $scope.mailerCheckPassword}
{name: 'mailer:check:password', value: $scope.mailerCheckPassword},
{name: 'mailer:check:ticketype', value: mailerCheckTicketTypeValue}

], {
headers: {
'Content-Type': 'application/json'
}
}).then(function successCallback() {
helpers.UI.showSnackbar('Mail Check Settings Saved', false);

}, function errorCallback(err) {
helpers.UI.showSnackbar(err, true);
helpers.UI.showSnackbar(err.data.error, true);
$log.error(err);
});
};

Expand Down
Loading

0 comments on commit cf5101e

Please sign in to comment.