Add segment support to triggers model and database

This commit is contained in:
Jonas Düver 2018-04-25 18:16:51 +02:00
parent 006e4aa116
commit 52f4213cb7
3 changed files with 85 additions and 30 deletions

View file

@ -1,8 +1,10 @@
'use strict';
let log = require('npmlog');
let tools = require('../tools');
let db = require('../db');
let lists = require('./lists');
let segments = require('./segments');
let util = require('util');
let _ = require('../translate')._;
let tableHelpers = require('../table-helpers');
@ -55,7 +57,9 @@ module.exports.list = callback => {
'`triggers`.`description` AS `description`',
'`triggers`.`enabled` AS `enabled`',
'`triggers`.`list` AS `list`',
'`triggers`.`segment` AS `segment`',
'`lists`.`name` AS `list_name`',
'`segments`.`name` AS `segment_name`',
'`source`.`id` AS `source_campaign`',
'`source`.`name` AS `source_campaign_name`',
'`dest`.`id` AS `dest_campaign`',
@ -69,7 +73,7 @@ module.exports.list = callback => {
'`triggers`.`created` AS `created`'
];
let query = 'SELECT ' + tableFields.join(', ') + ' FROM `triggers` LEFT JOIN `campaigns` `source` ON `source`.`id`=`triggers`.`source_campaign` LEFT JOIN `campaigns` `dest` ON `dest`.`id`=`triggers`.`dest_campaign` LEFT JOIN `lists` ON `lists`.`id`=`triggers`.`list` LEFT JOIN `custom_fields` ON `custom_fields`.`list` = `triggers`.`list` AND `custom_fields`.`column`=`triggers`.`column` ORDER BY `triggers`.`name`';
let query = 'SELECT ' + tableFields.join(', ') + ' FROM `triggers` LEFT JOIN `campaigns` `source` ON `source`.`id`=`triggers`.`source_campaign` LEFT JOIN `campaigns` `dest` ON `dest`.`id`=`triggers`.`dest_campaign` LEFT JOIN `lists` ON `lists`.`id`=`triggers`.`list` LEFT JOIN `segments` ON `segments`.`id`=`triggers`.`segment` LEFT JOIN `custom_fields` ON `custom_fields`.`list` = `triggers`.`list` AND `custom_fields`.`column`=`triggers`.`column` ORDER BY `triggers`.`name`';
connection.query(query, (err, rows) => {
connection.release();
if (err) {
@ -105,32 +109,70 @@ module.exports.getQuery = (id, callback) => {
let intervalQuery = (column, seconds, treshold) => column + ' <= NOW() - INTERVAL ' + seconds + ' SECOND AND ' + column + ' >= NOW() - INTERVAL ' + (treshold + seconds) + ' SECOND';
let query = false;
switch (trigger.rule) {
case 'subscription':
query = 'SELECT id FROM `subscription__' + trigger.list + '` subscription WHERE ' + intervalQuery('`' + trigger.column + '`', trigger.seconds, treshold) + ' AND id NOT IN (SELECT subscription FROM `trigger__' + id + '` triggertable WHERE triggertable.`list` = ' + trigger.list + ' AND triggertable.`subscription` = subscription.`id`) LIMIT ' + limit;
break;
case 'campaign':
switch (trigger.column) {
case 'delivered':
query = 'SELECT subscription.id AS id FROM `subscription__' + trigger.list + '` subscription LEFT JOIN `campaign__' + trigger.sourceCampaign + '` campaign ON campaign.list=' + trigger.list + ' AND subscription.id=campaign.subscription WHERE campaign.status=1 AND ' + intervalQuery('`campaign`.`created`', trigger.seconds, treshold) + ' AND subscription.id NOT IN (SELECT subscription FROM `trigger__' + id + '` triggertable WHERE triggertable.`list` = ' + trigger.list + ' AND triggertable.`subscription` = subscription.`id`) LIMIT ' + limit;
break;
case 'not_clicked':
query = 'SELECT subscription.id AS id FROM `subscription__' + trigger.list + '` subscription LEFT JOIN `campaign__' + trigger.sourceCampaign + '` campaign ON campaign.list=' + trigger.list + ' AND subscription.id=campaign.subscription LEFT JOIN `campaign_tracker__' + trigger.sourceCampaign + '` tracker ON tracker.list=campaign.list AND tracker.subscriber=subscription.id AND tracker.link=0 WHERE campaign.status=1 AND ' + intervalQuery('`campaign`.`created`', trigger.seconds, treshold) + ' AND tracker.created IS NULL AND subscription.id NOT IN (SELECT subscription FROM `trigger__' + id + '` triggertable WHERE triggertable.`list` = ' + trigger.list + ' AND triggertable.`subscription` = subscription.`id`) LIMIT ' + limit;
break;
case 'not_opened':
query = 'SELECT subscription.id AS id FROM `subscription__' + trigger.list + '` subscription LEFT JOIN `campaign__' + trigger.sourceCampaign + '` campaign ON campaign.list=' + trigger.list + ' AND subscription.id=campaign.subscription LEFT JOIN `campaign_tracker__' + trigger.sourceCampaign + '` tracker ON tracker.list=campaign.list AND tracker.subscriber=subscription.id AND tracker.link=-1 WHERE campaign.status=1 AND ' + intervalQuery('`campaign`.`created`', trigger.seconds, treshold) + ' AND tracker.created IS NULL AND subscription.id NOT IN (SELECT subscription FROM `trigger__' + id + '` triggertable WHERE triggertable.`list` = ' + trigger.list + ' AND triggertable.`subscription` = subscription.`id`) LIMIT ' + limit;
break;
case 'clicked':
query = 'SELECT subscription.id AS id FROM `subscription__' + trigger.list + '` subscription LEFT JOIN `campaign__' + trigger.sourceCampaign + '` campaign ON campaign.list=' + trigger.list + ' AND subscription.id=campaign.subscription LEFT JOIN `campaign_tracker__' + trigger.sourceCampaign + '` tracker ON tracker.list=campaign.list AND tracker.subscriber=subscription.id AND tracker.link=0 WHERE campaign.status=1 AND ' + intervalQuery('`tracker`.`created`', trigger.seconds, treshold) + ' AND subscription.id NOT IN (SELECT subscription FROM `trigger__' + id + '` triggertable WHERE triggertable.`list` = ' + trigger.list + ' AND triggertable.`subscription` = subscription.`id`) LIMIT ' + limit;
break;
case 'opened':
query = 'SELECT subscription.id AS id FROM `subscription__' + trigger.list + '` subscription LEFT JOIN `campaign__' + trigger.sourceCampaign + '` campaign ON campaign.list=' + trigger.list + ' AND subscription.id=campaign.subscription LEFT JOIN `campaign_tracker__' + trigger.sourceCampaign + '` tracker ON tracker.list=campaign.list AND tracker.subscriber=subscription.id AND tracker.link=-1 WHERE campaign.status=1 AND ' + intervalQuery('`tracker`.`created`', trigger.seconds, treshold) + ' AND subscription.id NOT IN (SELECT subscription FROM `trigger__' + id + '` triggertable WHERE triggertable.`list` = ' + trigger.list + ' AND triggertable.`subscription` = subscription.`id`) LIMIT ' + limit;
break;
let getSegmentQuery = (segmentId, next) => {
segmentId = Number(segmentId);
if (!segmentId) {
return next(null, {
where: '',
values: []
});
}
segments.getQuery(segmentId, 'subscription', next);
};
getSegmentQuery(trigger.segment, (err, queryData) => {
if (err) {
log.err('Triggers', err);
return null;
}
let query = false;
let querySegmentSubscription = '';
let querySegmentTriggertable = '';
if (trigger.segment > 0)
{
querySegmentSubscription = (queryData.where ? ' AND (' + queryData.where + ')' : '');
querySegmentTriggertable = ' AND triggertable.`segment` = ' + trigger.segment;
}
switch (trigger.rule) {
case 'subscription':
query = 'SELECT id FROM `subscription__' + trigger.list + '` subscription WHERE status=1 AND ' + intervalQuery('`' + trigger.column + '`', trigger.seconds, treshold) + ' ' + querySegmentSubscription + ' AND id NOT IN (SELECT subscription FROM `trigger__' + id + '` triggertable WHERE triggertable.`list` = ' + trigger.list + ' ' + querySegmentTriggertable + ' AND triggertable.`subscription` = subscription.`id`) LIMIT ' + limit;
break;
case 'campaign':
switch (trigger.column) {
case 'delivered':
query = 'SELECT subscription.id AS id FROM `subscription__' + trigger.list + '` subscription LEFT JOIN `campaign__' + trigger.sourceCampaign + '` campaign ON campaign.list=' + trigger.list + ' AND subscription.id=campaign.subscription WHERE campaign.status=1 AND ' + intervalQuery('`campaign`.`created`', trigger.seconds, treshold) + ' ' + querySegmentSubscription + ' AND subscription.id NOT IN (SELECT subscription FROM `trigger__' + id + '` triggertable WHERE triggertable.`list` = ' + trigger.list + ' ' + querySegmentTriggertable + ' AND triggertable.`subscription` = subscription.`id`) LIMIT ' + limit;
break;
case 'not_clicked':
query = 'SELECT subscription.id AS id FROM `subscription__' + trigger.list + '` subscription LEFT JOIN `campaign__' + trigger.sourceCampaign + '` campaign ON campaign.list=' + trigger.list + ' AND subscription.id=campaign.subscription LEFT JOIN `campaign_tracker__' + trigger.sourceCampaign + '` tracker ON tracker.list=campaign.list AND tracker.subscriber=subscription.id AND tracker.link=0 WHERE campaign.status=1 AND ' + intervalQuery('`campaign`.`created`', trigger.seconds, treshold) + ' AND tracker.created IS NULL ' + querySegmentSubscription + ' AND subscription.id NOT IN (SELECT subscription FROM `trigger__' + id + '` triggertable WHERE triggertable.`list` = ' + trigger.list + ' ' + querySegmentTriggertable + ' AND triggertable.`subscription` = subscription.`id`) LIMIT ' + limit;
break;
case 'not_opened':
query = 'SELECT subscription.id AS id FROM `subscription__' + trigger.list + '` subscription LEFT JOIN `campaign__' + trigger.sourceCampaign + '` campaign ON campaign.list=' + trigger.list + ' AND subscription.id=campaign.subscription LEFT JOIN `campaign_tracker__' + trigger.sourceCampaign + '` tracker ON tracker.list=campaign.list AND tracker.subscriber=subscription.id AND tracker.link=-1 WHERE campaign.status=1 AND ' + intervalQuery('`campaign`.`created`', trigger.seconds, treshold) + ' AND tracker.created IS NULL ' + querySegmentSubscription + ' AND subscription.id NOT IN (SELECT subscription FROM `trigger__' + id + '` triggertable WHERE triggertable.`list` = ' + trigger.list + ' ' + querySegmentTriggertable + ' AND triggertable.`subscription` = subscription.`id`) LIMIT ' + limit;
break;
case 'clicked':
query = 'SELECT subscription.id AS id FROM `subscription__' + trigger.list + '` subscription LEFT JOIN `campaign__' + trigger.sourceCampaign + '` campaign ON campaign.list=' + trigger.list + ' AND subscription.id=campaign.subscription LEFT JOIN `campaign_tracker__' + trigger.sourceCampaign + '` tracker ON tracker.list=campaign.list AND tracker.subscriber=subscription.id AND tracker.link=0 WHERE campaign.status=1 AND ' + intervalQuery('`tracker`.`created`', trigger.seconds, treshold) + ' ' + querySegmentSubscription + ' AND subscription.id NOT IN (SELECT subscription FROM `trigger__' + id + '` triggertable WHERE triggertable.`list` = ' + trigger.list + ' ' + querySegmentTriggertable + ' AND triggertable.`subscription` = subscription.`id`) LIMIT ' + limit;
break;
case 'opened':
query = 'SELECT subscription.id AS id FROM `subscription__' + trigger.list + '` subscription LEFT JOIN `campaign__' + trigger.sourceCampaign + '` campaign ON campaign.list=' + trigger.list + ' AND subscription.id=campaign.subscription LEFT JOIN `campaign_tracker__' + trigger.sourceCampaign + '` tracker ON tracker.list=campaign.list AND tracker.subscriber=subscription.id AND tracker.link=-1 WHERE campaign.status=1 AND ' + intervalQuery('`tracker`.`created`', trigger.seconds, treshold) + ' ' + querySegmentSubscription + ' AND subscription.id NOT IN (SELECT subscription FROM `trigger__' + id + '` triggertable WHERE triggertable.`list` = ' + trigger.list + ' ' + querySegmentTriggertable + ' AND triggertable.`subscription` = subscription.`id`) LIMIT ' + limit;
break;
}
break;
}
if (trigger.segment > 0) {
let values = queryData.values.concat([trigger.list, trigger.segment]);
for (let i = 0; i < values.length; i++) {
query = query.replace('?', db.escape(values[i]));
}
break;
}
callback(null, query);
}
callback(null, query);
});
});
};
@ -168,6 +210,7 @@ module.exports.create = (trigger, callback) => {
let name = (trigger.name || '').toString().trim();
let description = (trigger.description || '').toString().trim();
let listId = Number(trigger.list) || 0;
let segmentId = Number(trigger.segmentId) || 0;
let seconds = (Number(trigger.days) || 0) * 24 * 3600;
let rule = (trigger.rule || '').toString().toLowerCase().trim();
let destCampaign = Number(trigger.destCampaign) || 0;
@ -220,8 +263,8 @@ module.exports.create = (trigger, callback) => {
return callback(err);
}
let keys = ['name', 'description', 'list', 'source_campaign', 'rule', 'column', 'seconds', 'dest_campaign', 'last_check'];
let values = [name, description, list.id, sourceCampaign, rule, column, seconds, destCampaign];
let keys = ['name', 'description', 'list', 'segment', 'source_campaign', 'rule', 'column', 'seconds', 'dest_campaign', 'last_check'];
let values = [name, description, list.id, segmentId, sourceCampaign, rule, column, seconds, destCampaign];
let query = 'INSERT INTO `triggers` (`' + keys.join('`, `') + '`) VALUES (' + values.map(() => '?').join(', ') + ', NOW())';

View file

@ -82,8 +82,8 @@ function fireTrigger(trigger, callback) {
}
let subscriber = rows[pos++].id;
let query = 'INSERT INTO `trigger__' + trigger.id + '` (`list`, `subscription`) VALUES (?,?)';
let values = [trigger.list, subscriber];
let query = 'INSERT INTO `trigger__' + trigger.id + '` (`list`, `segment`, `subscription`) VALUES (?,?,?)';
let values = [trigger.list, trigger.segment, subscriber];
connection.query(query, values, (err, result) => {
if (err && err.code !== 'ER_DUP_ENTRY') {

View file

@ -0,0 +1,12 @@
# Header section
# Define incrementing schema version number
SET @schema_version = '30';
# Add segment support for triggers
ALTER TABLE `triggers` ADD `segment` INT(11) UNSIGNED NOT NULL AFTER `list`;
ALTER TABLE `trigger` ADD `segment` INT(11) UNSIGNED NOT NULL AFTER `list`;
# 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;