Skip to content

Commit

Permalink
IX Bid Adapter: First Party Data Support (#7265)
Browse files Browse the repository at this point in the history
* pass fpd data to r object

* remove .repeat() func in tests

* check if r.site.page exists

* use config.getConfig('ortb2')

* use JSON.stringify to calculate fpd length

* explicitly calculate request size for fpd

* check for impressionObjects.length
  • Loading branch information
umakajan authored Aug 17, 2021
1 parent 51eb7d0 commit 07ab54d
Show file tree
Hide file tree
Showing 2 changed files with 195 additions and 2 deletions.
68 changes: 66 additions & 2 deletions modules/ixBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ const USER_SYNC_URL = 'https://js-sec.indexww.com/um/ixmatch.html';

const FLOOR_SOURCE = { PBJS: 'p', IX: 'x' };
// determines which eids we send and the rtiPartner field in ext

const FIRST_PARTY_DATA = {
SITE: [
'id', 'name', 'domain', 'cat', 'sectioncat', 'pagecat', 'page', 'ref', 'search', 'mobile',
'privacypolicy', 'publisher', 'content', 'keywords', 'ext'
],
USER: ['id', 'buyeruid', 'yob', 'gender', 'keywords', 'customdata', 'geo', 'data', 'ext']
};

const SOURCE_RTI_MAPPING = {
'liveramp.com': 'idl',
'netid.de': 'NETID',
Expand Down Expand Up @@ -566,6 +575,8 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
}

let currentRequestSize = baseRequestSize;
let fpdRequestSize = 0;
let isFpdAdded = false;

if (otherIxConfig) {
// Append firstPartyData to r.site.page if firstPartyData exists.
Expand All @@ -579,7 +590,18 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
}
firstPartyString = firstPartyString.slice(0, -1);

r.site.page += firstPartyString;
fpdRequestSize = encodeURIComponent(firstPartyString).length;

if (fpdRequestSize < MAX_REQUEST_SIZE) {
if ('page' in r.site) {
r.site.page += firstPartyString;
} else {
r.site.page = firstPartyString;
}
currentRequestSize += fpdRequestSize;
} else {
utils.logError('ix bidder: IX config FPD request size has exceeded maximum request size.');
}
}

// Create t in payload if timeout is configured.
Expand Down Expand Up @@ -617,7 +639,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
currentImpressionSize = encodeURIComponent(JSON.stringify({ impressionObjects })).length;
}

if (BANNER in impressionObjects[0]) {
if (impressionObjects.length && BANNER in impressionObjects[0]) {
const { id, banner: { topframe } } = impressionObjects[0];
const _bannerImpression = {
id,
Expand All @@ -642,6 +664,47 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
r.imp.push(...impressionObjects);
}

currentRequestSize += currentImpressionSize;

const fpd = config.getConfig('ortb2') || {};

if (!utils.isEmpty(fpd) && !isFpdAdded) {
r.ext.ixdiag.fpd = true;

const site = { ...(fpd.site || fpd.context) };

Object.keys(site).forEach(key => {
if (FIRST_PARTY_DATA.SITE.indexOf(key) === -1) {
delete site[key];
}
});

const user = { ...fpd.user };

Object.keys(user).forEach(key => {
if (FIRST_PARTY_DATA.USER.indexOf(key) === -1) {
delete user[key];
}
});

const clonedRObject = utils.deepClone(r);

clonedRObject.site = utils.mergeDeep({}, clonedRObject.site, site);
clonedRObject.user = utils.mergeDeep({}, clonedRObject.user, user);

const requestSize = `${baseUrl}${utils.parseQueryStringParameters({ ...payload, r: JSON.stringify(clonedRObject) })}`.length;

if (requestSize < MAX_REQUEST_SIZE) {
r.site = utils.mergeDeep({}, r.site, site);
r.user = utils.mergeDeep({}, r.user, user);
isFpdAdded = true;
const fpdRequestSize = encodeURIComponent(JSON.stringify({ ...site, ...user })).length;
currentRequestSize += fpdRequestSize;
} else {
utils.logError('ix bidder: FPD request size has exceeded maximum request size.');
}
}

const isLastAdUnit = adUnitIndex === transactionIds.length - 1;

if (wasAdUnitImpressionsTrimmed || isLastAdUnit) {
Expand All @@ -664,6 +727,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
r.imp = [];
r.ext.ixdiag.msd = 0;
r.ext.ixdiag.msi = 0;
isFpdAdded = false;
}
}

Expand Down
129 changes: 129 additions & 0 deletions test/spec/modules/ixBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,135 @@ describe('IndexexchangeAdapter', function () {
});
});

describe('First party data', function () {
afterEach(function() {
config.setConfig({
ortb2: {}
})
});

it('should not set ixdiag.fpd value if not defined', function () {
config.setConfig({
ortb2: {}
});

const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID)[0];
const r = JSON.parse(request.data.r);

expect(r.ext.ixdiag.fpd).to.be.undefined;
});

it('should set ixdiag.fpd value if it exists using fpd', function () {
config.setConfig({
fpd: {
site: {
data: {
pageType: 'article'
}
}
}
});

const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID)[0];
const r = JSON.parse(request.data.r);

expect(r.ext.ixdiag.fpd).to.exist;
});

it('should set ixdiag.fpd value if it exists using ortb2', function () {
config.setConfig({
ortb2: {
site: {
ext: {
data: {
pageType: 'article'
}
}
}
}
});

const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID)[0];
const r = JSON.parse(request.data.r);

expect(r.ext.ixdiag.fpd).to.exist;
});

it('should not send information that is not part of openRTB spec v2.5 using fpd', function () {
config.setConfig({
fpd: {
site: {
keywords: 'power tools, drills',
search: 'drill',
testProperty: 'test_string'
},
user: {
keywords: ['a'],
testProperty: 'test_string'
}
}
});

const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID)[0];
const r = JSON.parse(request.data.r);

expect(r.site.keywords).to.exist;
expect(r.site.search).to.exist;
expect(r.site.testProperty).to.be.undefined;
expect(r.user.keywords).to.exist;
expect(r.user.testProperty).to.be.undefined;
});

it('should not send information that is not part of openRTB spec v2.5 using ortb2', function () {
config.setConfig({
ortb2: {
site: {
keywords: 'power tools, drills',
search: 'drill',
testProperty: 'test_string'
},
user: {
keywords: ['a'],
testProperty: 'test_string'
}
}
});

const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID)[0];
const r = JSON.parse(request.data.r);

expect(r.site.keywords).to.exist;
expect(r.site.search).to.exist;
expect(r.site.testProperty).to.be.undefined;
expect(r.user.keywords).to.exist;
expect(r.user.testProperty).to.be.undefined;
});

it('should not add fpd data to r object if it exceeds maximum request', function () {
config.setConfig({
ortb2: {
site: {
keywords: 'power tools, drills',
search: 'drill',
},
user: {
keywords: Array(1000).join('#'),
}
}
});

const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]);
bid.mediaTypes.banner.sizes = LARGE_SET_OF_SIZES;

const request = spec.buildRequests([bid])[0];
const r = JSON.parse(request.data.r);

expect(r.site.ref).to.exist;
expect(r.site.keywords).to.be.undefined;
expect(r.user).to.be.undefined;
});
});

describe('buildRequests', function () {
let request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION)[0];
const requestUrl = request.url;
Expand Down

0 comments on commit 07ab54d

Please sign in to comment.