Skip to content

Commit

Permalink
Nextmillenium bid adapter: Collection of statistics data (prebid#9265)
Browse files Browse the repository at this point in the history
* changed name company

* changed name company in test

* Added processing of a new group_id parameter

* Added processing of a new group_id parameter

* changed check parameters

* fixed lint remarks

* added test

* fixed bug - lint

* changed test

* changed test - 2

* fixed bug - adapter

* added logic for getting ad impressions

* Collecting timeouts data

* Collecting resaponses and no_bids data

* changed a name function

* added event bidRequested

* added event bidRequested

* added function initialization events

* fixed bug

* save

* added tests

* Added processing of the disabledSendingStatisticData parameter, which disables sending statistics data

* changed the name of the variables
  • Loading branch information
mhlm authored and JacobKlein26 committed Feb 8, 2023
1 parent 198c381 commit 5dab862
Show file tree
Hide file tree
Showing 2 changed files with 257 additions and 1 deletion.
125 changes: 124 additions & 1 deletion modules/nextMillenniumBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -22,18 +23,22 @@ 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 = [
'api', 'linearity', 'maxduration', 'mimes', 'minduration', 'placement',
'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,
Expand Down Expand Up @@ -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',
Expand All @@ -146,6 +152,7 @@ export const spec = {
},

bidId,
params,
auctionId,
});
});
Expand All @@ -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});
Expand All @@ -168,6 +176,7 @@ export const spec = {

const bidResponse = {
requestId,
params,
cpm: bid.price,
width: bid.w,
height: bid.h,
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -338,6 +382,10 @@ function bidWonHandler(bid) {
};
}

function auctionInitHandler() {
sendingDataStatistic.initEvents();
}

function cleanWurl() {
const dateNow = Date.now();
Object.keys(wurlMap).forEach(key => {
Expand All @@ -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);
133 changes: 133 additions & 0 deletions test/spec/modules/nextMillenniumBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};
})
});

0 comments on commit 5dab862

Please sign in to comment.