Skip to content

Commit

Permalink
ATS Analytics: Send additional analytics data (#6145)
Browse files Browse the repository at this point in the history
* ATS-analytics - add new way to detect browser and add envelope_source

* ATS-analytics - implement preflight logic

* ATS-analytics - change analytics prod url

* ATS-analytics - fix LGTM and add console log to atsAnalyticsAdapter test

* ATS-analytics - fix internet explorer 11 bug

* ATS-analytics - add logs on parseBrowser function

* ATS-analytics - try check with indexOf function

* ATS-analytics - fix sinon restore for ie11

* ATS-analytics - fix sinon restore for ie11

* ATS-analytics - try to fix sinon restore for ie11

* ATS-analytics - try to fix sinon restore for ie11

* ATS-analytics - refactor unit tests for userAgent

* [ATS-Analytics] - Added semicolons

Co-authored-by: Nemanja Rajkovic <[email protected]>
  • Loading branch information
mamatic and Nemanja Rajkovic authored Jan 27, 2021
1 parent eefd2af commit 819176c
Show file tree
Hide file tree
Showing 4 changed files with 302 additions and 132 deletions.
329 changes: 259 additions & 70 deletions modules/atsAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,230 @@ import CONSTANTS from '../src/constants.json';
import adaptermanager from '../src/adapterManager.js';
import * as utils from '../src/utils.js';
import {ajax} from '../src/ajax.js';
import {getStorageManager} from '../src/storageManager.js';

export const storage = getStorageManager();

const analyticsType = 'endpoint';
// dev endpoints
// const preflightUrl = 'https://analytics-check.publishersite.xyz/check/';
// export const analyticsUrl = 'https://analyticsv2.publishersite.xyz';

const preflightUrl = 'https://check.analytics.rlcdn.com/check/';
export const analyticsUrl = 'https://analytics.rlcdn.com';

let handlerRequest = [];
let handlerResponse = [];
let host = '';

let atsAnalyticsAdapterVersion = 1;

let browsersList = [
/* Googlebot */
{
test: /googlebot/i,
name: 'Googlebot'
},

/* Opera < 13.0 */
{
test: /opera/i,
name: 'Opera',
},

/* Opera > 13.0 */
{
test: /opr\/|opios/i,
name: 'Opera'
},
{
test: /SamsungBrowser/i,
name: 'Samsung Internet for Android',
},
{
test: /Whale/i,
name: 'NAVER Whale Browser',
},
{
test: /MZBrowser/i,
name: 'MZ Browser'
},
{
test: /focus/i,
name: 'Focus',
},
{
test: /swing/i,
name: 'Swing',
},
{
test: /coast/i,
name: 'Opera Coast',
},
{
test: /opt\/\d+(?:.?_?\d+)+/i,
name: 'Opera Touch',
},
{
test: /yabrowser/i,
name: 'Yandex Browser',
},
{
test: /ucbrowser/i,
name: 'UC Browser',
},
{
test: /Maxthon|mxios/i,
name: 'Maxthon',
},
{
test: /epiphany/i,
name: 'Epiphany',
},
{
test: /puffin/i,
name: 'Puffin',
},
{
test: /sleipnir/i,
name: 'Sleipnir',
},
{
test: /k-meleon/i,
name: 'K-Meleon',
},
{
test: /micromessenger/i,
name: 'WeChat',
},
{
test: /qqbrowser/i,
name: (/qqbrowserlite/i).test(window.navigator.userAgent) ? 'QQ Browser Lite' : 'QQ Browser',
},
{
test: /msie|trident/i,
name: 'Internet Explorer',
},
{
test: /\sedg\//i,
name: 'Microsoft Edge',
},
{
test: /edg([ea]|ios)/i,
name: 'Microsoft Edge',
},
{
test: /vivaldi/i,
name: 'Vivaldi',
},
{
test: /seamonkey/i,
name: 'SeaMonkey',
},
{
test: /sailfish/i,
name: 'Sailfish',
},
{
test: /silk/i,
name: 'Amazon Silk',
},
{
test: /phantom/i,
name: 'PhantomJS',
},
{
test: /slimerjs/i,
name: 'SlimerJS',
},
{
test: /blackberry|\bbb\d+/i,
name: 'BlackBerry',
},
{
test: /(web|hpw)[o0]s/i,
name: 'WebOS Browser',
},
{
test: /bada/i,
name: 'Bada',
},
{
test: /tizen/i,
name: 'Tizen',
},
{
test: /qupzilla/i,
name: 'QupZilla',
},
{
test: /firefox|iceweasel|fxios/i,
name: 'Firefox',
},
{
test: /electron/i,
name: 'Electron',
},
{
test: /MiuiBrowser/i,
name: 'Miui',
},
{
test: /chromium/i,
name: 'Chromium',
},
{
test: /chrome|crios|crmo/i,
name: 'Chrome',
},
{
test: /GSA/i,
name: 'Google Search',
},

/* Android Browser */
{
test: /android/i,
name: 'Android Browser',
},

/* PlayStation 4 */
{
test: /playstation 4/i,
name: 'PlayStation 4',
},

/* Safari */
{
test: /safari|applewebkit/i,
name: 'Safari',
},
];

function setSamplingCookie(samplRate) {
let now = new Date();
now.setTime(now.getTime() + 3600000);
storage.setCookie('_lr_sampling_rate', samplRate, now.toUTCString());
}

let listOfSupportedBrowsers = ['Safari', 'Chrome', 'Firefox', 'Microsoft Edge'];

function bidRequestedHandler(args) {
let envelopeSourceCookieValue = storage.getCookie('_lr_env_src_ats');
let envelopeSource = envelopeSourceCookieValue === 'true';
let requests;
requests = args.bids.map(function(bid) {
return {
envelope_source: envelopeSource,
has_envelope: bid.userId ? !!bid.userId.idl_env : false,
bidder: bid.bidder,
bid_id: bid.bidId,
auction_id: args.auctionId,
user_browser: checkUserBrowser(),
user_browser: parseBrowser(),
user_platform: navigator.platform,
auction_start: new Date(args.auctionStart).toJSON(),
domain: window.location.hostname,
pid: atsAnalyticsAdapter.context.pid,
adapter_version: atsAnalyticsAdapterVersion
};
});
return requests;
Expand All @@ -38,58 +242,44 @@ function bidResponseHandler(args) {
};
}

export function checkUserBrowser() {
let firefox = browserIsFirefox();
let chrome = browserIsChrome();
let edge = browserIsEdge();
let safari = browserIsSafari();
if (firefox) {
return firefox;
} if (chrome) {
return chrome;
} if (edge) {
return edge;
} if (safari) {
return safari;
} else {
return 'Unknown'
export function parseBrowser() {
let ua = atsAnalyticsAdapter.getUserAgent();
try {
let result = browsersList.filter(function(obj) {
return obj.test.test(ua);
});
let browserName = result && result.length ? result[0].name : '';
return (listOfSupportedBrowsers.indexOf(browserName) >= 0) ? browserName : 'Unknown';
} catch (err) {
utils.logError('ATS Analytics - Error while checking user browser!', err);
}
}

export function browserIsFirefox() {
if (typeof InstallTrigger !== 'undefined') {
return 'Firefox';
} else {
return false;
function sendDataToAnalytic () {
// send data to ats analytic endpoint
try {
let dataToSend = {'Data': atsAnalyticsAdapter.context.events};
let strJSON = JSON.stringify(dataToSend);
utils.logInfo('ATS Analytics - tried to send analytics data!');
ajax(analyticsUrl, function () {
}, strJSON, {method: 'POST', contentType: 'application/json'});
} catch (err) {
utils.logError('ATS Analytics - request encounter an error: ', err);
}
}

export function browserIsIE() {
return !!document.documentMode;
}

export function browserIsEdge() {
if (!browserIsIE() && !!window.StyleMedia) {
return 'Edge';
} else {
return false;
}
}

export function browserIsChrome() {
if ((!!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime)) || (/Android/i.test(navigator.userAgent) && !!window.chrome)) {
return 'Chrome';
} else {
return false;
}
}

export function browserIsSafari() {
if (window.safari !== undefined) {
return 'Safari'
} else {
return false;
}
// preflight request, to check did publisher have permission to send data to analytics endpoint
function preflightRequest (envelopeSourceCookieValue) {
ajax(preflightUrl + atsAnalyticsAdapter.context.pid, function (data) {
let samplingRateObject = JSON.parse(data);
utils.logInfo('ATS Analytics - Sampling Rate: ', samplingRateObject);
let samplingRate = samplingRateObject['samplingRate'];
setSamplingCookie(samplingRate);
let samplingRateNumber = Number(samplingRate);
if (data && samplingRate && atsAnalyticsAdapter.shouldFireRequest(samplingRateNumber) && envelopeSourceCookieValue != null) {
sendDataToAnalytic();
}
}, undefined, { method: 'GET', crossOrigin: true });
}

function callHandler(evtype, args) {
Expand Down Expand Up @@ -117,7 +307,6 @@ function callHandler(evtype, args) {

let atsAnalyticsAdapter = Object.assign(adapter(
{
host,
analyticsType
}),
{
Expand All @@ -126,16 +315,19 @@ let atsAnalyticsAdapter = Object.assign(adapter(
callHandler(eventType, args);
}
if (eventType === CONSTANTS.EVENTS.AUCTION_END) {
if (atsAnalyticsAdapter.shouldFireRequest()) {
// send data to ats analytic endpoint
try {
let dataToSend = {'Data': atsAnalyticsAdapter.context.events};
let strJSON = JSON.stringify(dataToSend);
utils.logInfo('atsAnalytics tried to send analytics data!');
ajax(atsAnalyticsAdapter.context.host, function () {
}, strJSON, {method: 'POST', contentType: 'application/json'});
} catch (err) {
let envelopeSourceCookieValue = storage.getCookie('_lr_env_src_ats');
try {
utils.logInfo('ATS Analytics - preflight request!');
let samplingRateCookie = storage.getCookie('_lr_sampling_rate');
if (!samplingRateCookie) {
preflightRequest(envelopeSourceCookieValue);
} else {
if (atsAnalyticsAdapter.shouldFireRequest(parseInt(samplingRateCookie)) && envelopeSourceCookieValue != null) {
sendDataToAnalytic();
}
}
} catch (err) {
utils.logError('ATS Analytics - preflight request encounter an error: ', err);
}
}
}
Expand All @@ -145,26 +337,23 @@ let atsAnalyticsAdapter = Object.assign(adapter(
atsAnalyticsAdapter.originEnableAnalytics = atsAnalyticsAdapter.enableAnalytics;

// add check to not fire request every time, but instead to send 1/10 events
atsAnalyticsAdapter.shouldFireRequest = function () {
return (Math.floor((Math.random() * 11)) === 10);
}
atsAnalyticsAdapter.shouldFireRequest = function (samplingRate) {
let shouldFireRequestValue = (Math.floor((Math.random() * samplingRate + 1)) === samplingRate);
utils.logInfo('ATS Analytics - Should Fire Request: ', shouldFireRequestValue);
return shouldFireRequestValue;
};

atsAnalyticsAdapter.getUserAgent = function () {
return window.navigator.userAgent;
};
// override enableAnalytics so we can get access to the config passed in from the page
atsAnalyticsAdapter.enableAnalytics = function (config) {
if (!config.options.pid) {
utils.logError('Publisher ID (pid) option is not defined. Analytics won\'t work');
utils.logError('ATS Analytics - Publisher ID (pid) option is not defined. Analytics won\'t work');
return;
}

if (!config.options.host) {
utils.logError('Host option is not defined. Analytics won\'t work');
return;
}

host = config.options.host;
atsAnalyticsAdapter.context = {
events: [],
host: config.options.host,
pid: config.options.pid
};
let initOptions = config.options;
Expand Down
Loading

0 comments on commit 819176c

Please sign in to comment.