diff --git a/modules/pulsepointBidAdapter.js b/modules/pulsepointBidAdapter.js index 52931be0078..25f82fb60d9 100644 --- a/modules/pulsepointBidAdapter.js +++ b/modules/pulsepointBidAdapter.js @@ -153,6 +153,8 @@ function bidResponseAvailable(request, response) { * Produces an OpenRTBImpression from a slot config. */ function impression(slot) { + var firstPartyData = slot.ortb2Imp?.ext || {}; + var ext = Object.assign({}, firstPartyData, slotUnknownParams(slot)); return { id: slot.bidId, banner: banner(slot), @@ -160,7 +162,7 @@ function impression(slot) { tagid: slot.params.ct.toString(), video: video(slot), bidfloor: bidFloor(slot), - ext: ext(slot), + ext: Object.keys(ext).length > 0 ? ext : null, }; } @@ -209,7 +211,7 @@ function video(slot) { /** * Unknown params are captured and sent on ext */ -function ext(slot) { +function slotUnknownParams(slot) { const ext = {}; const knownParamsMap = {}; KNOWN_PARAMS.forEach(value => knownParamsMap[value] = 1); @@ -330,14 +332,16 @@ function site(bidRequests, bidderRequest) { const pubId = bidRequests && bidRequests.length > 0 ? bidRequests[0].params.cp : '0'; const appParams = bidRequests[0].params.app; if (!appParams) { - return { + // use the first party data if available, and override only publisher/ref/page properties + var firstPartyData = bidderRequest?.ortb2?.site || {}; + return Object.assign({}, firstPartyData, { publisher: { id: pubId.toString(), }, // TODO: does the fallback make sense here? ref: bidderRequest?.refererInfo?.ref || window.document.referrer, page: bidderRequest?.refererInfo?.page || '' - } + }); } return null; } @@ -406,7 +410,8 @@ function adSize(slot, sizes) { * an openrtb User object. */ function user(bidRequest, bidderRequest) { - var ext = {}; + var user = bidderRequest?.ortb2?.user || { ext: {} }; + var ext = user.ext; if (bidderRequest) { if (bidderRequest.gdprConsent) { ext.consent = bidderRequest.gdprConsent.consentString; @@ -418,7 +423,7 @@ function user(bidRequest, bidderRequest) { ext.eids = eids; } } - return { ext }; + return user; } /** diff --git a/test/spec/modules/pulsepointBidAdapter_spec.js b/test/spec/modules/pulsepointBidAdapter_spec.js index 4426c91e1ec..825b3abf432 100644 --- a/test/spec/modules/pulsepointBidAdapter_spec.js +++ b/test/spec/modules/pulsepointBidAdapter_spec.js @@ -795,4 +795,127 @@ describe('PulsePoint Adapter Tests', function () { expect(ortbRequest.imp[0].video.minbitrate).to.equal(200); expect(ortbRequest.imp[0].video.protocols).to.eql([1, 2, 4]); }); + it('Verify user level first party data', function () { + const bidderRequest = { + refererInfo: { + page: 'https://publisher.com/home', + ref: 'https://referrer' + }, + gdprConsent: { + gdprApplies: true, + consentString: 'serialized_gpdr_data' + }, + ortb2: { + user: { + yob: 1985, + gender: 'm', + ext: { + data: { + registered: true, + interests: ['cars'] + } + } + } + } + }; + let request = spec.buildRequests(slotConfigs, bidderRequest); + let ortbRequest = request.data; + expect(ortbRequest).to.not.equal(null); + expect(ortbRequest.user).to.not.equal(null); + expect(ortbRequest.user).to.deep.equal({ + yob: 1985, + gender: 'm', + ext: { + data: { + registered: true, + interests: ['cars'] + }, + consent: 'serialized_gpdr_data' + } + }); + }); + it('Verify site level first party data', function () { + const bidderRequest = { + refererInfo: { + page: 'https://publisher.com/home', + ref: 'https://referrer' + }, + ortb2: { + site: { + content: { + data: [{ + name: 'www.iris.com', + ext: { + segtax: 500, + cids: ['iris_c73g5jq96mwso4d8'] + } + }] + }, + page: 'http://pub.com/news', + ref: 'http://google.com' + } + } + }; + let request = spec.buildRequests(slotConfigs, bidderRequest); + let ortbRequest = request.data; + expect(ortbRequest).to.not.equal(null); + expect(ortbRequest.site).to.not.equal(null); + expect(ortbRequest.site).to.deep.equal({ + content: { + data: [{ + name: 'www.iris.com', + ext: { + segtax: 500, + cids: ['iris_c73g5jq96mwso4d8'] + } + }] + }, + page: 'https://publisher.com/home', + ref: 'https://referrer', + publisher: { + id: 'p10000' + } + }); + }); + it('Verify impression/slot level first party data', function () { + const bidderRequests = [{ + placementCode: '/DfpAccount1/slot1', + mediaTypes: { + banner: { + sizes: [[1, 1]] + } + }, + bidId: 'bid12345', + params: { + cp: 'p10000', + ct: 't10000', + extra_key1: 'extra_val1', + extra_key2: 12345 + }, + ortb2Imp: { + ext: { + data: { + pbadslot: 'homepage-top-rect', + adUnitSpecificAttribute: '123' + } + } + } + }]; + let request = spec.buildRequests(bidderRequests, bidderRequest); + let ortbRequest = request.data; + expect(ortbRequest).to.not.equal(null); + expect(ortbRequest.imp).to.not.equal(null); + expect(ortbRequest.imp).to.have.lengthOf(1); + expect(ortbRequest.imp[0].ext).to.not.equal(null); + expect(ortbRequest.imp[0].ext).to.deep.equal({ + prebid: { + extra_key1: 'extra_val1', + extra_key2: 12345 + }, + data: { + pbadslot: 'homepage-top-rect', + adUnitSpecificAttribute: '123' + } + }); + }); });