1
- import { deepAccess , getBidIdParameter , getWindowTop , logError } from '../src/utils.js' ;
1
+ import {
2
+ deepAccess ,
3
+ getBidIdParameter ,
4
+ getWindowTop ,
5
+ triggerPixel ,
6
+ logInfo ,
7
+ logError
8
+ } from '../src/utils.js' ;
2
9
import { config } from '../src/config.js' ;
3
10
import { Renderer } from '../src/Renderer.js' ;
4
11
import { registerBidder } from '../src/adapters/bidderFactory.js' ;
@@ -7,6 +14,7 @@ import { loadExternalScript } from '../src/adloader.js';
7
14
8
15
const PROD_ENDPOINT = 'https://bs.showheroes.com/api/v1/bid' ;
9
16
const STAGE_ENDPOINT = 'https://bid-service.stage.showheroes.com/api/v1/bid' ;
17
+ const VIRALIZE_ENDPOINT = 'https://ads.viralize.tv/prebid-sh/' ;
10
18
const PROD_PUBLISHER_TAG = 'https://static.showheroes.com/publishertag.js' ;
11
19
const STAGE_PUBLISHER_TAG = 'https://pubtag.stage.showheroes.com/publishertag.js' ;
12
20
const PROD_VL = 'https://video-library.showheroes.com' ;
@@ -26,12 +34,13 @@ export const spec = {
26
34
aliases : [ 'showheroesBs' ] ,
27
35
supportedMediaTypes : [ VIDEO , BANNER ] ,
28
36
isBidRequestValid : function ( bid ) {
29
- return ! ! bid . params . playerId ;
37
+ return ! ! bid . params . playerId || ! ! bid . params . unitId ;
30
38
} ,
31
39
buildRequests : function ( validBidRequests , bidderRequest ) {
32
40
let adUnits = [ ] ;
33
- const pageURL = validBidRequests [ 0 ] . params . contentPageUrl || bidderRequest . refererInfo . page ;
41
+ const pageURL = validBidRequests [ 0 ] . params . contentPageUrl || bidderRequest . refererInfo . referer ;
34
42
const isStage = ! ! validBidRequests [ 0 ] . params . stage ;
43
+ const isViralize = ! ! validBidRequests [ 0 ] . params . unitId ;
35
44
const isOutstream = deepAccess ( validBidRequests [ 0 ] , 'mediaTypes.video.context' ) === 'outstream' ;
36
45
const isCustomRender = deepAccess ( validBidRequests [ 0 ] , 'params.outstreamOptions.customRender' ) ;
37
46
const isNodeRender = deepAccess ( validBidRequests [ 0 ] , 'params.outstreamOptions.slot' ) || deepAccess ( validBidRequests [ 0 ] , 'params.outstreamOptions.iframe' ) ;
@@ -40,12 +49,19 @@ export const spec = {
40
49
const isBanner = ! ! validBidRequests [ 0 ] . mediaTypes . banner || ( isOutstream && ! ( isCustomRender || isNativeRender || isNodeRender ) ) ;
41
50
const defaultSchain = validBidRequests [ 0 ] . schain || { } ;
42
51
52
+ const consentData = bidderRequest . gdprConsent || { } ;
53
+ const gdprConsent = {
54
+ apiVersion : consentData . apiVersion || 2 ,
55
+ gdprApplies : consentData . gdprApplies || 0 ,
56
+ consentString : consentData . consentString || '' ,
57
+ }
58
+
43
59
validBidRequests . forEach ( ( bid ) => {
44
60
const videoSizes = getVideoSizes ( bid ) ;
45
61
const bannerSizes = getBannerSizes ( bid ) ;
46
62
const vpaidMode = getBidIdParameter ( 'vpaidMode' , bid . params ) ;
47
63
48
- const makeBids = ( type , size ) => {
64
+ const makeBids = ( type , size , isViralize ) => {
49
65
let context = '' ;
50
66
let streamType = 2 ;
51
67
@@ -61,53 +77,79 @@ export const spec = {
61
77
}
62
78
}
63
79
64
- const consentData = bidderRequest . gdprConsent || { } ;
65
-
66
- const gdprConsent = {
67
- apiVersion : consentData . apiVersion || 2 ,
68
- gdprApplies : consentData . gdprApplies || 0 ,
69
- consentString : consentData . consentString || '' ,
70
- }
71
-
72
- return {
80
+ let rBid = {
73
81
type : streamType ,
74
82
adUnitCode : bid . adUnitCode ,
75
83
bidId : bid . bidId ,
76
- mediaType : type ,
77
84
context : context ,
78
- playerId : getBidIdParameter ( 'playerId' , bid . params ) ,
79
85
auctionId : bidderRequest . auctionId ,
80
86
bidderCode : BIDDER_CODE ,
81
- gdprConsent : gdprConsent ,
82
87
start : + new Date ( ) ,
83
88
timeout : 3000 ,
84
- size : {
85
- width : size [ 0 ] ,
86
- height : size [ 1 ]
87
- } ,
88
89
params : bid . params ,
89
- schain : bid . schain || defaultSchain ,
90
+ schain : bid . schain || defaultSchain
90
91
} ;
92
+
93
+ if ( isViralize ) {
94
+ rBid . unitId = getBidIdParameter ( 'unitId' , bid . params ) ;
95
+ rBid . sizes = size ;
96
+ rBid . mediaTypes = {
97
+ [ type ] : { 'context' : context }
98
+ } ;
99
+ } else {
100
+ rBid . playerId = getBidIdParameter ( 'playerId' , bid . params ) ;
101
+ rBid . mediaType = type ;
102
+ rBid . size = {
103
+ width : size [ 0 ] ,
104
+ height : size [ 1 ]
105
+ } ;
106
+ rBid . gdprConsent = gdprConsent ;
107
+ }
108
+
109
+ return rBid ;
91
110
} ;
92
111
93
- videoSizes . forEach ( ( size ) => {
94
- adUnits . push ( makeBids ( VIDEO , size ) ) ;
95
- } ) ;
112
+ if ( isViralize ) {
113
+ if ( videoSizes && videoSizes [ 0 ] ) {
114
+ adUnits . push ( makeBids ( VIDEO , videoSizes , isViralize ) ) ;
115
+ }
116
+ if ( bannerSizes && bannerSizes [ 0 ] ) {
117
+ adUnits . push ( makeBids ( BANNER , bannerSizes , isViralize ) ) ;
118
+ }
119
+ } else {
120
+ videoSizes . forEach ( ( size ) => {
121
+ adUnits . push ( makeBids ( VIDEO , size ) ) ;
122
+ } ) ;
96
123
97
- bannerSizes . forEach ( ( size ) => {
98
- adUnits . push ( makeBids ( BANNER , size ) ) ;
99
- } ) ;
124
+ bannerSizes . forEach ( ( size ) => {
125
+ adUnits . push ( makeBids ( BANNER , size ) ) ;
126
+ } ) ;
127
+ }
100
128
} ) ;
101
129
102
- return {
103
- url : isStage ? STAGE_ENDPOINT : PROD_ENDPOINT ,
104
- method : 'POST' ,
105
- options : { contentType : 'application/json' , accept : 'application/json' } ,
106
- data : {
130
+ let endpointUrl ;
131
+ let data ;
132
+
133
+ const QA = validBidRequests [ 0 ] . params . qa || { } ;
134
+
135
+ if ( isViralize ) {
136
+ endpointUrl = VIRALIZE_ENDPOINT ;
137
+ data = {
138
+ 'bidRequests' : adUnits ,
139
+ 'context' : {
140
+ 'gdprConsent' : gdprConsent ,
141
+ 'schain' : defaultSchain ,
142
+ 'pageURL' : QA . pageURL || encodeURIComponent ( pageURL )
143
+ }
144
+ }
145
+ } else {
146
+ endpointUrl = isStage ? STAGE_ENDPOINT : PROD_ENDPOINT ;
147
+
148
+ data = {
107
149
'user' : [ ] ,
108
150
'meta' : {
109
151
'adapterVersion' : 2 ,
110
- 'pageURL' : encodeURIComponent ( pageURL ) ,
152
+ 'pageURL' : QA . pageURL || encodeURIComponent ( pageURL ) ,
111
153
'vastCacheEnabled' : ( ! ! config . getConfig ( 'cache' ) && ! isBanner && ! outstreamOptions ) || false ,
112
154
'isDesktop' : getWindowTop ( ) . document . documentElement . clientWidth > 700 ,
113
155
'xmlAndTag' : ! ! ( isOutstream && isCustomRender ) || false ,
@@ -116,6 +158,13 @@ export const spec = {
116
158
'requests' : adUnits ,
117
159
'debug' : validBidRequests [ 0 ] . params . debug || false ,
118
160
}
161
+ }
162
+
163
+ return {
164
+ url : QA . endpoint || endpointUrl ,
165
+ method : 'POST' ,
166
+ options : { contentType : 'application/json' , accept : 'application/json' } ,
167
+ data : data
119
168
} ;
120
169
} ,
121
170
interpretResponse : function ( response , request ) {
@@ -149,33 +198,53 @@ export const spec = {
149
198
}
150
199
return syncs ;
151
200
} ,
201
+
202
+ onBidWon ( bid ) {
203
+ if ( bid . callbacks ) {
204
+ triggerPixel ( bid . callbacks . won ) ;
205
+ }
206
+ logInfo (
207
+ `Showheroes adapter won the auction. Bid id: ${ bid . bidId || bid . requestId } `
208
+ ) ;
209
+ } ,
152
210
} ;
153
211
154
212
function createBids ( bidRes , reqData ) {
155
- if ( bidRes && ( ! Array . isArray ( bidRes . bids ) || bidRes . bids . length < 1 ) ) {
213
+ if ( ! bidRes ) {
214
+ return [ ] ;
215
+ }
216
+ const responseBids = bidRes . bids || bidRes . bidResponses ;
217
+ if ( ! Array . isArray ( responseBids ) || responseBids . length < 1 ) {
156
218
return [ ] ;
157
219
}
158
220
159
221
const bids = [ ] ;
160
222
const bidMap = { } ;
161
- ( reqData . requests || [ ] ) . forEach ( ( bid ) => {
223
+ ( reqData . requests || reqData . bidRequests || [ ] ) . forEach ( ( bid ) => {
162
224
bidMap [ bid . bidId ] = bid ;
163
225
} ) ;
164
226
165
- bidRes . bids . forEach ( function ( bid ) {
166
- const reqBid = bidMap [ bid . bidId ] ;
227
+ responseBids . forEach ( function ( bid ) {
228
+ const requestId = bid . bidId || bid . requestId ;
229
+ const reqBid = bidMap [ requestId ] ;
167
230
const currentBidParams = reqBid . params ;
231
+ const isViralize = ! ! reqBid . params . unitId ;
232
+ const size = {
233
+ width : bid . width || bid . size . width ,
234
+ height : bid . height || bid . size . height
235
+ } ;
236
+
168
237
let bidUnit = { } ;
169
238
bidUnit . cpm = bid . cpm ;
170
- bidUnit . requestId = bid . bidId ;
239
+ bidUnit . requestId = requestId ;
171
240
bidUnit . adUnitCode = reqBid . adUnitCode ;
172
241
bidUnit . currency = bid . currency ;
173
242
bidUnit . mediaType = bid . mediaType || VIDEO ;
174
243
bidUnit . ttl = TTL ;
175
- bidUnit . creativeId = 'c_' + bid . bidId ;
244
+ bidUnit . creativeId = 'c_' + requestId ;
176
245
bidUnit . netRevenue = true ;
177
- bidUnit . width = bid . size . width ;
178
- bidUnit . height = bid . size . height ;
246
+ bidUnit . width = size . width ;
247
+ bidUnit . height = size . height ;
179
248
bidUnit . meta = {
180
249
advertiserDomains : bid . adomain || [ ]
181
250
} ;
@@ -185,24 +254,26 @@ function createBids(bidRes, reqData) {
185
254
content : bid . vastXml ,
186
255
} ;
187
256
}
188
- if ( bid . vastTag ) {
189
- bidUnit . vastUrl = bid . vastTag ;
257
+ if ( bid . vastTag || bid . vastUrl ) {
258
+ bidUnit . vastUrl = bid . vastTag || bid . vastUrl ;
190
259
}
191
260
if ( bid . mediaType === BANNER ) {
192
261
bidUnit . ad = getBannerHtml ( bid , reqBid , reqData ) ;
193
262
} else if ( bid . context === 'outstream' ) {
194
263
const renderer = Renderer . install ( {
195
- id : bid . bidId ,
264
+ id : requestId ,
196
265
url : 'https://static.showheroes.com/renderer.js' ,
197
266
adUnitCode : reqBid . adUnitCode ,
198
267
config : {
199
268
playerId : reqBid . playerId ,
200
- width : bid . size . width ,
201
- height : bid . size . height ,
269
+ width : size . width ,
270
+ height : size . height ,
202
271
vastUrl : bid . vastTag ,
203
272
vastXml : bid . vastXml ,
273
+ ad : bid . ad ,
204
274
debug : reqData . debug ,
205
- isStage : ! ! reqData . meta . stage ,
275
+ isStage : reqData . meta && ! ! reqData . meta . stage ,
276
+ isViralize : isViralize ,
206
277
customRender : getBidIdParameter ( 'customRender' , currentBidParams . outstreamOptions ) ,
207
278
slot : getBidIdParameter ( 'slot' , currentBidParams . outstreamOptions ) ,
208
279
iframe : getBidIdParameter ( 'iframe' , currentBidParams . outstreamOptions ) ,
@@ -218,7 +289,12 @@ function createBids(bidRes, reqData) {
218
289
}
219
290
220
291
function outstreamRender ( bid ) {
221
- const embedCode = createOutstreamEmbedCode ( bid ) ;
292
+ let embedCode ;
293
+ if ( bid . renderer . config . isViralize ) {
294
+ embedCode = createOutstreamEmbedCodeV2 ( bid ) ;
295
+ } else {
296
+ embedCode = createOutstreamEmbedCode ( bid ) ;
297
+ }
222
298
if ( typeof bid . renderer . config . customRender === 'function' ) {
223
299
bid . renderer . config . customRender ( bid , embedCode ) ;
224
300
} else {
@@ -266,6 +342,12 @@ function createOutstreamEmbedCode(bid) {
266
342
return fragment ;
267
343
}
268
344
345
+ function createOutstreamEmbedCodeV2 ( bid ) {
346
+ const range = document . createRange ( ) ;
347
+ range . selectNode ( document . getElementsByTagName ( 'body' ) [ 0 ] ) ;
348
+ return range . createContextualFragment ( getBidIdParameter ( 'ad' , bid . renderer . config ) ) ;
349
+ }
350
+
269
351
function getBannerHtml ( bid , reqBid , reqData ) {
270
352
const isStage = ! ! reqData . meta . stage ;
271
353
const urls = getEnvURLs ( isStage ) ;
0 commit comments