Skip to content
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
5 changes: 3 additions & 2 deletions integrationExamples/gpt/prebidServer_example.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,10 @@

<script>
googletag.cmd.push(function() {
var rightSlot = googletag.defineSlot('/19968336/header-bid-tag-0', [[300, 250]], 'div-gpt-ad-1460505748561-0').addService(googletag.pubads());
googletag.defineSlot('/19968336/header-bid-tag-0', [[300, 250]], 'div-gpt-ad-1460505748561-0').addService(googletag.pubads());

if (pbjs.libLoaded) { // Check if Prebid.js is loaded
// Check if Prebid.js is loaded
if (pbjs.libLoaded) {
pbjs.que.push(function() {
pbjs.setTargetingForGPTAsync();
googletag.pubads().refresh();
Expand Down
58 changes: 41 additions & 17 deletions integrationExamples/testBidder/testBidderBannerExample.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,51 @@
const adUnits = [{
mediaTypes: {
banner: {
sizes: [600, 500]
sizes: [[320, 250], [300, 250]]
}
},
code: adUnitCode,
bids: [
{bidder: 'testBidder', params: {}}
{bidder: 'testBidder', params: {}},
{bidder: 'kobler', params: {test: true}},
]
}]
}];

function requestBids() {
pbjs.requestBids({
adUnitCodes: [adUnitCode],
bidsBackHandler: function() {
const bids = pbjs.getHighestCpmBids(adUnitCode);
const winningBid = bids[0];
const div = document.getElementById('banner');
let iframe = div.querySelector('iframe')
if (iframe === null) {
iframe = document.createElement('iframe');
iframe.frameBorder = '0';
div.appendChild(iframe);
}
var iframeDoc = iframe.contentWindow.document;
pbjs.renderAd(iframeDoc, winningBid.adId);
}
});
}

function refreshBids() {
pbjs.que.push(requestBids);
}

function refreshPageViewId() {
pbjs.que.push(function () {
pbjs.refreshPageViewId()
});
}

pbjs.que.push(function () {

pbjs.setConfig({
pageUrl: 'https://www.tv2.no/mening-og-analyse/14555348/'
})

/**
* BID RESPONSE SIMULATION SECTION START
*
Expand Down Expand Up @@ -55,25 +89,15 @@
*/

pbjs.addAdUnits(adUnits);
pbjs.requestBids({
adUnitCodes: [adUnitCode],
bidsBackHandler: function() {
const bids = pbjs.getHighestCpmBids(adUnitCode);
const winningBid = bids[0];
const div = document.getElementById('banner');
let iframe = document.createElement('iframe');
iframe.frameBorder = '0';
div.appendChild(iframe);
var iframeDoc = iframe.contentWindow.document;
pbjs.renderAd(iframeDoc, winningBid.adId);
}
});
requestBids();
});
</script>
</head>
<body>
<h2>Prebid Test Bidder Example</h2>
<p><button onclick="refreshBids()">Refresh Ad Units</button></p>
<p><button onclick="refreshPageViewId()">Refresh page view ID</button></p>
<h5>Banner ad</h5>
<div id="banner"></div>
</body>
</html>
</html>
1 change: 1 addition & 0 deletions libraries/adagioUtils/adagioUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const _ADAGIO = (function() {
const w = getBestWindowForAdagio();

w.ADAGIO = w.ADAGIO || {};
// TODO: consider using the Prebid-generated page view ID instead of generating a custom one
w.ADAGIO.pageviewId = w.ADAGIO.pageviewId || generateUUID();
w.ADAGIO.adUnits = w.ADAGIO.adUnits || {};
w.ADAGIO.pbjsAdUnits = w.ADAGIO.pbjsAdUnits || [];
Expand Down
9 changes: 9 additions & 0 deletions libraries/pbsExtensions/processors/pageViewIds.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {deepSetValue} from '../../../src/utils.js';

export function setRequestExtPrebidPageViewIds(ortbRequest, bidderRequest) {
deepSetValue(
ortbRequest,
`ext.prebid.page_view_ids.${bidderRequest.bidderCode}`,
bidderRequest.pageViewId
);
}
7 changes: 6 additions & 1 deletion libraries/pbsExtensions/processors/pbs.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {setImpAdUnitCode} from './adUnitCode.js';
import {setRequestExtPrebid, setRequestExtPrebidChannel} from './requestExtPrebid.js';
import {setBidResponseVideoCache} from './video.js';
import {addEventTrackers} from './eventTrackers.js';
import {setRequestExtPrebidPageViewIds} from './pageViewIds.js';

export const PBS_PROCESSORS = {
[REQUEST]: {
Expand All @@ -21,7 +22,11 @@ export const PBS_PROCESSORS = {
extPrebidAliases: {
// sets ext.prebid.aliases
fn: setRequestExtPrebidAliases
}
},
extPrebidPageViewIds: {
// sets ext.prebid.page_view_ids
fn: setRequestExtPrebidPageViewIds
},
},
[IMP]: {
params: {
Expand Down
1 change: 1 addition & 0 deletions modules/carodaBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const spec = {
);
},
buildRequests: (validBidRequests, bidderRequest) => {
// TODO: consider using the Prebid-generated page view ID instead of generating a custom one
topUsableWindow.carodaPageViewId = topUsableWindow.carodaPageViewId || Math.floor(Math.random() * 1e9);
const pageViewId = topUsableWindow.carodaPageViewId;
const ortbCommon = getORTBCommon(bidderRequest);
Expand Down
8 changes: 1 addition & 7 deletions modules/cwireBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { registerBidder } from "../src/adapters/bidderFactory.js";
import { getStorageManager } from "../src/storageManager.js";
import { BANNER } from "../src/mediaTypes.js";
import {
generateUUID,
getParameterByName,
isNumber,
logError,
Expand All @@ -27,11 +26,6 @@ export const BID_ENDPOINT = "https://prebid.cwi.re/v1/bid";
export const EVENT_ENDPOINT = "https://prebid.cwi.re/v1/event";
export const GVL_ID = 1081;

/**
* Allows limiting ad impressions per site render. Unique per prebid instance ID.
*/
export const pageViewId = generateUUID();

export const storage = getStorageManager({ bidderCode: BIDDER_CODE });

/**
Expand Down Expand Up @@ -248,7 +242,7 @@ export const spec = {
slots: processed,
httpRef: referrer,
// TODO: Verify whether the auctionId and the usage of pageViewId make sense.
pageViewId: pageViewId,
pageViewId: bidderRequest.pageViewId,
networkBandwidth: getConnectionDownLink(window.navigator),
sdk: {
version: "$prebid.version$",
Expand Down
1 change: 1 addition & 0 deletions modules/kargoBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ function buildRequests(validBidRequests, bidderRequest) {

const page = {}
if (validPageId) {
// TODO: consider using the Prebid-generated page view ID instead of generating a custom one
page.id = getLocalStorageSafely(CERBERUS.PAGE_VIEW_ID);
}
if (validPageTimestamp) {
Expand Down
5 changes: 1 addition & 4 deletions modules/koblerBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
deepAccess,
generateUUID,
getWindowSelf,
isArray,
isStr,
Expand All @@ -15,8 +14,6 @@ import { getCurrencyFromBidderRequest } from '../libraries/ortb2Utils/currency.j

const additionalData = new WeakMap();

export const pageViewId = generateUUID();

export function setAdditionalData(obj, key, value) {
const prevValue = additionalData.get(obj) || {};
additionalData.set(obj, { ...prevValue, [key]: value });
Expand Down Expand Up @@ -185,7 +182,7 @@ function buildOpenRtbBidRequestPayload(validBidRequests, bidderRequest) {
kobler: {
tcf_purpose_2_given: purpose2Given,
tcf_purpose_3_given: purpose3Given,
page_view_id: pageViewId
page_view_id: bidderRequest.pageViewId
}
}
};
Expand Down
1 change: 1 addition & 0 deletions modules/ooloAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const prebidVersion = '$prebid.version$'
const analyticsType = 'endpoint'
const ADAPTER_CODE = 'oolo'
const AUCTION_END_SEND_TIMEOUT = 1500
// TODO: consider using the Prebid-generated page view ID instead of generating a custom one
export const PAGEVIEW_ID = +generatePageViewId()

const {
Expand Down
10 changes: 7 additions & 3 deletions modules/prebidServerBidAdapter/ortbConverter.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ const BIDDER_SPECIFIC_REQUEST_PROPS = new Set(['bidderCode', 'bidderRequestId',
const getMinimumFloor = (() => {
const getMin = minimum(currencyCompare(floor => [floor.bidfloor, floor.bidfloorcur]));
return function(candidates) {
let min;
let min = null;
for (const candidate of candidates) {
if (candidate?.bidfloorcur == null || candidate?.bidfloor == null) return null;
min = min == null ? candidate : getMin(min, candidate);
min = min === null ? candidate : getMin(min, candidate);
}
return min;
}
Expand Down Expand Up @@ -133,7 +133,7 @@ const PBS_CONVERTER = ortbConverter({
// also, take overrides from s2sConfig.adapterOptions
const adapterOptions = context.s2sBidRequest.s2sConfig.adapterOptions;
for (const req of context.actualBidRequests.values()) {
setImpBidParams(imp, req, context, context);
setImpBidParams(imp, req);
if (adapterOptions && adapterOptions[req.bidder]) {
Object.assign(imp.ext.prebid.bidder[req.bidder], adapterOptions[req.bidder]);
}
Expand Down Expand Up @@ -237,6 +237,10 @@ const PBS_CONVERTER = ortbConverter({
extPrebidAliases(orig, ortbRequest, proxyBidderRequest, context) {
// override alias processing to do it for each bidder in the request
context.actualBidderRequests.forEach(req => orig(ortbRequest, req, context));
},
extPrebidPageViewIds(orig, ortbRequest, proxyBidderRequest, context) {
// override page view ID processing to do it for each bidder in the request
context.actualBidderRequests.forEach(req => orig(ortbRequest, req, context));
}
},
[RESPONSE]: {
Expand Down
3 changes: 1 addition & 2 deletions modules/snigelBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ const getConfig = config.getConfig;
const storageManager = getStorageManager({bidderCode: BIDDER_CODE});
const refreshes = {};
const placementCounters = {};
const pageViewId = generateUUID();
const pageViewStart = new Date().getTime();
let auctionCounter = 0;

Expand All @@ -43,7 +42,7 @@ export const spec = {
site: deepAccess(bidRequests, '0.params.site'),
sessionId: getSessionId(),
counter: auctionCounter++,
pageViewId: pageViewId,
pageViewId: bidderRequest.pageViewId,
pageViewStart: pageViewStart,
gdprConsent: gdprApplies === true ? hasFullGdprConsent(deepAccess(bidderRequest, 'gdprConsent')) : false,
cur: getCurrencies(),
Expand Down
15 changes: 15 additions & 0 deletions src/adapterManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import type {
AnalyticsConfig,
AnalyticsProvider, AnalyticsProviderConfig,
} from "../libraries/analyticsAdapter/AnalyticsAdapter.ts";
import {getGlobal} from "./prebidGlobal.ts";

export {gdprDataHandler, gppDataHandler, uspDataHandler, coppaDataHandler} from './consentHandler.js';

Expand Down Expand Up @@ -168,6 +169,7 @@ export interface BaseBidderRequest<BIDDER extends BidderCode | null> {
*/
bidderRequestId: Identifier;
auctionId: Identifier;
pageViewId: Identifier;
/**
* The bidder associated with this request, or null in the case of stored impressions.
*/
Expand Down Expand Up @@ -554,6 +556,15 @@ const adapterManager = {
return bidderRequest as T;
}

const pbjsInstance = getGlobal();

function getPageViewIdForBidder(bidderCode: string | null): string {
if (!pbjsInstance.pageViewIdPerBidder.has(bidderCode)) {
pbjsInstance.pageViewIdPerBidder.set(bidderCode, generateUUID());
}
return pbjsInstance.pageViewIdPerBidder.get(bidderCode);
}

_s2sConfigs.forEach(s2sConfig => {
const s2sParams = s2sActivityParams(s2sConfig);
if (s2sConfig && s2sConfig.enabled && dep.isAllowed(ACTIVITY_FETCH_BIDS, s2sParams)) {
Expand All @@ -564,11 +575,13 @@ const adapterManager = {

(serverBidders.length === 0 && hasModuleBids ? [null] : serverBidders).forEach(bidderCode => {
const bidderRequestId = generateUUID();
const pageViewId = getPageViewIdForBidder(bidderCode);
const metrics = auctionMetrics.fork();
const bidderRequest = addOrtb2({
bidderCode,
auctionId,
bidderRequestId,
pageViewId,
uniquePbsTid,
bids: getBids({
bidderCode,
Expand Down Expand Up @@ -611,10 +624,12 @@ const adapterManager = {
const adUnitsClientCopy = getAdUnitCopyForClientAdapters(adUnits);
clientBidders.forEach(bidderCode => {
const bidderRequestId = generateUUID();
const pageViewId = getPageViewIdForBidder(bidderCode);
const metrics = auctionMetrics.fork();
const bidderRequest = addOrtb2({
bidderCode,
auctionId,
pageViewId,
bidderRequestId,
bids: getBids({
bidderCode,
Expand Down
14 changes: 14 additions & 0 deletions src/prebid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ declare module './prebidGlobal' {
*/
delayPrerendering?: boolean
adUnits: AdUnitDefinition[];
pageViewIdPerBidder: Map<string | null, string>
}
}

Expand All @@ -113,6 +114,7 @@ logInfo('Prebid.js v$prebid.version$ loaded');

// create adUnit array
pbjsInstance.adUnits = pbjsInstance.adUnits || [];
pbjsInstance.pageViewIdPerBidder = pbjsInstance.pageViewIdPerBidder || new Map<string | null, string>();

function validateSizes(sizes, targLength?: number) {
let cleanSizes = [];
Expand Down Expand Up @@ -483,6 +485,7 @@ declare module './prebidGlobal' {
setBidderConfig: typeof config.setBidderConfig;
processQueue: typeof processQueue;
triggerBilling: typeof triggerBilling;
refreshPageViewId: typeof refreshPageViewId;
}
}

Expand Down Expand Up @@ -1259,4 +1262,15 @@ function triggerBilling({adId, adUnitCode}: {
}
addApiMethod('triggerBilling', triggerBilling);

/**
* Refreshes the previously generated page view ID. Can be used to instruct bidders
* that use page view ID to consider future auctions as part of a new page load.
*/
function refreshPageViewId() {
for (const key of pbjsInstance.pageViewIdPerBidder.keys()) {
pbjsInstance.pageViewIdPerBidder.set(key, generateUUID());
}
}
addApiMethod('refreshPageViewId', refreshPageViewId);

export default pbjsInstance;
6 changes: 6 additions & 0 deletions src/types/common.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ export type Currency = string;
export type AdUnitCode = string;
export type Size = [number, number];
export type ContextIdentifiers = {
/**
* Page view ID. Unique for a page view (one load of Prebid); can also be refreshed programmatically.
* Shared across all requests and responses within the page view, for the same bidder.
* Different bidders see a different page view ID.
*/
pageViewId: Identifier;
/**
* Auction ID. Unique for any given auction, but shared across all requests and responses within that auction.
*/
Expand Down
Loading
Loading