From 260269d33c6d1125c7a9926d24e52f34021c8f27 Mon Sep 17 00:00:00 2001 From: Omer Dotan <54346241+omerBrowsi@users.noreply.github.com> Date: Mon, 11 Dec 2023 12:49:43 +0200 Subject: [PATCH 1/8] Browsi RTD : fix for targeting (#10814) * real time data module, browsi sub module for real time data, new hook bidsBackCallback, fix for config unsubscribe * change timeout&primary ad server only to auctionDelay update docs * support multiple providers * change promise to callbacks configure submodule on submodules.json * bug fixes * use Prebid ajax * tests fix * browsi real time data provider improvements * real time data module, browsi sub module for real time data, new hook bidsBackCallback, fix for config unsubscribe * change timeout&primary ad server only to auctionDelay update docs * support multiple providers * change promise to callbacks configure submodule on submodules.json * bug fixes * use Prebid ajax * tests fix * browsi real time data provider improvements * browsi-rtd-targeting-fix --- modules/browsiRtdProvider.js | 4 ++-- test/spec/modules/browsiRtdProvider_spec.js | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/modules/browsiRtdProvider.js b/modules/browsiRtdProvider.js index 4a61f40600d..1f37c7c5bc0 100644 --- a/modules/browsiRtdProvider.js +++ b/modules/browsiRtdProvider.js @@ -88,6 +88,7 @@ export function collectData() { let predictorData = { ...{ sk: _moduleParams.siteKey, + pk: _moduleParams.pubKey, sw: (win.screen && win.screen.width) || -1, sh: (win.screen && win.screen.height) || -1, url: `${doc.location.protocol}//${doc.location.host}${doc.location.pathname}`, @@ -134,7 +135,6 @@ function getRTD(auc) { const adSlot = getSlotByCode(uc); const identifier = adSlot ? getMacroId(_browsiData['pmd'], adSlot) : uc; const _pd = _bp[identifier]; - rp[uc] = getKVObject(-1); if (!_pd) { return rp } @@ -275,7 +275,7 @@ function getPredictionsFromServer(url) { if (req.status === 200) { try { const data = JSON.parse(response); - if (data && data.p && data.kn) { + if (data) { setData({p: data.p, kn: data.kn, pmd: data.pmd, bet: data.bet}); } else { setData({}); diff --git a/test/spec/modules/browsiRtdProvider_spec.js b/test/spec/modules/browsiRtdProvider_spec.js index 75120aa7505..5fcc78f4322 100644 --- a/test/spec/modules/browsiRtdProvider_spec.js +++ b/test/spec/modules/browsiRtdProvider_spec.js @@ -89,12 +89,6 @@ describe('browsi Real time data sub module', function () { expect(browsiRTD.browsiSubmodule.getTargetingData([], null, null, auction)).to.eql({}); }); - it('should return NA if no prediction for ad unit', function () { - makeSlot({code: 'adMock', divId: 'browsiAd_2'}); - browsiRTD.setData({}); - expect(browsiRTD.browsiSubmodule.getTargetingData(['adMock'], null, null, auction)).to.eql({adMock: {bv: 'NA'}}); - }); - it('should return prediction from server', function () { makeSlot({code: 'hasPrediction', divId: 'hasPrediction'}); const data = { From 2493f985e9049c8f0071e02a1f6d45c1fc0a856d Mon Sep 17 00:00:00 2001 From: Malkov Mikhail Date: Mon, 11 Dec 2023 17:30:25 +0300 Subject: [PATCH 2/8] nextMillennium Bid Adapter : add pbjs version and support for user.eids (#10812) * added support for gpp consent string * changed test for nextMillenniumBidAdapter * added some tests * added site.pagecat, site.content.cat and site.content.language to request * lint fix * formated code * formated code * formated code * pachage-lock with prebid * pachage-lock with prebid * formatted code * added device.sua, user.eids * formatted * fixed tests * fixed bug functio getSua --- modules/nextMillenniumBidAdapter.js | 40 +++++++++- .../modules/nextMillenniumBidAdapter_spec.js | 73 +++++++++++++++++++ 2 files changed, 110 insertions(+), 3 deletions(-) diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index 26d417b9baf..5dea4f9b651 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -14,6 +14,7 @@ import { triggerPixel, } from '../src/utils.js'; +import {getGlobal} from '../src/prebidGlobal.js'; import CONSTANTS from '../src/constants.json'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {config} from '../src/config.js'; @@ -22,7 +23,7 @@ import * as events from '../src/events.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {getRefererInfo} from '../src/refererDetection.js'; -const NM_VERSION = '3.0.0'; +const NM_VERSION = '3.1.0'; const GVLID = 1060; const BIDDER_CODE = 'nextMillennium'; const ENDPOINT = 'https://pbs.nextmillmedia.com/openrtb2/auction'; @@ -47,6 +48,7 @@ const ALLOWED_ORTB2_PARAMETERS = [ 'site.pagecat', 'site.content.cat', 'site.content.language', + 'device.sua', ]; const sendingDataStatistic = initSendingDataStatistic(); @@ -93,6 +95,7 @@ export const spec = { nextMillennium: { nm_version: NM_VERSION, + pbjs_version: getGlobal()?.version || undefined, refresh_count: window.nmmRefreshCounts[bid.adUnitCode]++, elOffsets: getBoundingClient(bid), scrollTop: window.pageYOffset || document.documentElement.scrollTop, @@ -107,6 +110,7 @@ export const spec = { postBody.imp.push(getImp(bid, id)); setConsentStrings(postBody, bidderRequest); setOrtb2Parameters(postBody, bidderRequest?.ortb2); + setEids(postBody, bid); const urlParameters = parseUrl(getWindowTop().location.href).search; const isTest = urlParameters['pbs'] && urlParameters['pbs'] === 'test'; @@ -312,6 +316,12 @@ export function setOrtb2Parameters(postBody, ortb2 = {}) { } } +export function setEids(postBody, bid) { + if (!isArray(bid.userIdAsEids) || !bid.userIdAsEids.length) return; + + deepSetValue(postBody, 'user.eids', bid.userIdAsEids); +} + export function replaceUsersyncMacros(url, gdprConsent = {}, uspConsent = '', gppConsent = {}, type = '') { const { consentString = '', gdprApplies = false } = gdprConsent; const gdpr = Number(gdprApplies); @@ -391,7 +401,7 @@ function getAd(bid) { } else if (bid.nurl) { adUrl = bid.nurl; }; - } + }; return {ad, adUrl, vastXml, vastUrl}; } @@ -399,10 +409,21 @@ function getAd(bid) { function getSiteObj() { const refInfo = (getRefererInfo && getRefererInfo()) || {}; + let language = navigator.language; + let content; + if (language) { + // get ISO-639-1-alpha-2 (2 character language) + language = language.split('-')[0]; + content = { + language, + }; + }; + return { page: refInfo.page, ref: refInfo.ref, - domain: refInfo.domain + domain: refInfo.domain, + content, }; } @@ -410,6 +431,19 @@ function getDeviceObj() { return { w: window.innerWidth || window.document.documentElement.clientWidth || window.document.body.clientWidth || 0, h: window.innerHeight || window.document.documentElement.clientHeight || window.document.body.clientHeight || 0, + ua: window.navigator.userAgent || undefined, + sua: getSua(), + }; +} + +function getSua() { + let {brands, mobile, platform} = (window?.navigator?.userAgentData || {}); + if (!(brands && platform)) return undefined; + + return { + brands, + mobile: Number(!!mobile), + platform: (platform && {brand: platform}) || undefined, }; } diff --git a/test/spec/modules/nextMillenniumBidAdapter_spec.js b/test/spec/modules/nextMillenniumBidAdapter_spec.js index 8b512218d56..f57db82aedc 100644 --- a/test/spec/modules/nextMillenniumBidAdapter_spec.js +++ b/test/spec/modules/nextMillenniumBidAdapter_spec.js @@ -4,6 +4,7 @@ import { replaceUsersyncMacros, setConsentStrings, setOrtb2Parameters, + setEids, spec, } from 'modules/nextMillenniumBidAdapter.js'; @@ -403,6 +404,78 @@ describe('nextMillenniumBidAdapterTests', () => { setOrtb2Parameters(postBody, ortb2); expect(postBody).to.deep.equal(expected); }); + }; + }); + + describe('function setEids', () => { + const dataTests = [ + { + title: 'setEids - userIdAsEids is empty', + data: { + postBody: {}, + bid: { + userIdAsEids: undefined, + }, + }, + + expected: {}, + }, + + { + title: 'setEids - userIdAsEids - array is empty', + data: { + postBody: {}, + bid: { + userIdAsEids: [], + }, + }, + + expected: {}, + }, + + { + title: 'setEids - userIdAsEids is', + data: { + postBody: {}, + bid: { + userIdAsEids: [ + { + source: '33across.com', + uids: [{id: 'some-random-id-value', atype: 1}], + }, + + { + source: 'utiq.com', + uids: [{id: 'some-random-id-value', atype: 1}], + }, + ], + }, + }, + + expected: { + user: { + eids: [ + { + source: '33across.com', + uids: [{id: 'some-random-id-value', atype: 1}], + }, + + { + source: 'utiq.com', + uids: [{id: 'some-random-id-value', atype: 1}], + }, + ], + }, + }, + }, + ]; + + for (let { title, data, expected } of dataTests) { + it(title, () => { + const { postBody, bid } = data; + setEids(postBody, bid); + expect(postBody).to.deep.equal(expected); + }); } }); From eecdc2e92d0f186ce897dda5f4aa0ea9fec66529 Mon Sep 17 00:00:00 2001 From: Patrick McCann Date: Mon, 11 Dec 2023 16:07:26 -0500 Subject: [PATCH 3/8] Update deepintentBidAdapter.js (#10818) --- modules/deepintentBidAdapter.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/deepintentBidAdapter.js b/modules/deepintentBidAdapter.js index e062686b320..7c24cd6a8f6 100644 --- a/modules/deepintentBidAdapter.js +++ b/modules/deepintentBidAdapter.js @@ -2,6 +2,7 @@ import { generateUUID, deepSetValue, deepAccess, isArray, isInteger, logError, l import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; const BIDDER_CODE = 'deepintent'; +const GVL_ID = 541; const BIDDER_ENDPOINT = 'https://prebid.deepintent.com/prebid'; const USER_SYNC_URL = 'https://cdn.deepintent.com/syncpixel.html'; const DI_M_V = '1.0.0'; @@ -32,6 +33,7 @@ export const ORTB_VIDEO_PARAMS = { }; export const spec = { code: BIDDER_CODE, + gvlid: GVL_ID, supportedMediaTypes: [BANNER, VIDEO], aliases: [], From 222b4428c36a71e898836ff3477ed2a3b88cea01 Mon Sep 17 00:00:00 2001 From: Chris Southern <79725079+southern-growthcode@users.noreply.github.com> Date: Mon, 11 Dec 2023 16:14:46 -0500 Subject: [PATCH 4/8] GC-158 When accessing the TCF it is pulling from the wrong location, use userConsent.gdpr.consentString (#10808) --- modules/growthCodeRtdProvider.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/growthCodeRtdProvider.js b/modules/growthCodeRtdProvider.js index e7dce81f7d0..b12b25a0951 100644 --- a/modules/growthCodeRtdProvider.js +++ b/modules/growthCodeRtdProvider.js @@ -81,8 +81,8 @@ function callServer(configParams, items, expiresAt, userConsent) { url = tryAppendQueryString(url, 'pid', configParams.pid); url = tryAppendQueryString(url, 'u', window.location.href); url = tryAppendQueryString(url, 'gcid', gcid); - if ((userConsent !== null) && (userConsent.gdpr !== null) && (userConsent.gdpr.consentData.getTCData.tcString)) { - url = tryAppendQueryString(url, 'tcf', userConsent.gdpr.consentData.getTCData.tcString) + if ((userConsent !== null) && (userConsent.gdpr !== null) && (userConsent.gdpr.consentString)) { + url = tryAppendQueryString(url, 'tcf', userConsent.gdpr.consentString) } ajax.ajaxBuilder()(url, { From 3ec81e61e6cb51c4a9420427c1ca9c504a7848a3 Mon Sep 17 00:00:00 2001 From: Olivier Date: Mon, 11 Dec 2023 22:44:48 +0100 Subject: [PATCH 5/8] Adagio Analytics Adapter: listen to AUCTION_END (#10798) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adagio Analytics Adapter: add tracker on auction_end * Adagio Analytics Adapter: refacto metadata transfer * Adagio Analytics Adapter: update pba props --------- Co-authored-by: François Rotta --- modules/adagioAnalyticsAdapter.js | 58 +++++++++- .../modules/adagioAnalyticsAdapter_spec.js | 109 +++++++++++++----- 2 files changed, 135 insertions(+), 32 deletions(-) diff --git a/modules/adagioAnalyticsAdapter.js b/modules/adagioAnalyticsAdapter.js index 9c4c0e8fea7..ee2368fde08 100644 --- a/modules/adagioAnalyticsAdapter.js +++ b/modules/adagioAnalyticsAdapter.js @@ -22,6 +22,12 @@ const cache = { getAuction: function(auctionId, adUnitCode) { return this.auctions[auctionId][adUnitCode]; }, + getBiddersFromAuction: function(auctionId, adUnitCode) { + return this.getAuction(auctionId, adUnitCode).bdrs.split(','); + }, + getAllAdUnitCodes: function(auctionId) { + return Object.keys(this.auctions[auctionId]); + }, updateAuction: function(auctionId, adUnitCode, values) { this.auctions[auctionId][adUnitCode] = { ...this.auctions[auctionId][adUnitCode], @@ -74,7 +80,8 @@ const adagioEnqueue = function adagioEnqueue(action, data) { const guard = { adagio: (value) => isAdagio(value), - bidTracked: (auctionId, adUnitCode) => deepAccess(cache, `auctions.${auctionId}.${adUnitCode}`, false) + bidTracked: (auctionId, adUnitCode) => deepAccess(cache, `auctions.${auctionId}.${adUnitCode}`, false), + auctionTracked: (auctionId) => deepAccess(cache, `auctions.${auctionId}`, false) }; function removeDuplicates(arr, getKey) { @@ -105,6 +112,19 @@ function getMediaTypeAlias(mediaType) { return mediaTypesMap[mediaType] || mediaType; }; +function addKeyPrefix(obj, prefix) { + return Object.keys(obj).reduce((acc, key) => { + // We don't want to prefix already prefixed keys. + if (key.startsWith(prefix)) { + acc[key] = obj[key]; + return acc; + } + + acc[`${prefix}${key}`] = obj[key]; + return acc; + }, {}); +} + /** * sendRequest to Adagio. It filter null values and encode each query param. * @param {Object} qp @@ -146,6 +166,7 @@ function getTargetedAuctionId(bid) { * HANDLERS * - handlerAuctionInit * - handlerBidResponse + * - handlerAuctionEnd * - handlerBidWon * - handlerAdRender * @@ -227,11 +248,10 @@ function handlerAuctionInit(event) { auct_id: adagioAuctionId, adu_code: adUnitCode, url_dmn: w.location.hostname, - dvc: params.environment, pgtyp: params.pagetype, plcmt: params.placement, - tname: params.testName || null, - tvname: params.testVariationName || null, + t_n: params.testName || null, + t_v: params.testVersion || null, mts: mediaTypesKeys.join(','), ban_szs: bannerSizes.join(','), bdrs: bidders.map(bidder => getAdapterNameForAlias(bidder.bidder)).sort().join(','), @@ -257,11 +277,33 @@ function handlerBidResponse(event) { return; } + if (!event.pba) { + return; + } + cache.updateAuction(event.auctionId, event.adUnitCode, { - adg_sid: event.seatId || null + ...addKeyPrefix(event.pba, 'e_') }); }; +function handlerAuctionEnd(event) { + const { auctionId } = event; + + if (!guard.auctionTracked(auctionId)) { + return; + } + + const adUnitCodes = cache.getAllAdUnitCodes(auctionId); + adUnitCodes.forEach(adUnitCode => { + const mapper = (bidder) => event.bidsReceived.find(bid => bid.adUnitCode === adUnitCode && bid.bidder === bidder) ? '1' : '0'; + + cache.updateAuction(auctionId, adUnitCode, { + bdrs_bid: cache.getBiddersFromAuction(auctionId, adUnitCode).map(mapper).join(',') + }); + sendNewBeacon(auctionId, adUnitCode); + }); +} + function handlerBidWon(event) { let auctionId = getTargetedAuctionId(event); @@ -340,10 +382,14 @@ let adagioAdapter = Object.assign(adapter({ emptyUrl, analyticsType }), { case CONSTANTS.EVENTS.BID_RESPONSE: handlerBidResponse(args); break; + case CONSTANTS.EVENTS.AUCTION_END: + handlerAuctionEnd(args); + break; case CONSTANTS.EVENTS.BID_WON: handlerBidWon(args); break; - case CONSTANTS.EVENTS.AD_RENDER_SUCCEEDED: + // AD_RENDER_SUCCEEDED seems redundant with BID_WON. + // case CONSTANTS.EVENTS.AD_RENDER_SUCCEEDED: case CONSTANTS.EVENTS.AD_RENDER_FAILED: handlerAdRender(args, eventType === CONSTANTS.EVENTS.AD_RENDER_SUCCEEDED); break; diff --git a/test/spec/modules/adagioAnalyticsAdapter_spec.js b/test/spec/modules/adagioAnalyticsAdapter_spec.js index 8359a34baa0..5ffd7b0b685 100644 --- a/test/spec/modules/adagioAnalyticsAdapter_spec.js +++ b/test/spec/modules/adagioAnalyticsAdapter_spec.js @@ -211,7 +211,10 @@ const BID_ADAGIO = Object.assign({}, BID_ADAGIO, { meta: { advertiserDomains: ['example.com'] }, - seatId: '42', + pba: { + sid: '42', + e_pba_test: true + } }); const BID_ANOTHER = Object.assign({}, BID_ANOTHER, { @@ -256,7 +259,9 @@ const PARAMS_ADG = { pageviewId: 'a68e6d70-213b-496c-be0a-c468ff387106', environment: 'desktop', pagetype: 'article', - placement: 'pave_top' + placement: 'pave_top', + testName: 'test', + testVersion: 'version', }; const AUCTION_INIT_ANOTHER = { @@ -285,6 +290,11 @@ const AUCTION_INIT_ANOTHER = { 'params': { 'publisherId': '1001' }, + }, { + 'bidder': 'nobid', + 'params': { + 'publisherId': '1002' + }, }, { 'bidder': 'adagio', 'params': { @@ -354,6 +364,24 @@ const AUCTION_INIT_ANOTHER = { 'auctionId': AUCTION_ID, 'src': 'client', 'bidRequestsCount': 1 + }, { + 'bidder': 'nobid', + 'params': { + 'publisherId': '1001' + }, + 'mediaTypes': { + 'banner': { + 'sizes': [[640, 480]] + } + }, + 'adUnitCode': '/19968336/footer-bid-tag-1', + 'transactionId': 'ca4af27a-6d02-4f90-949d-d5541fa12014', + 'sizes': [[640, 480]], + 'bidId': '2ecff0db240757', + 'bidderRequestId': '1be65d7958826a', + 'auctionId': AUCTION_ID, + 'src': 'client', + 'bidRequestsCount': 1 } ], 'timeout': 3000, @@ -533,6 +561,14 @@ const AUCTION_INIT_CACHE = { 'timeout': 3000 }; +const AUCTION_END_ANOTHER = Object.assign({}, AUCTION_INIT_ANOTHER, { + bidsReceived: [BID_ANOTHER, BID_ADAGIO] +}); + +const AUCTION_END_ANOTHER_NOBID = Object.assign({}, AUCTION_INIT_ANOTHER, { + bidsReceived: [] +}); + const MOCK = { SET_TARGETING: { [BID_ADAGIO.adUnitCode]: BID_ADAGIO.adserverTargeting, @@ -546,6 +582,10 @@ const MOCK = { adagio: BID_ADAGIO, another: BID_ANOTHER }, + AUCTION_END: { + another: AUCTION_END_ANOTHER, + another_nobid: AUCTION_END_ANOTHER_NOBID + }, BID_WON: { adagio: Object.assign({}, BID_ADAGIO, { 'status': 'rendered' @@ -569,6 +609,12 @@ const MOCK = { bid: BID_CACHED } }, + AD_RENDER_FAILED: { + bidcached: { + adId: 'fake_ad_id_2', + bid: BID_CACHED + } + } }; describe('adagio analytics adapter', () => { @@ -616,10 +662,11 @@ describe('adagio analytics adapter', () => { events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT.another); events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE.adagio); events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE.another); + events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END.another); events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON.another); events.emit(constants.EVENTS.AD_RENDER_SUCCEEDED, MOCK.AD_RENDER_SUCCEEDED.another); - expect(server.requests.length).to.equal(3); + expect(server.requests.length).to.equal(3, 'requests count'); { const { protocol, hostname, pathname, search } = utils.parseUrl(server.requests[0].url); expect(protocol).to.equal('https'); @@ -633,12 +680,11 @@ describe('adagio analytics adapter', () => { expect(search.site).to.equal('test-com'); expect(search.pv_id).to.equal('a68e6d70-213b-496c-be0a-c468ff387106'); expect(search.url_dmn).to.equal(window.location.hostname); - expect(search.dvc).to.equal('desktop'); expect(search.pgtyp).to.equal('article'); expect(search.plcmt).to.equal('pave_top'); expect(search.mts).to.equal('ban'); expect(search.ban_szs).to.equal('640x100,640x480'); - expect(search.bdrs).to.equal('adagio,another'); + expect(search.bdrs).to.equal('adagio,another,nobid'); expect(search.adg_mts).to.equal('ban'); } @@ -648,9 +694,19 @@ describe('adagio analytics adapter', () => { expect(hostname).to.equal('c.4dex.io'); expect(pathname).to.equal('/pba.gif'); expect(search.v).to.equal('2'); + expect(search.e_sid).to.equal('42'); + expect(search.e_pba_test).to.equal('true'); + expect(search.bdrs_bid).to.equal('1,1,0'); + } + + { + const { protocol, hostname, pathname, search } = utils.parseUrl(server.requests[2].url); + expect(protocol).to.equal('https'); + expect(hostname).to.equal('c.4dex.io'); + expect(pathname).to.equal('/pba.gif'); + expect(search.v).to.equal('3'); expect(search.auct_id).to.equal(AUCTION_ID_ADAGIO); expect(search.adu_code).to.equal('/19968336/header-bid-tag-1'); - expect(search.adg_sid).to.equal('42'); expect(search.win_bdr).to.equal('another'); expect(search.win_mt).to.equal('ban'); expect(search.win_ban_sz).to.equal('728x90'); @@ -661,17 +717,6 @@ describe('adagio analytics adapter', () => { expect(search.og_cur).to.equal('GBP'); expect(search.og_cur_rate).to.equal('1.6'); } - - { - const { protocol, hostname, pathname, search } = utils.parseUrl(server.requests[2].url); - expect(protocol).to.equal('https'); - expect(hostname).to.equal('c.4dex.io'); - expect(pathname).to.equal('/pba.gif'); - expect(search.v).to.equal('3'); - expect(search.auct_id).to.equal(AUCTION_ID_ADAGIO); - expect(search.adu_code).to.equal('/19968336/header-bid-tag-1'); - expect(search.rndr).to.equal('1'); - } }); it('builds and sends auction data with a cached bid win', () => { @@ -691,10 +736,11 @@ describe('adagio analytics adapter', () => { events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT.another); events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE.adagio); events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE.another); + events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END.another_nobid); events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON.bidcached); - events.emit(constants.EVENTS.AD_RENDER_SUCCEEDED, MOCK.AD_RENDER_SUCCEEDED.bidcached); + events.emit(constants.EVENTS.AD_RENDER_FAILED, MOCK.AD_RENDER_FAILED.bidcached); - expect(server.requests.length).to.equal(4); + expect(server.requests.length).to.equal(5, 'requests count'); { const { protocol, hostname, pathname, search } = utils.parseUrl(server.requests[0].url); expect(protocol).to.equal('https'); @@ -708,13 +754,14 @@ describe('adagio analytics adapter', () => { expect(search.site).to.equal('test-com'); expect(search.pv_id).to.equal('a68e6d70-213b-496c-be0a-c468ff387106'); expect(search.url_dmn).to.equal(window.location.hostname); - expect(search.dvc).to.equal('desktop'); expect(search.pgtyp).to.equal('article'); expect(search.plcmt).to.equal('pave_top'); expect(search.mts).to.equal('ban'); expect(search.ban_szs).to.equal('640x100,640x480'); expect(search.bdrs).to.equal('adagio,another'); expect(search.adg_mts).to.equal('ban'); + expect(search.t_n).to.equal('test'); + expect(search.t_v).to.equal('version'); } { @@ -730,12 +777,11 @@ describe('adagio analytics adapter', () => { expect(search.site).to.equal('test-com'); expect(search.pv_id).to.equal('a68e6d70-213b-496c-be0a-c468ff387106'); expect(search.url_dmn).to.equal(window.location.hostname); - expect(search.dvc).to.equal('desktop'); expect(search.pgtyp).to.equal('article'); expect(search.plcmt).to.equal('pave_top'); expect(search.mts).to.equal('ban'); expect(search.ban_szs).to.equal('640x100,640x480'); - expect(search.bdrs).to.equal('adagio,another'); + expect(search.bdrs).to.equal('adagio,another,nobid'); expect(search.adg_mts).to.equal('ban'); } @@ -745,10 +791,20 @@ describe('adagio analytics adapter', () => { expect(hostname).to.equal('c.4dex.io'); expect(pathname).to.equal('/pba.gif'); expect(search.v).to.equal('2'); + expect(search.e_sid).to.equal('42'); + expect(search.e_pba_test).to.equal('true'); + expect(search.bdrs_bid).to.equal('0,0,0'); + } + + { + const { protocol, hostname, pathname, search } = utils.parseUrl(server.requests[3].url); + expect(protocol).to.equal('https'); + expect(hostname).to.equal('c.4dex.io'); + expect(pathname).to.equal('/pba.gif'); + expect(search.v).to.equal('3'); expect(search.auct_id).to.equal(AUCTION_ID_ADAGIO); expect(search.auct_id_c).to.equal(AUCTION_ID_CACHE_ADAGIO); expect(search.adu_code).to.equal('/19968336/header-bid-tag-1'); - expect(search.adg_sid).to.equal('42'); expect(search.win_bdr).to.equal('adagio'); expect(search.win_mt).to.equal('ban'); expect(search.win_ban_sz).to.equal('728x90'); @@ -758,18 +814,19 @@ describe('adagio analytics adapter', () => { expect(search.og_cpm).to.equal('1.42'); expect(search.og_cur).to.equal('USD'); expect(search.og_cur_rate).to.equal('1'); + expect(search.rndr).to.not.exist; } { - const { protocol, hostname, pathname, search } = utils.parseUrl(server.requests[3].url); + const { protocol, hostname, pathname, search } = utils.parseUrl(server.requests[4].url); expect(protocol).to.equal('https'); expect(hostname).to.equal('c.4dex.io'); expect(pathname).to.equal('/pba.gif'); - expect(search.v).to.equal('3'); + expect(search.v).to.equal('4'); expect(search.auct_id).to.equal(AUCTION_ID_ADAGIO); expect(search.auct_id_c).to.equal(AUCTION_ID_CACHE_ADAGIO); expect(search.adu_code).to.equal('/19968336/header-bid-tag-1'); - expect(search.rndr).to.equal('1'); + expect(search.rndr).to.equal('0'); } }); }); From 6275c00cdc47fefd521b4a1f8cbae44944560367 Mon Sep 17 00:00:00 2001 From: kapil-tuptewar <91458408+kapil-tuptewar@users.noreply.github.com> Date: Tue, 12 Dec 2023 03:31:13 +0530 Subject: [PATCH 6/8] PubMaticAnalyticAdapter : Added new fields related to floors (fetch status, source of floor, provider and unique id) in analytics call (#10768) * Added floors field to logger call * Added sid in logger records --- modules/pubmaticAnalyticsAdapter.js | 30 ++++++++--- src/constants.json | 4 +- .../modules/pubmaticAnalyticsAdapter_spec.js | 51 +++++++++++++++++++ 3 files changed, 77 insertions(+), 8 deletions(-) diff --git a/modules/pubmaticAnalyticsAdapter.js b/modules/pubmaticAnalyticsAdapter.js index a8f2b8d20ee..fbc45f1a8d7 100755 --- a/modules/pubmaticAnalyticsAdapter.js +++ b/modules/pubmaticAnalyticsAdapter.js @@ -1,4 +1,4 @@ -import {_each, isArray, isStr, logError, logWarn, pick} from '../src/utils.js'; +import {_each, isArray, isStr, logError, logWarn, pick, generateUUID} from '../src/utils.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; import CONSTANTS from '../src/constants.json'; @@ -286,7 +286,7 @@ function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) { 'ocpm': bid.bidResponse ? (bid.bidResponse.originalCpm || 0) : 0, 'ocry': bid.bidResponse ? (bid.bidResponse.originalCurrency || CURRENCY_USD) : CURRENCY_USD, 'piid': bid.bidResponse ? (bid.bidResponse.partnerImpId || EMPTY_STRING) : EMPTY_STRING, - 'frv': (bid.bidResponse ? (bid.bidResponse.floorData ? bid.bidResponse.floorData.floorRuleValue : undefined) : undefined), + 'frv': bid.bidResponse ? bid.bidResponse.floorData?.floorRuleValue : undefined, 'md': bid.bidResponse ? getMetadata(bid.bidResponse.meta) : undefined }); }); @@ -337,11 +337,10 @@ function executeBidsLoggerCall(e, highestCpmBids) { let auctionId = e.auctionId; let referrer = config.getConfig('pageUrl') || cache.auctions[auctionId].referer || ''; let auctionCache = cache.auctions[auctionId]; - let floorData = auctionCache.floorData; + let floorData = auctionCache?.floorData; + let floorFetchStatus = getFloorFetchStatus(auctionCache?.floorData); let outputObj = { s: [] }; let pixelURL = END_POINT_BID_LOGGER; - // will return true if floor data is present. - let fetchStatus = getFloorFetchStatus(auctionCache.floorData); if (!auctionCache) { return; @@ -364,7 +363,7 @@ function executeBidsLoggerCall(e, highestCpmBids) { outputObj['tgid'] = getTgId(); outputObj['pbv'] = getGlobal()?.version || '-1'; - if (floorData && fetchStatus) { + if (floorData && floorFetchStatus) { outputObj['fmv'] = floorData.floorRequestData ? floorData.floorRequestData.modelVersion || undefined : undefined; outputObj['ft'] = floorData.floorResponseData ? (floorData.floorResponseData.enforcements.enforceJS == false ? 0 : 1) : undefined; } @@ -379,8 +378,25 @@ function executeBidsLoggerCall(e, highestCpmBids) { 'mt': getAdUnitAdFormats(origAdUnit), 'sz': getSizesForAdUnit(adUnit, adUnitId), 'ps': gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestCpmBids.filter(bid => bid.adUnitCode === adUnitId)), - 'fskp': (floorData && fetchStatus) ? (floorData.floorRequestData ? (floorData.floorRequestData.skipped == false ? 0 : 1) : undefined) : undefined, + 'fskp': floorData && floorFetchStatus ? (floorData.floorRequestData ? (floorData.floorRequestData.skipped == false ? 0 : 1) : undefined) : undefined, + 'sid': generateUUID() }; + if (floorData?.floorRequestData) { + const { location, fetchStatus, floorProvider } = floorData?.floorRequestData; + slotObject.ffs = { + [CONSTANTS.FLOOR_VALUES.SUCCESS]: 1, + [CONSTANTS.FLOOR_VALUES.ERROR]: 2, + [CONSTANTS.FLOOR_VALUES.TIMEOUT]: 4, + undefined: 0 + }[fetchStatus]; + slotObject.fsrc = { + [CONSTANTS.FLOOR_VALUES.FETCH]: 2, + [CONSTANTS.FLOOR_VALUES.NO_DATA]: 2, + [CONSTANTS.FLOOR_VALUES.AD_UNIT]: 1, + [CONSTANTS.FLOOR_VALUES.SET_CONFIG]: 1 + }[location]; + slotObject.fp = floorProvider; + } slotsArray.push(slotObject); return slotsArray; }, []); diff --git a/src/constants.json b/src/constants.json index ad0f5b3a71b..c8266ff85f8 100644 --- a/src/constants.json +++ b/src/constants.json @@ -176,6 +176,8 @@ "AD_UNIT": "adUnit", "SET_CONFIG": "setConfig", "FETCH": "fetch", - "SUCCESS": "success" + "SUCCESS": "success", + "ERROR": "error", + "TIMEOUT": "timeout" } } diff --git a/test/spec/modules/pubmaticAnalyticsAdapter_spec.js b/test/spec/modules/pubmaticAnalyticsAdapter_spec.js index 7fce08fc24f..6af497bd2e9 100755 --- a/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +++ b/test/spec/modules/pubmaticAnalyticsAdapter_spec.js @@ -374,6 +374,10 @@ describe('pubmatic analytics adapter', function () { // slot 1 expect(data.s[0].sn).to.equal('/19968336/header-bid-tag-0'); expect(data.s[0].fskp).to.equal(0); + expect(data.s[0].sid).not.to.be.undefined; + expect(data.s[0].ffs).to.equal(1); + expect(data.s[0].fsrc).to.equal(2); + expect(data.s[0].fp).to.equal('pubmatic'); expect(data.s[0].sz).to.deep.equal(['640x480']); expect(data.s[0].ps).to.be.an('array'); expect(data.s[0].au).to.equal('/19968336/header-bid-tag-0'); @@ -403,6 +407,10 @@ describe('pubmatic analytics adapter', function () { // slot 2 expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); expect(data.s[1].fskp).to.equal(0); + expect(data.s[1].sid).not.to.be.undefined; + expect(data.s[1].ffs).to.equal(1); + expect(data.s[1].fsrc).to.equal(2); + expect(data.s[1].fp).to.equal('pubmatic'); expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); expect(data.s[1].ps).to.be.an('array'); expect(data.s[1].ps.length).to.equal(1); @@ -583,6 +591,10 @@ describe('pubmatic analytics adapter', function () { // slot 1 expect(data.s[0].sn).to.equal('/19968336/header-bid-tag-0'); expect(data.s[0].fskp).to.equal(0); + expect(data.s[0].sid).not.to.be.undefined; + expect(data.s[0].ffs).to.equal(1); + expect(data.s[0].fsrc).to.equal(2); + expect(data.s[0].fp).to.equal('pubmatic'); expect(data.s[0].sz).to.deep.equal(['640x480']); expect(data.s[0].ps).to.be.an('array'); expect(data.s[0].au).to.equal('/19968336/header-bid-tag-0'); @@ -702,6 +714,13 @@ describe('pubmatic analytics adapter', function () { expect(data.tgid).to.equal(0);// test group id should be an INT between 0-15 else set to 0 expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); expect(data.s[1].fskp).to.equal(0); + + expect(data.s[1].sid).not.to.be.undefined; + + expect(data.s[1].ffs).to.equal(1); + expect(data.s[1].fsrc).to.equal(2); + expect(data.s[1].fp).to.equal('pubmatic'); + expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); expect(data.s[1].ps).to.be.an('array'); expect(data.s[1].ps.length).to.equal(1); @@ -784,6 +803,10 @@ describe('pubmatic analytics adapter', function () { let data = getLoggerJsonFromRequest(request.requestBody); expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); expect(data.s[1].fskp).to.equal(0); + expect(data.s[1].sid).not.to.be.undefined; + expect(data.s[1].ffs).to.equal(1); + expect(data.s[1].fsrc).to.equal(2); + expect(data.s[1].fp).to.equal('pubmatic'); expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); expect(data.s[1].ps).to.be.an('array'); expect(data.s[1].ps.length).to.equal(1); @@ -846,6 +869,7 @@ describe('pubmatic analytics adapter', function () { expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); expect(data.s[1].ps).to.be.an('array'); + expect(data.s[1].sid).not.to.be.undefined; expect(data.s[1].ps.length).to.equal(1); expect(data.s[1].ps[0].pn).to.equal('pubmatic'); expect(data.s[1].ps[0].bc).to.equal('pubmatic'); @@ -893,6 +917,10 @@ describe('pubmatic analytics adapter', function () { let data = getLoggerJsonFromRequest(request.requestBody); expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); expect(data.s[1].fskp).to.equal(0); + expect(data.s[1].sid).not.to.be.undefined; + expect(data.s[1].ffs).to.equal(1); + expect(data.s[1].fsrc).to.equal(2); + expect(data.s[1].fp).to.equal('pubmatic'); expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); expect(data.s[1].ps).to.be.an('array'); expect(data.s[1].ps.length).to.equal(1); @@ -952,6 +980,7 @@ describe('pubmatic analytics adapter', function () { let data = getLoggerJsonFromRequest(request.requestBody); expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); + expect(data.s[1].sid).not.to.be.undefined; expect(data.s[1].ps).to.be.an('array'); expect(data.s[1].ps.length).to.equal(1); expect(data.s[1].ps[0].pn).to.equal('pubmatic'); @@ -1006,6 +1035,10 @@ describe('pubmatic analytics adapter', function () { let data = getLoggerJsonFromRequest(request.requestBody); expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); expect(data.s[1].fskp).to.equal(0); + expect(data.s[1].sid).not.to.be.undefined; + expect(data.s[1].ffs).to.equal(1); + expect(data.s[1].fsrc).to.equal(2); + expect(data.s[1].fp).to.equal('pubmatic'); expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); expect(data.s[1].ps).to.be.an('array'); expect(data.s[1].ps.length).to.equal(1); @@ -1063,6 +1096,7 @@ describe('pubmatic analytics adapter', function () { let data = getLoggerJsonFromRequest(request.requestBody); expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); + expect(data.s[1].sid).not.to.be.undefined; expect(data.s[1].ps).to.be.an('array'); expect(data.s[1].ps.length).to.equal(1); expect(data.s[1].ps[0].pn).to.equal('pubmatic'); @@ -1121,7 +1155,11 @@ describe('pubmatic analytics adapter', function () { // Testing only for rejected bid as other scenarios will be covered under other TCs expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); expect(data.s[1].fskp).to.equal(0); + expect(data.s[1].ffs).to.equal(1); + expect(data.s[1].fsrc).to.equal(2); + expect(data.s[1].fp).to.equal('pubmatic'); expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); + expect(data.s[1].sid).not.to.be.undefined; expect(data.s[1].ps).to.be.an('array'); expect(data.s[1].ps.length).to.equal(1); expect(data.s[1].ps[0].pn).to.equal('pubmatic'); @@ -1196,7 +1234,11 @@ describe('pubmatic analytics adapter', function () { // slot 1 expect(data.s[0].sn).to.equal('/19968336/header-bid-tag-0'); expect(data.s[0].fskp).to.equal(0); + expect(data.s[0].ffs).to.equal(1); + expect(data.s[0].fsrc).to.equal(2); + expect(data.s[0].fp).to.equal('pubmatic'); expect(data.s[0].sz).to.deep.equal(['640x480']); + expect(data.s[0].sid).not.to.be.undefined; expect(data.s[0].ps).to.be.an('array'); expect(data.s[0].au).to.equal('/19968336/header-bid-tag-0'); expect(data.s[0].ps.length).to.equal(1); @@ -1226,7 +1268,11 @@ describe('pubmatic analytics adapter', function () { // slot 2 expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); expect(data.s[1].fskp).to.equal(0); + expect(data.s[1].ffs).to.equal(1); + expect(data.s[1].fsrc).to.equal(2); + expect(data.s[1].fp).to.equal('pubmatic'); expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); + expect(data.s[1].sid).not.to.be.undefined; expect(data.s[1].ps).to.be.an('array'); expect(data.s[1].ps.length).to.equal(1); expect(data.s[1].ps[0].pn).to.equal('pubmatic'); @@ -1318,7 +1364,11 @@ describe('pubmatic analytics adapter', function () { // slot 1 expect(data.s[0].sn).to.equal('/19968336/header-bid-tag-0'); expect(data.s[0].fskp).to.equal(0); + expect(data.s[0].ffs).to.equal(1); + expect(data.s[0].fsrc).to.equal(2); + expect(data.s[0].fp).to.equal('pubmatic'); expect(data.s[0].sz).to.deep.equal(['640x480']); + expect(data.s[0].sid).not.to.be.undefined; expect(data.s[0].ps).to.be.an('array'); expect(data.s[0].au).to.equal('/19968336/header-bid-tag-0'); expect(data.s[0].ps.length).to.equal(1); @@ -1348,6 +1398,7 @@ describe('pubmatic analytics adapter', function () { // slot 2 expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); + expect(data.s[1].sid).not.to.be.undefined; expect(data.s[1].ps).to.be.an('array'); expect(data.s[1].ps.length).to.equal(1); expect(data.s[1].ps[0].pn).to.equal('pubmatic'); From 62a20ba19fe7c90efa7666e6964cc45dbde435be Mon Sep 17 00:00:00 2001 From: 3link <34981284+3link@users.noreply.github.com> Date: Tue, 12 Dec 2023 17:21:06 +0100 Subject: [PATCH 7/8] Add missing brackets --- modules/userId/eids.md | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/userId/eids.md b/modules/userId/eids.md index 04073923ed1..20507952362 100644 --- a/modules/userId/eids.md +++ b/modules/userId/eids.md @@ -77,6 +77,7 @@ userIdAsEids = [ uids: [{ id: 'the-ids-object-stringified', atype: 1 + }] }, { From 290da75981c2765376e8a4ba7b2447167b458724 Mon Sep 17 00:00:00 2001 From: 3link <34981284+3link@users.noreply.github.com> Date: Tue, 12 Dec 2023 17:22:56 +0100 Subject: [PATCH 8/8] Add missing examples --- modules/userId/eids.md | 46 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/modules/userId/eids.md b/modules/userId/eids.md index 20507952362..fbf100d6301 100644 --- a/modules/userId/eids.md +++ b/modules/userId/eids.md @@ -117,7 +117,51 @@ userIdAsEids = [ } }] }, - + + { + source: 'liveintent.indexexchange.com', + uids: [{ + id: 'some-random-id-value', + atype: 3, + ext: { + provider: 'liveintent.com' + } + }] + }, + + { + source: 'liveintent.sovrn.com'', + uids: [{ + id: 'some-random-id-value', + atype: 3, + ext: { + provider: 'liveintent.com' + } + }] + }, + + { + source: 'openx.net'', + uids: [{ + id: 'some-random-id-value', + atype: 3, + ext: { + provider: 'liveintent.com' + } + }] + }, + + { + source: 'pubmatic.com'', + uids: [{ + id: 'some-random-id-value', + atype: 3, + ext: { + provider: 'liveintent.com' + } + }] + }, + { source: 'media.net', uids: [{