1
1
/* eslint dot-notation:0, quote-props:0 */
2
2
import * as utils from '../src/utils' ;
3
3
import { registerBidder } from '../src/adapters/bidderFactory' ;
4
+ import { Renderer } from '../src/Renderer' ;
4
5
5
6
const NATIVE_DEFAULTS = {
6
7
TITLE_LEN : 100 ,
@@ -13,13 +14,14 @@ const NATIVE_DEFAULTS = {
13
14
const DEFAULT_BID_TTL = 20 ;
14
15
const DEFAULT_CURRENCY = 'USD' ;
15
16
const DEFAULT_NET_REVENUE = true ;
17
+ const KNOWN_PARAMS = [ 'cp' , 'ct' , 'cf' , 'video' , 'battr' , 'bcat' , 'badv' , 'bidfloor' ] ;
16
18
17
19
/**
18
20
* PulsePoint Bid Adapter.
19
21
20
22
*
21
23
* Aliases - pulseLite and pulsepointLite are supported for backwards compatibility.
22
- * Formats - Display/Native/Outstream formats supported.
24
+ * Formats - Display/Native/Video formats supported.
23
25
*
24
26
*/
25
27
export const spec = {
@@ -28,7 +30,7 @@ export const spec = {
28
30
29
31
aliases : [ 'pulseLite' , 'pulsepointLite' ] ,
30
32
31
- supportedMediaTypes : [ 'banner' , 'native' ] ,
33
+ supportedMediaTypes : [ 'banner' , 'native' , 'video' ] ,
32
34
33
35
isBidRequestValid : bid => (
34
36
! ! ( bid && bid . params && bid . params . cp && bid . params . ct )
@@ -41,12 +43,16 @@ export const spec = {
41
43
site : site ( bidRequests ) ,
42
44
app : app ( bidRequests ) ,
43
45
device : device ( ) ,
46
+ bcat : bidRequests [ 0 ] . params . bcat ,
47
+ badv : bidRequests [ 0 ] . params . badv ,
48
+ user : user ( bidRequests [ 0 ] , bidderRequest ) ,
49
+ regs : regs ( bidderRequest ) ,
44
50
} ;
45
- applyGdpr ( bidderRequest , request ) ;
46
51
return {
47
52
method : 'POST' ,
48
- url : '//bid.contextweb.com/header/ortb' ,
49
- data : JSON . stringify ( request ) ,
53
+ url : 'https://bid.contextweb.com/header/ortb?src=prebid' ,
54
+ data : request ,
55
+ bidderRequest
50
56
} ;
51
57
} ,
52
58
@@ -58,12 +64,12 @@ export const spec = {
58
64
if ( syncOptions . iframeEnabled ) {
59
65
return [ {
60
66
type : 'iframe' ,
61
- url : '//bh.contextweb.com/visitormatch'
67
+ url : 'https: //bh.contextweb.com/visitormatch'
62
68
} ] ;
63
69
} else if ( syncOptions . pixelEnabled ) {
64
70
return [ {
65
71
type : 'image' ,
66
- url : '//bh.contextweb.com/visitormatch/prebid'
72
+ url : 'https: //bh.contextweb.com/visitormatch/prebid'
67
73
} ] ;
68
74
}
69
75
} ,
@@ -79,12 +85,13 @@ export const spec = {
79
85
/**
80
86
* Callback for bids, after the call to PulsePoint completes.
81
87
*/
82
- function bidResponseAvailable ( bidRequest , bidResponse ) {
88
+ function bidResponseAvailable ( request , response ) {
83
89
const idToImpMap = { } ;
84
90
const idToBidMap = { } ;
85
- bidResponse = bidResponse . body
91
+ const idToSlotConfig = { } ;
92
+ const bidResponse = response . body
86
93
// extract the request bids and the response bids, keyed by impr-id
87
- const ortbRequest = parse ( bidRequest . data ) ;
94
+ const ortbRequest = request . data ;
88
95
ortbRequest . imp . forEach ( imp => {
89
96
idToImpMap [ imp . id ] = imp ;
90
97
} ) ;
@@ -93,6 +100,11 @@ function bidResponseAvailable(bidRequest, bidResponse) {
93
100
idToBidMap [ bid . impid ] = bid ;
94
101
} ) ) ;
95
102
}
103
+ if ( request . bidderRequest ) {
104
+ request . bidderRequest . bids . forEach ( bid => {
105
+ idToSlotConfig [ bid . bidId ] = bid ;
106
+ } ) ;
107
+ }
96
108
const bids = [ ] ;
97
109
Object . keys ( idToImpMap ) . forEach ( id => {
98
110
if ( idToBidMap [ id ] ) {
@@ -109,6 +121,15 @@ function bidResponseAvailable(bidRequest, bidResponse) {
109
121
if ( idToImpMap [ id ] [ 'native' ] ) {
110
122
bid [ 'native' ] = nativeResponse ( idToImpMap [ id ] , idToBidMap [ id ] ) ;
111
123
bid . mediaType = 'native' ;
124
+ } else if ( idToImpMap [ id ] . video ) {
125
+ // for outstream, a renderer is specified
126
+ if ( idToSlotConfig [ id ] && utils . deepAccess ( idToSlotConfig [ id ] , 'mediaTypes.video.context' ) === 'outstream' ) {
127
+ bid . renderer = outstreamRenderer ( utils . deepAccess ( idToSlotConfig [ id ] , 'renderer.options' ) , utils . deepAccess ( idToBidMap [ id ] , 'ext.outstream' ) ) ;
128
+ }
129
+ bid . vastXml = idToBidMap [ id ] . adm ;
130
+ bid . mediaType = 'video' ;
131
+ bid . width = idToBidMap [ id ] . w ;
132
+ bid . height = idToBidMap [ id ] . h ;
112
133
} else {
113
134
bid . ad = idToBidMap [ id ] . adm ;
114
135
bid . width = idToImpMap [ id ] . banner . w ;
@@ -138,6 +159,9 @@ function impression(slot) {
138
159
banner : banner ( slot ) ,
139
160
'native' : nativeImpression ( slot ) ,
140
161
tagid : slot . params . ct . toString ( ) ,
162
+ video : video ( slot ) ,
163
+ bidfloor : slot . params . bidfloor ,
164
+ ext : ext ( slot ) ,
141
165
} ;
142
166
}
143
167
@@ -146,12 +170,66 @@ function impression(slot) {
146
170
*/
147
171
function banner ( slot ) {
148
172
const size = adSize ( slot ) ;
149
- return slot . nativeParams ? null : {
173
+ return ( slot . nativeParams || slot . params . video ) ? null : {
150
174
w : size [ 0 ] ,
151
175
h : size [ 1 ] ,
176
+ battr : slot . params . battr ,
152
177
} ;
153
178
}
154
179
180
+ /**
181
+ * Produces an OpenRTB Video object for the slot given
182
+ */
183
+ function video ( slot ) {
184
+ if ( slot . params . video ) {
185
+ return Object . assign ( { } , slot . params . video , { battr : slot . params . battr } ) ;
186
+ }
187
+ return null ;
188
+ }
189
+
190
+ /**
191
+ * Unknown params are captured and sent on ext
192
+ */
193
+ function ext ( slot ) {
194
+ const ext = { } ;
195
+ const knownParamsMap = { } ;
196
+ KNOWN_PARAMS . forEach ( value => knownParamsMap [ value ] = 1 ) ;
197
+ Object . keys ( slot . params ) . forEach ( key => {
198
+ if ( ! knownParamsMap [ key ] ) {
199
+ ext [ key ] = slot . params [ key ] ;
200
+ }
201
+ } ) ;
202
+ return Object . keys ( ext ) . length > 0 ? { prebid : ext } : null ;
203
+ }
204
+
205
+ /**
206
+ * Sets up the renderer on the bid, for outstream bid responses.
207
+ */
208
+ function outstreamRenderer ( rendererOptions , outstreamExtOptions ) {
209
+ const renderer = Renderer . install ( {
210
+ url : outstreamExtOptions . rendererUrl ,
211
+ config : {
212
+ defaultOptions : outstreamExtOptions . config ,
213
+ rendererOptions,
214
+ type : outstreamExtOptions . type
215
+ } ,
216
+ loaded : false ,
217
+ } ) ;
218
+ renderer . setRender ( ( bid ) => {
219
+ bid . renderer . push ( ( ) => {
220
+ const config = bid . renderer . getConfig ( ) ;
221
+ new window . PulsePointOutstreamRenderer ( ) . render ( {
222
+ adUnitCode : bid . adUnitCode ,
223
+ vastXml : bid . vastXml ,
224
+ type : config . type ,
225
+ defaultOptions : config . defaultOptions ,
226
+ rendererOptions
227
+ } ) ;
228
+ } ) ;
229
+ } ) ;
230
+ return renderer ;
231
+ }
232
+
155
233
/**
156
234
* Produces an OpenRTB Native object for the slot given.
157
235
*/
@@ -166,6 +244,7 @@ function nativeImpression(slot) {
166
244
return {
167
245
request : JSON . stringify ( { assets } ) ,
168
246
ver : '1.1' ,
247
+ battr : slot . params . battr ,
169
248
} ;
170
249
}
171
250
return null ;
@@ -312,13 +391,50 @@ function adSize(slot) {
312
391
}
313
392
314
393
/**
315
- * Applies GDPR parameters to request.
394
+ * Handles the user level attributes and produces
395
+ * an openrtb User object.
316
396
*/
317
- function applyGdpr ( bidderRequest , ortbRequest ) {
397
+ function user ( bidRequest , bidderRequest ) {
398
+ var ext = { } ;
399
+ if ( bidderRequest ) {
400
+ if ( bidderRequest . gdprConsent ) {
401
+ ext . consent = bidderRequest . gdprConsent . consentString ;
402
+ }
403
+ }
404
+ if ( bidRequest ) {
405
+ if ( bidRequest . userId ) {
406
+ ext . eids = [ ] ;
407
+ addExternalUserId ( ext . eids , bidRequest . userId . pubcid , 'pubcommon' ) ;
408
+ addExternalUserId ( ext . eids , bidRequest . userId . tdid , 'ttdid' ) ;
409
+ addExternalUserId ( ext . eids , utils . deepAccess ( bidRequest . userId . digitrustid , 'data.id' ) , 'digitrust' ) ;
410
+ addExternalUserId ( ext . eids , bidRequest . userId . id5id , 'id5id' ) ;
411
+ }
412
+ }
413
+ return { ext } ;
414
+ }
415
+
416
+ /**
417
+ * Produces external userid object in ortb 3.0 model.
418
+ */
419
+ function addExternalUserId ( eids , value , source ) {
420
+ if ( value ) {
421
+ eids . push ( {
422
+ source,
423
+ uids : [ {
424
+ id : value
425
+ } ]
426
+ } ) ;
427
+ }
428
+ }
429
+
430
+ /**
431
+ * Produces the regulations ortb object
432
+ */
433
+ function regs ( bidderRequest ) {
318
434
if ( bidderRequest && bidderRequest . gdprConsent ) {
319
- ortbRequest . regs = { ext : { gdpr : bidderRequest . gdprConsent . gdprApplies ? 1 : 0 } } ;
320
- ortbRequest . user = { ext : { consent : bidderRequest . gdprConsent . consentString } } ;
435
+ return { ext : { gdpr : bidderRequest . gdprConsent . gdprApplies ? 1 : 0 } } ;
321
436
}
437
+ return null ;
322
438
}
323
439
324
440
/**
0 commit comments