From c1a681485777102f08b750417c16c56f4be5b753 Mon Sep 17 00:00:00 2001 From: Mateusz Michalowski Date: Tue, 11 Dec 2018 13:20:33 +0100 Subject: [PATCH 1/9] Add Adhese adapter --- modules/adheseBidAdapter.js | 166 ++++++++++++ modules/adheseBidAdapter.md | 59 +++++ test/spec/modules/adheseBidAdapter_spec.js | 285 +++++++++++++++++++++ 3 files changed, 510 insertions(+) create mode 100644 modules/adheseBidAdapter.js create mode 100644 modules/adheseBidAdapter.md create mode 100644 test/spec/modules/adheseBidAdapter_spec.js diff --git a/modules/adheseBidAdapter.js b/modules/adheseBidAdapter.js new file mode 100644 index 00000000000..bb848cf33bc --- /dev/null +++ b/modules/adheseBidAdapter.js @@ -0,0 +1,166 @@ +'use strict'; + +import { registerBidder } from 'src/adapters/bidderFactory'; +import { BANNER, VIDEO } from 'src/mediaTypes'; + +const BIDDER_CODE = 'adhese'; +const USER_SYNC_BASE_URL = 'https://user-sync.adhese.com/iframe/user_sync.html'; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO], + + isBidRequestValid: function(bid) { + return !!(bid.params.account && bid.params.location && bid.params.format); + }, + + mergeTargets: function(targets, target) { + if (target) { + Object.keys(target).forEach(function (key) { + let val = target[key]; + let values = Array.isArray(val) ? val : [val]; + if (targets[key]) { + let distinctValues = values.filter(v => targets[key].indexOf(v) < 0); + targets[key].push.apply(targets[key], distinctValues); + } else { + targets[key] = values; + } + }); + } + return targets; + }, + + bidToSlotName: function(bid) { + return bid.params.location + '-' + bid.params.format; + }, + + getAccount: function(validBidRequests) { + return validBidRequests[0].params.account; + }, + + buildRequests: function(validBidRequests, bidderRequest) { + if (validBidRequests.length === 0) { + return null; + } + + let account = this.getAccount(validBidRequests); + let targets = validBidRequests.map(bid => bid.params.data).reduce(this.mergeTargets, {}); + let gdprParams = (bidderRequest.gdprConsent && bidderRequest.gdprConsent.consentString) ? [ 'xt' + bidderRequest.gdprConsent.consentString ] : []; + let targetsParams = Object.entries(targets).map(param => param[0] + param[1].join(';')); + let slotsParams = validBidRequests.map(bid => 'sl' + this.bidToSlotName(bid)); + let params = [...slotsParams, ...targetsParams, ...gdprParams].map(s => '/' + s).join(''); + let cacheBuster = '?t=' + new Date().getTime(); + let uri = 'https://ads-' + account + '.adhese.com/json' + params + cacheBuster; + + return { + method: 'GET', + url: uri, + bids: validBidRequests + }; + }, + + baseAdResponse: function(response) { + return Object.assign({ netRevenue: true, ttl: 360 }, response); + }, + + isAdheseAd: function(ad) { + return !ad.origin || ad.origin === 'JERLICIA'; + }, + + getMediaType: function(markup) { + let isVideo = markup.trim().toLowerCase().match(/<\?xml|"; + } + return bidResponse; + }, + + interpretResponse: function(serverResponse, request) { + let serverAds = serverResponse.body.reduce(function(map, ad) { + map[ad.slotName] = ad; + return map; + }, {}); + + serverResponse.account = this.getAccount(request.bids); + + return request.bids + .map(bid => ({ + bid: bid, + ad: serverAds[this.bidToSlotName(bid)] + })) + .filter(item => item.ad) + .map(item => this.adResponse(item.bid, item.ad)); + }, + + getUserSyncs: function(syncOptions, serverResponse, gdprConsent) { + const account = serverResponse.account || ''; + if (syncOptions.iframeEnabled) { + let syncurl = USER_SYNC_BASE_URL + '?account=' + account; + if (gdprConsent) { + syncurl += '&gdpr=' + (gdprConsent.gdprApplies ? 1 : 0); + syncurl += '&consentString=' + encodeURIComponent(gdprConsent.consentString || ''); + } + return [{ type: 'iframe', url: syncurl }]; + } + }, + + onTimeout: function(timeoutData) {}, +}; +registerBidder(spec); diff --git a/modules/adheseBidAdapter.md b/modules/adheseBidAdapter.md new file mode 100644 index 00000000000..977c3096a90 --- /dev/null +++ b/modules/adheseBidAdapter.md @@ -0,0 +1,59 @@ +# Overview + +``` +Module Name: Adhese Bidder Adapter +Module Type: Bidder Adapter +Maintainer: info@adhese.com +``` + +//TODO: + +# Description + +Module that connects to Example's demand sources + +# Test Parameters +``` + var adUnits = [ + { + code: 'test-div1', + mediaTypes: { + banner: { + sizes: [[300, 250]], // a display size + } + }, + bids: [ + { + bidder: "adhese", + params: { + account: 'demo', // required - the name of your adhese account, if unknown, please contact your sales rep + location: '_main_page_', // required - the location you want to refer to for a specific section or page, as defined in your Adhese inventory + format: 'middle', // required - the format you accept for this unit, as defined in your Adhese inventory + data: { // optional - target params, as defined in your Adhese setup + 'ci': ['gent', 'brussels'] + 'ag': ['55'] + 'tl': ['all'] + } + } + } + ] + },{ + code: 'test-div2', + mediaTypes: { + banner: { + sizes: [[320, 50]], // a mobile size + } + }, + bids: [ + { + bidder: "adhese", + params: { + account: 'demo', + location: '_main_page_', + format: 'middle' + } + } + ] + } + ]; +``` diff --git a/test/spec/modules/adheseBidAdapter_spec.js b/test/spec/modules/adheseBidAdapter_spec.js new file mode 100644 index 00000000000..bbeafe6d3b7 --- /dev/null +++ b/test/spec/modules/adheseBidAdapter_spec.js @@ -0,0 +1,285 @@ +import {expect} from 'chai'; +import {spec} from 'modules/adheseBidAdapter'; + +const BID_ID = 456; +const TTL = 360; +const NET_REVENUE = true; + +let minimalBid = function() { + return { + 'bidId': BID_ID, + 'bidder': 'adhese', + 'params': { + account: 'demo', + location: '_main_page_', + format: 'leaderboard' + } + } +}; + +let bidWithParams = function(data) { + let bid = minimalBid(); + bid.params.data = data; + return bid; +}; + +describe('AdheseAdapter', function () { + describe('getUserSyncs', function () { + const serverResponse = { + account: 'demo' + }; + const gdprConsent = { + gdprApplies: true, + consentString: 'CONSENT_STRING' + }; + it('should return empty when iframe disallowed', function () { + expect(spec.getUserSyncs({ iframeEnabled: false }, serverResponse, gdprConsent)).to.be.empty; + }); + it('should return usersync url when iframe allowed', function () { + expect(spec.getUserSyncs({ iframeEnabled: true }, serverResponse, gdprConsent)).to.deep.equal([{ type: 'iframe', url: 'https://user-sync.adhese.com/iframe/user_sync.html?account=demo&gdpr=1&consentString=CONSENT_STRING' }]); + }); + }); + + describe('isBidRequestValid', function () { + it('should return true when required params found', function () { + expect(spec.isBidRequestValid(minimalBid())).to.equal(true); + }); + + it('should return false when required params are not passed', function () { + let bid = Object.assign({}, minimalBid()); + delete bid.params; + bid.params = {}; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + }); + + describe('buildRequests', function () { + let bidderRequest = { + gdprConsent: { + gdprApplies: true, + consentString: 'CONSENT_STRING' + } + }; + + it('should include all extra bid params', function () { + let req = spec.buildRequests([ bidWithParams({ 'ag': '25' }) ], bidderRequest); + + expect(req.url).to.contain('/sl_main_page_-leaderboard/ag25'); + }); + + it('should include duplicate bid params once', function () { + let req = spec.buildRequests([ bidWithParams({ 'ag': '25' }), bidWithParams({ 'ag': '25', 'ci': 'gent' }) ], bidderRequest); + + expect(req.url).to.contain('/sl_main_page_-leaderboard/ag25/cigent'); + }); + + it('should split multiple target values', function () { + let req = spec.buildRequests([ bidWithParams({ 'ci': 'london' }), bidWithParams({ 'ci': 'gent' }) ], bidderRequest); + + expect(req.url).to.contain('/sl_main_page_-leaderboard/cilondon;gent'); + }); + + it('should include gdpr consent param', function () { + let req = spec.buildRequests([ minimalBid() ], bidderRequest); + + expect(req.url).to.contain('/xtCONSENT_STRING'); + }); + + it('should include bids', function () { + let bid = minimalBid(); + let req = spec.buildRequests([ bid ], bidderRequest); + + expect(req.bids).to.deep.equal([ bid ]); + }); + }); + + describe('interpretResponse', () => { + let bidRequest = { + bids: [ minimalBid() ] + }; + + it('should get correct ssp banner response', () => { + let sspBannerResponse = { + body: [ + { + origin: 'APPNEXUS', + originInstance: '', + ext: 'js', + slotName: '_main_page_-leaderboard', + adType: 'leaderboard', + originData: { + seatbid: [{ + bid: [{ + crid: '60613369', + dealid: null + }], + seat: '958' + }] + }, + width: '728', + height: '90', + body: '
', + tracker: 'https://hosts-demo.adhese.com/rtb_gateway/handlers/client/track/?id=a2f39296-6dd0-4b3c-be85-7baa22e7ff4a', + impressionCounter: 'https://hosts-demo.adhese.com/rtb_gateway/handlers/client/track/?id=a2f39296-6dd0-4b3c-be85-7baa22e7ff4a', + extension: {'prebid': {'cpm': {'amount': '1.000000', 'currency': 'USD'}}} + } + ] + }; + + let expectedResponse = [{ + requestId: BID_ID, + ad: '
', + cpm: 1, + currency: 'USD', + creativeId: '60613369', + dealId: '', + width: 728, + height: 90, + mediaType: 'banner', + netRevenue: NET_REVENUE, + ttl: TTL, + }]; + expect(spec.interpretResponse(sspBannerResponse, bidRequest)).to.deep.equal(expectedResponse); + }); + + it('should get correct ssp video response', () => { + let sspVideoResponse = { + body: [ + { + origin: 'RUBICON', + ext: 'js', + slotName: '_main_page_-leaderboard', + adType: 'leaderboard', + width: '640', + height: '350', + body: '', + extension: {'prebid': {'cpm': {'amount': '2.1', 'currency': 'USD'}}} + } + ] + }; + + let expectedResponse = [{ + requestId: BID_ID, + vastXml: '', + cpm: 2.1, + currency: 'USD', + creativeId: 'RUBICON', + dealId: '', + width: 640, + height: 350, + mediaType: 'video', + netRevenue: NET_REVENUE, + ttl: TTL, + }]; + expect(spec.interpretResponse(sspVideoResponse, bidRequest)).to.deep.equal(expectedResponse); + }); + + it('should get correct Adhese banner response', () => { + const adheseBannerResponse = { + body: [ + { + adType: 'largeleaderboard', // it can differ from the requested slot + adFormat: 'largeleaderboard', + timeStamp: '1544009030000', + orderId: '22051', + adspaceId: '162363', + body: '', + tag: '', + tracker: 'https://hosts-demo.adhese.com/track/tracker', + altText: '', + height: '150', + width: '840', + tagUrl: 'https://pool-demo.adhese.com/pool/lib/90511.js', + libId: '90511', + id: '742898', + advertiserId: '2081', + ext: 'js', + url: 'https://hosts-demo.adhese.com/raylene/url', + clickTag: 'https://hosts-demo.adhese.com/raylene/clickTag', + poolPath: 'https://hosts-demo.adhese.com/pool/lib/', + orderName: 'Luminus boiler comodity-Pareto -201812', + creativeName: 'nl_demo _network_ron_dlbd_840x150_fix_dir_asv_std_dis_brd_nrt_na_red', + slotName: '_main_page_-leaderboard', + slotID: '29306', + impressionCounter: 'https://hosts-demo.adhese.com/track/742898', + origin: 'JERLICIA', + originData: {}, + auctionable: true, + extension: { + prebid: { + cpm: { + amount: '5.96', + currency: 'USD' + } + } + } + } + ] + }; + + let expectedResponse = [{ + requestId: BID_ID, + ad: '', + cpm: 5.96, + currency: 'USD', + creativeId: '742898', + dealId: '22051', + width: 840, + height: 150, + mediaType: 'banner', + netRevenue: NET_REVENUE, + ttl: TTL, + }]; + expect(spec.interpretResponse(adheseBannerResponse, bidRequest)).to.deep.equal(expectedResponse); + }); + + it('should get correct Adhese video response', () => { + const adheseVideoResponse = { + body: [ + { + adType: 'preroll', + adFormat: '', + orderId: '22248', + adspaceId: '164196', + body: '', + height: '360', + width: '640', + tag: "", + libId: '89860', + id: '742470', + advertiserId: '2263', + ext: 'advar', + orderName: 'Smartphoto EOY-20181112', + creativeName: 'PREROLL', + slotName: '_main_page_-leaderboard', + slotID: '41711', + impressionCounter: 'https://hosts-demo.adhese.com/track/742898', + origin: 'JERLICIA', + originData: {}, + auctionable: true + } + ] + }; + + let expectedResponse = [{ + requestId: BID_ID, + vastXml: '', + cpm: 0, + currency: 'USD', + creativeId: '742470', + dealId: '22248', + width: 640, + height: 360, + mediaType: 'video', + netRevenue: NET_REVENUE, + ttl: TTL, + }]; + expect(spec.interpretResponse(adheseVideoResponse, bidRequest)).to.deep.equal(expectedResponse); + }); + + it('should return no bids for empty adserver response', () => { + let adserverResponse = { body: [] }; + expect(spec.interpretResponse(adserverResponse, bidRequest)).to.be.empty; + }); + }); +}); From 045b8e5bb5ce6b984d142232ec9aad1720bdfe55 Mon Sep 17 00:00:00 2001 From: Mateusz Michalowski Date: Mon, 17 Dec 2018 15:16:16 +0100 Subject: [PATCH 2/9] Support empty impressionCounters --- modules/adheseBidAdapter.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/adheseBidAdapter.js b/modules/adheseBidAdapter.js index bb848cf33bc..eb10e8d48cc 100644 --- a/modules/adheseBidAdapter.js +++ b/modules/adheseBidAdapter.js @@ -127,7 +127,8 @@ export const spec = { if (bidResponse.mediaType === VIDEO) { bidResponse.vastXml = markup; } else { - bidResponse.ad = markup + ""; + const counter = ad.impressionCounter ? "" : ''; + bidResponse.ad = markup + counter; } return bidResponse; }, From 94a74ebf836b749c8ba8daa47fe74dca558197e3 Mon Sep 17 00:00:00 2001 From: Mateusz Michalowski Date: Mon, 17 Dec 2018 15:26:45 +0100 Subject: [PATCH 3/9] Fix the description --- modules/adheseBidAdapter.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/adheseBidAdapter.md b/modules/adheseBidAdapter.md index 977c3096a90..5270dfb5f79 100644 --- a/modules/adheseBidAdapter.md +++ b/modules/adheseBidAdapter.md @@ -6,11 +6,9 @@ Module Type: Bidder Adapter Maintainer: info@adhese.com ``` -//TODO: - # Description -Module that connects to Example's demand sources +Module that connects with Adhese Adserver and Adhese Gateway. Banner and Video are supported. # Test Parameters ``` From c617dd6ca02bb4c5eab071ef990ae5d6541fab6e Mon Sep 17 00:00:00 2001 From: Mateusz Michalowski Date: Mon, 17 Dec 2018 17:19:32 +0100 Subject: [PATCH 4/9] Replace Object.entries with Object.keys --- modules/adheseBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/adheseBidAdapter.js b/modules/adheseBidAdapter.js index eb10e8d48cc..68c635dc9ce 100644 --- a/modules/adheseBidAdapter.js +++ b/modules/adheseBidAdapter.js @@ -46,7 +46,7 @@ export const spec = { let account = this.getAccount(validBidRequests); let targets = validBidRequests.map(bid => bid.params.data).reduce(this.mergeTargets, {}); let gdprParams = (bidderRequest.gdprConsent && bidderRequest.gdprConsent.consentString) ? [ 'xt' + bidderRequest.gdprConsent.consentString ] : []; - let targetsParams = Object.entries(targets).map(param => param[0] + param[1].join(';')); + let targetsParams = Object.keys(targets).map(targetCode => targetCode + targets[targetCode].join(';')); let slotsParams = validBidRequests.map(bid => 'sl' + this.bidToSlotName(bid)); let params = [...slotsParams, ...targetsParams, ...gdprParams].map(s => '/' + s).join(''); let cacheBuster = '?t=' + new Date().getTime(); From 7416232a03d5b86e118c71fcbc577562989565c8 Mon Sep 17 00:00:00 2001 From: Mateusz Michalowski Date: Mon, 17 Dec 2018 17:29:11 +0100 Subject: [PATCH 5/9] Cleanup --- modules/adheseBidAdapter.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/adheseBidAdapter.js b/modules/adheseBidAdapter.js index 68c635dc9ce..f69d6d7f3ed 100644 --- a/modules/adheseBidAdapter.js +++ b/modules/adheseBidAdapter.js @@ -160,8 +160,6 @@ export const spec = { } return [{ type: 'iframe', url: syncurl }]; } - }, - - onTimeout: function(timeoutData) {}, + } }; registerBidder(spec); From 8ccd996d2f47483a9ab55c894980343be12c7dcc Mon Sep 17 00:00:00 2001 From: Mateusz Michalowski Date: Tue, 18 Dec 2018 12:30:28 +0100 Subject: [PATCH 6/9] Use const instead of let --- modules/adheseBidAdapter.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/modules/adheseBidAdapter.js b/modules/adheseBidAdapter.js index f69d6d7f3ed..86091556e6f 100644 --- a/modules/adheseBidAdapter.js +++ b/modules/adheseBidAdapter.js @@ -17,10 +17,10 @@ export const spec = { mergeTargets: function(targets, target) { if (target) { Object.keys(target).forEach(function (key) { - let val = target[key]; - let values = Array.isArray(val) ? val : [val]; + const val = target[key]; + const values = Array.isArray(val) ? val : [val]; if (targets[key]) { - let distinctValues = values.filter(v => targets[key].indexOf(v) < 0); + const distinctValues = values.filter(v => targets[key].indexOf(v) < 0); targets[key].push.apply(targets[key], distinctValues); } else { targets[key] = values; @@ -43,14 +43,14 @@ export const spec = { return null; } - let account = this.getAccount(validBidRequests); - let targets = validBidRequests.map(bid => bid.params.data).reduce(this.mergeTargets, {}); - let gdprParams = (bidderRequest.gdprConsent && bidderRequest.gdprConsent.consentString) ? [ 'xt' + bidderRequest.gdprConsent.consentString ] : []; - let targetsParams = Object.keys(targets).map(targetCode => targetCode + targets[targetCode].join(';')); - let slotsParams = validBidRequests.map(bid => 'sl' + this.bidToSlotName(bid)); - let params = [...slotsParams, ...targetsParams, ...gdprParams].map(s => '/' + s).join(''); - let cacheBuster = '?t=' + new Date().getTime(); - let uri = 'https://ads-' + account + '.adhese.com/json' + params + cacheBuster; + const account = this.getAccount(validBidRequests); + const targets = validBidRequests.map(bid => bid.params.data).reduce(this.mergeTargets, {}); + const gdprParams = (bidderRequest.gdprConsent && bidderRequest.gdprConsent.consentString) ? [ 'xt' + bidderRequest.gdprConsent.consentString ] : []; + const targetsParams = Object.keys(targets).map(targetCode => targetCode + targets[targetCode].join(';')); + const slotsParams = validBidRequests.map(bid => 'sl' + this.bidToSlotName(bid)); + const params = [...slotsParams, ...targetsParams, ...gdprParams].map(s => '/' + s).join(''); + const cacheBuster = '?t=' + new Date().getTime(); + const uri = 'https://ads-' + account + '.adhese.com/json' + params + cacheBuster; return { method: 'GET', @@ -68,7 +68,7 @@ export const spec = { }, getMediaType: function(markup) { - let isVideo = markup.trim().toLowerCase().match(/<\?xml| Date: Mon, 7 Jan 2019 16:56:49 +0100 Subject: [PATCH 7/9] Internal functions are no longer exposed --- modules/adheseBidAdapter.js | 209 ++++++++++++++++++------------------ 1 file changed, 105 insertions(+), 104 deletions(-) diff --git a/modules/adheseBidAdapter.js b/modules/adheseBidAdapter.js index 86091556e6f..7a75e0971a7 100644 --- a/modules/adheseBidAdapter.js +++ b/modules/adheseBidAdapter.js @@ -14,40 +14,16 @@ export const spec = { return !!(bid.params.account && bid.params.location && bid.params.format); }, - mergeTargets: function(targets, target) { - if (target) { - Object.keys(target).forEach(function (key) { - const val = target[key]; - const values = Array.isArray(val) ? val : [val]; - if (targets[key]) { - const distinctValues = values.filter(v => targets[key].indexOf(v) < 0); - targets[key].push.apply(targets[key], distinctValues); - } else { - targets[key] = values; - } - }); - } - return targets; - }, - - bidToSlotName: function(bid) { - return bid.params.location + '-' + bid.params.format; - }, - - getAccount: function(validBidRequests) { - return validBidRequests[0].params.account; - }, - buildRequests: function(validBidRequests, bidderRequest) { if (validBidRequests.length === 0) { return null; } - const account = this.getAccount(validBidRequests); - const targets = validBidRequests.map(bid => bid.params.data).reduce(this.mergeTargets, {}); + const account = getAccount(validBidRequests); + const targets = validBidRequests.map(bid => bid.params.data).reduce(mergeTargets, {}); const gdprParams = (bidderRequest.gdprConsent && bidderRequest.gdprConsent.consentString) ? [ 'xt' + bidderRequest.gdprConsent.consentString ] : []; const targetsParams = Object.keys(targets).map(targetCode => targetCode + targets[targetCode].join(';')); - const slotsParams = validBidRequests.map(bid => 'sl' + this.bidToSlotName(bid)); + const slotsParams = validBidRequests.map(bid => 'sl' + bidToSlotName(bid)); const params = [...slotsParams, ...targetsParams, ...gdprParams].map(s => '/' + s).join(''); const cacheBuster = '?t=' + new Date().getTime(); const uri = 'https://ads-' + account + '.adhese.com/json' + params + cacheBuster; @@ -59,95 +35,21 @@ export const spec = { }; }, - baseAdResponse: function(response) { - return Object.assign({ netRevenue: true, ttl: 360 }, response); - }, - - isAdheseAd: function(ad) { - return !ad.origin || ad.origin === 'JERLICIA'; - }, - - getMediaType: function(markup) { - const isVideo = markup.trim().toLowerCase().match(/<\?xml|" : ''; - bidResponse.ad = markup + counter; - } - return bidResponse; - }, - interpretResponse: function(serverResponse, request) { const serverAds = serverResponse.body.reduce(function(map, ad) { map[ad.slotName] = ad; return map; }, {}); - serverResponse.account = this.getAccount(request.bids); + serverResponse.account = getAccount(request.bids); return request.bids .map(bid => ({ bid: bid, - ad: serverAds[this.bidToSlotName(bid)] + ad: serverAds[bidToSlotName(bid)] })) .filter(item => item.ad) - .map(item => this.adResponse(item.bid, item.ad)); + .map(item => adResponse(item.bid, item.ad)); }, getUserSyncs: function(syncOptions, serverResponse, gdprConsent) { @@ -162,4 +64,103 @@ export const spec = { } } }; + +function adResponse(bid, ad) { + const price = getPrice(ad); + const adDetails = getAdDetails(ad); + const markup = getAdMarkup(ad); + + const bidResponse = baseAdResponse({ + requestId: bid.bidId, + mediaType: getMediaType(markup), + cpm: Number(price.amount), + currency: price.currency, + width: Number(ad.width), + height: Number(ad.height), + creativeId: adDetails.creativeId, + dealId: adDetails.dealId + }); + + if (bidResponse.mediaType === VIDEO) { + bidResponse.vastXml = markup; + } else { + const counter = ad.impressionCounter ? "" : ''; + bidResponse.ad = markup + counter; + } + return bidResponse; +} + +function mergeTargets(targets, target) { + if (target) { + Object.keys(target).forEach(function (key) { + const val = target[key]; + const values = Array.isArray(val) ? val : [val]; + if (targets[key]) { + const distinctValues = values.filter(v => targets[key].indexOf(v) < 0); + targets[key].push.apply(targets[key], distinctValues); + } else { + targets[key] = values; + } + }); + } + return targets; +} + +function bidToSlotName(bid) { + return bid.params.location + '-' + bid.params.format; +} + +function getAccount(validBidRequests) { + return validBidRequests[0].params.account; +} + +function baseAdResponse(response) { + return Object.assign({ netRevenue: true, ttl: 360 }, response); +} + +function isAdheseAd(ad) { + return !ad.origin || ad.origin === 'JERLICIA'; +} + +function getMediaType(markup) { + const isVideo = markup.trim().toLowerCase().match(/<\?xml| Date: Tue, 8 Jan 2019 15:37:47 +0100 Subject: [PATCH 8/9] Rename getter --- modules/adheseBidAdapter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/adheseBidAdapter.js b/modules/adheseBidAdapter.js index 7a75e0971a7..c78af965202 100644 --- a/modules/adheseBidAdapter.js +++ b/modules/adheseBidAdapter.js @@ -70,7 +70,7 @@ function adResponse(bid, ad) { const adDetails = getAdDetails(ad); const markup = getAdMarkup(ad); - const bidResponse = baseAdResponse({ + const bidResponse = getbaseAdResponse({ requestId: bid.bidId, mediaType: getMediaType(markup), cpm: Number(price.amount), @@ -114,7 +114,7 @@ function getAccount(validBidRequests) { return validBidRequests[0].params.account; } -function baseAdResponse(response) { +function getbaseAdResponse(response) { return Object.assign({ netRevenue: true, ttl: 360 }, response); } From 9801afb7e42f23d8597e4738da0ac5db64c25530 Mon Sep 17 00:00:00 2001 From: Mateusz Michalowski Date: Fri, 11 Jan 2019 16:47:00 +0100 Subject: [PATCH 9/9] Use the bid parameters pointing to the existing demo position --- modules/adheseBidAdapter.md | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/modules/adheseBidAdapter.md b/modules/adheseBidAdapter.md index 5270dfb5f79..0179c10ec0e 100644 --- a/modules/adheseBidAdapter.md +++ b/modules/adheseBidAdapter.md @@ -17,17 +17,17 @@ Module that connects with Adhese Adserver and Adhese Gateway. Banner and Video a code: 'test-div1', mediaTypes: { banner: { - sizes: [[300, 250]], // a display size + sizes: [[728, 90], [850, 150]], // a display size } }, bids: [ { bidder: "adhese", params: { - account: 'demo', // required - the name of your adhese account, if unknown, please contact your sales rep - location: '_main_page_', // required - the location you want to refer to for a specific section or page, as defined in your Adhese inventory - format: 'middle', // required - the format you accept for this unit, as defined in your Adhese inventory - data: { // optional - target params, as defined in your Adhese setup + account: 'demo', // required - the name of your adhese account, if unknown, please contact your sales rep + location: '_adhese_prebid_demo_', // required - the location you want to refer to for a specific section or page, as defined in your Adhese inventory + format: 'leaderboard', // required - the format you accept for this unit, as defined in your Adhese inventory + data: { // optional - target params, as defined in your Adhese setup 'ci': ['gent', 'brussels'] 'ag': ['55'] 'tl': ['all'] @@ -35,23 +35,6 @@ Module that connects with Adhese Adserver and Adhese Gateway. Banner and Video a } } ] - },{ - code: 'test-div2', - mediaTypes: { - banner: { - sizes: [[320, 50]], // a mobile size - } - }, - bids: [ - { - bidder: "adhese", - params: { - account: 'demo', - location: '_main_page_', - format: 'middle' - } - } - ] } ]; ```