prebid.js 5.19.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/.babelrc.js +1 -10
- package/README.md +4 -2
- package/browsers.json +13 -37
- package/gulpfile.js +1 -0
- package/karma.conf.maker.js +1 -1
- package/modules/adheseBidAdapter.js +7 -2
- package/modules/adkernelBidAdapter.js +1 -0
- package/modules/adlivetechBidAdapter.md +61 -0
- package/modules/admixerBidAdapter.js +2 -1
- package/modules/adnuntiusBidAdapter.js +2 -1
- package/modules/adomikAnalyticsAdapter.js +10 -4
- package/modules/adplusBidAdapter.js +203 -0
- package/modules/adplusBidAdapter.md +39 -0
- package/modules/adyoulikeBidAdapter.js +7 -2
- package/modules/airgridRtdProvider.js +1 -1
- package/modules/appnexusBidAdapter.js +28 -5
- package/modules/atsAnalyticsAdapter.js +67 -46
- package/modules/atsAnalyticsAdapter.md +1 -0
- package/modules/beachfrontBidAdapter.js +14 -17
- package/modules/betweenBidAdapter.js +2 -1
- package/modules/browsiRtdProvider.js +106 -18
- package/modules/cleanioRtdProvider.js +192 -0
- package/modules/cleanioRtdProvider.md +59 -0
- package/modules/codefuelBidAdapter.js +1 -3
- package/modules/codefuelBidAdapter.md +3 -3
- package/modules/craftBidAdapter.js +5 -3
- package/modules/datablocksBidAdapter.js +3 -3
- package/modules/dchain.js +149 -0
- package/modules/dchain.md +45 -0
- package/modules/deepintentBidAdapter.js +1 -1
- package/modules/deltaprojectsBidAdapter.js +252 -0
- package/modules/deltaprojectsBidAdapter.md +32 -0
- package/modules/emx_digitalBidAdapter.js +9 -1
- package/modules/engageyaBidAdapter.js +68 -54
- package/modules/freewheel-sspBidAdapter.js +6 -0
- package/modules/glimpseBidAdapter.js +31 -16
- package/modules/goldbachBidAdapter.js +1176 -0
- package/modules/goldbachBidAdapter.md +151 -0
- package/modules/gptPreAuction.js +11 -5
- package/modules/gridBidAdapter.js +1 -0
- package/modules/gumgumBidAdapter.js +5 -1
- package/modules/id5IdSystem.md +6 -6
- package/modules/imRtdProvider.js +31 -0
- package/modules/intersectionRtdProvider.js +114 -0
- package/modules/invibesBidAdapter.js +15 -9
- package/modules/ipromBidAdapter.js +79 -0
- package/modules/ixBidAdapter.js +173 -22
- package/modules/jixieBidAdapter.js +8 -2
- package/modules/justpremiumBidAdapter.js +6 -1
- package/modules/limelightDigitalBidAdapter.js +2 -1
- package/modules/livewrappedAnalyticsAdapter.js +5 -0
- package/modules/luponmediaBidAdapter.js +570 -0
- package/modules/merkleIdSystem.js +5 -0
- package/modules/missenaBidAdapter.js +89 -0
- package/modules/multibid/index.js +3 -3
- package/modules/nativoBidAdapter.js +32 -2
- package/modules/oguryBidAdapter.js +2 -1
- package/modules/openxBidAdapter.js +7 -2
- 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/pubmaticBidAdapter.js +5 -3
- package/modules/relaidoBidAdapter.js +86 -65
- package/modules/richaudienceBidAdapter.js +1 -1
- 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 +9 -1
- package/modules/smartxBidAdapter.js +17 -1
- package/modules/sonobiBidAdapter.js +7 -0
- package/modules/sortableBidAdapter.js +1 -0
- package/modules/sspBCBidAdapter.js +34 -3
- package/modules/tappxBidAdapter.js +3 -1
- package/modules/teadsBidAdapter.js +3 -0
- package/modules/trustxBidAdapter.js +18 -7
- package/modules/undertoneBidAdapter.js +8 -1
- package/modules/userId/index.js +27 -2
- package/modules/ventes.md +71 -0
- package/modules/ventesBidAdapter.js +410 -0
- package/modules/ventesBidAdapter.md +93 -0
- package/modules/vidoomyBidAdapter.js +51 -100
- package/modules/visxBidAdapter.js +20 -3
- package/modules/visxBidAdapter.md +4 -6
- package/modules/yahoosspBidAdapter.js +6 -6
- package/modules/yahoosspBidAdapter.md +1 -1
- package/modules/yieldlabBidAdapter.js +41 -10
- package/modules/yieldlabBidAdapter.md +91 -48
- package/modules/yieldoneBidAdapter.js +115 -11
- package/package.json +6 -1
- package/src/adapterManager.js +14 -8
- package/src/auction.js +14 -13
- 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/adheseBidAdapter_spec.js +27 -1
- package/test/spec/modules/adnuntiusBidAdapter_spec.js +18 -0
- package/test/spec/modules/adomikAnalyticsAdapter_spec.js +3 -1
- 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 +65 -2
- package/test/spec/modules/atsAnalyticsAdapter_spec.js +42 -9
- package/test/spec/modules/beachfrontBidAdapter_spec.js +65 -1
- 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 +1 -1
- package/test/spec/modules/datablocksBidAdapter_spec.js +3 -3
- package/test/spec/modules/dchain_spec.js +329 -0
- package/test/spec/modules/deltaprojectsBidAdapter_spec.js +399 -0
- package/test/spec/modules/emx_digitalBidAdapter_spec.js +10 -0
- package/test/spec/modules/engageyaBidAdapter_spec.js +231 -95
- package/test/spec/modules/eplanningBidAdapter_spec.js +8 -8
- package/test/spec/modules/freewheel-sspBidAdapter_spec.js +19 -0
- package/test/spec/modules/glimpseBidAdapter_spec.js +33 -0
- package/test/spec/modules/goldbachBidAdapter_spec.js +1359 -0
- package/test/spec/modules/gptPreAuction_spec.js +58 -4
- package/test/spec/modules/gumgumBidAdapter_spec.js +6 -0
- package/test/spec/modules/imRtdProvider_spec.js +25 -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/ixBidAdapter_spec.js +288 -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 +10 -7
- package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +23 -4
- package/test/spec/modules/luponmediaBidAdapter_spec.js +412 -0
- package/test/spec/modules/merkleIdSystem_spec.js +18 -0
- package/test/spec/modules/missenaBidAdapter_spec.js +134 -0
- package/test/spec/modules/multibid_spec.js +31 -31
- package/test/spec/modules/nativoBidAdapter_spec.js +35 -18
- package/test/spec/modules/oguryBidAdapter_spec.js +13 -11
- package/test/spec/modules/openxBidAdapter_spec.js +5 -26
- 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/pubmaticBidAdapter_spec.js +1 -1
- package/test/spec/modules/relaidoBidAdapter_spec.js +71 -63
- package/test/spec/modules/seedtagBidAdapter_spec.js +3 -0
- package/test/spec/modules/smaatoBidAdapter_spec.js +61 -0
- package/test/spec/modules/smartxBidAdapter_spec.js +9 -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/tappxBidAdapter_spec.js +4 -0
- package/test/spec/modules/teadsBidAdapter_spec.js +132 -0
- package/test/spec/modules/trustxBidAdapter_spec.js +45 -3
- package/test/spec/modules/userId_spec.js +51 -0
- package/test/spec/modules/ventesBidAdapter_spec.js +845 -0
- package/test/spec/modules/vidoomyBidAdapter_spec.js +32 -13
- package/test/spec/modules/visxBidAdapter_spec.js +121 -5
- package/test/spec/modules/yieldlabBidAdapter_spec.js +81 -0
- package/test/spec/modules/yieldoneBidAdapter_spec.js +299 -53
- package/test/spec/unit/core/adapterManager_spec.js +26 -7
- package/test/spec/unit/core/targeting_spec.js +44 -0
- package/wdio.conf.js +1 -1
|
@@ -0,0 +1,410 @@
|
|
|
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';
|
|
14
|
+
import find from 'core-js-pure/features/array/find.js';
|
|
15
|
+
import {
|
|
16
|
+
registerBidder
|
|
17
|
+
} from '../src/adapters/bidderFactory.js';
|
|
18
|
+
|
|
19
|
+
const BID_METHOD = 'POST';
|
|
20
|
+
const BIDDER_URL = 'http://13.234.201.146:8088/va/ad';
|
|
21
|
+
|
|
22
|
+
const DOMAIN_REGEX = new RegExp('//([^/]*)');
|
|
23
|
+
|
|
24
|
+
function groupBy(values, key) {
|
|
25
|
+
const groups = values.reduce((acc, value) => {
|
|
26
|
+
const groupId = value[key];
|
|
27
|
+
|
|
28
|
+
if (!acc[groupId]) acc[groupId] = [];
|
|
29
|
+
acc[groupId].push(value);
|
|
30
|
+
|
|
31
|
+
return acc;
|
|
32
|
+
}, {});
|
|
33
|
+
|
|
34
|
+
return Object
|
|
35
|
+
.keys(groups)
|
|
36
|
+
.map(id => ({
|
|
37
|
+
id,
|
|
38
|
+
key,
|
|
39
|
+
values: groups[id]
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function validateMediaTypes(mediaTypes, allowedMediaTypes) {
|
|
44
|
+
if (!isPlainObject(mediaTypes)) return false;
|
|
45
|
+
if (!allowedMediaTypes.some(mediaType => mediaType in mediaTypes)) return false;
|
|
46
|
+
|
|
47
|
+
if (isBanner(mediaTypes)) {
|
|
48
|
+
if (!validateBanner(mediaTypes.banner)) return false;
|
|
49
|
+
}
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function isBanner(mediaTypes) {
|
|
54
|
+
return isPlainObject(mediaTypes) && isPlainObject(mediaTypes.banner);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function validateBanner(banner) {
|
|
58
|
+
return isPlainObject(banner) &&
|
|
59
|
+
isArray(banner.sizes) &&
|
|
60
|
+
(banner.sizes.length > 0) &&
|
|
61
|
+
banner.sizes.every(validateMediaSizes);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function validateMediaSizes(mediaSize) {
|
|
65
|
+
return isArray(mediaSize) &&
|
|
66
|
+
(mediaSize.length === 2) &&
|
|
67
|
+
mediaSize.every(size => (isNumber(size) && size >= 0));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function hasUserInfo(bid) {
|
|
71
|
+
return !!bid.params.user;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function validateParameters(parameters) {
|
|
75
|
+
if (!(parameters.placementId)) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
if (!(parameters.publisherId)) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function extractSiteDomainFromURL(url) {
|
|
86
|
+
if (!url || !isStr(url)) return null;
|
|
87
|
+
|
|
88
|
+
const domain = url.match(DOMAIN_REGEX);
|
|
89
|
+
|
|
90
|
+
if (isArray(domain) && domain.length === 2) return domain[1];
|
|
91
|
+
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function generateSiteFromAdUnitContext(bidRequests, adUnitContext) {
|
|
96
|
+
if (!adUnitContext || !adUnitContext.refererInfo) return null;
|
|
97
|
+
|
|
98
|
+
const domain = extractSiteDomainFromURL(adUnitContext.refererInfo.referer);
|
|
99
|
+
const publisherId = bidRequests[0].params.publisherId;
|
|
100
|
+
|
|
101
|
+
if (!domain) return null;
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
page: adUnitContext.refererInfo.referer,
|
|
105
|
+
domain: domain,
|
|
106
|
+
name: domain,
|
|
107
|
+
publisher: {
|
|
108
|
+
id: publisherId
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function validateServerRequest(serverRequest) {
|
|
114
|
+
return isPlainObject(serverRequest) &&
|
|
115
|
+
isPlainObject(serverRequest.data) &&
|
|
116
|
+
isArray(serverRequest.data.imp)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function createServerRequestFromAdUnits(adUnits, bidRequestId, adUnitContext) {
|
|
120
|
+
return {
|
|
121
|
+
method: BID_METHOD,
|
|
122
|
+
url: BIDDER_URL,
|
|
123
|
+
data: generateBidRequestsFromAdUnits(adUnits, bidRequestId, adUnitContext),
|
|
124
|
+
options: {
|
|
125
|
+
contentType: 'application/json',
|
|
126
|
+
withCredentials: false,
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function generateBidRequestsFromAdUnits(bidRequests, bidRequestId, adUnitContext) {
|
|
132
|
+
const userObjBid = find(bidRequests, hasUserInfo);
|
|
133
|
+
let userObj = {};
|
|
134
|
+
if (userObjBid) {
|
|
135
|
+
Object.keys(userObjBid.params.user)
|
|
136
|
+
.forEach((param) => {
|
|
137
|
+
let uparam = convertCamelToUnderscore(param);
|
|
138
|
+
if (param === 'segments' && isArray(userObjBid.params.user[param])) {
|
|
139
|
+
let segs = [];
|
|
140
|
+
userObjBid.params.user[param].forEach(val => {
|
|
141
|
+
if (isNumber(val)) {
|
|
142
|
+
segs.push({
|
|
143
|
+
'id': val
|
|
144
|
+
});
|
|
145
|
+
} else if (isPlainObject(val)) {
|
|
146
|
+
segs.push(val);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
userObj[uparam] = segs;
|
|
150
|
+
} else if (param !== 'segments') {
|
|
151
|
+
userObj[uparam] = userObjBid.params.user[param];
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const deviceObjBid = find(bidRequests, hasDeviceInfo);
|
|
157
|
+
let deviceObj;
|
|
158
|
+
if (deviceObjBid && deviceObjBid.params && deviceObjBid.params.device) {
|
|
159
|
+
deviceObj = {};
|
|
160
|
+
Object.keys(deviceObjBid.params.device)
|
|
161
|
+
.forEach(param => deviceObj[param] = deviceObjBid.params.device[param]);
|
|
162
|
+
if (!deviceObjBid.hasOwnProperty('ua')) {
|
|
163
|
+
deviceObj.ua = navigator.userAgent;
|
|
164
|
+
}
|
|
165
|
+
if (!deviceObjBid.hasOwnProperty('language')) {
|
|
166
|
+
deviceObj.language = navigator.language;
|
|
167
|
+
}
|
|
168
|
+
} else {
|
|
169
|
+
deviceObj = {};
|
|
170
|
+
deviceObj.ua = navigator.userAgent;
|
|
171
|
+
deviceObj.language = navigator.language;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const payload = {}
|
|
175
|
+
payload.id = bidRequestId
|
|
176
|
+
payload.at = 1
|
|
177
|
+
payload.cur = ['USD']
|
|
178
|
+
payload.imp = bidRequests.reduce(generateImpressionsFromAdUnit, [])
|
|
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
|
+
}
|
|
189
|
+
payload.app = appIdObj;
|
|
190
|
+
}
|
|
191
|
+
payload.device = deviceObj;
|
|
192
|
+
payload.user = userObj
|
|
193
|
+
return payload
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function generateImpressionsFromAdUnit(acc, adUnit) {
|
|
197
|
+
const {
|
|
198
|
+
bidId,
|
|
199
|
+
mediaTypes,
|
|
200
|
+
params
|
|
201
|
+
} = adUnit;
|
|
202
|
+
const {
|
|
203
|
+
placementId
|
|
204
|
+
} = params;
|
|
205
|
+
const pmp = {};
|
|
206
|
+
|
|
207
|
+
if (placementId) pmp.deals = [{ id: placementId }]
|
|
208
|
+
|
|
209
|
+
const imps = Object
|
|
210
|
+
.keys(mediaTypes)
|
|
211
|
+
.reduce((acc, mediaType) => {
|
|
212
|
+
const data = mediaTypes[mediaType];
|
|
213
|
+
const impId = `${bidId}`;
|
|
214
|
+
|
|
215
|
+
if (mediaType === 'banner') return acc.concat(generateBannerFromAdUnit(impId, data, params));
|
|
216
|
+
}, []);
|
|
217
|
+
|
|
218
|
+
return acc.concat(imps);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function generateBannerFromAdUnit(impId, data, params) {
|
|
222
|
+
const {
|
|
223
|
+
position,
|
|
224
|
+
placementId
|
|
225
|
+
} = params;
|
|
226
|
+
const pos = position || 0;
|
|
227
|
+
const pmp = {};
|
|
228
|
+
const ext = {
|
|
229
|
+
placementId
|
|
230
|
+
};
|
|
231
|
+
|
|
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
|
+
}));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function validateServerResponse(serverResponse) {
|
|
252
|
+
return isPlainObject(serverResponse) &&
|
|
253
|
+
isPlainObject(serverResponse.body) &&
|
|
254
|
+
isStr(serverResponse.body.cur) &&
|
|
255
|
+
isArray(serverResponse.body.seatbid);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function seatBidsToAds(seatBid, bidResponse, serverRequest) {
|
|
259
|
+
return seatBid.bid
|
|
260
|
+
.filter(bid => validateBids(bid))
|
|
261
|
+
.map(bid => generateAdFromBid(bid, bidResponse));
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function validateBids(bid) {
|
|
265
|
+
if (!isPlainObject(bid)) return false;
|
|
266
|
+
if (!isStr(bid.impid)) return false;
|
|
267
|
+
if (!isStr(bid.crid)) return false;
|
|
268
|
+
if (!isNumber(bid.price)) return false;
|
|
269
|
+
if (!isNumber(bid.w)) return false;
|
|
270
|
+
if (!isNumber(bid.h)) return false;
|
|
271
|
+
if (!bid.adm) return false;
|
|
272
|
+
if (bid.adm) {
|
|
273
|
+
if (!isStr(bid.adm)) return false;
|
|
274
|
+
}
|
|
275
|
+
return true;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function getMediaType(adm) {
|
|
279
|
+
const videoRegex = new RegExp(/VAST\s+version/);
|
|
280
|
+
|
|
281
|
+
if (videoRegex.test(adm)) {
|
|
282
|
+
return VIDEO;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const markup = safeJSONparse(adm.replace(/\\/g, ''));
|
|
286
|
+
|
|
287
|
+
if (markup && isPlainObject(markup.native)) {
|
|
288
|
+
return NATIVE;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return BANNER;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function safeJSONparse(...args) {
|
|
295
|
+
try {
|
|
296
|
+
return JSON.parse(...args);
|
|
297
|
+
} catch (_) {
|
|
298
|
+
return undefined;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function generateAdFromBid(bid, bidResponse) {
|
|
303
|
+
const mediaType = getMediaType(bid.adm);
|
|
304
|
+
const base = {
|
|
305
|
+
requestId: bid.impid,
|
|
306
|
+
cpm: bid.price,
|
|
307
|
+
currency: bidResponse.cur,
|
|
308
|
+
ttl: 10,
|
|
309
|
+
creativeId: bid.crid,
|
|
310
|
+
mediaType: mediaType,
|
|
311
|
+
netRevenue: true
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
if (bid.adomain) {
|
|
315
|
+
base.meta = {
|
|
316
|
+
advertiserDomains: bid.adomain
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
const size = getSizeFromBid(bid);
|
|
321
|
+
const creative = getCreativeFromBid(bid);
|
|
322
|
+
|
|
323
|
+
return {
|
|
324
|
+
...base,
|
|
325
|
+
height: size.height,
|
|
326
|
+
width: size.width,
|
|
327
|
+
ad: creative.markup,
|
|
328
|
+
adUrl: creative.markupUrl,
|
|
329
|
+
renderer: creative.renderer
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function getSizeFromBid(bid) {
|
|
334
|
+
if (isNumber(bid.w) && isNumber(bid.h)) {
|
|
335
|
+
return {
|
|
336
|
+
width: bid.w,
|
|
337
|
+
height: bid.h
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
width: null,
|
|
342
|
+
height: null
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function getCreativeFromBid(bid) {
|
|
347
|
+
const shouldUseAdMarkup = !!bid.adm;
|
|
348
|
+
const price = bid.price;
|
|
349
|
+
return {
|
|
350
|
+
markup: shouldUseAdMarkup ? replaceAuctionPrice(bid.adm, price) : null,
|
|
351
|
+
markupUrl: !shouldUseAdMarkup ? replaceAuctionPrice(bid.nurl, price) : null
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function hasDeviceInfo(bid) {
|
|
356
|
+
if (bid.params) {
|
|
357
|
+
return !!bid.params.device
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function hasAppInfo(bid) {
|
|
362
|
+
if (bid.params) {
|
|
363
|
+
return !!bid.params.app
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const venavenBidderSpec = {
|
|
368
|
+
code: 'ventes',
|
|
369
|
+
supportedMediaTypes: [BANNER],
|
|
370
|
+
isBidRequestValid(adUnit) {
|
|
371
|
+
const allowedBidderCodes = [this.code];
|
|
372
|
+
|
|
373
|
+
return isPlainObject(adUnit) &&
|
|
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);
|
|
380
|
+
},
|
|
381
|
+
buildRequests(bidRequests, bidderRequest) {
|
|
382
|
+
if (!bidRequests) return null;
|
|
383
|
+
|
|
384
|
+
return groupBy(bidRequests, 'bidderRequestId').map(group => {
|
|
385
|
+
const bidRequestId = group.id;
|
|
386
|
+
const adUnits = groupBy(group.values, 'bidId').map((group) => {
|
|
387
|
+
const length = group.values.length;
|
|
388
|
+
return length > 0 && group.values[length - 1]
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
return createServerRequestFromAdUnits(adUnits, bidRequestId, bidderRequest)
|
|
392
|
+
});
|
|
393
|
+
},
|
|
394
|
+
interpretResponse(serverResponse, serverRequest) {
|
|
395
|
+
if (!validateServerRequest(serverRequest)) return [];
|
|
396
|
+
if (!validateServerResponse(serverResponse)) return [];
|
|
397
|
+
|
|
398
|
+
const bidResponse = serverResponse.body;
|
|
399
|
+
|
|
400
|
+
return bidResponse.seatbid
|
|
401
|
+
.filter(seatBid => isPlainObject(seatBid) && isArray(seatBid.bid))
|
|
402
|
+
.reduce((acc, seatBid) => acc.concat(seatBidsToAds(seatBid, bidResponse, serverRequest)), []);
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
registerBidder(venavenBidderSpec);
|
|
407
|
+
|
|
408
|
+
export {
|
|
409
|
+
venavenBidderSpec as spec
|
|
410
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
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
|
+
ifa:"AEBE52E7-03EE-455A-B3C4-E57283966239",
|
|
59
|
+
},
|
|
60
|
+
app: {
|
|
61
|
+
id: "agltb3B1Yi1pbmNyDAsSA0FwcBiJkfIUDA",
|
|
62
|
+
name: "Yahoo Weather",
|
|
63
|
+
bundle: 'com.kiloo.subwaysurf',
|
|
64
|
+
storeurl: 'https://play.google.com/store/apps/details?id=com.kiloo.subwaysurf&hl=en',
|
|
65
|
+
domain: 'somoaudience.com',
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}]
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Ad Unit Setup for Banner through Websites
|
|
74
|
+
```javascript
|
|
75
|
+
var adUnits = [
|
|
76
|
+
{
|
|
77
|
+
code: 'test-hb-ad-11111-1',
|
|
78
|
+
mediaTypes: {
|
|
79
|
+
banner: {
|
|
80
|
+
sizes: [
|
|
81
|
+
[300, 250]
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
bids: [{
|
|
86
|
+
bidder: 'ventes',
|
|
87
|
+
params: {
|
|
88
|
+
placementId: 'VA-002-0007-0799',
|
|
89
|
+
publisherId: '5cebea3c9eea646c7b623d5e',
|
|
90
|
+
}
|
|
91
|
+
}]
|
|
92
|
+
}
|
|
93
|
+
]
|
|
@@ -9,7 +9,17 @@ const ENDPOINT = `https://d.vidoomy.com/api/rtbserver/prebid/`;
|
|
|
9
9
|
const BIDDER_CODE = 'vidoomy';
|
|
10
10
|
const GVLID = 380;
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const COOKIE_SYNC_FALLBACK_URLS = [
|
|
13
|
+
'https://x.bidswitch.net/sync?ssp=vidoomy',
|
|
14
|
+
'https://ib.adnxs.com/getuid?https%3A%2F%2Fa-prebid.vidoomy.com%2Fsetuid%3Fbidder%3Dadnxs%26gdpr%3D{{GDPR}}%26gdpr_consent%3D{{GDPR_CONSENT}}%26uid%3D%24UID',
|
|
15
|
+
'https://pixel-sync.sitescout.com/dmp/pixelSync?nid=120&redir=https%3A%2F%2Fa.vidoomy.com%2Fapi%2Frtbserver%2Fcookie%3Fi%3DCEN%26uid%3D%7BuserId%7D',
|
|
16
|
+
'https://sync.1rx.io/usersync2/vidoomy?redir=https%3A%2F%2Fa.vidoomy.com%2Fapi%2Frtbserver%2Fcookie%3Fi%3DUN%26uid%3D%5BRX_UUID%5D',
|
|
17
|
+
'https://rtb.openx.net/sync/prebid?gdpr={{GDPR}}&gdpr_consent={{GDPR_CONSENT}}&r=https%3A%2F%2Fa-prebid.vidoomy.com%2Fsetuid%3Fbidder%3Dopenx%26uid%3D$%7BUID%7D',
|
|
18
|
+
'https://ads.pubmatic.com/AdServer/js/user_sync.html?gdpr={{GDPR}}&gdpr_consent={{GDPR_CONSENT}}&us_privacy=&predirect=https%3A%2F%2Fa-prebid.vidoomy.com%2Fsetuid%3Fbidder%3Dpubmatic%26gdpr%3D{{GDPR}}%26gdpr_consent%3D{{GDPR_CONSENT}}%26uid%3D',
|
|
19
|
+
'https://cm.adform.net/cookie?redirect_url=https%3A%2F%2Fa-prebid.vidoomy.com%2Fsetuid%3Fbidder%3Dadf%26gdpr%3D{{GDPR}}%26gdpr_consent%3D{{GDPR_CONSENT}}%26uid%3D%24UID',
|
|
20
|
+
'https://ups.analytics.yahoo.com/ups/58531/occ?gdpr={{GDPR}}&gdpr_consent={{GDPR_CONSENT}}',
|
|
21
|
+
'https://ap.lijit.com/pixel?redir=https%3A%2F%2Fa-prebid.vidoomy.com%2Fsetuid%3Fbidder%3Dsovrn%26gdpr%3D{{GDPR}}%26gdpr_consent%3D{{GDPR_CONSENT}}%26uid%3D%24UID'
|
|
22
|
+
];
|
|
13
23
|
|
|
14
24
|
const isBidRequestValid = bid => {
|
|
15
25
|
if (!bid.params) {
|
|
@@ -36,7 +46,7 @@ const isBidRequestValid = bid => {
|
|
|
36
46
|
};
|
|
37
47
|
|
|
38
48
|
const isBidResponseValid = bid => {
|
|
39
|
-
if (!bid.requestId || !bid.cpm || !bid.ttl || !bid.currency) {
|
|
49
|
+
if (!bid || !bid.requestId || !bid.cpm || !bid.ttl || !bid.currency) {
|
|
40
50
|
return false;
|
|
41
51
|
}
|
|
42
52
|
switch (bid.mediaType) {
|
|
@@ -67,35 +77,33 @@ const buildRequests = (validBidRequests, bidderRequest) => {
|
|
|
67
77
|
|
|
68
78
|
const videoContext = deepAccess(bid, 'mediaTypes.video.context');
|
|
69
79
|
|
|
70
|
-
const queryParams =
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
const queryParams = {
|
|
81
|
+
id: bid.params.id,
|
|
82
|
+
adtype: adType,
|
|
83
|
+
w,
|
|
84
|
+
h,
|
|
85
|
+
pos: parseInt(bid.params.position) || 1,
|
|
86
|
+
ua: navigator.userAgent,
|
|
87
|
+
l: navigator.language && navigator.language.indexOf('-') !== -1 ? navigator.language.split('-')[0] : '',
|
|
88
|
+
dt: /Mobi/.test(navigator.userAgent) ? 2 : 1,
|
|
89
|
+
pid: bid.params.pid,
|
|
90
|
+
requestId: bid.bidId,
|
|
91
|
+
d: getDomainWithoutSubdomain(hostname),
|
|
92
|
+
sp: encodeURIComponent(aElement.href),
|
|
93
|
+
usp: bidderRequest.uspConsent || '',
|
|
94
|
+
coppa: !!config.getConfig('coppa'),
|
|
95
|
+
videoContext: videoContext || ''
|
|
96
|
+
};
|
|
97
|
+
|
|
83
98
|
if (bidderRequest.gdprConsent) {
|
|
84
|
-
queryParams.
|
|
85
|
-
queryParams.
|
|
99
|
+
queryParams.gdpr = bidderRequest.gdprConsent.gdprApplies;
|
|
100
|
+
queryParams.gdprcs = bidderRequest.gdprConsent.consentString;
|
|
86
101
|
}
|
|
87
|
-
queryParams.push(['usp', bidderRequest.uspConsent || '']);
|
|
88
|
-
queryParams.push(['coppa', !!config.getConfig('coppa')]);
|
|
89
|
-
|
|
90
|
-
const rawQueryParams = queryParams.map(qp => qp.join('=')).join('&');
|
|
91
102
|
|
|
92
|
-
cookieSync(bidderRequest)
|
|
93
|
-
|
|
94
|
-
const url = `${ENDPOINT}?${rawQueryParams}`;
|
|
95
103
|
return {
|
|
96
104
|
method: 'GET',
|
|
97
|
-
url:
|
|
98
|
-
data:
|
|
105
|
+
url: ENDPOINT,
|
|
106
|
+
data: queryParams
|
|
99
107
|
}
|
|
100
108
|
});
|
|
101
109
|
return serverRequests;
|
|
@@ -117,6 +125,7 @@ const render = (bid) => {
|
|
|
117
125
|
const interpretResponse = (serverResponse, bidRequest) => {
|
|
118
126
|
try {
|
|
119
127
|
let responseBody = serverResponse.body;
|
|
128
|
+
if (!responseBody) return;
|
|
120
129
|
if (responseBody.mediaType === 'video') {
|
|
121
130
|
responseBody.ad = responseBody.vastUrl;
|
|
122
131
|
const videoContext = bidRequest.data.videoContext;
|
|
@@ -185,6 +194,21 @@ const interpretResponse = (serverResponse, bidRequest) => {
|
|
|
185
194
|
}
|
|
186
195
|
};
|
|
187
196
|
|
|
197
|
+
function getUserSyncs (syncOptions, responses, gdprConsent, uspConsent) {
|
|
198
|
+
if (syncOptions.iframeEnabled || syncOptions.pixelEnabled) {
|
|
199
|
+
const pixelType = syncOptions.pixelEnabled ? 'image' : 'iframe';
|
|
200
|
+
const urls = deepAccess(responses, '0.body.pixels') || COOKIE_SYNC_FALLBACK_URLS;
|
|
201
|
+
|
|
202
|
+
return [].concat(urls).map(url => ({
|
|
203
|
+
type: pixelType,
|
|
204
|
+
url: url
|
|
205
|
+
.replace('{{GDPR}}', gdprConsent ? gdprConsent.gdprApplies : '0')
|
|
206
|
+
.replace('{{GDPR_CONSENT}}', gdprConsent ? encodeURIComponent(gdprConsent.consentString) : '')
|
|
207
|
+
.replace('{{USP_CONSENT}}', uspConsent ? encodeURIComponent(uspConsent) : '')
|
|
208
|
+
}));
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
|
|
188
212
|
export const spec = {
|
|
189
213
|
code: BIDDER_CODE,
|
|
190
214
|
supportedMediaTypes: [BANNER, VIDEO],
|
|
@@ -192,84 +216,11 @@ export const spec = {
|
|
|
192
216
|
buildRequests,
|
|
193
217
|
interpretResponse,
|
|
194
218
|
gvlid: GVLID,
|
|
219
|
+
getUserSyncs,
|
|
195
220
|
};
|
|
196
221
|
|
|
197
222
|
registerBidder(spec);
|
|
198
223
|
|
|
199
|
-
let cookieSynced = false;
|
|
200
|
-
function cookieSync(bidderRequest) {
|
|
201
|
-
if (cookieSynced) return;
|
|
202
|
-
const xhr = new XMLHttpRequest();
|
|
203
|
-
xhr.open('GET', COOKIE_SYNC_JSON)
|
|
204
|
-
xhr.addEventListener('load', function () {
|
|
205
|
-
const macro = Macro({
|
|
206
|
-
gpdr: bidderRequest.gdprConsent ? bidderRequest.gdprConsent.gdprApplies : '0',
|
|
207
|
-
gpdr_consent: bidderRequest.gdprConsent ? bidderRequest.gdprConsent.consentString : '',
|
|
208
|
-
});
|
|
209
|
-
JSON.parse(this.responseText).filter(Boolean).forEach(url => {
|
|
210
|
-
firePixel(macro.replace(url))
|
|
211
|
-
})
|
|
212
|
-
})
|
|
213
|
-
xhr.send()
|
|
214
|
-
cookieSynced = true;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
function firePixel(url) {
|
|
218
|
-
const img = document.createElement('img');
|
|
219
|
-
img.width = 1;
|
|
220
|
-
img.height = 1;
|
|
221
|
-
img.src = url;
|
|
222
|
-
document.body.appendChild(img);
|
|
223
|
-
setTimeout(() => {
|
|
224
|
-
img.remove();
|
|
225
|
-
}, 10000)
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
function normalizeKey (x) {
|
|
229
|
-
return x.replace(/_/g, '').toLowerCase();
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function Macro (obj) {
|
|
233
|
-
const macros = {};
|
|
234
|
-
for (const key in obj) {
|
|
235
|
-
macros[normalizeKey(key)] = obj[key];
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
const set = (key, value) => {
|
|
239
|
-
macros[normalizeKey(key)] = typeof value === 'function' ? value : String(value);
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
return {
|
|
243
|
-
set,
|
|
244
|
-
setAll (obj) {
|
|
245
|
-
for (const key in obj) {
|
|
246
|
-
macros[normalizeKey(key)] = set(obj[key]);
|
|
247
|
-
}
|
|
248
|
-
},
|
|
249
|
-
replace (string, extraMacros = {}) {
|
|
250
|
-
const allMacros = {
|
|
251
|
-
...macros,
|
|
252
|
-
...extraMacros,
|
|
253
|
-
};
|
|
254
|
-
const regexes = [
|
|
255
|
-
/{{\s*([a-zA-Z0-9_]+)\s*}}/g,
|
|
256
|
-
/\$\$\s*([a-zA-Z0-9_]+)\s*\$\$/g,
|
|
257
|
-
/\[\s*([a-zA-Z0-9_]+)\s*\]/g,
|
|
258
|
-
/\{\s*([a-zA-Z0-9_]+)\s*\}/g,
|
|
259
|
-
];
|
|
260
|
-
regexes.forEach(regex => {
|
|
261
|
-
string = string.replace(regex, (str, x) => {
|
|
262
|
-
x = normalizeKey(x);
|
|
263
|
-
let value = allMacros[x];
|
|
264
|
-
value = typeof value === 'function' ? value(allMacros) : value;
|
|
265
|
-
return !value && value !== 0 ? '' : value;
|
|
266
|
-
});
|
|
267
|
-
});
|
|
268
|
-
return string;
|
|
269
|
-
},
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
|
|
273
224
|
function getDomainWithoutSubdomain (hostname) {
|
|
274
225
|
const parts = hostname.split('.');
|
|
275
226
|
const newParts = [];
|