Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Magnite Analytics: Check if prebid cache was called for video tracking #10928

Merged
merged 7 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions modules/magniteAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {config} from '../src/config.js';
import {getGlobal} from '../src/prebidGlobal.js';
import {getStorageManager} from '../src/storageManager.js';
import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js';
import { getHook } from '../src/hook.js';

const RUBICON_GVL_ID = 52;
export const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleName: 'magnite' });
Expand Down Expand Up @@ -75,7 +76,8 @@ const resetConfs = () => {
pendingEvents: {},
eventPending: false,
elementIdMap: {},
sessionData: {}
sessionData: {},
bidsCachedClientSide: new WeakSet()
}
rubiConf = {
pvid: generateUUID().slice(0, 8),
Expand Down Expand Up @@ -671,8 +673,20 @@ function enableMgniAnalytics(config = {}) {
window.googletag.cmd = window.googletag.cmd || [];
window.googletag.cmd.push(() => subscribeToGamSlots());
}

// Edge case handler for client side video caching
getHook('callPrebidCache').before(callPrebidCacheHook);
};

/*
We want to know if a bid was cached client side
And if it was we will use the actual bidId instead of the pbsBidId override in our BID_RESPONSE handler
*/
export function callPrebidCacheHook(fn, auctionInstance, bidResponse, afterBidAdded, videoMediaType) {
cache.bidsCachedClientSide.add(bidResponse);
fn.call(this, auctionInstance, bidResponse, afterBidAdded, videoMediaType);
}

const handleBidWon = args => {
const bidWon = formatBidWon(args);
addEventToQueue({ bidsWon: [bidWon] }, bidWon.renderAuctionId, 'bidWon');
Expand All @@ -687,6 +701,7 @@ magniteAdapter.disableAnalytics = function () {
endpoint = undefined;
accountId = undefined;
resetConfs();
getHook('callPrebidCache').getHooks({ hook: callPrebidCacheHook }).remove();
magniteAdapter.originDisableAnalytics();
};

Expand Down Expand Up @@ -749,7 +764,7 @@ const handleBidResponse = (args, bidStatus) => {

// if pbs gave us back a bidId, we need to use it and update our bidId to PBA
const pbsBidId = (args.pbsBidId == 0 ? generateUUID() : args.pbsBidId) || (args.seatBidId == 0 ? generateUUID() : args.seatBidId);
if (pbsBidId) {
if (pbsBidId && !cache.bidsCachedClientSide.has(args)) {
bid.pbsBidId = pbsBidId;
}
}
Expand Down
36 changes: 35 additions & 1 deletion test/spec/modules/magniteAnalyticsAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import magniteAdapter, {
getHostNameFromReferer,
storage,
rubiConf,
detectBrowserFromUa
detectBrowserFromUa,
callPrebidCacheHook
} from '../../../modules/magniteAnalyticsAdapter.js';
import CONSTANTS from 'src/constants.json';
import { config } from 'src/config.js';
Expand Down Expand Up @@ -1137,6 +1138,39 @@ describe('magnite analytics adapter', function () {
});
});

it('should not use pbsBidId if the bid was client side cached', function () {
// bid response
let seatBidResponse = utils.deepClone(MOCK.BID_RESPONSE);
seatBidResponse.pbsBidId = 'do-not-use-me';

// Run auction
events.emit(AUCTION_INIT, MOCK.AUCTION_INIT);
events.emit(BID_REQUESTED, MOCK.BID_REQUESTED);

// mock client side cache call
callPrebidCacheHook(() => {}, {}, seatBidResponse);

events.emit(BID_RESPONSE, seatBidResponse);
events.emit(BIDDER_DONE, MOCK.BIDDER_DONE);
events.emit(AUCTION_END, MOCK.AUCTION_END);

// emmit gpt events and bidWon
mockGpt.emitEvent(gptSlotRenderEnded0.eventName, gptSlotRenderEnded0.params);

events.emit(BID_WON, MOCK.BID_WON);

// tick the event delay time plus processing delay
clock.tick(rubiConf.analyticsEventDelay + rubiConf.analyticsProcessDelay);

expect(server.requests.length).to.equal(1);
let request = server.requests[0];
let message = JSON.parse(request.requestBody);

// Expect the ids sent to server to use the original bidId not the pbsBidId thing
expect(message.auctions[0].adUnits[0].bids[0].bidId).to.equal(MOCK.BID_RESPONSE.requestId);
expect(message.bidsWon[0].bidId).to.equal(MOCK.BID_RESPONSE.requestId);
});

[0, '0'].forEach(pbsParam => {
it(`should generate new bidId if incoming pbsBidId is ${pbsParam}`, function () {
// bid response
Expand Down