prebid.js 6.7.0 → 6.11.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 (160) hide show
  1. package/.eslintrc.js +8 -1
  2. package/integrationExamples/gpt/{haloRtdProvider_example.html → hadronRtdProvider_example.html} +9 -9
  3. package/integrationExamples/gpt/idImportLibrary_example.html +2 -2
  4. package/integrationExamples/gpt/userId_example.html +2 -2
  5. package/integrationExamples/gpt/weboramaRtdProvider_example.html +154 -115
  6. package/integrationExamples/gpt/x-domain/creative.html +63 -29
  7. package/modules/.submodules.json +3 -0
  8. package/modules/adagioBidAdapter.js +0 -8
  9. package/modules/adagioBidAdapter.md +1 -1
  10. package/modules/adkernelBidAdapter.js +2 -1
  11. package/modules/adnuntiusRtdProvider.js +96 -0
  12. package/modules/adnuntiusRtdProvider.md +41 -0
  13. package/modules/adotBidAdapter.js +516 -567
  14. package/modules/adotBidAdapter.md +6 -44
  15. package/modules/adpod.js +12 -14
  16. package/modules/adyoulikeBidAdapter.js +2 -0
  17. package/modules/appnexusBidAdapter.js +14 -2
  18. package/modules/asealBidAdapter.js +58 -0
  19. package/modules/asealBidAdapter.md +52 -0
  20. package/modules/brandmetricsRtdProvider.js +168 -0
  21. package/modules/brandmetricsRtdProvider.md +40 -0
  22. package/modules/conversantBidAdapter.js +7 -0
  23. package/modules/criteoBidAdapter.js +9 -0
  24. package/modules/currency.js +27 -5
  25. package/modules/displayioBidAdapter.js +157 -0
  26. package/modules/displayioBidAdapter.md +148 -0
  27. package/modules/dspxBidAdapter.js +69 -29
  28. package/modules/dspxBidAdapter.md +2 -1
  29. package/modules/e_volutionBidAdapter.js +158 -0
  30. package/modules/gridBidAdapter.js +15 -1
  31. package/modules/gumgumBidAdapter.js +52 -38
  32. package/modules/hadronIdSystem.js +96 -0
  33. package/modules/hadronIdSystem.md +35 -0
  34. package/modules/hadronRtdProvider.js +254 -0
  35. package/modules/hadronRtdProvider.md +126 -0
  36. package/modules/haloIdSystem.md +4 -35
  37. package/modules/haloRtdProvider.md +3 -126
  38. package/modules/imRtdProvider.js +10 -0
  39. package/modules/improvedigitalBidAdapter.js +5 -0
  40. package/modules/interactiveOffersBidAdapter.js +9 -6
  41. package/modules/iqzoneBidAdapter.js +10 -3
  42. package/modules/iqzoneBidAdapter.md +16 -0
  43. package/modules/ixBidAdapter.js +2 -6
  44. package/modules/kubientBidAdapter.js +50 -19
  45. package/modules/lunamediahbBidAdapter.js +32 -4
  46. package/modules/malltvBidAdapter.js +7 -3
  47. package/modules/malltvBidAdapter.md +64 -51
  48. package/modules/mass.js +3 -5
  49. package/modules/mediakeysBidAdapter.js +0 -5
  50. package/modules/medianetAnalyticsAdapter.js +1 -1
  51. package/modules/mediasquareBidAdapter.js +9 -1
  52. package/modules/nextMillenniumBidAdapter.js +1 -0
  53. package/modules/oguryBidAdapter.js +7 -14
  54. package/modules/prebidServerBidAdapter/index.js +61 -39
  55. package/modules/priceFloors.js +20 -12
  56. package/modules/pubmaticBidAdapter.js +1 -1
  57. package/modules/richaudienceBidAdapter.js +8 -3
  58. package/modules/riseBidAdapter.js +17 -6
  59. package/modules/rtbhouseBidAdapter.js +2 -0
  60. package/modules/rubiconAnalyticsAdapter.js +5 -0
  61. package/modules/rubiconBidAdapter.js +2 -2
  62. package/modules/sizeMappingV2.js +1 -8
  63. package/modules/sortableAnalyticsAdapter.js +5 -4
  64. package/modules/sovrnBidAdapter.js +93 -18
  65. package/modules/sovrnBidAdapter.md +80 -2
  66. package/modules/sspBCBidAdapter.js +53 -20
  67. package/modules/telariaBidAdapter.js +22 -29
  68. package/modules/trustpidSystem.js +197 -0
  69. package/modules/trustpidSystem.md +45 -0
  70. package/modules/undertoneBidAdapter.js +17 -1
  71. package/modules/userId/eids.js +16 -1
  72. package/modules/userId/eids.md +10 -2
  73. package/modules/userId/userId.md +17 -2
  74. package/modules/vibrantmediaBidAdapter.js +220 -0
  75. package/modules/vibrantmediaBidAdapter.md +92 -0
  76. package/modules/vidoomyBidAdapter.js +8 -0
  77. package/modules/vidoomyBidAdapter.md +4 -2
  78. package/modules/weboramaRtdProvider.js +264 -34
  79. package/modules/weboramaRtdProvider.md +110 -40
  80. package/modules/yahoosspBidAdapter.js +3 -1
  81. package/modules/yieldoneBidAdapter.js +6 -0
  82. package/package.json +2 -1
  83. package/src/adRendering.js +38 -0
  84. package/src/adapterManager.js +24 -19
  85. package/src/adapters/bidderFactory.js +14 -11
  86. package/src/adloader.js +2 -1
  87. package/src/auction.js +138 -115
  88. package/src/auctionIndex.js +85 -0
  89. package/src/auctionManager.js +3 -0
  90. package/src/bidderSettings.js +69 -0
  91. package/src/bidfactory.js +18 -6
  92. package/src/native.js +29 -21
  93. package/src/prebid.js +3 -19
  94. package/src/secureCreatives.js +128 -45
  95. package/src/targeting.js +11 -2
  96. package/src/utils.js +14 -17
  97. package/src/video.js +10 -11
  98. package/src/videoCache.js +10 -9
  99. package/test/fixtures/fixtures.js +2 -1
  100. package/test/helpers/indexStub.js +28 -0
  101. package/test/helpers/syncPromise.js +71 -0
  102. package/test/spec/auctionmanager_spec.js +268 -89
  103. package/test/spec/config_spec.js +24 -1
  104. package/test/spec/modules/adagioBidAdapter_spec.js +0 -10
  105. package/test/spec/modules/adnuntiusRtdProvider_spec.js +145 -0
  106. package/test/spec/modules/adotBidAdapter_spec.js +294 -3124
  107. package/test/spec/modules/adpod_spec.js +91 -156
  108. package/test/spec/modules/adyoulikeBidAdapter_spec.js +4 -0
  109. package/test/spec/modules/appnexusBidAdapter_spec.js +27 -0
  110. package/test/spec/modules/asealBidAdapter_spec.js +144 -0
  111. package/test/spec/modules/brandmetricsRtdProvider_spec.js +191 -0
  112. package/test/spec/modules/conversantBidAdapter_spec.js +54 -2
  113. package/test/spec/modules/criteoBidAdapter_spec.js +21 -0
  114. package/test/spec/modules/currency_spec.js +36 -15
  115. package/test/spec/modules/displayioBidAdapter_spec.js +239 -0
  116. package/test/spec/modules/dspxBidAdapter_spec.js +20 -15
  117. package/test/spec/modules/e_volutionBidAdapter_spec.js +242 -0
  118. package/test/spec/modules/eids_spec.js +2 -2
  119. package/test/spec/modules/gridBidAdapter_spec.js +18 -0
  120. package/test/spec/modules/gumgumBidAdapter_spec.js +49 -3
  121. package/test/spec/modules/hadronIdSystem_spec.js +57 -0
  122. package/test/spec/modules/hadronRtdProvider_spec.js +762 -0
  123. package/test/spec/modules/imRtdProvider_spec.js +30 -1
  124. package/test/spec/modules/improvedigitalBidAdapter_spec.js +19 -0
  125. package/test/spec/modules/iqzoneBidAdapter_spec.js +1 -0
  126. package/test/spec/modules/ixBidAdapter_spec.js +1 -1
  127. package/test/spec/modules/kubientBidAdapter_spec.js +182 -84
  128. package/test/spec/modules/lunamediahbBidAdapter_spec.js +27 -1
  129. package/test/spec/modules/mass_spec.js +2 -14
  130. package/test/spec/modules/mediakeysBidAdapter_spec.js +9 -5
  131. package/test/spec/modules/mediasquareBidAdapter_spec.js +25 -1
  132. package/test/spec/modules/oguryBidAdapter_spec.js +63 -5
  133. package/test/spec/modules/prebidServerBidAdapter_spec.js +43 -6
  134. package/test/spec/modules/priceFloors_spec.js +83 -24
  135. package/test/spec/modules/pubmaticBidAdapter_spec.js +40 -0
  136. package/test/spec/modules/riseBidAdapter_spec.js +30 -4
  137. package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +31 -1
  138. package/test/spec/modules/rubiconBidAdapter_spec.js +1 -1
  139. package/test/spec/modules/sortableAnalyticsAdapter_spec.js +2 -3
  140. package/test/spec/modules/sovrnBidAdapter_spec.js +413 -333
  141. package/test/spec/modules/sspBCBidAdapter_spec.js +7 -7
  142. package/test/spec/modules/telariaBidAdapter_spec.js +1 -3
  143. package/test/spec/modules/trustpidSystem_spec.js +232 -0
  144. package/test/spec/modules/undertoneBidAdapter_spec.js +55 -2
  145. package/test/spec/modules/userId_spec.js +39 -39
  146. package/test/spec/modules/vibrantmediaBidAdapter_spec.js +1237 -0
  147. package/test/spec/modules/vidoomyBidAdapter_spec.js +7 -1
  148. package/test/spec/modules/weboramaRtdProvider_spec.js +536 -20
  149. package/test/spec/modules/yahoosspBidAdapter_spec.js +10 -0
  150. package/test/spec/modules/yieldoneBidAdapter_spec.js +33 -0
  151. package/test/spec/native_spec.js +62 -40
  152. package/test/spec/unit/core/adapterManager_spec.js +22 -0
  153. package/test/spec/unit/core/auctionIndex_spec.js +129 -0
  154. package/test/spec/unit/core/bidderFactory_spec.js +65 -12
  155. package/test/spec/unit/core/bidderSettings_spec.js +123 -0
  156. package/test/spec/unit/core/targeting_spec.js +93 -0
  157. package/test/spec/unit/pbjs_api_spec.js +80 -42
  158. package/test/spec/unit/secureCreatives_spec.js +143 -24
  159. package/test/spec/videoCache_spec.js +18 -19
  160. package/test/spec/video_spec.js +51 -61
package/modules/mass.js CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { config } from '../src/config.js';
6
6
  import { getHook } from '../src/hook.js';
7
- import find from 'core-js-pure/features/array/find.js';
7
+ import {auctionManager} from '../src/auctionManager.js';
8
8
 
9
9
  const defaultCfg = {
10
10
  dealIdPattern: /^MASS/i
@@ -78,7 +78,7 @@ export function updateRenderers() {
78
78
  /**
79
79
  * Before hook for 'addBidResponse'.
80
80
  */
81
- export function addBidResponseHook(next, adUnitCode, bid) {
81
+ export function addBidResponseHook(next, adUnitCode, bid, {index = auctionManager.index} = {}) {
82
82
  let renderer;
83
83
  for (let i = 0; i < renderers.length; i++) {
84
84
  if (renderers[i].match(bid)) {
@@ -88,9 +88,7 @@ export function addBidResponseHook(next, adUnitCode, bid) {
88
88
  }
89
89
 
90
90
  if (renderer) {
91
- const bidRequest = find(this.bidderRequest.bids, bidRequest =>
92
- bidRequest.bidId === bid.requestId
93
- );
91
+ const bidRequest = index.getBidRequest(bid);
94
92
 
95
93
  matchedBids[bid.requestId] = {
96
94
  renderer,
@@ -653,11 +653,6 @@ export const spec = {
653
653
  if (fpd.user) {
654
654
  mergeDeep(payload, { user: fpd.user });
655
655
  }
656
- // Here we can handle device.geo prop
657
- const deviceGeo = deepAccess(fpd, 'device.geo');
658
- if (deviceGeo) {
659
- mergeDeep(payload.device, { geo: deviceGeo });
660
- }
661
656
 
662
657
  const request = {
663
658
  method: 'POST',
@@ -511,7 +511,7 @@ function bidResponseHandler(bid) {
511
511
  bidObj.originalCpm = originalCpm || cpm;
512
512
  let dfpbd = deepAccess(bid, 'adserverTargeting.hb_pb');
513
513
  if (!dfpbd) {
514
- let priceGranularity = getPriceGranularity(mediaType, bid);
514
+ let priceGranularity = getPriceGranularity(bid);
515
515
  let priceGranularityKey = PRICE_GRANULARITY[priceGranularity];
516
516
  dfpbd = bid[priceGranularityKey] || cpm;
517
517
  }
@@ -11,6 +11,7 @@ const BIDDER_ENDPOINT_WINNING = 'winning';
11
11
 
12
12
  export const spec = {
13
13
  code: BIDDER_CODE,
14
+ gvlid: 791,
14
15
  aliases: ['msq'], // short code
15
16
  supportedMediaTypes: [BANNER, NATIVE, VIDEO],
16
17
  /**
@@ -31,10 +32,16 @@ export const spec = {
31
32
  buildRequests: function(validBidRequests, bidderRequest) {
32
33
  let codes = [];
33
34
  let endpoint = document.location.search.match(/msq_test=true/) ? BIDDER_URL_TEST : BIDDER_URL_PROD;
35
+ let floor = {};
34
36
  const test = config.getConfig('debug') ? 1 : 0;
35
37
  let adunitValue = null;
36
38
  Object.keys(validBidRequests).forEach(key => {
37
39
  adunitValue = validBidRequests[key];
40
+ if (typeof adunitValue.getFloor === 'function') {
41
+ floor = adunitValue.getFloor({currency: 'EUR', mediaType: '*', size: '*'});
42
+ } else {
43
+ floor = {};
44
+ }
38
45
  codes.push({
39
46
  owner: adunitValue.params.owner,
40
47
  code: adunitValue.params.code,
@@ -42,7 +49,8 @@ export const spec = {
42
49
  bidId: adunitValue.bidId,
43
50
  auctionId: adunitValue.auctionId,
44
51
  transactionId: adunitValue.transactionId,
45
- mediatypes: adunitValue.mediaTypes
52
+ mediatypes: adunitValue.mediaTypes,
53
+ floor: floor
46
54
  });
47
55
  });
48
56
  const payload = {
@@ -109,6 +109,7 @@ export const spec = {
109
109
  let bidders = []
110
110
  if (responses) {
111
111
  _each(responses, (response) => {
112
+ if (!(response && response.body && response.body.ext && response.body.ext.responsetimemillis)) return
112
113
  _each(Object.keys(response.body.ext.responsetimemillis), b => bidders.push(b))
113
114
  })
114
115
  }
@@ -10,7 +10,7 @@ const DEFAULT_TIMEOUT = 1000;
10
10
  const BID_HOST = 'https://mweb-hb.presage.io/api/header-bidding-request';
11
11
  const TIMEOUT_MONITORING_HOST = 'https://ms-ads-monitoring-events.presage.io';
12
12
  const MS_COOKIE_SYNC_DOMAIN = 'https://ms-cookie-sync.presage.io';
13
- const ADAPTER_VERSION = '1.2.7';
13
+ const ADAPTER_VERSION = '1.2.10';
14
14
 
15
15
  function isBidRequestValid(bid) {
16
16
  const adUnitSizes = getAdUnitSizes(bid);
@@ -41,10 +41,10 @@ function buildRequests(validBidRequests, bidderRequest) {
41
41
  const openRtbBidRequestBanner = {
42
42
  id: bidderRequest.auctionId,
43
43
  tmax: DEFAULT_TIMEOUT,
44
- at: 2,
44
+ at: 1,
45
45
  regs: {
46
46
  ext: {
47
- gdpr: 1
47
+ gdpr: bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies ? 1 : 0
48
48
  },
49
49
  },
50
50
  site: {
@@ -63,14 +63,7 @@ function buildRequests(validBidRequests, bidderRequest) {
63
63
  }
64
64
  };
65
65
 
66
- if (bidderRequest.hasOwnProperty('gdprConsent') &&
67
- bidderRequest.gdprConsent.hasOwnProperty('gdprApplies')) {
68
- openRtbBidRequestBanner.regs.ext.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0
69
- }
70
-
71
- if (bidderRequest.hasOwnProperty('gdprConsent') &&
72
- bidderRequest.gdprConsent.hasOwnProperty('consentString') &&
73
- bidderRequest.gdprConsent.consentString.length > 0) {
66
+ if (bidderRequest.gdprConsent && bidderRequest.gdprConsent.consentString) {
74
67
  openRtbBidRequestBanner.user.ext.consent = bidderRequest.gdprConsent.consentString
75
68
  }
76
69
 
@@ -78,7 +71,7 @@ function buildRequests(validBidRequests, bidderRequest) {
78
71
  const sizes = getAdUnitSizes(bidRequest)
79
72
  .map(size => ({ w: size[0], h: size[1] }));
80
73
 
81
- if (bidRequest.hasOwnProperty('mediaTypes') &&
74
+ if (bidRequest.mediaTypes &&
82
75
  bidRequest.mediaTypes.hasOwnProperty('banner')) {
83
76
  openRtbBidRequestBanner.site.id = bidRequest.params.assetKey;
84
77
 
@@ -166,11 +159,11 @@ function onBidWon(bid) {
166
159
  w.OG_PREBID_BID_OBJECT = {
167
160
  ...(bid && { ...bid }),
168
161
  }
169
- if (bid && bid.hasOwnProperty('nurl') && bid.nurl.length > 0) ajax(bid['nurl'], null);
162
+ if (bid && bid.nurl) ajax(bid.nurl, null);
170
163
  }
171
164
 
172
165
  function onTimeout(timeoutData) {
173
- ajax(`${TIMEOUT_MONITORING_HOST}/bid_timeout`, null, JSON.stringify(timeoutData[0]), {
166
+ ajax(`${TIMEOUT_MONITORING_HOST}/bid_timeout`, null, JSON.stringify({...timeoutData[0], location: window.location.href}), {
174
167
  method: 'POST',
175
168
  contentType: 'application/json'
176
169
  });
@@ -4,13 +4,12 @@ import {
4
4
  getPrebidInternal, logError, isStr, isPlainObject, logWarn, generateUUID, bind, logMessage,
5
5
  triggerPixel, insertUserSyncIframe, deepAccess, mergeDeep, deepSetValue, cleanObj, parseSizesInput,
6
6
  getBidRequest, getDefinedParams, createTrackPixelHtml, pick, deepClone, uniques, flatten, isNumber,
7
- isEmpty, isArray, logInfo
7
+ isEmpty, isArray, logInfo, timestamp
8
8
  } from '../../src/utils.js';
9
9
  import CONSTANTS from '../../src/constants.json';
10
10
  import adapterManager from '../../src/adapterManager.js';
11
11
  import { config } from '../../src/config.js';
12
12
  import { VIDEO, NATIVE } from '../../src/mediaTypes.js';
13
- import { processNativeAdUnitParams } from '../../src/native.js';
14
13
  import { isValid } from '../../src/adapters/bidderFactory.js';
15
14
  import events from '../../src/events.js';
16
15
  import includes from 'core-js-pure/features/array/includes.js';
@@ -54,6 +53,7 @@ let eidPermissions;
54
53
  * @typedef {Object} S2SDefaultConfig
55
54
  * @summary Base config properties for server to server header bidding
56
55
  * @property {string} [adapter='prebidServer'] adapter code to use for S2S
56
+ * @property {boolean} [allowUnknownBidderCodes=false] allow bids from bidders that were not explicitly requested
57
57
  * @property {boolean} [enabled=false] enables S2S bidding
58
58
  * @property {number} [timeout=1000] timeout for S2S bidders - should be lower than `pbjs.requestBids({timeout})`
59
59
  * @property {number} [syncTimeout=1000] timeout for cookie sync iframe / image rendering
@@ -81,6 +81,7 @@ const s2sDefaultConfig = {
81
81
  syncTimeout: 1000,
82
82
  maxBids: 1,
83
83
  adapter: 'prebidServer',
84
+ allowUnknownBidderCodes: false,
84
85
  adapterOptions: {},
85
86
  syncUrlModifier: {}
86
87
  };
@@ -433,7 +434,6 @@ let nativeEventTrackerMethodMap = {
433
434
  * Protocol spec for OpenRTB endpoint
434
435
  * e.g., https://<prebid-server-url>/v1/openrtb2/auction
435
436
  */
436
- let bidIdMap = {};
437
437
  let nativeAssetCache = {}; // store processed native params to preserve
438
438
 
439
439
  /**
@@ -491,8 +491,24 @@ export function resetWurlMap() {
491
491
  wurlMap = {};
492
492
  }
493
493
 
494
- const OPEN_RTB_PROTOCOL = {
495
- buildRequest(s2sBidRequest, bidRequests, adUnits, s2sConfig, requestedBidders) {
494
+ function ORTB2(s2sBidRequest, bidderRequests, adUnits, requestedBidders) {
495
+ this.s2sBidRequest = s2sBidRequest;
496
+ this.bidderRequests = bidderRequests;
497
+ this.adUnits = adUnits;
498
+ this.s2sConfig = s2sBidRequest.s2sConfig;
499
+ this.requestedBidders = requestedBidders;
500
+
501
+ this.bidIdMap = {};
502
+ this.adUnitsByImp = {};
503
+ this.impRequested = {};
504
+ this.auctionId = bidderRequests.map(br => br.auctionId).reduce((l, r) => (l == null || l === r) && r);
505
+ this.requestTimestamp = timestamp();
506
+ }
507
+
508
+ Object.assign(ORTB2.prototype, {
509
+ buildRequest() {
510
+ const {s2sBidRequest, bidderRequests: bidRequests, adUnits, s2sConfig, requestedBidders} = this;
511
+
496
512
  let imps = [];
497
513
  let aliases = {};
498
514
  const firstBidRequest = bidRequests[0];
@@ -510,8 +526,9 @@ const OPEN_RTB_PROTOCOL = {
510
526
  impressionId = `${adUnit.code}-${i}`;
511
527
  }
512
528
  impIds.add(impressionId);
529
+ this.adUnitsByImp[impressionId] = adUnit;
513
530
 
514
- const nativeParams = processNativeAdUnitParams(deepAccess(adUnit, 'mediaTypes.native'));
531
+ const nativeParams = adUnit.nativeParams;
515
532
  let nativeAssets;
516
533
  if (nativeParams) {
517
534
  try {
@@ -584,9 +601,7 @@ const OPEN_RTB_PROTOCOL = {
584
601
  const bannerParams = deepAccess(adUnit, 'mediaTypes.banner');
585
602
 
586
603
  adUnit.bids.forEach(bid => {
587
- // OpenRTB response contains imp.id and bidder name. These are
588
- // combined to create a unique key for each bid since an id isn't returned
589
- bidIdMap[`${impressionId}${bid.bidder}`] = bid.bid_id;
604
+ this.setBidRequestId(impressionId, bid.bidder, bid.bid_id);
590
605
  // check for and store valid aliases to add to the request
591
606
  if (adapterManager.aliasRegistry[bid.bidder]) {
592
607
  const bidder = adapterManager.bidderRegistry[bid.bidder];
@@ -854,10 +869,12 @@ const OPEN_RTB_PROTOCOL = {
854
869
 
855
870
  addBidderFirstPartyDataToRequest(request);
856
871
 
872
+ request.imp.forEach((imp) => this.impRequested[imp.id] = imp);
857
873
  return request;
858
874
  },
859
875
 
860
- interpretResponse(response, bidderRequests, s2sConfig) {
876
+ interpretResponse(response) {
877
+ const {bidderRequests, s2sConfig} = this;
861
878
  const bids = [];
862
879
 
863
880
  [['errors', 'serverErrors'], ['responsetimemillis', 'serverResponseTimeMs']]
@@ -867,22 +884,22 @@ const OPEN_RTB_PROTOCOL = {
867
884
  // a seatbid object contains a `bid` array and a `seat` string
868
885
  response.seatbid.forEach(seatbid => {
869
886
  (seatbid.bid || []).forEach(bid => {
870
- let bidRequest;
871
- let key = `${bid.impid}${seatbid.seat}`;
872
- if (bidIdMap[key]) {
873
- bidRequest = getBidRequest(
874
- bidIdMap[key],
875
- bidderRequests
876
- );
887
+ const bidRequest = this.getBidRequest(bid.impid, seatbid.seat);
888
+ if (bidRequest == null && !s2sConfig.allowUnknownBidderCodes) {
889
+ logWarn(`PBS adapter received bid from unknown bidder (${seatbid.seat}), but 's2sConfig.allowUnknownBidderCodes' is not set. Ignoring bid.`);
890
+ return;
877
891
  }
878
892
 
879
893
  const cpm = bid.price;
880
894
  const status = cpm !== 0 ? CONSTANTS.STATUS.GOOD : CONSTANTS.STATUS.NO_BID;
881
- let bidObject = createBid(status, bidRequest || {
895
+ let bidObject = createBid(status, {
882
896
  bidder: seatbid.seat,
883
- src: TYPE
897
+ src: TYPE,
898
+ bidId: bidRequest ? (bidRequest.bidId || bidRequest.bid_Id) : null,
899
+ transactionId: this.adUnitsByImp[bid.impid].transactionId,
900
+ auctionId: this.auctionId,
884
901
  });
885
-
902
+ bidObject.requestTimestamp = this.requestTimestamp;
886
903
  bidObject.cpm = cpm;
887
904
 
888
905
  // temporarily leaving attaching it to each bidResponse so no breaking change
@@ -900,7 +917,7 @@ const OPEN_RTB_PROTOCOL = {
900
917
 
901
918
  // store wurl by auctionId and adId so it can be accessed from the BID_WON event handler
902
919
  if (isStr(deepAccess(bid, 'ext.prebid.events.win'))) {
903
- addWurl(bidRequest.auctionId, bidObject.adId, deepAccess(bid, 'ext.prebid.events.win'));
920
+ addWurl(this.auctionId, bidObject.adId, deepAccess(bid, 'ext.prebid.events.win'));
904
921
  }
905
922
 
906
923
  let extPrebidTargeting = deepAccess(bid, 'ext.prebid.targeting');
@@ -921,9 +938,8 @@ const OPEN_RTB_PROTOCOL = {
921
938
 
922
939
  if (deepAccess(bid, 'ext.prebid.type') === VIDEO) {
923
940
  bidObject.mediaType = VIDEO;
924
- let sizes = bidRequest.sizes && bidRequest.sizes[0];
925
- bidObject.playerWidth = sizes[0];
926
- bidObject.playerHeight = sizes[1];
941
+ const impReq = this.impRequested[bid.impid];
942
+ [bidObject.playerWidth, bidObject.playerHeight] = [impReq.video.w, impReq.video.h];
927
943
 
928
944
  // try to get cache values from 'response.ext.prebid.cache.js'
929
945
  // else try 'bid.ext.prebid.targeting' as fallback
@@ -1006,7 +1022,6 @@ const OPEN_RTB_PROTOCOL = {
1006
1022
  bidObject.width = bid.w;
1007
1023
  bidObject.height = bid.h;
1008
1024
  if (bid.dealid) { bidObject.dealId = bid.dealid; }
1009
- bidObject.requestId = bidRequest.bidId || bidRequest.bid_Id;
1010
1025
  bidObject.creative_id = bid.crid;
1011
1026
  bidObject.creativeId = bid.crid;
1012
1027
  if (bid.burl) { bidObject.burl = bid.burl; }
@@ -1021,14 +1036,24 @@ const OPEN_RTB_PROTOCOL = {
1021
1036
  bidObject.ttl = (bid.exp) ? bid.exp : configTtl;
1022
1037
  bidObject.netRevenue = (bid.netRevenue) ? bid.netRevenue : DEFAULT_S2S_NETREVENUE;
1023
1038
 
1024
- bids.push({ adUnit: bidRequest.adUnitCode, bid: bidObject });
1039
+ bids.push({ adUnit: this.adUnitsByImp[bid.impid].code, bid: bidObject });
1025
1040
  });
1026
1041
  });
1027
1042
  }
1028
1043
 
1029
1044
  return bids;
1045
+ },
1046
+ setBidRequestId(impId, bidderCode, bidId) {
1047
+ this.bidIdMap[this.impBidderKey(impId, bidderCode)] = bidId;
1048
+ },
1049
+ getBidRequest(impId, bidderCode) {
1050
+ const key = this.impBidderKey(impId, bidderCode);
1051
+ return this.bidIdMap[key] && getBidRequest(this.bidIdMap[key], this.bidderRequests);
1052
+ },
1053
+ impBidderKey(impId, bidderCode) {
1054
+ return `${impId}${bidderCode}`;
1030
1055
  }
1031
- };
1056
+ });
1032
1057
 
1033
1058
  /**
1034
1059
  * BID_WON event to request the wurl
@@ -1099,7 +1124,8 @@ export function PrebidServer() {
1099
1124
  queueSync(syncBidders, gdprConsent, uspConsent, s2sBidRequest.s2sConfig);
1100
1125
  }
1101
1126
 
1102
- const request = OPEN_RTB_PROTOCOL.buildRequest(s2sBidRequest, bidRequests, validAdUnits, s2sBidRequest.s2sConfig, requestedBidders);
1127
+ const ortb2 = new ORTB2(s2sBidRequest, bidRequests, validAdUnits, requestedBidders);
1128
+ const request = ortb2.buildRequest();
1103
1129
  const requestJson = request && JSON.stringify(request);
1104
1130
  logInfo('BidRequest: ' + requestJson);
1105
1131
  const endpointUrl = getMatchingConsentUrl(s2sBidRequest.s2sConfig.endpoint, gdprConsent);
@@ -1107,7 +1133,7 @@ export function PrebidServer() {
1107
1133
  ajax(
1108
1134
  endpointUrl,
1109
1135
  {
1110
- success: response => handleResponse(response, requestedBidders, bidRequests, addBidResponse, done, s2sBidRequest.s2sConfig),
1136
+ success: response => handleResponse(response, ortb2, addBidResponse, done),
1111
1137
  error: done
1112
1138
  },
1113
1139
  requestJson,
@@ -1120,27 +1146,23 @@ export function PrebidServer() {
1120
1146
  };
1121
1147
 
1122
1148
  /* Notify Prebid of bid responses so bids can get in the auction */
1123
- function handleResponse(response, requestedBidders, bidderRequests, addBidResponse, done, s2sConfig) {
1149
+ function handleResponse(response, ortb2, addBidResponse, done) {
1124
1150
  let result;
1125
1151
  let bids = [];
1126
- let { gdprConsent, uspConsent } = getConsentData(bidderRequests);
1152
+ let { gdprConsent, uspConsent } = getConsentData(ortb2.bidderRequests);
1127
1153
 
1128
1154
  try {
1129
1155
  result = JSON.parse(response);
1130
1156
 
1131
- bids = OPEN_RTB_PROTOCOL.interpretResponse(
1132
- result,
1133
- bidderRequests,
1134
- s2sConfig
1135
- );
1157
+ bids = ortb2.interpretResponse(result);
1136
1158
 
1137
1159
  bids.forEach(({adUnit, bid}) => {
1138
- if (isValid(adUnit, bid, bidderRequests)) {
1160
+ if (isValid(adUnit, bid)) {
1139
1161
  addBidResponse(adUnit, bid);
1140
1162
  }
1141
1163
  });
1142
1164
 
1143
- bidderRequests.forEach(bidderRequest => events.emit(CONSTANTS.EVENTS.BIDDER_DONE, bidderRequest));
1165
+ ortb2.bidderRequests.forEach(bidderRequest => events.emit(CONSTANTS.EVENTS.BIDDER_DONE, bidderRequest));
1144
1166
  } catch (error) {
1145
1167
  logError(error);
1146
1168
  }
@@ -1150,7 +1172,7 @@ export function PrebidServer() {
1150
1172
  }
1151
1173
 
1152
1174
  done();
1153
- doClientSideSyncs(requestedBidders, gdprConsent, uspConsent);
1175
+ doClientSideSyncs(ortb2.requestedBidders, gdprConsent, uspConsent);
1154
1176
  }
1155
1177
 
1156
1178
  // Listen for bid won to call wurl
@@ -8,6 +8,8 @@ import { getHook } from '../src/hook.js';
8
8
  import { createBid } from '../src/bidfactory.js';
9
9
  import find from 'core-js-pure/features/array/find.js';
10
10
  import { getRefererInfo } from '../src/refererDetection.js';
11
+ import {auctionManager} from '../src/auctionManager.js';
12
+ import {bidderSettings} from '../src/bidderSettings.js';
11
13
 
12
14
  /**
13
15
  * @summary This Module is intended to provide users with the ability to dynamically set and enforce price floors on a per auction basis.
@@ -65,9 +67,14 @@ function getHostNameFromReferer(referer) {
65
67
  }
66
68
 
67
69
  // First look into bidRequest!
68
- function getGptSlotFromBidRequest(bidRequest) {
69
- const isGam = deepAccess(bidRequest, 'ortb2Imp.ext.data.adserver.name') === 'gam';
70
- return isGam && bidRequest.ortb2Imp.ext.data.adserver.adslot;
70
+ function getGptSlotFromAdUnit(transactionId, {index = auctionManager.index} = {}) {
71
+ const adUnit = index.getAdUnit({transactionId});
72
+ const isGam = deepAccess(adUnit, 'ortb2Imp.ext.data.adserver.name') === 'gam';
73
+ return isGam && adUnit.ortb2Imp.ext.data.adserver.adslot;
74
+ }
75
+
76
+ function getAdUnitCode(request, response, {index = auctionManager.index} = {}) {
77
+ return request?.adUnitCode || index.getAdUnit(response).code;
71
78
  }
72
79
 
73
80
  /**
@@ -76,9 +83,9 @@ function getGptSlotFromBidRequest(bidRequest) {
76
83
  export let fieldMatchingFunctions = {
77
84
  'size': (bidRequest, bidResponse) => parseGPTSingleSizeArray(bidResponse.size) || '*',
78
85
  'mediaType': (bidRequest, bidResponse) => bidResponse.mediaType || 'banner',
79
- 'gptSlot': (bidRequest, bidResponse) => getGptSlotFromBidRequest(bidRequest) || getGptSlotInfoForAdUnitCode(bidRequest.adUnitCode).gptSlot,
86
+ 'gptSlot': (bidRequest, bidResponse) => getGptSlotFromAdUnit((bidRequest || bidResponse).transactionId) || getGptSlotInfoForAdUnitCode(getAdUnitCode(bidRequest, bidResponse)).gptSlot,
80
87
  'domain': (bidRequest, bidResponse) => referrerHostname || getHostNameFromReferer(getRefererInfo().referer),
81
- 'adUnitCode': (bidRequest, bidResponse) => bidRequest.adUnitCode
88
+ 'adUnitCode': (bidRequest, bidResponse) => getAdUnitCode(bidRequest, bidResponse)
82
89
  }
83
90
 
84
91
  /**
@@ -147,7 +154,7 @@ function generatePossibleEnumerations(arrayOfFields, delimiter) {
147
154
  * @summary If a the input bidder has a registered cpmadjustment it returns the input CPM after being adjusted
148
155
  */
149
156
  export function getBiddersCpmAdjustment(bidderName, inputCpm, bid = {}) {
150
- const adjustmentFunction = deepAccess(getGlobal(), `bidderSettings.${bidderName}.bidCpmAdjustment`) || deepAccess(getGlobal(), 'bidderSettings.standard.bidCpmAdjustment');
157
+ const adjustmentFunction = bidderSettings.get(bidderName, 'bidCpmAdjustment');
151
158
  if (adjustmentFunction) {
152
159
  return parseFloat(adjustmentFunction(inputCpm, {...bid, cpm: inputCpm}));
153
160
  }
@@ -664,15 +671,16 @@ function shouldFloorBid(floorData, floorInfo, bid) {
664
671
  * And if the rule we find determines a bid should be floored we will do so.
665
672
  */
666
673
  export function addBidResponseHook(fn, adUnitCode, bid) {
667
- let floorData = _floorDataForAuction[this.bidderRequest.auctionId];
668
- // if no floor data or associated bidRequest then bail
669
- const matchingBidRequest = find(this.bidderRequest.bids, bidRequest => bidRequest.bidId && bidRequest.bidId === bid.requestId);
670
- if (!floorData || !bid || floorData.skipped || !matchingBidRequest) {
674
+ let floorData = _floorDataForAuction[bid.auctionId];
675
+ // if no floor data then bail
676
+ if (!floorData || !bid || floorData.skipped) {
671
677
  return fn.call(this, adUnitCode, bid);
672
678
  }
673
679
 
680
+ const matchingBidRequest = auctionManager.index.getBidRequest(bid)
681
+
674
682
  // get the matching rule
675
- let floorInfo = getFirstMatchingFloor(floorData.data, {...matchingBidRequest}, {...bid, size: [bid.width, bid.height]});
683
+ let floorInfo = getFirstMatchingFloor(floorData.data, matchingBidRequest, {...bid, size: [bid.width, bid.height]});
676
684
 
677
685
  if (!floorInfo.matchingFloor) {
678
686
  logWarn(`${MODULE_NAME}: unable to determine a matching price floor for bidResponse`, bid);
@@ -706,7 +714,7 @@ export function addBidResponseHook(fn, adUnitCode, bid) {
706
714
  if (shouldFloorBid(floorData, floorInfo, bid)) {
707
715
  // bid fails floor -> throw it out
708
716
  // create basic bid no-bid with necessary data fro analytics adapters
709
- let flooredBid = createBid(CONSTANTS.STATUS.NO_BID, matchingBidRequest);
717
+ let flooredBid = createBid(CONSTANTS.STATUS.NO_BID, bid.getIdentifiers());
710
718
  Object.assign(flooredBid, pick(bid, [
711
719
  'floorData',
712
720
  'width',
@@ -1080,7 +1080,7 @@ export const spec = {
1080
1080
  bid = deepClone(originalBid);
1081
1081
  bid.params.adSlot = bid.params.adSlot || '';
1082
1082
  _parseAdSlot(bid);
1083
- if (bid.params.hasOwnProperty('video')) {
1083
+ if ((bid.mediaTypes && bid.mediaTypes.hasOwnProperty('video')) || bid.params.hasOwnProperty('video')) {
1084
1084
  // Nothing to do
1085
1085
  } else {
1086
1086
  // If we have a native mediaType configured alongside banner, its ok if the banner size is not set in width and height
@@ -59,10 +59,15 @@ export const spec = {
59
59
  REFERER = (typeof bidderRequest.refererInfo.referer != 'undefined' ? encodeURIComponent(bidderRequest.refererInfo.referer) : null)
60
60
 
61
61
  payload.gdpr_consent = '';
62
- payload.gdpr = bidderRequest.gdprConsent.gdprApplies;
62
+ payload.gdpr = false;
63
63
 
64
64
  if (bidderRequest && bidderRequest.gdprConsent) {
65
- payload.gdpr_consent = bidderRequest.gdprConsent.consentString;
65
+ if (typeof bidderRequest.gdprConsent.gdprApplies != 'undefined') {
66
+ payload.gdpr = bidderRequest.gdprConsent.gdprApplies;
67
+ }
68
+ if (typeof bidderRequest.gdprConsent.consentString != 'undefined') {
69
+ payload.gdpr_consent = bidderRequest.gdprConsent.consentString;
70
+ }
66
71
  }
67
72
 
68
73
  var payloadString = JSON.stringify(payload);
@@ -295,7 +300,7 @@ function raiGetFloor(bid, config) {
295
300
  raiFloor = bid.params.bidfloor;
296
301
  } else if (typeof bid.getFloor == 'function') {
297
302
  let floorSpec = bid.getFloor({
298
- currency: config.getConfig('currency.adServerCurrency'),
303
+ currency: config.getConfig('floors.data.currency') != null ? config.getConfig('floors.data.currency') : 'USD',
299
304
  mediaType: typeof bid.mediaTypes['banner'] == 'object' ? 'banner' : 'video',
300
305
  size: '*'
301
306
  })
@@ -1,4 +1,4 @@
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 } from '../src/utils.js';
2
2
  import {registerBidder} from '../src/adapters/bidderFactory.js';
3
3
  import {VIDEO} from '../src/mediaTypes.js';
4
4
  import {config} from '../src/config.js';
@@ -23,7 +23,7 @@ export const spec = {
23
23
  gvlid: 1043,
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 Rise adapter');
29
29
  return false;
@@ -49,7 +49,7 @@ export const spec = {
49
49
 
50
50
  return requests;
51
51
  },
52
- interpretResponse: function({body}) {
52
+ interpretResponse: function ({body}) {
53
53
  const bidResponses = [];
54
54
 
55
55
  const bidResponse = {
@@ -62,6 +62,7 @@ export const spec = {
62
62
  netRevenue: body.netRevenue,
63
63
  ttl: body.ttl || TTL,
64
64
  vastXml: body.vastXml,
65
+ nurl: body.nurl,
65
66
  mediaType: VIDEO
66
67
  };
67
68
 
@@ -73,7 +74,7 @@ export const spec = {
73
74
 
74
75
  return bidResponses;
75
76
  },
76
- getUserSyncs: function(syncOptions, serverResponses) {
77
+ getUserSyncs: function (syncOptions, serverResponses) {
77
78
  const syncs = [];
78
79
  for (const response of serverResponses) {
79
80
  if (syncOptions.iframeEnabled && response.body.userSyncURL) {
@@ -93,8 +94,18 @@ export const spec = {
93
94
  }
94
95
  }
95
96
  return syncs;
96
- }
97
- };
97
+ },
98
+ onBidWon: function (bid) {
99
+ if (bid == null) {
100
+ return;
101
+ }
102
+
103
+ logInfo('onBidWon:', bid);
104
+ if (bid.hasOwnProperty('nurl') && bid.nurl.length > 0) {
105
+ triggerPixel(bid.nurl);
106
+ }
107
+ },
108
+ }
98
109
 
99
110
  registerBidder(spec);
100
111
 
@@ -9,6 +9,7 @@ const ENDPOINT_URL = 'creativecdn.com/bidder/prebid/bids';
9
9
  const DEFAULT_CURRENCY_ARR = ['USD']; // NOTE - USD is the only supported currency right now; Hardcoded for bids
10
10
  const SUPPORTED_MEDIA_TYPES = [BANNER, NATIVE];
11
11
  const TTL = 55;
12
+ const GVLID = 16;
12
13
 
13
14
  // Codes defined by OpenRTB Native Ads 1.1 specification
14
15
  export const OPENRTB = {
@@ -36,6 +37,7 @@ export const OPENRTB = {
36
37
  export const spec = {
37
38
  code: BIDDER_CODE,
38
39
  supportedMediaTypes: SUPPORTED_MEDIA_TYPES,
40
+ gvlid: GVLID,
39
41
 
40
42
  isBidRequestValid: function (bid) {
41
43
  return !!(includes(REGIONS, bid.params.region) && bid.params.publisherId);
@@ -234,6 +234,9 @@ function sendMessage(auctionId, bidWonId, trigger) {
234
234
 
235
235
  let auction = {
236
236
  clientTimeoutMillis: auctionCache.timeout,
237
+ auctionStart: auctionCache.timestamp,
238
+ auctionEnd: auctionCache.endTs,
239
+ bidderOrder: auctionCache.bidderOrder,
237
240
  samplingFactor,
238
241
  accountId,
239
242
  adUnits: Object.keys(adUnitMap).map(i => adUnitMap[i]),
@@ -583,6 +586,7 @@ let rubiconAdapter = Object.assign({}, baseAdapter, {
583
586
  cacheEntry.bids = {};
584
587
  cacheEntry.bidsWon = {};
585
588
  cacheEntry.gamHasRendered = {};
589
+ cacheEntry.bidderOrder = [];
586
590
  cacheEntry.referrer = deepAccess(args, 'bidderRequests.0.refererInfo.referer');
587
591
  const floorData = deepAccess(args, 'bidderRequests.0.bids.0.floorData');
588
592
  if (floorData) {
@@ -608,6 +612,7 @@ let rubiconAdapter = Object.assign({}, baseAdapter, {
608
612
  }
609
613
  break;
610
614
  case BID_REQUESTED:
615
+ cache.auctions[args.auctionId].bidderOrder.push(args.bidderCode);
611
616
  Object.assign(cache.auctions[args.auctionId].bids, args.bids.reduce((memo, bid) => {
612
617
  // mark adUnits we expect bidWon events for
613
618
  cache.auctions[args.auctionId].bidsWon[bid.adUnitCode] = false;
@@ -8,7 +8,7 @@ import { getGlobal } from '../src/prebidGlobal.js';
8
8
 
9
9
  const DEFAULT_INTEGRATION = 'pbjs_lite';
10
10
  const DEFAULT_PBS_INTEGRATION = 'pbjs';
11
- const DEFAULT_RENDERER_URL = 'https://video-outstream.rubiconproject.com/apex-2.0.0.js';
11
+ const DEFAULT_RENDERER_URL = 'https://video-outstream.rubiconproject.com/apex-2.2.1.js';
12
12
  // renderer code at https://github.com/rubicon-project/apex2
13
13
 
14
14
  let rubiConf = {};
@@ -864,7 +864,7 @@ function renderBid(bid) {
864
864
  height: bid.height,
865
865
  vastUrl: bid.vastUrl,
866
866
  placement: {
867
- attachTo: `#${bid.adUnitCode}`,
867
+ attachTo: adUnitElement,
868
868
  align: config.align || 'center',
869
869
  position: config.position || 'append'
870
870
  },