Skip to content

Commit de42f8d

Browse files
authored
Adagio Analytics: change bidder code for aliases and add bidder cpm (prebid#11301)
1 parent beeb901 commit de42f8d

File tree

2 files changed

+100
-73
lines changed

2 files changed

+100
-73
lines changed

modules/adagioAnalyticsAdapter.js

Lines changed: 41 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ const ADAGIO_GVLID = 617;
1717
const VERSION = '3.0.0';
1818
const PREBID_VERSION = '$prebid.version$';
1919
const ENDPOINT = 'https://c.4dex.io/pba.gif';
20+
const CURRENCY_USD = 'USD';
21+
const ADAGIO_CODE = 'adagio';
2022
const cache = {
2123
auctions: {},
2224
getAuction: function(auctionId, adUnitCode) {
@@ -92,17 +94,11 @@ function removeDuplicates(arr, getKey) {
9294
});
9395
};
9496

95-
function getAdapterNameForAlias(aliasName) {
96-
return adapterManager.aliasRegistry[aliasName] || aliasName;
97-
};
98-
99-
function isAdagio(value) {
100-
if (!value) {
97+
function isAdagio(alias) {
98+
if (!alias) {
10199
return false
102100
}
103-
104-
return value.toLowerCase().includes('adagio') ||
105-
getAdapterNameForAlias(value).toLowerCase().includes('adagio');
101+
return (alias + adapterManager.aliasRegistry[alias]).toLowerCase().includes(ADAGIO_CODE);
106102
};
107103

108104
function getMediaTypeAlias(mediaType) {
@@ -129,6 +125,26 @@ function addKeyPrefix(obj, prefix) {
129125
}, {});
130126
}
131127

128+
function getUsdCpm(cpm, currency) {
129+
let netCpm = cpm
130+
131+
if (typeof currency === 'string' && currency.toUpperCase() !== CURRENCY_USD) {
132+
if (typeof getGlobal().convertCurrency === 'function') {
133+
netCpm = parseFloat(Number(getGlobal().convertCurrency(cpm, currency, CURRENCY_USD))).toFixed(3);
134+
} else {
135+
netCpm = null
136+
}
137+
}
138+
return netCpm
139+
}
140+
141+
function getCurrencyData(bid) {
142+
return {
143+
netCpm: getUsdCpm(bid.cpm, bid.currency),
144+
orginalCpm: getUsdCpm(bid.originalCpm, bid.originalCurrency)
145+
}
146+
}
147+
132148
/**
133149
* sendRequest to Adagio. It filter null values and encode each query param.
134150
* @param {Object} qp
@@ -258,7 +274,7 @@ function handlerAuctionInit(event) {
258274
t_v: params.testVersion || null,
259275
mts: mediaTypesKeys.join(','),
260276
ban_szs: bannerSizes.join(','),
261-
bdrs: bidders.map(bidder => getAdapterNameForAlias(bidder.bidder)).sort().join(','),
277+
bdrs: bidders.map(bidder => bidder.bidder).sort().join(','),
262278
adg_mts: adagioMediaTypes.join(',')
263279
};
264280

@@ -299,56 +315,43 @@ function handlerAuctionEnd(event) {
299315

300316
const adUnitCodes = cache.getAllAdUnitCodes(auctionId);
301317
adUnitCodes.forEach(adUnitCode => {
302-
const mapper = (bidder) => event.bidsReceived.find(bid => bid.adUnitCode === adUnitCode && bid.bidder === bidder) ? '1' : '0';
318+
const bidResponseMapper = (bidder) => {
319+
const bid = event.bidsReceived.find(bid => bid.adUnitCode === adUnitCode && bid.bidder === bidder)
320+
return bid ? '1' : '0'
321+
}
322+
const bidCpmMapper = (bidder) => {
323+
const bid = event.bidsReceived.find(bid => bid.adUnitCode === adUnitCode && bid.bidder === bidder)
324+
return bid ? getCurrencyData(bid).netCpm : null
325+
}
303326

304327
cache.updateAuction(auctionId, adUnitCode, {
305-
bdrs_bid: cache.getBiddersFromAuction(auctionId, adUnitCode).map(mapper).join(',')
328+
bdrs_bid: cache.getBiddersFromAuction(auctionId, adUnitCode).map(bidResponseMapper).join(','),
329+
bdrs_cpm: cache.getBiddersFromAuction(auctionId, adUnitCode).map(bidCpmMapper).join(',')
306330
});
307331
sendNewBeacon(auctionId, adUnitCode);
308332
});
309333
}
310-
311334
function handlerBidWon(event) {
312335
let auctionId = getTargetedAuctionId(event);
313336

314337
if (!guard.bidTracked(auctionId, event.adUnitCode)) {
315338
return;
316339
}
317340

318-
let adsCurRateToUSD = (event.currency === 'USD') ? 1 : null;
319-
let ogCurRateToUSD = (event.originalCurrency === 'USD') ? 1 : null;
320-
try {
321-
if (typeof getGlobal().convertCurrency === 'function') {
322-
// Currency module is loaded, we can calculate the conversion rate.
323-
324-
// Get the conversion rate from the original currency to USD.
325-
ogCurRateToUSD = getGlobal().convertCurrency(1, event.originalCurrency, 'USD');
326-
// Get the conversion rate from the ad server currency to USD.
327-
adsCurRateToUSD = getGlobal().convertCurrency(1, event.currency, 'USD');
328-
}
329-
} catch (error) {
330-
logError('Error on Adagio Analytics Adapter - handlerBidWon', error);
331-
}
341+
const currencyData = getCurrencyData(event)
332342

333343
const adagioAuctionCacheId = (
334344
(event.latestTargetedAuctionId && event.latestTargetedAuctionId !== event.auctionId)
335345
? cache.getAdagioAuctionId(event.auctionId)
336346
: null);
337347

338348
cache.updateAuction(auctionId, event.adUnitCode, {
339-
win_bdr: getAdapterNameForAlias(event.bidder),
349+
win_bdr: event.bidder,
340350
win_mt: getMediaTypeAlias(event.mediaType),
341351
win_ban_sz: event.mediaType === BANNER ? `${event.width}x${event.height}` : null,
342352

343-
// ad server currency
344-
win_cpm: event.cpm,
345-
cur: event.currency,
346-
cur_rate: adsCurRateToUSD,
347-
348-
// original currency from bidder
349-
og_cpm: event.originalCpm,
350-
og_cur: event.originalCurrency,
351-
og_cur_rate: ogCurRateToUSD,
353+
win_net_cpm: currencyData.netCpm,
354+
win_og_cpm: currencyData.orginalCpm,
352355

353356
// cache bid id
354357
auct_id_c: adagioAuctionCacheId,
@@ -428,7 +431,7 @@ adagioAdapter.enableAnalytics = config => {
428431

429432
adapterManager.registerAnalyticsAdapter({
430433
adapter: adagioAdapter,
431-
code: 'adagio',
434+
code: ADAGIO_CODE,
432435
gvlid: ADAGIO_GVLID,
433436
});
434437

test/spec/modules/adagioAnalyticsAdapter_spec.js

Lines changed: 59 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import adagioAnalyticsAdapter from 'modules/adagioAnalyticsAdapter.js';
22
import { expect } from 'chai';
33
import * as utils from 'src/utils.js';
4-
import { getGlobal } from 'src/prebidGlobal.js';
54
import { server } from 'test/mocks/xhr.js';
5+
import * as prebidGlobal from 'src/prebidGlobal.js';
66

77
let adapterManager = require('src/adapterManager').default;
88
let events = require('src/events');
@@ -647,17 +647,19 @@ describe('adagio analytics adapter', () => {
647647
});
648648

649649
it('builds and sends auction data', () => {
650-
getGlobal().convertCurrency = (cpm, from, to) => {
651-
const convKeys = {
652-
'GBP-EUR': 0.7,
653-
'EUR-GBP': 1.3,
654-
'USD-EUR': 0.8,
655-
'EUR-USD': 1.2,
656-
'USD-GBP': 0.6,
657-
'GBP-USD': 1.6,
658-
};
659-
return cpm * (convKeys[`${from}-${to}`] || 1);
660-
};
650+
sandbox.stub(prebidGlobal, 'getGlobal').returns({
651+
convertCurrency: (cpm, from, to) => {
652+
const convKeys = {
653+
'GBP-EUR': 0.7,
654+
'EUR-GBP': 1.3,
655+
'USD-EUR': 0.8,
656+
'EUR-USD': 1.2,
657+
'USD-GBP': 0.6,
658+
'GBP-USD': 1.6,
659+
};
660+
return cpm * (convKeys[`${from}-${to}`] || 1);
661+
}
662+
});
661663

662664
events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT.another);
663665
events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE.adagio);
@@ -697,6 +699,7 @@ describe('adagio analytics adapter', () => {
697699
expect(search.e_sid).to.equal('42');
698700
expect(search.e_pba_test).to.equal('true');
699701
expect(search.bdrs_bid).to.equal('1,1,0');
702+
expect(search.bdrs_cpm).to.equal('1.42,2.052,');
700703
}
701704

702705
{
@@ -710,27 +713,25 @@ describe('adagio analytics adapter', () => {
710713
expect(search.win_bdr).to.equal('another');
711714
expect(search.win_mt).to.equal('ban');
712715
expect(search.win_ban_sz).to.equal('728x90');
713-
expect(search.win_cpm).to.equal('1.71');
714-
expect(search.cur).to.equal('EUR');
715-
expect(search.cur_rate).to.equal('1.2');
716-
expect(search.og_cpm).to.equal('1.62');
717-
expect(search.og_cur).to.equal('GBP');
718-
expect(search.og_cur_rate).to.equal('1.6');
716+
expect(search.win_net_cpm).to.equal('2.052');
717+
expect(search.win_og_cpm).to.equal('2.592');
719718
}
720719
});
721720

722721
it('builds and sends auction data with a cached bid win', () => {
723-
getGlobal().convertCurrency = (cpm, from, to) => {
724-
const convKeys = {
725-
'GBP-EUR': 0.7,
726-
'EUR-GBP': 1.3,
727-
'USD-EUR': 0.8,
728-
'EUR-USD': 1.2,
729-
'USD-GBP': 0.6,
730-
'GBP-USD': 1.6,
731-
};
732-
return cpm * (convKeys[`${from}-${to}`] || 1);
733-
};
722+
sandbox.stub(prebidGlobal, 'getGlobal').returns({
723+
convertCurrency: (cpm, from, to) => {
724+
const convKeys = {
725+
'GBP-EUR': 0.7,
726+
'EUR-GBP': 1.3,
727+
'USD-EUR': 0.8,
728+
'EUR-USD': 1.2,
729+
'USD-GBP': 0.6,
730+
'GBP-USD': 1.6,
731+
};
732+
return cpm * (convKeys[`${from}-${to}`] || 1);
733+
}
734+
});
734735

735736
events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT.bidcached);
736737
events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT.another);
@@ -794,6 +795,7 @@ describe('adagio analytics adapter', () => {
794795
expect(search.e_sid).to.equal('42');
795796
expect(search.e_pba_test).to.equal('true');
796797
expect(search.bdrs_bid).to.equal('0,0,0');
798+
expect(search.bdrs_cpm).to.equal(',,');
797799
}
798800

799801
{
@@ -808,12 +810,8 @@ describe('adagio analytics adapter', () => {
808810
expect(search.win_bdr).to.equal('adagio');
809811
expect(search.win_mt).to.equal('ban');
810812
expect(search.win_ban_sz).to.equal('728x90');
811-
expect(search.win_cpm).to.equal('1.42');
812-
expect(search.cur).to.equal('USD');
813-
expect(search.cur_rate).to.equal('1');
814-
expect(search.og_cpm).to.equal('1.42');
815-
expect(search.og_cur).to.equal('USD');
816-
expect(search.og_cur_rate).to.equal('1');
813+
expect(search.win_net_cpm).to.equal('1.42');
814+
expect(search.win_og_cpm).to.equal('1.42');
817815
expect(search.rndr).to.not.exist;
818816
}
819817

@@ -829,5 +827,31 @@ describe('adagio analytics adapter', () => {
829827
expect(search.rndr).to.equal('0');
830828
}
831829
});
830+
831+
it('send an "empty" cpm when adserver currency != USD and convertCurrency() is undefined', () => {
832+
sandbox.stub(prebidGlobal, 'getGlobal').returns({});
833+
834+
events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT.another);
835+
events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE.adagio);
836+
events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE.another);
837+
events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END.another);
838+
events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON.another);
839+
events.emit(constants.EVENTS.AD_RENDER_SUCCEEDED, MOCK.AD_RENDER_SUCCEEDED.another);
840+
841+
expect(server.requests.length).to.equal(3, 'requests count');
842+
843+
// fail to compute bidder cpm and send an "empty" cpm
844+
{
845+
const { protocol, hostname, pathname, search } = utils.parseUrl(server.requests[1].url);
846+
expect(protocol).to.equal('https');
847+
expect(hostname).to.equal('c.4dex.io');
848+
expect(pathname).to.equal('/pba.gif');
849+
expect(search.v).to.equal('2');
850+
expect(search.e_sid).to.equal('42');
851+
expect(search.e_pba_test).to.equal('true');
852+
expect(search.bdrs_bid).to.equal('1,1,0');
853+
expect(search.bdrs_cpm).to.equal('1.42,,');
854+
}
855+
});
832856
});
833857
});

0 commit comments

Comments
 (0)