prebid.js 7.48.0 → 7.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/33acrossIdSystem.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/admixerBidAdapter.js +1 -1
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adtrgtmeBidAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/adyoulikeBidAdapter.js +1 -1
- package/dist/aidemBidAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/beopBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/carodaBidAdapter.js +1 -1
- package/dist/chtnwBidAdapter.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/confiantRtdProvider.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantAnalyticsAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/cwireBidAdapter.js +1 -1
- package/dist/dependencies.json +3 -0
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/feedadBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/freewheel-sspBidAdapter.js +1 -1
- package/dist/glimpseBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/greenbidsAnalyticsAdapter.js +1 -1
- package/dist/greenbidsRtdProvider.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/inmarBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/kargoBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/kueezRtbBidAdapter.js +1 -1
- package/dist/kulturemediaBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/lifestreetBidAdapter.js +1 -1
- package/dist/liveIntentIdSystem.js +1 -1
- package/dist/liveyieldAnalyticsAdapter.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/magniteAnalyticsAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/minutemediaplusBidAdapter.js +1 -1
- package/dist/nexx360BidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +136 -134
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/optidigitalBidAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/permutiveRtdProvider.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +1 -1
- package/dist/prebidServerBidAdapter.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticAnalyticsAdapter.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/retailspotBidAdapter.js +1 -0
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseBidAdapter.js +1 -1
- package/dist/rubiconAnalyticsAdapter.js +1 -1
- package/dist/rubiconBidAdapter.js +1 -1
- package/dist/seedingAllianceBidAdapter.js +1 -1
- package/dist/seedtagBidAdapter.js +1 -1
- package/dist/sharethroughAnalyticsAdapter.js +1 -1
- package/dist/sharethroughBidAdapter.js +1 -1
- package/dist/shinezBidAdapter.js +1 -1
- package/dist/silverpushBidAdapter.js +1 -0
- package/dist/smaatoBidAdapter.js +1 -1
- package/dist/smartadserverBidAdapter.js +1 -1
- package/dist/smartxBidAdapter.js +1 -1
- package/dist/smilewantedBidAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnAnalyticsAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/stvBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/synacormediaBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/trionBidAdapter.js +1 -1
- package/dist/tripleliftBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.js +1 -1
- package/dist/uid2IdSystem.js +1 -1
- package/dist/underdogmediaBidAdapter.js +1 -1
- package/dist/undertoneBidAdapter.js +1 -1
- package/dist/vidazooBidAdapter.js +1 -1
- package/dist/video.js +1 -1
- package/dist/videoModule.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/visxBidAdapter.js +1 -1
- package/dist/vuukleBidAdapter.js +1 -1
- package/dist/widespaceBidAdapter.js +1 -1
- package/dist/winrBidAdapter.js +1 -1
- package/dist/yahoosspBidAdapter.js +1 -1
- package/dist/yieldlabBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/integrationExamples/videoModule/eventsUI/eventsUI.css +205 -0
- package/integrationExamples/videoModule/eventsUI/eventsUI.js +181 -0
- package/integrationExamples/videoModule/jwplayer/eventsUI.html +295 -0
- package/integrationExamples/videoModule/videojs/eventsUI.html +319 -0
- package/libraries/video/shared/helpers.js +14 -0
- package/modules/33acrossBidAdapter.js +1 -1
- package/modules/adgenerationBidAdapter.js +24 -15
- package/modules/admixerBidAdapter.js +15 -9
- package/modules/aidemBidAdapter.js +3 -1
- package/modules/appnexusBidAdapter.js +1 -0
- package/modules/beopBidAdapter.js +1 -0
- package/modules/confiantRtdProvider.js +15 -12
- package/modules/conversantAnalyticsAdapter.js +7 -5
- package/modules/conversantBidAdapter.js +1 -1
- package/modules/criteoBidAdapter.js +17 -1
- package/modules/gridBidAdapter.js +3 -0
- package/modules/ixBidAdapter.js +65 -47
- package/modules/kueezRtbBidAdapter.js +30 -33
- package/modules/liveIntentIdSystem.js +8 -4
- package/modules/magniteAnalyticsAdapter.js +26 -3
- package/modules/mgidBidAdapter.js +9 -8
- package/modules/minutemediaBidAdapter.js +6 -0
- package/modules/minutemediaplusBidAdapter.js +30 -32
- package/modules/nexx360BidAdapter.js +2 -1
- package/modules/permutiveRtdProvider.js +9 -38
- package/modules/prebidServerBidAdapter/index.js +1 -3
- package/modules/prebidServerBidAdapter/ortbConverter.js +5 -1
- package/modules/pubmaticAnalyticsAdapter.js +3 -2
- package/modules/retailspotBidAdapter .md +32 -0
- package/modules/retailspotBidAdapter.js +186 -0
- package/modules/riseBidAdapter.js +6 -0
- package/modules/rubiconBidAdapter.js +6 -2
- package/modules/silverpushBidAdapter.js +326 -0
- package/modules/silverpushBidAdapter.md +107 -0
- package/modules/ttdBidAdapter.js +23 -22
- package/modules/underdogmediaBidAdapter.js +2 -2
- package/modules/vidazooBidAdapter.js +28 -32
- package/modules/videoModule/adQueue.js +2 -2
- package/modules/videoModule/index.js +9 -5
- package/modules/yahoosspBidAdapter.js +6 -0
- package/modules/yahoosspBidAdapter.md +37 -0
- package/modules/yieldlabBidAdapter.js +27 -5
- package/package.json +1 -1
- package/src/adapterManager.js +4 -0
- package/src/adapters/bidderFactory.js +1 -0
- package/src/auction.js +2 -0
- package/src/prebid.js +36 -12
- package/src/utils/cpm.js +4 -1
- package/test/spec/modules/33acrossBidAdapter_spec.js +4 -3
- package/test/spec/modules/adgenerationBidAdapter_spec.js +6 -6
- package/test/spec/modules/admixerBidAdapter_spec.js +64 -25
- package/test/spec/modules/aidemBidAdapter_spec.js +3 -0
- package/test/spec/modules/beopBidAdapter_spec.js +4 -0
- package/test/spec/modules/confiantRtdProvider_spec.js +4 -1
- package/test/spec/modules/conversantBidAdapter_spec.js +2 -1
- package/test/spec/modules/criteoBidAdapter_spec.js +109 -0
- package/test/spec/modules/gridBidAdapter_spec.js +3 -0
- package/test/spec/modules/ixBidAdapter_spec.js +66 -1
- package/test/spec/modules/kueezRtbBidAdapter_spec.js +3 -2
- package/test/spec/modules/liveIntentIdMinimalSystem_spec.js +28 -0
- package/test/spec/modules/liveIntentIdSystem_spec.js +45 -0
- package/test/spec/modules/magniteAnalyticsAdapter_spec.js +16 -36
- package/test/spec/modules/mass_spec.js +2 -0
- package/test/spec/modules/mgidBidAdapter_spec.js +9 -9
- package/test/spec/modules/minutemediaBidAdapter_spec.js +18 -0
- package/test/spec/modules/minutemediaplusBidAdapter_spec.js +3 -2
- package/test/spec/modules/permutiveRtdProvider_spec.js +0 -20
- package/test/spec/modules/prebidServerBidAdapter_spec.js +96 -1
- package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +6 -1
- package/test/spec/modules/retailspotBidAdapter_spec.js +426 -0
- package/test/spec/modules/riseBidAdapter_spec.js +18 -0
- package/test/spec/modules/rubiconBidAdapter_spec.js +143 -67
- package/test/spec/modules/silverpushBidAdapter_spec.js +394 -0
- package/test/spec/modules/ttdBidAdapter_spec.js +129 -2
- package/test/spec/modules/underdogmediaBidAdapter_spec.js +1 -1
- package/test/spec/modules/vidazooBidAdapter_spec.js +3 -2
- package/test/spec/modules/videoModule/shared/helpers_spec.js +22 -0
- package/test/spec/modules/yahoosspBidAdapter_spec.js +60 -1
- package/test/spec/modules/yieldlabBidAdapter_spec.js +8 -1
- package/test/spec/unit/core/bidderFactory_spec.js +9 -9
- package/test/spec/unit/pbjs_api_spec.js +59 -1
- package/test/spec/unit/utils/cpm_spec.js +56 -1
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import {buildUrl, deepAccess, parseSizesInput} from '../src/utils.js';
|
|
2
|
+
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
3
|
+
import {BANNER, VIDEO} from '../src/mediaTypes.js';
|
|
4
|
+
|
|
5
|
+
const BIDDER_CODE = 'retailspot';
|
|
6
|
+
const DEFAULT_SUBDOMAIN = 'ssp';
|
|
7
|
+
const PREPROD_SUBDOMAIN = 'ssp-preprod';
|
|
8
|
+
const HOST = 'retail-spot.io';
|
|
9
|
+
const ENDPOINT = '/prebid';
|
|
10
|
+
const DEV_URL = 'http://localhost:8090/prebid';
|
|
11
|
+
|
|
12
|
+
export const spec = {
|
|
13
|
+
code: BIDDER_CODE,
|
|
14
|
+
supportedMediaTypes: [BANNER, VIDEO],
|
|
15
|
+
aliases: ['rs'], // short code
|
|
16
|
+
/**
|
|
17
|
+
* Determines whether or not the given bid request is valid.
|
|
18
|
+
*
|
|
19
|
+
* @param {BidRequest} bid The bid params to validate.
|
|
20
|
+
* @return boolean True if this is a valid bid, and false otherwise.
|
|
21
|
+
*/
|
|
22
|
+
isBidRequestValid: function (bid) {
|
|
23
|
+
const sizes = getSize(getSizeArray(bid));
|
|
24
|
+
const sizeValid = sizes.width > 0 && sizes.height > 0;
|
|
25
|
+
|
|
26
|
+
return deepAccess(bid, 'params.placement') && sizeValid;
|
|
27
|
+
},
|
|
28
|
+
/**
|
|
29
|
+
* Make a server request from the list of BidRequests.
|
|
30
|
+
*
|
|
31
|
+
* @param {bidRequests} - bidRequests.bids[] is an array of AdUnits and bids
|
|
32
|
+
* @return ServerRequest Info describing the request to the server.
|
|
33
|
+
*/
|
|
34
|
+
buildRequests: function (bidRequests, bidderRequest) {
|
|
35
|
+
const payload = bidderRequest;
|
|
36
|
+
payload.rs_pbjs_version = '$prebid.version$';
|
|
37
|
+
|
|
38
|
+
const data = JSON.stringify(payload);
|
|
39
|
+
const options = {
|
|
40
|
+
withCredentials: true
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const envParam = bidRequests[0].params.env;
|
|
44
|
+
var subDomain = DEFAULT_SUBDOMAIN;
|
|
45
|
+
if (envParam === 'preprod') {
|
|
46
|
+
subDomain = PREPROD_SUBDOMAIN;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let url = buildUrl({
|
|
50
|
+
protocol: 'https',
|
|
51
|
+
host: `${subDomain}.${HOST}`,
|
|
52
|
+
pathname: ENDPOINT
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
if (envParam === 'dev') {
|
|
56
|
+
url = DEV_URL;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
method: 'POST',
|
|
61
|
+
url,
|
|
62
|
+
data,
|
|
63
|
+
options
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
/**
|
|
67
|
+
* Unpack the response from the server into a list of bids.
|
|
68
|
+
*
|
|
69
|
+
* @param {*} serverResponse A successful response from the server.
|
|
70
|
+
* @return {Bid[]} An array of bids which were nested inside the server.
|
|
71
|
+
*/
|
|
72
|
+
interpretResponse: function (serverResponse, request) {
|
|
73
|
+
const bidResponses = [];
|
|
74
|
+
var bidRequests = {};
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
bidRequests = JSON.parse(request.data).bids;
|
|
78
|
+
} catch (err) {
|
|
79
|
+
// json error initial request can't be read
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// For this adapter, serverResponse is a list
|
|
83
|
+
serverResponse.body.forEach(response => {
|
|
84
|
+
const bid = createBid(response, bidRequests);
|
|
85
|
+
if (bid) {
|
|
86
|
+
bidResponses.push(bid);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
return bidResponses;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function getSizeArray(bid) {
|
|
95
|
+
let inputSize = bid.sizes || [];
|
|
96
|
+
|
|
97
|
+
if (bid.mediaTypes && bid.mediaTypes.banner) {
|
|
98
|
+
inputSize = bid.mediaTypes.banner.sizes || [];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// handle size in bid.params in formats: [w, h] and [[w,h]].
|
|
102
|
+
if (bid.params && Array.isArray(bid.params.size)) {
|
|
103
|
+
inputSize = bid.params.size;
|
|
104
|
+
if (!Array.isArray(inputSize[0])) {
|
|
105
|
+
inputSize = [inputSize]
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return parseSizesInput(inputSize);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/* Get parsed size from request size */
|
|
113
|
+
function getSize(sizesArray) {
|
|
114
|
+
const parsed = {};
|
|
115
|
+
// the main requested size is the first one
|
|
116
|
+
const size = sizesArray[0];
|
|
117
|
+
|
|
118
|
+
if (typeof size !== 'string') {
|
|
119
|
+
return parsed;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const parsedSize = size.toUpperCase().split('X');
|
|
123
|
+
const width = parseInt(parsedSize[0], 10);
|
|
124
|
+
if (width) {
|
|
125
|
+
parsed.width = width;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const height = parseInt(parsedSize[1], 10);
|
|
129
|
+
if (height) {
|
|
130
|
+
parsed.height = height;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return parsed;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* Create bid from response */
|
|
137
|
+
function createBid(response, bidRequests) {
|
|
138
|
+
if (!response || !response.mediaType ||
|
|
139
|
+
(response.mediaType === 'video' && !response.vastXml) ||
|
|
140
|
+
(response.mediaType === 'banner' && !response.ad)) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const request = bidRequests && bidRequests.length && bidRequests.find(itm => response.requestId === itm.bidId);
|
|
145
|
+
// In case we don't retreive the size from the adserver, use the given one.
|
|
146
|
+
if (request) {
|
|
147
|
+
if (!response.width || response.width === '0') {
|
|
148
|
+
response.width = request.width;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (!response.height || response.height === '0') {
|
|
152
|
+
response.height = request.height;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const bid = {
|
|
157
|
+
bidderCode: BIDDER_CODE,
|
|
158
|
+
width: response.width,
|
|
159
|
+
height: response.height,
|
|
160
|
+
requestId: response.requestId,
|
|
161
|
+
ttl: response.ttl || 3600,
|
|
162
|
+
creativeId: response.creativeId,
|
|
163
|
+
cpm: response.cpm,
|
|
164
|
+
netRevenue: response.netRevenue,
|
|
165
|
+
currency: response.currency,
|
|
166
|
+
meta: response.meta || { advertiserDomains: ['retail-spot.io'] },
|
|
167
|
+
mediaType: response.mediaType
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// retreive video response if present
|
|
171
|
+
if (response.mediaType === 'video') {
|
|
172
|
+
bid.vastXml = window.atob(response.vastXml);
|
|
173
|
+
} else {
|
|
174
|
+
bid.ad = response.ad;
|
|
175
|
+
}
|
|
176
|
+
if (response.adId) {
|
|
177
|
+
bid.adId = response.adId;
|
|
178
|
+
}
|
|
179
|
+
if (response.dealId) {
|
|
180
|
+
bid.dealId = response.dealId;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return bid;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
registerBidder(spec);
|
|
@@ -292,6 +292,7 @@ function generateBidParameters(bid, bidderRequest) {
|
|
|
292
292
|
bidderRequestId: getBidIdParameter('bidderRequestId', bid),
|
|
293
293
|
loop: getBidIdParameter('bidderRequestsCount', bid),
|
|
294
294
|
transactionId: getBidIdParameter('transactionId', bid),
|
|
295
|
+
coppa: 0
|
|
295
296
|
};
|
|
296
297
|
|
|
297
298
|
const pos = deepAccess(bid, `mediaTypes.${mediaType}.pos`);
|
|
@@ -364,6 +365,11 @@ function generateBidParameters(bid, bidderRequest) {
|
|
|
364
365
|
if (protocols) {
|
|
365
366
|
bidObject.protocols = protocols;
|
|
366
367
|
}
|
|
368
|
+
|
|
369
|
+
const coppa = deepAccess(bid, 'ortb2.regs.coppa')
|
|
370
|
+
if (coppa) {
|
|
371
|
+
bidObject.coppa = 1;
|
|
372
|
+
}
|
|
367
373
|
}
|
|
368
374
|
|
|
369
375
|
return bidObject;
|
|
@@ -207,11 +207,15 @@ export const converter = ortbConverter({
|
|
|
207
207
|
const bidResponse = buildBidResponse(bid, context);
|
|
208
208
|
bidResponse.meta.mediaType = deepAccess(bid, 'ext.prebid.type');
|
|
209
209
|
const {bidRequest} = context;
|
|
210
|
+
|
|
211
|
+
let [parseSizeWidth, parseSizeHeight] = bidRequest.mediaTypes.video?.context === 'outstream' ? parseSizes(bidRequest, VIDEO) : [undefined, undefined];
|
|
212
|
+
|
|
213
|
+
bidResponse.width = bid.w || parseSizeWidth || bidResponse.playerWidth;
|
|
214
|
+
bidResponse.height = bid.h || parseSizeHeight || bidResponse.playerHeight;
|
|
215
|
+
|
|
210
216
|
if (bidResponse.mediaType === VIDEO && bidRequest.mediaTypes.video.context === 'outstream') {
|
|
211
217
|
bidResponse.renderer = outstreamRenderer(bidResponse);
|
|
212
218
|
}
|
|
213
|
-
bidResponse.width = bid.w || deepAccess(bidRequest, 'mediaTypes.video.w') || deepAccess(bidRequest, 'params.video.playerWidth');
|
|
214
|
-
bidResponse.height = bid.h || deepAccess(bidRequest, 'mediaTypes.video.h') || deepAccess(bidRequest, 'params.video.playerHeight');
|
|
215
219
|
|
|
216
220
|
if (deepAccess(bid, 'ext.bidder.rp.advid')) {
|
|
217
221
|
deepSetValue(bidResponse, 'meta.advertiserId', bid.ext.bidder.rp.advid);
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import { config } from '../src/config.js';
|
|
2
|
+
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
3
|
+
import * as utils from '../src/utils.js';
|
|
4
|
+
import { mergeDeep } from '../src/utils.js';
|
|
5
|
+
import { BANNER, VIDEO } from '../src/mediaTypes.js';
|
|
6
|
+
import { ortbConverter } from '../libraries/ortbConverter/converter.js';
|
|
7
|
+
import { Renderer } from '../src/Renderer.js';
|
|
8
|
+
import { ajax } from '../src/ajax.js';
|
|
9
|
+
|
|
10
|
+
const BIDDER_CODE = 'silverpush';
|
|
11
|
+
const bidderConfig = 'sp_pb_ortb';
|
|
12
|
+
const bidderVersion = '1.0.0';
|
|
13
|
+
const DEFAULT_CURRENCY = 'USD';
|
|
14
|
+
|
|
15
|
+
export const REQUEST_URL = 'https://apac.chocolateplatform.com/bidder/?identifier=prebidchoc';
|
|
16
|
+
export const SP_OUTSTREAM_PLAYER_URL = 'https://xaido.sgp1.cdn.digitaloceanspaces.com/prebid/spoutstream.min.js';
|
|
17
|
+
|
|
18
|
+
const VIDEO_ORTB_PARAMS = [
|
|
19
|
+
'mimes',
|
|
20
|
+
'minduration',
|
|
21
|
+
'maxduration',
|
|
22
|
+
'placement',
|
|
23
|
+
'protocols',
|
|
24
|
+
'startdelay',
|
|
25
|
+
'skip',
|
|
26
|
+
'skipafter',
|
|
27
|
+
'minbitrate',
|
|
28
|
+
'maxbitrate',
|
|
29
|
+
'delivery',
|
|
30
|
+
'playbackmethod',
|
|
31
|
+
'api',
|
|
32
|
+
'linearity'
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
export const VIDEO_ORTB_REQUIRED = ['api', 'mimes', 'placement', 'protocols', 'minduration', 'maxduration', 'startdelay'];
|
|
36
|
+
|
|
37
|
+
export const spec = {
|
|
38
|
+
code: BIDDER_CODE,
|
|
39
|
+
supportedMediaTypes: [BANNER, VIDEO],
|
|
40
|
+
isBidRequestValid,
|
|
41
|
+
buildRequests,
|
|
42
|
+
interpretResponse,
|
|
43
|
+
onBidWon,
|
|
44
|
+
getRequest: function(endpoint) {
|
|
45
|
+
ajax(endpoint, null, undefined, {method: 'GET'});
|
|
46
|
+
},
|
|
47
|
+
getOS: function(ua) {
|
|
48
|
+
if (ua.indexOf('Windows') != -1) { return 'Windows'; } else if (ua.match(/(iPhone|iPod|iPad)/)) { return 'iOS'; } else if (ua.indexOf('Mac OS X') != -1) { return 'macOS'; } else if (ua.match(/Android/)) { return 'Android'; } else if (ua.indexOf('Linux') != -1) { return 'Linux'; } else { return 'Unknown'; }
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
registerBidder(spec);
|
|
53
|
+
|
|
54
|
+
export const CONVERTER = ortbConverter({
|
|
55
|
+
context: {
|
|
56
|
+
netRevenue: true,
|
|
57
|
+
ttl: 300
|
|
58
|
+
},
|
|
59
|
+
imp(buildImp, bidRequest, context) {
|
|
60
|
+
let imp = buildImp(bidRequest, context);
|
|
61
|
+
|
|
62
|
+
if (bidRequest.mediaTypes[VIDEO]) {
|
|
63
|
+
imp = buildVideoImp(bidRequest, imp);
|
|
64
|
+
} else if (bidRequest.mediaTypes[BANNER]) {
|
|
65
|
+
imp = buildBannerImp(bidRequest, imp);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const bidFloor = getBidFloor(bidRequest);
|
|
69
|
+
|
|
70
|
+
utils.deepSetValue(imp, 'bidfloor', bidFloor);
|
|
71
|
+
|
|
72
|
+
if (bidRequest.params.deals && bidRequest.params.deals.length > 0) {
|
|
73
|
+
utils.deepSetValue(imp, 'pmp', { deals: bidRequest.params.deals });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return imp;
|
|
77
|
+
},
|
|
78
|
+
request(buildRequest, imps, bidderRequest, context) {
|
|
79
|
+
const req = buildRequest(imps, bidderRequest, context);
|
|
80
|
+
mergeDeep(req, {
|
|
81
|
+
at: 1,
|
|
82
|
+
ext: {
|
|
83
|
+
bc: `${bidderConfig}_${bidderVersion}`
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
let userAgent = navigator.userAgent;
|
|
88
|
+
utils.deepSetValue(req, 'device.os', spec.getOS(userAgent));
|
|
89
|
+
utils.deepSetValue(req, 'device.devicetype', _isMobile() ? 1 : _isConnectedTV() ? 3 : 2);
|
|
90
|
+
|
|
91
|
+
const bid = context.bidRequests[0];
|
|
92
|
+
if (bid.params.publisherId) {
|
|
93
|
+
utils.deepSetValue(req, 'site.publisher.id', bid.params.publisherId);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return req;
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
bidResponse(buildBidResponse, bid, context) {
|
|
100
|
+
let bidResponse = buildBidResponse(bid, context);
|
|
101
|
+
|
|
102
|
+
if (bid.ext) {
|
|
103
|
+
bidResponse.meta.networkId = bid.ext.dsp_id;
|
|
104
|
+
bidResponse.meta.advertiserId = bid.ext.buyer_id;
|
|
105
|
+
bidResponse.meta.brandId = bid.ext.brand_id;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (context.ortbResponse.ext && context.ortbResponse.ext.paf) {
|
|
109
|
+
bidResponse.meta.paf = Object.assign({}, context.ortbResponse.ext.paf);
|
|
110
|
+
bidResponse.meta.paf.content_id = utils.deepAccess(bid, 'ext.paf.content_id');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
bidResponse = buildVideoVastResponse(bidResponse)
|
|
114
|
+
bidResponse = buildVideoOutstreamResponse(bidResponse, context)
|
|
115
|
+
|
|
116
|
+
return bidResponse;
|
|
117
|
+
},
|
|
118
|
+
response(buildResponse, bidResponses, ortbResponse, context) {
|
|
119
|
+
const response = buildResponse(bidResponses, ortbResponse, context);
|
|
120
|
+
|
|
121
|
+
let fledgeAuctionConfigs = utils.deepAccess(ortbResponse, 'ext.fledge_auction_configs');
|
|
122
|
+
if (fledgeAuctionConfigs) {
|
|
123
|
+
fledgeAuctionConfigs = Object.entries(fledgeAuctionConfigs).map(([bidId, cfg]) => {
|
|
124
|
+
return Object.assign({
|
|
125
|
+
bidId,
|
|
126
|
+
auctionSignals: {}
|
|
127
|
+
}, cfg);
|
|
128
|
+
});
|
|
129
|
+
return {
|
|
130
|
+
bids: response.bids,
|
|
131
|
+
fledgeAuctionConfigs,
|
|
132
|
+
}
|
|
133
|
+
} else {
|
|
134
|
+
return response.bids
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
function isBidRequestValid(bidRequest) {
|
|
140
|
+
return (isPublisherIdValid(bidRequest) && (isValidBannerRequest(bidRequest) || isValidVideoRequest(bidRequest)));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function isPublisherIdValid(bidRequest) {
|
|
144
|
+
let pubId = utils.deepAccess(bidRequest, 'params.publisherId');
|
|
145
|
+
return (pubId != null && utils.isStr(pubId) && pubId != '');
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function isValidBannerRequest(bidRequest) {
|
|
149
|
+
const bannerSizes = utils.deepAccess(bidRequest, `mediaTypes.${BANNER}.sizes`);
|
|
150
|
+
|
|
151
|
+
return utils.isArray(bannerSizes) && bannerSizes.length > 0 && bannerSizes.every(size => utils.isNumber(size[0]) && utils.isNumber(size[1]));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function isValidVideoRequest(bidRequest) {
|
|
155
|
+
const videoSizes = utils.deepAccess(bidRequest, `mediaTypes.${VIDEO}.playerSize`);
|
|
156
|
+
const PARAM_EXISTS = VIDEO_ORTB_REQUIRED.every(param => utils.deepAccess(bidRequest, `mediaTypes.${VIDEO}.${param}`) != null);
|
|
157
|
+
|
|
158
|
+
return PARAM_EXISTS && utils.isArray(videoSizes) && videoSizes.length > 0 && videoSizes.every(size => utils.isNumber(size[0]) && utils.isNumber(size[1]));
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function buildRequests(validBids, bidderRequest) {
|
|
162
|
+
let videoBids = validBids.filter(bid => isVideoBid(bid));
|
|
163
|
+
let bannerBids = validBids.filter(bid => isBannerBid(bid));
|
|
164
|
+
let requests = [];
|
|
165
|
+
|
|
166
|
+
bannerBids.forEach(bid => {
|
|
167
|
+
requests.push(createRequest([bid], bidderRequest, BANNER));
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
videoBids.forEach(bid => {
|
|
171
|
+
requests.push(createRequest([bid], bidderRequest, VIDEO));
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
return requests;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function buildVideoImp(bidRequest, imp) {
|
|
178
|
+
if (bidRequest.mediaTypes[VIDEO]?.context === 'outstream') {
|
|
179
|
+
imp.video.placement = imp.video.placement || 4;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const videoMediaType = utils.deepAccess(bidRequest, `mediaTypes.${VIDEO}`);
|
|
183
|
+
const videoSizes = (videoMediaType && videoMediaType.playerSize) || [];
|
|
184
|
+
|
|
185
|
+
if (videoSizes && videoSizes.length > 0) {
|
|
186
|
+
utils.deepSetValue(imp, 'video.w', videoSizes[0][0]);
|
|
187
|
+
utils.deepSetValue(imp, 'video.h', videoSizes[0][1]);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const videoAdUnitParams = utils.deepAccess(bidRequest, `mediaTypes.${VIDEO}`, {});
|
|
191
|
+
const videoBidderParams = utils.deepAccess(bidRequest, `params.${VIDEO}`, {});
|
|
192
|
+
|
|
193
|
+
const videoParams = { ...videoAdUnitParams, ...videoBidderParams };
|
|
194
|
+
|
|
195
|
+
VIDEO_ORTB_PARAMS.forEach((param) => {
|
|
196
|
+
if (videoParams.hasOwnProperty(param)) {
|
|
197
|
+
utils.deepSetValue(imp, `video.${param}`, videoParams[param]);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
return { ...imp };
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function buildBannerImp(bidRequest, imp) {
|
|
205
|
+
const bannerSizes = utils.deepAccess(bidRequest, `mediaTypes.${BANNER}.sizes`, []);
|
|
206
|
+
|
|
207
|
+
if (bannerSizes && bannerSizes.length > 0) {
|
|
208
|
+
utils.deepSetValue(imp, 'banner.w', bannerSizes[0][0]);
|
|
209
|
+
utils.deepSetValue(imp, 'banner.h', bannerSizes[0][1]);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return {...imp};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function createRequest(bidRequests, bidderRequest, mediaType) {
|
|
216
|
+
return {
|
|
217
|
+
method: 'POST',
|
|
218
|
+
url: REQUEST_URL,
|
|
219
|
+
data: CONVERTER.toORTB({ bidRequests, bidderRequest, context: { mediaType } })
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function buildVideoVastResponse(bidResponse) {
|
|
224
|
+
if (bidResponse.mediaType == VIDEO && bidResponse.vastXml) {
|
|
225
|
+
bidResponse.vastUrl = bidResponse.vastXml;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return { ...bidResponse }
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function buildVideoOutstreamResponse(bidResponse, context) {
|
|
232
|
+
if (context.bidRequest.mediaTypes[VIDEO]?.context === 'outstream') {
|
|
233
|
+
bidResponse.rendererUrl = SP_OUTSTREAM_PLAYER_URL;
|
|
234
|
+
bidResponse.adUnitCode = context.bidRequest.adUnitCode;
|
|
235
|
+
|
|
236
|
+
bidResponse.renderer = Renderer.install({
|
|
237
|
+
id: bidResponse.requestId,
|
|
238
|
+
adUnitCode: context.bidRequest.adUnitCode,
|
|
239
|
+
url: bidResponse.rendererUrl
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
bidResponse.renderer.setRender(_renderer(bidResponse));
|
|
243
|
+
|
|
244
|
+
bidResponse.renderer.render(bidResponse);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return {...bidResponse};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function getBidFloor(bid) {
|
|
251
|
+
const currency = config.getConfig('currency.adServerCurrency') || DEFAULT_CURRENCY;
|
|
252
|
+
|
|
253
|
+
if (typeof bid.getFloor !== 'function') {
|
|
254
|
+
return utils.deepAccess(bid, 'params.bidFloor', 0.05);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const bidFloor = bid.getFloor({
|
|
258
|
+
currency: currency,
|
|
259
|
+
mediaType: '*',
|
|
260
|
+
size: '*',
|
|
261
|
+
});
|
|
262
|
+
return bidFloor.floor;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function _renderer(bid) {
|
|
266
|
+
bid.renderer.push(() => {
|
|
267
|
+
if (typeof window.SPOutStreamPlayer === 'function') {
|
|
268
|
+
const spoplayer = new window.SPOutStreamPlayer(bid);
|
|
269
|
+
|
|
270
|
+
spoplayer.on('ready', () => {
|
|
271
|
+
spoplayer.startAd();
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
try {
|
|
275
|
+
let vastUrlbt = 'data:text/xml;charset=utf-8;base64,' + btoa(bid.vastUrl.replace(/\\"/g, '"'));
|
|
276
|
+
spoplayer.load(vastUrlbt).then(function() {
|
|
277
|
+
window.spoplayer = spoplayer;
|
|
278
|
+
}).catch(function(reason) {
|
|
279
|
+
setTimeout(function() { throw reason; }, 0);
|
|
280
|
+
});
|
|
281
|
+
} catch (err) {
|
|
282
|
+
utils.logMessage(err);
|
|
283
|
+
}
|
|
284
|
+
} else {
|
|
285
|
+
utils.logMessage(`Silverpush outstream player is not defined`);
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function isVideoBid(bid) {
|
|
291
|
+
return utils.deepAccess(bid, 'mediaTypes.video');
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function isBannerBid(bid) {
|
|
295
|
+
return utils.deepAccess(bid, 'mediaTypes.banner') || !isVideoBid(bid);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function interpretResponse(resp, req) {
|
|
299
|
+
if (!resp.body) {
|
|
300
|
+
resp.body = { nbr: 0 };
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return CONVERTER.fromORTB({ request: req.data, response: resp.body });
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function onBidWon(bid) {
|
|
307
|
+
if (bid == null) { return; }
|
|
308
|
+
if (bid['burl'] == null) { return; }
|
|
309
|
+
|
|
310
|
+
let burlMac = bid['burl'];
|
|
311
|
+
burlMac = burlMac.replace('$' + '{AUCTION_PRICE}', bid['cpm']);
|
|
312
|
+
burlMac = burlMac.replace('$' + '{AUCTION_ID}', bid['auctionId']);
|
|
313
|
+
burlMac = burlMac.replace('$' + '{AUCTION_IMP_ID}', bid['requestId']);
|
|
314
|
+
burlMac = burlMac.replace('$' + '{AUCTION_AD_ID}', bid['adId']);
|
|
315
|
+
burlMac = burlMac.replace('$' + '{AUCTION_SEAT_ID}', bid['seatBidId']);
|
|
316
|
+
|
|
317
|
+
spec.getRequest(burlMac);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function _isMobile() {
|
|
321
|
+
return (/(ios|ipod|ipad|iphone|android)/i).test(navigator.userAgent);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function _isConnectedTV() {
|
|
325
|
+
return (/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(navigator.userAgent);
|
|
326
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
Module Name: Silverpush OpenRTB Bidder Adapter
|
|
5
|
+
Module Type: Bidder Adapter
|
|
6
|
+
Maintainer: prebid@silverpush.co
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
# Description
|
|
10
|
+
|
|
11
|
+
Prebid.JS adapter that connects to the Chocolate Ad Exchange.
|
|
12
|
+
|
|
13
|
+
*NOTE*: The Silverpush Bidder Adapter requires setup and approval before use. Please reach out to prebid@silverpush.co representative for more details.
|
|
14
|
+
|
|
15
|
+
# Bid Parameters
|
|
16
|
+
|
|
17
|
+
## Banner/Video
|
|
18
|
+
|
|
19
|
+
{: .table .table-bordered .table-striped }
|
|
20
|
+
| Name | Scope | Description | Example | Type |
|
|
21
|
+
| -------------- | ----------- | ------------------------------------------ | ------------- | ------------ |
|
|
22
|
+
| `publisherId` | required | Publisher id provided by silverpush | "123456" | String |
|
|
23
|
+
| `bidFloor` | optional | Minimum price in USD. bidFloor applies to a specific unit. For example, use the following value to set a $1.50 floor: 1.50. <br/> | 1.50 | Number |
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# mediaTypes Parameters
|
|
29
|
+
|
|
30
|
+
## mediaTypes.banner
|
|
31
|
+
|
|
32
|
+
The following banner parameters are supported here so publishers may fully declare their banner inventory:
|
|
33
|
+
|
|
34
|
+
{: .table .table-bordered .table-striped }
|
|
35
|
+
| Name | Scope | Description | Example | Type |
|
|
36
|
+
| --------- | ------------| ----------------------------------------------------------------- | --------- | --------- |
|
|
37
|
+
| sizes | required | Avalaible sizes supported for banner ad unit | [ [300, 250], [300, 600] ] | [[Integer, Integer], [Integer, Integer]] |
|
|
38
|
+
|
|
39
|
+
## mediaTypes.video
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
The following video parameters are supported here so publishers may fully declare their video inventory:
|
|
43
|
+
|
|
44
|
+
{: .table .table-bordered .table-striped }
|
|
45
|
+
| Name | Scope | Description | Example | Type |
|
|
46
|
+
| --------- | ------------| ----------------------------------------------------------------- | --------- | --------- |
|
|
47
|
+
| context | required | instream or outstream |"outstream" | string |
|
|
48
|
+
| playerSize | required | Avalaible sizes supported for video ad unit. | [300, 250] | [Integer, Integer] |
|
|
49
|
+
| mimes | required | List of content MIME types supported by the player. | ["video/mp4"]| [String]|
|
|
50
|
+
| protocols | required | Supported video bid response protocol values. | [2,3,5,6] | [integers]|
|
|
51
|
+
| api | required | Supported API framework values. | [2] | [integers] |
|
|
52
|
+
| maxduration | required | Maximum video ad duration in seconds. | 30 | Integer |
|
|
53
|
+
| minduration | required | Minimum video ad duration in seconds. | 6 | Integer |
|
|
54
|
+
| startdelay | required | Indicates the start delay in seconds for pre-roll, mid-roll, or post-roll ad placements. | 0 | Integer |
|
|
55
|
+
| placement | required | Placement type for the impression. | 1 | Integer |
|
|
56
|
+
| minbitrate | optional | Minimum bit rate in Kbps. | 300 | Integer |
|
|
57
|
+
| maxbitrate | optional | Maximum bit rate in Kbps. | 9600 | Integer |
|
|
58
|
+
| playbackmethod | optional | Playback methods that may be in use. Only one method is typically used in practice. | [2]| [Integers] |
|
|
59
|
+
| linearity | optional | OpenRTB2 linearity. in-strea,overlay... | 1 | Integer |
|
|
60
|
+
| skip | optional | Indicates if the player will allow the video to be skipped, where 0 = no, 1 = yes . | 1 | Integer |
|
|
61
|
+
| skipafter | optional | Number of seconds a video must play before skipping is enabled; only applicable if the ad is skippable. | 5 | Integer |
|
|
62
|
+
| delivery | optional | OpenRTB2 delivery. Supported delivery methods (e.g., streaming, progressive). If none specified, assume all are supported. | 1 | [Integer] |
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# Example
|
|
66
|
+
```javascript
|
|
67
|
+
var adUnits = [{
|
|
68
|
+
code: 'div-1',
|
|
69
|
+
mediaTypes: {
|
|
70
|
+
banner: {
|
|
71
|
+
sizes: [ [300, 250], [300,600] ]
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
bids: [{
|
|
75
|
+
bidder: 'silverpush',
|
|
76
|
+
params: {
|
|
77
|
+
publisherId: "123456",
|
|
78
|
+
bidFloor: 1.2
|
|
79
|
+
}
|
|
80
|
+
}]
|
|
81
|
+
},{
|
|
82
|
+
code: 'video-1',
|
|
83
|
+
mediaTypes: {
|
|
84
|
+
video: {
|
|
85
|
+
api: [1, 2, 4, 6],
|
|
86
|
+
mimes: ['video/mp4'],
|
|
87
|
+
context: 'instream', // or 'outstream'
|
|
88
|
+
playerSize: [ 640, 480 ],
|
|
89
|
+
protocols: [4,5,6,7],
|
|
90
|
+
placement: 1,
|
|
91
|
+
minduration: 0,
|
|
92
|
+
maxduration: 60,
|
|
93
|
+
startdelay: 0
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
bids: [
|
|
97
|
+
{
|
|
98
|
+
bidder: 'silverpush',
|
|
99
|
+
params: {
|
|
100
|
+
publisherId: "123456",
|
|
101
|
+
bidfloor: 2.5
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
];
|
|
107
|
+
```
|