prebid.js 5.18.0 → 6.1.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/.babelrc.js +1 -10
- package/README.md +3 -1
- package/browsers.json +1 -8
- package/gulpfile.js +1 -0
- package/integrationExamples/gpt/akamaidap_segments_example.html +132 -0
- package/modules/.submodules.json +1 -0
- package/modules/adfBidAdapter.js +21 -16
- package/modules/adheseBidAdapter.js +7 -2
- package/modules/adkernelBidAdapter.js +1 -0
- package/modules/adlivetechBidAdapter.md +61 -0
- package/modules/adomikAnalyticsAdapter.js +10 -4
- package/modules/adtelligentBidAdapter.js +2 -1
- package/modules/airgridRtdProvider.js +1 -1
- package/modules/akamaiDapRtdProvider.js +474 -0
- package/modules/akamaiDapRtdProvider.md +47 -0
- package/modules/appnexusBidAdapter.js +9 -3
- package/modules/atsAnalyticsAdapter.js +67 -46
- package/modules/atsAnalyticsAdapter.md +1 -0
- package/modules/betweenBidAdapter.js +20 -3
- package/modules/browsiRtdProvider.js +106 -18
- package/modules/cleanioRtdProvider.js +192 -0
- package/modules/cleanioRtdProvider.md +59 -0
- package/modules/codefuelBidAdapter.js +181 -0
- package/modules/codefuelBidAdapter.md +111 -0
- package/modules/connectIdSystem.js +104 -0
- package/modules/connectIdSystem.md +33 -0
- package/modules/datablocksBidAdapter.js +3 -3
- package/modules/deepintentBidAdapter.js +107 -10
- package/modules/deepintentBidAdapter.md +36 -1
- package/modules/deltaprojectsBidAdapter.js +252 -0
- package/modules/deltaprojectsBidAdapter.md +32 -0
- package/modules/engageyaBidAdapter.js +171 -0
- package/modules/glimpseBidAdapter.js +31 -16
- package/modules/gptPreAuction.js +11 -5
- package/modules/gridBidAdapter.js +1 -0
- package/modules/gumgumBidAdapter.js +8 -0
- package/modules/id5IdSystem.md +6 -6
- package/modules/imRtdProvider.js +31 -0
- package/modules/inskinBidAdapter.js +7 -3
- package/modules/ixBidAdapter.js +174 -22
- package/modules/jixieBidAdapter.js +8 -2
- package/modules/justpremiumBidAdapter.js +6 -1
- package/modules/limelightDigitalBidAdapter.js +22 -2
- package/modules/livewrappedAnalyticsAdapter.js +49 -1
- package/modules/merkleIdSystem.js +5 -0
- package/modules/multibid/index.js +3 -3
- package/modules/nativoBidAdapter.js +32 -2
- package/modules/nextMillenniumBidAdapter.js +12 -3
- package/modules/oguryBidAdapter.js +16 -2
- package/modules/openxBidAdapter.js +40 -23
- package/modules/operaadsBidAdapter.js +21 -1
- package/modules/otmBidAdapter.js +146 -0
- package/modules/otmBidAdapter.md +27 -26
- package/modules/outbrainBidAdapter.js +5 -0
- package/modules/playwireBidAdapter.md +61 -0
- package/modules/prebidServerBidAdapter/index.js +3 -3
- package/modules/publinkIdSystem.js +11 -6
- package/modules/pubmaticBidAdapter.js +2 -0
- package/modules/rtdModule/index.js +2 -2
- package/modules/saambaaBidAdapter.js +420 -0
- package/modules/saambaaBidAdapter.md +65 -68
- package/modules/seedtagBidAdapter.js +6 -0
- package/modules/smaatoBidAdapter.js +6 -1
- package/modules/sonobiBidAdapter.js +7 -0
- package/modules/sortableBidAdapter.js +1 -0
- package/modules/sspBCBidAdapter.js +34 -3
- package/modules/teadsBidAdapter.js +3 -0
- package/modules/tripleliftBidAdapter.js +22 -5
- package/modules/trustxBidAdapter.js +18 -7
- package/modules/undertoneBidAdapter.js +9 -5
- package/modules/undertoneBidAdapter.md +5 -1
- package/modules/userId/eids.js +18 -0
- package/modules/userId/eids.md +7 -0
- package/modules/userId/userId.md +12 -0
- package/modules/ventesBidAdapter.js +370 -0
- package/modules/ventesBidAdapter.md +94 -0
- package/modules/videobyteBidAdapter.js +13 -6
- package/modules/videobyteBidAdapter.md +49 -0
- package/modules/vidoomyBidAdapter.js +51 -100
- package/modules/visxBidAdapter.js +1 -1
- package/modules/yahoosspBidAdapter.js +6 -6
- package/modules/yieldlabBidAdapter.js +41 -10
- package/modules/yieldlabBidAdapter.md +91 -48
- package/modules/yieldmoSyntheticInventoryModule.js +46 -0
- package/modules/yieldmoSyntheticInventoryModule.md +68 -0
- package/package.json +6 -1
- package/src/adapterManager.js +19 -8
- package/src/adapters/bidderFactory.js +4 -3
- package/src/auction.js +11 -11
- package/src/constants.json +1 -0
- package/src/secureCreatives.js +6 -7
- package/src/targeting.js +11 -9
- package/test/spec/modules/adfBidAdapter_spec.js +83 -29
- package/test/spec/modules/adheseBidAdapter_spec.js +27 -1
- package/test/spec/modules/adomikAnalyticsAdapter_spec.js +3 -1
- package/test/spec/modules/adtelligentBidAdapter_spec.js +1 -0
- package/test/spec/modules/akamaiDapRtdProvider_spec.js +246 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +16 -1
- package/test/spec/modules/atsAnalyticsAdapter_spec.js +42 -9
- package/test/spec/modules/betweenBidAdapter_spec.js +41 -0
- package/test/spec/modules/browsiRtdProvider_spec.js +62 -7
- package/test/spec/modules/cleanioRtdProvider_spec.js +188 -0
- package/test/spec/modules/codefuelBidAdapter_spec.js +316 -0
- package/test/spec/modules/connectIdSystem_spec.js +189 -0
- package/test/spec/modules/datablocksBidAdapter_spec.js +3 -3
- package/test/spec/modules/deepintentBidAdapter_spec.js +153 -3
- package/test/spec/modules/deltaprojectsBidAdapter_spec.js +399 -0
- package/test/spec/modules/engageyaBidAdapter_spec.js +422 -0
- package/test/spec/modules/eplanningBidAdapter_spec.js +8 -8
- package/test/spec/modules/glimpseBidAdapter_spec.js +33 -0
- package/test/spec/modules/gptPreAuction_spec.js +58 -4
- package/test/spec/modules/gumgumBidAdapter_spec.js +5 -1
- package/test/spec/modules/imRtdProvider_spec.js +25 -0
- package/test/spec/modules/ixBidAdapter_spec.js +298 -5
- package/test/spec/modules/jixieBidAdapter_spec.js +13 -11
- package/test/spec/modules/justpremiumBidAdapter_spec.js +9 -2
- package/test/spec/modules/konduitWrapper_spec.js +0 -1
- package/test/spec/modules/limelightDigitalBidAdapter_spec.js +155 -1
- package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +52 -7
- package/test/spec/modules/merkleIdSystem_spec.js +18 -0
- package/test/spec/modules/multibid_spec.js +31 -31
- package/test/spec/modules/nativoBidAdapter_spec.js +35 -18
- package/test/spec/modules/nextMillenniumBidAdapter_spec.js +13 -1
- package/test/spec/modules/oguryBidAdapter_spec.js +66 -23
- package/test/spec/modules/openxBidAdapter_spec.js +90 -13
- package/test/spec/modules/operaadsBidAdapter_spec.js +38 -6
- package/test/spec/modules/otmBidAdapter_spec.js +67 -0
- package/test/spec/modules/outbrainBidAdapter_spec.js +18 -0
- package/test/spec/modules/prebidServerBidAdapter_spec.js +19 -2
- package/test/spec/modules/publinkIdSystem_spec.js +6 -6
- package/test/spec/modules/seedtagBidAdapter_spec.js +3 -0
- package/test/spec/modules/smaatoBidAdapter_spec.js +30 -0
- package/test/spec/modules/sonobiBidAdapter_spec.js +34 -1
- package/test/spec/modules/sortableBidAdapter_spec.js +11 -0
- package/test/spec/modules/sspBCBidAdapter_spec.js +33 -3
- package/test/spec/modules/teadsBidAdapter_spec.js +132 -0
- package/test/spec/modules/tripleliftBidAdapter_spec.js +128 -0
- package/test/spec/modules/trustxBidAdapter_spec.js +45 -3
- package/test/spec/modules/undertoneBidAdapter_spec.js +52 -0
- package/test/spec/modules/ventesBidAdapter_spec.js +845 -0
- package/test/spec/modules/videobyteBidAdapter_spec.js +2 -2
- package/test/spec/modules/vidoomyBidAdapter_spec.js +32 -13
- package/test/spec/modules/visxBidAdapter_spec.js +1 -1
- package/test/spec/modules/yieldlabBidAdapter_spec.js +81 -0
- package/test/spec/modules/yieldmoSyntheticInventoryModule_spec.js +89 -0
- package/test/spec/unit/core/adapterManager_spec.js +56 -6
- package/test/spec/unit/core/bidderFactory_spec.js +61 -1
- package/test/spec/unit/pbjs_api_spec.js +37 -2
- package/test/spec/unit/secureCreatives_spec.js +54 -25
- package/wdio.conf.js +1 -1
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
2
|
+
import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js';
|
|
3
|
+
import {convertCamelToUnderscore, isStr, isArray, isNumber, isPlainObject, replaceAuctionPrice} from '../src/utils.js';
|
|
4
|
+
import find from 'core-js-pure/features/array/find.js';
|
|
5
|
+
import includes from 'core-js-pure/features/array/includes.js';
|
|
6
|
+
|
|
7
|
+
const BID_METHOD = 'POST';
|
|
8
|
+
const BIDDER_URL = 'http://13.234.201.146:8088/va/ad';
|
|
9
|
+
const FIRST_PRICE = 1;
|
|
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
|
|
15
|
+
const DOMAIN_REGEX = new RegExp('//([^/]*)');
|
|
16
|
+
|
|
17
|
+
function groupBy(values, key) {
|
|
18
|
+
const groups = values.reduce((acc, value) => {
|
|
19
|
+
const groupId = value[key];
|
|
20
|
+
|
|
21
|
+
if (!acc[groupId]) acc[groupId] = [];
|
|
22
|
+
acc[groupId].push(value);
|
|
23
|
+
|
|
24
|
+
return acc;
|
|
25
|
+
}, {});
|
|
26
|
+
|
|
27
|
+
return Object
|
|
28
|
+
.keys(groups)
|
|
29
|
+
.map(id => ({id, key, values: groups[id]}));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function validateMediaTypes(mediaTypes, allowedMediaTypes) {
|
|
33
|
+
if (!isPlainObject(mediaTypes)) return false;
|
|
34
|
+
if (!allowedMediaTypes.some(mediaType => mediaType in mediaTypes)) return false;
|
|
35
|
+
|
|
36
|
+
if (isBanner(mediaTypes)) {
|
|
37
|
+
if (!validateBanner(mediaTypes.banner)) return false;
|
|
38
|
+
}
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function isBanner(mediaTypes) {
|
|
43
|
+
return isPlainObject(mediaTypes) && isPlainObject(mediaTypes.banner);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function validateBanner(banner) {
|
|
47
|
+
return isPlainObject(banner) &&
|
|
48
|
+
isArray(banner.sizes) &&
|
|
49
|
+
(banner.sizes.length > 0) &&
|
|
50
|
+
banner.sizes.every(validateMediaSizes);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function validateMediaSizes(mediaSize) {
|
|
54
|
+
return isArray(mediaSize) &&
|
|
55
|
+
(mediaSize.length === 2) &&
|
|
56
|
+
mediaSize.every(size => (isNumber(size) && size >= 0));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function hasUserInfo(bid) {
|
|
60
|
+
return !!bid.params.user;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function validateParameters(parameters, adUnit) {
|
|
64
|
+
if (!(parameters.placementId)) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
if (!(parameters.publisherId)) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function extractSiteDomainFromURL(url) {
|
|
75
|
+
if (!url || !isStr(url)) return null;
|
|
76
|
+
|
|
77
|
+
const domain = url.match(DOMAIN_REGEX);
|
|
78
|
+
|
|
79
|
+
if (isArray(domain) && domain.length === 2) return domain[1];
|
|
80
|
+
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function generateSiteFromAdUnitContext(bidRequests, adUnitContext) {
|
|
85
|
+
if (!adUnitContext || !adUnitContext.refererInfo) return null;
|
|
86
|
+
|
|
87
|
+
const domain = extractSiteDomainFromURL(adUnitContext.refererInfo.referer);
|
|
88
|
+
const publisherId = bidRequests[0].params.publisherId;
|
|
89
|
+
|
|
90
|
+
if (!domain) return null;
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
page: adUnitContext.refererInfo.referer,
|
|
94
|
+
domain: domain,
|
|
95
|
+
name: domain,
|
|
96
|
+
publisher: {
|
|
97
|
+
id: publisherId
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function validateServerRequest(serverRequest) {
|
|
103
|
+
return isPlainObject(serverRequest) &&
|
|
104
|
+
isPlainObject(serverRequest.data) &&
|
|
105
|
+
isArray(serverRequest.data.imp)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function createServerRequestFromAdUnits(adUnits, bidRequestId, adUnitContext) {
|
|
109
|
+
return {
|
|
110
|
+
method: BID_METHOD,
|
|
111
|
+
url: BIDDER_URL,
|
|
112
|
+
data: generateBidRequestsFromAdUnits(adUnits, bidRequestId, adUnitContext),
|
|
113
|
+
options: {
|
|
114
|
+
contentType: 'application/json',
|
|
115
|
+
withCredentials: false,
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function generateBidRequestsFromAdUnits(bidRequests, bidRequestId, adUnitContext) {
|
|
121
|
+
const userObjBid = find(bidRequests, hasUserInfo);
|
|
122
|
+
let userObj = {};
|
|
123
|
+
if (userObjBid) {
|
|
124
|
+
Object.keys(userObjBid.params.user)
|
|
125
|
+
.filter(param => includes(USER_PARAMS, param))
|
|
126
|
+
.forEach((param) => {
|
|
127
|
+
let uparam = convertCamelToUnderscore(param);
|
|
128
|
+
if (param === 'segments' && isArray(userObjBid.params.user[param])) {
|
|
129
|
+
let segs = [];
|
|
130
|
+
userObjBid.params.user[param].forEach(val => {
|
|
131
|
+
if (isNumber(val)) {
|
|
132
|
+
segs.push({'id': val});
|
|
133
|
+
} else if (isPlainObject(val)) {
|
|
134
|
+
segs.push(val);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
userObj[uparam] = segs;
|
|
138
|
+
} else if (param !== 'segments') {
|
|
139
|
+
userObj[uparam] = userObjBid.params.user[param];
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const deviceObjBid = find(bidRequests, hasDeviceInfo);
|
|
145
|
+
let deviceObj;
|
|
146
|
+
if (deviceObjBid && deviceObjBid.params && deviceObjBid.params.device) {
|
|
147
|
+
deviceObj = {};
|
|
148
|
+
Object.keys(deviceObjBid.params.device)
|
|
149
|
+
.filter(param => includes(DEVICE_PARAMS, param))
|
|
150
|
+
.forEach(param => deviceObj[param] = deviceObjBid.params.device[param]);
|
|
151
|
+
if (!deviceObjBid.hasOwnProperty('ua')) {
|
|
152
|
+
deviceObj.ua = navigator.userAgent;
|
|
153
|
+
}
|
|
154
|
+
if (!deviceObjBid.hasOwnProperty('language')) {
|
|
155
|
+
deviceObj.language = navigator.language;
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
deviceObj = {};
|
|
159
|
+
deviceObj.ua = navigator.userAgent;
|
|
160
|
+
deviceObj.language = navigator.language;
|
|
161
|
+
}
|
|
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
|
+
|
|
170
|
+
const payload = {}
|
|
171
|
+
payload.id = bidRequestId
|
|
172
|
+
payload.at = FIRST_PRICE
|
|
173
|
+
payload.cur = ['USD']
|
|
174
|
+
payload.imp = bidRequests.reduce(generateImpressionsFromAdUnit, [])
|
|
175
|
+
payload.site = generateSiteFromAdUnitContext(bidRequests, adUnitContext)
|
|
176
|
+
payload.device = deviceObj
|
|
177
|
+
if (appDeviceObjBid && payload.site != null) {
|
|
178
|
+
payload.app = appIdObj;
|
|
179
|
+
}
|
|
180
|
+
payload.user = userObj
|
|
181
|
+
// payload.regs = getRegulationFromAdUnitContext(adUnitContext)
|
|
182
|
+
// payload.ext = generateBidRequestExtension()
|
|
183
|
+
|
|
184
|
+
return payload
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function generateImpressionsFromAdUnit(acc, adUnit) {
|
|
188
|
+
const {bidId, mediaTypes, params} = adUnit;
|
|
189
|
+
const {placementId} = params;
|
|
190
|
+
const pmp = {};
|
|
191
|
+
|
|
192
|
+
if (placementId) pmp.deals = [{id: placementId}]
|
|
193
|
+
|
|
194
|
+
const imps = Object
|
|
195
|
+
.keys(mediaTypes)
|
|
196
|
+
.reduce((acc, mediaType) => {
|
|
197
|
+
const data = mediaTypes[mediaType];
|
|
198
|
+
const impId = `${bidId}`;
|
|
199
|
+
|
|
200
|
+
if (mediaType === 'banner') return acc.concat(generateBannerFromAdUnit(impId, data, params));
|
|
201
|
+
}, []);
|
|
202
|
+
|
|
203
|
+
return acc.concat(imps);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function generateBannerFromAdUnit(impId, data, params) {
|
|
207
|
+
const {position, placementId} = params;
|
|
208
|
+
const pos = position || 0;
|
|
209
|
+
const pmp = {};
|
|
210
|
+
const ext = {placementId};
|
|
211
|
+
|
|
212
|
+
if (placementId) pmp.deals = [{id: placementId}]
|
|
213
|
+
|
|
214
|
+
return data.sizes.map(([w, h]) => ({id: `${impId}`, banner: {format: [{w, h}], w, h, pos}, pmp, ext, tagid: placementId}));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function validateServerResponse(serverResponse) {
|
|
218
|
+
return isPlainObject(serverResponse) &&
|
|
219
|
+
isPlainObject(serverResponse.body) &&
|
|
220
|
+
isStr(serverResponse.body.cur) &&
|
|
221
|
+
isArray(serverResponse.body.seatbid);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function seatBidsToAds(seatBid, bidResponse, serverRequest) {
|
|
225
|
+
return seatBid.bid
|
|
226
|
+
.filter(bid => validateBids(bid))
|
|
227
|
+
.map(bid => generateAdFromBid(bid, bidResponse));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function validateBids(bid) {
|
|
231
|
+
if (!isPlainObject(bid)) return false;
|
|
232
|
+
if (!isStr(bid.impid)) return false;
|
|
233
|
+
if (!isStr(bid.crid)) return false;
|
|
234
|
+
if (!isNumber(bid.price)) return false;
|
|
235
|
+
if (!isNumber(bid.w)) return false;
|
|
236
|
+
if (!isNumber(bid.h)) return false;
|
|
237
|
+
if (!bid.adm) return false;
|
|
238
|
+
if (bid.adm) {
|
|
239
|
+
if (!isStr(bid.adm)) return false;
|
|
240
|
+
}
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const VAST_REGEXP = /VAST\s+version/;
|
|
245
|
+
|
|
246
|
+
function getMediaType(adm) {
|
|
247
|
+
const videoRegex = new RegExp(VAST_REGEXP);
|
|
248
|
+
|
|
249
|
+
if (videoRegex.test(adm)) {
|
|
250
|
+
return VIDEO;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const markup = safeJSONparse(adm.replace(/\\/g, ''));
|
|
254
|
+
|
|
255
|
+
if (markup && isPlainObject(markup.native)) {
|
|
256
|
+
return NATIVE;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return BANNER;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function safeJSONparse(...args) {
|
|
263
|
+
try {
|
|
264
|
+
return JSON.parse(...args);
|
|
265
|
+
} catch (_) {
|
|
266
|
+
return undefined;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function generateAdFromBid(bid, bidResponse) {
|
|
271
|
+
const mediaType = getMediaType(bid.adm);
|
|
272
|
+
const base = {
|
|
273
|
+
requestId: bid.impid,
|
|
274
|
+
cpm: bid.price,
|
|
275
|
+
currency: bidResponse.cur,
|
|
276
|
+
ttl: TTL,
|
|
277
|
+
creativeId: bid.crid,
|
|
278
|
+
mediaType: mediaType,
|
|
279
|
+
netRevenue: NET_REVENUE
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
if (bid.adomain) {
|
|
283
|
+
base.meta = { advertiserDomains: bid.adomain };
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const size = getSizeFromBid(bid);
|
|
287
|
+
const creative = getCreativeFromBid(bid);
|
|
288
|
+
|
|
289
|
+
return {
|
|
290
|
+
...base,
|
|
291
|
+
height: size.height,
|
|
292
|
+
width: size.width,
|
|
293
|
+
ad: creative.markup,
|
|
294
|
+
adUrl: creative.markupUrl,
|
|
295
|
+
// vastXml: isVideo && !isStr(creative.markupUrl) ? creative.markup : null,
|
|
296
|
+
// vastUrl: isVideo && isStr(creative.markupUrl) ? creative.markupUrl : null,
|
|
297
|
+
renderer: creative.renderer
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function getSizeFromBid(bid) {
|
|
302
|
+
if (isNumber(bid.w) && isNumber(bid.h)) {
|
|
303
|
+
return { width: bid.w, height: bid.h };
|
|
304
|
+
}
|
|
305
|
+
return { width: null, height: null };
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function getCreativeFromBid(bid) {
|
|
309
|
+
const shouldUseAdMarkup = !!bid.adm;
|
|
310
|
+
const price = bid.price;
|
|
311
|
+
return {
|
|
312
|
+
markup: shouldUseAdMarkup ? replaceAuctionPrice(bid.adm, price) : null,
|
|
313
|
+
markupUrl: !shouldUseAdMarkup ? replaceAuctionPrice(bid.nurl, price) : null
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function hasDeviceInfo(bid) {
|
|
318
|
+
if (bid.params) {
|
|
319
|
+
return !!bid.params.device
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function hasAppInfo(bid) {
|
|
324
|
+
if (bid.params) {
|
|
325
|
+
return !!bid.params.app
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const venavenBidderSpec = {
|
|
330
|
+
code: 'ventes',
|
|
331
|
+
supportedMediaTypes: [BANNER],
|
|
332
|
+
isBidRequestValid(adUnit) {
|
|
333
|
+
const allowedBidderCodes = [this.code];
|
|
334
|
+
|
|
335
|
+
return isPlainObject(adUnit) &&
|
|
336
|
+
allowedBidderCodes.indexOf(adUnit.bidder) !== -1 &&
|
|
337
|
+
isStr(adUnit.adUnitCode) &&
|
|
338
|
+
isStr(adUnit.bidderRequestId) &&
|
|
339
|
+
isStr(adUnit.bidId) &&
|
|
340
|
+
validateMediaTypes(adUnit.mediaTypes, this.supportedMediaTypes) &&
|
|
341
|
+
validateParameters(adUnit.params, adUnit);
|
|
342
|
+
},
|
|
343
|
+
buildRequests(bidRequests, bidderRequest) {
|
|
344
|
+
if (!bidRequests) return null;
|
|
345
|
+
|
|
346
|
+
return groupBy(bidRequests, 'bidderRequestId').map(group => {
|
|
347
|
+
const bidRequestId = group.id;
|
|
348
|
+
const adUnits = groupBy(group.values, 'bidId').map((group) => {
|
|
349
|
+
const length = group.values.length;
|
|
350
|
+
return length > 0 && group.values[length - 1]
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
return createServerRequestFromAdUnits(adUnits, bidRequestId, bidderRequest)
|
|
354
|
+
});
|
|
355
|
+
},
|
|
356
|
+
interpretResponse(serverResponse, serverRequest) {
|
|
357
|
+
if (!validateServerRequest(serverRequest)) return [];
|
|
358
|
+
if (!validateServerResponse(serverResponse)) return [];
|
|
359
|
+
|
|
360
|
+
const bidResponse = serverResponse.body;
|
|
361
|
+
|
|
362
|
+
return bidResponse.seatbid
|
|
363
|
+
.filter(seatBid => isPlainObject(seatBid) && isArray(seatBid.bid))
|
|
364
|
+
.reduce((acc, seatBid) => acc.concat(seatBidsToAds(seatBid, bidResponse, serverRequest)), []);
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
registerBidder(venavenBidderSpec);
|
|
369
|
+
|
|
370
|
+
export {venavenBidderSpec as spec};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: bidder
|
|
3
|
+
title: ventes
|
|
4
|
+
description: Prebid ventes Bidder Adapter
|
|
5
|
+
pbjs: false
|
|
6
|
+
biddercode: ventes
|
|
7
|
+
gdpr_supported: false
|
|
8
|
+
usp_supported: false
|
|
9
|
+
media_types: banner
|
|
10
|
+
coppa_supported: false
|
|
11
|
+
schain_supported: false
|
|
12
|
+
dchain_supported: false
|
|
13
|
+
prebid_member: false
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
### BidParams
|
|
17
|
+
{: .table .table-bordered .table-striped }
|
|
18
|
+
| Name | Scope | Description | Example | Type |
|
|
19
|
+
|-----------------|----------|-----------------------------------------------------------|----------------------------------------------|---------------|
|
|
20
|
+
| `placementId` | required | Placement ID from Ventes Avenues | `'VA-062-0013-0183'` | `string` |
|
|
21
|
+
| `publisherId` | required | Publisher ID from Ventes Avenues | `'VA-062'` | `string` |
|
|
22
|
+
| `user` | optional | Object that specifies information about an external user. | `user: { age: 25, gender: 0, dnt: true}` | `object` |
|
|
23
|
+
| `app` | required | Object containing mobile app parameters. | `app : { id: 'app-id'}` | `object` |
|
|
24
|
+
| `device` | required | Object containing device info mandatory for mobile devices| `device : { ifa: 'device-id'}` | `object` |
|
|
25
|
+
|
|
26
|
+
#### User Object
|
|
27
|
+
|
|
28
|
+
{: .table .table-bordered .table-striped }
|
|
29
|
+
| Name | Description | Example | Type |
|
|
30
|
+
|-------------------|-------------------------------------------------------------------------------------------|-----------------------|-----------------------|
|
|
31
|
+
| `age` | The age of the user. | `35` | `integer` |
|
|
32
|
+
| `externalUid` | Specifies a string that corresponds to an external user ID for this user. | `'1234567890abcdefg'` | `string` |
|
|
33
|
+
| `segments` | Specifies the segments to which the user belongs. | `[1, 2]` | `Array<integer>` |
|
|
34
|
+
| `gender` | Specifies the gender of the user. Allowed values: Unknown: `0`; Male: `1`; Female: `2` | `1` | `integer` |
|
|
35
|
+
| `dnt` | Do not track flag. Indicates if tracking cookies should be disabled for this auction | `true` | `boolean` |
|
|
36
|
+
| `language` | Two-letter ANSI code for this user's language. | `EN` | `string` |
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
### Ad Unit Setup for Banner through mobile devices
|
|
40
|
+
```javascript
|
|
41
|
+
var adUnits = [
|
|
42
|
+
{
|
|
43
|
+
code: 'test-hb-ad-11111-1',
|
|
44
|
+
mediaTypes: {
|
|
45
|
+
banner: {
|
|
46
|
+
sizes: [
|
|
47
|
+
[300, 250]
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
bids: [{
|
|
52
|
+
bidder: 'ventes',
|
|
53
|
+
params: {
|
|
54
|
+
placementId: 'VA-062-0013-0183',
|
|
55
|
+
publisherId: '5cebea3c9eea646c7b623d5e',
|
|
56
|
+
IABCategories: "['IAB1', 'IAB5']",
|
|
57
|
+
device:{
|
|
58
|
+
ip: '123.145.167.189',
|
|
59
|
+
ifa:"AEBE52E7-03EE-455A-B3C4-E57283966239",
|
|
60
|
+
},
|
|
61
|
+
app: {
|
|
62
|
+
id: "agltb3B1Yi1pbmNyDAsSA0FwcBiJkfIUDA",
|
|
63
|
+
name: "Yahoo Weather",
|
|
64
|
+
bundle: 'com.kiloo.subwaysurf',
|
|
65
|
+
storeurl: 'https://play.google.com/store/apps/details?id=com.kiloo.subwaysurf&hl=en',
|
|
66
|
+
domain: 'somoaudience.com',
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}]
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Ad Unit Setup for Banner through Websites
|
|
75
|
+
```javascript
|
|
76
|
+
var adUnits = [
|
|
77
|
+
{
|
|
78
|
+
code: 'test-hb-ad-11111-1',
|
|
79
|
+
mediaTypes: {
|
|
80
|
+
banner: {
|
|
81
|
+
sizes: [
|
|
82
|
+
[300, 250]
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
bids: [{
|
|
87
|
+
bidder: 'ventes',
|
|
88
|
+
params: {
|
|
89
|
+
placementId: 'VA-002-0007-0799',
|
|
90
|
+
publisherId: '5cebea3c9eea646c7b623d5e',
|
|
91
|
+
}
|
|
92
|
+
}]
|
|
93
|
+
}
|
|
94
|
+
]
|
|
@@ -27,7 +27,7 @@ export const spec = {
|
|
|
27
27
|
code: BIDDER_CODE,
|
|
28
28
|
supportedMediaTypes: [VIDEO],
|
|
29
29
|
VERSION: '1.0.0',
|
|
30
|
-
ENDPOINT: 'https://x.videobyte.com/
|
|
30
|
+
ENDPOINT: 'https://x.videobyte.com/ortbhb',
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* Determines whether or not the given bid request is valid.
|
|
@@ -53,13 +53,22 @@ export const spec = {
|
|
|
53
53
|
return bidRequests.map(bidRequest => {
|
|
54
54
|
const {params} = bidRequest;
|
|
55
55
|
let pubId = params.pubId;
|
|
56
|
+
const placementId = params.placementId;
|
|
57
|
+
const nId = params.nid;
|
|
56
58
|
if (bidRequest.params.video && bidRequest.params.video.e2etest) {
|
|
57
59
|
logMessage('E2E test mode enabled');
|
|
58
60
|
pubId = 'e2etest'
|
|
59
61
|
}
|
|
62
|
+
let baseEndpoint = spec.ENDPOINT + '?pid=' + pubId;
|
|
63
|
+
if (placementId) {
|
|
64
|
+
baseEndpoint += '&placementId=' + placementId
|
|
65
|
+
}
|
|
66
|
+
if (nId) {
|
|
67
|
+
baseEndpoint += '&nid=' + nId
|
|
68
|
+
}
|
|
60
69
|
return {
|
|
61
70
|
method: 'POST',
|
|
62
|
-
url:
|
|
71
|
+
url: baseEndpoint,
|
|
63
72
|
data: JSON.stringify(buildRequestData(bidRequest, bidderRequest)),
|
|
64
73
|
}
|
|
65
74
|
});
|
|
@@ -97,8 +106,6 @@ export const spec = {
|
|
|
97
106
|
};
|
|
98
107
|
bidResponses.push(bidResponse)
|
|
99
108
|
}
|
|
100
|
-
} else {
|
|
101
|
-
logError('invalid server response received');
|
|
102
109
|
}
|
|
103
110
|
return bidResponses;
|
|
104
111
|
},
|
|
@@ -228,7 +235,7 @@ function buildRequestData(bidRequest, bidderRequest) {
|
|
|
228
235
|
// content
|
|
229
236
|
if (videoParams.content && isPlainObject(videoParams.content)) {
|
|
230
237
|
openrtbRequest.site.content = {};
|
|
231
|
-
const contentStringKeys = ['id', 'title', 'series', 'season', 'genre', 'contentrating', 'language'];
|
|
238
|
+
const contentStringKeys = ['id', 'title', 'series', 'season', 'genre', 'contentrating', 'language', 'url'];
|
|
232
239
|
const contentNumberkeys = ['episode', 'prodq', 'context', 'livestream', 'len'];
|
|
233
240
|
const contentArrayKeys = ['cat'];
|
|
234
241
|
const contentObjectKeys = ['ext'];
|
|
@@ -271,7 +278,7 @@ function validateVideo(bidRequest) {
|
|
|
271
278
|
}
|
|
272
279
|
|
|
273
280
|
if (!bidRequest.params.pubId) {
|
|
274
|
-
logError('failed validation:
|
|
281
|
+
logError('failed validation: pubId not declared');
|
|
275
282
|
return false;
|
|
276
283
|
}
|
|
277
284
|
|
|
@@ -49,6 +49,55 @@ Module that connects to VideoByte's demand sources
|
|
|
49
49
|
]
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
## Instream Video adUnit with placement, nid and content params
|
|
53
|
+
```
|
|
54
|
+
var adUnits = [
|
|
55
|
+
{
|
|
56
|
+
code: 'video1',
|
|
57
|
+
mediaTypes: {
|
|
58
|
+
video: {
|
|
59
|
+
context: 'instream',
|
|
60
|
+
playerSize: [640, 480],
|
|
61
|
+
mimes: ['video/mp4', 'application/javascript'],
|
|
62
|
+
protocols: [2,5],
|
|
63
|
+
api: [2],
|
|
64
|
+
position: 1,
|
|
65
|
+
delivery: [2],
|
|
66
|
+
minduration: 10,
|
|
67
|
+
maxduration: 30,
|
|
68
|
+
placement: 1,
|
|
69
|
+
playbackmethod: [1,5],
|
|
70
|
+
protocols: [2,5],
|
|
71
|
+
api: [2],
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
bids: [
|
|
75
|
+
{
|
|
76
|
+
bidder: 'videobyte',
|
|
77
|
+
params: {
|
|
78
|
+
bidfloor: 0.5,
|
|
79
|
+
pubId: 'e2etest',
|
|
80
|
+
placementId: '1234567',
|
|
81
|
+
nid: '1234',
|
|
82
|
+
video: {
|
|
83
|
+
content:{
|
|
84
|
+
id: "uuid",
|
|
85
|
+
url: "https://videobyte.com/awesome-video.mp4",
|
|
86
|
+
title: "Awesome video",
|
|
87
|
+
genre: "Comedy",
|
|
88
|
+
language: "en",
|
|
89
|
+
season: "1",
|
|
90
|
+
series: "1",
|
|
91
|
+
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
```
|
|
100
|
+
|
|
52
101
|
# End To End testing mode
|
|
53
102
|
By passing bid.params.video.e2etest = true you will be able to receive a test creative
|
|
54
103
|
|