Added initial support for trigger based automation
This commit is contained in:
parent
cc1c70d57f
commit
b16209f23e
36 changed files with 2025 additions and 263 deletions
|
@ -90,6 +90,9 @@ router.get('/create', passport.csrfProtection, (req, res) => {
|
|||
case 'rss':
|
||||
view = 'campaigns/create-rss';
|
||||
break;
|
||||
case 'triggered':
|
||||
view = 'campaigns/create-triggered';
|
||||
break;
|
||||
default:
|
||||
view = 'campaigns/create';
|
||||
}
|
||||
|
@ -151,6 +154,9 @@ router.get('/edit/:id', passport.csrfProtection, (req, res, next) => {
|
|||
|
||||
let view;
|
||||
switch (campaign.type) {
|
||||
case 4: //triggered
|
||||
view = 'campaigns/edit-triggered';
|
||||
break;
|
||||
case 2: //rss
|
||||
view = 'campaigns/edit-rss';
|
||||
break;
|
||||
|
@ -159,55 +165,72 @@ router.get('/edit/:id', passport.csrfProtection, (req, res, next) => {
|
|||
view = 'campaigns/edit';
|
||||
}
|
||||
|
||||
lists.get(campaign.list, (err, list) => {
|
||||
let getList = (listId, callback) => {
|
||||
lists.get(listId, (err, list) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
if (!list) {
|
||||
return callback(new Error('Selected list not found'));
|
||||
}
|
||||
|
||||
fields.list(list.id, (err, fieldList) => {
|
||||
if (err && !fieldList) {
|
||||
fieldList = [];
|
||||
}
|
||||
|
||||
let mergeTags = [
|
||||
// keep indentation
|
||||
{
|
||||
key: 'LINK_UNSUBSCRIBE',
|
||||
value: 'URL that points to the preferences page of the subscriber'
|
||||
}, {
|
||||
key: 'LINK_PREFERENCES',
|
||||
value: 'URL that points to the unsubscribe page'
|
||||
}, {
|
||||
key: 'LINK_BROWSER',
|
||||
value: 'URL to preview the message in a browser'
|
||||
}, {
|
||||
key: 'FIRST_NAME',
|
||||
value: 'First name'
|
||||
}, {
|
||||
key: 'LAST_NAME',
|
||||
value: 'Last name'
|
||||
}, {
|
||||
key: 'FULL_NAME',
|
||||
value: 'Full name (first and last name combined)'
|
||||
}, {
|
||||
key: 'SUBSCRIPTION_ID',
|
||||
value: 'Unique ID that identifies the recipient'
|
||||
}, {
|
||||
key: 'LIST_ID',
|
||||
value: 'Unique ID that identifies the list used for this campaign'
|
||||
}, {
|
||||
key: 'CAMPAIGN_ID',
|
||||
value: 'Unique ID that identifies current campaign'
|
||||
}
|
||||
];
|
||||
|
||||
fieldList.forEach(field => {
|
||||
mergeTags.push({
|
||||
key: field.key,
|
||||
value: field.name
|
||||
});
|
||||
});
|
||||
|
||||
return callback(null, list, mergeTags);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
getList(campaign.list, (err, list, mergeTags) => {
|
||||
if (err) {
|
||||
req.flash('danger', err.message || err);
|
||||
return res.redirect('/');
|
||||
}
|
||||
if (!list) {
|
||||
req.flash('danger', 'Selected list does not exist');
|
||||
res.render(view, campaign);
|
||||
return;
|
||||
}
|
||||
|
||||
fields.list(list.id, (err, fieldList) => {
|
||||
if (err && !fieldList) {
|
||||
fieldList = [];
|
||||
}
|
||||
|
||||
let mergeTags = [
|
||||
// indent
|
||||
{
|
||||
key: 'LINK_UNSUBSCRIBE',
|
||||
value: 'URL that points to the preferences page of the subscriber'
|
||||
}, {
|
||||
key: 'LINK_PREFERENCES',
|
||||
value: 'URL that points to the unsubscribe page'
|
||||
}, {
|
||||
key: 'LINK_BROWSER',
|
||||
value: 'URL to preview the message in a browser'
|
||||
}, {
|
||||
key: 'FIRST_NAME',
|
||||
value: 'First name'
|
||||
}, {
|
||||
key: 'LAST_NAME',
|
||||
value: 'Last name'
|
||||
}, {
|
||||
key: 'FULL_NAME',
|
||||
value: 'Full name (first and last name combined)'
|
||||
}
|
||||
];
|
||||
|
||||
fieldList.forEach(field => {
|
||||
mergeTags.push({
|
||||
key: field.key,
|
||||
value: field.name
|
||||
});
|
||||
});
|
||||
|
||||
campaign.mergeTags = mergeTags;
|
||||
res.render(view, campaign);
|
||||
});
|
||||
campaign.mergeTags = mergeTags;
|
||||
res.render(view, campaign);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -298,61 +321,74 @@ router.get('/view/:id', passport.csrfProtection, (req, res) => {
|
|||
return res.redirect('/campaigns');
|
||||
}
|
||||
|
||||
lists.get(campaign.list, (err, list) => {
|
||||
if (err || !campaign) {
|
||||
let getList = (listId, callback) => {
|
||||
lists.get(listId, (err, list) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
if (!list) {
|
||||
return callback(new Error('Selected list not found'));
|
||||
}
|
||||
subscriptions.listTestUsers(listId, (err, testUsers) => {
|
||||
if (err || !testUsers) {
|
||||
testUsers = [];
|
||||
}
|
||||
return callback(null, list, testUsers);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
getList(campaign.list, (err, list, testUsers) => {
|
||||
if (err) {
|
||||
req.flash('danger', err && err.message || err);
|
||||
return res.redirect('/campaigns');
|
||||
}
|
||||
|
||||
campaign.csrfToken = req.csrfToken();
|
||||
|
||||
campaign.list = list;
|
||||
campaign.testUsers = testUsers;
|
||||
|
||||
subscriptions.listTestUsers(list.id, (err, testUsers) => {
|
||||
if (err || !testUsers) {
|
||||
testUsers = [];
|
||||
campaign.isIdling = campaign.status === 1;
|
||||
campaign.isSending = campaign.status === 2;
|
||||
campaign.isFinished = campaign.status === 3;
|
||||
campaign.isPaused = campaign.status === 4;
|
||||
campaign.isInactive = campaign.status === 5;
|
||||
campaign.isActive = campaign.status === 6;
|
||||
|
||||
campaign.isNormal = campaign.type === 1 || campaign.type === 3;
|
||||
campaign.isRss = campaign.type === 2;
|
||||
campaign.isTriggered = campaign.type === 4;
|
||||
|
||||
campaign.isScheduled = campaign.scheduled && campaign.scheduled > new Date();
|
||||
|
||||
// show only messages that weren't bounced as delivered
|
||||
campaign.delivered = campaign.delivered - campaign.bounced;
|
||||
|
||||
campaign.openRate = campaign.delivered ? Math.round((campaign.opened / campaign.delivered) * 10000) / 100 : 0;
|
||||
campaign.clicksRate = campaign.delivered ? Math.round((campaign.clicks / campaign.delivered) * 10000) / 100 : 0;
|
||||
campaign.bounceRate = campaign.delivered ? Math.round((campaign.bounced / campaign.delivered) * 10000) / 100 : 0;
|
||||
campaign.complaintRate = campaign.delivered ? Math.round((campaign.complained / campaign.delivered) * 10000) / 100 : 0;
|
||||
campaign.unsubscribeRate = campaign.delivered ? Math.round((campaign.unsubscribed / campaign.delivered) * 10000) / 100 : 0;
|
||||
|
||||
campaigns.getLinks(campaign.id, (err, links) => {
|
||||
if (err) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
campaign.testUsers = testUsers;
|
||||
campaign.isIdling = campaign.status === 1;
|
||||
campaign.isSending = campaign.status === 2;
|
||||
campaign.isFinished = campaign.status === 3;
|
||||
campaign.isPaused = campaign.status === 4;
|
||||
campaign.isInactive = campaign.status === 5;
|
||||
campaign.isActive = campaign.status === 6;
|
||||
|
||||
campaign.isNormal = campaign.type === 1 || campaign.type === 3;
|
||||
campaign.isRss = campaign.type === 2;
|
||||
|
||||
campaign.isScheduled = campaign.scheduled && campaign.scheduled > new Date();
|
||||
|
||||
// show only messages that weren't bounced as delivered
|
||||
campaign.delivered = campaign.delivered - campaign.bounced;
|
||||
|
||||
campaign.openRate = campaign.delivered ? Math.round((campaign.opened / campaign.delivered) * 10000) / 100 : 0;
|
||||
campaign.clicksRate = campaign.delivered ? Math.round((campaign.clicks / campaign.delivered) * 10000) / 100 : 0;
|
||||
campaign.bounceRate = campaign.delivered ? Math.round((campaign.bounced / campaign.delivered) * 10000) / 100 : 0;
|
||||
campaign.complaintRate = campaign.delivered ? Math.round((campaign.complained / campaign.delivered) * 10000) / 100 : 0;
|
||||
campaign.unsubscribeRate = campaign.delivered ? Math.round((campaign.unsubscribed / campaign.delivered) * 10000) / 100 : 0;
|
||||
|
||||
campaigns.getLinks(campaign.id, (err, links) => {
|
||||
if (err) {
|
||||
// ignore
|
||||
let index = 0;
|
||||
campaign.links = (links || []).map(link => {
|
||||
link.index = ++index;
|
||||
link.totalPercentage = campaign.delivered ? Math.round(((link.clicks / campaign.delivered) * 100) * 1000) / 1000 : 0;
|
||||
link.relPercentage = campaign.clicks ? Math.round(((link.clicks / campaign.clicks) * 100) * 1000) / 1000 : 0;
|
||||
link.short = link.url.replace(/^https?:\/\/(www.)?/i, '');
|
||||
if (link.short > 63) {
|
||||
link.short = link.short.substr(0, 60) + '…';
|
||||
}
|
||||
let index = 0;
|
||||
campaign.links = (links || []).map(link => {
|
||||
link.index = ++index;
|
||||
link.totalPercentage = campaign.delivered ? Math.round(((link.clicks / campaign.delivered) * 100) * 1000) / 1000 : 0;
|
||||
link.relPercentage = campaign.clicks ? Math.round(((link.clicks / campaign.clicks) * 100) * 1000) / 1000 : 0;
|
||||
link.short = link.url.replace(/^https?:\/\/(www.)?/i, '');
|
||||
if (link.short > 63) {
|
||||
link.short = link.short.substr(0, 60) + '…';
|
||||
}
|
||||
return link;
|
||||
});
|
||||
campaign.showOverview = !req.query.tab || req.query.tab === 'overview';
|
||||
campaign.showLinks = req.query.tab === 'links';
|
||||
res.render('campaigns/view', campaign);
|
||||
return link;
|
||||
});
|
||||
campaign.showOverview = !req.query.tab || req.query.tab === 'overview';
|
||||
campaign.showLinks = req.query.tab === 'links';
|
||||
res.render('campaigns/view', campaign);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -423,8 +459,20 @@ router.get('/status/:id/:status', passport.csrfProtection, (req, res) => {
|
|||
return res.redirect('/campaigns');
|
||||
}
|
||||
|
||||
lists.get(campaign.list, (err, list) => {
|
||||
if (err || !campaign) {
|
||||
let getList = (listId, callback) => {
|
||||
lists.get(listId, (err, list) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
if (!list) {
|
||||
return callback(new Error('Selected list not found'));
|
||||
}
|
||||
return callback(null, list);
|
||||
});
|
||||
};
|
||||
|
||||
getList(campaign.list, (err, list) => {
|
||||
if (err) {
|
||||
req.flash('danger', err && err.message || err);
|
||||
return res.redirect('/campaigns');
|
||||
}
|
||||
|
@ -449,8 +497,20 @@ router.get('/clicked/:id/:linkId', passport.csrfProtection, (req, res) => {
|
|||
return res.redirect('/campaigns');
|
||||
}
|
||||
|
||||
lists.get(campaign.list, (err, list) => {
|
||||
if (err || !campaign) {
|
||||
let getList = (listId, callback) => {
|
||||
lists.get(listId, (err, list) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
if (!list) {
|
||||
return callback(new Error('Selected list not found'));
|
||||
}
|
||||
return callback(null, list);
|
||||
});
|
||||
};
|
||||
|
||||
getList(campaign.list, (err, list) => {
|
||||
if (err) {
|
||||
req.flash('danger', err && err.message || err);
|
||||
return res.redirect('/campaigns');
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue