Skip to content

Commit

Permalink
Merged in RVR-1126-define-data-format (pull request #2)
Browse files Browse the repository at this point in the history
RVR-1126 Define data format
  • Loading branch information
Kacper Woźniak committed May 17, 2018
2 parents 6ea9f01 + d60ee26 commit 48e2fac
Showing 1 changed file with 194 additions and 60 deletions.
254 changes: 194 additions & 60 deletions modules/rivrAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,9 @@ import adaptermanager from 'src/adaptermanager';
import { logInfo } from 'src/utils';

const analyticsType = 'endpoint';
const DEFAULT_HOST = 'integrations.rivr.simplaex.net/prebid/auctions';
const DEFAULT_HOST = 'integrations.rivr.simplaex.net/prebid';
const DEFAULT_QUEUE_TIMEOUT = 4000;

const RIVR_HB_EVENTS = {
AUCTION_INIT: 'auctionInit',
BID_REQUEST: 'bidRequested',
BID_RESPONSE: 'bidResponse',
BID_WON: 'bidWon',
AUCTION_END: 'auctionEnd',
TIMEOUT: 'adapterTimedOut'
};

let rivrAnalytics = Object.assign(adapter({analyticsType}), {
track({ eventType, args }) {
if (!rivrAnalytics.context) {
Expand All @@ -26,8 +17,12 @@ let rivrAnalytics = Object.assign(adapter({analyticsType}), {
let handler = null;
switch (eventType) {
case CONSTANTS.EVENTS.AUCTION_INIT:
if (rivrAnalytics.context.queue) {
rivrAnalytics.context.queue.init();
if (rivrAnalytics.context.impressionsQueue) {
rivrAnalytics.context.impressionsQueue.init();
}
if (rivrAnalytics.context.auctionObject) {
rivrAnalytics.context.auctionObject = fulfillAuctionObject();
fetchLocalization();
}
handler = trackAuctionInit;
break;
Expand All @@ -48,83 +43,222 @@ let rivrAnalytics = Object.assign(adapter({analyticsType}), {
break;
}
if (handler) {
let events = handler(args);
if (rivrAnalytics.context.queue) {
rivrAnalytics.context.queue.push(events);
}
if (eventType === CONSTANTS.EVENTS.AUCTION_END) {
sendAll();
if (handler == trackBidWon) {
let impressions = handler(args);
if (rivrAnalytics.context.impressionsQueue) {
rivrAnalytics.context.impressionsQueue.push(impressions);
}
} else {
handler(args)
}
}
}
});

function sendAll() {
let events = rivrAnalytics.context.queue.popAll();
if (events.length !== 0) {
let req = Object.assign({}, {hb_ev: events});
logInfo('sending request to analytics => ', req);
ajax(`http://${rivrAnalytics.context.host}`, () => {
}, JSON.stringify(req));
let impressions = rivrAnalytics.context.impressionsQueue.popAll();
let auctionObject = rivrAnalytics.context.auctionObject;
let req = Object.assign({}, {Auction: auctionObject});
auctionObject = fulfillAuctionObject();
logInfo('sending request to analytics => ', req);
ajax(`http://${rivrAnalytics.context.host}/auctions`, () => {
}, JSON.stringify(req));

if (impressions.length !== 0) {
let impressionsReq = Object.assign({}, {impressions});
logInfo('sending impressions request to analytics => ', impressionsReq);
ajax(`http://${rivrAnalytics.context.host}/impressions`, () => {
}, JSON.stringify(impressionsReq));
}
}
};

function trackAuctionInit() {
function trackAuctionInit(args) {
rivrAnalytics.context.auctionTimeStart = Date.now();
const event = createHbEvent(undefined, RIVR_HB_EVENTS.AUCTION_INIT);
return [event];
}
rivrAnalytics.context.auctionObject.id = args.auctionId;
};

function trackBidRequest(args) {
return args.bids.map(bid =>
createHbEvent(args.bidderCode, RIVR_HB_EVENTS.BID_REQUEST, bid.adUnitCode));
}
setCurrentPublisherId(args);
};

function trackBidResponse(args) {
const event = createHbEvent(args.bidderCode, RIVR_HB_EVENTS.BID_RESPONSE,
args.adUnitCode, args.cpm, args.timeToRespond / 1000);
return [event];
}
let bidResponse = createBidResponse(args);
rivrAnalytics.context.auctionObject.bidResponses.push(bidResponse);
};

function trackBidWon(args) {
const event = createHbEvent(args.bidderCode, RIVR_HB_EVENTS.BID_WON, args.adUnitCode, args.cpm);
return [event];
let auctionObject = rivrAnalytics.context.auctionObject;
let bidResponse = createBidResponse(args);
let impression = createImpression(args);
let imp = createImp(args);
auctionObject.bidResponses.push(bidResponse);
auctionObject.imp.push(imp);

return [impression];
}

function trackAuctionEnd(args) {
const event = createHbEvent(undefined, RIVR_HB_EVENTS.AUCTION_END, undefined,
undefined, (Date.now() - rivrAnalytics.context.auctionTimeStart) / 1000);
return [event];
}
rivrAnalytics.context.auctionTimeEnd = Date.now();
};

function trackBidTimeout(args) {
return args.map(bidderName => createHbEvent(bidderName, RIVR_HB_EVENTS.TIMEOUT));
}
return [args];
};

function setCurrentPublisherId(bidRequested) {
let site = rivrAnalytics.context.auctionObject.site;
let app = rivrAnalytics.context.auctionObject.app;
let pubId = rivrAnalytics.context.pubId;
if (!site.publisher.id || app.publisher.id) {
if (pubId) {
site.publisher.id = pubId;
app.publisher.id = pubId;
} else {
site.publisher.id = bidRequested.bids[0].crumbs.pubcid;
app.publisher.id = bidRequested.bids[0].crumbs.pubcid;
}
}
};

function fetchLocalization() {
navigator.geolocation.getCurrentPosition((position) => {
let deviceLocation = rivrAnalytics.context.auctionObject.device.geo;
deviceLocation.lat = position.coords.latitude;
deviceLocation.long = position.coords.longitude;
});
};

function createHbEvent(adapter, event, tagid = undefined, value = 0, time = 0) {
let ev = { event: event };
if (adapter) {
ev.adapter = adapter
function getPlatformType() {
if (navigator.userAgent.match(/mobile/i)) {
return 'Mobile';
} else if (navigator.userAgent.match(/iPad|Android|Touch/i)) {
return 'Tablet';
} else {
return 'Desktop';
}
if (tagid) {
ev.tagid = tagid;
}

function createBidResponse(bidResponseEvent) {
return {
timestamp: bidResponseEvent.responseTimestamp,
status: bidResponseEvent.getStatusCode(),
total_duration: bidResponseEvent.timeToRespond,
bidderId: null,
bidder_name: bidResponseEvent.bidder,
cur: bidResponseEvent.currency,
seatid: [
{
seat: null,
bid: [
{
status: bidResponseEvent.getStatusCode(),
clear_price: bidResponseEvent.cpm,
attr: [],
crid: bidResponseEvent.creativeId,
cid: null,
id: null,
adid: bidResponseEvent.adId,
adomain: [],
iurl: null
}
]
}
]
}
if (value) {
ev.val = value;
};

function createImpression(bidWonEvent) {
return {
timestamp: bidWonEvent.responseTimestamp,
requestId: bidWonEvent.auctionId,
chargePrice: bidWonEvent.adserverTargeting.hb_pb,
publisherRevenue: bidWonEvent.cpm
}
if (time) {
ev.time = time;
};

function createImp(bidWonEvent) {
return {
tagid: bidWonEvent.adUnitCode,
displaymanager: null,
displaymanagerver: null,
secure: null,
bidfloor: null,
banner: {
w: bidWonEvent.width,
h: bidWonEvent.height,
pos: null,
expandable: [],
api: []
}
}
return ev;
}
};

function fulfillAuctionObject() {
return {
id: null,
timestamp: null,
at: null,
bcat: [],
imp: [],
app: {
id: null,
name: null,
domain: null,
bundle: null,
cat: [],
publisher: {
id: null,
name: null
}
},
site: {
id: null,
name: null,
domain: window.location.hostname,
cat: [],
publisher: {
id: null,
name: null
}
},
device: {
geo: {
city: null,
country: null,
region: null,
zip: null,
type: null,
metro: null
},
connectiontype: navigator.connection.effectiveType,
devicetype: getPlatformType(),
osv: null,
os: null,
model: null,
make: null,
carrier: null,
ip: null,
didsha1: null,
dpidmd5: null,
ext: {
uid: null
}
},
user: {
id: null,
yob: null,
gender: null,
},
bidResponses: []
}
};
/**
* Expiring queue implementation. Fires callback on elapsed timeout since last last update or creation.
* @param callback
* @param ttl
* @constructor
*/
export function ExpiringQueue(callback, ttl) {
export function ExpiringQueue(callback, ttl, log) {
let queue = [];
let timeoutId;

Expand All @@ -143,7 +277,6 @@ export function ExpiringQueue(callback, ttl) {
reset();
return result;
};

/**
* For test/debug purposes only
* @return {Array}
Expand All @@ -164,7 +297,7 @@ export function ExpiringQueue(callback, ttl) {
}
}, ttl);
}
}
};

// save the base class function
rivrAnalytics.originEnableAnalytics = rivrAnalytics.enableAnalytics;
Expand All @@ -174,7 +307,8 @@ rivrAnalytics.enableAnalytics = (config) => {
rivrAnalytics.context = {
host: config.options.host || DEFAULT_HOST,
pubId: config.options.pubId,
queue: new ExpiringQueue(sendAll, config.options.queueTimeout || DEFAULT_QUEUE_TIMEOUT)
auctionObject: {},
impressionsQueue: new ExpiringQueue(sendAll, config.options.queueTimeout || DEFAULT_QUEUE_TIMEOUT)
};
logInfo('Rivr Analytics enabled with config', rivrAnalytics.context);
rivrAnalytics.originEnableAnalytics(config);
Expand Down

0 comments on commit 48e2fac

Please sign in to comment.