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

Extend Mode #11

Merged
merged 23 commits into from
May 10, 2022
Merged
Show file tree
Hide file tree
Changes from 3 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
88 changes: 71 additions & 17 deletions modules/improvedigitalBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,18 @@ import {Renderer} from '../src/Renderer.js';
import {createEidsArray} from './userId/eids.js';

const BIDDER_CODE = 'improvedigital';
const REQUEST_URL = 'https://ad.360yield.com/pb';
const CREATIVE_TTL = 300;

const REQUEST = {
PB_URL: 'https://ad.360yield.com/pb',
PBS_URL: 'https://pbs.360yield.com/openrtb2/auction',
PBS_SYNC_URL: 'https://localhost:3001/load-cookie.html?endpoint=improvedigital&gdpr=$$GDPR$$&gdpr_consent=$$GDPR_CONSENT$$',
getUrl(pbs = false) {
return pbs ? this.PBS_URL : this.PB_URL;
},
BIDDER_REQUEST: [],
};

const VIDEO_PARAMS = {
DEFAULT_MIMES: ['video/mp4'],
SUPPORTED_PROPERTIES: ['mimes', 'minduration', 'maxduration', 'protocols', 'w', 'h', 'startdelay', 'placement', 'linearity', 'skip', 'skipmin',
Expand Down Expand Up @@ -86,7 +95,8 @@ export const spec = {
version: '$prebid.version$',
}
}
}
},
test: 1
};

// Device
Expand Down Expand Up @@ -145,6 +155,8 @@ export const spec = {
deepSetValue(request, 'user.ext.eids', eids.length ? eids : undefined);
}

REQUEST.BIDDER_REQUEST.push(bidderRequest);

return ID_REQUEST.buildServerRequests(request, bidRequests, bidderRequest);
},

Expand Down Expand Up @@ -177,11 +189,11 @@ export const spec = {
cpm: bidObject.price,
creativeId: bidObject.crid,
currency: serverResponse.body.cur.toUpperCase() || 'USD',
dealId: (typeof idExt.buying_type === 'string' && idExt.buying_type !== 'rtb') ? idExt.line_item_id : undefined,
dealId: (idExt && typeof idExt.buying_type === 'string' && idExt.buying_type !== 'rtb') ? idExt.line_item_id : undefined,
meta: {
advertiserDomains: bidObject.adomain ? bidObject.adomain : []
},
netRevenue: idExt.is_net || false,
netRevenue: idExt && idExt.is_net || false,
faisalvs marked this conversation as resolved.
Show resolved Hide resolved
ttl: CREATIVE_TTL
}

Expand All @@ -206,7 +218,7 @@ export const spec = {
* @param {ServerResponse[]} serverResponses List of server's responses.
* @return {UserSync[]} The user syncs which should be dropped.
*/
getUserSyncs(syncOptions, serverResponses) {
getUserSyncs(syncOptions, serverResponses, gdprConsent) {
if (syncOptions.pixelEnabled) {
const syncs = [];
serverResponses.forEach(response => {
Expand All @@ -216,8 +228,37 @@ export const spec = {
syncs.push(syncElement);
}
});
// FOR PBS MODE
const seatBids = deepAccess(response, 'body.seatbid', []);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic is wrong for several reasons:

  1. It only syncs when there's a bid from Improve. We should also sync when there's no bid.
  2. It relies on a bid impid - syncs are separated and independent from any particular request
  3. This is iframe sync and runs from the "if pixelEnabled"
  4. It doesn't check that iframe syncs are actually enabled

The logic should be like this: if pbs mode == true and iframe enabled => run iframe sync. else if pixelenabled, run the non-PBS logic.
You can store pbs mode value in buildRequests in a syncStore like bluebilly has it. It is enough if one ad unit has pbs enable to set pbs=true in the syncStore.

if (Array.isArray(seatBids)) {
seatBids.forEach(seatbid => {
seatbid.bid.forEach(bid => {
if (bid.adm && bid.price && !bid.hasOwnProperty('errorCode')) {
const bidRequest = getBidRequest(bid.impid, REQUEST.BIDDER_REQUEST);
const pbsConfig = ID_REQUEST.pbsConfig(bidRequest.params);
if (pbsConfig.pbs) {
syncs.push({
type: 'iframe',
url: REQUEST.PBS_SYNC_URL
.replace('$$GDPR$$', ID_UTIL.toBit(gdprConsent.gdprApplies))
.replace('$$GDPR_CONSENT$$', gdprConsent.consentString)
,
});
}
}
})
})
}
});
return syncs.map(sync => {
if (typeof sync === 'object' && sync.type && sync.url) {
return {
type: sync.type,
url: sync.url,
}
}
return { type: 'image', url: sync }
});
return syncs.map(sync => ({ type: 'image', url: sync }));
}
return [];
}
Expand All @@ -229,31 +270,40 @@ const ID_REQUEST = {
buildServerRequests(requestObject, bidRequests, bidderRequest) {
const requests = [];
if (config.getConfig('improvedigital.singleRequest') === true) {
requestObject.imp = bidRequests.map((bidRequest) => this.buildImp(bidRequest));
requests[0] = this.formatRequest(requestObject, bidderRequest);
const pbsConfig = this.pbsConfig();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pbsConfig method is redundant. It's not an object, we just need a simple pbs boolean and pass this boolean as param to other methods. Why would we need an object here after the publisherId was removed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Overriding the global PBS mode from ad-unit param. Let me know your feedback.

requestObject.imp = bidRequests.map((bidRequest) => this.buildImp(bidRequest, pbsConfig));
requests[0] = this.formatRequest(requestObject, bidderRequest, pbsConfig);
} else {
bidRequests.map((bidRequest) => {
const request = deepClone(requestObject);
const pbsConfig = this.pbsConfig(bidRequest.params);
request.id = bidRequest.bidId || getUniqueIdentifierStr();
request.imp = [this.buildImp(bidRequest)];
request.imp = [this.buildImp(bidRequest, pbsConfig)];
deepSetValue(request, 'source.tid', bidRequest.transactionId);
requests.push(this.formatRequest(request, bidderRequest));
requests.push(this.formatRequest(request, bidderRequest, pbsConfig));
});
}

return requests;
},

formatRequest(request, bidderRequest) {
formatRequest(request, bidderRequest, pbsConfig) {
return {
method: 'POST',
url: REQUEST_URL,
url: REQUEST.getUrl(pbsConfig.pbs),
data: JSON.stringify(request),
bidderRequest
}
},

buildImp(bidRequest) {
pbsConfig(bidParams = {}) {
return mergeDeep({}, {
pbs: config.getConfig('improvedigital.pbs') === true,
}, bidParams)
},

buildImp(bidRequest, pbsConfig) {
const bidderCode = pbsConfig.pbs ? 'ext.prebid.bidder.improvedigital' : 'ext.bidder';
const imp = {
id: getBidIdParameter('bidId', bidRequest) || getUniqueIdentifierStr(),
secure: ID_UTIL.toBit(window.location.protocol === 'https:'),
Expand All @@ -269,13 +319,17 @@ const ID_REQUEST = {

const placementId = getBidIdParameter('placementId', bidRequest.params);
if (placementId) {
deepSetValue(imp, 'ext.bidder.placementId', placementId);
deepSetValue(imp, bidderCode + '.placementId', placementId);
// When PBS Mode Enabled
if (pbsConfig.pbs) {
deepSetValue(imp, 'ext.prebid.storedrequest.id', placementId);
}
} else {
deepSetValue(imp, 'ext.bidder.publisherId', getBidIdParameter('publisherId', bidRequest.params));
deepSetValue(imp, 'ext.bidder.placementKey', getBidIdParameter('placementKey', bidRequest.params));
deepSetValue(imp, bidderCode + '.publisherId', getBidIdParameter('publisherId', bidRequest.params));
deepSetValue(imp, bidderCode + '.placementKey', getBidIdParameter('placementKey', bidRequest.params));
}

deepSetValue(imp, 'ext.bidder.keyValues', getBidIdParameter('keyValues', bidRequest.params) || undefined);
deepSetValue(imp, bidderCode + '.keyValues', getBidIdParameter('keyValues', bidRequest.params) || undefined);

// Adding GPID
const gpid = deepAccess(bidRequest, 'ortb2Imp.ext.gpid') ||
Expand Down
69 changes: 55 additions & 14 deletions test/spec/modules/improvedigitalBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {BANNER, VIDEO} from '../../../src/mediaTypes';
describe('Improve Digital Adapter Tests', function () {
const METHOD = 'POST';
const URL = 'https://ad.360yield.com/pb';
const PBS_URL = 'https://pbs.360yield.com/openrtb2/auction';
const INSTREAM_TYPE = 1;
const OUTSTREAM_TYPE = 3;

Expand Down Expand Up @@ -238,20 +239,6 @@ describe('Improve Digital Adapter Tests', function () {
expect(payload.imp[0].ext.bidder.keyValues).to.deep.equal(keyValues);
});

// it('should add single size filter', function () {
// const bidRequest = Object.assign({}, simpleBidRequest);
// const size = {
// w: 800,
// h: 600
// };
// bidRequest.params.size = size;
// const payload = JSON.parse(spec.buildRequests([bidRequest], bidderRequest).data);
// expect(payload.imp[0].banner).to.deep.equal(size);
// // When single size filter is set, format shouldn't be populated. This
// // is to maintain backward compatibily
// expect(payload.imp[0].banner.format).to.not.exist;
// });

it('should add currency', function () {
const bidRequest = Object.assign({}, simpleBidRequest);
const getConfigStub = sinon.stub(config, 'getConfig').returns('JPY');
Expand Down Expand Up @@ -646,6 +633,60 @@ describe('Improve Digital Adapter Tests', function () {
expect(payload.app).does.not.exist;
getConfigStub.restore();
});

it('should set PBS_URL when pbs mode enabled from configure', function () {
const getConfigStub = sinon.stub(config, 'getConfig');
getConfigStub.withArgs('improvedigital.pbs').returns(true);
const request = spec.buildRequests([simpleBidRequest], bidderRequest)[0];
expect(request.method).to.equal(METHOD);
expect(request.url).to.equal(PBS_URL);
expect(request.bidderRequest).to.deep.equal(bidderRequest);
const payload = JSON.parse(request.data);
expect(payload).to.be.an('object');
expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal(1053688);
getConfigStub.restore();
});

it('should set PBS_URL when pbs mode enabled from params', function () {
const bidRequest = JSON.parse(JSON.stringify(simpleBidRequest));
bidRequest.params.pbs = true;
const request = spec.buildRequests([bidRequest], bidderRequest)[0];
expect(request.method).to.equal(METHOD);
expect(request.url).to.equal(PBS_URL);
expect(request.bidderRequest).to.deep.equal(bidderRequest);
const payload = JSON.parse(request.data);
expect(payload).to.be.an('object');
expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal(1053688);
});

it('should not set PBS_URL when pbs mode disabled from params', function () {
const getConfigStub = sinon.stub(config, 'getConfig');
getConfigStub.withArgs('improvedigital.pbs').returns(true);
const bidRequest = JSON.parse(JSON.stringify(simpleBidRequest));
bidRequest.params.pbs = false;
const request = spec.buildRequests([bidRequest], bidderRequest)[0];
expect(request.method).to.equal(METHOD);
expect(request.url).to.equal(URL);
expect(request.bidderRequest).to.deep.equal(bidderRequest);
const payload = JSON.parse(request.data);
expect(payload).to.be.an('object');
getConfigStub.restore();
});

it('should set PBS_URL when pbs mode enabled from params and disabled from config', function () {
const getConfigStub = sinon.stub(config, 'getConfig');
getConfigStub.withArgs('improvedigital.pbs').returns(false);
const bidRequest = JSON.parse(JSON.stringify(simpleBidRequest));
bidRequest.params.pbs = true;
const request = spec.buildRequests([bidRequest], bidderRequest)[0];
expect(request.method).to.equal(METHOD);
expect(request.url).to.equal(PBS_URL);
expect(request.bidderRequest).to.deep.equal(bidderRequest);
const payload = JSON.parse(request.data);
expect(payload).to.be.an('object');
expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal(1053688);
getConfigStub.restore();
});
});

const serverResponse = {
Expand Down