From 0371d3e1342f067eaf0cf92d7b7352f0fc56d888 Mon Sep 17 00:00:00 2001 From: Alexander Date: Tue, 8 Jun 2021 22:51:48 +0400 Subject: [PATCH 1/4] Add adomains/userIds support and change banner ad type priority --- modules/radsBidAdapter.js | 24 +++++++++++++++++++++--- test/spec/modules/radsBidAdapter_spec.js | 22 ++++++++++++++++------ 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/modules/radsBidAdapter.js b/modules/radsBidAdapter.js index 8f3cbe02f23..af6fc4277cb 100644 --- a/modules/radsBidAdapter.js +++ b/modules/radsBidAdapter.js @@ -57,7 +57,7 @@ export const spec = { bid_id: bidId, }; } - prepareExtraParams(params, payload, bidderRequest); + prepareExtraParams(params, payload, bidderRequest, bidRequest); return { method: 'GET', @@ -84,7 +84,10 @@ export const spec = { dealId: dealId, currency: currency, netRevenue: netRevenue, - ttl: config.getConfig('_bidderTimeout') + ttl: config.getConfig('_bidderTimeout'), + meta: { + advertiserDomains: response.adomain || [] + } }; if (response.vastXml) { @@ -162,7 +165,15 @@ function isVideoRequest(bid) { return bid.mediaType === 'video' || !!utils.deepAccess(bid, 'mediaTypes.video'); } -function prepareExtraParams(params, payload, bidderRequest) { +/** + * Add extra params to server request + * + * @param params + * @param payload + * @param bidderRequest + * @param {BidRequest} bidRequest - Bid request generated from ad slots + */ +function prepareExtraParams(params, payload, bidderRequest, bidRequest) { if (params.pfilter !== undefined) { payload.pfilter = params.pfilter; } @@ -196,6 +207,13 @@ function prepareExtraParams(params, payload, bidderRequest) { if (params.ip !== undefined) { payload.i = params.ip; } + + if (bidRequest.userId && bidRequest.userId.netId) { + payload.did_netid = bidRequest.userId.netId; + } + if (bidRequest.userId && bidRequest.userId.uid2) { + payload.did_uid2 = bidRequest.userId.uid2; + } } registerBidder(spec); diff --git a/test/spec/modules/radsBidAdapter_spec.js b/test/spec/modules/radsBidAdapter_spec.js index c3c3b4b2746..5f2fafe4d67 100644 --- a/test/spec/modules/radsBidAdapter_spec.js +++ b/test/spec/modules/radsBidAdapter_spec.js @@ -61,7 +61,11 @@ describe('radsAdapter', function () { ], 'bidId': '30b31c1838de1e', 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' + 'auctionId': '1d1a030790a475', + 'userId': { + 'netId': '123', + 'uid2': '456' + } }, { 'bidder': 'rads', 'params': { @@ -110,7 +114,7 @@ describe('radsAdapter', function () { it('sends bid request to our endpoint via GET', function () { expect(request[0].method).to.equal('GET'); let data = request[0].data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); - expect(data).to.equal('rt=bid-response&_f=prebid_js&_ps=6682&srw=300&srh=250&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&bcat=IAB2%2CIAB4&dvt=desktop&i=1.1.1.1'); + expect(data).to.equal('rt=bid-response&_f=prebid_js&_ps=6682&srw=300&srh=250&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&bcat=IAB2%2CIAB4&dvt=desktop&i=1.1.1.1&did_netid=123&did_uid2=456'); }); it('sends bid video request to our rads endpoint via GET', function () { @@ -124,7 +128,7 @@ describe('radsAdapter', function () { it('sends bid request to our endpoint via GET', function () { expect(request2[0].method).to.equal('GET'); let data = request2[0].data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); - expect(data).to.equal('rt=bid-response&_f=prebid_js&_ps=6682&srw=300&srh=250&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgdpr_consent%5D=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&pfilter%5Bgdpr%5D=true&bcat=IAB2%2CIAB4&dvt=desktop&i=1.1.1.1'); + expect(data).to.equal('rt=bid-response&_f=prebid_js&_ps=6682&srw=300&srh=250&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgdpr_consent%5D=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&pfilter%5Bgdpr%5D=true&bcat=IAB2%2CIAB4&dvt=desktop&i=1.1.1.1&did_netid=123&did_uid2=456'); }); it('sends bid video request to our rads endpoint via GET', function () { @@ -146,7 +150,8 @@ describe('radsAdapter', function () { 'currency': 'EUR', 'ttl': 60, 'netRevenue': true, - 'zone': '6682' + 'zone': '6682', + 'adomain': ['bdomain'] } }; let serverVideoResponse = { @@ -174,7 +179,8 @@ describe('radsAdapter', function () { currency: 'EUR', netRevenue: true, ttl: 300, - ad: '' + ad: '', + meta: {advertiserDomains: ['bdomain']} }, { requestId: '23beaa6af6cdde', cpm: 0.5, @@ -186,7 +192,8 @@ describe('radsAdapter', function () { netRevenue: true, ttl: 300, vastXml: '{"reason":7001,"status":"accepted"}', - mediaType: 'video' + mediaType: 'video', + meta: {advertiserDomains: []} }]; it('should get the correct bid response by display ad', function () { @@ -202,6 +209,8 @@ describe('radsAdapter', function () { }]; let result = spec.interpretResponse(serverBannerResponse, bidRequest[0]); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); + expect(result[0].meta.advertiserDomains.length).to.equal(1); + expect(result[0].meta.advertiserDomains[0]).to.equal(expectedResponse[0].meta.advertiserDomains[0]); }); it('should get the correct rads video bid response by display ad', function () { @@ -220,6 +229,7 @@ describe('radsAdapter', function () { }]; let result = spec.interpretResponse(serverVideoResponse, bidRequest[0]); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[1])); + expect(result[0].meta.advertiserDomains.length).to.equal(0); }); it('handles empty bid response', function () { From e6b37937eb3a051aa4ea1b7970474cee888065d7 Mon Sep 17 00:00:00 2001 From: Alexander Date: Tue, 8 Jun 2021 23:04:21 +0400 Subject: [PATCH 2/4] Add adomains/userIds support and change banner ad type priority --- modules/radsBidAdapter.js | 96 ++++++++++++++++++------ test/spec/modules/radsBidAdapter_spec.js | 11 +++ 2 files changed, 85 insertions(+), 22 deletions(-) diff --git a/modules/radsBidAdapter.js b/modules/radsBidAdapter.js index af6fc4277cb..2ec96d11915 100644 --- a/modules/radsBidAdapter.js +++ b/modules/radsBidAdapter.js @@ -18,9 +18,6 @@ export const spec = { buildRequests: function(validBidRequests, bidderRequest) { return validBidRequests.map(bidRequest => { const params = bidRequest.params; - const videoData = utils.deepAccess(bidRequest, 'mediaTypes.video') || {}; - const sizes = utils.parseSizesInput(videoData.playerSize || bidRequest.sizes)[0]; - const [width, height] = sizes.split('x'); const placementId = params.placement; const rnd = Math.floor(Math.random() * 99999999999); @@ -31,26 +28,28 @@ export const spec = { let endpoint = isDev ? ENDPOINT_URL_DEV : ENDPOINT_URL; let payload = {}; - if (isVideoRequest(bidRequest)) { - let vastFormat = params.vastFormat || DEFAULT_VAST_FORMAT; + if (isBannerRequest(bidRequest)) { + let size = getBannerSizes(bidRequest)[0]; payload = { - rt: vastFormat, + rt: 'bid-response', _f: 'prebid_js', _ps: placementId, - srw: width, - srh: height, + srw: size.width, + srh: size.height, idt: 100, rnd: rnd, p: referrer, bid_id: bidId, }; } else { + let vastFormat = params.vastFormat || DEFAULT_VAST_FORMAT; + let size = getVideoSizes(bidRequest)[0]; payload = { - rt: 'bid-response', + rt: vastFormat, _f: 'prebid_js', _ps: placementId, - srw: width, - srh: height, + srw: size.width, + srh: size.height, idt: 100, rnd: rnd, p: referrer, @@ -154,17 +153,6 @@ function objectToQueryString(obj, prefix) { } return str.join('&'); } - -/** - * Check if it's a video bid request - * - * @param {BidRequest} bid - Bid request generated from ad slots - * @returns {boolean} True if it's a video bid - */ -function isVideoRequest(bid) { - return bid.mediaType === 'video' || !!utils.deepAccess(bid, 'mediaTypes.video'); -} - /** * Add extra params to server request * @@ -216,4 +204,68 @@ function prepareExtraParams(params, payload, bidderRequest, bidRequest) { } } +/** + * Check if it's a banner bid request + * + * @param {BidRequest} bid - Bid request generated from ad slots + * @returns {boolean} True if it's a banner bid + */ +function isBannerRequest(bid) { + return bid.mediaType === 'banner' || !!utils.deepAccess(bid, 'mediaTypes.banner') || !isVideoRequest(bid); +} + +/** + * Check if it's a video bid request + * + * @param {BidRequest} bid - Bid request generated from ad slots + * @returns {boolean} True if it's a video bid + */ +function isVideoRequest(bid) { + return bid.mediaType === 'video' || !!utils.deepAccess(bid, 'mediaTypes.video'); +} + +/** + * Get video sizes + * + * @param {BidRequest} bid - Bid request generated from ad slots + * @returns {object} True if it's a video bid + */ +function getVideoSizes(bid) { + return parseSizes(utils.deepAccess(bid, 'mediaTypes.video.playerSize') || bid.sizes); +} + +/** + * Get banner sizes + * + * @param {BidRequest} bid - Bid request generated from ad slots + * @returns {object} True if it's a video bid + */ +function getBannerSizes(bid) { + return parseSizes(utils.deepAccess(bid, 'mediaTypes.banner.sizes') || bid.sizes); +} + +/** + * Parse size + * @param sizes + * @returns {width: number, h: height} + */ +function parseSize(size) { + let sizeObj = {} + sizeObj.width = parseInt(size[0], 10); + sizeObj.height = parseInt(size[1], 10); + return sizeObj; +} + +/** + * Parse sizes + * @param sizes + * @returns {{width: number , height: number }[]} + */ +function parseSizes(sizes) { + if (Array.isArray(sizes[0])) { // is there several sizes ? (ie. [[728,90],[200,300]]) + return sizes.map(size => parseSize(size)); + } + return [parseSize(sizes)]; // or a single one ? (ie. [728,90]) +} + registerBidder(spec); diff --git a/test/spec/modules/radsBidAdapter_spec.js b/test/spec/modules/radsBidAdapter_spec.js index 5f2fafe4d67..13e912d6583 100644 --- a/test/spec/modules/radsBidAdapter_spec.js +++ b/test/spec/modules/radsBidAdapter_spec.js @@ -59,6 +59,17 @@ describe('radsAdapter', function () { 'sizes': [ [300, 250] ], + 'mediaTypes': { + 'video': { + 'playerSize': [640, 480], + 'context': 'instream' + }, + 'banner': { + 'sizes': [ + [300, 250] + ] + } + }, 'bidId': '30b31c1838de1e', 'bidderRequestId': '22edbae2733bf6', 'auctionId': '1d1a030790a475', From f7fc7e9aea76c635609c7d1b90f2a5febd82a17f Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 9 Jun 2021 21:38:26 +0400 Subject: [PATCH 3/4] Set GVLID --- modules/radsBidAdapter.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/radsBidAdapter.js b/modules/radsBidAdapter.js index 2ec96d11915..95284309cc1 100644 --- a/modules/radsBidAdapter.js +++ b/modules/radsBidAdapter.js @@ -7,9 +7,11 @@ const BIDDER_CODE = 'rads'; const ENDPOINT_URL = 'https://rads.recognified.net/md.request.php'; const ENDPOINT_URL_DEV = 'https://dcradn1.online-solution.biz/md.request.php'; const DEFAULT_VAST_FORMAT = 'vast2'; +const GVLID = 602; export const spec = { code: BIDDER_CODE, + gvlid: GVLID, aliases: ['rads'], supportedMediaTypes: [BANNER, VIDEO], isBidRequestValid: function(bid) { From 8e068159b0d1a7bef9bbf3fad5595a951649188e Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 18 Jun 2021 23:57:28 +0400 Subject: [PATCH 4/4] Add changes after review --- modules/radsBidAdapter.js | 53 ++++++++++++------------ modules/radsBidAdapter.md | 1 + test/spec/modules/radsBidAdapter_spec.js | 12 +++--- 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/modules/radsBidAdapter.js b/modules/radsBidAdapter.js index 95284309cc1..2db42802067 100644 --- a/modules/radsBidAdapter.js +++ b/modules/radsBidAdapter.js @@ -12,7 +12,7 @@ const GVLID = 602; export const spec = { code: BIDDER_CODE, gvlid: GVLID, - aliases: ['rads'], + aliases: [], supportedMediaTypes: [BANNER, VIDEO], isBidRequestValid: function(bid) { return !!(bid.params.placement); @@ -29,35 +29,36 @@ export const spec = { let endpoint = isDev ? ENDPOINT_URL_DEV : ENDPOINT_URL; - let payload = {}; + let payload = { + _f: 'prebid_js', + _ps: placementId, + idt: 100, + rnd: rnd, + p: referrer, + bid_id: bidId, + }; + + let sizes; if (isBannerRequest(bidRequest)) { - let size = getBannerSizes(bidRequest)[0]; - payload = { - rt: 'bid-response', - _f: 'prebid_js', - _ps: placementId, - srw: size.width, - srh: size.height, - idt: 100, - rnd: rnd, - p: referrer, - bid_id: bidId, - }; + sizes = getBannerSizes(bidRequest); + payload.rt = 'bid-response'; + payload.srw = sizes[0].width; + payload.srh = sizes[0].height; } else { let vastFormat = params.vastFormat || DEFAULT_VAST_FORMAT; - let size = getVideoSizes(bidRequest)[0]; - payload = { - rt: vastFormat, - _f: 'prebid_js', - _ps: placementId, - srw: size.width, - srh: size.height, - idt: 100, - rnd: rnd, - p: referrer, - bid_id: bidId, - }; + sizes = getVideoSizes(bidRequest); + payload.rt = vastFormat; + payload.srw = sizes[0].width; + payload.srh = sizes[0].height; + } + + if (sizes.length > 1) { + payload.alt_ad_sizes = []; + for (let i = 1; i < sizes.length; i++) { + payload.alt_ad_sizes.push(sizes[i].width + 'x' + sizes[i].height); + } } + prepareExtraParams(params, payload, bidderRequest, bidRequest); return { diff --git a/modules/radsBidAdapter.md b/modules/radsBidAdapter.md index 6e970093154..a00b82e20cb 100644 --- a/modules/radsBidAdapter.md +++ b/modules/radsBidAdapter.md @@ -25,6 +25,7 @@ RADS Bidder Adapter for Prebid.js 1.x bidder: "rads", params: { placement: 3, // placement ID + vastFormat: "vast2", // vast2(default) or vast4 devMode: true // if true: library uses dev server for tests } } diff --git a/test/spec/modules/radsBidAdapter_spec.js b/test/spec/modules/radsBidAdapter_spec.js index 13e912d6583..019108fce9d 100644 --- a/test/spec/modules/radsBidAdapter_spec.js +++ b/test/spec/modules/radsBidAdapter_spec.js @@ -66,7 +66,7 @@ describe('radsAdapter', function () { }, 'banner': { 'sizes': [ - [300, 250] + [100, 100], [400, 400], [500, 500] ] } }, @@ -93,7 +93,7 @@ describe('radsAdapter', function () { }, 'mediaTypes': { 'video': { - 'playerSize': [640, 480], + 'playerSize': [[640, 480], [500, 500], [600, 600]], 'context': 'instream' } }, @@ -125,13 +125,13 @@ describe('radsAdapter', function () { it('sends bid request to our endpoint via GET', function () { expect(request[0].method).to.equal('GET'); let data = request[0].data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); - expect(data).to.equal('rt=bid-response&_f=prebid_js&_ps=6682&srw=300&srh=250&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&bcat=IAB2%2CIAB4&dvt=desktop&i=1.1.1.1&did_netid=123&did_uid2=456'); + expect(data).to.equal('_f=prebid_js&_ps=6682&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&rt=bid-response&srw=100&srh=100&alt_ad_sizes%5B0%5D=400x400&alt_ad_sizes%5B1%5D=500x500&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&bcat=IAB2%2CIAB4&dvt=desktop&i=1.1.1.1&did_netid=123&did_uid2=456'); }); it('sends bid video request to our rads endpoint via GET', function () { expect(request[1].method).to.equal('GET'); let data = request[1].data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); - expect(data).to.equal('rt=vast2&_f=prebid_js&_ps=6682&srw=640&srh=480&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgeo%5D%5Bregion%5D=DE-BE&bcat=IAB2%2CIAB4&dvt=desktop'); + expect(data).to.equal('_f=prebid_js&_ps=6682&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&rt=vast2&srw=640&srh=480&alt_ad_sizes%5B0%5D=500x500&alt_ad_sizes%5B1%5D=600x600&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgeo%5D%5Bregion%5D=DE-BE&bcat=IAB2%2CIAB4&dvt=desktop'); }); // with gdprConsent @@ -139,13 +139,13 @@ describe('radsAdapter', function () { it('sends bid request to our endpoint via GET', function () { expect(request2[0].method).to.equal('GET'); let data = request2[0].data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); - expect(data).to.equal('rt=bid-response&_f=prebid_js&_ps=6682&srw=300&srh=250&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgdpr_consent%5D=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&pfilter%5Bgdpr%5D=true&bcat=IAB2%2CIAB4&dvt=desktop&i=1.1.1.1&did_netid=123&did_uid2=456'); + expect(data).to.equal('_f=prebid_js&_ps=6682&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&rt=bid-response&srw=100&srh=100&alt_ad_sizes%5B0%5D=400x400&alt_ad_sizes%5B1%5D=500x500&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgdpr_consent%5D=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&pfilter%5Bgdpr%5D=true&bcat=IAB2%2CIAB4&dvt=desktop&i=1.1.1.1&did_netid=123&did_uid2=456'); }); it('sends bid video request to our rads endpoint via GET', function () { expect(request2[1].method).to.equal('GET'); let data = request2[1].data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); - expect(data).to.equal('rt=vast2&_f=prebid_js&_ps=6682&srw=640&srh=480&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgeo%5D%5Bregion%5D=DE-BE&pfilter%5Bgdpr_consent%5D=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&pfilter%5Bgdpr%5D=true&bcat=IAB2%2CIAB4&dvt=desktop'); + expect(data).to.equal('_f=prebid_js&_ps=6682&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&rt=vast2&srw=640&srh=480&alt_ad_sizes%5B0%5D=500x500&alt_ad_sizes%5B1%5D=600x600&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgeo%5D%5Bregion%5D=DE-BE&pfilter%5Bgdpr_consent%5D=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&pfilter%5Bgdpr%5D=true&bcat=IAB2%2CIAB4&dvt=desktop'); }); });