Skip to content

Commit bfcdb91

Browse files
ShowHeroes adapter - expanded outstream support
1 parent b6c0154 commit bfcdb91

File tree

2 files changed

+132
-5
lines changed

2 files changed

+132
-5
lines changed

modules/shBidAdapter.js

+97-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as utils from '../src/utils';
22
import { config } from '../src/config';
3+
import { Renderer } from '../src/Renderer';
34
import { registerBidder } from '../src/adapters/bidderFactory';
45
import { VIDEO, BANNER } from '../src/mediaTypes';
56

@@ -12,6 +13,13 @@ const STAGE_VL = 'https://video-library.stage.showheroes.com';
1213
const BIDDER_CODE = 'showheroes-bs';
1314
const TTL = 300;
1415

16+
function getEnvURLs(isStage) {
17+
return {
18+
pubTag: isStage ? STAGE_PUBLISHER_TAG : PROD_PUBLISHER_TAG,
19+
vlHost: isStage ? STAGE_VL : PROD_VL
20+
}
21+
}
22+
1523
export const spec = {
1624
code: BIDDER_CODE,
1725
aliases: ['showheroesBs'],
@@ -23,6 +31,9 @@ export const spec = {
2331
const pageURL = validBidRequests[0].params.contentPageUrl || bidderRequest.refererInfo.referer;
2432
const isStage = !!validBidRequests[0].params.stage;
2533
const isBanner = !!validBidRequests[0].mediaTypes.banner;
34+
const isOutstream = utils.deepAccess(validBidRequests[0], 'mediaTypes.video.context');
35+
const isCustomRender = utils.deepAccess(validBidRequests[0], 'params.outstreamOptions.customRender');
36+
const outstreamOptions = utils.deepAccess(validBidRequests[0], 'params.outstreamOptions');
2637

2738
let adUnits = validBidRequests.map((bid) => {
2839
const vpaidMode = utils.getBidIdParameter('vpaidMode', bid.params);
@@ -57,6 +68,7 @@ export const spec = {
5768
type: streamType,
5869
bidId: bid.bidId,
5970
mediaType: isBanner ? BANNER : VIDEO,
71+
context: context,
6072
playerId: utils.getBidIdParameter('playerId', bid.params),
6173
auctionId: bidderRequest.auctionId,
6274
bidderCode: BIDDER_CODE,
@@ -67,6 +79,7 @@ export const spec = {
6779
width: sizes[0],
6880
height: sizes[1]
6981
},
82+
bidRequest: bidderRequest,
7083
};
7184
});
7285

@@ -78,8 +91,9 @@ export const spec = {
7891
'user': [],
7992
'meta': {
8093
'pageURL': encodeURIComponent(pageURL),
81-
'vastCacheEnabled': (!!config.getConfig('cache') && !isBanner) || false,
94+
'vastCacheEnabled': (!!config.getConfig('cache') && !isBanner && !outstreamOptions) || false,
8295
'isDesktop': utils.getWindowTop().document.documentElement.clientWidth > 700,
96+
'xmlAndTag': (isOutstream && isCustomRender) || false,
8397
'stage': isStage || undefined
8498
},
8599
'requests': adUnits,
@@ -133,6 +147,14 @@ function createBids(bidRes, reqData) {
133147

134148
bidRes.bids.forEach(function (bid) {
135149
const reqBid = bidMap[bid.bidId];
150+
let currentBidRequest;
151+
for (let i in reqBid.bidRequest.bids) {
152+
if (bid.bidId === reqBid.bidRequest.bids[i].bidId) {
153+
currentBidRequest = reqBid.bidRequest.bids[i];
154+
break;
155+
}
156+
}
157+
136158
let bidUnit = {};
137159
bidUnit.cpm = bid.cpm;
138160
bidUnit.requestId = bid.bidId;
@@ -154,25 +176,95 @@ function createBids(bidRes, reqData) {
154176
}
155177
if (reqBid.mediaType === BANNER) {
156178
bidUnit.ad = getBannerHtml(bid, reqBid, reqData);
179+
} else if (reqBid.context === 'outstream') {
180+
const renderer = Renderer.install({
181+
id: bid.bidId,
182+
url: '//',
183+
config: {
184+
playerId: reqBid.playerId,
185+
width: bid.video.width,
186+
height: bid.video.height,
187+
vastUrl: bid.vastTag,
188+
vastXml: bid.vastXml,
189+
debug: reqData.debug,
190+
isStage: !!reqData.meta.stage,
191+
customRender: utils.getBidIdParameter('customRender', currentBidRequest.params.outstreamOptions),
192+
slot: utils.getBidIdParameter('slot', currentBidRequest.params.outstreamOptions),
193+
iframe: utils.getBidIdParameter('iframe', currentBidRequest.params.outstreamOptions),
194+
}
195+
});
196+
renderer.setRender(outstreamRender);
197+
bidUnit.renderer = renderer;
157198
}
158199
bids.push(bidUnit);
159200
});
160201

161202
return bids;
162203
}
163204

205+
function outstreamRender(bid) {
206+
const embedCode = createOutstreamEmbedCode(bid);
207+
if (typeof bid.renderer.config.customRender === 'function') {
208+
bid.renderer.config.customRender(bid, embedCode);
209+
} else {
210+
try {
211+
const inIframe = utils.getBidIdParameter('iframe', bid.renderer.config);
212+
if (inIframe && window.document.getElementById(inIframe).nodeName === 'IFRAME') {
213+
const iframe = window.document.getElementById(inIframe);
214+
let framedoc = iframe.contentDocument || (iframe.contentWindow && iframe.contentWindow.document);
215+
framedoc.body.appendChild(embedCode);
216+
return;
217+
}
218+
219+
const slot = utils.getBidIdParameter('slot', bid.renderer.config);
220+
if (slot && window.document.getElementById(slot)) {
221+
window.document.getElementById(slot).appendChild(embedCode);
222+
} else if (slot) {
223+
utils.logError('[ShowHeroes][renderer] Error: spot not found');
224+
}
225+
} catch (err) {
226+
utils.logError('[ShowHeroes][renderer] Error:' + err.message)
227+
}
228+
}
229+
}
230+
231+
function createOutstreamEmbedCode(bid) {
232+
const isStage = utils.getBidIdParameter('isStage', bid.renderer.config);
233+
const urls = getEnvURLs(isStage);
234+
235+
const fragment = window.document.createDocumentFragment();
236+
237+
const script = window.document.createElement('script');
238+
script.type = 'text/javascript';
239+
script.src = urls.pubTag;
240+
script.onload = function () {
241+
window.ShowheroesTag = this;
242+
};
243+
script.setAttribute('data-player-host', urls.vlHost);
244+
245+
const spot = window.document.createElement('div');
246+
spot.setAttribute('class', 'showheroes-spot');
247+
spot.setAttribute('data-player', utils.getBidIdParameter('playerId', bid.renderer.config));
248+
spot.setAttribute('data-debug', utils.getBidIdParameter('debug', bid.renderer.config));
249+
spot.setAttribute('data-ad-vast-tag', utils.getBidIdParameter('vastUrl', bid.renderer.config));
250+
spot.setAttribute('data-stream-type', 'outstream');
251+
252+
fragment.appendChild(spot);
253+
fragment.appendChild(script);
254+
return fragment;
255+
}
256+
164257
function getBannerHtml (bid, reqBid, reqData) {
165258
const isStage = !!reqData.meta.stage;
166-
const pubTag = isStage ? STAGE_PUBLISHER_TAG : PROD_PUBLISHER_TAG;
167-
const vlHost = isStage ? STAGE_VL : PROD_VL;
259+
const urls = getEnvURLs(isStage);
168260
return `<html>
169261
<head></head>
170262
<body>
171-
<script async src="${pubTag}"
263+
<script async src="${urls.pubTag}"
172264
data-canvas=""
173265
data-noad-passback-listener=""
174266
onload="window.ShowheroesTag=this"
175-
data-player-host="${vlHost}"></script>
267+
data-player-host="${urls.vlHost}"></script>
176268
<div class="showheroes-spot"
177269
data-debug="${reqData.debug ? '1' : ''}"
178270
data-player="${reqBid.playerId}"

modules/shBidAdapter.md

+35
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,41 @@ Module that connects to ShowHeroes demand source to fetch bids.
4949
}
5050
]
5151
},
52+
{
53+
code: 'video',
54+
mediaTypes: {
55+
video: {
56+
playerSize: [640, 480],
57+
context: 'outstream',
58+
}
59+
},
60+
bids: [
61+
{
62+
bidder: "showheroes-bs",
63+
params: {
64+
playerId: '0151f985-fb1a-4f37-bb26-cfc62e43ec05',
65+
vpaidMode: true, // by default is 'false'
66+
outstreamOptions: {
67+
// Required for the default outstream renderer, one of
68+
iframe: 'iframe_id',
69+
slot: 'slot_id'
70+
71+
// Custom outstream rendering function
72+
customRender: function(bid, embedCode) {
73+
// Example with embedCode
74+
someContainer.appendChild(embedCode);
75+
76+
// bid config data
77+
var vastUrl = bid.renderer.config.vastUrl;
78+
var videoWidth = bid.renderer.config.width;
79+
var videoHeight = bid.renderer.config.height;
80+
var playerId = bid.renderer.config.playerId;
81+
},
82+
}
83+
}
84+
}
85+
]
86+
},
5287
{
5388
code: 'banner',
5489
mediaTypes: {

0 commit comments

Comments
 (0)