diff --git a/modules/bidwatchAnalyticsAdapter.js b/modules/bidwatchAnalyticsAdapter.js index 26a8c370af3..138f0533238 100644 --- a/modules/bidwatchAnalyticsAdapter.js +++ b/modules/bidwatchAnalyticsAdapter.js @@ -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'] @@ -22,38 +26,87 @@ 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}), { @@ -61,14 +114,20 @@ let bidwatchAnalytics = Object.assign(adapter({url, analyticsType}), { 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; } }}); diff --git a/test/spec/modules/bidwatchAnalyticsAdapter_spec.js b/test/spec/modules/bidwatchAnalyticsAdapter_spec.js index 1a322d131a9..f827f068bb3 100644 --- a/test/spec/modules/bidwatchAnalyticsAdapter_spec.js +++ b/test/spec/modules/bidwatchAnalyticsAdapter_spec.js @@ -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 }, @@ -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); }); });