From eab46d758a2641229d47d79754b433bba14c7a35 Mon Sep 17 00:00:00 2001 From: Andris Reinman Date: Fri, 24 Jun 2016 14:12:21 +0300 Subject: [PATCH] Display a list of triggered users --- lib/models/subscriptions.js | 1 - lib/models/triggers.js | 68 ++++++++++++++++++++++++++++++++++++ meta.json | 2 +- routes/triggers.js | 49 ++++++++++++++++++++++++++ services/triggers.js | 5 ++- setup/sql/mailtrain.sql | 5 +-- setup/sql/upgrade-00016.sql | 10 ++++++ views/triggers/triggered.hbs | 47 +++++++++++++++++++++++++ views/triggers/triggers.hbs | 8 ++++- 9 files changed, 189 insertions(+), 6 deletions(-) create mode 100644 setup/sql/upgrade-00016.sql create mode 100644 views/triggers/triggered.hbs diff --git a/lib/models/subscriptions.js b/lib/models/subscriptions.js index c0a63825..e75cf298 100644 --- a/lib/models/subscriptions.js +++ b/lib/models/subscriptions.js @@ -172,7 +172,6 @@ module.exports.filter = (listId, request, columns, segmentId, callback) => { }; - module.exports.addConfirmation = (list, email, data, callback) => { let cid = shortid.generate(); diff --git a/lib/models/triggers.js b/lib/models/triggers.js index 75b4648b..479eef8d 100644 --- a/lib/models/triggers.js +++ b/lib/models/triggers.js @@ -58,6 +58,7 @@ module.exports.list = callback => { '`source`.`name` AS `source_campaign_name`', '`dest`.`id` AS `dest_campaign`', '`dest`.`name` AS `dest_campaign_name`', + '`triggers`.`count` AS `count`', '`custom_fields`.`id` AS `column_id`', '`triggers`.`column` AS `column`', '`custom_fields`.`name` AS `column_name`', @@ -336,6 +337,73 @@ module.exports.delete = (id, callback) => { }); }; +module.exports.filterSubscribers = (trigger, request, columns, callback) => { + db.getConnection((err, connection) => { + if (err) { + return callback(err); + } + + let query = 'SELECT COUNT(`subscription__' + trigger.list + '`.`id`) AS total FROM `subscription__' + trigger.list + '` JOIN `trigger__' + trigger.id + '` ON `trigger__' + trigger.id + '`.`list`=? AND `trigger__' + trigger.id + '`.`subscription`=`subscription__' + trigger.list + '`.`id`'; + let values = [trigger.list]; + + connection.query(query, values, (err, total) => { + if (err) { + connection.release(); + return callback(err); + } + total = total && total[0] && total[0].total || 0; + + let ordering = []; + + if (request.order && request.order.length) { + + request.order.forEach(order => { + let orderField = columns[Number(order.column)]; + let orderDirection = (order.dir || '').toString().toLowerCase() === 'desc' ? 'DESC' : 'ASC'; + if (orderField) { + ordering.push('`' + orderField + '` ' + orderDirection); + } + }); + } + + if (!ordering.length) { + ordering.push('`email` ASC'); + } + + let args = [Number(request.length) || 50, Number(request.start) || 0]; + + if (request.search && request.search.value) { + query = 'SELECT SQL_CALC_FOUND_ROWS * FROM `subscription__' + trigger.list + '` JOIN `trigger__' + trigger.id + '` ON `trigger__' + trigger.id + '`.`list`=? AND `trigger__' + trigger.id + '`.`subscription`=`subscription__' + trigger.list + '`.`id AND (email LIKE ? OR first_name LIKE ? OR last_name LIKE ?) ORDER BY ' + ordering.join(', ') + ' LIMIT ? OFFSET ?'; + + let searchVal = '%' + request.search.value.replace(/\\/g, '\\\\').replace(/([%_])/g, '\\$1') + '%'; + args = values.concat([searchVal, searchVal, searchVal]).concat(args); + } else { + query = 'SELECT SQL_CALC_FOUND_ROWS * FROM `subscription__' + trigger.list + '` JOIN `trigger__' + trigger.id + '` ON `trigger__' + trigger.id + '`.`list`=? AND `trigger__' + trigger.id + '`.`subscription`=`subscription__' + trigger.list + '`.`id` ORDER BY ' + ordering.join(', ') + ' LIMIT ? OFFSET ?'; + args = values.concat(args); + } + + connection.query(query, args, (err, rows) => { + if (err) { + connection.release(); + return callback(err); + } + connection.query('SELECT FOUND_ROWS() AS total', (err, filteredTotal) => { + connection.release(); + if (err) { + return callback(err); + } + + let subscriptions = rows.map(row => tools.convertKeys(row)); + + filteredTotal = filteredTotal && filteredTotal[0] && filteredTotal[0].total || 0; + return callback(null, subscriptions, total, filteredTotal); + }); + }); + }); + }); + +}; + function createTriggerTable(id, callback) { db.getConnection((err, connection) => { if (err) { diff --git a/meta.json b/meta.json index 574f4279..62816c23 100644 --- a/meta.json +++ b/meta.json @@ -1,3 +1,3 @@ { - "schemaVersion": 15 + "schemaVersion": 16 } diff --git a/routes/triggers.js b/routes/triggers.js index d4525147..d1a31f98 100644 --- a/routes/triggers.js +++ b/routes/triggers.js @@ -9,6 +9,7 @@ let fields = require('../lib/models/fields'); let striptags = require('striptags'); let passport = require('../lib/passport'); let tools = require('../lib/tools'); +let htmlescape = require('escape-html'); router.all('/*', (req, res, next) => { if (!req.user) { @@ -231,5 +232,53 @@ router.post('/delete', passport.parseForm, passport.csrfProtection, (req, res) = }); }); +router.get('/status/:id', passport.csrfProtection, (req, res) => { + let id = Number(req.params.id) || 0; + + triggers.get(id, (err, trigger) => { + if (err || !trigger) { + req.flash('danger', err && err.message || err || 'Could not find trigger with specified ID'); + return res.redirect('/triggers'); + } + + trigger.csrfToken = req.csrfToken(); + res.render('triggers/triggered', trigger); + }); +}); + +router.post('/status/ajax/:id', (req, res) => { + triggers.get(req.params.id, (err, trigger) => { + if (err || !trigger) { + return res.json({ + error: err && err.message || err || 'Trigger not found', + data: [] + }); + } + + let columns = ['#', 'email', 'first_name', 'last_name', 'trigger__' + trigger.id + '`.`created']; + triggers.filterSubscribers(trigger, req.body, columns, (err, data, total, filteredTotal) => { + if (err) { + return res.json({ + error: err.message || err, + data: [] + }); + } + + res.json({ + draw: req.body.draw, + recordsTotal: total, + recordsFiltered: filteredTotal, + data: data.map((row, i) => [ + (Number(req.body.start) || 0) + 1 + i, + htmlescape(row.email || ''), + htmlescape(row.firstName || ''), + htmlescape(row.lastName || ''), + '' + row.created.toISOString() + '', + 'Edit' + ]) + }); + }); + }); +}); module.exports = router; diff --git a/services/triggers.js b/services/triggers.js index be14d81c..511ea8fa 100644 --- a/services/triggers.js +++ b/services/triggers.js @@ -99,7 +99,10 @@ function fireTrigger(trigger, callback) { connection.release(); return callback(err); } - return setImmediate(insertNext); + // update counter + let query = 'UPDATE `triggers` SET `count`=`count`+1 WHERE id=?'; + let values = [trigger.id]; + connection.query(query, values, () => setImmediate(insertNext)); }); }); }; diff --git a/setup/sql/mailtrain.sql b/setup/sql/mailtrain.sql index b124c01e..20bc8b7a 100644 --- a/setup/sql/mailtrain.sql +++ b/setup/sql/mailtrain.sql @@ -194,7 +194,7 @@ CREATE TABLE `settings` ( `value` text NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `key` (`key`) -) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb4; INSERT INTO `settings` (`id`, `key`, `value`) VALUES (1,'smtp_hostname','localhost'); INSERT INTO `settings` (`id`, `key`, `value`) VALUES (2,'smtp_port','465'); INSERT INTO `settings` (`id`, `key`, `value`) VALUES (3,'smtp_encryption','TLS'); @@ -211,7 +211,7 @@ INSERT INTO `settings` (`id`, `key`, `value`) VALUES (13,'default_from','My Awes INSERT INTO `settings` (`id`, `key`, `value`) VALUES (14,'default_address','admin@example.com'); INSERT INTO `settings` (`id`, `key`, `value`) VALUES (15,'default_subject','Test message'); INSERT INTO `settings` (`id`, `key`, `value`) VALUES (16,'default_homepage','http://localhost:3000/'); -INSERT INTO `settings` (`id`, `key`, `value`) VALUES (17,'db_schema_version','15'); +INSERT INTO `settings` (`id`, `key`, `value`) VALUES (17,'db_schema_version','16'); CREATE TABLE `subscription` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `cid` varchar(255) CHARACTER SET ascii NOT NULL, @@ -267,6 +267,7 @@ CREATE TABLE `triggers` ( `column` varchar(255) CHARACTER SET ascii DEFAULT NULL, `seconds` int(11) NOT NULL DEFAULT '0', `dest_campaign` int(11) unsigned DEFAULT NULL, + `count` int(11) unsigned NOT NULL DEFAULT '0', `last_check` timestamp NULL DEFAULT NULL, `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), diff --git a/setup/sql/upgrade-00016.sql b/setup/sql/upgrade-00016.sql new file mode 100644 index 00000000..6d1d5d38 --- /dev/null +++ b/setup/sql/upgrade-00016.sql @@ -0,0 +1,10 @@ +# Header section +# Define incrementing schema version number +SET @schema_version = '16'; + +ALTER TABLE `triggers` ADD COLUMN `count` int(11) unsigned NOT NULL DEFAULT '0' AFTER `dest_campaign`; + +# Footer section +LOCK TABLES `settings` WRITE; +INSERT INTO `settings` (`key`, `value`) VALUES('db_schema_version', @schema_version) ON DUPLICATE KEY UPDATE `value`=@schema_version; +UNLOCK TABLES; diff --git a/views/triggers/triggered.hbs b/views/triggers/triggered.hbs new file mode 100644 index 00000000..cc5945ea --- /dev/null +++ b/views/triggers/triggered.hbs @@ -0,0 +1,47 @@ + + +

{{name}} Triggered subscribers

+ +
+ +{{#if description}} +
{{{description}}}
+{{/if}} + +
+ +
+ +
Subscribers who caused this trigger to fire:
+
+
+ + + + + + + + + + + +
+ # + + Address + + First Name + + Last Name + + Triggered +
+
+
+
+
diff --git a/views/triggers/triggers.hbs b/views/triggers/triggers.hbs index 844fbb5a..211ec1f6 100644 --- a/views/triggers/triggers.hbs +++ b/views/triggers/triggers.hbs @@ -12,7 +12,7 @@
- +
+ @@ -69,6 +72,9 @@ +
# @@ -35,6 +35,9 @@ Target Campaign + Triggered +   {{destCampaignName}} + {{count}} +