Subject: Built motion from commit e202e64.|0.0.141
From: Daniele Cinti <[email-masked]>
Date: Tue, 13 Sep 2016 14:46:02 +0000 (+0200)

Built motion from commit e202e64.|0.0.141
---

diff --git a/release-notes/changelog_0.0.141.txt b/release-notes/changelog_0.0.141.txt
index 9e208ed..d71ea6c 100644
--- a/release-notes/changelog_0.0.141.txt
+++ b/release-notes/changelog_0.0.141.txt
@@ -1,5 +1,8 @@
 # xCALLY MOTION Changelog
 
+- * 49fe26d - 2016-09-13: move socket dashboard 
+- * 4eae3b4 - 2016-09-13: Added emitter to scheduler service 
+- * 9270b6b - 2016-09-13: Fixed triggers with emitter; Fixed agi. 
 - * 5fb560b - 2016-09-13: server side config/ami + config/tools update 
 - * 51d6d3e - 2016-09-13: server side update 
 - * 9750695 - 2016-09-13: fix duplicate events 
@@ -78,6 +81,4 @@
 - * 0a64ca2 - 2016-09-07: Updated ui-select; Fixed sounds and announces in queue settings. 
 - * 16b208a - 2016-09-07: new version 
 - * 54a160d - 2016-09-07: fixed chat error 
-- * 9d72825 - 2016-09-06: Fixed customfields in case the select json value exceeds the varchar limit (changed to TEXT) and added a check to recover the failing customfields 
-- * 2c30e8c - 2016-09-06: Fixed license for report xtraction and xchatty 
 
diff --git a/server/api/trigger/trigger.controller.js b/server/api/trigger/trigger.controller.js
index f3a4806..dbb3e29 100644
--- a/server/api/trigger/trigger.controller.js
+++ b/server/api/trigger/trigger.controller.js
@@ -70,89 +70,100 @@ exports.update = function(req, res, next) {
   if (req.body.id) {
     delete req.body.id;
   }
-  return sequelize.transaction(function(t) {
-      return Trigger
-        .findById(req.params.id)
-        .then(function(trigger) {
-          _trigger = trigger;
-          if (req.body.Any) {
-            return ToolsCondition
-              .destroy({
-                where: {
-                  TriggerAnyId: req.params.id
-                },
-                transaction: t
-              });
-          }
-          return;
-        })
-        .then(function() {
-          if (req.body.Any && Array.isArray(req.body.Any) && req.body.Any.length) {
-            _.forEach(req.body.Any, function(elem) {
-              elem.TriggerAnyId = req.params.id;
-            });
-            return ToolsCondition
-              .bulkCreate(req.body.Any, {
-                transaction: t
-              });
-          }
-          return;
-        })
-        .then(function() {
-          if (req.body.All) {
-            return ToolsCondition
-              .destroy({
-                where: {
-                  TriggerAllId: req.params.id
-                },
-                transaction: t
-              });
-          }
-          return;
-        })
-        .then(function() {
-          if (req.body.All && Array.isArray(req.body.All) && req.body.All.length) {
-            _.forEach(req.body.All, function(elem) {
-              elem.TriggerAllId = req.params.id;
-            });
-            return ToolsCondition
-              .bulkCreate(req.body.All, {
-                transaction: t
-              });
-          }
-          return;
-        })
-        .then(function() {
-          if (req.body.Actions) {
-            return ToolsAction
-              .destroy({
-                where: {
-                  TriggerId: req.params.id
-                },
-                transaction: t
-              });
-          }
-          return;
-        })
-        .then(function() {
-          if (req.body.Actions && Array.isArray(req.body.Actions) && req.body.Actions.length) {
-            _.forEach(req.body.Actions, function(elem) {
-              elem.TriggerId = req.params.id;
-            });
-            return ToolsAction
-              .bulkCreate(req.body.Actions, {
-                transaction: t
-              });
-          }
-          return;
-        })
-        .then(function() {
-          var updated = _.merge(_trigger, req.body);
-          return updated
-            .save({
-              transaction: t
-            });
+  // return sequelize.transaction(function(t) {
+  return Trigger
+    .findById(req.params.id)
+    .then(function(trigger) {
+      _trigger = trigger;
+      if (req.body.Any) {
+        return ToolsCondition
+          .destroy({
+            where: {
+              TriggerAnyId: req.params.id
+            }
+            // ,
+            // transaction: t
+          });
+      }
+      return;
+    })
+    .then(function() {
+      if (req.body.Any && Array.isArray(req.body.Any) && req.body.Any.length) {
+        _.forEach(req.body.Any, function(elem) {
+          elem.TriggerAnyId = req.params.id;
         });
+        return ToolsCondition
+          .bulkCreate(req.body.Any
+            //   , {
+            //   transaction: t
+            // }
+          );
+      }
+      return;
+    })
+    .then(function() {
+      if (req.body.All) {
+        return ToolsCondition
+          .destroy({
+            where: {
+              TriggerAllId: req.params.id
+            }
+            // ,
+            // transaction: t
+          });
+      }
+      return;
+    })
+    .then(function() {
+      if (req.body.All && Array.isArray(req.body.All) && req.body.All.length) {
+        _.forEach(req.body.All, function(elem) {
+          elem.TriggerAllId = req.params.id;
+        });
+        return ToolsCondition
+          .bulkCreate(req.body.All
+            //   , {
+            //   transaction: t
+            // }
+          );
+      }
+      return;
+    })
+    .then(function() {
+      if (req.body.Actions) {
+        return ToolsAction
+          .destroy({
+            where: {
+              TriggerId: req.params.id
+            }
+            // ,
+            // transaction: t
+          });
+      }
+      return;
+    })
+    .then(function() {
+      if (req.body.Actions && Array.isArray(req.body.Actions) && req.body.Actions.length) {
+        _.forEach(req.body.Actions, function(elem) {
+          elem.TriggerId = req.params.id;
+        });
+        return ToolsAction
+          .bulkCreate(req.body.Actions
+            //   , {
+            //   transaction: t
+            // }
+          );
+      }
+      return;
+    })
+    .then(function() {
+      var updated = _.merge(_trigger, req.body);
+      return updated
+        .save(
+          //   {
+          //   transaction: t
+          // }
+        );
+      // });
     })
     .then(function() {
       return res.sendStatus(200);
diff --git a/server/app.js b/server/app.js
index eda90e8..0d6efa4 100644
--- a/server/app.js
+++ b/server/app.js
@@ -70,17 +70,18 @@ if (!sticky.listen(server, config.port)) {
       require('./config/automations/mail')();
       require('./config/automations/fax')();
       require('./config/automations/chat')();
-      require('./config/triggers')(ami); // max
+      require('./config/triggers')(ami);
       require('./config/ami')(ami); // dani
-      require('./config/scheduler')(); // max
+      require('./config/scheduler')();
       require('./config/imap')(); // dani
       require('./config/smtp')() // dani
       require('./config/sms')(); // andre
       require('./config/chat')(); // andre
       require('./config/openchannel')();
       require('./config/tools')(); // dani
-      require('./config/agi')(); // max
+      require('./config/agi')();
       require('./config/license')(); // no hooks
+      require('./services/dashboard')();
     })
     .then(function() {
       // Connect to database history
@@ -110,7 +111,7 @@ if (!sticky.listen(server, config.port)) {
     port: 6379
   }));
 
-  require('./config/socketio')(io, require('./services/dashboard')(io));
+  require('./config/socketio')(io);
 }
 
 // Expose app
diff --git a/server/config/agi/agi.js b/server/config/agi/agi.js
index 89f0bc9..6514c00 100644
--- a/server/config/agi/agi.js
+++ b/server/config/agi/agi.js
@@ -1752,7 +1752,7 @@ function getUsers(synch) {
   return User
     .findAll()
     .then(function(result) {
-      collections.users = _.clone(result);
+      collections.users = _.map(result, 'dataValues');
       if (synch) {
         synchUpdates('User', 'users', 'id');
       }
@@ -1766,7 +1766,7 @@ function getQueues(synch) {
   return VoiceQueue
     .findAll()
     .then(function(result) {
-      collections.queues = _.clone(result);
+      collections.queues = _.map(result, 'dataValues');
       if (synch) {
         synchUpdates('VoiceQueue', 'queues', 'name');
       }
@@ -1780,7 +1780,7 @@ function getVariables(synch) {
   return Variable
     .findAll()
     .then(function(result) {
-      collections.variables = _.clone(result);
+      collections.variables = _.map(result, 'dataValues');
       if (synch) {
         synchUpdates('Variable', 'variables', 'id');
       }
@@ -1794,7 +1794,7 @@ function getDbConnections(synch) {
   return SquareOdbc
     .findAll()
     .then(function(result) {
-      collections.dbConnections = _.clone(result);
+      collections.dbConnections = _.map(result, 'dataValues');
       if (synch) {
         synchUpdates('SquareOdbc', 'dbConnections', 'id');
       }
@@ -1808,7 +1808,7 @@ function getIntervals(synch) {
   return Interval
     .findAll()
     .then(function(result) {
-      collections.intervals = _.clone(result);
+      collections.intervals = _.map(result, 'dataValues');
       if (synch) {
         synchUpdates('Interval', 'intervals');
       }
@@ -1822,7 +1822,7 @@ function getProjects(synch) {
   return SquareProject
     .findAll()
     .then(function(result) {
-      collections.projects = _.clone(result);
+      collections.projects = _.map(result, 'dataValues');
       if (synch) {
         synchUpdates('SquareProject', 'projects', 'id');
       }
@@ -1836,7 +1836,7 @@ function getSounds(synch) {
   return Sound
     .findAll()
     .then(function(result) {
-      collections.sounds = _.clone(result);
+      collections.sounds = _.map(result, 'dataValues');
       if (synch) {
         synchUpdates('Sound', 'sounds', 'id');
       }
@@ -1850,7 +1850,7 @@ function getMailServerOut(synch) {
   return MailServerOut
     .findAll()
     .then(function(result) {
-      collections.mailServerOut = _.clone(result);
+      collections.mailServerOut = _.map(result, 'dataValues');
       if (synch) {
         synchUpdates('MailServerOut', 'mailServerOut', 'id');
       }
@@ -1864,7 +1864,7 @@ function getTemplates(synch) {
   return Template
     .findAll()
     .then(function(result) {
-      collections.templates = _.clone(result);
+      collections.templates = _.map(result, 'dataValues');
       if (synch) {
         synchUpdates('Template', 'templates', 'id');
       }
@@ -1878,7 +1878,7 @@ function getSmsAccounts(synch) {
   return SmsAccount
     .findAll()
     .then(function(result) {
-      collections.smsAccounts = _.clone(result);
+      collections.smsAccounts = _.map(result, 'dataValues');
       if (synch) {
         synchUpdates('SmsAccount', 'smsAccounts', 'id');
       }
diff --git a/server/config/agi/index.js b/server/config/agi/index.js
index 4f1d0dd..a88b659 100644
--- a/server/config/agi/index.js
+++ b/server/config/agi/index.js
@@ -103,36 +103,6 @@ function synchCollection(data, child) {
   });
 }
 
-// function synchCollection(data, child) {
-//   var condition = {};
-//   models[data.model].afterCreate(function(doc) {
-//     condition[data.key] = doc[data.key];
-//     child.send({
-//       message: 'updateCollection',
-//       collection: data.collection,
-//       condition: condition,
-//       doc: doc
-//     });
-//   });
-//   models[data.model].afterUpdate(function(doc) {
-//     condition[data.key] = doc[data.key];
-//     child.send({
-//       message: 'updateCollection',
-//       collection: data.collection,
-//       condition: condition,
-//       doc: doc
-//     });
-//   });
-//   models[data.model].afterDestroy(function(doc) {
-//     condition[data.key] = doc[data.key];
-//     child.send({
-//       message: 'removeFromCollection',
-//       collection: data.collection,
-//       condition: condition
-//     });
-//   });
-// }
-
 function replaceCollection(data, child) {
   emitter.on(data.model + '.afterCreate', function(doc) {
     getCollection(data, child, doc);
@@ -145,18 +115,6 @@ function replaceCollection(data, child) {
   });
 }
 
-// function replaceCollection(data, child) {
-//   models[data.model].afterCreate(function(doc) {
-//     getCollection(data, child, doc);
-//   });
-//   models[data.model].afterUpdate(function(doc) {
-//     getCollection(data, child, doc);
-//   });
-//   models[data.model].afterDestroy(function(doc) {
-//     getCollection(data, child, doc);
-//   });
-// }
-
 function getCollection(data, child, doc) {
   models[data.model]
     .findAll()
diff --git a/server/config/scheduler/index.js b/server/config/scheduler/index.js
index 429d7a2..f9d13b0 100644
--- a/server/config/scheduler/index.js
+++ b/server/config/scheduler/index.js
@@ -3,6 +3,7 @@ var MailServerOut = require('../../models').MailServerOut;
 var CronJobManager = require('cron-job-manager');
 var _ = require('lodash');
 var Reports = require('./reports');
+var emitter = require('cluster-emitter');

 function deleteSchedule(data, manager) {
@@ -89,15 +90,16 @@ function executeSchedule(scheduleId, reports) {
 }
 
 function synchSchedules(manager, reports) {
-  Schedule.afterCreate(function(doc, options) {
+  emitter.on('Schedule.afterCreate', function(doc) {
     if (doc.active) {
-      createJob(doc.dataValues, manager, reports);
+      createJob(doc, manager, reports);
     }
   });
-  Schedule.afterUpdate(function(doc, options) {
-    updateSchedule(doc.dataValues, manager, reports);
+  emitter.on('Schedule.afterUpdate', function(doc) {
+    updateSchedule(doc, manager, reports);
   });
-  Schedule.afterDestroy(function(doc) {
-    deleteSchedule(doc.dataValues, manager);
+  emitter.on('Schedule.afterDestroy', function(doc) {
+    deleteSchedule(doc, manager);
   });
+  Schedule.afterCreate(function(doc, options) {});
 }
diff --git a/server/config/socketio.js b/server/config/socketio.js
index e46d29d..c4f7cd6 100644
--- a/server/config/socketio.js
+++ b/server/config/socketio.js
@@ -41,7 +41,7 @@ function onDisconnect(socket) {
   }
 }
 
-function onConnect(socket, dashboardProcess) {
+function onConnect(socket) {
 
   console.info('[%s] SOCKET CONNECTED', socket.handshake.address);
 
@@ -256,7 +256,7 @@ function onConnect(socket, dashboardProcess) {
   });
 }
 
-module.exports = function(socketio, dashboardProcess) {
+module.exports = function(socketio) {
   // socket.io (v1.x.x) is powered by debug.
   // In order to see all the debug output, set DEBUG (in server/config/local.env.js) to including the desired scope.
   //
@@ -280,6 +280,6 @@ module.exports = function(socketio, dashboardProcess) {
     });
 
     // Call onConnect.
-    onConnect(socket, dashboardProcess);
+    onConnect(socket);
   });
 };
diff --git a/server/config/triggers/chat.js b/server/config/triggers/chat.js
index df65e21..91fe887 100644
--- a/server/config/triggers/chat.js
+++ b/server/config/triggers/chat.js
@@ -71,7 +71,7 @@ function Chat() {
   });
 }
 
-// Chat.prototype.http = function(action, dataValues) {
+// Chat.prototype.http = function(action, doc) {
 //   var options = {
 //     method: action.data1,
 //     uri: action.data2,
@@ -80,10 +80,10 @@ function Chat() {
 //
 //   switch (action.data1) {
 //     case 'GET':
-//       options.qs = dataValues;
+//       options.qs = doc;
 //       break;
 //     case 'POST':
-//       options.form = dataValues;
+//       options.form = doc;
 //       break;
 //     default:
 //   }
@@ -94,13 +94,13 @@ function Chat() {
 //     });
 // }
 
-Chat.prototype.tag = function(action, dataValues) {
+Chat.prototype.tag = function(action, doc) {
   return ChatRoom
     .update({
       tags: action.data1.split(';')
     }, {
       where: {
-        id: dataValues.id
+        id: doc.id
       }
     })
     .catch(function(err) {
@@ -108,7 +108,7 @@ Chat.prototype.tag = function(action, dataValues) {
     });
 }
 
-Chat.prototype.accountEmail = function(action, dataValues) {
+Chat.prototype.accountEmail = function(action, doc) {
   return MailAccount
     .findById(action.data1)
     .then(function(mailAccount) {
@@ -119,7 +119,7 @@ Chat.prototype.accountEmail = function(action, dataValues) {
           to: action.data2.split(';'),
           cc: action.data3 ? action.data3.split(';') : [],
           html: action.data5 ? Mustache
-            .render(action.data5, dataValues)
+            .render(action.data5, doc)
             .replace(/&/g, '&amp;')
             .replace(/</g, '&lt;')
             .replace(/>/g, '&gt;')
@@ -137,7 +137,7 @@ Chat.prototype.accountEmail = function(action, dataValues) {
     });
 }
 
-Chat.prototype.close = function(action, dataValues) {
+Chat.prototype.close = function(action, doc) {
   return ChatRoom
     .update({
       status: 'CLOSED',
@@ -145,7 +145,7 @@ Chat.prototype.close = function(action, dataValues) {
     }, {
       individualHooks: true,
       where: {
-        id: dataValues.id
+        id: doc.id
       }
     })
     .catch(function(err) {
diff --git a/server/config/triggers/index.js b/server/config/triggers/index.js
index 125a065..a369d59 100644
--- a/server/config/triggers/index.js
+++ b/server/config/triggers/index.js
@@ -2,6 +2,7 @@
 
 var _ = require('lodash');
 var Mustache = require('mustache');
+var emitter = require('cluster-emitter');
 
 var Util = require('./util');
 var Voice = require('./voice');
@@ -49,7 +50,7 @@ module.exports = function(ami) {
     .scope('all')
     .findAll()
     .then(function(triggers) {
-      _triggers = triggers;
+      _triggers = _.map(triggers, 'dataValues');
       return synchTriggers(_triggers);
     })
     .then(function() {
@@ -57,55 +58,65 @@ module.exports = function(ami) {
     })
     .then(function() {
       console.log('Triggers are ', _triggers.length);
-      ChatRoom.afterCreate(function(chatRoom) {
-        return chatRoom
-          .getChatVisitor()
+      emitter.on('ChatRoom.afterCreate', function(doc) {
+        doc = doc.dataValues || doc;
+        return ChatRoom
+          .findById(doc.id)
+          .then(function(chatRoom) {
+            return chatRoom
+              .getChatVisitor();
+          })
           .then(function(chatVisitor) {
-            var actions = util.getActionsByTriggers(chatVisitor, _.filter(_triggers, {
+            var actions = util.getActionsByTriggers(chatVisitor.dataValues, _.filter(_triggers, {
               channel: 'chat'
             }));
-            execActions(actions, _.merge(chatVisitor.dataValues, chatRoom.dataValues), 'chat', null, util, voice, mail, cm, jscripty, integration, urlForward, chat);
+            execActions(actions, _.merge(chatVisitor.dataValues, doc), 'chat', null, util, voice, mail, cm, jscripty, integration, urlForward, chat);
           })
           .catch(function(err) {
             console.error(err);
           });
       });
-      SmsMessage.afterCreate(function(smsMessage) {
-        if (smsMessage.status === 'RECEIVED') {
-          var actions = util.getActionsByTriggers(smsMessage, _.filter(_triggers, {
+      emitter.on('SmsMessage.afterCreate', function(doc) {
+        if (doc.status === 'RECEIVED') {
+          doc = doc.dataValues || doc;
+          var actions = util.getActionsByTriggers(doc, _.filter(_triggers, {
             channel: 'sms'
           }));
-          execActions(actions, smsMessage.dataValues, 'sms', null, util, voice, mail, cm, jscripty, integration, urlForward, chat, sms);
+          execActions(actions, doc, 'sms', null, util, voice, mail, cm, jscripty, integration, urlForward, chat, sms);
         }
       });
-      ReportDial.afterUpdate(function(doc) {
+      emitter.on('ReportDial.afterUpdate', function(doc) {
         if (doc.channel) {
+          doc = doc.dataValues || doc;
           var actions = util.getActionsByTriggers(doc, _.filter(_triggers, {
             channel: 'voice'
           }));
-          doc.dataValues.membername = doc.channel.split(/\/|-/)[1];
+          doc.membername = doc.channel.split(/\/|-/)[1];
           console.log('After dial update, Actions are ', actions.length);
           execActions(actions, doc, 'voice', 'outbound', util, voice, mail, cm, jscripty, integration, urlForward);
         }
-      })
-      ReportAgent.afterCreate(function(doc) {
+      });
+      emitter.on('ReportAgent.afterCreate', function(doc) {
+        doc = doc.dataValues || doc;
         var actions = util.getActionsByTriggers(doc, _.filter(_triggers, {
           channel: 'voice'
         }));
         console.log('After agent create, Actions are ', actions.length);
         execActions(actions, doc, 'voice', 'queue', util, voice, mail, cm, jscripty, integration, urlForward);
-      })
-      ReportAgent.afterUpdate(function(doc) {
-        if (doc.changed('lastevent')) {
+      });
+      emitter.on('ReportAgent.afterUpdate', function(doc, options) {
+        if (_.includes(options.changed, 'lastevent')) {
+          doc = doc.dataValues || doc;
           var actions = util.getActionsByTriggers(doc, _.filter(_triggers, {
             channel: 'voice'
           }));
           console.log('After agent update, Actions are ', actions.length);
           execActions(actions, doc, 'voice', 'queue', util, voice, mail, cm, jscripty, integration, urlForward);
         }
-      })
-      MailMessage.afterCreate(function(doc) {
+      });
+      emitter.on('MailMessage.afterCreate', function(doc) {
         if (doc.status === 'RECEIVED') {
+          doc = doc.dataValues || doc;
           var actions = util.getActionsByTriggers(doc, _.filter(_triggers, {
             channel: 'mail',
             status: true
@@ -161,15 +172,15 @@ function synchVars(ami) {
 }
 
 function synchVariables(active) {
-  Variable.afterCreate(function(doc) {
+  emitter.on('Variable.afterCreate', function(doc) {
     updateCollection(active, doc);
     console.log('After create, Variables are ', active.length);
   });
-  Variable.afterUpdate(function(doc) {
+  emitter.on('Variable.afterUpdate', function(doc) {
     updateCollection(active, doc);
     console.log('After update, Variables are ', active.length);
   });
-  Variable.afterDestroy(function(doc) {
+  emitter.on('Variable.afterDestroy', function(doc) {
     _.remove(active, {
       id: doc.id
     });
@@ -183,9 +194,9 @@ function getActionVariables(doc, channel) {
     var channelVariables = _.find(callChannels, {
       uniqueid: doc.uniqueid
     });
-    return channelVariables ? _.merge(_.clone(doc.dataValues), channelVariables.variables) : _.clone(doc.dataValues);
+    return channelVariables ? _.merge(_.clone(doc), channelVariables.variables) : _.clone(doc);
   } else {
-    return _.clone(doc.dataValues);
+    return _.clone(doc);
   }
 }
 
@@ -196,23 +207,23 @@ function execActions(actions, doc, channel, subtype, util, voice, mail, cm, jscr
     console.log('Executing action "' + action.action + '"');
     switch (action.action) {
       case 'contactManager':
-        cm.manageContact(doc.dataValues, channel);
+        cm.manageContact(doc, channel);
         break;
       case 'urlForward':
       case 'http':
-        urlForward.sendRequest(doc.dataValues, channel, action, getActionVariables(doc, channel));
+        urlForward.sendRequest(doc, channel, action, getActionVariables(doc, channel));
         break;
       case 'jscripty':
-        jscripty.manageJscripty(action.data1, doc.dataValues, channel);
+        jscripty.manageJscripty(action.data1, doc, channel);
         break;
       case 'integration':
       case 'motionbar':
-        integration.manageEvent(action, doc.dataValues, channel, subtype, getActionVariables(doc, channel));
+        integration.manageEvent(action, doc, channel, subtype, getActionVariables(doc, channel));
         break;
       case 'tag':
         switch (channel) {
           case 'mail':
-            mail.tag(action, doc.dataValues);
+            mail.tag(action, doc);
             break;
           case 'chat':
             chat.tag(action, doc);
@@ -227,7 +238,7 @@ function execActions(actions, doc, channel, subtype, util, voice, mail, cm, jscr
         // case 'http': //commented cause urlforward does the same, so we don't repeat the same function
         //   switch (channel) {
         //     case 'mail':
-        //       mail.http(action, doc.dataValues);
+        //       mail.http(action, doc);
         //       break;
         //     case 'chat':
         //       chat.http(action, doc);
@@ -240,7 +251,7 @@ function execActions(actions, doc, channel, subtype, util, voice, mail, cm, jscr
         //
         //   break;
       case 'email':
-        mail.email(action, doc.dataValues);
+        mail.email(action, doc);
         break;
       case 'accountEmail':
         switch (channel) {
@@ -255,10 +266,10 @@ function execActions(actions, doc, channel, subtype, util, voice, mail, cm, jscr
 
         break;
       case 'forward':
-        mail.forward(action, doc.dataValues);
+        mail.forward(action, doc);
         break;
       case 'template':
-        mail.template(action, doc.dataValues);
+        mail.template(action, doc);
         break;
       case 'accountTemplate':
         mail.accountTemplate(action, doc);
@@ -266,7 +277,7 @@ function execActions(actions, doc, channel, subtype, util, voice, mail, cm, jscr
       case 'close':
         switch (channel) {
           case 'mail':
-            mail.close(action, doc.dataValues);
+            mail.close(action, doc);
             break;
           case 'chat':
             chat.close(action, doc);
@@ -286,20 +297,20 @@ function execActions(actions, doc, channel, subtype, util, voice, mail, cm, jscr
 }
 
 function synchTriggers(triggers) {
-  Trigger.afterCreate(function(doc, options) {
+  emitter.on('Trigger.afterCreate', function(doc, options) {
     options.newTrigger.id = doc.id;
     triggers.push(options.newTrigger);
   });
-  Trigger.afterUpdate(function(doc, options) {
+  emitter.on('Trigger.afterUpdate', function(doc) {
     updateCollection(triggers, doc);
   });
-  Trigger.afterDestroy(function(doc) {
+  emitter.on('Trigger.afterDestroy', function(doc) {
     _.remove(triggers, {
       id: doc.id
     });
   });
-  ToolsAction.afterBulkDestroy(function(doc) {
-    var triggerId = parseInt(doc.where.TriggerId);
+  emitter.on('ToolsAction.afterBulkDestroy', function(doc, options) {
+    var triggerId = parseInt(options.TriggerId);
     var triggerFound = _.find(triggers, function(obj) {
       return obj.id === triggerId;
     });
@@ -307,7 +318,7 @@ function synchTriggers(triggers) {
       triggerFound.Actions = [];
     }
   });
-  ToolsAction.afterBulkCreate(function(doc) {
+  emitter.on('ToolsAction.afterBulkCreate', function(doc) {
     _.forEach(doc, function(action) {
       var triggerFound = _.find(triggers, function(obj) {
         return obj.id === parseInt(action.TriggerId);
@@ -317,17 +328,17 @@ function synchTriggers(triggers) {
       }
     });
   });
-  ToolsCondition.afterBulkDestroy(function(doc) {
-    if (doc.where.hasOwnProperty('TriggerAllId')) {
-      var triggerAllId = parseInt(doc.where.TriggerAllId);
+  emitter.on('ToolsCondition.afterBulkDestroy', function(doc, options) {
+    if (options.hasOwnProperty('TriggerAllId')) {
+      var triggerAllId = parseInt(options.TriggerAllId);
       var triggerAllFound = _.find(triggers, function(obj) {
         return obj.id === triggerAllId;
       });
       if (triggerAllFound) {
         triggerAllFound.All = [];
       }
-    } else if (doc.where.hasOwnProperty('TriggerAnyId')) {
-      var triggerAnyId = parseInt(doc.where.TriggerAnyId);
+    } else if (options.hasOwnProperty('TriggerAnyId')) {
+      var triggerAnyId = parseInt(options.TriggerAnyId);
       var triggerAnyFound = _.find(triggers, function(obj) {
         return obj.id === triggerAnyId;
       });
@@ -336,18 +347,18 @@ function synchTriggers(triggers) {
       }
     }
   });
-  ToolsCondition.afterBulkCreate(function(doc) {
+  emitter.on('ToolsCondition.afterBulkCreate', function(doc, options) {
     _.forEach(doc, function(condition) {
-      if (condition.dataValues.hasOwnProperty('TriggerAllId')) {
-        var triggerAllId = parseInt(condition.dataValues.TriggerAllId);
+      if (condition.hasOwnProperty('TriggerAllId')) {
+        var triggerAllId = parseInt(condition.TriggerAllId);
         var triggerAllFound = _.find(triggers, function(obj) {
           return obj.id === triggerAllId;
         });
         if (triggerAllFound) {
           triggerAllFound.All.push(condition);
         }
-      } else if (condition.dataValues.hasOwnProperty('TriggerAnyId')) {
-        var triggerAnyId = parseInt(condition.dataValues.TriggerAnyId);
+      } else if (condition.hasOwnProperty('TriggerAnyId')) {
+        var triggerAnyId = parseInt(condition.TriggerAnyId);
         var triggerAnyFound = _.find(triggers, function(obj) {
           return obj.id === triggerAnyId;
         });
@@ -356,7 +367,7 @@ function synchTriggers(triggers) {
         }
       }
     });
-  })
+  });
 }
 
 function updateCollection(collection, doc) {
diff --git a/server/config/triggers/mail.js b/server/config/triggers/mail.js
index 4b521e4..d270019 100644
--- a/server/config/triggers/mail.js
+++ b/server/config/triggers/mail.js
@@ -12,13 +12,13 @@ function Mail() {
   console.log('Trigger Mail Initialization...');
 }
 
-Mail.prototype.tag = function(action, dataValues, channel, subtype) {
+Mail.prototype.tag = function(action, doc, channel, subtype) {
   return MailRoom
     .update({
       tags: action.data1.split(';')
     }, {
       where: {
-        id: dataValues.MailRoomId
+        id: doc.MailRoomId
       }
     })
     .catch(function(err) {
@@ -26,7 +26,7 @@ Mail.prototype.tag = function(action, dataValues, channel, subtype) {
     });
 }
 
-// Mail.prototype.http = function(action, dataValues) {
+// Mail.prototype.http = function(action, doc) {
 //   var options = {
 //     method: action.data1,
 //     uri: action.data2,
@@ -35,10 +35,10 @@ Mail.prototype.tag = function(action, dataValues, channel, subtype) {
 //
 //   switch (action.data1) {
 //     case 'GET':
-//       options.qs = dataValues;
+//       options.qs = doc;
 //       break;
 //     case 'POST':
-//       options.form = dataValues;
+//       options.form = doc;
 //       break;
 //     default:
 //   }
@@ -49,9 +49,9 @@ Mail.prototype.tag = function(action, dataValues, channel, subtype) {
 //     });
 // }
 
-Mail.prototype.email = function(action, dataValues) {
+Mail.prototype.email = function(action, doc) {
   return MailAccount
-    .findById(dataValues.accountId)
+    .findById(doc.accountId)
     .then(function(mailAccount) {
 
       return MailMessage
@@ -61,7 +61,7 @@ Mail.prototype.email = function(action, dataValues) {
           to: action.data1.split(';'),
           cc: action.data2 ? action.data2.split(';') : [],
           html: action.data4 ? Mustache
-            .render(action.data4, dataValues)
+            .render(action.data4, doc)
             .replace(/&/g, '&amp;')
             .replace(/</g, '&lt;')
             .replace(/>/g, '&gt;')
@@ -79,17 +79,17 @@ Mail.prototype.email = function(action, dataValues) {
     });
 }
 
-Mail.prototype.forward = function(action, dataValues) {
+Mail.prototype.forward = function(action, doc) {
   return MailAccount
-    .findById(dataValues.accountId)
+    .findById(doc.accountId)
     .then(function(mailAccount) {
       return MailMessage
         .create({
-          subject: dataValues.subject || null,
+          subject: doc.subject || null,
           from: [mailAccount.address],
-          fromId: dataValues.fromId,
+          fromId: doc.fromId,
           to: action.data1.split(';'),
-          text: dataValues
+          text: doc
             .text
             .replace(/&/g, '&amp;')
             .replace(/</g, '&lt;')
@@ -97,7 +97,7 @@ Mail.prototype.forward = function(action, dataValues) {
             .replace(/"/g, '&quot;')
             .replace(/'/g, '&#039;')
             .replace(/\n/g, '<br>'),
-          html: dataValues.html,
+          html: doc.html,
           status: 'SENDING',
           auto: true,
           accountId: mailAccount.id,
@@ -109,11 +109,11 @@ Mail.prototype.forward = function(action, dataValues) {
     });
 }
 
-Mail.prototype.template = function(action, dataValues) {
+Mail.prototype.template = function(action, doc) {
   var _mailAccount;
 
   return MailAccount
-    .findById(dataValues.accountId)
+    .findById(doc.accountId)
     .then(function(mailAccount) {
       _mailAccount = mailAccount;
       return Template
@@ -126,7 +126,7 @@ Mail.prototype.template = function(action, dataValues) {
           subject: template.subject,
           from: [_mailAccount.address],
           to: action.data2.split(';'),
-          html: template.html ? Mustache.render(template.html, dataValues) : null,
+          html: template.html ? Mustache.render(template.html, doc) : null,
           auto: true,
           accountId: _mailAccount.id,
           accountName: _mailAccount.name
@@ -137,7 +137,7 @@ Mail.prototype.template = function(action, dataValues) {
     });
 }
 
-Mail.prototype.accountTemplate = function(action, dataValues) {
+Mail.prototype.accountTemplate = function(action, doc) {
   var _mailAccount;
 
   return MailAccount
@@ -154,7 +154,7 @@ Mail.prototype.accountTemplate = function(action, dataValues) {
           subject: template.subject,
           from: [_mailAccount.address],
           to: action.data3.split(';'),
-          html: template.html ? Mustache.render(template.html, dataValues) : null,
+          html: template.html ? Mustache.render(template.html, doc) : null,
           auto: true,
           accountId: _mailAccount.id,
           accountName: _mailAccount.name,
@@ -165,7 +165,7 @@ Mail.prototype.accountTemplate = function(action, dataValues) {
     });
 }
 
-Mail.prototype.close = function(action, dataValues) {
+Mail.prototype.close = function(action, doc) {
   return MailRoom
     .update({
       status: 'CLOSED',
@@ -173,7 +173,7 @@ Mail.prototype.close = function(action, dataValues) {
     }, {
       individualHooks: true,
       where: {
-        id: dataValues.MailRoomId
+        id: doc.MailRoomId
       }
     })
     .catch(function(err) {
diff --git a/server/config/triggers/sms.js b/server/config/triggers/sms.js
index 3a2dff7..f7b27e5 100644
--- a/server/config/triggers/sms.js
+++ b/server/config/triggers/sms.js
@@ -11,7 +11,7 @@ function Sms() {
   console.log('Trigger Sms Initialization...');
 }
 
-// Sms.prototype.http = function(action, dataValues) {
+// Sms.prototype.http = function(action, doc) {
 //   var options = {
 //     method: action.data1,
 //     uri: action.data2,
@@ -20,10 +20,10 @@ function Sms() {
 //
 //   switch (action.data1) {
 //     case 'GET':
-//       options.qs = dataValues;
+//       options.qs = doc;
 //       break;
 //     case 'POST':
-//       options.form = dataValues;
+//       options.form = doc;
 //       break;
 //     default:
 //   }
@@ -34,13 +34,13 @@ function Sms() {
 //     });
 // }
 
-Sms.prototype.tag = function(action, dataValues) {
+Sms.prototype.tag = function(action, doc) {
   return SmsRoom
     .update({
       tags: action.data1.split(';')
     }, {
       where: {
-        id: dataValues.SmsRoomId
+        id: doc.SmsRoomId
       }
     })
     .catch(function(err) {
@@ -48,7 +48,7 @@ Sms.prototype.tag = function(action, dataValues) {
     });
 }
 
-Sms.prototype.close = function(action, dataValues) {
+Sms.prototype.close = function(action, doc) {
   return SmsRoom
     .update({
       status: 'CLOSED',
@@ -56,7 +56,7 @@ Sms.prototype.close = function(action, dataValues) {
     }, {
       individualHooks: true,
       where: {
-        id: dataValues.SmsRoomId
+        id: doc.SmsRoomId
       }
     })
     .catch(function(err) {
@@ -64,7 +64,7 @@ Sms.prototype.close = function(action, dataValues) {
     });
 }
 
-Sms.prototype.accountEmail = function(action, dataValues) {
+Sms.prototype.accountEmail = function(action, doc) {
   return MailAccount
     .findById(action.data1)
     .then(function(mailAccount) {
@@ -75,7 +75,7 @@ Sms.prototype.accountEmail = function(action, dataValues) {
           to: action.data2.split(';'),
           cc: action.data3 ? action.data3.split(';') : [],
           html: action.data5 ? Mustache
-            .render(action.data5, dataValues)
+            .render(action.data5, doc)
             .replace(/&/g, '&amp;')
             .replace(/</g, '&lt;')
             .replace(/>/g, '&gt;')
@@ -93,7 +93,7 @@ Sms.prototype.accountEmail = function(action, dataValues) {
     });
 }
 
-Sms.prototype.accountTemplate = function(action, dataValues) {
+Sms.prototype.accountTemplate = function(action, doc) {
   var _mailAccount;
 
   return MailAccount
@@ -110,7 +110,7 @@ Sms.prototype.accountTemplate = function(action, dataValues) {
           subject: template.subject,
           from: [_mailAccount.address],
           to: action.data3.split(';'),
-          html: template.html ? Mustache.render(template.html, dataValues) : null,
+          html: template.html ? Mustache.render(template.html, doc) : null,
           auto: true,
           accountId: _mailAccount.id,
           accountName: _mailAccount.name,
diff --git a/server/config/triggers/util.js b/server/config/triggers/util.js
index 97bd1dc..d1bf7be 100644
--- a/server/config/triggers/util.js
+++ b/server/config/triggers/util.js
@@ -8,18 +8,18 @@ function Util() {
 
 Util.prototype.getActionsByTriggers = function(doc, triggers) {
   var actions = [];
-  doc.dataValues.from = doc.dataValues.from ? doc.dataValues.from.split(';') : [];
-  doc.dataValues.cc = doc.dataValues.cc ? doc.dataValues.cc.split(';') : [];
-  doc.dataValues.to = doc.dataValues.to ? doc.dataValues.to.split(';') : [];
+  doc.from = doc.from ? doc.from.split(';') : [];
+  doc.cc = doc.cc ? doc.cc.split(';') : [];
+  doc.to = doc.to ? doc.to.split(';') : [];
   triggers.forEach(function(trigger) {
     if (trigger.status) {
       var All = [];
       var Any = [];
       trigger.All.forEach(function(condition) {
-        All.push(checkCondition(condition.dataValues || condition, doc.dataValues));
+        All.push(checkCondition(condition, doc));
       });
       trigger.Any.forEach(function(condition) {
-        Any.push(checkCondition(condition.dataValues || condition, doc.dataValues));
+        Any.push(checkCondition(condition, doc));
       });
 
       var allResult = [],
@@ -42,9 +42,9 @@ Util.prototype.getActionsByTriggers = function(doc, triggers) {
       }
     }
   });
-  doc.dataValues.from = doc.dataValues.from.join(';');
-  doc.dataValues.cc = doc.dataValues.cc.join(';');
-  doc.dataValues.to = doc.dataValues.to.join(';');
+  doc.from = doc.from.join(';');
+  doc.cc = doc.cc.join(';');
+  doc.to = doc.to.join(';');
   //return actions array
   return actions;
 }
diff --git a/server/models/chat_room.js b/server/models/chat_room.js
index b051d78..85a6341 100644
--- a/server/models/chat_room.js
+++ b/server/models/chat_room.js
@@ -49,6 +49,11 @@ module.exports = function(sequelize, DataTypes) {
 		website: DataTypes.STRING
 	}, {
 		tableName: 'chat_rooms',
+		hooks: {
+			afterCreate: function(doc) {
+				emitter.to(['master']).emit('ChatRoom.afterCreate', doc);
+			}
+		},
 		associate: function(models) {
 			ChatRoom.hasMany(models.ChatMessage);
 			ChatRoom.belongsTo(models.ChatVisitor);
diff --git a/server/models/mail_message.js b/server/models/mail_message.js
index 20a9d5d..61ff5ec 100644
--- a/server/models/mail_message.js
+++ b/server/models/mail_message.js
@@ -3,6 +3,7 @@
  */
 
 var _ = require('lodash');
+var emitter = require('cluster-emitter');
 
 module.exports = function(sequelize, DataTypes) {
 
@@ -88,6 +89,11 @@ module.exports = function(sequelize, DataTypes) {
 		accountName: DataTypes.STRING
 	}, {
 		tableName: 'mail_messages',
+		hooks: {
+			afterCreate: function(doc) {
+				emitter.to(['master']).emit('MailMessage.afterCreate', doc);
+			}
+		},
 		paranoid: true,
 		associate: function(models) {
 			MailMessage.hasMany(models.MailAttachment);
diff --git a/server/models/report_agent.js b/server/models/report_agent.js
index f9bd42d..268a27b 100644
--- a/server/models/report_agent.js
+++ b/server/models/report_agent.js
@@ -2,6 +2,8 @@
  * Agent Log Model
  */
 
+var emitter = require('cluster-emitter');
+
 module.exports = function(sequelize, DataTypes) {
 
   var ReportAgent = sequelize.define('ReportAgent', {
@@ -64,6 +66,16 @@ module.exports = function(sequelize, DataTypes) {
     answeredelsewheremembername: DataTypes.STRING
   }, {
     tableName: 'report_agent',
+    hooks: {
+      afterCreate: function(doc) {
+        emitter.to(['master']).emit('ReportAgent.afterCreate', doc);
+      },
+      afterUpdate: function(doc) {
+        emitter.to(['master']).emit('ReportAgent.afterUpdate', doc, {
+          changed: doc.changed()
+        });
+      }
+    },
     indexes: [{
       fields: ['uniqueid', 'destuniqueid']
     }]
diff --git a/server/models/report_dial.js b/server/models/report_dial.js
index 200fb4c..c918e3e 100644
--- a/server/models/report_dial.js
+++ b/server/models/report_dial.js
@@ -2,6 +2,8 @@
  * DIAL Model
  */
 
+var emitter = require('cluster-emitter');
+
 module.exports = function(sequelize, DataTypes) {
 
   var ReportDial = sequelize.define('ReportDial', {
@@ -43,6 +45,11 @@ module.exports = function(sequelize, DataTypes) {
     routeId: DataTypes.INTEGER
   }, {
     tableName: 'report_dial',
+    hooks: {
+      afterUpdate: function(doc) {
+        emitter.to(['master']).emit('ReportDial.afterUpdate', doc);
+      }
+    },
     indexes: [{
       fields: ['uniqueid']
     }]
diff --git a/server/models/report_queue.js b/server/models/report_queue.js
index 4b9c61a..224e110 100644
--- a/server/models/report_queue.js
+++ b/server/models/report_queue.js
@@ -1,8 +1,7 @@
-/**
- * QueueLog Model
- */
+'use strict';
 
-var moment = require('moment');
+const emitter = require('cluster-emitter');
+const moment = require('moment');
 
 module.exports = function(sequelize, DataTypes) {
 
@@ -82,6 +81,19 @@ module.exports = function(sequelize, DataTypes) {
             queuecallerleaveAt: null
           }
         });
+    },
+    hooks: {
+      afterCreate: function(doc, options) {
+        emitter.to(['master', 'self']).emit('ReportQueue.afterCreate', doc, {
+          body: options.body
+        });
+      },
+      afterUpdate: function(doc, options) {
+        emitter.to(['master']).emit('ReportQueue.afterUpdate', doc);
+      },
+      afterDestroy: function(doc, options) {
+        emitter.to(['master']).emit('ReportQueue.afterDestroy', doc);
+      }
     }
   });
 
diff --git a/server/models/sms_message.js b/server/models/sms_message.js
index 7759a0b..f4072e4 100644
--- a/server/models/sms_message.js
+++ b/server/models/sms_message.js
@@ -1,5 +1,7 @@
 'use strict';
 
+var emitter = require('cluster-emitter');
+
 module.exports = function(sequelize, DataTypes) {
   var SmsMessage = sequelize.define('SmsMessage', {
     from: {
@@ -33,6 +35,11 @@ module.exports = function(sequelize, DataTypes) {
     },
   }, {
     tableName: 'sms_messages',
+    hooks: {
+      afterCreate: function(doc) {
+        emitter.to(['master']).emit('SmsMessage.afterCreate', doc);
+      }
+    },
     associate: function(models) {
       SmsMessage.belongsTo(models.User);
       SmsMessage.belongsTo(models.SmsRoom, {
diff --git a/server/models/tools_action.js b/server/models/tools_action.js
index aaeece0..9e04d3f 100644
--- a/server/models/tools_action.js
+++ b/server/models/tools_action.js
@@ -2,6 +2,8 @@
  * Tools Actions Model
  */
 
+var emitter = require('cluster-emitter');
+
 module.exports = function(sequelize, DataTypes) {
 
   var ToolsAction = sequelize.define('ToolsAction', {
@@ -24,7 +26,17 @@ module.exports = function(sequelize, DataTypes) {
       type: DataTypes.STRING(4096)
     }
   }, {
-    tableName: 'tools_actions'
+    tableName: 'tools_actions',
+    hooks: {
+      afterBulkCreate: function(doc) {
+        emitter.to(['master']).emit('ToolsAction.afterBulkCreate', doc);
+      },
+      afterBulkDestroy: function(doc) {
+        emitter.to(['master']).emit('ToolsAction.afterBulkDestroy', doc, {
+          TriggerId: doc.where.TriggerId
+        });
+      }
+    }
   });
 
   return ToolsAction;
diff --git a/server/models/tools_condition.js b/server/models/tools_condition.js
index cb0b603..50902ba 100644
--- a/server/models/tools_condition.js
+++ b/server/models/tools_condition.js
@@ -2,7 +2,7 @@
  * Tools Conditions Model
  */
 
-var crypto = require('crypto');
+var emitter = require('cluster-emitter');
 
 module.exports = function(sequelize, DataTypes) {
 
@@ -11,7 +11,22 @@ module.exports = function(sequelize, DataTypes) {
     operator: DataTypes.STRING,
     value: DataTypes.STRING
   }, {
-    tableName: 'tools_conditions'
+    tableName: 'tools_conditions',
+    hooks: {
+      afterBulkCreate: function(doc) {
+        emitter.to(['master']).emit('ToolsCondition.afterBulkCreate', doc);
+      },
+      afterBulkDestroy: function(doc) {
+        var options = {};
+        if (doc.where.hasOwnProperty('TriggerAllId')) {
+          options.TriggerAllId = doc.where.TriggerAllId;
+        }
+        if (doc.where.hasOwnProperty('TriggerAnyId')) {
+          options.TriggerAnyId = doc.where.TriggerAnyId;
+        }
+        emitter.to(['master']).emit('ToolsCondition.afterBulkDestroy', doc, options);
+      }
+    }
   });
 
   return ToolsCondition;
diff --git a/server/models/tools_schedule.js b/server/models/tools_schedule.js
index 1cdadf1..1f1b075 100644
--- a/server/models/tools_schedule.js
+++ b/server/models/tools_schedule.js
@@ -1,5 +1,7 @@
 'use strict';
 
+var emitter = require('cluster-emitter');
+
 module.exports = function(sequelize, DataTypes) {
 
   var Schedule = sequelize.define('Schedule', {
@@ -35,6 +37,17 @@ module.exports = function(sequelize, DataTypes) {
     }
   }, {
     tableName: 'tools_schedules',
+    hooks: {
+      afterCreate: function(doc) {
+        emitter.to(['master']).emit('Schedule.afterCreate', doc);
+      },
+      afterUpdate: function(doc) {
+        emitter.to(['master']).emit('Schedule.afterUpdate', doc);
+      },
+      afterDestroy: function(doc) {
+        emitter.to(['master']).emit('Schedule.afterDestroy', doc);
+      }
+    },
     associate: function(models) {
       Schedule.belongsTo(models.MailServerOut);
     }
diff --git a/server/models/tools_trigger.js b/server/models/tools_trigger.js
index 58f32a3..98dd763 100644
--- a/server/models/tools_trigger.js
+++ b/server/models/tools_trigger.js
@@ -2,6 +2,8 @@
  * Trigger Model
  */
 
+var emitter = require('cluster-emitter');
+
 module.exports = function(sequelize, DataTypes) {
 
   var Trigger = sequelize.define('Trigger', {
@@ -14,6 +16,19 @@ module.exports = function(sequelize, DataTypes) {
     }
   }, {
     tableName: 'tools_triggers',
+    hooks: {
+      afterCreate: function(doc, options) {
+        emitter.to(['master']).emit('Trigger.afterCreate', doc, {
+          newTrigger: options.newTrigger
+        });
+      },
+      afterUpdate: function(doc) {
+        emitter.to(['master']).emit('Trigger.afterUpdate', doc);
+      },
+      afterDestroy: function(doc) {
+        emitter.to(['master']).emit('Trigger.afterDestroy', doc);
+      }
+    },
     associate: function(models) {
       Trigger.hasMany(models.ToolsCondition, {
         as: {
diff --git a/server/services/dashboard/index.js b/server/services/dashboard/index.js
index d317e36..a3d53aa 100644
--- a/server/services/dashboard/index.js
+++ b/server/services/dashboard/index.js
@@ -3,7 +3,7 @@
 const util = require('util');
 const cp = require('child_process');
 
-module.exports = function(io) {
+module.exports = function() {
   const n = cp
     .fork(__dirname + '/workers')
     .on('message', function(data) {