prebid.js 7.48.0 → 7.49.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 (171) hide show
  1. package/README.md +3 -0
  2. package/dist/33acrossBidAdapter.js +1 -1
  3. package/dist/33acrossIdSystem.js +1 -1
  4. package/dist/adagioBidAdapter.js +1 -1
  5. package/dist/adbookpspBidAdapter.js +1 -1
  6. package/dist/adgenerationBidAdapter.js +1 -1
  7. package/dist/admixerBidAdapter.js +1 -1
  8. package/dist/adrelevantisBidAdapter.js +1 -1
  9. package/dist/adtrgtmeBidAdapter.js +1 -1
  10. package/dist/adxcgBidAdapter.js +1 -1
  11. package/dist/adyoulikeBidAdapter.js +1 -1
  12. package/dist/aidemBidAdapter.js +1 -1
  13. package/dist/ajaBidAdapter.js +1 -1
  14. package/dist/amxBidAdapter.js +1 -1
  15. package/dist/amxIdSystem.js +1 -1
  16. package/dist/appierAnalyticsAdapter.js +1 -1
  17. package/dist/appnexusBidAdapter.js +1 -1
  18. package/dist/asoBidAdapter.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/bridgewellBidAdapter.js +1 -1
  23. package/dist/brightMountainMediaBidAdapter.js +1 -1
  24. package/dist/carodaBidAdapter.js +1 -1
  25. package/dist/chtnwBidAdapter.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/conversantAnalyticsAdapter.js +1 -1
  30. package/dist/conversantBidAdapter.js +1 -1
  31. package/dist/craftBidAdapter.js +1 -1
  32. package/dist/criteoBidAdapter.js +1 -1
  33. package/dist/cwireBidAdapter.js +1 -1
  34. package/dist/dspxBidAdapter.js +1 -1
  35. package/dist/eplanningBidAdapter.js +1 -1
  36. package/dist/feedadBidAdapter.js +1 -1
  37. package/dist/finativeBidAdapter.js +1 -1
  38. package/dist/freewheel-sspBidAdapter.js +1 -1
  39. package/dist/glimpseBidAdapter.js +1 -1
  40. package/dist/gmosspBidAdapter.js +1 -1
  41. package/dist/goldbachBidAdapter.js +1 -1
  42. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  43. package/dist/greenbidsRtdProvider.js +1 -1
  44. package/dist/gridBidAdapter.js +1 -1
  45. package/dist/gumgumBidAdapter.js +1 -1
  46. package/dist/h12mediaBidAdapter.js +1 -1
  47. package/dist/id5IdSystem.js +1 -1
  48. package/dist/improvedigitalBidAdapter.js +1 -1
  49. package/dist/inmarBidAdapter.js +1 -1
  50. package/dist/insticatorBidAdapter.js +1 -1
  51. package/dist/ixBidAdapter.js +1 -1
  52. package/dist/justpremiumBidAdapter.js +1 -1
  53. package/dist/kargoBidAdapter.js +1 -1
  54. package/dist/konduitAnalyticsAdapter.js +1 -1
  55. package/dist/kueezBidAdapter.js +1 -1
  56. package/dist/kueezRtbBidAdapter.js +1 -1
  57. package/dist/kulturemediaBidAdapter.js +1 -1
  58. package/dist/lassoBidAdapter.js +1 -1
  59. package/dist/lifestreetBidAdapter.js +1 -1
  60. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  61. package/dist/logicadBidAdapter.js +1 -1
  62. package/dist/loglyliftBidAdapter.js +1 -1
  63. package/dist/magniteAnalyticsAdapter.js +1 -1
  64. package/dist/malltvAnalyticsAdapter.js +1 -1
  65. package/dist/marsmediaBidAdapter.js +1 -1
  66. package/dist/mediafuseBidAdapter.js +1 -1
  67. package/dist/mediasquareBidAdapter.js +1 -1
  68. package/dist/mgidBidAdapter.js +1 -1
  69. package/dist/minutemediaBidAdapter.js +1 -1
  70. package/dist/minutemediaplusBidAdapter.js +1 -1
  71. package/dist/nexx360BidAdapter.js +1 -1
  72. package/dist/not-for-prod/prebid.js +129 -128
  73. package/dist/oguryBidAdapter.js +1 -1
  74. package/dist/onetagBidAdapter.js +1 -1
  75. package/dist/ooloAnalyticsAdapter.js +1 -1
  76. package/dist/optidigitalBidAdapter.js +1 -1
  77. package/dist/outbrainBidAdapter.js +1 -1
  78. package/dist/parrableIdSystem.js +1 -1
  79. package/dist/pixfutureBidAdapter.js +1 -1
  80. package/dist/prebid-core.js +1 -1
  81. package/dist/prebidServerBidAdapter.js +1 -1
  82. package/dist/publinkIdSystem.js +1 -1
  83. package/dist/pubmaticAnalyticsAdapter.js +1 -1
  84. package/dist/pubmaticBidAdapter.js +1 -1
  85. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  86. package/dist/pxyzBidAdapter.js +1 -1
  87. package/dist/quantcastBidAdapter.js +1 -1
  88. package/dist/readpeakBidAdapter.js +1 -1
  89. package/dist/relaidoBidAdapter.js +1 -1
  90. package/dist/retailspotBidAdapter.js +1 -0
  91. package/dist/rhythmoneBidAdapter.js +1 -1
  92. package/dist/riseBidAdapter.js +1 -1
  93. package/dist/rubiconAnalyticsAdapter.js +1 -1
  94. package/dist/rubiconBidAdapter.js +1 -1
  95. package/dist/seedingAllianceBidAdapter.js +1 -1
  96. package/dist/seedtagBidAdapter.js +1 -1
  97. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  98. package/dist/sharethroughBidAdapter.js +1 -1
  99. package/dist/shinezBidAdapter.js +1 -1
  100. package/dist/smaatoBidAdapter.js +1 -1
  101. package/dist/smartadserverBidAdapter.js +1 -1
  102. package/dist/smartxBidAdapter.js +1 -1
  103. package/dist/smilewantedBidAdapter.js +1 -1
  104. package/dist/sonobiBidAdapter.js +1 -1
  105. package/dist/sovrnAnalyticsAdapter.js +1 -1
  106. package/dist/sovrnBidAdapter.js +1 -1
  107. package/dist/sspBCBidAdapter.js +1 -1
  108. package/dist/stvBidAdapter.js +1 -1
  109. package/dist/sublimeBidAdapter.js +1 -1
  110. package/dist/synacormediaBidAdapter.js +1 -1
  111. package/dist/targetVideoBidAdapter.js +1 -1
  112. package/dist/teadsBidAdapter.js +1 -1
  113. package/dist/trionBidAdapter.js +1 -1
  114. package/dist/tripleliftBidAdapter.js +1 -1
  115. package/dist/ttdBidAdapter.js +1 -1
  116. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  117. package/dist/uid2IdSystem.js +1 -1
  118. package/dist/underdogmediaBidAdapter.js +1 -1
  119. package/dist/undertoneBidAdapter.js +1 -1
  120. package/dist/vidazooBidAdapter.js +1 -1
  121. package/dist/videobyteBidAdapter.js +1 -1
  122. package/dist/visxBidAdapter.js +1 -1
  123. package/dist/vuukleBidAdapter.js +1 -1
  124. package/dist/widespaceBidAdapter.js +1 -1
  125. package/dist/winrBidAdapter.js +1 -1
  126. package/dist/yahoosspBidAdapter.js +1 -1
  127. package/dist/yieldlabBidAdapter.js +1 -1
  128. package/dist/yieldmoBidAdapter.js +1 -1
  129. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  130. package/modules/adgenerationBidAdapter.js +24 -15
  131. package/modules/admixerBidAdapter.js +15 -9
  132. package/modules/aidemBidAdapter.js +3 -1
  133. package/modules/ixBidAdapter.js +65 -47
  134. package/modules/kueezRtbBidAdapter.js +30 -33
  135. package/modules/mgidBidAdapter.js +9 -8
  136. package/modules/minutemediaBidAdapter.js +6 -0
  137. package/modules/minutemediaplusBidAdapter.js +30 -32
  138. package/modules/nexx360BidAdapter.js +2 -1
  139. package/modules/prebidServerBidAdapter/index.js +1 -3
  140. package/modules/prebidServerBidAdapter/ortbConverter.js +5 -1
  141. package/modules/pubmaticAnalyticsAdapter.js +3 -2
  142. package/modules/retailspotBidAdapter .md +32 -0
  143. package/modules/retailspotBidAdapter.js +186 -0
  144. package/modules/riseBidAdapter.js +6 -0
  145. package/modules/ttdBidAdapter.js +23 -22
  146. package/modules/vidazooBidAdapter.js +28 -32
  147. package/modules/yieldlabBidAdapter.js +27 -5
  148. package/package.json +1 -1
  149. package/src/adapterManager.js +4 -0
  150. package/src/adapters/bidderFactory.js +1 -0
  151. package/src/auction.js +2 -0
  152. package/src/prebid.js +36 -12
  153. package/src/utils/cpm.js +4 -1
  154. package/test/spec/modules/adgenerationBidAdapter_spec.js +6 -6
  155. package/test/spec/modules/admixerBidAdapter_spec.js +64 -25
  156. package/test/spec/modules/aidemBidAdapter_spec.js +3 -0
  157. package/test/spec/modules/ixBidAdapter_spec.js +66 -1
  158. package/test/spec/modules/kueezRtbBidAdapter_spec.js +3 -2
  159. package/test/spec/modules/mgidBidAdapter_spec.js +9 -9
  160. package/test/spec/modules/minutemediaBidAdapter_spec.js +18 -0
  161. package/test/spec/modules/minutemediaplusBidAdapter_spec.js +3 -2
  162. package/test/spec/modules/prebidServerBidAdapter_spec.js +96 -1
  163. package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +6 -1
  164. package/test/spec/modules/retailspotBidAdapter_spec.js +426 -0
  165. package/test/spec/modules/riseBidAdapter_spec.js +18 -0
  166. package/test/spec/modules/ttdBidAdapter_spec.js +129 -2
  167. package/test/spec/modules/vidazooBidAdapter_spec.js +3 -2
  168. package/test/spec/modules/yieldlabBidAdapter_spec.js +8 -1
  169. package/test/spec/unit/core/bidderFactory_spec.js +9 -9
  170. package/test/spec/unit/pbjs_api_spec.js +59 -1
  171. package/test/spec/unit/utils/cpm_spec.js +56 -1
@@ -380,15 +380,15 @@ export const spec = {
380
380
 
381
381
  const syncs = [];
382
382
  const query = [];
383
- query.push('cbuster=' + Math.round(new Date().getTime()));
384
- query.push('consentData=' + encodeURIComponent(isPlainObject(gdprConsent) && isStr(gdprConsent?.consentString) ? gdprConsent.consentString : ''));
383
+ query.push('cbuster={cbuster}');
384
+ query.push('gdpr_consent=' + encodeURIComponent(isPlainObject(gdprConsent) && isStr(gdprConsent?.consentString) ? gdprConsent.consentString : ''));
385
385
  if (isPlainObject(gdprConsent) && typeof gdprConsent?.gdprApplies === 'boolean' && gdprConsent.gdprApplies) {
386
- query.push('gdprApplies=1');
386
+ query.push('gdpr=1');
387
387
  } else {
388
- query.push('gdprApplies=0');
388
+ query.push('gdpr=0');
389
389
  }
390
390
  if (isPlainObject(uspConsent) && uspConsent?.consentString) {
391
- query.push(`uspString=${encodeURIComponent(uspConsent?.consentString)}`);
391
+ query.push(`us_privacy=${encodeURIComponent(uspConsent?.consentString)}`);
392
392
  }
393
393
  if (isPlainObject(gppConsent) && gppConsent?.gppString) {
394
394
  query.push(`gppString=${encodeURIComponent(gppConsent?.gppString)}`);
@@ -396,24 +396,25 @@ export const spec = {
396
396
  if (config.getConfig('coppa')) {
397
397
  query.push('coppa=1')
398
398
  }
399
+ const q = query.join('&')
399
400
  if (syncOptions.iframeEnabled) {
400
401
  syncs.push({
401
402
  type: 'iframe',
402
- url: 'https://cm.mgid.com/i.html?' + query.join('&')
403
+ url: 'https://cm.mgid.com/i.html?' + q.replace('{cbuster}', Math.round(new Date().getTime()))
403
404
  });
404
405
  } else if (syncOptions.pixelEnabled) {
405
406
  if (pixels.length === 0) {
406
407
  for (let i = 0; i < spb; i++) {
407
408
  syncs.push({
408
409
  type: 'image',
409
- url: 'https://cm.mgid.com/i.gif?' + query.join('&') // randomly selects partner if sync required
410
+ url: 'https://cm.mgid.com/i.gif?' + q.replace('{cbuster}', Math.round(new Date().getTime())) // randomly selects partner if sync required
410
411
  });
411
412
  }
412
413
  } else {
413
414
  for (let i = 0; i < spb && i < pixels.length; i++) {
414
415
  syncs.push({
415
416
  type: 'image',
416
- url: pixels[i] + (pixels[i].indexOf('?') > 0 ? '&' : '?') + query.join('&')
417
+ url: pixels[i] + (pixels[i].indexOf('?') > 0 ? '&' : '?') + q.replace('{cbuster}', Math.round(new Date().getTime()))
417
418
  });
418
419
  }
419
420
  }
@@ -289,6 +289,7 @@ function generateBidParameters(bid, bidderRequest) {
289
289
  loop: getBidIdParameter('bidderRequestsCount', bid),
290
290
  bidderRequestId: getBidIdParameter('bidderRequestId', bid),
291
291
  transactionId: getBidIdParameter('transactionId', bid),
292
+ coppa: 0
292
293
  };
293
294
 
294
295
  const pos = deepAccess(bid, `mediaTypes.${mediaType}.pos`);
@@ -346,6 +347,11 @@ function generateBidParameters(bid, bidderRequest) {
346
347
  if (linearity) {
347
348
  bidObject.linearity = linearity;
348
349
  }
350
+
351
+ const coppa = deepAccess(bid, `ortb2.regs.coppa`);
352
+ if (coppa) {
353
+ bidObject.coppa = 1;
354
+ }
349
355
  }
350
356
 
351
357
  return bidObject;
@@ -11,18 +11,7 @@ const BIDDER_VERSION = '1.0.0';
11
11
  const CURRENCY = 'USD';
12
12
  const TTL_SECONDS = 60 * 5;
13
13
  const UNIQUE_DEAL_ID_EXPIRY = 1000 * 60 * 15;
14
- export const SUPPORTED_ID_SYSTEMS = {
15
- 'britepoolid': 1,
16
- 'criteoId': 1,
17
- 'id5id': 1,
18
- 'idl_env': 1,
19
- 'lipb': 1,
20
- 'netId': 1,
21
- 'parrableId': 1,
22
- 'pubcid': 1,
23
- 'tdid': 1,
24
- 'pubProvidedId': 1
25
- };
14
+
26
15
  const storage = getStorageManager({bidderCode: BIDDER_CODE});
27
16
 
28
17
  function getTopWindowQueryParams() {
@@ -161,25 +150,23 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) {
161
150
  function appendUserIdsToRequestPayload(payloadRef, userIds) {
162
151
  let key;
163
152
  _each(userIds, (userId, idSystemProviderName) => {
164
- if (SUPPORTED_ID_SYSTEMS[idSystemProviderName]) {
165
- key = `uid.${idSystemProviderName}`;
166
-
167
- switch (idSystemProviderName) {
168
- case 'digitrustid':
169
- payloadRef[key] = deepAccess(userId, 'data.id');
170
- break;
171
- case 'lipb':
172
- payloadRef[key] = userId.lipbid;
173
- break;
174
- case 'parrableId':
175
- payloadRef[key] = userId.eid;
176
- break;
177
- case 'id5id':
178
- payloadRef[key] = userId.uid;
179
- break;
180
- default:
181
- payloadRef[key] = userId;
182
- }
153
+ key = `uid.${idSystemProviderName}`;
154
+
155
+ switch (idSystemProviderName) {
156
+ case 'digitrustid':
157
+ payloadRef[key] = deepAccess(userId, 'data.id');
158
+ break;
159
+ case 'lipb':
160
+ payloadRef[key] = userId.lipbid;
161
+ break;
162
+ case 'parrableId':
163
+ payloadRef[key] = userId.eid;
164
+ break;
165
+ case 'id5id':
166
+ payloadRef[key] = userId.uid;
167
+ break;
168
+ default:
169
+ payloadRef[key] = userId;
183
170
  }
184
171
  });
185
172
  }
@@ -207,7 +194,18 @@ function interpretResponse(serverResponse, request) {
207
194
 
208
195
  try {
209
196
  results.forEach(result => {
210
- const {creativeId, ad, price, exp, width, height, currency, metaData, advertiserDomains, mediaType = BANNER} = result;
197
+ const {
198
+ creativeId,
199
+ ad,
200
+ price,
201
+ exp,
202
+ width,
203
+ height,
204
+ currency,
205
+ metaData,
206
+ advertiserDomains,
207
+ mediaType = BANNER
208
+ } = result;
211
209
  if (!ad || !price) {
212
210
  return;
213
211
  }
@@ -21,7 +21,8 @@ const ALIASES = [
21
21
  { code: 'revenuemaker' },
22
22
  { code: 'first-id', gvlid: 1178 },
23
23
  { code: 'adwebone' },
24
- { code: 'league-m', gvlid: 965 }
24
+ { code: 'league-m', gvlid: 965 },
25
+ { code: 'prjads' },
25
26
  ];
26
27
 
27
28
  export const storage = getStorageManager({
@@ -260,9 +260,7 @@ function queueSync(bidderCodes, gdprConsent, uspConsent, gppConsent, s2sConfig)
260
260
  }
261
261
 
262
262
  if (gppConsent) {
263
- // proposing the following formatting, can adjust if needed...
264
- // update - leaving this param as an array, since it's part of a POST payload where the [] characters shouldn't matter too much
265
- payload.gpp_sid = gppConsent.applicableSections
263
+ payload.gpp_sid = gppConsent.applicableSections.join();
266
264
  // should we add check if applicableSections was not equal to -1 (where user was out of scope)?
267
265
  // this would be similar to what was done above for TCF
268
266
  payload.gpp = gppConsent.gppString;
@@ -167,7 +167,11 @@ const PBS_CONVERTER = ortbConverter({
167
167
  deepSetValue(ortbRequest, 'ext.prebid', mergeDeep(ortbRequest.ext?.prebid || {}, context.s2sBidRequest.s2sConfig.extPrebid));
168
168
  }
169
169
 
170
- const fpdConfigs = Object.entries(context.s2sBidRequest.ortb2Fragments?.bidder || {}).map(([bidder, ortb2]) => ({
170
+ const fpdConfigs = Object.entries(context.s2sBidRequest.ortb2Fragments?.bidder || {}).filter(([bidder]) => {
171
+ const bidders = context.s2sBidRequest.s2sConfig.bidders;
172
+ const allowUnknownBidderCodes = context.s2sBidRequest.s2sConfig.allowUnknownBidderCodes;
173
+ return allowUnknownBidderCodes || (bidders && bidders.includes(bidder));
174
+ }).map(([bidder, ortb2]) => ({
171
175
  bidders: [bidder],
172
176
  config: {ortb2}
173
177
  }));
@@ -1,4 +1,4 @@
1
- import { _each, pick, logWarn, isStr, isArray, logError } from '../src/utils.js';
1
+ import { _each, pick, logWarn, isStr, isArray, logError, getGptSlotInfoForAdUnitCode } from '../src/utils.js';
2
2
  import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
3
3
  import adapterManager from '../src/adapterManager.js';
4
4
  import CONSTANTS from '../src/constants.json';
@@ -353,9 +353,10 @@ function executeBidsLoggerCall(e, highestCpmBids) {
353
353
  outputObj.s = Object.keys(auctionCache.adUnitCodes).reduce(function(slotsArray, adUnitId) {
354
354
  let adUnit = auctionCache.adUnitCodes[adUnitId];
355
355
  let origAdUnit = getAdUnit(auctionCache.origAdUnits, adUnitId) || {};
356
+ // getGptSlotInfoForAdUnitCode returns gptslot corresponding to adunit provided as input.
356
357
  let slotObject = {
357
358
  'sn': adUnitId,
358
- 'au': origAdUnit.adUnitId || adUnitId,
359
+ 'au': origAdUnit.adUnitId || getGptSlotInfoForAdUnitCode(adUnitId)?.gptSlot || adUnitId,
359
360
  'mt': getAdUnitAdFormats(origAdUnit),
360
361
  'sz': getSizesForAdUnit(adUnit, adUnitId),
361
362
  'ps': gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestCpmBids.filter(bid => bid.adUnitCode === adUnitId)),
@@ -0,0 +1,32 @@
1
+ # Overview
2
+
3
+ Module Name: RetailSpot Bidder Adapter
4
+ Module Type: Bidder Adapter
5
+ Maintainer: guillaume@retail-spot.io
6
+
7
+ # Description
8
+
9
+ Module that connects to RetailSpot demand sources.
10
+ Banner and Video ad formats are supported.
11
+
12
+ # Test Parameters
13
+ ```
14
+ var adUnits = {
15
+ "code": "test-div",
16
+ "mediaTypes": {
17
+ "banner": {
18
+ "sizes": ["300x250"]
19
+ },
20
+ "video": {
21
+ context: "instream",
22
+ playerSize: [[640, 480]]
23
+ }
24
+ },
25
+ bids: [{
26
+ bidder: "retailspot",
27
+ params: {
28
+ placement: "test-12345"
29
+ }
30
+ }]
31
+ };
32
+ ```
@@ -0,0 +1,186 @@
1
+ import {buildUrl, deepAccess, parseSizesInput} from '../src/utils.js';
2
+ import {registerBidder} from '../src/adapters/bidderFactory.js';
3
+ import {BANNER, VIDEO} from '../src/mediaTypes.js';
4
+
5
+ const BIDDER_CODE = 'retailspot';
6
+ const DEFAULT_SUBDOMAIN = 'ssp';
7
+ const PREPROD_SUBDOMAIN = 'ssp-preprod';
8
+ const HOST = 'retail-spot.io';
9
+ const ENDPOINT = '/prebid';
10
+ const DEV_URL = 'http://localhost:8090/prebid';
11
+
12
+ export const spec = {
13
+ code: BIDDER_CODE,
14
+ supportedMediaTypes: [BANNER, VIDEO],
15
+ aliases: ['rs'], // short code
16
+ /**
17
+ * Determines whether or not the given bid request is valid.
18
+ *
19
+ * @param {BidRequest} bid The bid params to validate.
20
+ * @return boolean True if this is a valid bid, and false otherwise.
21
+ */
22
+ isBidRequestValid: function (bid) {
23
+ const sizes = getSize(getSizeArray(bid));
24
+ const sizeValid = sizes.width > 0 && sizes.height > 0;
25
+
26
+ return deepAccess(bid, 'params.placement') && sizeValid;
27
+ },
28
+ /**
29
+ * Make a server request from the list of BidRequests.
30
+ *
31
+ * @param {bidRequests} - bidRequests.bids[] is an array of AdUnits and bids
32
+ * @return ServerRequest Info describing the request to the server.
33
+ */
34
+ buildRequests: function (bidRequests, bidderRequest) {
35
+ const payload = bidderRequest;
36
+ payload.rs_pbjs_version = '$prebid.version$';
37
+
38
+ const data = JSON.stringify(payload);
39
+ const options = {
40
+ withCredentials: true
41
+ };
42
+
43
+ const envParam = bidRequests[0].params.env;
44
+ var subDomain = DEFAULT_SUBDOMAIN;
45
+ if (envParam === 'preprod') {
46
+ subDomain = PREPROD_SUBDOMAIN;
47
+ }
48
+
49
+ let url = buildUrl({
50
+ protocol: 'https',
51
+ host: `${subDomain}.${HOST}`,
52
+ pathname: ENDPOINT
53
+ });
54
+
55
+ if (envParam === 'dev') {
56
+ url = DEV_URL;
57
+ }
58
+
59
+ return {
60
+ method: 'POST',
61
+ url,
62
+ data,
63
+ options
64
+ };
65
+ },
66
+ /**
67
+ * Unpack the response from the server into a list of bids.
68
+ *
69
+ * @param {*} serverResponse A successful response from the server.
70
+ * @return {Bid[]} An array of bids which were nested inside the server.
71
+ */
72
+ interpretResponse: function (serverResponse, request) {
73
+ const bidResponses = [];
74
+ var bidRequests = {};
75
+
76
+ try {
77
+ bidRequests = JSON.parse(request.data).bids;
78
+ } catch (err) {
79
+ // json error initial request can't be read
80
+ }
81
+
82
+ // For this adapter, serverResponse is a list
83
+ serverResponse.body.forEach(response => {
84
+ const bid = createBid(response, bidRequests);
85
+ if (bid) {
86
+ bidResponses.push(bid);
87
+ }
88
+ });
89
+
90
+ return bidResponses;
91
+ }
92
+ }
93
+
94
+ function getSizeArray(bid) {
95
+ let inputSize = bid.sizes || [];
96
+
97
+ if (bid.mediaTypes && bid.mediaTypes.banner) {
98
+ inputSize = bid.mediaTypes.banner.sizes || [];
99
+ }
100
+
101
+ // handle size in bid.params in formats: [w, h] and [[w,h]].
102
+ if (bid.params && Array.isArray(bid.params.size)) {
103
+ inputSize = bid.params.size;
104
+ if (!Array.isArray(inputSize[0])) {
105
+ inputSize = [inputSize]
106
+ }
107
+ }
108
+
109
+ return parseSizesInput(inputSize);
110
+ }
111
+
112
+ /* Get parsed size from request size */
113
+ function getSize(sizesArray) {
114
+ const parsed = {};
115
+ // the main requested size is the first one
116
+ const size = sizesArray[0];
117
+
118
+ if (typeof size !== 'string') {
119
+ return parsed;
120
+ }
121
+
122
+ const parsedSize = size.toUpperCase().split('X');
123
+ const width = parseInt(parsedSize[0], 10);
124
+ if (width) {
125
+ parsed.width = width;
126
+ }
127
+
128
+ const height = parseInt(parsedSize[1], 10);
129
+ if (height) {
130
+ parsed.height = height;
131
+ }
132
+
133
+ return parsed;
134
+ }
135
+
136
+ /* Create bid from response */
137
+ function createBid(response, bidRequests) {
138
+ if (!response || !response.mediaType ||
139
+ (response.mediaType === 'video' && !response.vastXml) ||
140
+ (response.mediaType === 'banner' && !response.ad)) {
141
+ return;
142
+ }
143
+
144
+ const request = bidRequests && bidRequests.length && bidRequests.find(itm => response.requestId === itm.bidId);
145
+ // In case we don't retreive the size from the adserver, use the given one.
146
+ if (request) {
147
+ if (!response.width || response.width === '0') {
148
+ response.width = request.width;
149
+ }
150
+
151
+ if (!response.height || response.height === '0') {
152
+ response.height = request.height;
153
+ }
154
+ }
155
+
156
+ const bid = {
157
+ bidderCode: BIDDER_CODE,
158
+ width: response.width,
159
+ height: response.height,
160
+ requestId: response.requestId,
161
+ ttl: response.ttl || 3600,
162
+ creativeId: response.creativeId,
163
+ cpm: response.cpm,
164
+ netRevenue: response.netRevenue,
165
+ currency: response.currency,
166
+ meta: response.meta || { advertiserDomains: ['retail-spot.io'] },
167
+ mediaType: response.mediaType
168
+ };
169
+
170
+ // retreive video response if present
171
+ if (response.mediaType === 'video') {
172
+ bid.vastXml = window.atob(response.vastXml);
173
+ } else {
174
+ bid.ad = response.ad;
175
+ }
176
+ if (response.adId) {
177
+ bid.adId = response.adId;
178
+ }
179
+ if (response.dealId) {
180
+ bid.dealId = response.dealId;
181
+ }
182
+
183
+ return bid;
184
+ }
185
+
186
+ registerBidder(spec);
@@ -292,6 +292,7 @@ function generateBidParameters(bid, bidderRequest) {
292
292
  bidderRequestId: getBidIdParameter('bidderRequestId', bid),
293
293
  loop: getBidIdParameter('bidderRequestsCount', bid),
294
294
  transactionId: getBidIdParameter('transactionId', bid),
295
+ coppa: 0
295
296
  };
296
297
 
297
298
  const pos = deepAccess(bid, `mediaTypes.${mediaType}.pos`);
@@ -364,6 +365,11 @@ function generateBidParameters(bid, bidderRequest) {
364
365
  if (protocols) {
365
366
  bidObject.protocols = protocols;
366
367
  }
368
+
369
+ const coppa = deepAccess(bid, 'ortb2.regs.coppa')
370
+ if (coppa) {
371
+ bidObject.coppa = 1;
372
+ }
367
373
  }
368
374
 
369
375
  return bidObject;
@@ -2,6 +2,7 @@ import * as utils from '../src/utils.js';
2
2
  import { config } from '../src/config.js';
3
3
  import { registerBidder } from '../src/adapters/bidderFactory.js';
4
4
  import { BANNER, VIDEO } from '../src/mediaTypes.js';
5
+ import {isNumber} from '../src/utils.js';
5
6
 
6
7
  const BIDADAPTERVERSION = 'TTD-PREBID-2022.06.28';
7
8
  const BIDDER_CODE = 'ttd';
@@ -75,7 +76,7 @@ function getSource(validBidRequests) {
75
76
  return source;
76
77
  }
77
78
 
78
- function getDevice() {
79
+ function getDevice(firstPartyData) {
79
80
  const language = navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage;
80
81
  let device = {
81
82
  ua: navigator.userAgent,
@@ -84,6 +85,8 @@ function getDevice() {
84
85
  connectiontype: getConnectionType()
85
86
  };
86
87
 
88
+ utils.mergeDeep(device, firstPartyData.device)
89
+
87
90
  return device;
88
91
  };
89
92
 
@@ -114,7 +117,7 @@ function getConnectionType() {
114
117
  }
115
118
  }
116
119
 
117
- function getUser(bidderRequest) {
120
+ function getUser(bidderRequest, firstPartyData) {
118
121
  let user = {};
119
122
  if (bidderRequest.gdprConsent) {
120
123
  utils.deepSetValue(user, 'ext.consent', bidderRequest.gdprConsent.consentString);
@@ -129,13 +132,8 @@ function getUser(bidderRequest) {
129
132
  utils.deepSetValue(user, 'ext.eids', eids);
130
133
  }
131
134
 
132
- // gather user.data
133
- const ortb2UserData = utils.deepAccess(bidderRequest, 'ortb2.user.data');
134
- if (ortb2UserData && ortb2UserData.length) {
135
- user = utils.mergeDeep(user, {
136
- data: [...ortb2UserData]
137
- });
138
- };
135
+ utils.mergeDeep(user, firstPartyData.user)
136
+
139
137
  return user;
140
138
  }
141
139
 
@@ -163,16 +161,6 @@ function getImpression(bidRequest) {
163
161
  };
164
162
 
165
163
  const gpid = utils.deepAccess(bidRequest, 'ortb2Imp.ext.gpid');
166
- const tid = utils.deepAccess(bidRequest, 'ortb2Imp.ext.tid');
167
- const rwdd = utils.deepAccess(bidRequest, 'ortb2Imp.rwdd');
168
- if (gpid || tid) {
169
- impression.ext = {}
170
- if (gpid) { impression.ext.gpid = gpid }
171
- if (tid) { impression.ext.tid = tid }
172
- }
173
- if (rwdd) {
174
- impression.rwdd = rwdd;
175
- }
176
164
  const tagid = gpid || bidRequest.params.placementId;
177
165
  if (tagid) {
178
166
  impression.tagid = tagid;
@@ -197,6 +185,11 @@ function getImpression(bidRequest) {
197
185
  impression.bidfloorcur = 'USD';
198
186
  }
199
187
 
188
+ const secure = utils.deepAccess(bidRequest, 'ortb2Imp.secure');
189
+ impression.secure = isNumber(secure) ? secure : 1
190
+
191
+ utils.mergeDeep(impression, bidRequest.ortb2Imp)
192
+
200
193
  return impression;
201
194
  }
202
195
 
@@ -416,8 +409,8 @@ export const spec = {
416
409
  id: bidderRequest.auctionId,
417
410
  imp: validBidRequests.map(bidRequest => getImpression(bidRequest)),
418
411
  site: getSite(bidderRequest, firstPartyData),
419
- device: getDevice(),
420
- user: getUser(bidderRequest),
412
+ device: getDevice(firstPartyData),
413
+ user: getUser(bidderRequest, firstPartyData),
421
414
  at: 1,
422
415
  cur: ['USD'],
423
416
  regs: getRegs(bidderRequest),
@@ -433,6 +426,14 @@ export const spec = {
433
426
  topLevel.badv = firstPartyData.badv;
434
427
  }
435
428
 
429
+ if (firstPartyData && firstPartyData.app) {
430
+ topLevel.app = firstPartyData.app
431
+ }
432
+
433
+ if (firstPartyData && firstPartyData.pmp) {
434
+ topLevel.pmp = firstPartyData.pmp
435
+ }
436
+
436
437
  let url = BIDDER_ENDPOINT + bidderRequest.bids[0].params.supplySourceId;
437
438
 
438
439
  let serverRequest = {
@@ -468,7 +469,7 @@ export const spec = {
468
469
  * @param {ttdResponseObj} bidResponse A successful response from ttd.
469
470
  * @param {ServerRequest} serverRequest The result of buildRequests() that lead to this response.
470
471
  * @return {Bid[]} An array of formatted bids.
471
- */
472
+ */
472
473
  interpretResponse: function (response, serverRequest) {
473
474
  let seatBidsInResponse = utils.deepAccess(response, 'body.seatbid');
474
475
  const currency = utils.deepAccess(response, 'body.cur');
@@ -15,18 +15,6 @@ const DEAL_ID_EXPIRY = 1000 * 60 * 15;
15
15
  const UNIQUE_DEAL_ID_EXPIRY = 1000 * 60 * 60;
16
16
  const SESSION_ID_KEY = 'vidSid';
17
17
  const OPT_CACHE_KEY = 'vdzwopt';
18
- export const SUPPORTED_ID_SYSTEMS = {
19
- 'britepoolid': 1,
20
- 'criteoId': 1,
21
- 'id5id': 1,
22
- 'idl_env': 1,
23
- 'lipb': 1,
24
- 'netId': 1,
25
- 'parrableId': 1,
26
- 'pubcid': 1,
27
- 'tdid': 1,
28
- 'pubProvidedId': 1
29
- };
30
18
  export const webSessionId = 'wsid_' + parseInt(Date.now() * Math.random());
31
19
  const storage = getStorageManager({bidderCode: BIDDER_CODE});
32
20
 
@@ -180,25 +168,22 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) {
180
168
  function appendUserIdsToRequestPayload(payloadRef, userIds) {
181
169
  let key;
182
170
  _each(userIds, (userId, idSystemProviderName) => {
183
- if (SUPPORTED_ID_SYSTEMS[idSystemProviderName]) {
184
- key = `uid.${idSystemProviderName}`;
185
-
186
- switch (idSystemProviderName) {
187
- case 'digitrustid':
188
- payloadRef[key] = deepAccess(userId, 'data.id');
189
- break;
190
- case 'lipb':
191
- payloadRef[key] = userId.lipbid;
192
- break;
193
- case 'parrableId':
194
- payloadRef[key] = userId.eid;
195
- break;
196
- case 'id5id':
197
- payloadRef[key] = userId.uid;
198
- break;
199
- default:
200
- payloadRef[key] = userId;
201
- }
171
+ key = `uid.${idSystemProviderName}`;
172
+ switch (idSystemProviderName) {
173
+ case 'digitrustid':
174
+ payloadRef[key] = deepAccess(userId, 'data.id');
175
+ break;
176
+ case 'lipb':
177
+ payloadRef[key] = userId.lipbid;
178
+ break;
179
+ case 'parrableId':
180
+ payloadRef[key] = userId.eid;
181
+ break;
182
+ case 'id5id':
183
+ payloadRef[key] = userId.uid;
184
+ break;
185
+ default:
186
+ payloadRef[key] = userId;
202
187
  }
203
188
  });
204
189
  }
@@ -227,7 +212,18 @@ function interpretResponse(serverResponse, request) {
227
212
 
228
213
  try {
229
214
  results.forEach(result => {
230
- const {creativeId, ad, price, exp, width, height, currency, advertiserDomains, metaData, mediaType = BANNER} = result;
215
+ const {
216
+ creativeId,
217
+ ad,
218
+ price,
219
+ exp,
220
+ width,
221
+ height,
222
+ currency,
223
+ advertiserDomains,
224
+ metaData,
225
+ mediaType = BANNER
226
+ } = result;
231
227
  if (!ad || !price) {
232
228
  return;
233
229
  }