Add device type detect and stats calculation for open/click rate by device type and country

This commit is contained in:
vladimir 2017-03-19 16:47:03 +02:00
parent b6497b0e86
commit 1ba3bce6eb
10 changed files with 176 additions and 15 deletions

View file

@ -193,7 +193,43 @@ module.exports.filterClickedSubscribers = (campaign, linkId, request, columns, c
});
});
});
};
module.exports.statsClickedSubscribersByColumn = (campaign, linkId, request, column, limit, callback) => {
db.getConnection((err, connection) => {
if (err) {
return callback(err);
}
let values = [campaign.list, linkId];
let query = 'SELECT SQL_CALC_FOUND_ROWS ' + column + ' AS data, COUNT(*) AS cnt FROM `subscription__' + campaign.list + '` JOIN `campaign_tracker__' + campaign.id + '` ON `campaign_tracker__' + campaign.id + '`.`list`=? AND `campaign_tracker__' + campaign.id + '`.`subscriber`=`subscription__' + campaign.list + '`.`id` AND `campaign_tracker__' + campaign.id + '`.`link`=? GROUP BY ' + column + ' ORDER BY COUNT(' + column + ') DESC,' + column;
connection.query(query, values, (err, rows) => {
connection.release();
if (err) {
return callback(err);
}
let data = {};
let dataPercent = [];
let total = 0;
rows.forEach(function (row, index) {
if (index < limit) {
data[row.data] = row.cnt;
} else {
data.other = (data.other ? data.other : 0) + row.cnt;
}
total += row.cnt;
});
Object.keys(data).forEach(function (key) {
let name = key + ': ' + data[key];
let value = parseInt(data[key] * 100 / total);
dataPercent.push([name, value]);
});
return callback(null, dataPercent, total);
});
});
};
module.exports.filterStatusSubscribers = (campaign, status, request, columns, callback) => {

View file

@ -13,6 +13,7 @@ let lists = require('./lists');
let log = require('npmlog');
let urllib = require('url');
let he = require('he');
let ua_parser = require('device');
module.exports.resolve = (linkCid, callback) => {
db.getConnection((err, connection) => {
@ -35,7 +36,7 @@ module.exports.resolve = (linkCid, callback) => {
});
};
module.exports.countClick = (remoteIp, campaignCid, listCid, subscriptionCid, linkId, callback) => {
module.exports.countClick = (remoteIp, useragent, campaignCid, listCid, subscriptionCid, linkId, callback) => {
getSubscriptionData(campaignCid, listCid, subscriptionCid, (err, data) => {
if (err) {
return callback(err);
@ -57,9 +58,9 @@ module.exports.countClick = (remoteIp, campaignCid, listCid, subscriptionCid, li
}
let country = geoip.lookupCountry(remoteIp) || null;
let query = 'INSERT INTO `campaign_tracker__' + data.campaign.id + '` (`list`, `subscriber`, `link`, `ip`, `country`) VALUES (?,?,?,?,?) ON DUPLICATE KEY UPDATE `count`=`count`+1';
connection.query(query, [data.list.id, data.subscription.id, linkId, remoteIp, country], (err, result) => {
let device = ua_parser(useragent, { unknownUserAgentDeviceType: 'desktop', emptyUserAgentDeviceType: 'desktop' });
let query = 'INSERT INTO `campaign_tracker__' + data.campaign.id + '` (`list`, `subscriber`, `link`, `ip`, `device_type`, `country`) VALUES (?,?,?,?,?,?) ON DUPLICATE KEY UPDATE `count`=`count`+1';
connection.query(query, [data.list.id, data.subscription.id, linkId, remoteIp, device.type, country], (err, result) => {
if (err && err.code !== 'ER_DUP_ENTRY') {
return connection.rollback(() => {
connection.release();
@ -98,8 +99,8 @@ module.exports.countClick = (remoteIp, campaignCid, listCid, subscriptionCid, li
});
}
let query = 'INSERT INTO `campaign_tracker__' + data.campaign.id + '` (`list`, `subscriber`, `link`, `ip`, `country`) VALUES (?,?,?,?,?)';
connection.query(query, [data.list.id, data.subscription.id, 0, remoteIp, country], err => {
let query = 'INSERT INTO `campaign_tracker__' + data.campaign.id + '` (`list`, `subscriber`, `link`, `ip`, `device_type`, `country`) VALUES (?,?,?,?,?,?)';
connection.query(query, [data.list.id, data.subscription.id, 0, remoteIp, device.type, country], err => {
if (err && err.code !== 'ER_DUP_ENTRY') {
return connection.rollback(() => {
connection.release();
@ -141,7 +142,7 @@ module.exports.countClick = (remoteIp, campaignCid, listCid, subscriptionCid, li
});
// also count clicks as open events in case beacon image was blocked
module.exports.countOpen(remoteIp, campaignCid, listCid, subscriptionCid, () => false);
module.exports.countOpen(remoteIp, useragent, campaignCid, listCid, subscriptionCid, () => false);
});
});
});
@ -151,7 +152,7 @@ module.exports.countClick = (remoteIp, campaignCid, listCid, subscriptionCid, li
});
};
module.exports.countOpen = (remoteIp, campaignCid, listCid, subscriptionCid, callback) => {
module.exports.countOpen = (remoteIp, useragent, campaignCid, listCid, subscriptionCid, callback) => {
getSubscriptionData(campaignCid, listCid, subscriptionCid, (err, data) => {
if (err) {
return callback(err);
@ -173,9 +174,9 @@ module.exports.countOpen = (remoteIp, campaignCid, listCid, subscriptionCid, cal
}
let country = geoip.lookupCountry(remoteIp) || null;
let query = 'INSERT INTO `campaign_tracker__' + data.campaign.id + '` (`list`, `subscriber`, `link`, `ip`, `country`) VALUES (?,?,?,?,?) ON DUPLICATE KEY UPDATE `count`=`count`+1';
connection.query(query, [data.list.id, data.subscription.id, -1, remoteIp, country], (err, result) => {
let device = ua_parser(useragent, { unknownUserAgentDeviceType: 'desktop', emptyUserAgentDeviceType: 'desktop' });
let query = 'INSERT INTO `campaign_tracker__' + data.campaign.id + '` (`list`, `subscriber`, `link`, `ip`, `device_type`, `country`) VALUES (?,?,?,?,?,?) ON DUPLICATE KEY UPDATE `count`=`count`+1';
connection.query(query, [data.list.id, data.subscription.id, -1, remoteIp, device.type, country], (err, result) => {
if (err && err.code !== 'ER_DUP_ENTRY') {
return connection.rollback(() => {
connection.release();