prebid.js 5.17.0 → 6.0.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.
Files changed (145) hide show
  1. package/.babelrc.js +3 -6
  2. package/README.md +3 -1
  3. package/browsers.json +1 -8
  4. package/integrationExamples/gpt/akamaidap_segments_example.html +132 -0
  5. package/modules/.submodules.json +1 -0
  6. package/modules/adfBidAdapter.js +21 -16
  7. package/modules/adgenerationBidAdapter.js +28 -4
  8. package/modules/adkernelBidAdapter.js +2 -1
  9. package/modules/admixerBidAdapter.js +11 -0
  10. package/modules/adtelligentBidAdapter.js +2 -1
  11. package/modules/airgridRtdProvider.js +1 -1
  12. package/modules/akamaiDapRtdProvider.js +474 -0
  13. package/modules/akamaiDapRtdProvider.md +47 -0
  14. package/modules/aolBidAdapter.js +2 -1
  15. package/modules/appnexusBidAdapter.js +5 -3
  16. package/modules/atsAnalyticsAdapter.js +67 -46
  17. package/modules/atsAnalyticsAdapter.md +1 -0
  18. package/modules/betweenBidAdapter.js +20 -3
  19. package/modules/bliinkBidAdapter.js +58 -32
  20. package/modules/bliinkBidAdapter.md +29 -6
  21. package/modules/browsiRtdProvider.js +106 -18
  22. package/modules/cleanioRtdProvider.js +192 -0
  23. package/modules/cleanioRtdProvider.md +59 -0
  24. package/modules/codefuelBidAdapter.js +183 -0
  25. package/modules/codefuelBidAdapter.md +111 -0
  26. package/modules/connectIdSystem.js +104 -0
  27. package/modules/connectIdSystem.md +33 -0
  28. package/modules/cwireBidAdapter.js +272 -0
  29. package/modules/cwireBidAdapter.md +43 -0
  30. package/modules/deepintentBidAdapter.js +106 -9
  31. package/modules/deepintentBidAdapter.md +36 -1
  32. package/modules/deltaprojectsBidAdapter.js +252 -0
  33. package/modules/deltaprojectsBidAdapter.md +32 -0
  34. package/modules/dgkeywordRtdProvider.js +0 -1
  35. package/modules/engageyaBidAdapter.js +157 -0
  36. package/modules/gridBidAdapter.js +1 -0
  37. package/modules/gumgumBidAdapter.js +8 -0
  38. package/modules/inskinBidAdapter.js +7 -3
  39. package/modules/ixBidAdapter.js +8 -1
  40. package/modules/jixieBidAdapter.js +8 -2
  41. package/modules/justpremiumBidAdapter.js +6 -1
  42. package/modules/limelightDigitalBidAdapter.js +22 -2
  43. package/modules/livewrappedAnalyticsAdapter.js +53 -3
  44. package/modules/mediakeysBidAdapter.js +2 -1
  45. package/modules/multibid/index.js +3 -3
  46. package/modules/nativoBidAdapter.js +6 -2
  47. package/modules/nextMillenniumBidAdapter.js +12 -3
  48. package/modules/oguryBidAdapter.js +36 -7
  49. package/modules/openxBidAdapter.js +34 -22
  50. package/modules/operaadsBidAdapter.js +21 -1
  51. package/modules/otmBidAdapter.js +146 -0
  52. package/modules/otmBidAdapter.md +27 -26
  53. package/modules/outbrainBidAdapter.js +5 -0
  54. package/modules/pixfutureBidAdapter.js +24 -4
  55. package/modules/pixfutureBidAdapter.md +127 -0
  56. package/modules/playwireBidAdapter.md +61 -0
  57. package/modules/prebidServerBidAdapter/index.js +1 -1
  58. package/modules/proxistoreBidAdapter.js +4 -6
  59. package/modules/publinkIdSystem.js +11 -6
  60. package/modules/pubmaticBidAdapter.js +9 -0
  61. package/modules/pubmaticBidAdapter.md +1 -1
  62. package/modules/rtdModule/index.js +2 -2
  63. package/modules/sonobiBidAdapter.js +7 -0
  64. package/modules/sortableBidAdapter.js +1 -0
  65. package/modules/talkadsBidAdapter.js +129 -0
  66. package/modules/talkadsBidAdapter.md +60 -0
  67. package/modules/teadsBidAdapter.js +3 -0
  68. package/modules/tripleliftBidAdapter.js +22 -5
  69. package/modules/trustxBidAdapter.js +8 -6
  70. package/modules/undertoneBidAdapter.js +9 -5
  71. package/modules/undertoneBidAdapter.md +5 -1
  72. package/modules/unicornBidAdapter.js +3 -3
  73. package/modules/userId/eids.js +18 -0
  74. package/modules/userId/eids.md +7 -0
  75. package/modules/userId/userId.md +12 -0
  76. package/modules/ventesBidAdapter.js +370 -0
  77. package/modules/ventesBidAdapter.md +94 -0
  78. package/modules/videobyteBidAdapter.js +13 -6
  79. package/modules/videobyteBidAdapter.md +49 -0
  80. package/modules/visxBidAdapter.js +15 -22
  81. package/modules/yahoosspBidAdapter.js +637 -0
  82. package/modules/yahoosspBidAdapter.md +795 -0
  83. package/modules/yieldlabBidAdapter.js +48 -3
  84. package/modules/yieldlabBidAdapter.md +16 -1
  85. package/modules/yieldmoSyntheticInventoryModule.js +46 -0
  86. package/modules/yieldmoSyntheticInventoryModule.md +68 -0
  87. package/package.json +1 -1
  88. package/src/adapterManager.js +5 -0
  89. package/src/adapters/bidderFactory.js +4 -3
  90. package/src/auction.js +11 -11
  91. package/src/constants.json +1 -0
  92. package/src/secureCreatives.js +6 -7
  93. package/src/targeting.js +11 -9
  94. package/test/spec/modules/adfBidAdapter_spec.js +83 -29
  95. package/test/spec/modules/adgenerationBidAdapter_spec.js +121 -50
  96. package/test/spec/modules/adtelligentBidAdapter_spec.js +1 -0
  97. package/test/spec/modules/akamaiDapRtdProvider_spec.js +246 -0
  98. package/test/spec/modules/appnexusBidAdapter_spec.js +2 -1
  99. package/test/spec/modules/atsAnalyticsAdapter_spec.js +42 -9
  100. package/test/spec/modules/betweenBidAdapter_spec.js +41 -0
  101. package/test/spec/modules/bliinkBidAdapter_spec.js +87 -36
  102. package/test/spec/modules/browsiRtdProvider_spec.js +62 -7
  103. package/test/spec/modules/cleanioRtdProvider_spec.js +188 -0
  104. package/test/spec/modules/codefuelBidAdapter_spec.js +316 -0
  105. package/test/spec/modules/connectIdSystem_spec.js +189 -0
  106. package/test/spec/modules/cwireBidAdapter_spec.js +246 -0
  107. package/test/spec/modules/deepintentBidAdapter_spec.js +153 -3
  108. package/test/spec/modules/deltaprojectsBidAdapter_spec.js +399 -0
  109. package/test/spec/modules/engageyaBidAdapter_spec.js +286 -0
  110. package/test/spec/modules/gumgumBidAdapter_spec.js +5 -1
  111. package/test/spec/modules/ixBidAdapter_spec.js +13 -3
  112. package/test/spec/modules/jixieBidAdapter_spec.js +13 -11
  113. package/test/spec/modules/justpremiumBidAdapter_spec.js +9 -2
  114. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +155 -1
  115. package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +67 -12
  116. package/test/spec/modules/multibid_spec.js +31 -31
  117. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +13 -1
  118. package/test/spec/modules/oguryBidAdapter_spec.js +125 -37
  119. package/test/spec/modules/openxBidAdapter_spec.js +85 -13
  120. package/test/spec/modules/operaadsBidAdapter_spec.js +38 -6
  121. package/test/spec/modules/otmBidAdapter_spec.js +67 -0
  122. package/test/spec/modules/outbrainBidAdapter_spec.js +18 -0
  123. package/test/spec/modules/publinkIdSystem_spec.js +6 -6
  124. package/test/spec/modules/pubmaticBidAdapter_spec.js +39 -1
  125. package/test/spec/modules/sonobiBidAdapter_spec.js +34 -1
  126. package/test/spec/modules/sortableBidAdapter_spec.js +11 -0
  127. package/test/spec/modules/talkadsBidAdapter_spec.js +231 -0
  128. package/test/spec/modules/teadsBidAdapter_spec.js +132 -0
  129. package/test/spec/modules/tripleliftBidAdapter_spec.js +128 -0
  130. package/test/spec/modules/trustxBidAdapter_spec.js +3 -3
  131. package/test/spec/modules/undertoneBidAdapter_spec.js +52 -0
  132. package/test/spec/modules/unicornBidAdapter_spec.js +4 -4
  133. package/test/spec/modules/ventesBidAdapter_spec.js +845 -0
  134. package/test/spec/modules/videobyteBidAdapter_spec.js +2 -2
  135. package/test/spec/modules/visxBidAdapter_spec.js +48 -4
  136. package/test/spec/modules/yahoosspBidAdapter_spec.js +1332 -0
  137. package/test/spec/modules/yieldlabBidAdapter_spec.js +65 -1
  138. package/test/spec/modules/yieldmoSyntheticInventoryModule_spec.js +89 -0
  139. package/test/spec/unit/core/adapterManager_spec.js +32 -0
  140. package/test/spec/unit/core/bidderFactory_spec.js +61 -1
  141. package/test/spec/unit/pbjs_api_spec.js +37 -2
  142. package/test/spec/unit/secureCreatives_spec.js +54 -25
  143. package/wdio.conf.js +1 -1
  144. package/modules/turktelekomBidAdapter.md +0 -49
  145. package/yarn.lock +0 -13122
@@ -429,9 +429,10 @@ function addSegments(name, segName, segments, data, bidConfigName) {
429
429
  if (segments && segments.length) {
430
430
  data.push({
431
431
  name: name,
432
- segment: segments.map((seg) => {
433
- return {name: segName, value: seg};
434
- })
432
+ segment: segments
433
+ .map((seg) => seg && (seg.id || seg))
434
+ .filter((seg) => seg && (typeof seg === 'string' || typeof seg === 'number'))
435
+ .map((seg) => ({ name: segName, value: seg.toString() }))
435
436
  });
436
437
  } else if (bidConfigName) {
437
438
  const configData = config.getConfig('ortb2.user.data');
@@ -445,9 +446,10 @@ function addSegments(name, segName, segments, data, bidConfigName) {
445
446
  if (segData && segData.length) {
446
447
  data.push({
447
448
  name: name,
448
- segment: segData.map((seg) => {
449
- return {name: segName, value: seg};
450
- })
449
+ segment: segData
450
+ .map((seg) => seg && (seg.id || seg))
451
+ .filter((seg) => seg && (typeof seg === 'string' || typeof seg === 'number'))
452
+ .map((seg) => ({ name: segName, value: seg.toString() }))
451
453
  });
452
454
  }
453
455
  }
@@ -85,13 +85,17 @@ export const spec = {
85
85
  const vw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
86
86
  const vh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
87
87
  const pageSizeArray = vw == 0 || vh == 0 ? null : [vw, vh];
88
+ const commons = {
89
+ 'adapterVersion': '$prebid.version$',
90
+ 'uids': validBidRequests[0].userId,
91
+ 'pageSize': pageSizeArray
92
+ };
93
+ if (validBidRequests[0].schain) {
94
+ commons.schain = validBidRequests[0].schain;
95
+ }
88
96
  const payload = {
89
97
  'x-ut-hb-params': [],
90
- 'commons': {
91
- 'adapterVersion': '$prebid.version$',
92
- 'uids': validBidRequests[0].userId,
93
- 'pageSize': pageSizeArray
94
- }
98
+ 'commons': commons
95
99
  };
96
100
  const referer = bidderRequest.refererInfo.referer;
97
101
  const hostname = parseUrl(referer).hostname;
@@ -1,9 +1,13 @@
1
1
  # Overview
2
2
 
3
3
  ```
4
- Module Name: Example Bidder Adapter
4
+ Module Name: Undertone Bidder Adapter
5
5
  Module Type: Bidder Adapter
6
6
  Maintainer: RampProgrammatic@perion.com
7
+ gdpr_supported: true
8
+ usp_supported: true
9
+ schain_supported: true
10
+ media_types: video, native
7
11
  ```
8
12
  # Description
9
13
 
@@ -8,7 +8,7 @@ const BIDDER_CODE = 'unicorn';
8
8
  const UNICORN_ENDPOINT = 'https://ds.uncn.jp/pb/0/bid.json';
9
9
  const UNICORN_DEFAULT_CURRENCY = 'JPY';
10
10
  const UNICORN_PB_COOKIE_KEY = '__pb_unicorn_aud';
11
- const UNICORN_PB_VERSION = '1.0';
11
+ const UNICORN_PB_VERSION = '1.1';
12
12
 
13
13
  /**
14
14
  * Placement ID and Account ID are required.
@@ -58,11 +58,11 @@ function buildOpenRtbBidRequestPayload(validBidRequests, bidderRequest) {
58
58
  id: bidderRequest.auctionId,
59
59
  at: 1,
60
60
  imp,
61
- cur: UNICORN_DEFAULT_CURRENCY,
61
+ cur: [UNICORN_DEFAULT_CURRENCY],
62
62
  site: {
63
63
  id: deepAccess(validBidRequests[0], 'params.mediaId') || '',
64
64
  publisher: {
65
- id: deepAccess(validBidRequests[0], 'params.publisherId') || 0
65
+ id: String(deepAccess(validBidRequests[0], 'params.publisherId') || 0)
66
66
  },
67
67
  domain: window.location.hostname,
68
68
  page: window.location.href,
@@ -181,15 +181,18 @@ const USER_IDS_CONFIG = {
181
181
  source: 'neustar.biz',
182
182
  atype: 1
183
183
  },
184
+
184
185
  // MediaWallah OpenLink
185
186
  'mwOpenLinkId': {
186
187
  source: 'mediawallahscript.com',
187
188
  atype: 1
188
189
  },
190
+
189
191
  'tapadId': {
190
192
  source: 'tapad.com',
191
193
  atype: 1
192
194
  },
195
+
193
196
  // Novatiq Snowflake
194
197
  'novatiq': {
195
198
  getValue: function(data) {
@@ -198,6 +201,7 @@ const USER_IDS_CONFIG = {
198
201
  source: 'novatiq.com',
199
202
  atype: 1
200
203
  },
204
+
201
205
  'uid2': {
202
206
  source: 'uidapi.com',
203
207
  atype: 3,
@@ -205,40 +209,54 @@ const USER_IDS_CONFIG = {
205
209
  return data.id;
206
210
  }
207
211
  },
212
+
208
213
  // Akamai Data Activation Platform (DAP)
209
214
  'dapId': {
210
215
  source: 'akamai.com',
211
216
  atype: 1
212
217
  },
218
+
213
219
  'deepintentId': {
214
220
  source: 'deepintent.com',
215
221
  atype: 3
216
222
  },
223
+
217
224
  // Admixer Id
218
225
  'admixerId': {
219
226
  source: 'admixer.net',
220
227
  atype: 3
221
228
  },
229
+
222
230
  // Adtelligent Id
223
231
  'adtelligentId': {
224
232
  source: 'adtelligent.com',
225
233
  atype: 3
226
234
  },
235
+
227
236
  amxId: {
228
237
  source: 'amxrtb.com',
229
238
  atype: 1,
230
239
  },
240
+
231
241
  'publinkId': {
232
242
  source: 'epsilon.com',
233
243
  atype: 3
234
244
  },
245
+
235
246
  'kpuid': {
236
247
  source: 'kpuid.com',
237
248
  atype: 3
238
249
  },
250
+
239
251
  'imuid': {
240
252
  source: 'intimatemerger.com',
241
253
  atype: 1
254
+ },
255
+
256
+ // Yahoo ConnectID
257
+ 'connectId': {
258
+ source: 'yahoo.com',
259
+ atype: 3
242
260
  }
243
261
  };
244
262
 
@@ -210,6 +210,13 @@ userIdAsEids = [
210
210
  id: 'some-random-id-value',
211
211
  atype: 3
212
212
  }]
213
+ },
214
+ {
215
+ source: 'yahoo.com',
216
+ uids: [{
217
+ id: 'some-random-id-value',
218
+ atype: 3
219
+ }]
213
220
  }
214
221
  ]
215
222
  ```
@@ -285,6 +285,18 @@ pbjs.setConfig({
285
285
  params: {
286
286
  cid: 5126 // Set your Intimate Merger Customer ID here for production
287
287
  }
288
+ },
289
+ {
290
+ name: 'connectId',
291
+ params: {
292
+ pixelId: 58776,
293
+ he: '0bef996248d63cea1529cb86de31e9547a712d9f380146e98bbd39beec70355a'
294
+ },
295
+ storage: {
296
+ name: 'connectId',
297
+ type: 'html5',
298
+ expires: 15
299
+ }
288
300
  }],
289
301
  syncDelay: 5000
290
302
  }
@@ -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
+ ]