Skip to content

Commit

Permalink
PubMatic Analytics Adapter : Logging MultiBids from bidders (#11844)
Browse files Browse the repository at this point in the history
* Using orignalRequestId to find the bid in case of MultiBid response

* Using orignalRequestId to find the winning bid in case of MultiBid response

* Handled bidderCode while logging

* replaced Prebid version method by string

---------

Co-authored-by: pm-azhar-mulla <[email protected]>
  • Loading branch information
pm-azhar-mulla and pm-azhar-mulla committed Jun 21, 2024
1 parent 1f8af9e commit a4a6de8
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 13 deletions.
29 changes: 21 additions & 8 deletions modules/pubmaticAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ function isOWPubmaticBid(adapterName) {
})
}

function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) {
function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid, e) {
highestBid = (highestBid && highestBid.length > 0) ? highestBid[0] : null;
return Object.keys(adUnit.bids).reduce(function(partnerBids, bidId) {
adUnit.bids[bidId].forEach(function(bid) {
Expand All @@ -290,6 +290,16 @@ function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) {
return;
}
const pg = window.parseFloat(Number(bid.bidResponse?.adserverTargeting?.hb_pb || bid.bidResponse?.adserverTargeting?.pwtpb).toFixed(BID_PRECISION));

const prebidBidsReceived = e?.bidsReceived;
if (isArray(prebidBidsReceived) && prebidBidsReceived.length > 0) {
prebidBidsReceived.forEach(function(iBid) {
if (iBid.adId === bid.adId) {
bid.bidderCode = iBid.bidderCode;
}
});
}

partnerBids.push({
'pn': adapterName,
'bc': bid.bidderCode || bid.bidder,
Expand Down Expand Up @@ -391,7 +401,7 @@ function executeBidsLoggerCall(e, highestCpmBids) {
outputObj['pdvid'] = '' + profileVersionId;
outputObj['dvc'] = {'plt': getDevicePlatform()};
outputObj['tgid'] = getTgId();
outputObj['pbv'] = getGlobal()?.version || '-1';
outputObj['pbv'] = '$prebid.version$' || '-1';

if (floorData && floorFetchStatus) {
outputObj['fmv'] = floorData.floorRequestData ? floorData.floorRequestData.modelVersion || undefined : undefined;
Expand All @@ -407,7 +417,7 @@ function executeBidsLoggerCall(e, highestCpmBids) {
'au': origAdUnit.owAdUnitId || getGptSlotInfoForAdUnitCode(adUnitId)?.gptSlot || adUnitId,
'mt': getAdUnitAdFormats(origAdUnit),
'sz': getSizesForAdUnit(adUnit, adUnitId),
'ps': gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestCpmBids.filter(bid => bid.adUnitCode === adUnitId)),
'ps': gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestCpmBids.filter(bid => bid.adUnitCode === adUnitId), e),
'fskp': floorData && floorFetchStatus ? (floorData.floorRequestData ? (floorData.floorRequestData.skipped == false ? 0 : 1) : undefined) : undefined,
'sid': generateUUID()
};
Expand Down Expand Up @@ -559,15 +569,18 @@ function bidResponseHandler(args) {
logWarn(LOG_PRE_FIX + 'Got null requestId in bidResponseHandler');
return;
}
let bid = cache.auctions[args.auctionId].adUnitCodes[args.adUnitCode].bids[args.requestId][0];
let requestId = args.originalRequestId || args.requestId;
let bid = cache.auctions[args.auctionId].adUnitCodes[args.adUnitCode].bids[requestId][0];
if (!bid) {
logError(LOG_PRE_FIX + 'Could not find associated bid request for bid response with requestId: ', args.requestId);
return;
}

if ((bid.bidder && args.bidderCode && bid.bidder !== args.bidderCode) || (bid.bidder === args.bidderCode && bid.status === SUCCESS)) {
bid = copyRequiredBidDetails(args);
cache.auctions[args.auctionId].adUnitCodes[args.adUnitCode].bids[args.requestId].push(bid);
cache.auctions[args.auctionId].adUnitCodes[args.adUnitCode].bids[requestId].push(bid);
} else if (args.originalRequestId) {
bid.bidId = args.requestId;
}

if (args.floorData) {
Expand Down Expand Up @@ -598,7 +611,7 @@ function bidRejectedHandler(args) {
function bidderDoneHandler(args) {
cache.auctions[args.auctionId].bidderDonePendingCount--;
args.bids.forEach(bid => {
let cachedBid = cache.auctions[bid.auctionId].adUnitCodes[bid.adUnitCode].bids[bid.bidId || bid.requestId];
let cachedBid = cache.auctions[bid.auctionId].adUnitCodes[bid.adUnitCode].bids[bid.bidId || bid.originalRequestId || bid.requestId];
if (typeof bid.serverResponseTimeMs !== 'undefined') {
cachedBid.serverLatencyTimeMs = bid.serverResponseTimeMs;
}
Expand All @@ -613,7 +626,7 @@ function bidderDoneHandler(args) {

function bidWonHandler(args) {
let auctionCache = cache.auctions[args.auctionId];
auctionCache.adUnitCodes[args.adUnitCode].bidWon = args.requestId;
auctionCache.adUnitCodes[args.adUnitCode].bidWon = args.originalRequestId || args.requestId;
auctionCache.adUnitCodes[args.adUnitCode].bidWonAdId = args.adId;
executeBidWonLoggerCall(args.auctionId, args.adUnitCode);
}
Expand All @@ -631,7 +644,7 @@ function bidTimeoutHandler(args) {
// db = 0 and t = 1 means bidder did respond with a bid but post timeout
args.forEach(badBid => {
let auctionCache = cache.auctions[badBid.auctionId];
let bid = auctionCache.adUnitCodes[badBid.adUnitCode].bids[ badBid.bidId || badBid.requestId ][0];
let bid = auctionCache.adUnitCodes[badBid.adUnitCode].bids[ badBid.bidId || badBid.originalRequestId || badBid.requestId ][0];
if (bid) {
bid.status = ERROR;
bid.error = {
Expand Down
57 changes: 52 additions & 5 deletions test/spec/modules/pubmaticAnalyticsAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ describe('pubmatic analytics adapter', function () {
expect(data.tgid).to.equal(15);
expect(data.fmv).to.equal('floorModelTest');
expect(data.ft).to.equal(1);
expect(data.pbv).to.equal(getGlobal()?.version || '-1');
expect(data.pbv).to.equal('$prebid.version$' || '-1');
expect(data.s).to.be.an('array');
expect(data.s.length).to.equal(2);
// slot 1
Expand Down Expand Up @@ -786,7 +786,7 @@ describe('pubmatic analytics adapter', function () {
expect(data.pid).to.equal('1111');
expect(data.fmv).to.equal('floorModelTest');
expect(data.ft).to.equal(1);
expect(data.pbv).to.equal(getGlobal()?.version || '-1');
expect(data.pbv).to.equal('$prebid.version$' || '-1');
expect(data.s).to.be.an('array');
expect(data.s.length).to.equal(2);
expect(data.tgid).to.equal(0);
Expand Down Expand Up @@ -866,7 +866,7 @@ describe('pubmatic analytics adapter', function () {
expect(data.tgid).to.equal(0);// test group id should be between 0-15 else set to 0
expect(data.fmv).to.equal('floorModelTest');
expect(data.ft).to.equal(1);
expect(data.pbv).to.equal(getGlobal()?.version || '-1');
expect(data.pbv).to.equal('$prebid.version$' || '-1');
expect(data.s).to.be.an('array');
expect(data.s.length).to.equal(2);
// slot 1
Expand Down Expand Up @@ -1434,7 +1434,7 @@ describe('pubmatic analytics adapter', function () {
expect(data.tst).to.equal(1519767016);
expect(data.tgid).to.equal(15);
expect(data.fmv).to.equal('floorModelTest');
expect(data.pbv).to.equal(getGlobal()?.version || '-1');
expect(data.pbv).to.equal('$prebid.version$' || '-1');
expect(data.ft).to.equal(1);
expect(data.s).to.be.an('array');
expect(data.s.length).to.equal(2);
Expand Down Expand Up @@ -1566,7 +1566,7 @@ describe('pubmatic analytics adapter', function () {
expect(data.tst).to.equal(1519767016);
expect(data.tgid).to.equal(15);
expect(data.fmv).to.equal('floorModelTest');
expect(data.pbv).to.equal(getGlobal()?.version || '-1');
expect(data.pbv).to.equal('$prebid.version$' || '-1');
expect(data.ft).to.equal(1);
expect(data.s).to.be.an('array');
expect(data.s.length).to.equal(2);
Expand Down Expand Up @@ -1657,8 +1657,55 @@ describe('pubmatic analytics adapter', function () {
expect(data.origbidid).to.equal('partnerImpressionID-1');
});

it('Logger: should use originalRequestId to find the bid', function() {
MOCK.BID_RESPONSE[1]['originalRequestId'] = '3bd4ebb1c900e2';
MOCK.BID_RESPONSE[1]['requestId'] = '54d4ebb1c9003e';
sandbox.stub($$PREBID_GLOBAL$$, 'getHighestCpmBids').callsFake((key) => {
return [MOCK.BID_RESPONSE[0], MOCK.BID_RESPONSE[1]]
});

config.setConfig({
testGroupId: 15
});

events.emit(AUCTION_INIT, MOCK.AUCTION_INIT);
events.emit(BID_REQUESTED, MOCK.BID_REQUESTED);
events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]);
events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[1]);
events.emit(BIDDER_DONE, MOCK.BIDDER_DONE);
events.emit(AUCTION_END, MOCK.AUCTION_END);
events.emit(SET_TARGETING, MOCK.SET_TARGETING);
events.emit(BID_WON, MOCK.BID_WON[0]);
events.emit(BID_WON, MOCK.BID_WON[1]);

clock.tick(2000 + 1000);
expect(requests.length).to.equal(3); // 1 logger and 2 win-tracker
let request = requests[2]; // logger is executed late, trackers execute first
expect(request.url).to.equal('https://t.pubmatic.com/wl?pubid=9999');
let data = getLoggerJsonFromRequest(request.requestBody);
expect(data.s).to.be.an('array');
expect(data.s.length).to.equal(2);

// slot 1
expect(data.s[0].ps[0].bidid).to.equal('2ecff0db240757');
expect(data.s[0].ps[0].origbidid).to.equal('partnerImpressionID-1');

// slot 2
expect(data.s[1].ps[0].bidid).to.equal('54d4ebb1c9003e');
expect(data.s[1].ps[0].origbidid).to.equal('partnerImpressionID-2');

// tracker slot1
let firstTracker = requests[0].url;
expect(firstTracker.split('?')[0]).to.equal('https://t.pubmatic.com/wt');
data = {};
firstTracker.split('?')[1].split('&').map(e => e.split('=')).forEach(e => data[e[0]] = e[1]);
expect(data.bidid).to.equal('2ecff0db240757');
expect(data.origbidid).to.equal('partnerImpressionID-1');
});

it('Logger: best case + win tracker. Log bidId when partnerimpressionid is missing', function() {
delete MOCK.BID_RESPONSE[1]['partnerImpId'];
MOCK.BID_RESPONSE[1]['requestId'] = '3bd4ebb1c900e2';
MOCK.BID_RESPONSE[1]['prebidBidId'] = 'Prebid-bid-id-1';
sandbox.stub($$PREBID_GLOBAL$$, 'getHighestCpmBids').callsFake((key) => {
return [MOCK.BID_RESPONSE[0], MOCK.BID_RESPONSE[1]]
Expand Down

0 comments on commit a4a6de8

Please sign in to comment.