@mate-academy/sourcebuster
Version:
Get sources of your site's visitors (utm / organic / referral / typein).
515 lines (443 loc) • 17.6 kB
JavaScript
;
var data = require('./data'),
terms = require('./terms'),
cookies = require('./helpers/cookies'),
uri = require('./helpers/uri'),
utils = require('./helpers/utils'),
params = require('./params'),
migrations = require('./migrations');
module.exports = function(prefs) {
var p = params.fetch(prefs);
var get_param = uri.getParam();
var domain = p.domain.host,
isolate = p.domain.isolate,
lifetime = p.lifetime;
migrations.go(lifetime, domain, isolate);
var __sbjs_type,
__sbjs_source,
__sbjs_medium,
__sbjs_campaign,
__sbjs_content,
__sbjs_term,
__sbjs_account_id,
__sbjs_campaign_id,
__sbjs_ad_group_id,
__sbjs_ad_id,
__sbjs_term_id;
function mainData() {
var sbjs_data;
var isGetParamsContainsUtm = (
typeof get_param.utm_source !== 'undefined' ||
typeof get_param.utm_medium !== 'undefined' ||
typeof get_param.utm_campaign !== 'undefined' ||
typeof get_param.utm_content !== 'undefined' ||
typeof get_param.utm_term !== 'undefined' ||
typeof get_param.utm_ac_id !== 'undefined' ||
typeof get_param.utm_id !== 'undefined' ||
typeof get_param.utm_ad_group_id !== 'undefined' ||
typeof get_param.utm_ad_id !== 'undefined' ||
typeof get_param.utm_term_id !== 'undefined' ||
typeof get_param.gclid !== 'undefined' ||
typeof get_param.yclid !== 'undefined' ||
typeof get_param[p.campaign_param] !== 'undefined' ||
typeof get_param[p.term_param] !== 'undefined' ||
typeof get_param[p.content_param] !== 'undefined'
);
var parsedContainer = cookies.parse(data.containers);
var parsedCurrent = parsedContainer[cookies.unsbjs(data.containers.current)];
var isOrganic = checkReferer(terms.traffic.organic);
var current_data;
var new_data;
var is_utm_changed = false;
setClickIdsToCookies();
if (isGetParamsContainsUtm) {
setFirstAndCurrentExtraData();
sbjs_data = getData(terms.traffic.utm);
current_data = parsedCurrent;
new_data = data.pack.unpack(sbjs_data);
is_utm_changed = checkIsUtmChanged(current_data, new_data);
} else if (isOrganic) {
setFirstAndCurrentExtraData();
sbjs_data = getData(terms.traffic.organic);
current_data = parsedCurrent;
new_data = data.pack.unpack(sbjs_data);
is_utm_changed = checkIsUtmChanged(current_data, new_data);
} else if (!cookies.get(data.containers.session) && checkReferer(terms.traffic.referral)) {
setFirstAndCurrentExtraData();
sbjs_data = getData(terms.traffic.referral);
is_utm_changed = true;
} else if (!cookies.get(data.containers.first) && !cookies.get(data.containers.current)) {
setFirstAndCurrentExtraData();
sbjs_data = getData(terms.traffic.typein);
is_utm_changed = true;
} else {
return {
data: cookies.get(data.containers.current),
is_utm_changed: is_utm_changed
};
}
return {
data: sbjs_data,
is_utm_changed: is_utm_changed
};
}
function checkIsUtmChanged(
current_data,
new_data
) {
return (
current_data[data.aliases.main.type] !== new_data[data.aliases.main.type] ||
current_data[data.aliases.main.source] !== new_data[data.aliases.main.source] ||
current_data[data.aliases.main.medium] !== new_data[data.aliases.main.medium] ||
current_data[data.aliases.main.campaign] !== new_data[data.aliases.main.campaign] ||
current_data[data.aliases.main.content] !== new_data[data.aliases.main.content] ||
current_data[data.aliases.main.term] !== new_data[data.aliases.main.term]
);
}
function getData(type) {
switch (type) {
case terms.traffic.utm:
// Allow explicit type override via utm_type URL parameter
// This fixes mixed attribution when organic visits include UTM params in redirect URLs
if (typeof get_param.utm_type !== 'undefined') {
__sbjs_type = get_param.utm_type;
} else {
__sbjs_type = terms.traffic.utm;
}
if (typeof get_param.utm_source !== 'undefined') {
__sbjs_source = get_param.utm_source;
} else if (typeof get_param.gclid !== 'undefined') {
__sbjs_source = 'google';
} else if (typeof get_param.yclid !== 'undefined') {
__sbjs_source = 'yandex';
} else {
__sbjs_source = terms.none;
}
if (typeof get_param.utm_medium !== 'undefined') {
__sbjs_medium = get_param.utm_medium;
} else if (typeof get_param.gclid !== 'undefined') {
__sbjs_medium = 'cpc';
} else if (typeof get_param.yclid !== 'undefined') {
__sbjs_medium = 'cpc';
} else {
__sbjs_medium = terms.none;
}
if (typeof get_param.utm_campaign !== 'undefined') {
__sbjs_campaign = get_param.utm_campaign;
} else if (typeof get_param[p.campaign_param] !== 'undefined') {
__sbjs_campaign = get_param[p.campaign_param];
} else if (typeof get_param.gclid !== 'undefined') {
__sbjs_campaign = 'google_cpc';
} else if (typeof get_param.yclid !== 'undefined') {
__sbjs_campaign = 'yandex_cpc';
} else {
__sbjs_campaign = terms.none;
}
if (typeof get_param.utm_content !== 'undefined') {
__sbjs_content = get_param.utm_content;
} else if (typeof get_param[p.content_param] !== 'undefined') {
__sbjs_content = get_param[p.content_param];
} else {
__sbjs_content = terms.none;
}
if (typeof get_param.utm_term !== 'undefined') {
__sbjs_term = get_param.utm_term;
} else if (typeof get_param[p.term_param] !== 'undefined') {
__sbjs_term = get_param[p.term_param];
} else {
__sbjs_term = getUtmTerm() || terms.none;
}
if (typeof get_param.utm_ac_id !== 'undefined') {
__sbjs_account_id = get_param.utm_ac_id;
} else if (typeof get_param.gclid !== 'undefined') {
__sbjs_account_id = 'google_cpc';
} else {
__sbjs_account_id = terms.none;
}
if (typeof get_param.utm_id !== 'undefined') {
__sbjs_campaign_id = get_param.utm_id;
} else if (typeof get_param.gclid !== 'undefined') {
__sbjs_campaign_id = 'google_cpc';
} else {
__sbjs_campaign_id = terms.none;
}
if (typeof get_param.utm_ad_group_id !== 'undefined') {
__sbjs_ad_group_id = get_param.utm_ad_group_id;
} else if (typeof get_param.gclid !== 'undefined') {
__sbjs_ad_group_id = 'google_cpc';
} else {
__sbjs_ad_group_id = terms.none;
}
if (typeof get_param.utm_ad_id !== 'undefined') {
__sbjs_ad_id = get_param.utm_ad_id;
} else if (typeof get_param.gclid !== 'undefined') {
__sbjs_ad_id = 'google_cpc';
} else {
__sbjs_ad_id = terms.none;
}
if (typeof get_param.utm_term_id !== 'undefined') {
__sbjs_term_id = get_param.utm_term_id;
} else if (typeof get_param.gclid !== 'undefined') {
__sbjs_term_id = 'google_cpc';
} else {
__sbjs_term_id = terms.none;
}
break;
case terms.traffic.organic:
__sbjs_type = terms.traffic.organic;
__sbjs_source = __sbjs_source || uri.getHost(document.referrer);
__sbjs_medium = terms.referer.organic;
__sbjs_campaign = terms.none;
__sbjs_content = terms.none;
__sbjs_term = terms.none;
__sbjs_account_id = terms.none;
__sbjs_campaign_id = terms.none;
__sbjs_ad_group_id = terms.none;
__sbjs_ad_id = terms.none;
__sbjs_term_id = terms.none;
break;
case terms.traffic.referral:
__sbjs_type = terms.traffic.referral;
__sbjs_source = __sbjs_source || uri.getHost(document.referrer);
__sbjs_medium = __sbjs_medium || terms.referer.referral;
__sbjs_campaign = terms.none;
__sbjs_content = uri.parse(document.referrer).path;
__sbjs_term = terms.none;
__sbjs_account_id = terms.none;
__sbjs_campaign_id = terms.none;
__sbjs_ad_group_id = terms.none;
__sbjs_ad_id = terms.none;
__sbjs_term_id = terms.none;
break;
case terms.traffic.typein:
__sbjs_type = terms.traffic.typein;
__sbjs_source = p.typein_attributes.source;
__sbjs_medium = p.typein_attributes.medium;
__sbjs_campaign = terms.none;
__sbjs_content = terms.none;
__sbjs_term = terms.none;
__sbjs_account_id = terms.none;
__sbjs_campaign_id = terms.none;
__sbjs_ad_group_id = terms.none;
__sbjs_ad_id = terms.none;
__sbjs_term_id = terms.none;
break;
default:
__sbjs_type = terms.oops;
__sbjs_source = terms.oops;
__sbjs_medium = terms.oops;
__sbjs_campaign = terms.oops;
__sbjs_content = terms.oops;
__sbjs_term = terms.oops;
__sbjs_account_id = terms.oops;
__sbjs_campaign_id = terms.oops;
__sbjs_ad_group_id = terms.oops;
__sbjs_ad_id = terms.oops;
__sbjs_term_id = terms.oops;
}
var sbjs_data = {
type: __sbjs_type,
source: __sbjs_source,
medium: __sbjs_medium,
campaign: __sbjs_campaign,
content: __sbjs_content,
term: __sbjs_term,
account_id: __sbjs_account_id,
campaign_id: __sbjs_campaign_id,
ad_group_id: __sbjs_ad_group_id,
ad_id: __sbjs_ad_id,
term_id: __sbjs_term_id,
};
return data.pack.main(sbjs_data);
}
function getUtmTerm() {
var referer = document.referrer;
if (get_param.utm_term) {
return get_param.utm_term;
} else if (referer && uri.parse(referer).host && uri.parse(referer).host.match(/^(?:.*\.)?yandex\..{2,9}$/i)) {
try {
return uri.getParam(uri.parse(document.referrer).query).text;
} catch (err) {
return false;
}
} else {
return false;
}
}
function checkReferer(type) {
var referer = document.referrer;
switch(type) {
case terms.traffic.organic:
return (!!referer && checkRefererHost(referer) && isOrganic(referer));
case terms.traffic.referral:
return (!!referer && checkRefererHost(referer) && isReferral(referer));
default:
return false;
}
}
function checkRefererHost(referer) {
if (p.domain) {
if (!isolate) {
var host_regex = new RegExp('^(?:.*\\.)?' + utils.escapeRegexp(domain) + '$', 'i');
return !(uri.getHost(referer).match(host_regex));
} else {
return (uri.getHost(referer) !== uri.getHost(domain));
}
} else {
return (uri.getHost(referer) !== uri.getHost(document.location.href));
}
}
function isOrganic(referer) {
var y_host = 'yandex',
y_param = 'text',
g_host = 'google';
var y_host_regex = new RegExp('^(?:.*\\.)?' + utils.escapeRegexp(y_host) + '\\..{2,9}$'),
y_param_regex = new RegExp('.*' + utils.escapeRegexp(y_param) + '=.*'),
g_host_regex = new RegExp('^(?:www\\.)?' + utils.escapeRegexp(g_host) + '\\..{2,9}$');
if (
!!uri.parse(referer).query &&
!!uri.parse(referer).host.match(y_host_regex) &&
!!uri.parse(referer).query.match(y_param_regex)
) {
__sbjs_source = y_host;
return true;
} else if (uri.parse(referer).host.match(g_host_regex)) {
__sbjs_source = g_host;
return true;
} else if (uri.parse(referer).query) {
for (var i = 0; i < p.organics.length; i++) {
if (
uri.parse(referer).host.match(new RegExp('^(?:.*\\.)?' + utils.escapeRegexp(p.organics[i].host) + '$', 'i')) &&
uri.parse(referer).query.match(new RegExp('.*' + utils.escapeRegexp(p.organics[i].param) + '=.*', 'i'))
) {
__sbjs_source = p.organics[i].display || p.organics[i].host;
return true;
}
if (i + 1 === p.organics.length) {
return false;
}
}
} else {
return false;
}
}
function isReferral(referer) {
if (p.referrals.length > 0) {
for (var i = 0; i < p.referrals.length; i++) {
if (uri.parse(referer).host.match(new RegExp('^(?:.*\\.)?' + utils.escapeRegexp(p.referrals[i].host) + '$', 'i'))) {
__sbjs_source = p.referrals[i].display || p.referrals[i].host;
__sbjs_medium = p.referrals[i].medium || terms.referer.referral;
return true;
}
if (i + 1 === p.referrals.length) {
__sbjs_source = uri.getHost(referer);
return true;
}
}
} else {
__sbjs_source = uri.getHost(referer);
return true;
}
}
function setFirstAndCurrentExtraData() {
cookies.set(data.containers.current_extra, data.pack.extra(p.timezone_offset), lifetime, domain, isolate);
if (!cookies.get(data.containers.first_extra)) {
cookies.set(data.containers.first_extra, data.pack.extra(p.timezone_offset), lifetime, domain, isolate);
}
}
function setClickIdsToCookies() {
// 30 days in minutes for affiliate cookies (SD, KS)
var affiliateLifetime = 30 * 24 * 60;
var gclid = get_param.gclid || '';
var gbraid = get_param.gbraid || '';
var wbraid = get_param.wbraid || '';
var fbclid = get_param.fbclid || '';
var ttclid = get_param.ttclid || '';
// if utm_source = "sd" -> utm_term param is used
var sdclid = get_param.utm_source === 'sd' ? get_param.utm_term || '' : '';
// Kyivstar click ID
var ksclid = get_param.ks_click_id || '';
if (gbraid !== '') {
cookies.destroy('_mate-sdclid', domain, isolate);
cookies.destroy('_mate-ksclid', domain, isolate);
cookies.set('_mate-gbraid', gbraid, lifetime, domain, isolate);
}
if (wbraid !== '') {
cookies.destroy('_mate-sdclid', domain, isolate);
cookies.destroy('_mate-ksclid', domain, isolate);
cookies.set('_mate-wbraid', wbraid, lifetime, domain, isolate);
}
if (gclid !== '') {
cookies.destroy('_mate-sdclid', domain, isolate);
cookies.destroy('_mate-ksclid', domain, isolate);
cookies.set('_mate-gclid', gclid, lifetime, domain, isolate);
}
if (fbclid !== '') {
cookies.destroy('_mate-sdclid', domain, isolate);
cookies.destroy('_mate-ksclid', domain, isolate);
cookies.set('_mate-fbclid', fbclid, lifetime, domain, isolate);
}
if (ttclid !== '') {
cookies.destroy('_mate-sdclid', domain, isolate);
cookies.destroy('_mate-ksclid', domain, isolate);
cookies.set('_mate-ttclid', ttclid, lifetime, domain, isolate);
}
if (sdclid !== '') {
cookies.destroy('_mate-ksclid', domain, isolate);
cookies.set('_mate-sdclid', sdclid, affiliateLifetime, domain, isolate);
}
if (ksclid !== '') {
cookies.destroy('_mate-sdclid', domain, isolate);
cookies.set('_mate-ksclid', ksclid, affiliateLifetime, domain, isolate);
}
// Mirror Axon pixel cookie for enhanced user identification
var axwrt = cookies.get('_axwrt');
if (axwrt && axwrt !== cookies.get('axwrt')) {
var oneYearInMinutes = 365 * 24 * 60;
cookies.set('axwrt', axwrt, oneYearInMinutes, domain, isolate);
}
}
(function setData() {
var sbjs_data = mainData();
// Main data
cookies.set(data.containers.current, sbjs_data.data, lifetime, domain, isolate);
if (!cookies.get(data.containers.first)) {
cookies.set(data.containers.first, cookies.get(data.containers.current), lifetime, domain, isolate);
}
// User data
var visits, udata;
if (!cookies.get(data.containers.udata)) {
visits = 1;
udata = data.pack.user(visits, p.user_ip);
} else {
visits = parseInt(cookies.parse(data.containers.udata)[cookies.unsbjs(data.containers.udata)][data.aliases.udata.visits]) || 1;
visits = cookies.get(data.containers.session) ? visits : visits + 1;
udata = data.pack.user(visits, p.user_ip);
}
cookies.set(data.containers.udata, udata, lifetime, domain, isolate);
// Session
var pages_count;
var session_id;
if (!cookies.get(data.containers.session)) {
pages_count = 1;
} else {
pages_count = parseInt(cookies.parse(data.containers.session)[cookies.unsbjs(data.containers.session)][data.aliases.session.pages_seen]) || 1;
pages_count += 1;
}
if (!cookies.get(data.containers.session) || sbjs_data.is_utm_changed) {
session_id = new Date().getTime();
}
cookies.set(
data.containers.session,
data.pack.session(pages_count, session_id),
p.session_length,
domain,
isolate
);
// Promocode
if (p.promocode && !cookies.get(data.containers.promocode)) {
cookies.set(data.containers.promocode, data.pack.promo(p.promocode), lifetime, domain, isolate);
}
})();
return cookies.parse(data.containers);
};