Skip to content

Commit 72aa251

Browse files
Hassijaafewcc
authored andcommitted
Invisibly analytics adapter (prebid#4470)
* PUBA-5273:initial commit with analytics adapter, spec & md file * PUBA-5273: updated adapter definition * PUBA-5273: added support contact info * PUBA-5273: adding clearInterval on AUCTION_END * PUBA-5273: reverted last commit as CircleCI job failed * Reverted changes to fix CircleCI build error * Re-commiting invocation of clearInterval on Auction_end
1 parent 95d8601 commit 72aa251

File tree

3 files changed

+744
-0
lines changed

3 files changed

+744
-0
lines changed

modules/invisiblyAnalyticsAdapter.js

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
/**
2+
* invisiblyAdapterAdapter.js - analytics adapter for Invisibly
3+
*/
4+
import { ajaxBuilder } from '../src/ajax';
5+
import adapter from '../src/AnalyticsAdapter';
6+
import adapterManager from '../src/adapterManager';
7+
8+
const DEFAULT_EVENT_URL = 'https://api.pymx5.com/v1/' + 'sites/events';
9+
const analyticsType = 'endpoint';
10+
const analyticsName = 'Invisibly Analytics Adapter:';
11+
12+
const utils = require('../src/utils');
13+
const CONSTANTS = require('../src/constants.json');
14+
const ajax = ajaxBuilder(0);
15+
16+
// Events needed
17+
const {
18+
EVENTS: {
19+
AUCTION_INIT,
20+
AUCTION_END,
21+
BID_ADJUSTMENT,
22+
BID_TIMEOUT,
23+
BID_REQUESTED,
24+
BID_RESPONSE,
25+
NO_BID,
26+
BID_WON,
27+
BIDDER_DONE,
28+
SET_TARGETING,
29+
REQUEST_BIDS,
30+
ADD_AD_UNITS,
31+
AD_RENDER_FAILED
32+
}
33+
} = CONSTANTS;
34+
35+
const _VERSION = 1;
36+
const _pageViewId = utils.generateUUID();
37+
let initOptions = null;
38+
let _startAuction = 0;
39+
let _bidRequestTimeout = 0;
40+
let flushInterval;
41+
let invisiblyAnalyticsEnabled = false;
42+
43+
const w = window;
44+
const d = document;
45+
let e = d.documentElement;
46+
let g = d.getElementsByTagName('body')[0];
47+
let x = w.innerWidth || e.clientWidth || g.clientWidth;
48+
let y = w.innerHeight || e.clientHeight || g.clientHeight;
49+
50+
let _pageView = {
51+
eventType: 'pageView',
52+
userAgent: window.navigator.userAgent,
53+
timestamp: Date.now(),
54+
timezoneOffset: new Date().getTimezoneOffset(),
55+
language: window.navigator.language,
56+
vendor: window.navigator.vendor,
57+
screenWidth: x,
58+
screenHeight: y
59+
};
60+
61+
let _eventQueue = [_pageView];
62+
63+
let invisiblyAdapter = Object.assign(
64+
adapter({ url: DEFAULT_EVENT_URL, analyticsType }),
65+
{
66+
track({ eventType, args }) {
67+
handleEvent(eventType, args);
68+
},
69+
sendEvent
70+
}
71+
);
72+
73+
invisiblyAdapter.originEnableAnalytics = invisiblyAdapter.enableAnalytics;
74+
invisiblyAdapter.enableAnalytics = function(config) {
75+
initOptions = config.options || {};
76+
initOptions.url = initOptions.url || DEFAULT_EVENT_URL;
77+
if (initOptions.url && initOptions.account) {
78+
invisiblyAnalyticsEnabled = true;
79+
invisiblyAdapter.originEnableAnalytics(config);
80+
} else {
81+
invisiblyAnalyticsEnabled = false;
82+
invisiblyAdapter.originDisableAnalytics();
83+
}
84+
flushInterval = setInterval(flush, 1000);
85+
};
86+
87+
invisiblyAdapter.originDisableAnalytics = invisiblyAdapter.disableAnalytics;
88+
invisiblyAdapter.disableAnalytics = function() {
89+
if (!invisiblyAnalyticsEnabled) {
90+
return;
91+
}
92+
flush();
93+
clearInterval(flushInterval);
94+
invisiblyAdapter.originDisableAnalytics();
95+
};
96+
97+
function flush() {
98+
if (!invisiblyAnalyticsEnabled) {
99+
return;
100+
}
101+
102+
if (_eventQueue.length > 0) {
103+
while (_eventQueue.length) {
104+
let eventFromQue = _eventQueue.shift();
105+
let eventtype = 'PREBID_' + eventFromQue.eventType;
106+
delete eventFromQue.eventType;
107+
108+
let data = {
109+
pageViewId: _pageViewId,
110+
ver: _VERSION,
111+
bundleId: initOptions.bundleId,
112+
...eventFromQue
113+
};
114+
115+
let payload = {
116+
event_type: eventtype,
117+
event_data: { ...data }
118+
};
119+
ajax(
120+
initOptions.url,
121+
() => utils.logInfo(`${analyticsName} sent events batch`),
122+
JSON.stringify(payload),
123+
{
124+
contentType: 'application/json',
125+
method: 'POST',
126+
withCredentials: true
127+
}
128+
);
129+
}
130+
}
131+
}
132+
133+
function handleEvent(eventType, eventArgs) {
134+
eventArgs = eventArgs ? JSON.parse(JSON.stringify(eventArgs)) : {};
135+
let invisiblyEvent = {};
136+
137+
switch (eventType) {
138+
case AUCTION_INIT: {
139+
invisiblyEvent = eventArgs;
140+
_startAuction = invisiblyEvent.timestamp;
141+
_bidRequestTimeout = invisiblyEvent.timeout;
142+
break;
143+
}
144+
case AUCTION_END: {
145+
invisiblyEvent = eventArgs;
146+
invisiblyEvent.start = _startAuction;
147+
invisiblyEvent.end = Date.now();
148+
break;
149+
}
150+
case BID_ADJUSTMENT: {
151+
invisiblyEvent.bidders = eventArgs;
152+
break;
153+
}
154+
case BID_TIMEOUT: {
155+
invisiblyEvent.bidders = eventArgs;
156+
invisiblyEvent.duration = _bidRequestTimeout;
157+
break;
158+
}
159+
case BID_REQUESTED: {
160+
invisiblyEvent = eventArgs;
161+
break;
162+
}
163+
case BID_RESPONSE: {
164+
invisiblyEvent = eventArgs;
165+
break;
166+
}
167+
case NO_BID: {
168+
invisiblyEvent.noBid = eventArgs;
169+
break;
170+
}
171+
case BID_WON: {
172+
invisiblyEvent = eventArgs;
173+
break;
174+
}
175+
case BIDDER_DONE: {
176+
invisiblyEvent = eventArgs;
177+
break;
178+
}
179+
case SET_TARGETING: {
180+
invisiblyEvent.targetings = eventArgs;
181+
break;
182+
}
183+
case REQUEST_BIDS: {
184+
invisiblyEvent = eventArgs;
185+
break;
186+
}
187+
case ADD_AD_UNITS: {
188+
invisiblyEvent = eventArgs;
189+
break;
190+
}
191+
case AD_RENDER_FAILED: {
192+
invisiblyEvent = eventArgs;
193+
break;
194+
}
195+
default:
196+
return;
197+
}
198+
invisiblyEvent.eventType = eventType;
199+
invisiblyEvent.timestamp = invisiblyEvent.timestamp || Date.now();
200+
sendEvent(invisiblyEvent);
201+
}
202+
203+
function sendEvent(event) {
204+
_eventQueue.push(event);
205+
utils.logInfo(`${analyticsName}Event ${event.eventType}:`, event);
206+
207+
if (event.eventType === AUCTION_END) {
208+
flush();
209+
clearInterval(flushInterval);
210+
}
211+
}
212+
213+
adapterManager.registerAnalyticsAdapter({
214+
adapter: invisiblyAdapter,
215+
code: 'invisiblyAnalytics'
216+
});
217+
218+
invisiblyAdapter.getOptions = function() {
219+
return initOptions;
220+
};
221+
222+
invisiblyAdapter.flush = flush;
223+
224+
export default invisiblyAdapter;

modules/invisiblyAnalyticsAdapter.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Overview
2+
3+
```
4+
Module Name: Invisibly Analytics
5+
6+
Module Type: Analytics Adapter
7+
8+
Maintainer: [email protected]
9+
```
10+
11+
# Description
12+
13+
Analytics adapter for Invisibly. Please contact: [email protected] for any additional information. Official website link to the vendor: https://invisibly.com/
14+
15+
# Test Parameters
16+
17+
```
18+
{
19+
provider: 'invisiblyAnalytics',
20+
options : {
21+
account: 'invisibly' //account is a mandatory input to adapter configuration
22+
}
23+
}
24+
```

0 commit comments

Comments
 (0)