From d0b644da6a57e587cdc0eb307b991863af830238 Mon Sep 17 00:00:00 2001 From: Eldengrof Date: Wed, 10 Apr 2019 12:38:25 +0600 Subject: [PATCH 1/8] add ShowHeroes Adapter --- modules/shBidAdapter.js | 184 ++++++++++++++++++++++++ modules/shBidAdapter.md | 69 +++++++++ test/spec/modules/shBidAdapter_spec.js | 187 +++++++++++++++++++++++++ 3 files changed, 440 insertions(+) create mode 100644 modules/shBidAdapter.js create mode 100644 modules/shBidAdapter.md create mode 100644 test/spec/modules/shBidAdapter_spec.js diff --git a/modules/shBidAdapter.js b/modules/shBidAdapter.js new file mode 100644 index 00000000000..94d28770548 --- /dev/null +++ b/modules/shBidAdapter.js @@ -0,0 +1,184 @@ +import * as utils from '../src/utils'; +import { config } from '../src/config'; +import { registerBidder } from '../src/adapters/bidderFactory'; +import { VIDEO, BANNER } from '../src/mediaTypes'; + +const PROD_ENDPOINT = 'https://bs1.showheroes.com/api/v1/bid'; +const STAGE_ENDPOINT = 'https://bid-service.stage.showheroes.com/api/v1/bid'; +const PROD_PUBLISHER_TAG = 'https://static.showheroes.com/publishertag.js'; +const STAGE_PUBLISHER_TAG = 'https://pubtag.stage.showheroes.com/publishertag.js'; +const PROD_VL = 'https://video-library.showheroes.com'; +const STAGE_VL = 'https://video-library.stage.showheroes.com'; +const BIDDER_CODE = 'showheroes-bs'; +const TTL = 300; + +export const spec = { + code: BIDDER_CODE, + aliases: ['showheroesBs'], + supportedMediaTypes: [VIDEO, BANNER], + isBidRequestValid: function(bid) { + return !!bid.params.playerId; + }, + buildRequests: function(validBidRequests, bidderRequest) { + const pageURL = validBidRequests[0].params.contentPageUrl || bidderRequest.refererInfo.referer; + const isStage = !!validBidRequests[0].params.stage; + const isBanner = !!validBidRequests[0].mediaTypes.banner; + + let adUnits = validBidRequests.map((bid) => { + const vpaidMode = utils.getBidIdParameter('vpaidMode', bid.params); + + let sizes = bid.sizes.length === 1 ? bid.sizes[0] : bid.sizes; + if (sizes && !sizes.length) { + let mediaSize; + if (!isBanner) { + mediaSize = bid.mediaTypes.video.playerSize; + } else { + mediaSize = bid.mediaTypes.banner.sizes; + } + if (utils.isArray(mediaSize[0])) { + sizes = mediaSize[0]; + } else if (utils.isNumber(mediaSize[0])) { + sizes = mediaSize; + } + } + + const context = utils.deepAccess(bid, 'mediaTypes.video.context'); + + let streamType = 2; + + if (vpaidMode && context === 'instream') { + streamType = 1; + } + if (context === 'outstream' || isBanner) { + streamType = 5; + } + + return { + type: streamType, + bidId: bid.bidId, + mediaType: isBanner ? BANNER : VIDEO, + playerId: utils.getBidIdParameter('playerId', bid.params), + auctionId: bidderRequest.auctionId, + bidderCode: BIDDER_CODE, + gdprConsent: bidderRequest.gdprConsent, + start: +new Date(), + timeout: 3000, + video: { + width: sizes[0], + height: sizes[1] + }, + }; + }); + + return { + url: isStage ? STAGE_ENDPOINT : PROD_ENDPOINT, + method: 'POST', + options: {contentType: 'application/json', accept: 'application/json'}, + data: { + 'user': [], + 'meta': { + 'pageURL': encodeURIComponent(pageURL), + 'vastCacheEnabled': (!!config.getConfig('cache') && !isBanner) || false, + 'isDesktop': utils.getWindowTop().document.documentElement.clientWidth > 700, + 'stage': isStage || undefined + }, + 'requests': adUnits, + 'debug': validBidRequests[0].params.debug || false, + } + }; + }, + interpretResponse: function(response, request) { + return createBids(response.body, request.data); + }, + getUserSyncs: function(syncOptions, serverResponses) { + const syncs = []; + + if (!serverResponses.length || !serverResponses[0].body.userSync) { + return syncs; + } + + const userSync = serverResponses[0].body.userSync; + + if (syncOptions.iframeEnabled) { + (userSync.iframes || []).forEach(url => { + syncs.push({ + type: 'iframe', + url + }); + }); + } + + if (syncOptions.pixelEnabled) { + (userSync.pixels || []).forEach(url => { + syncs.push({ + type: 'image', + url + }); + }); + } + return syncs; + }, +}; + +function createBids(bidRes, reqData) { + if (bidRes && (!Array.isArray(bidRes.bids) || bidRes.bids.length < 1)) { + return []; + } + + const bids = []; + const bidMap = {}; + (reqData.requests || []).forEach((bid) => { + bidMap[bid.bidId] = bid; + }); + + bidRes.bids.forEach(function (bid) { + const reqBid = bidMap[bid.bidId]; + let bidUnit = {}; + bidUnit.cpm = bid.cpm; + bidUnit.requestId = bid.bidId; + bidUnit.currency = bid.currency; + bidUnit.mediaType = reqBid.mediaType || VIDEO; + bidUnit.ttl = TTL; + bidUnit.creativeId = 'c_' + bid.bidId; + bidUnit.netRevenue = true; + bidUnit.width = bid.video.width; + bidUnit.height = bid.video.height; + if (bid.vastXml) { + bidUnit.vastXml = bid.vastXml; + bidUnit.adResponse = { + content: bid.vastXml, + }; + } + if (bid.vastTag) { + bidUnit.vastUrl = bid.vastTag; + } + if (reqBid.mediaType === BANNER) { + bidUnit.ad = getBannerHtml(bid, reqBid, reqData); + } + bids.push(bidUnit); + }); + + return bids; +} + +function getBannerHtml (bid, reqBid, reqData) { + const isStage = !!reqData.meta.stage; + const pubTag = isStage ? STAGE_PUBLISHER_TAG : PROD_PUBLISHER_TAG; + const vlHost = isStage ? STAGE_VL : PROD_VL; + return ` + + + +
+ + `; +} + +registerBidder(spec); diff --git a/modules/shBidAdapter.md b/modules/shBidAdapter.md new file mode 100644 index 00000000000..b1ca1782725 --- /dev/null +++ b/modules/shBidAdapter.md @@ -0,0 +1,69 @@ +# Overview + +Module Name: ShowHeroes Bidder Adapter + +Module Type: Bidder Adapter + +Maintainer: tech@showheroes.com + +# Description + +Module that connects to ShowHeroes demand source to fetch bids. + +# Test Parameters +``` + var adUnits = [ + { + code: 'video', + mediaTypes: { + video: { + playerSize: [640, 480], + context: 'instream', + } + }, + bids: [ + { + bidder: "showheroes-bs", + params: { + playerId: '0151f985-fb1a-4f37-bb26-cfc62e43ec05', + vpaidMode: true // by default is 'false' + } + } + ] + }, + { + code: 'video', + mediaTypes: { + video: { + playerSize: [640, 480], + context: 'outstream', + } + }, + bids: [ + { + bidder: "showheroes-bs", + params: { + playerId: '0151f985-fb1a-4f37-bb26-cfc62e43ec05', + vpaidMode: true // by default is 'false' + } + } + ] + }, + { + code: 'banner', + mediaTypes: { + banner: { + sizes: [[640, 480]], + } + }, + bids: [ + { + bidder: "showheroes-bs", + params: { + playerId: '0151f985-fb1a-4f37-bb26-cfc62e43ec05', + } + } + ] + } + ]; +``` diff --git a/test/spec/modules/shBidAdapter_spec.js b/test/spec/modules/shBidAdapter_spec.js new file mode 100644 index 00000000000..588d4c54150 --- /dev/null +++ b/test/spec/modules/shBidAdapter_spec.js @@ -0,0 +1,187 @@ +import {expect} from 'chai' +import {spec} from 'modules/shBidAdapter' +import {newBidder} from 'src/adapters/bidderFactory' +import {VIDEO, BANNER} from 'src/mediaTypes' + +const bidderRequest = { + refererInfo: { + referer: 'http://example.com' + } +} + +const gdpr = { + 'gdprConsent': { + 'consentString': 'BOEFEAyOEFEAyAHABDENAI4AAAB9vABAASA', + 'gdprApplies': true + } +} + +const bidRequestVideo = { + 'bidder': 'showheroes-bs', + 'params': { + 'playerId': '47427aa0-f11a-4d24-abca-1295a46a46cd', + }, + 'mediaTypes': { + 'video': { + 'playerSize': [640, 480], + 'context': 'instream', + } + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[640, 480]], + 'bidId': '38b373e1e31c18', + 'bidderRequestId': '12e3ade2543ba6', + 'auctionId': '43aa080090a47f', +} + +const bidRequestVideoVpaid = { + 'bidder': 'showheroes-bs', + 'params': { + 'playerId': '47427aa0-f11a-4d24-abca-1295a46a46cd', + 'vpaidMode': true, + }, + 'mediaTypes': { + 'video': { + 'playerSize': [640, 480], + 'context': 'instream', + } + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[640, 480]], + 'bidId': '38b373e1e31c18', + 'bidderRequestId': '12e3ade2543ba6', + 'auctionId': '43aa080090a47f', +} + +const bidRequestBanner = { + 'bidder': 'showheroes-bs', + 'params': { + 'playerId': '47427aa0-f11a-4d24-abca-1295a46a46cd', + }, + 'mediaTypes': { + 'banner': { + 'sizes': [[640, 360]] + } + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[640, 480]], + 'bidId': '38b373e1e31c18', + 'bidderRequestId': '12e3ade2543ba6', + 'auctionId': '43aa080090a47f', +} + +describe('shBidAdapter', function () { + const adapter = newBidder(spec) + + describe('inherited functions', function () { + it('exists and is a function', function () { + expect(adapter.callBids).to.exist.and.to.be.a('function') + }) + }) + + describe('isBidRequestValid', function () { + it('should return true when required params found', function () { + const request = { + 'params': { + 'playerId': '47427aa0-f11a-4d24-abca-1295a46a46cd', + } + } + expect(spec.isBidRequestValid(request)).to.equal(true) + }) + + it('should return false when required params are not passed', function () { + const request = { + 'params': {} + } + expect(spec.isBidRequestValid(request)).to.equal(false) + }) + }) + + describe('buildRequests', function () { + it('sends bid request to ENDPOINT via POST', function () { + const request = spec.buildRequests([bidRequestVideo], bidderRequest) + expect(request.method).to.equal('POST') + }) + + it('should attach valid params to the payload when type is video', function () { + const request = spec.buildRequests([bidRequestVideo], bidderRequest) + const payload = request.data.requests[0]; + expect(payload).to.be.an('object'); + expect(payload).to.have.property('playerId', '47427aa0-f11a-4d24-abca-1295a46a46cd'); + expect(payload).to.have.property('mediaType', VIDEO); + expect(payload).to.have.property('type', 2); + }) + + it('should attach valid params to the payload when type is video & vpaid mode on', function () { + const request = spec.buildRequests([bidRequestVideoVpaid], bidderRequest) + const payload = request.data.requests[0]; + expect(payload).to.be.an('object'); + expect(payload).to.have.property('playerId', '47427aa0-f11a-4d24-abca-1295a46a46cd'); + expect(payload).to.have.property('mediaType', VIDEO); + expect(payload).to.have.property('type', 1); + }) + + it('should attach valid params to the payload when type is banner', function () { + const request = spec.buildRequests([bidRequestBanner], bidderRequest) + const payload = request.data.requests[0]; + expect(payload).to.be.an('object'); + expect(payload).to.have.property('playerId', '47427aa0-f11a-4d24-abca-1295a46a46cd'); + expect(payload).to.have.property('mediaType', BANNER); + expect(payload).to.have.property('type', 5); + }) + + it('passes gdpr if present', function () { + const request = spec.buildRequests([bidRequestVideo], {...bidderRequest, ...gdpr}) + const payload = request.data.requests[0]; + expect(payload).to.be.an('object'); + expect(payload.gdprConsent).to.eql(gdpr.gdprConsent) + }) + }) + + describe('interpretResponse', function () { + it('handles nobid responses', function () { + expect(spec.interpretResponse({body: {}}, {data: {meta: {}}}).length).to.equal(0) + expect(spec.interpretResponse({body: []}, {data: {meta: {}}}).length).to.equal(0) + }) + + const response = { + 'bids': [{ + 'cpm': 5, + 'currency': 'EUR', + 'bidId': '38b373e1e31c18', + 'video': {'width': 640, 'height': 480}, + 'vastTag': 'https:\/\/video-library.stage.showheroes.com\/commercial\/wrapper?player_id=47427aa0-f11a-4d24-abca-1295a46a46cd&ad_bidder=showheroes-bs&master_shadt=1&description_url=https%3A%2F%2Fbid-service.stage.showheroes.com%2Fvast%2Fad%2Fcache%2F4840b920-40e1-4e09-9231-60bbf088c8d6', + }], + } + + it('should get correct bid response when type is video', function () { + const request = spec.buildRequests([bidRequestVideo], bidderRequest) + const expectedResponse = [ + { + 'cpm': 5, + 'creativeId': 'c_38b373e1e31c18', + 'currency': 'EUR', + 'width': 640, + 'height': 480, + 'mediaType': 'video', + 'netRevenue': true, + 'vastUrl': 'https://video-library.stage.showheroes.com/commercial/wrapper?player_id=47427aa0-f11a-4d24-abca-1295a46a46cd&ad_bidder=showheroes-bs&master_shadt=1&description_url=https%3A%2F%2Fbid-service.stage.showheroes.com%2Fvast%2Fad%2Fcache%2F4840b920-40e1-4e09-9231-60bbf088c8d6', + 'requestId': '38b373e1e31c18', + 'ttl': 300, + } + ] + + const result = spec.interpretResponse({'body': response}, request) + expect(result).to.deep.equal(expectedResponse) + }) + + it('should get correct bid response when type is banner', function () { + const request = spec.buildRequests([bidRequestBanner], bidderRequest) + + const result = spec.interpretResponse({'body': response}, request) + expect(result[0]).to.have.property('mediaType', BANNER); + expect(result[0].ad).to.include(' + data-player-host="${urls.vlHost}">
Date: Mon, 23 Sep 2019 15:22:38 +0600 Subject: [PATCH 3/8] Revert "ShowHeroes adapter - expanded outstream support" This reverts commit bfcdb913b52012b5afbf95a84956b906518a4b51. --- modules/shBidAdapter.js | 102 ++-------------------------------------- modules/shBidAdapter.md | 35 -------------- 2 files changed, 5 insertions(+), 132 deletions(-) diff --git a/modules/shBidAdapter.js b/modules/shBidAdapter.js index 60b88ad694a..94d28770548 100644 --- a/modules/shBidAdapter.js +++ b/modules/shBidAdapter.js @@ -1,6 +1,5 @@ import * as utils from '../src/utils'; import { config } from '../src/config'; -import { Renderer } from '../src/Renderer'; import { registerBidder } from '../src/adapters/bidderFactory'; import { VIDEO, BANNER } from '../src/mediaTypes'; @@ -13,13 +12,6 @@ const STAGE_VL = 'https://video-library.stage.showheroes.com'; const BIDDER_CODE = 'showheroes-bs'; const TTL = 300; -function getEnvURLs(isStage) { - return { - pubTag: isStage ? STAGE_PUBLISHER_TAG : PROD_PUBLISHER_TAG, - vlHost: isStage ? STAGE_VL : PROD_VL - } -} - export const spec = { code: BIDDER_CODE, aliases: ['showheroesBs'], @@ -31,9 +23,6 @@ export const spec = { const pageURL = validBidRequests[0].params.contentPageUrl || bidderRequest.refererInfo.referer; const isStage = !!validBidRequests[0].params.stage; const isBanner = !!validBidRequests[0].mediaTypes.banner; - const isOutstream = utils.deepAccess(validBidRequests[0], 'mediaTypes.video.context'); - const isCustomRender = utils.deepAccess(validBidRequests[0], 'params.outstreamOptions.customRender'); - const outstreamOptions = utils.deepAccess(validBidRequests[0], 'params.outstreamOptions'); let adUnits = validBidRequests.map((bid) => { const vpaidMode = utils.getBidIdParameter('vpaidMode', bid.params); @@ -68,7 +57,6 @@ export const spec = { type: streamType, bidId: bid.bidId, mediaType: isBanner ? BANNER : VIDEO, - context: context, playerId: utils.getBidIdParameter('playerId', bid.params), auctionId: bidderRequest.auctionId, bidderCode: BIDDER_CODE, @@ -79,7 +67,6 @@ export const spec = { width: sizes[0], height: sizes[1] }, - bidRequest: bidderRequest, }; }); @@ -91,9 +78,8 @@ export const spec = { 'user': [], 'meta': { 'pageURL': encodeURIComponent(pageURL), - 'vastCacheEnabled': (!!config.getConfig('cache') && !isBanner && !outstreamOptions) || false, + 'vastCacheEnabled': (!!config.getConfig('cache') && !isBanner) || false, 'isDesktop': utils.getWindowTop().document.documentElement.clientWidth > 700, - 'xmlAndTag': (isOutstream && isCustomRender) || false, 'stage': isStage || undefined }, 'requests': adUnits, @@ -147,14 +133,6 @@ function createBids(bidRes, reqData) { bidRes.bids.forEach(function (bid) { const reqBid = bidMap[bid.bidId]; - let currentBidRequest; - for (let i in reqBid.bidRequest.bids) { - if (bid.bidId === reqBid.bidRequest.bids[i].bidId) { - currentBidRequest = reqBid.bidRequest.bids[i]; - break; - } - } - let bidUnit = {}; bidUnit.cpm = bid.cpm; bidUnit.requestId = bid.bidId; @@ -176,25 +154,6 @@ function createBids(bidRes, reqData) { } if (reqBid.mediaType === BANNER) { bidUnit.ad = getBannerHtml(bid, reqBid, reqData); - } else if (reqBid.context === 'outstream') { - const renderer = Renderer.install({ - id: bid.bidId, - url: '//', - config: { - playerId: reqBid.playerId, - width: bid.video.width, - height: bid.video.height, - vastUrl: bid.vastTag, - vastXml: bid.vastXml, - debug: reqData.debug, - isStage: !!reqData.meta.stage, - customRender: utils.getBidIdParameter('customRender', currentBidRequest.params.outstreamOptions), - slot: utils.getBidIdParameter('slot', currentBidRequest.params.outstreamOptions), - iframe: utils.getBidIdParameter('iframe', currentBidRequest.params.outstreamOptions), - } - }); - renderer.setRender(outstreamRender); - bidUnit.renderer = renderer; } bids.push(bidUnit); }); @@ -202,69 +161,18 @@ function createBids(bidRes, reqData) { return bids; } -function outstreamRender(bid) { - const embedCode = createOutstreamEmbedCode(bid); - if (typeof bid.renderer.config.customRender === 'function') { - bid.renderer.config.customRender(bid, embedCode); - } else { - try { - const inIframe = utils.getBidIdParameter('iframe', bid.renderer.config); - if (inIframe && window.document.getElementById(inIframe).nodeName === 'IFRAME') { - const iframe = window.document.getElementById(inIframe); - let framedoc = iframe.contentDocument || (iframe.contentWindow && iframe.contentWindow.document); - framedoc.body.appendChild(embedCode); - return; - } - - const slot = utils.getBidIdParameter('slot', bid.renderer.config); - if (slot && window.document.getElementById(slot)) { - window.document.getElementById(slot).appendChild(embedCode); - } else if (slot) { - utils.logError('[ShowHeroes][renderer] Error: spot not found'); - } - } catch (err) { - utils.logError('[ShowHeroes][renderer] Error:' + err.message) - } - } -} - -function createOutstreamEmbedCode(bid) { - const isStage = utils.getBidIdParameter('isStage', bid.renderer.config); - const urls = getEnvURLs(isStage); - - const fragment = window.document.createDocumentFragment(); - - const script = window.document.createElement('script'); - script.type = 'text/javascript'; - script.src = urls.pubTag; - script.onload = function () { - window.ShowheroesTag = this; - }; - script.setAttribute('data-player-host', urls.vlHost); - - const spot = window.document.createElement('div'); - spot.setAttribute('class', 'showheroes-spot'); - spot.setAttribute('data-player', utils.getBidIdParameter('playerId', bid.renderer.config)); - spot.setAttribute('data-debug', utils.getBidIdParameter('debug', bid.renderer.config)); - spot.setAttribute('data-ad-vast-tag', utils.getBidIdParameter('vastUrl', bid.renderer.config)); - spot.setAttribute('data-stream-type', 'outstream'); - - fragment.appendChild(spot); - fragment.appendChild(script); - return fragment; -} - function getBannerHtml (bid, reqBid, reqData) { const isStage = !!reqData.meta.stage; - const urls = getEnvURLs(isStage); + const pubTag = isStage ? STAGE_PUBLISHER_TAG : PROD_PUBLISHER_TAG; + const vlHost = isStage ? STAGE_VL : PROD_VL; return ` - + data-player-host="${vlHost}">
Date: Mon, 23 Sep 2019 15:24:02 +0600 Subject: [PATCH 4/8] ShowHeroes adapter - expanded outstream support --- modules/shBidAdapter.js | 102 ++++++++++++++++++++++++++++++++++++++-- modules/shBidAdapter.md | 36 ++++++++++++++ 2 files changed, 133 insertions(+), 5 deletions(-) diff --git a/modules/shBidAdapter.js b/modules/shBidAdapter.js index 94d28770548..955194bcaa3 100644 --- a/modules/shBidAdapter.js +++ b/modules/shBidAdapter.js @@ -1,5 +1,6 @@ import * as utils from '../src/utils'; import { config } from '../src/config'; +import { Renderer } from '../src/Renderer'; import { registerBidder } from '../src/adapters/bidderFactory'; import { VIDEO, BANNER } from '../src/mediaTypes'; @@ -12,6 +13,13 @@ const STAGE_VL = 'https://video-library.stage.showheroes.com'; const BIDDER_CODE = 'showheroes-bs'; const TTL = 300; +function getEnvURLs(isStage) { + return { + pubTag: isStage ? STAGE_PUBLISHER_TAG : PROD_PUBLISHER_TAG, + vlHost: isStage ? STAGE_VL : PROD_VL + } +} + export const spec = { code: BIDDER_CODE, aliases: ['showheroesBs'], @@ -23,6 +31,9 @@ export const spec = { const pageURL = validBidRequests[0].params.contentPageUrl || bidderRequest.refererInfo.referer; const isStage = !!validBidRequests[0].params.stage; const isBanner = !!validBidRequests[0].mediaTypes.banner; + const isOutstream = utils.deepAccess(validBidRequests[0], 'mediaTypes.video.context') === 'outstream'; + const isCustomRender = utils.deepAccess(validBidRequests[0], 'params.outstreamOptions.customRender'); + const outstreamOptions = utils.deepAccess(validBidRequests[0], 'params.outstreamOptions'); let adUnits = validBidRequests.map((bid) => { const vpaidMode = utils.getBidIdParameter('vpaidMode', bid.params); @@ -57,6 +68,7 @@ export const spec = { type: streamType, bidId: bid.bidId, mediaType: isBanner ? BANNER : VIDEO, + context: context, playerId: utils.getBidIdParameter('playerId', bid.params), auctionId: bidderRequest.auctionId, bidderCode: BIDDER_CODE, @@ -67,6 +79,7 @@ export const spec = { width: sizes[0], height: sizes[1] }, + bidRequest: bidderRequest, }; }); @@ -78,8 +91,9 @@ export const spec = { 'user': [], 'meta': { 'pageURL': encodeURIComponent(pageURL), - 'vastCacheEnabled': (!!config.getConfig('cache') && !isBanner) || false, + 'vastCacheEnabled': (!!config.getConfig('cache') && !isBanner && !outstreamOptions) || false, 'isDesktop': utils.getWindowTop().document.documentElement.clientWidth > 700, + 'xmlAndTag': !!(isOutstream && isCustomRender) || false, 'stage': isStage || undefined }, 'requests': adUnits, @@ -133,6 +147,14 @@ function createBids(bidRes, reqData) { bidRes.bids.forEach(function (bid) { const reqBid = bidMap[bid.bidId]; + let currentBidRequest; + for (let i in reqBid.bidRequest.bids) { + if (bid.bidId === reqBid.bidRequest.bids[i].bidId) { + currentBidRequest = reqBid.bidRequest.bids[i]; + break; + } + } + let bidUnit = {}; bidUnit.cpm = bid.cpm; bidUnit.requestId = bid.bidId; @@ -154,6 +176,25 @@ function createBids(bidRes, reqData) { } if (reqBid.mediaType === BANNER) { bidUnit.ad = getBannerHtml(bid, reqBid, reqData); + } else if (reqBid.context === 'outstream') { + const renderer = Renderer.install({ + id: bid.bidId, + url: '//', + config: { + playerId: reqBid.playerId, + width: bid.video.width, + height: bid.video.height, + vastUrl: bid.vastTag, + vastXml: bid.vastXml, + debug: reqData.debug, + isStage: !!reqData.meta.stage, + customRender: utils.getBidIdParameter('customRender', currentBidRequest.params.outstreamOptions), + slot: utils.getBidIdParameter('slot', currentBidRequest.params.outstreamOptions), + iframe: utils.getBidIdParameter('iframe', currentBidRequest.params.outstreamOptions), + } + }); + renderer.setRender(outstreamRender); + bidUnit.renderer = renderer; } bids.push(bidUnit); }); @@ -161,18 +202,69 @@ function createBids(bidRes, reqData) { return bids; } +function outstreamRender(bid) { + const embedCode = createOutstreamEmbedCode(bid); + if (typeof bid.renderer.config.customRender === 'function') { + bid.renderer.config.customRender(bid, embedCode); + } else { + try { + const inIframe = utils.getBidIdParameter('iframe', bid.renderer.config); + if (inIframe && window.document.getElementById(inIframe).nodeName === 'IFRAME') { + const iframe = window.document.getElementById(inIframe); + let framedoc = iframe.contentDocument || (iframe.contentWindow && iframe.contentWindow.document); + framedoc.body.appendChild(embedCode); + return; + } + + const slot = utils.getBidIdParameter('slot', bid.renderer.config); + if (slot && window.document.getElementById(slot)) { + window.document.getElementById(slot).appendChild(embedCode); + } else if (slot) { + utils.logError('[ShowHeroes][renderer] Error: spot not found'); + } + } catch (err) { + utils.logError('[ShowHeroes][renderer] Error:' + err.message) + } + } +} + +function createOutstreamEmbedCode(bid) { + const isStage = utils.getBidIdParameter('isStage', bid.renderer.config); + const urls = getEnvURLs(isStage); + + const fragment = window.document.createDocumentFragment(); + + const script = window.document.createElement('script'); + script.type = 'text/javascript'; + script.src = urls.pubTag; + script.onload = function () { + window.ShowheroesTag=this; + }; + script.setAttribute('data-player-host', urls.vlHost); + + const spot = window.document.createElement('div'); + spot.setAttribute('class', 'showheroes-spot'); + spot.setAttribute('data-player', utils.getBidIdParameter('playerId', bid.renderer.config)); + spot.setAttribute('data-debug', utils.getBidIdParameter('debug', bid.renderer.config)); + spot.setAttribute('data-ad-vast-tag', utils.getBidIdParameter('vastUrl', bid.renderer.config)); + spot.setAttribute('data-stream-type', 'outstream'); + + fragment.appendChild(spot); + fragment.appendChild(script); + return fragment; +} + function getBannerHtml (bid, reqBid, reqData) { const isStage = !!reqData.meta.stage; - const pubTag = isStage ? STAGE_PUBLISHER_TAG : PROD_PUBLISHER_TAG; - const vlHost = isStage ? STAGE_VL : PROD_VL; + const urls = getEnvURLs(isStage); return ` - + data-player-host="${urls.vlHost}">
Date: Tue, 1 Oct 2019 13:10:00 +0300 Subject: [PATCH 5/8] ShowHeroes adapter - fixes (#4222) --- modules/shBidAdapter.js | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/modules/shBidAdapter.js b/modules/shBidAdapter.js index 955194bcaa3..e9d5ca6f4b3 100644 --- a/modules/shBidAdapter.js +++ b/modules/shBidAdapter.js @@ -147,14 +147,7 @@ function createBids(bidRes, reqData) { bidRes.bids.forEach(function (bid) { const reqBid = bidMap[bid.bidId]; - let currentBidRequest; - for (let i in reqBid.bidRequest.bids) { - if (bid.bidId === reqBid.bidRequest.bids[i].bidId) { - currentBidRequest = reqBid.bidRequest.bids[i]; - break; - } - } - + const currentBidRequest = reqBid.bidRequest.bids && reqBid.bidRequest.bids.find(requestBid => bid.bidId === requestBid.bidId); let bidUnit = {}; bidUnit.cpm = bid.cpm; bidUnit.requestId = bid.bidId; @@ -238,7 +231,7 @@ function createOutstreamEmbedCode(bid) { script.type = 'text/javascript'; script.src = urls.pubTag; script.onload = function () { - window.ShowheroesTag=this; + window.ShowheroesTag = this; }; script.setAttribute('data-player-host', urls.vlHost); @@ -260,7 +253,7 @@ function getBannerHtml (bid, reqBid, reqData) { return ` -