diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index 802a8ac25b0..cf732d343e5 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -14,6 +14,7 @@ import { import CONSTANTS from '../src/constants.json'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import {config} from '../src/config.js'; import * as events from '../src/events.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; @@ -22,6 +23,7 @@ import { getRefererInfo } from '../src/refererDetection.js'; const BIDDER_CODE = 'nextMillennium'; const ENDPOINT = 'https://pbs.nextmillmedia.com/openrtb2/auction'; const TEST_ENDPOINT = 'https://test.pbs.nextmillmedia.com/openrtb2/auction'; +const REPORT_ENDPOINT = 'https://report2.hb.brainlyads.com/statistics/metric'; const SYNC_ENDPOINT = 'https://cookies.nextmillmedia.com/sync?'; const TIME_TO_LIVE = 360; const VIDEO_PARAMS = [ @@ -29,11 +31,14 @@ const VIDEO_PARAMS = [ 'playbackmethod', 'protocols', 'startdelay' ]; +const sendingDataStatistic = initSendingDataStatistic(); +events.on(CONSTANTS.EVENTS.AUCTION_INIT, auctionInitHandler); + const EXPIRENCE_WURL = 20 * 60000; const wurlMap = {}; +cleanWurl(); events.on(CONSTANTS.EVENTS.BID_WON, bidWonHandler); -cleanWurl(); export const spec = { code: BIDDER_CODE, @@ -135,6 +140,7 @@ export const spec = { const urlParameters = parseUrl(getWindowTop().location.href).search; const isTest = urlParameters['pbs'] && urlParameters['pbs'] === 'test'; + const params = bid.params; requests.push({ method: 'POST', @@ -146,6 +152,7 @@ export const spec = { }, bidId, + params, auctionId, }); }); @@ -160,6 +167,7 @@ export const spec = { _each(response.seatbid, (resp) => { _each(resp.bid, (bid) => { const requestId = bidRequest.bidId; + const params = bidRequest.params; const auctionId = bidRequest.auctionId; const wurl = deepAccess(bid, 'ext.prebid.events.win'); addWurl({auctionId, requestId, wurl}); @@ -168,6 +176,7 @@ export const spec = { const bidResponse = { requestId, + params, cpm: bid.price, width: bid.w, height: bid.h, @@ -217,6 +226,41 @@ export const spec = { return pixels; }, + + getUrlPixelMetric(eventName, bid) { + const bidder = bid.bidder || bid.bidderCode; + if (bidder != BIDDER_CODE) return; + + let params; + if (bid.params) { + params = Array.isArray(bid.params) ? bid.params : [bid.params]; + } else { + if (Array.isArray(bid.bids)) params = bid.bids.map(bidI => bidI.params); + }; + + if (!params.length) return; + + const placementIdsArray = []; + const groupIdsArray = []; + params.forEach(paramsI => { + if (paramsI.group_id) { + groupIdsArray.push(paramsI.group_id); + } else { + if (paramsI.placement_id) placementIdsArray.push(paramsI.placement_id); + }; + }); + + const placementIds = (placementIdsArray.length && `&placements=${placementIdsArray.join(';')}`) || ''; + const groupIds = (groupIdsArray.length && `&groups=${groupIdsArray.join(';')}`) || ''; + + if (!(groupIds || placementIds)) { + return; + }; + + const url = `${REPORT_ENDPOINT}?event=${eventName}&bidder=${bidder}&source=pbjs${groupIds}${placementIds}`; + + return url; + }, }; function getAdEl(bid) { @@ -338,6 +382,10 @@ function bidWonHandler(bid) { }; } +function auctionInitHandler() { + sendingDataStatistic.initEvents(); +} + function cleanWurl() { const dateNow = Date.now(); Object.keys(wurlMap).forEach(key => { @@ -349,4 +397,79 @@ function cleanWurl() { setTimeout(cleanWurl, 60000); } +function initSendingDataStatistic() { + class SendingDataStatistic { + eventNames = [ + CONSTANTS.EVENTS.BID_TIMEOUT, + CONSTANTS.EVENTS.BID_RESPONSE, + CONSTANTS.EVENTS.BID_REQUESTED, + CONSTANTS.EVENTS.NO_BID, + ]; + + disabledSending = false; + enabledSending = false; + eventHendlers = {}; + + initEvents() { + this.disabledSending = !!config.getBidderConfig()?.nextMillennium?.disabledSendingStatisticData; + if (this.disabledSending) { + this.removeEvents(); + } else { + this.createEvents(); + }; + } + + createEvents() { + if (this.enabledSending) return; + + this.enabledSending = true; + for (let eventName of this.eventNames) { + if (!this.eventHendlers[eventName]) { + this.eventHendlers[eventName] = this.eventHandler(eventName); + }; + + events.on(eventName, this.eventHendlers[eventName]); + }; + } + + removeEvents() { + if (!this.enabledSending) return; + + this.enabledSending = false; + for (let eventName of this.eventNames) { + if (!this.eventHendlers[eventName]) continue; + + events.off(eventName, this.eventHendlers[eventName]); + }; + } + + eventHandler(eventName) { + const eventHandlerFunc = this.getEventHandler(eventName); + if (eventName == CONSTANTS.EVENTS.BID_TIMEOUT) { + return bids => { + if (this.disabledSending || !Array.isArray(bids)) return; + + for (let bid of bids) { + eventHandlerFunc(bid); + }; + } + }; + + return eventHandlerFunc; + } + + getEventHandler(eventName) { + return bid => { + if (this.disabledSending) return; + + const url = spec.getUrlPixelMetric(eventName, bid); + if (!url) return; + triggerPixel(url); + }; + } + }; + + return new SendingDataStatistic(); +} + registerBidder(spec); diff --git a/test/spec/modules/nextMillenniumBidAdapter_spec.js b/test/spec/modules/nextMillenniumBidAdapter_spec.js index 2b5ae801489..3094c1349f7 100644 --- a/test/spec/modules/nextMillenniumBidAdapter_spec.js +++ b/test/spec/modules/nextMillenniumBidAdapter_spec.js @@ -276,4 +276,137 @@ describe('nextMillenniumBidAdapterTests', function() { expect(bid.height).to.equal(250); expect(bid.currency).to.equal('USD'); }); + + it('Check function of getting URL for sending statistics data', function() { + const dataForTests = [ + { + eventName: 'bidRequested', + bid: { + bidderCode: 'appnexus', + bids: [{bidder: 'appnexus', params: {}}], + }, + + expected: undefined, + }, + + { + eventName: 'bidRequested', + bid: { + bidderCode: 'appnexus', + bids: [{bidder: 'appnexus', params: {placement_id: '807'}}], + }, + + expected: undefined, + }, + + { + eventName: 'bidRequested', + bid: { + bidderCode: 'nextMillennium', + bids: [{bidder: 'nextMillennium', params: {placement_id: '807'}}], + }, + + expected: 'https://report2.hb.brainlyads.com/statistics/metric?event=bidRequested&bidder=nextMillennium&source=pbjs&placements=807', + }, + + { + eventName: 'bidRequested', + bid: { + bidderCode: 'nextMillennium', + bids: [ + {bidder: 'nextMillennium', params: {placement_id: '807'}}, + {bidder: 'nextMillennium', params: {placement_id: '111'}}, + ], + }, + + expected: 'https://report2.hb.brainlyads.com/statistics/metric?event=bidRequested&bidder=nextMillennium&source=pbjs&placements=807;111', + }, + + { + eventName: 'bidRequested', + bid: { + bidderCode: 'nextMillennium', + bids: [{bidder: 'nextMillennium', params: {placement_id: '807', group_id: '123'}}], + }, + + expected: 'https://report2.hb.brainlyads.com/statistics/metric?event=bidRequested&bidder=nextMillennium&source=pbjs&groups=123', + }, + + { + eventName: 'bidRequested', + bid: { + bidderCode: 'nextMillennium', + bids: [ + {bidder: 'nextMillennium', params: {placement_id: '807', group_id: '123'}}, + {bidder: 'nextMillennium', params: {group_id: '456'}}, + {bidder: 'nextMillennium', params: {placement_id: '222'}}, + ], + }, + + expected: 'https://report2.hb.brainlyads.com/statistics/metric?event=bidRequested&bidder=nextMillennium&source=pbjs&groups=123;456&placements=222', + }, + + { + eventName: 'bidResponse', + bid: { + bidderCode: 'appnexus', + }, + + expected: undefined, + }, + + { + eventName: 'bidResponse', + bid: { + bidderCode: 'nextMillennium', + params: {placement_id: '807'}, + }, + + expected: 'https://report2.hb.brainlyads.com/statistics/metric?event=bidResponse&bidder=nextMillennium&source=pbjs&placements=807', + }, + + { + eventName: 'noBid', + bid: { + bidder: 'appnexus', + }, + + expected: undefined, + }, + + { + eventName: 'noBid', + bid: { + bidder: 'nextMillennium', + params: {placement_id: '807'}, + }, + + expected: 'https://report2.hb.brainlyads.com/statistics/metric?event=noBid&bidder=nextMillennium&source=pbjs&placements=807', + }, + + { + eventName: 'bidTimeout', + bid: { + bidder: 'appnexus', + }, + + expected: undefined, + }, + + { + eventName: 'bidTimeout', + bid: { + bidder: 'nextMillennium', + params: {placement_id: '807'}, + }, + + expected: 'https://report2.hb.brainlyads.com/statistics/metric?event=bidTimeout&bidder=nextMillennium&source=pbjs&placements=807', + }, + ]; + + for (let {eventName, bid, expected} of dataForTests) { + const url = spec.getUrlPixelMetric(eventName, bid); + expect(url).to.equal(expected); + }; + }) });