Skip to content

Commit

Permalink
bidWatch Analytics Adapter : add creative endpoint (prebid#8710)
Browse files Browse the repository at this point in the history
* New Analytics Adapter bidwatch

* test for bidwatch Analytics Adapter

* change maintainer address

* Update bidwatchAnalyticsAdapter.js

* Update bidwatchAnalyticsAdapter.js

* Update bidwatchAnalyticsAdapter.md

* Update bidwatchAnalyticsAdapter.md

* add features to bidwatchAnalyticsAdapter

* update tests

* add test and made improvements
  • Loading branch information
matthieularere-msq authored and JacobKlein26 committed Feb 8, 2023
1 parent 018fe56 commit a95c929
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 12 deletions.
81 changes: 70 additions & 11 deletions modules/bidwatchAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@ const {
EVENTS: {
AUCTION_END,
BID_WON,
BID_RESPONSE,
BID_REQUESTED,
}
} = CONSTANTS;

let saveEvents = {}
let allEvents = {}
let auctionEnd = {}
let initOptions = {}
let endpoint = 'https://default'
let objectToSearchForBidderCode = ['bidderRequests', 'bidsReceived', 'noBids']
Expand All @@ -22,53 +26,108 @@ function getAdapterNameForAlias(aliasName) {
return adapterManager.aliasRegistry[aliasName] || aliasName;
}

function setOriginalBidder(arg) {
function cleanArgObject(arg, removead) {
if (typeof arg['bidderCode'] == 'string') { arg['originalBidder'] = getAdapterNameForAlias(arg['bidderCode']); }
if (typeof arg['creativeId'] == 'number') {
arg['creativeId'] = arg['creativeId'].toString();
}
if (removead && typeof arg['ad'] != 'undefined') {
arg['ad'] = 'emptied';
}
if (typeof arg['gdprConsent'] != 'undefined' && typeof arg['gdprConsent']['vendorData'] != 'undefined') {
arg['gdprConsent']['vendorData'] = 'emptied';
}
return arg;
}

function cleanArgs(arg, removead) {
Object.keys(arg).forEach(key => {
arg[key]['originalBidder'] = getAdapterNameForAlias(arg[key]['bidderCode']);
if (typeof arg[key]['creativeId'] == 'number') { arg[key]['creativeId'] = arg[key]['creativeId'].toString(); }
arg[key] = cleanArgObject(arg[key], removead);
});
return arg
}

function checkBidderCode(args) {
function checkBidderCode(args, removead) {
if (typeof args == 'object') {
for (let i = 0; i < objectToSearchForBidderCode.length; i++) {
if (typeof args[objectToSearchForBidderCode[i]] == 'object') { args[objectToSearchForBidderCode[i]] = setOriginalBidder(args[objectToSearchForBidderCode[i]]) }
if (typeof args[objectToSearchForBidderCode[i]] == 'object') { args[objectToSearchForBidderCode[i]] = cleanArgs(args[objectToSearchForBidderCode[i]], removead) }
}
}
if (typeof args['bidderCode'] == 'string') { args['originalBidder'] = getAdapterNameForAlias(args['bidderCode']); } else if (typeof args['bidder'] == 'string') { args['originalBidder'] = getAdapterNameForAlias(args['bidder']); }
if (typeof args['creativeId'] == 'number') { args['creativeId'] = args['creativeId'].toString(); }

return args
}

function addEvent(eventType, args) {
if (allEvents[eventType] == undefined) { allEvents[eventType] = [] }
if (eventType && args) { args = checkBidderCode(args); }
allEvents[eventType].push(args);
let argsCleaned;
if (eventType && args) {
if (allEvents[eventType] == undefined) { allEvents[eventType] = [] }
if (saveEvents[eventType] == undefined) { saveEvents[eventType] = [] }
argsCleaned = checkBidderCode(JSON.parse(JSON.stringify(args)), false);
allEvents[eventType].push(argsCleaned);
saveEvents[eventType].push(argsCleaned);
argsCleaned = checkBidderCode(JSON.parse(JSON.stringify(args)), true);
if (['auctionend', 'bidtimeout'].includes(eventType.toLowerCase())) {
if (auctionEnd[eventType] == undefined) { auctionEnd[eventType] = [] }
auctionEnd[eventType].push(argsCleaned);
}
}
}

function handleBidWon(args) {
if (typeof allEvents.bidRequested == 'object' && allEvents.bidRequested.length > 0 && allEvents.bidRequested[0].gdprConsent) { args.gdpr = allEvents.bidRequested[0].gdprConsent; }
args = cleanArgObject(JSON.parse(JSON.stringify(args)), true);
let increment = args['cpm'];
if (typeof saveEvents['auctionEnd'] == 'object') {
for (let i = 0; i < saveEvents['auctionEnd'].length; i++) {
let tmpAuction = saveEvents['auctionEnd'][i];
if (tmpAuction['auctionId'] == args['auctionId'] && typeof tmpAuction['bidsReceived'] == 'object') {
for (let j = 0; j < tmpAuction['bidsReceived'].length; j++) {
let tmpBid = tmpAuction['bidsReceived'][j];
if (tmpBid['transactionId'] == args['transactionId'] && tmpBid['adId'] != args['adId']) {
if (args['cpm'] < tmpBid['cpm']) {
increment = 0;
} else if (increment > args['cpm'] - tmpBid['cpm']) {
increment = args['cpm'] - tmpBid['cpm'];
}
}
}
}
}
}
args['cpmIncrement'] = increment;
if (typeof saveEvents.bidRequested == 'object' && saveEvents.bidRequested.length > 0 && saveEvents.bidRequested[0].gdprConsent) { args.gdpr = saveEvents.bidRequested[0].gdprConsent; }
ajax(endpoint + '.bidwatch.io/analytics/bid_won', null, JSON.stringify(args), {method: 'POST', withCredentials: true});
}

function handleAuctionEnd() {
ajax(endpoint + '.bidwatch.io/analytics/auctions', null, JSON.stringify(allEvents), {method: 'POST', withCredentials: true});
ajax(endpoint + '.bidwatch.io/analytics/auctions', null, JSON.stringify(auctionEnd), {method: 'POST', withCredentials: true});
auctionEnd = {}
if (typeof allEvents['bidResponse'] != 'undefined') {
for (let i = 0; i < allEvents['bidResponse'].length; i++) { ajax(endpoint + '.bidwatch.io/analytics/creatives', null, JSON.stringify(allEvents['bidResponse'][i]), {method: 'POST', withCredentials: true}); }
}
allEvents = {}
}

let bidwatchAnalytics = Object.assign(adapter({url, analyticsType}), {
track({
eventType,
args
}) {
addEvent(eventType, args);
switch (eventType) {
case AUCTION_END:
addEvent(eventType, args);
handleAuctionEnd();
break;
case BID_WON:
handleBidWon(args);
break;
case BID_RESPONSE:
addEvent(eventType, args);
break;
case BID_REQUESTED:
addEvent(eventType, args);
break;
}
}});

Expand Down
18 changes: 17 additions & 1 deletion test/spec/modules/bidwatchAnalyticsAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ describe('BidWatch Analytics', function () {
'gdprConsent': {
'consentString': 'CONSENT',
'gdprApplies': true,
'apiVersion': 2
'apiVersion': 2,
'vendorData': 'a lot of borring stuff',
},
'start': 1647424261189
},
Expand Down Expand Up @@ -281,7 +282,22 @@ describe('BidWatch Analytics', function () {
});
events.emit(constants.EVENTS.BID_TIMEOUT, bidTimeout);
events.emit(constants.EVENTS.AUCTION_END, auctionEnd);
expect(server.requests.length).to.equal(1);
let message = JSON.parse(server.requests[0].requestBody);
expect(message).to.have.property('auctionEnd').exist;
expect(message.auctionEnd).to.have.lengthOf(1);
expect(message.auctionEnd[0]).to.have.property('bidsReceived').and.to.have.lengthOf(1);
expect(message.auctionEnd[0].bidsReceived[0]).to.have.property('ad');
expect(message.auctionEnd[0].bidsReceived[0].ad).to.equal('emptied');
expect(message.auctionEnd[0]).to.have.property('bidderRequests').and.to.have.lengthOf(1);
expect(message.auctionEnd[0].bidderRequests[0]).to.have.property('gdprConsent');
expect(message.auctionEnd[0].bidderRequests[0].gdprConsent).to.have.property('vendorData');
expect(message.auctionEnd[0].bidderRequests[0].gdprConsent.vendorData).to.equal('emptied');
events.emit(constants.EVENTS.BID_WON, bidWon);
expect(server.requests.length).to.equal(2);
message = JSON.parse(server.requests[1].requestBody);
expect(message).to.have.property('ad').and.to.equal('emptied');
expect(message).to.have.property('cpmIncrement').and.to.equal(27.4276);
sinon.assert.callCount(bidwatchAnalytics.track, 3);
});
});
Expand Down

0 comments on commit a95c929

Please sign in to comment.