Skip to content

Commit

Permalink
IX Bid Adapter: add support for signaling privacy sandbox (fledge) au…
Browse files Browse the repository at this point in the history
…ction requests [PB-1841] (#10537)

* feat: add support for signaling fledge auction request [PB-1841]

feat: add test coverage [PB-1841]

feat: add more test coverage [PB-1841]

feat: fix code smell [PB-1841]

feat: fix code smell [PB-1841]

feat: fix code smell and update test adunit code [PB-1841]

feat: update ix adapter doc for fledge [PB-1841]

feat: update auction config response interpretation [PB-1841]

fix: fix typo [PB-1841]

fix: add missing null check for banner ext [PB-1841]

fix: add missing null check for banner ext [PB-1841]

feat: update interpret response to consider igbid in response ext [PB-1841]

feat: add extra validation and tests [PB-1841]

feat: add test case [PB-1841]

feat: update interpret response with new auctiuon confis [PB-1841]

fix: update config name

feat: update tests for new auction configs list response [PB-1841]

* feat: update banner ext definition [PB-1841]

* feat: update ixdiag and add integer check when signaling ae [PB-1841]

* feat: change order of reading ae config to respect ad unit level override [PB-1841]

* feat: add test case [PB-1841]

* feat: fix lint issue [PB-1841]

* feat: update fledgeenabled check in build request [PB-1841]

---------

Co-authored-by: shahin.rahbariasl <shahin.rahbariasl@indexexchange.com>
  • Loading branch information
shahinrahbariasl and shahin-rahbariasl authored Oct 4, 2023
1 parent 3f95c97 commit 3396f47
Show file tree
Hide file tree
Showing 3 changed files with 350 additions and 15 deletions.
89 changes: 74 additions & 15 deletions modules/ixBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,8 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
r = addRequestedFeatureToggles(r, FEATURE_TOGGLES.REQUESTED_FEATURE_TOGGLES)

// getting ixdiags for adunits of the video, outstream & multi format (MF) style
let ixdiag = buildIXDiag(validBidRequests);
const fledgeEnabled = deepAccess(bidderRequest, 'fledgeEnabled')
let ixdiag = buildIXDiag(validBidRequests, fledgeEnabled);
for (var key in ixdiag) {
r.ext.ixdiag[key] = ixdiag[key];
}
Expand Down Expand Up @@ -952,6 +953,7 @@ function addImpressions(impressions, impKeys, r, adUnitIndex) {
const dfpAdUnitCode = impressions[impKeys[adUnitIndex]].dfp_ad_unit_code;
const tid = impressions[impKeys[adUnitIndex]].tid;
const sid = impressions[impKeys[adUnitIndex]].sid;
const auctionEnvironment = impressions[impKeys[adUnitIndex]].ae;
const bannerImpressions = impressionObjects.filter(impression => BANNER in impression);
const otherImpressions = impressionObjects.filter(impression => !(BANNER in impression));

Expand Down Expand Up @@ -991,12 +993,18 @@ function addImpressions(impressions, impKeys, r, adUnitIndex) {
_bannerImpression.banner.pos = position;
}

if (dfpAdUnitCode || gpid || tid || sid) {
if (dfpAdUnitCode || gpid || tid || sid || auctionEnvironment) {
_bannerImpression.ext = {};

_bannerImpression.ext.dfp_ad_unit_code = dfpAdUnitCode;
_bannerImpression.ext.gpid = gpid;
_bannerImpression.ext.tid = tid;
_bannerImpression.ext.sid = sid;

// enable fledge auction
if (auctionEnvironment == 1) {
_bannerImpression.ext.ae = 1;
}
}

if ('bidfloor' in bannerImps[0]) {
Expand Down Expand Up @@ -1220,15 +1228,16 @@ function _getUserIds(bidRequest) {
/**
* Calculates IX diagnostics values and packages them into an object
*
* @param {array} validBidRequests The valid bid requests from prebid
* @param {array} validBidRequests - The valid bid requests from prebid
* @param {bool} fledgeEnabled - Flag indicating if protected audience (fledge) is enabled
* @return {Object} IX diag values for ad units
*/
function buildIXDiag(validBidRequests) {
function buildIXDiag(validBidRequests, fledgeEnabled) {
var adUnitMap = validBidRequests
.map(bidRequest => bidRequest.adUnitCode)
.filter((value, index, arr) => arr.indexOf(value) === index);

var ixdiag = {
let ixdiag = {
mfu: 0,
bu: 0,
iu: 0,
Expand All @@ -1239,12 +1248,13 @@ function buildIXDiag(validBidRequests) {
version: '$prebid.version$',
userIds: _getUserIds(validBidRequests[0]),
url: window.location.href.split('?')[0],
vpd: defaultVideoPlacement
vpd: defaultVideoPlacement,
ae: fledgeEnabled
};

// create ad unit map and collect the required diag properties
for (let i = 0; i < adUnitMap.length; i++) {
var bid = validBidRequests.filter(bidRequest => bidRequest.adUnitCode === adUnitMap[i])[0];
for (let adUnit of adUnitMap) {
let bid = validBidRequests.filter(bidRequest => bidRequest.adUnitCode === adUnit)[0];

if (deepAccess(bid, 'mediaTypes')) {
if (Object.keys(bid.mediaTypes).length > 1) {
Expand Down Expand Up @@ -1350,7 +1360,7 @@ function createVideoImps(validBidRequest, videoImps) {
* @param {object} missingBannerSizes reference to missing banner config sizes
* @param {object} bannerImps reference to created banner impressions
*/
function createBannerImps(validBidRequest, missingBannerSizes, bannerImps) {
function createBannerImps(validBidRequest, missingBannerSizes, bannerImps, bidderRequest) {
let imp = bidToBannerImp(validBidRequest);

const bannerSizeDefined = includesSize(deepAccess(validBidRequest, 'mediaTypes.banner.sizes'), deepAccess(validBidRequest, 'params.size'));
Expand All @@ -1366,6 +1376,21 @@ function createBannerImps(validBidRequest, missingBannerSizes, bannerImps) {
bannerImps[validBidRequest.adUnitCode].tagId = deepAccess(validBidRequest, 'params.tagId');
bannerImps[validBidRequest.adUnitCode].pos = deepAccess(validBidRequest, 'mediaTypes.banner.pos');

// Add Fledge flag if enabled
const fledgeEnabled = deepAccess(bidderRequest, 'fledgeEnabled')
if (fledgeEnabled) {
const auctionEnvironment = deepAccess(validBidRequest, 'ortb2Imp.ext.ae')
if (auctionEnvironment) {
if (isInteger(auctionEnvironment)) {
bannerImps[validBidRequest.adUnitCode].ae = auctionEnvironment;
} else {
logWarn('error setting auction environment flag - must be an integer')
}
} else if (deepAccess(bidderRequest, 'defaultForSlots') == 1) {
bannerImps[validBidRequest.adUnitCode].ae = 1
}
}

// AdUnit-Specific First Party Data
const adUnitFPD = deepAccess(validBidRequest, 'ortb2Imp.ext.data');
if (adUnitFPD) {
Expand Down Expand Up @@ -1720,7 +1745,7 @@ export const spec = {
for (const type in adUnitMediaTypes) {
switch (adUnitMediaTypes[type]) {
case BANNER:
createBannerImps(validBidRequest, missingBannerSizes, bannerImps);
createBannerImps(validBidRequest, missingBannerSizes, bannerImps, bidderRequest);
break;
case VIDEO:
createVideoImps(validBidRequest, videoImps)
Expand Down Expand Up @@ -1795,13 +1820,18 @@ export const spec = {
const bids = [];
let bid = null;

if (!serverResponse.hasOwnProperty('body') || !serverResponse.body.hasOwnProperty('seatbid')) {
FEATURE_TOGGLES.setFeatureToggles(serverResponse);
// Extract the FLEDGE auction configuration list from the response
let fledgeAuctionConfigs = deepAccess(serverResponse, 'body.ext.protectedAudienceAuctionConfigs') || [];

FEATURE_TOGGLES.setFeatureToggles(serverResponse);

if (!serverResponse.hasOwnProperty('body')) {
return bids;
}

const responseBody = serverResponse.body;
const seatbid = responseBody.seatbid;
const seatbid = responseBody.seatbid || [];

for (let i = 0; i < seatbid.length; i++) {
if (!seatbid[i].hasOwnProperty('bid')) {
continue;
Expand Down Expand Up @@ -1837,8 +1867,28 @@ export const spec = {
}
}

FEATURE_TOGGLES.setFeatureToggles(serverResponse);
return bids;
if (Array.isArray(fledgeAuctionConfigs) && fledgeAuctionConfigs.length > 0) {
// Validate and filter fledgeAuctionConfigs
fledgeAuctionConfigs = fledgeAuctionConfigs.filter(config => {
if (!isValidAuctionConfig(config)) {
logWarn('Malformed auction config detected:', config);
return false;
}
return true;
});

try {
return {
bids,
fledgeAuctionConfigs,
};
} catch (error) {
logWarn('Error attaching AuctionConfigs', error);
return bids;
}
} else {
return bids;
}
},

/**
Expand Down Expand Up @@ -2059,6 +2109,15 @@ function getFormatCount(imp) {
return formatCount;
}

/**
* Checks if auction config is valid
* @param {object} config
* @returns bool
*/
function isValidAuctionConfig(config) {
return typeof config === 'object' && config !== null;
}

/**
* Adds device.w / device.h info
* @param {object} r
Expand Down
5 changes: 5 additions & 0 deletions modules/ixBidAdapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,11 @@ pbjs.setConfig({

The timeout value must be a positive whole number in milliseconds.

Protected Audience API (FLEDGE)
===========================

In order to enable receiving [Protected Audience API](https://developer.chrome.com/en/docs/privacy-sandbox/fledge/) traffic, follow Prebid's documentation on [fledgeForGpt](https://docs.prebid.org/dev-docs/modules/fledgeForGpt.html) module to build and enable Fledge.

Additional Information
======================

Expand Down
Loading

0 comments on commit 3396f47

Please sign in to comment.