prebid.js 6.1.0 → 6.2.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 +1 -1
- package/browsers.json +13 -29
- package/karma.conf.maker.js +1 -1
- package/modules/admixerBidAdapter.js +2 -1
- package/modules/adnuntiusBidAdapter.js +2 -1
- package/modules/adplusBidAdapter.js +203 -0
- package/modules/adplusBidAdapter.md +39 -0
- package/modules/adyoulikeBidAdapter.js +7 -2
- package/modules/appnexusBidAdapter.js +19 -2
- package/modules/beachfrontBidAdapter.js +14 -17
- package/modules/craftBidAdapter.js +5 -3
- package/modules/dchain.js +149 -0
- package/modules/dchain.md +45 -0
- package/modules/emx_digitalBidAdapter.js +9 -1
- package/modules/freewheel-sspBidAdapter.js +6 -0
- package/modules/goldbachBidAdapter.js +1176 -0
- package/modules/goldbachBidAdapter.md +151 -0
- package/modules/gumgumBidAdapter.js +5 -1
- package/modules/intersectionRtdProvider.js +114 -0
- package/modules/invibesBidAdapter.js +15 -9
- package/modules/ipromBidAdapter.js +79 -0
- package/modules/limelightDigitalBidAdapter.js +2 -1
- package/modules/luponmediaBidAdapter.js +570 -0
- package/modules/missenaBidAdapter.js +89 -0
- package/modules/pubmaticBidAdapter.js +3 -3
- package/modules/relaidoBidAdapter.js +86 -65
- package/modules/richaudienceBidAdapter.js +1 -1
- package/modules/smaatoBidAdapter.js +4 -1
- package/modules/smartxBidAdapter.js +17 -1
- package/modules/tappxBidAdapter.js +3 -1
- package/modules/undertoneBidAdapter.js +8 -1
- package/modules/userId/index.js +27 -2
- package/modules/ventes.md +71 -0
- package/modules/ventesBidAdapter.js +104 -64
- package/modules/ventesBidAdapter.md +0 -1
- package/modules/visxBidAdapter.js +19 -2
- package/modules/visxBidAdapter.md +4 -6
- package/modules/yahoosspBidAdapter.md +1 -1
- package/modules/yieldoneBidAdapter.js +115 -11
- package/package.json +1 -1
- package/src/auction.js +3 -2
- package/src/targeting.js +2 -2
- package/src/utils.js +7 -0
- package/test/spec/integration/faker/googletag.js +6 -0
- package/test/spec/modules/adnuntiusBidAdapter_spec.js +18 -0
- package/test/spec/modules/adplusBidAdapter_spec.js +213 -0
- package/test/spec/modules/adyoulikeBidAdapter_spec.js +26 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +49 -1
- package/test/spec/modules/beachfrontBidAdapter_spec.js +65 -1
- package/test/spec/modules/dchain_spec.js +329 -0
- package/test/spec/modules/emx_digitalBidAdapter_spec.js +10 -0
- package/test/spec/modules/freewheel-sspBidAdapter_spec.js +19 -0
- package/test/spec/modules/goldbachBidAdapter_spec.js +1359 -0
- package/test/spec/modules/gumgumBidAdapter_spec.js +6 -0
- package/test/spec/modules/intersectionRtdProvider_spec.js +141 -0
- package/test/spec/modules/invibesBidAdapter_spec.js +29 -4
- package/test/spec/modules/ipromBidAdapter_spec.js +195 -0
- package/test/spec/modules/limelightDigitalBidAdapter_spec.js +10 -7
- package/test/spec/modules/luponmediaBidAdapter_spec.js +412 -0
- package/test/spec/modules/missenaBidAdapter_spec.js +134 -0
- package/test/spec/modules/pubmaticBidAdapter_spec.js +1 -1
- package/test/spec/modules/relaidoBidAdapter_spec.js +71 -63
- package/test/spec/modules/smaatoBidAdapter_spec.js +31 -0
- package/test/spec/modules/smartxBidAdapter_spec.js +9 -0
- package/test/spec/modules/tappxBidAdapter_spec.js +4 -0
- package/test/spec/modules/userId_spec.js +51 -0
- package/test/spec/modules/visxBidAdapter_spec.js +120 -4
- package/test/spec/modules/yieldoneBidAdapter_spec.js +299 -53
- package/test/spec/unit/core/targeting_spec.js +44 -0
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
BANNER,
|
|
3
|
+
NATIVE,
|
|
4
|
+
VIDEO
|
|
5
|
+
} from '../src/mediaTypes.js';
|
|
6
|
+
import {
|
|
7
|
+
convertCamelToUnderscore,
|
|
8
|
+
isStr,
|
|
9
|
+
isArray,
|
|
10
|
+
isNumber,
|
|
11
|
+
isPlainObject,
|
|
12
|
+
replaceAuctionPrice
|
|
13
|
+
} from '../src/utils.js';
|
|
4
14
|
import find from 'core-js-pure/features/array/find.js';
|
|
5
|
-
import
|
|
15
|
+
import {
|
|
16
|
+
registerBidder
|
|
17
|
+
} from '../src/adapters/bidderFactory.js';
|
|
6
18
|
|
|
7
19
|
const BID_METHOD = 'POST';
|
|
8
20
|
const BIDDER_URL = 'http://13.234.201.146:8088/va/ad';
|
|
9
|
-
|
|
10
|
-
const NET_REVENUE = true;
|
|
11
|
-
const TTL = 10;
|
|
12
|
-
const USER_PARAMS = ['age', 'externalUid', 'segments', 'gender', 'dnt', 'language'];
|
|
13
|
-
const DEVICE_PARAMS = ['ua', 'geo', 'dnt', 'lmt', 'ip', 'ipv6', 'devicetype'];
|
|
14
|
-
const APP_DEVICE_PARAMS = ['geo', 'device_id']; // appid is collected separately
|
|
21
|
+
|
|
15
22
|
const DOMAIN_REGEX = new RegExp('//([^/]*)');
|
|
16
23
|
|
|
17
24
|
function groupBy(values, key) {
|
|
@@ -26,7 +33,11 @@ function groupBy(values, key) {
|
|
|
26
33
|
|
|
27
34
|
return Object
|
|
28
35
|
.keys(groups)
|
|
29
|
-
.map(id => ({
|
|
36
|
+
.map(id => ({
|
|
37
|
+
id,
|
|
38
|
+
key,
|
|
39
|
+
values: groups[id]
|
|
40
|
+
}));
|
|
30
41
|
}
|
|
31
42
|
|
|
32
43
|
function validateMediaTypes(mediaTypes, allowedMediaTypes) {
|
|
@@ -45,22 +56,22 @@ function isBanner(mediaTypes) {
|
|
|
45
56
|
|
|
46
57
|
function validateBanner(banner) {
|
|
47
58
|
return isPlainObject(banner) &&
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
59
|
+
isArray(banner.sizes) &&
|
|
60
|
+
(banner.sizes.length > 0) &&
|
|
61
|
+
banner.sizes.every(validateMediaSizes);
|
|
51
62
|
}
|
|
52
63
|
|
|
53
64
|
function validateMediaSizes(mediaSize) {
|
|
54
65
|
return isArray(mediaSize) &&
|
|
55
|
-
|
|
56
|
-
|
|
66
|
+
(mediaSize.length === 2) &&
|
|
67
|
+
mediaSize.every(size => (isNumber(size) && size >= 0));
|
|
57
68
|
}
|
|
58
69
|
|
|
59
70
|
function hasUserInfo(bid) {
|
|
60
71
|
return !!bid.params.user;
|
|
61
72
|
}
|
|
62
73
|
|
|
63
|
-
function validateParameters(parameters
|
|
74
|
+
function validateParameters(parameters) {
|
|
64
75
|
if (!(parameters.placementId)) {
|
|
65
76
|
return false;
|
|
66
77
|
}
|
|
@@ -101,8 +112,8 @@ function generateSiteFromAdUnitContext(bidRequests, adUnitContext) {
|
|
|
101
112
|
|
|
102
113
|
function validateServerRequest(serverRequest) {
|
|
103
114
|
return isPlainObject(serverRequest) &&
|
|
104
|
-
|
|
105
|
-
|
|
115
|
+
isPlainObject(serverRequest.data) &&
|
|
116
|
+
isArray(serverRequest.data.imp)
|
|
106
117
|
}
|
|
107
118
|
|
|
108
119
|
function createServerRequestFromAdUnits(adUnits, bidRequestId, adUnitContext) {
|
|
@@ -122,14 +133,15 @@ function generateBidRequestsFromAdUnits(bidRequests, bidRequestId, adUnitContext
|
|
|
122
133
|
let userObj = {};
|
|
123
134
|
if (userObjBid) {
|
|
124
135
|
Object.keys(userObjBid.params.user)
|
|
125
|
-
.filter(param => includes(USER_PARAMS, param))
|
|
126
136
|
.forEach((param) => {
|
|
127
137
|
let uparam = convertCamelToUnderscore(param);
|
|
128
138
|
if (param === 'segments' && isArray(userObjBid.params.user[param])) {
|
|
129
139
|
let segs = [];
|
|
130
140
|
userObjBid.params.user[param].forEach(val => {
|
|
131
141
|
if (isNumber(val)) {
|
|
132
|
-
segs.push({
|
|
142
|
+
segs.push({
|
|
143
|
+
'id': val
|
|
144
|
+
});
|
|
133
145
|
} else if (isPlainObject(val)) {
|
|
134
146
|
segs.push(val);
|
|
135
147
|
}
|
|
@@ -146,7 +158,6 @@ function generateBidRequestsFromAdUnits(bidRequests, bidRequestId, adUnitContext
|
|
|
146
158
|
if (deviceObjBid && deviceObjBid.params && deviceObjBid.params.device) {
|
|
147
159
|
deviceObj = {};
|
|
148
160
|
Object.keys(deviceObjBid.params.device)
|
|
149
|
-
.filter(param => includes(DEVICE_PARAMS, param))
|
|
150
161
|
.forEach(param => deviceObj[param] = deviceObjBid.params.device[param]);
|
|
151
162
|
if (!deviceObjBid.hasOwnProperty('ua')) {
|
|
152
163
|
deviceObj.ua = navigator.userAgent;
|
|
@@ -159,37 +170,41 @@ function generateBidRequestsFromAdUnits(bidRequests, bidRequestId, adUnitContext
|
|
|
159
170
|
deviceObj.ua = navigator.userAgent;
|
|
160
171
|
deviceObj.language = navigator.language;
|
|
161
172
|
}
|
|
162
|
-
const appDeviceObjBid = find(bidRequests, hasAppInfo);
|
|
163
|
-
let appIdObj;
|
|
164
|
-
if (appDeviceObjBid && appDeviceObjBid.params && appDeviceObjBid.params.app && appDeviceObjBid.params.app.id) {
|
|
165
|
-
Object.keys(appDeviceObjBid.params.app)
|
|
166
|
-
.filter(param => includes(APP_DEVICE_PARAMS, param))
|
|
167
|
-
.forEach(param => appDeviceObjBid[param] = appDeviceObjBid.params.app[param]);
|
|
168
|
-
}
|
|
169
173
|
|
|
170
174
|
const payload = {}
|
|
171
175
|
payload.id = bidRequestId
|
|
172
|
-
payload.at =
|
|
176
|
+
payload.at = 1
|
|
173
177
|
payload.cur = ['USD']
|
|
174
178
|
payload.imp = bidRequests.reduce(generateImpressionsFromAdUnit, [])
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
179
|
+
const appDeviceObjBid = find(bidRequests, hasAppInfo);
|
|
180
|
+
if (!appDeviceObjBid) {
|
|
181
|
+
payload.site = generateSiteFromAdUnitContext(bidRequests, adUnitContext)
|
|
182
|
+
} else {
|
|
183
|
+
let appIdObj;
|
|
184
|
+
if (appDeviceObjBid && appDeviceObjBid.params && appDeviceObjBid.params.app && appDeviceObjBid.params.app.id) {
|
|
185
|
+
appIdObj = {};
|
|
186
|
+
Object.keys(appDeviceObjBid.params.app)
|
|
187
|
+
.forEach(param => appIdObj[param] = appDeviceObjBid.params.app[param]);
|
|
188
|
+
}
|
|
178
189
|
payload.app = appIdObj;
|
|
179
190
|
}
|
|
191
|
+
payload.device = deviceObj;
|
|
180
192
|
payload.user = userObj
|
|
181
|
-
// payload.regs = getRegulationFromAdUnitContext(adUnitContext)
|
|
182
|
-
// payload.ext = generateBidRequestExtension()
|
|
183
|
-
|
|
184
193
|
return payload
|
|
185
194
|
}
|
|
186
195
|
|
|
187
196
|
function generateImpressionsFromAdUnit(acc, adUnit) {
|
|
188
|
-
const {
|
|
189
|
-
|
|
197
|
+
const {
|
|
198
|
+
bidId,
|
|
199
|
+
mediaTypes,
|
|
200
|
+
params
|
|
201
|
+
} = adUnit;
|
|
202
|
+
const {
|
|
203
|
+
placementId
|
|
204
|
+
} = params;
|
|
190
205
|
const pmp = {};
|
|
191
206
|
|
|
192
|
-
if (placementId) pmp.deals = [{id: placementId}]
|
|
207
|
+
if (placementId) pmp.deals = [{ id: placementId }]
|
|
193
208
|
|
|
194
209
|
const imps = Object
|
|
195
210
|
.keys(mediaTypes)
|
|
@@ -204,21 +219,40 @@ function generateImpressionsFromAdUnit(acc, adUnit) {
|
|
|
204
219
|
}
|
|
205
220
|
|
|
206
221
|
function generateBannerFromAdUnit(impId, data, params) {
|
|
207
|
-
const {
|
|
222
|
+
const {
|
|
223
|
+
position,
|
|
224
|
+
placementId
|
|
225
|
+
} = params;
|
|
208
226
|
const pos = position || 0;
|
|
209
227
|
const pmp = {};
|
|
210
|
-
const ext = {
|
|
211
|
-
|
|
212
|
-
|
|
228
|
+
const ext = {
|
|
229
|
+
placementId
|
|
230
|
+
};
|
|
213
231
|
|
|
214
|
-
|
|
232
|
+
if (placementId) pmp.deals = [{ id: placementId }]
|
|
233
|
+
|
|
234
|
+
return data.sizes.map(([w, h]) => ({
|
|
235
|
+
id: `${impId}`,
|
|
236
|
+
banner: {
|
|
237
|
+
format: [{
|
|
238
|
+
w,
|
|
239
|
+
h
|
|
240
|
+
}],
|
|
241
|
+
w,
|
|
242
|
+
h,
|
|
243
|
+
pos
|
|
244
|
+
},
|
|
245
|
+
pmp,
|
|
246
|
+
ext,
|
|
247
|
+
tagid: placementId
|
|
248
|
+
}));
|
|
215
249
|
}
|
|
216
250
|
|
|
217
251
|
function validateServerResponse(serverResponse) {
|
|
218
252
|
return isPlainObject(serverResponse) &&
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
253
|
+
isPlainObject(serverResponse.body) &&
|
|
254
|
+
isStr(serverResponse.body.cur) &&
|
|
255
|
+
isArray(serverResponse.body.seatbid);
|
|
222
256
|
}
|
|
223
257
|
|
|
224
258
|
function seatBidsToAds(seatBid, bidResponse, serverRequest) {
|
|
@@ -241,10 +275,8 @@ function validateBids(bid) {
|
|
|
241
275
|
return true;
|
|
242
276
|
}
|
|
243
277
|
|
|
244
|
-
const VAST_REGEXP = /VAST\s+version/;
|
|
245
|
-
|
|
246
278
|
function getMediaType(adm) {
|
|
247
|
-
const videoRegex = new RegExp(
|
|
279
|
+
const videoRegex = new RegExp(/VAST\s+version/);
|
|
248
280
|
|
|
249
281
|
if (videoRegex.test(adm)) {
|
|
250
282
|
return VIDEO;
|
|
@@ -273,14 +305,16 @@ function generateAdFromBid(bid, bidResponse) {
|
|
|
273
305
|
requestId: bid.impid,
|
|
274
306
|
cpm: bid.price,
|
|
275
307
|
currency: bidResponse.cur,
|
|
276
|
-
ttl:
|
|
308
|
+
ttl: 10,
|
|
277
309
|
creativeId: bid.crid,
|
|
278
310
|
mediaType: mediaType,
|
|
279
|
-
netRevenue:
|
|
311
|
+
netRevenue: true
|
|
280
312
|
};
|
|
281
313
|
|
|
282
314
|
if (bid.adomain) {
|
|
283
|
-
base.meta = {
|
|
315
|
+
base.meta = {
|
|
316
|
+
advertiserDomains: bid.adomain
|
|
317
|
+
};
|
|
284
318
|
}
|
|
285
319
|
|
|
286
320
|
const size = getSizeFromBid(bid);
|
|
@@ -292,17 +326,21 @@ function generateAdFromBid(bid, bidResponse) {
|
|
|
292
326
|
width: size.width,
|
|
293
327
|
ad: creative.markup,
|
|
294
328
|
adUrl: creative.markupUrl,
|
|
295
|
-
// vastXml: isVideo && !isStr(creative.markupUrl) ? creative.markup : null,
|
|
296
|
-
// vastUrl: isVideo && isStr(creative.markupUrl) ? creative.markupUrl : null,
|
|
297
329
|
renderer: creative.renderer
|
|
298
330
|
};
|
|
299
331
|
}
|
|
300
332
|
|
|
301
333
|
function getSizeFromBid(bid) {
|
|
302
334
|
if (isNumber(bid.w) && isNumber(bid.h)) {
|
|
303
|
-
return {
|
|
335
|
+
return {
|
|
336
|
+
width: bid.w,
|
|
337
|
+
height: bid.h
|
|
338
|
+
};
|
|
304
339
|
}
|
|
305
|
-
return {
|
|
340
|
+
return {
|
|
341
|
+
width: null,
|
|
342
|
+
height: null
|
|
343
|
+
};
|
|
306
344
|
}
|
|
307
345
|
|
|
308
346
|
function getCreativeFromBid(bid) {
|
|
@@ -333,12 +371,12 @@ const venavenBidderSpec = {
|
|
|
333
371
|
const allowedBidderCodes = [this.code];
|
|
334
372
|
|
|
335
373
|
return isPlainObject(adUnit) &&
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
374
|
+
allowedBidderCodes.indexOf(adUnit.bidder) !== -1 &&
|
|
375
|
+
isStr(adUnit.adUnitCode) &&
|
|
376
|
+
isStr(adUnit.bidderRequestId) &&
|
|
377
|
+
isStr(adUnit.bidId) &&
|
|
378
|
+
validateMediaTypes(adUnit.mediaTypes, this.supportedMediaTypes) &&
|
|
379
|
+
validateParameters(adUnit.params);
|
|
342
380
|
},
|
|
343
381
|
buildRequests(bidRequests, bidderRequest) {
|
|
344
382
|
if (!bidRequests) return null;
|
|
@@ -367,4 +405,6 @@ const venavenBidderSpec = {
|
|
|
367
405
|
|
|
368
406
|
registerBidder(venavenBidderSpec);
|
|
369
407
|
|
|
370
|
-
export {
|
|
408
|
+
export {
|
|
409
|
+
venavenBidderSpec as spec
|
|
410
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { triggerPixel, parseSizesInput, deepAccess, logError } from '../src/utils.js';
|
|
1
|
+
import { triggerPixel, parseSizesInput, deepAccess, logError, getGptSlotInfoForAdUnitCode } from '../src/utils.js';
|
|
2
2
|
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
3
3
|
import { config } from '../src/config.js';
|
|
4
4
|
import { BANNER, VIDEO } from '../src/mediaTypes.js';
|
|
@@ -241,7 +241,7 @@ function makeVideo(videoParams = {}) {
|
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
function buildImpObject(bid) {
|
|
244
|
-
const { params: { uid }, bidId, mediaTypes, sizes } = bid;
|
|
244
|
+
const { params: { uid }, bidId, mediaTypes, sizes, adUnitCode } = bid;
|
|
245
245
|
const video = mediaTypes && _isVideoBid(bid) && _isValidVideoBid(bid) && makeVideo(mediaTypes.video);
|
|
246
246
|
const banner = makeBanner((mediaTypes && mediaTypes.banner) || (!video && { sizes }));
|
|
247
247
|
const impObject = {
|
|
@@ -253,6 +253,10 @@ function buildImpObject(bid) {
|
|
|
253
253
|
}
|
|
254
254
|
};
|
|
255
255
|
|
|
256
|
+
if (impObject.banner) {
|
|
257
|
+
impObject.ext.bidder.adslotExists = _isAdSlotExists(adUnitCode);
|
|
258
|
+
}
|
|
259
|
+
|
|
256
260
|
if (impObject.ext.bidder.uid && (impObject.banner || impObject.video)) {
|
|
257
261
|
return impObject;
|
|
258
262
|
}
|
|
@@ -355,4 +359,17 @@ function _isValidVideoBid(bid, logErrors = false) {
|
|
|
355
359
|
return result;
|
|
356
360
|
}
|
|
357
361
|
|
|
362
|
+
function _isAdSlotExists(adUnitCode) {
|
|
363
|
+
if (document.getElementById(adUnitCode)) {
|
|
364
|
+
return true;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const gptAdSlot = getGptSlotInfoForAdUnitCode(adUnitCode);
|
|
368
|
+
if (gptAdSlot && gptAdSlot.divId && document.getElementById(gptAdSlot.divId)) {
|
|
369
|
+
return true;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return false;
|
|
373
|
+
}
|
|
374
|
+
|
|
358
375
|
registerBidder(spec);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
```
|
|
4
4
|
Module Name: YOC VIS.X Bidder Adapter
|
|
5
5
|
Module Type: Bidder Adapter
|
|
6
|
-
Maintainer:
|
|
6
|
+
Maintainer: supply.partners@yoc.com
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
# Description
|
|
@@ -47,16 +47,14 @@ var adUnits = [
|
|
|
47
47
|
}
|
|
48
48
|
]
|
|
49
49
|
},
|
|
50
|
-
//
|
|
50
|
+
// In-stream video adUnit
|
|
51
51
|
{
|
|
52
52
|
code: 'instream-test-div',
|
|
53
53
|
mediaTypes: {
|
|
54
54
|
video: {
|
|
55
55
|
context: 'instream',
|
|
56
|
-
playerSize: [400, 300]
|
|
57
|
-
|
|
58
|
-
protocols: [3, 6]
|
|
59
|
-
},
|
|
56
|
+
playerSize: [400, 300]
|
|
57
|
+
}
|
|
60
58
|
},
|
|
61
59
|
bids: [
|
|
62
60
|
{
|
|
@@ -57,7 +57,7 @@ At this time, only the following partners/publishers are eligble for pubId integ
|
|
|
57
57
|
A. Do not have any display/banner inventory.
|
|
58
58
|
B. Do not have any existing accounts on Yahoo SSP (aka: aol, oneMobile, oneDisplay).
|
|
59
59
|
|
|
60
|
-
#
|
|
60
|
+
# Mandatory Bidder Parameters
|
|
61
61
|
## dcn & pos (DEFAULT)
|
|
62
62
|
The minimal requirements for the 'yahoossp' bid adapter to generate an outbound bid-request to our Yahoo SSP are:
|
|
63
63
|
1. At least 1 adUnit including mediaTypes: banner or video
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {deepAccess, isEmpty, isStr, logWarn, parseSizesInput} from '../src/utils.js';
|
|
2
2
|
import {config} from '../src/config.js';
|
|
3
3
|
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
4
4
|
import { Renderer } from '../src/Renderer.js';
|
|
@@ -11,6 +11,8 @@ const VIDEO_PLAYER_URL = 'https://img.ak.impact-ad.jp/ic/pone/ivt/firstview/js/d
|
|
|
11
11
|
const CMER_PLAYER_URL = 'https://an.cmertv.com/hb/renderer/cmertv-video-yone-prebid.min.js';
|
|
12
12
|
const VIEWABLE_PERCENTAGE_URL = 'https://img.ak.impact-ad.jp/ic/pone/ivt/firstview/js/prebid-adformat-config.js';
|
|
13
13
|
|
|
14
|
+
const DEFAULT_VIDEO_SIZE = {w: 640, h: 360};
|
|
15
|
+
|
|
14
16
|
export const spec = {
|
|
15
17
|
code: BIDDER_CODE,
|
|
16
18
|
aliases: ['y1'],
|
|
@@ -40,16 +42,18 @@ export const spec = {
|
|
|
40
42
|
t: 'i'
|
|
41
43
|
};
|
|
42
44
|
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
const mediaType = getMediaType(bidRequest);
|
|
46
|
+
switch (mediaType) {
|
|
47
|
+
case BANNER:
|
|
48
|
+
payload.sz = getBannerSizes(bidRequest);
|
|
49
|
+
break;
|
|
50
|
+
case VIDEO:
|
|
51
|
+
const videoSize = getVideoSize(bidRequest);
|
|
52
|
+
payload.w = videoSize.w;
|
|
53
|
+
payload.h = videoSize.h;
|
|
54
|
+
break;
|
|
55
|
+
default:
|
|
56
|
+
break;
|
|
53
57
|
}
|
|
54
58
|
|
|
55
59
|
// LiveRampID
|
|
@@ -167,6 +171,106 @@ export const spec = {
|
|
|
167
171
|
},
|
|
168
172
|
}
|
|
169
173
|
|
|
174
|
+
/**
|
|
175
|
+
* NOTE: server side does not yet support multiple formats.
|
|
176
|
+
* @param {Object} bidRequest -
|
|
177
|
+
* @param {boolean} [enabledOldFormat = true] - default: `true`.
|
|
178
|
+
* @return {string|null} - `"banner"` or `"video"` or `null`.
|
|
179
|
+
*/
|
|
180
|
+
function getMediaType(bidRequest, enabledOldFormat = true) {
|
|
181
|
+
let hasBannerType = Boolean(deepAccess(bidRequest, 'mediaTypes.banner'));
|
|
182
|
+
let hasVideoType = Boolean(deepAccess(bidRequest, 'mediaTypes.video'));
|
|
183
|
+
|
|
184
|
+
if (enabledOldFormat) {
|
|
185
|
+
hasBannerType = hasBannerType || bidRequest.mediaType === BANNER ||
|
|
186
|
+
(isEmpty(bidRequest.mediaTypes) && isEmpty(bidRequest.mediaType));
|
|
187
|
+
hasVideoType = hasVideoType || bidRequest.mediaType === VIDEO;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (hasBannerType && hasVideoType) {
|
|
191
|
+
const playerParams = deepAccess(bidRequest, 'params.playerParams')
|
|
192
|
+
if (playerParams) {
|
|
193
|
+
return VIDEO;
|
|
194
|
+
} else {
|
|
195
|
+
return BANNER;
|
|
196
|
+
}
|
|
197
|
+
} else if (hasBannerType) {
|
|
198
|
+
return BANNER;
|
|
199
|
+
} else if (hasVideoType) {
|
|
200
|
+
return VIDEO;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* NOTE:
|
|
208
|
+
* If `mediaTypes.banner` exists, then `mediaTypes.banner.sizes` must also exist.
|
|
209
|
+
* The reason for this is that Prebid.js will perform the verification and
|
|
210
|
+
* if `mediaTypes.banner.sizes` is inappropriate, it will delete the entire `mediaTypes.banner`.
|
|
211
|
+
* @param {Object} bidRequest -
|
|
212
|
+
* @param {Object} bidRequest.banner -
|
|
213
|
+
* @param {Array<string>} bidRequest.banner.sizes -
|
|
214
|
+
* @param {boolean} [enabledOldFormat = true] - default: `true`.
|
|
215
|
+
* @return {string} - strings like `"300x250"` or `"300x250,728x90"`.
|
|
216
|
+
*/
|
|
217
|
+
function getBannerSizes(bidRequest, enabledOldFormat = true) {
|
|
218
|
+
let sizes = deepAccess(bidRequest, 'mediaTypes.banner.sizes');
|
|
219
|
+
|
|
220
|
+
if (enabledOldFormat) {
|
|
221
|
+
sizes = sizes || bidRequest.sizes;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return parseSizesInput(sizes).join(',');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* @param {Object} bidRequest -
|
|
229
|
+
* @param {boolean} [enabledOldFormat = true] - default: `true`.
|
|
230
|
+
* @param {boolean} [enabledFlux = true] - default: `true`.
|
|
231
|
+
* @return {{w: number, h: number}} -
|
|
232
|
+
*/
|
|
233
|
+
function getVideoSize(bidRequest, enabledOldFormat = true, enabledFlux = true) {
|
|
234
|
+
/**
|
|
235
|
+
* @param {Array<number, number> | Array<Array<number, number>>} sizes -
|
|
236
|
+
* @return {{w: number, h: number} | null} -
|
|
237
|
+
*/
|
|
238
|
+
const _getPlayerSize = (sizes) => {
|
|
239
|
+
let result = null;
|
|
240
|
+
|
|
241
|
+
const size = parseSizesInput(sizes)[0];
|
|
242
|
+
if (isEmpty(size)) {
|
|
243
|
+
return result;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const splited = size.split('x');
|
|
247
|
+
const sizeObj = {w: parseInt(splited[0], 10), h: parseInt(splited[1], 10)};
|
|
248
|
+
const _isValidPlayerSize = !(isEmpty(sizeObj)) && (isFinite(sizeObj.w) && isFinite(sizeObj.h));
|
|
249
|
+
if (!_isValidPlayerSize) {
|
|
250
|
+
return result;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
result = sizeObj;
|
|
254
|
+
return result;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
let playerSize = _getPlayerSize(deepAccess(bidRequest, 'mediaTypes.video.playerSize'));
|
|
258
|
+
|
|
259
|
+
if (enabledOldFormat) {
|
|
260
|
+
playerSize = playerSize || _getPlayerSize(bidRequest.sizes);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (enabledFlux) {
|
|
264
|
+
// NOTE: `video.playerSize` in Flux is always [1,1].
|
|
265
|
+
if (playerSize && (playerSize.w === 1 && playerSize.h === 1)) {
|
|
266
|
+
// NOTE: `params.playerSize` is a specific object to support `FLUX`.
|
|
267
|
+
playerSize = _getPlayerSize(deepAccess(bidRequest, 'params.playerSize'));
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return playerSize || DEFAULT_VIDEO_SIZE;
|
|
272
|
+
}
|
|
273
|
+
|
|
170
274
|
function newRenderer(response) {
|
|
171
275
|
const renderer = Renderer.install({
|
|
172
276
|
id: response.uid,
|
package/package.json
CHANGED
package/src/auction.js
CHANGED
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
|
|
60
60
|
import {
|
|
61
61
|
flatten, timestamp, adUnitsFilter, deepAccess, getBidRequest, getValue, parseUrl, generateUUID,
|
|
62
|
-
logMessage, bind, logError, logInfo, logWarn, isEmpty, _each, isFn, isEmptyStr
|
|
62
|
+
logMessage, bind, logError, logInfo, logWarn, isEmpty, _each, isFn, isEmptyStr, isAllowZeroCpmBidsEnabled
|
|
63
63
|
} from './utils.js';
|
|
64
64
|
import { getPriceBucketString } from './cpmBucketManager.js';
|
|
65
65
|
import { getNativeTargeting } from './native.js';
|
|
@@ -567,7 +567,8 @@ function getPreparedBidForAuction({adUnitCode, bid, bidderRequest, auctionId}) {
|
|
|
567
567
|
|
|
568
568
|
function setupBidTargeting(bidObject, bidderRequest) {
|
|
569
569
|
let keyValues;
|
|
570
|
-
|
|
570
|
+
const cpmCheck = (isAllowZeroCpmBidsEnabled(bidObject.bidderCode)) ? bidObject.cpm >= 0 : bidObject.cpm > 0;
|
|
571
|
+
if (bidObject.bidderCode && (cpmCheck || bidObject.dealId)) {
|
|
571
572
|
let bidReq = find(bidderRequest.bids, bid => bid.adUnitCode === bidObject.adUnitCode);
|
|
572
573
|
keyValues = getKeyValueTargetingPairs(bidObject.bidderCode, bidObject, bidReq);
|
|
573
574
|
}
|
package/src/targeting.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
uniques, isGptPubadsDefined, getHighestCpm, getOldestHighestCpmBid, groupBy, isAdUnitCodeMatchingSlot, timestamp,
|
|
3
|
-
deepAccess, deepClone, logError, logWarn, logInfo, isFn, isArray, logMessage, isStr
|
|
3
|
+
deepAccess, deepClone, logError, logWarn, logInfo, isFn, isArray, logMessage, isStr, isAllowZeroCpmBidsEnabled
|
|
4
4
|
} from './utils.js';
|
|
5
5
|
import { config } from './config.js';
|
|
6
6
|
import { NATIVE_TARGETING_KEYS } from './native.js';
|
|
@@ -438,7 +438,7 @@ export function newTargeting(auctionManager) {
|
|
|
438
438
|
const adUnitCodes = getAdUnitCodes(adUnitCode);
|
|
439
439
|
return bidsReceived
|
|
440
440
|
.filter(bid => includes(adUnitCodes, bid.adUnitCode))
|
|
441
|
-
.filter(bid => bid.cpm > 0)
|
|
441
|
+
.filter(bid => (isAllowZeroCpmBidsEnabled(bid.bidderCode)) ? bid.cpm >= 0 : bid.cpm > 0)
|
|
442
442
|
.map(bid => bid.adUnitCode)
|
|
443
443
|
.filter(uniques)
|
|
444
444
|
.map(adUnitCode => bidsReceived
|
package/src/utils.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
import { config } from './config.js';
|
|
3
|
+
import { getGlobal } from './prebidGlobal.js';
|
|
3
4
|
import clone from 'just-clone';
|
|
4
5
|
import find from 'core-js-pure/features/array/find.js';
|
|
5
6
|
import includes from 'core-js-pure/features/array/includes.js';
|
|
@@ -1294,3 +1295,9 @@ export function cyrb53Hash(str, seed = 0) {
|
|
|
1294
1295
|
h2 = imul(h2 ^ (h2 >>> 16), 2246822507) ^ imul(h1 ^ (h1 >>> 13), 3266489909);
|
|
1295
1296
|
return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString();
|
|
1296
1297
|
}
|
|
1298
|
+
|
|
1299
|
+
export function isAllowZeroCpmBidsEnabled(bidderCode) {
|
|
1300
|
+
const bidderSettings = getGlobal().bidderSettings;
|
|
1301
|
+
return ((bidderSettings[bidderCode] && bidderSettings[bidderCode].allowZeroCpmBids === true) ||
|
|
1302
|
+
(bidderSettings.standard && bidderSettings.standard.allowZeroCpmBids === true));
|
|
1303
|
+
}
|
|
@@ -51,9 +51,15 @@ export function enable() {
|
|
|
51
51
|
window.googletag = {
|
|
52
52
|
_slots: [],
|
|
53
53
|
_callbackMap: {},
|
|
54
|
+
_ppid: undefined,
|
|
55
|
+
cmd: [],
|
|
54
56
|
pubads: function () {
|
|
55
57
|
var self = this;
|
|
56
58
|
return {
|
|
59
|
+
setPublisherProvidedId: function (ppid) {
|
|
60
|
+
self._ppid = ppid;
|
|
61
|
+
},
|
|
62
|
+
|
|
57
63
|
getSlots: function () {
|
|
58
64
|
return self._slots;
|
|
59
65
|
},
|
|
@@ -251,6 +251,24 @@ describe('adnuntiusBidAdapter', function () {
|
|
|
251
251
|
expect(request[0]).to.have.property('url')
|
|
252
252
|
expect(request[0].url).to.equal(ENDPOINT_URL_SEGMENTS);
|
|
253
253
|
});
|
|
254
|
+
|
|
255
|
+
it('should user user ID if present in ortb2.user.id field', function () {
|
|
256
|
+
config.setBidderConfig({
|
|
257
|
+
bidders: ['adnuntius', 'other'],
|
|
258
|
+
config: {
|
|
259
|
+
ortb2: {
|
|
260
|
+
user: {
|
|
261
|
+
id: usi
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
const request = config.runWithBidder('adnuntius', () => spec.buildRequests(bidRequests));
|
|
268
|
+
expect(request.length).to.equal(1);
|
|
269
|
+
expect(request[0]).to.have.property('url')
|
|
270
|
+
expect(request[0].url).to.equal(ENDPOINT_URL);
|
|
271
|
+
});
|
|
254
272
|
});
|
|
255
273
|
|
|
256
274
|
describe('user privacy', function () {
|