prebid.js 6.22.0 → 6.23.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 (164) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/33acrossIdSystem.js +1 -0
  3. package/dist/adagioBidAdapter.js +1 -1
  4. package/dist/adbookpspBidAdapter.js +1 -1
  5. package/dist/adfBidAdapter.js +1 -1
  6. package/dist/adgenerationBidAdapter.js +1 -1
  7. package/dist/adrelevantisBidAdapter.js +1 -1
  8. package/dist/adxcgBidAdapter.js +1 -1
  9. package/dist/adyoulikeBidAdapter.js +1 -1
  10. package/dist/ajaBidAdapter.js +1 -1
  11. package/dist/amxBidAdapter.js +1 -1
  12. package/dist/amxIdSystem.js +1 -1
  13. package/dist/appierAnalyticsAdapter.js +1 -1
  14. package/dist/appnexusBidAdapter.js +1 -1
  15. package/dist/asealBidAdapter.js +1 -1
  16. package/dist/asoBidAdapter.js +1 -1
  17. package/dist/audiencerunBidAdapter.js +1 -1
  18. package/dist/automatadBidAdapter.js +1 -1
  19. package/dist/axonixBidAdapter.js +1 -1
  20. package/dist/bidglassBidAdapter.js +1 -1
  21. package/dist/big-richmediaBidAdapter.js +1 -1
  22. package/dist/bizzclickBidAdapter.js +1 -1
  23. package/dist/bluebillywigBidAdapter.js +1 -1
  24. package/dist/bridgewellBidAdapter.js +1 -1
  25. package/dist/brightMountainMediaBidAdapter.js +1 -1
  26. package/dist/concertBidAdapter.js +1 -1
  27. package/dist/connectadBidAdapter.js +1 -1
  28. package/dist/consumableBidAdapter.js +1 -1
  29. package/dist/conversantBidAdapter.js +1 -1
  30. package/dist/craftBidAdapter.js +1 -1
  31. package/dist/criteoBidAdapter.js +1 -1
  32. package/dist/dspxBidAdapter.js +1 -1
  33. package/dist/eplanningBidAdapter.js +1 -1
  34. package/dist/glimpseBidAdapter.js +1 -1
  35. package/dist/gmosspBidAdapter.js +1 -1
  36. package/dist/goldbachBidAdapter.js +1 -1
  37. package/dist/gridBidAdapter.js +1 -1
  38. package/dist/gridNMBidAdapter.js +1 -1
  39. package/dist/gumgumBidAdapter.js +1 -1
  40. package/dist/h12mediaBidAdapter.js +1 -1
  41. package/dist/id5IdSystem.js +1 -1
  42. package/dist/impactifyBidAdapter.js +1 -1
  43. package/dist/improvedigitalBidAdapter.js +1 -1
  44. package/dist/inmarBidAdapter.js +1 -1
  45. package/dist/insticatorBidAdapter.js +1 -1
  46. package/dist/ixBidAdapter.js +1 -1
  47. package/dist/jixieBidAdapter.js +1 -1
  48. package/dist/justpremiumBidAdapter.js +1 -1
  49. package/dist/jwplayerRtdProvider.js +1 -1
  50. package/dist/konduitAnalyticsAdapter.js +1 -1
  51. package/dist/livewrappedBidAdapter.js +1 -1
  52. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  53. package/dist/logicadBidAdapter.js +1 -1
  54. package/dist/loglyliftBidAdapter.js +1 -1
  55. package/dist/malltvAnalyticsAdapter.js +1 -1
  56. package/dist/marsmediaBidAdapter.js +1 -1
  57. package/dist/mediafuseBidAdapter.js +1 -1
  58. package/dist/mediakeysBidAdapter.js +1 -1
  59. package/dist/mediasquareBidAdapter.js +1 -1
  60. package/dist/mgidBidAdapter.js +1 -1
  61. package/dist/minutemediaBidAdapter.js +1 -1
  62. package/dist/not-for-prod/prebid.js +117 -116
  63. package/dist/oguryBidAdapter.js +1 -1
  64. package/dist/oneVideoBidAdapter.js +1 -1
  65. package/dist/onetagBidAdapter.js +1 -1
  66. package/dist/ooloAnalyticsAdapter.js +1 -1
  67. package/dist/outbrainBidAdapter.js +1 -1
  68. package/dist/parrableIdSystem.js +1 -1
  69. package/dist/pixfutureBidAdapter.js +1 -1
  70. package/dist/prebid-core.js +3 -3
  71. package/dist/prebidServerBidAdapter.js +1 -1
  72. package/dist/publinkIdSystem.js +1 -1
  73. package/dist/pubmaticBidAdapter.js +1 -1
  74. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  75. package/dist/pxyzBidAdapter.js +1 -1
  76. package/dist/quantcastBidAdapter.js +1 -1
  77. package/dist/readpeakBidAdapter.js +1 -1
  78. package/dist/relaidoBidAdapter.js +1 -1
  79. package/dist/rhythmoneBidAdapter.js +1 -1
  80. package/dist/riseBidAdapter.js +1 -1
  81. package/dist/rubiconAnalyticsAdapter.js +1 -1
  82. package/dist/rubiconBidAdapter.js +1 -1
  83. package/dist/seedingAllianceBidAdapter.js +1 -1
  84. package/dist/seedtagBidAdapter.js +1 -1
  85. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  86. package/dist/sharethroughBidAdapter.js +1 -1
  87. package/dist/smaatoBidAdapter.js +1 -1
  88. package/dist/smartadserverBidAdapter.js +1 -1
  89. package/dist/smartxBidAdapter.js +1 -1
  90. package/dist/smilewantedBidAdapter.js +1 -1
  91. package/dist/sonobiBidAdapter.js +1 -1
  92. package/dist/sortableBidAdapter.js +1 -1
  93. package/dist/sovrnAnalyticsAdapter.js +1 -1
  94. package/dist/sovrnBidAdapter.js +1 -1
  95. package/dist/sspBCBidAdapter.js +1 -1
  96. package/dist/sublimeBidAdapter.js +1 -1
  97. package/dist/synacormediaBidAdapter.js +1 -1
  98. package/dist/targetVideoBidAdapter.js +1 -1
  99. package/dist/teadsBidAdapter.js +1 -1
  100. package/dist/trionBidAdapter.js +1 -1
  101. package/dist/tripleliftBidAdapter.js +1 -1
  102. package/dist/trustxBidAdapter.js +1 -1
  103. package/dist/ttdBidAdapter.js +1 -1
  104. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  105. package/dist/underdogmediaBidAdapter.js +1 -1
  106. package/dist/undertoneBidAdapter.js +1 -1
  107. package/dist/userId.js +1 -1
  108. package/dist/vidazooBidAdapter.js +1 -1
  109. package/dist/videobyteBidAdapter.js +1 -1
  110. package/dist/visxBidAdapter.js +1 -1
  111. package/dist/vuukleBidAdapter.js +1 -1
  112. package/dist/widespaceBidAdapter.js +1 -1
  113. package/dist/winrBidAdapter.js +1 -1
  114. package/dist/yahoosspBidAdapter.js +1 -1
  115. package/dist/yieldmoBidAdapter.js +1 -1
  116. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  117. package/integrationExamples/gpt/userId_example.html +12 -0
  118. package/modules/.submodules.json +1 -0
  119. package/modules/33acrossIdSystem.js +115 -0
  120. package/modules/33acrossIdSystem.md +53 -0
  121. package/modules/adagioBidAdapter.js +45 -5
  122. package/modules/adfBidAdapter.js +5 -0
  123. package/modules/adyoulikeBidAdapter.js +1 -9
  124. package/modules/asealBidAdapter.js +62 -14
  125. package/modules/automatadBidAdapter.js +24 -11
  126. package/modules/automatadBidAdapter.md +2 -2
  127. package/modules/big-richmediaBidAdapter.js +9 -1
  128. package/modules/bizzclickBidAdapter.js +5 -14
  129. package/modules/criteoBidAdapter.js +20 -20
  130. package/modules/improvedigitalBidAdapter.js +10 -6
  131. package/modules/insticatorBidAdapter.js +14 -4
  132. package/modules/jixieBidAdapter.js +29 -0
  133. package/modules/jixieBidAdapter.md +1 -0
  134. package/modules/jwplayerRtdProvider.js +27 -9
  135. package/modules/jwplayerRtdProvider.md +5 -3
  136. package/modules/livewrappedBidAdapter.js +1 -1
  137. package/modules/minutemediaBidAdapter.js +206 -135
  138. package/modules/minutemediaBidAdapter.md +42 -17
  139. package/modules/prebidServerBidAdapter/index.js +4 -1
  140. package/modules/sovrnBidAdapter.js +16 -3
  141. package/modules/tripleliftBidAdapter.js +13 -9
  142. package/modules/userId/eids.js +9 -0
  143. package/modules/userId/eids.md +7 -0
  144. package/modules/userId/index.js +5 -2
  145. package/modules/userId/userId.md +23 -2
  146. package/package.json +1 -1
  147. package/test/spec/modules/33acrossIdSystem_spec.js +413 -0
  148. package/test/spec/modules/adagioBidAdapter_spec.js +11 -2
  149. package/test/spec/modules/adfBidAdapter_spec.js +27 -0
  150. package/test/spec/modules/asealBidAdapter_spec.js +134 -65
  151. package/test/spec/modules/automatadBidAdapter_spec.js +28 -11
  152. package/test/spec/modules/criteoBidAdapter_spec.js +33 -33
  153. package/test/spec/modules/eids_spec.js +17 -0
  154. package/test/spec/modules/improvedigitalBidAdapter_spec.js +27 -5
  155. package/test/spec/modules/insticatorBidAdapter_spec.js +24 -15
  156. package/test/spec/modules/jixieBidAdapter_spec.js +96 -0
  157. package/test/spec/modules/jwplayerRtdProvider_spec.js +50 -14
  158. package/test/spec/modules/livewrappedBidAdapter_spec.js +3 -1
  159. package/test/spec/modules/minutemediaBidAdapter_spec.js +196 -122
  160. package/test/spec/modules/prebidServerBidAdapter_spec.js +4 -0
  161. package/test/spec/modules/sovrnBidAdapter_spec.js +12 -0
  162. package/test/spec/modules/tripleliftBidAdapter_spec.js +12 -2
  163. package/test/spec/modules/userId_spec.js +8 -0
  164. package/modules/pubnxBidAdapter.md +0 -31
@@ -95,9 +95,10 @@ Example:
95
95
  content: {
96
96
  id: 'jw_abc123',
97
97
  data: [{
98
- name: 'jwplayer',
98
+ name: 'jwplayer.com',
99
99
  ext: {
100
- segtax: 502
100
+ segtax: 502,
101
+ cids: ['abc123']
101
102
  },
102
103
  segment: [{
103
104
  id: '123'
@@ -117,8 +118,9 @@ where:
117
118
  - `content` is an object containing metadata for the media. It may contain the following information:
118
119
  - `id` is a unique identifier for the specific media asset
119
120
  - `data` is an array containing segment taxonomy objects that have the following parameters:
120
- - `name` is the `jwplayer` string indicating the provider name
121
+ - `name` is the `jwplayer.com` string indicating the provider name
121
122
  - `ext.segtax` whose `502` value is the unique identifier for JW Player's proprietary taxonomy
123
+ - `ext.cids` is an array containing the list of extended content ids as defined in [oRTB's community extensions](https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/extensions/community_extensions/extended-content-ids.md#example---content-id-and-seller-defined-context).
122
124
  - `segment` is an array containing the segment taxonomy values as an object where:
123
125
  - `id` is the string representation of the data segment value.
124
126
 
@@ -67,7 +67,7 @@ export const spec = {
67
67
  var adRequests = bidRequests.map(bidToAdRequest);
68
68
 
69
69
  if (eids) {
70
- ortb2 = mergeDeep(ortb2 || {}, eids);
70
+ ortb2 = mergeDeep(mergeDeep({}, ortb2 || {}), eids);
71
71
  }
72
72
 
73
73
  const payload = {
@@ -1,17 +1,17 @@
1
- import { logWarn, isArray, isFn, deepAccess, isEmpty, contains, timestamp, getBidIdParameter } from '../src/utils.js';
1
+ import { logWarn, logInfo, isArray, isFn, deepAccess, isEmpty, contains, timestamp, getBidIdParameter, triggerPixel, isInteger } from '../src/utils.js';
2
2
  import {registerBidder} from '../src/adapters/bidderFactory.js';
3
- import {VIDEO} from '../src/mediaTypes.js';
3
+ import {BANNER, VIDEO} from '../src/mediaTypes.js';
4
4
  import {config} from '../src/config.js';
5
5
 
6
- const SUPPORTED_AD_TYPES = [VIDEO];
6
+ const SUPPORTED_AD_TYPES = [BANNER, VIDEO];
7
7
  const BIDDER_CODE = 'minutemedia';
8
- const ADAPTER_VERSION = '5.0.1';
8
+ const ADAPTER_VERSION = '6.0.0';
9
9
  const TTL = 360;
10
10
  const CURRENCY = 'USD';
11
11
  const SELLER_ENDPOINT = 'https://hb.minutemedia-prebid.com/';
12
12
  const MODES = {
13
- PRODUCTION: 'hb-mm',
14
- TEST: 'hb-mm-test'
13
+ PRODUCTION: 'hb-mm-multi',
14
+ TEST: 'hb-multi-mm-test'
15
15
  }
16
16
  const SUPPORTED_SYNC_METHODS = {
17
17
  IFRAME: 'iframe',
@@ -23,7 +23,7 @@ export const spec = {
23
23
  gvlid: 918,
24
24
  version: ADAPTER_VERSION,
25
25
  supportedMediaTypes: SUPPORTED_AD_TYPES,
26
- isBidRequestValid: function(bidRequest) {
26
+ isBidRequestValid: function (bidRequest) {
27
27
  if (!bidRequest.params) {
28
28
  logWarn('no params have been set to MinuteMedia adapter');
29
29
  return false;
@@ -36,54 +36,70 @@ export const spec = {
36
36
 
37
37
  return true;
38
38
  },
39
- buildRequests: function (bidRequests, bidderRequest) {
40
- if (bidRequests.length === 0) {
41
- return [];
42
- }
39
+ buildRequests: function (validBidRequests, bidderRequest) {
40
+ const combinedRequestsObject = {};
43
41
 
44
- const requests = [];
42
+ // use data from the first bid, to create the general params for all bids
43
+ const generalObject = validBidRequests[0];
44
+ const testMode = generalObject.params.testMode;
45
45
 
46
- bidRequests.forEach(bid => {
47
- requests.push(buildVideoRequest(bid, bidderRequest));
48
- });
46
+ combinedRequestsObject.params = generateGeneralParams(generalObject, bidderRequest);
47
+ combinedRequestsObject.bids = generateBidsParams(validBidRequests, bidderRequest);
49
48
 
50
- return requests;
49
+ return {
50
+ method: 'POST',
51
+ url: getEndpoint(testMode),
52
+ data: combinedRequestsObject
53
+ }
51
54
  },
52
- interpretResponse: function({body}) {
55
+ interpretResponse: function ({body}) {
53
56
  const bidResponses = [];
54
57
 
55
- const bidResponse = {
56
- requestId: body.requestId,
57
- cpm: body.cpm,
58
- width: body.width,
59
- height: body.height,
60
- creativeId: body.requestId,
61
- currency: body.currency,
62
- netRevenue: body.netRevenue,
63
- ttl: body.ttl || TTL,
64
- vastXml: body.vastXml,
65
- mediaType: VIDEO
66
- };
67
-
68
- if (body.adomain && body.adomain.length) {
69
- bidResponse.meta = {};
70
- bidResponse.meta.advertiserDomains = body.adomain
58
+ if (body.bids) {
59
+ body.bids.forEach(adUnit => {
60
+ const bidResponse = {
61
+ requestId: adUnit.requestId,
62
+ cpm: adUnit.cpm,
63
+ currency: adUnit.currency || CURRENCY,
64
+ width: adUnit.width,
65
+ height: adUnit.height,
66
+ ttl: adUnit.ttl || TTL,
67
+ creativeId: adUnit.requestId,
68
+ netRevenue: adUnit.netRevenue || true,
69
+ nurl: adUnit.nurl,
70
+ mediaType: adUnit.mediaType,
71
+ meta: {
72
+ mediaType: adUnit.mediaType
73
+ }
74
+ };
75
+
76
+ if (adUnit.mediaType === VIDEO) {
77
+ bidResponse.vastXml = adUnit.vastXml;
78
+ } else if (adUnit.mediaType === BANNER) {
79
+ bidResponse.ad = adUnit.ad;
80
+ }
81
+
82
+ if (adUnit.adomain && adUnit.adomain.length) {
83
+ bidResponse.meta.advertiserDomains = adUnit.adomain;
84
+ }
85
+
86
+ bidResponses.push(bidResponse);
87
+ });
71
88
  }
72
- bidResponses.push(bidResponse);
73
89
 
74
90
  return bidResponses;
75
91
  },
76
- getUserSyncs: function(syncOptions, serverResponses) {
92
+ getUserSyncs: function (syncOptions, serverResponses) {
77
93
  const syncs = [];
78
94
  for (const response of serverResponses) {
79
- if (syncOptions.iframeEnabled && response.body.userSyncURL) {
95
+ if (syncOptions.iframeEnabled && response.body.params.userSyncURL) {
80
96
  syncs.push({
81
97
  type: 'iframe',
82
- url: response.body.userSyncURL
98
+ url: response.body.params.userSyncURL
83
99
  });
84
100
  }
85
- if (syncOptions.pixelEnabled && isArray(response.body.userSyncPixels)) {
86
- const pixels = response.body.userSyncPixels.map(pixel => {
101
+ if (syncOptions.pixelEnabled && isArray(response.body.params.userSyncPixels)) {
102
+ const pixels = response.body.params.userSyncPixels.map(pixel => {
87
103
  return {
88
104
  type: 'image',
89
105
  url: pixel
@@ -93,6 +109,16 @@ export const spec = {
93
109
  }
94
110
  }
95
111
  return syncs;
112
+ },
113
+ onBidWon: function (bid) {
114
+ if (bid == null) {
115
+ return;
116
+ }
117
+
118
+ logInfo('onBidWon:', bid);
119
+ if (bid.hasOwnProperty('nurl') && bid.nurl.length > 0) {
120
+ triggerPixel(bid.nurl);
121
+ }
96
122
  }
97
123
  };
98
124
 
@@ -103,46 +129,33 @@ registerBidder(spec);
103
129
  * @param bid {bid}
104
130
  * @returns {Number}
105
131
  */
106
- function getFloor(bid) {
132
+ function getFloor(bid, mediaType) {
107
133
  if (!isFn(bid.getFloor)) {
108
134
  return 0;
109
135
  }
110
136
  let floorResult = bid.getFloor({
111
137
  currency: CURRENCY,
112
- mediaType: VIDEO,
138
+ mediaType: mediaType,
113
139
  size: '*'
114
140
  });
115
141
  return floorResult.currency === CURRENCY && floorResult.floor ? floorResult.floor : 0;
116
142
  }
117
143
 
118
144
  /**
119
- * Build the video request
120
- * @param bid {bid}
121
- * @param bidderRequest {bidderRequest}
122
- * @returns {Object}
123
- */
124
- function buildVideoRequest(bid, bidderRequest) {
125
- const sellerParams = generateParameters(bid, bidderRequest);
126
- const {params} = bid;
127
- return {
128
- method: 'GET',
129
- url: getEndpoint(params.testMode),
130
- data: sellerParams
131
- };
132
- }
133
-
134
- /**
135
- * Get the the ad size from the bid
145
+ * Get the the ad sizes array from the bid
136
146
  * @param bid {bid}
137
147
  * @returns {Array}
138
148
  */
139
- function getSizes(bid) {
140
- if (deepAccess(bid, 'mediaTypes.video.sizes')) {
141
- return bid.mediaTypes.video.sizes[0];
149
+ function getSizesArray(bid, mediaType) {
150
+ let sizesArray = []
151
+
152
+ if (deepAccess(bid, `mediaTypes.${mediaType}.sizes`)) {
153
+ sizesArray = bid.mediaTypes[mediaType].sizes;
142
154
  } else if (Array.isArray(bid.sizes) && bid.sizes.length > 0) {
143
- return bid.sizes[0];
155
+ sizesArray = bid.sizes;
144
156
  }
145
- return [];
157
+
158
+ return sizesArray;
146
159
  }
147
160
 
148
161
  /**
@@ -239,122 +252,180 @@ function getDeviceType(ua) {
239
252
  return '1';
240
253
  }
241
254
 
255
+ function generateBidsParams(validBidRequests, bidderRequest) {
256
+ const bidsArray = [];
257
+
258
+ if (validBidRequests.length) {
259
+ validBidRequests.forEach(bid => {
260
+ bidsArray.push(generateBidParameters(bid, bidderRequest));
261
+ });
262
+ }
263
+
264
+ return bidsArray;
265
+ }
266
+
242
267
  /**
243
- * Generate query parameters for the request
244
- * @param bid {bid}
245
- * @param bidderRequest {bidderRequest}
246
- * @returns {Object}
268
+ * Generate bid specific parameters
269
+ * @param {bid} bid
270
+ * @param {bidderRequest} bidderRequest
271
+ * @returns {Object} bid specific params object
247
272
  */
248
- function generateParameters(bid, bidderRequest) {
273
+ function generateBidParameters(bid, bidderRequest) {
249
274
  const {params} = bid;
250
- const timeout = config.getConfig('bidderTimeout');
251
- const {syncEnabled, filterSettings} = config.getConfig('userSync') || {};
252
- const [width, height] = getSizes(bid);
253
- const {bidderCode} = bidderRequest;
254
- const domain = window.location.hostname;
275
+ const mediaType = isBanner(bid) ? BANNER : VIDEO;
276
+ const sizesArray = getSizesArray(bid, mediaType);
255
277
 
256
278
  // fix floor price in case of NAN
257
279
  if (isNaN(params.floorPrice)) {
258
280
  params.floorPrice = 0;
259
281
  }
260
282
 
261
- const requestParams = {
283
+ const bidObject = {
284
+ mediaType,
285
+ adUnitCode: getBidIdParameter('adUnitCode', bid),
286
+ sizes: sizesArray,
287
+ floorPrice: Math.max(getFloor(bid, mediaType), params.floorPrice),
288
+ bidId: getBidIdParameter('bidId', bid),
289
+ bidderRequestId: getBidIdParameter('bidderRequestId', bid),
290
+ transactionId: getBidIdParameter('transactionId', bid),
291
+ };
292
+
293
+ const pos = deepAccess(bid, `mediaTypes.${mediaType}.pos`);
294
+ if (pos) {
295
+ bidObject.pos = pos;
296
+ }
297
+
298
+ const gpid = deepAccess(bid, `ortb2Imp.ext.gpid`);
299
+ if (gpid) {
300
+ bidObject.gpid = gpid;
301
+ }
302
+
303
+ const placementId = params.placementId || deepAccess(bid, `mediaTypes.${mediaType}.name`);
304
+ if (placementId) {
305
+ bidObject.placementId = placementId;
306
+ }
307
+
308
+ if (mediaType === VIDEO) {
309
+ const playbackMethod = deepAccess(bid, `mediaTypes.video.playbackmethod`);
310
+ let playbackMethodValue;
311
+
312
+ // verify playbackMethod is of type integer array, or integer only.
313
+ if (Array.isArray(playbackMethod) && isInteger(playbackMethod[0])) {
314
+ // only the first playbackMethod in the array will be used, according to OpenRTB 2.5 recommendation
315
+ playbackMethodValue = playbackMethod[0];
316
+ } else if (isInteger(playbackMethod)) {
317
+ playbackMethodValue = playbackMethod;
318
+ }
319
+
320
+ if (playbackMethodValue) {
321
+ bidObject.playbackMethod = playbackMethodValue;
322
+ }
323
+
324
+ const placement = deepAccess(bid, `mediaTypes.video.placement`);
325
+ if (placement) {
326
+ bidObject.placement = placement;
327
+ }
328
+
329
+ const minDuration = deepAccess(bid, `mediaTypes.video.minduration`);
330
+ if (minDuration) {
331
+ bidObject.minDuration = minDuration;
332
+ }
333
+
334
+ const maxDuration = deepAccess(bid, `mediaTypes.video.maxduration`);
335
+ if (maxDuration) {
336
+ bidObject.maxDuration = maxDuration;
337
+ }
338
+
339
+ const skip = deepAccess(bid, `mediaTypes.video.skip`);
340
+ if (skip) {
341
+ bidObject.skip = skip;
342
+ }
343
+
344
+ const linearity = deepAccess(bid, `mediaTypes.video.linearity`);
345
+ if (linearity) {
346
+ bidObject.linearity = linearity;
347
+ }
348
+ }
349
+
350
+ return bidObject;
351
+ }
352
+
353
+ function isBanner(bid) {
354
+ return bid.mediaTypes && bid.mediaTypes.banner;
355
+ }
356
+
357
+ /**
358
+ * Generate params that are common between all bids
359
+ * @param {single bid object} generalObject
360
+ * @param {bidderRequest} bidderRequest
361
+ * @returns {object} the common params object
362
+ */
363
+ function generateGeneralParams(generalObject, bidderRequest) {
364
+ const domain = window.location.hostname;
365
+ const {syncEnabled, filterSettings} = config.getConfig('userSync') || {};
366
+ const {bidderCode} = bidderRequest;
367
+ const generalBidParams = generalObject.params;
368
+ const timeout = config.getConfig('bidderTimeout');
369
+
370
+ // these params are snake_case instead of camelCase to allow backwards compatability on the server.
371
+ // in the future, these will be converted to camelCase to match our convention.
372
+ const generalParams = {
262
373
  wrapper_type: 'prebidjs',
263
374
  wrapper_vendor: '$$PREBID_GLOBAL$$',
264
375
  wrapper_version: '$prebid.version$',
265
376
  adapter_version: ADAPTER_VERSION,
266
377
  auction_start: timestamp(),
267
- ad_unit_code: getBidIdParameter('adUnitCode', bid),
268
- tmax: timeout,
269
- width: width,
270
- height: height,
271
- publisher_id: params.org,
272
- floor_price: Math.max(getFloor(bid), params.floorPrice),
273
- ua: navigator.userAgent,
274
- bid_id: getBidIdParameter('bidId', bid),
275
- bidder_request_id: getBidIdParameter('bidderRequestId', bid),
276
- transaction_id: getBidIdParameter('transactionId', bid),
277
- session_id: getBidIdParameter('auctionId', bid),
378
+ publisher_id: generalBidParams.org,
278
379
  publisher_name: domain,
279
380
  site_domain: domain,
280
381
  dnt: (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0,
281
- device_type: getDeviceType(navigator.userAgent)
282
- };
382
+ device_type: getDeviceType(navigator.userAgent),
383
+ ua: navigator.userAgent,
384
+ session_id: getBidIdParameter('auctionId', generalObject),
385
+ tmax: timeout
386
+ }
283
387
 
284
- const userIdsParam = getBidIdParameter('userId', bid);
388
+ const userIdsParam = getBidIdParameter('userId', generalObject);
285
389
  if (userIdsParam) {
286
- requestParams.userIds = JSON.stringify(userIdsParam);
390
+ generalParams.userIds = JSON.stringify(userIdsParam);
287
391
  }
288
392
 
289
393
  const ortb2Metadata = config.getConfig('ortb2') || {};
290
394
  if (ortb2Metadata.site) {
291
- requestParams.site_metadata = JSON.stringify(ortb2Metadata.site);
395
+ generalParams.site_metadata = JSON.stringify(ortb2Metadata.site);
292
396
  }
293
397
  if (ortb2Metadata.user) {
294
- requestParams.user_metadata = JSON.stringify(ortb2Metadata.user);
295
- }
296
-
297
- const playbackMethod = deepAccess(bid, 'mediaTypes.video.playbackmethod');
298
- if (playbackMethod) {
299
- requestParams.playback_method = playbackMethod;
300
- }
301
- const placement = deepAccess(bid, 'mediaTypes.video.placement');
302
- if (placement) {
303
- requestParams.placement = placement;
304
- }
305
- const pos = deepAccess(bid, 'mediaTypes.video.pos');
306
- if (pos) {
307
- requestParams.pos = pos;
308
- }
309
- const minduration = deepAccess(bid, 'mediaTypes.video.minduration');
310
- if (minduration) {
311
- requestParams.min_duration = minduration;
312
- }
313
- const maxduration = deepAccess(bid, 'mediaTypes.video.maxduration');
314
- if (maxduration) {
315
- requestParams.max_duration = maxduration;
316
- }
317
- const skip = deepAccess(bid, 'mediaTypes.video.skip');
318
- if (skip) {
319
- requestParams.skip = skip;
320
- }
321
- const linearity = deepAccess(bid, 'mediaTypes.video.linearity');
322
- if (linearity) {
323
- requestParams.linearity = linearity;
324
- }
325
-
326
- if (params.placementId) {
327
- requestParams.placement_id = params.placementId;
398
+ generalParams.user_metadata = JSON.stringify(ortb2Metadata.user);
328
399
  }
329
400
 
330
401
  if (syncEnabled) {
331
402
  const allowedSyncMethod = getAllowedSyncMethod(filterSettings, bidderCode);
332
403
  if (allowedSyncMethod) {
333
- requestParams.cs_method = allowedSyncMethod;
404
+ generalParams.cs_method = allowedSyncMethod;
334
405
  }
335
406
  }
336
407
 
337
408
  if (bidderRequest.uspConsent) {
338
- requestParams.us_privacy = bidderRequest.uspConsent;
409
+ generalParams.us_privacy = bidderRequest.uspConsent;
339
410
  }
340
411
 
341
412
  if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) {
342
- requestParams.gdpr = bidderRequest.gdprConsent.gdprApplies;
343
- requestParams.gdpr_consent = bidderRequest.gdprConsent.consentString;
413
+ generalParams.gdpr = bidderRequest.gdprConsent.gdprApplies;
414
+ generalParams.gdpr_consent = bidderRequest.gdprConsent.consentString;
344
415
  }
345
416
 
346
- if (params.ifa) {
347
- requestParams.ifa = params.ifa;
417
+ if (generalBidParams.ifa) {
418
+ generalParams.ifa = generalBidParams.ifa;
348
419
  }
349
420
 
350
- if (bid.schain) {
351
- requestParams.schain = getSupplyChain(bid.schain);
421
+ if (generalObject.schain) {
422
+ generalParams.schain = getSupplyChain(generalObject.schain);
352
423
  }
353
424
 
354
425
  if (bidderRequest && bidderRequest.refererInfo) {
355
- requestParams.referrer = deepAccess(bidderRequest, 'refererInfo.referer');
356
- requestParams.page_url = config.getConfig('pageUrl') || deepAccess(window, 'location.href');
426
+ generalParams.referrer = deepAccess(bidderRequest, 'refererInfo.referer');
427
+ generalParams.page_url = config.getConfig('pageUrl') || deepAccess(window, 'location.href');
357
428
  }
358
429
 
359
- return requestParams;
430
+ return generalParams
360
431
  }
@@ -13,7 +13,7 @@ Module that connects to MinuteMedia's demand sources.
13
13
 
14
14
  The MinuteMedia adapter requires setup and approval from the MinuteMedia. Please reach out to hb@minutemedia.com to create an MinuteMedia account.
15
15
 
16
- The adapter supports Video(instream).
16
+ The adapter supports Video(instream) & Banner.
17
17
 
18
18
  # Bid Parameters
19
19
  ## Video
@@ -27,25 +27,50 @@ The adapter supports Video(instream).
27
27
 
28
28
  # Test Parameters
29
29
  ```javascript
30
- var adUnits = [
31
- {
30
+ var adUnits = [{
32
31
  code: 'dfp-video-div',
33
- sizes: [[640, 480]],
32
+ sizes: [
33
+ [640, 480]
34
+ ],
34
35
  mediaTypes: {
35
- video: {
36
- playerSize: [[640, 480]],
37
- context: 'instream'
38
- }
36
+ video: {
37
+ playerSize: [
38
+ [640, 480]
39
+ ],
40
+ context: 'instream'
41
+ }
39
42
  },
40
43
  bids: [{
41
- bidder: 'minutemedia',
42
- params: {
43
- org: '56f91cd4d3e3660002000033', // Required
44
- floorPrice: 2.00, // Optional
45
- placementId: '12345678', // Optional
46
- testMode: false // Optional
47
- }
44
+ bidder: 'minutemedia',
45
+ params: {
46
+ org: '56f91cd4d3e3660002000033', // Required
47
+ floorPrice: 2.00, // Optional
48
+ placementId: 'video-test', // Optional
49
+ testMode: false // Optional
50
+ }
48
51
  }]
49
- }
50
- ];
52
+ },
53
+ {
54
+ code: 'dfp-banner-div',
55
+ sizes: [
56
+ [640, 480]
57
+ ],
58
+ mediaTypes: {
59
+ banner: {
60
+ sizes: [
61
+ [640, 480]
62
+ ]
63
+ }
64
+ },
65
+ bids: [{
66
+ bidder: 'minutemedia',
67
+ params: {
68
+ org: '56f91cd4d3e3660002000033', // Required
69
+ floorPrice: 2.00, // Optional
70
+ placementId: 'banner-test', // Optional
71
+ testMode: false // Optional
72
+ }
73
+ }]
74
+ }
75
+ ];
51
76
  ```
@@ -563,13 +563,16 @@ Object.assign(ORTB2.prototype, {
563
563
  const nativeParams = adUnit.nativeParams;
564
564
  let nativeAssets;
565
565
  if (nativeParams) {
566
+ let idCounter = -1;
566
567
  try {
567
568
  nativeAssets = nativeAssetCache[impressionId] = Object.keys(nativeParams).reduce((assets, type) => {
568
569
  let params = nativeParams[type];
569
570
 
570
571
  function newAsset(obj) {
572
+ idCounter++;
571
573
  return Object.assign({
572
- required: params.required ? 1 : 0
574
+ required: params.required ? 1 : 0,
575
+ id: (isNumber(params.id)) ? idCounter = params.id : idCounter
573
576
  }, obj ? cleanObj(obj) : {});
574
577
  }
575
578
 
@@ -30,6 +30,14 @@ const ORTB_VIDEO_PARAMS = {
30
30
  'api': (value) => Array.isArray(value) && value.every(v => v >= 1 && v <= 6)
31
31
  }
32
32
 
33
+ const REQUIRED_VIDEO_PARAMS = {
34
+ context: (value) => value !== ADPOD,
35
+ mimes: ORTB_VIDEO_PARAMS.mimes,
36
+ minduration: ORTB_VIDEO_PARAMS.minduration,
37
+ maxduration: ORTB_VIDEO_PARAMS.maxduration,
38
+ protocols: ORTB_VIDEO_PARAMS.protocols
39
+ }
40
+
33
41
  export const spec = {
34
42
  code: 'sovrn',
35
43
  supportedMediaTypes: [BANNER, VIDEO],
@@ -40,12 +48,17 @@ export const spec = {
40
48
  * @param {object} bid the Sovrn bid to validate
41
49
  * @return boolean for whether or not a bid is valid
42
50
  */
43
- isBidRequestValid: function(bid) {
51
+ isBidRequestValid: function (bid) {
52
+ const video = bid?.mediaTypes?.video
44
53
  return !!(
45
54
  bid.params.tagid &&
46
55
  !isNaN(parseFloat(bid.params.tagid)) &&
47
- isFinite(bid.params.tagid) &&
48
- deepAccess(bid, 'mediaTypes.video.context') !== ADPOD
56
+ isFinite(bid.params.tagid) && (
57
+ !video || (
58
+ Object.keys(REQUIRED_VIDEO_PARAMS)
59
+ .every(key => REQUIRED_VIDEO_PARAMS[key](video[key]))
60
+ )
61
+ )
49
62
  )
50
63
  },
51
64
 
@@ -1,4 +1,4 @@
1
- import { tryAppendQueryString, logMessage, isEmpty, isStr, isPlainObject, isArray, logWarn } from '../src/utils.js';
1
+ import { tryAppendQueryString, logMessage, logError, isEmpty, isStr, isPlainObject, isArray, logWarn } from '../src/utils.js';
2
2
  import { BANNER, VIDEO } from '../src/mediaTypes.js';
3
3
  import { registerBidder } from '../src/adapters/bidderFactory.js';
4
4
  import { config } from '../src/config.js';
@@ -175,14 +175,18 @@ function _getORTBVideo(bidRequest) {
175
175
  function _getFloor (bid) {
176
176
  let floor = null;
177
177
  if (typeof bid.getFloor === 'function') {
178
- const floorInfo = bid.getFloor({
179
- currency: 'USD',
180
- mediaType: _isInstreamBidRequest(bid) ? 'video' : 'banner',
181
- size: '*'
182
- });
183
- if (typeof floorInfo === 'object' &&
184
- floorInfo.currency === 'USD' && !isNaN(parseFloat(floorInfo.floor))) {
185
- floor = parseFloat(floorInfo.floor);
178
+ try {
179
+ const floorInfo = bid.getFloor({
180
+ currency: 'USD',
181
+ mediaType: _isInstreamBidRequest(bid) ? 'video' : 'banner',
182
+ size: '*'
183
+ });
184
+ if (typeof floorInfo === 'object' &&
185
+ floorInfo.currency === 'USD' && !isNaN(parseFloat(floorInfo.floor))) {
186
+ floor = parseFloat(floorInfo.floor);
187
+ }
188
+ } catch (err) {
189
+ logError('Triplelift: getFloor threw an error: ', err);
186
190
  }
187
191
  }
188
192
  return floor !== null ? floor : bid.params.floor;
@@ -305,6 +305,15 @@ export const USER_IDS_CONFIG = {
305
305
  source: 'impact-ad.jp',
306
306
  atype: 1
307
307
  },
308
+
309
+ // 33across ID
310
+ '33acrossId': {
311
+ source: '33across.com',
312
+ atype: 1,
313
+ getValue: function(data) {
314
+ return data.envelope;
315
+ }
316
+ },
308
317
  };
309
318
 
310
319
  // this function will create an eid object for the given UserId sub-module