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
@@ -6,7 +6,7 @@ Adot Bidder Adapter is a module that enables the communication between the Prebi
6
6
 
7
7
  - Module name: Adot Bidder Adapter
8
8
  - Module type: Bidder Adapter
9
- - Maintainer: `aurelien.giudici@adotmob.com`
9
+ - Maintainer: `alexandre.lorin@adotmob.com`
10
10
  - Supported media types: `banner`, `video`, `native`
11
11
 
12
12
  ## Example ad units
@@ -34,9 +34,9 @@ const adUnit = {
34
34
 
35
35
  ### Video ad unit
36
36
 
37
- #### Outstream video ad unit
37
+ #### Video ad unit
38
38
 
39
- Adot Bidder Adapter accepts outstream video ad units using the following ad unit format:
39
+ Adot Bidder Adapter accepts video ad units using the following ad unit format:
40
40
 
41
41
  ```javascript
42
42
  const adUnit = {
@@ -51,9 +51,9 @@ const adUnit = {
51
51
  // Content MIME types supported by the ad unit.
52
52
  mimes: ['video/mp4'],
53
53
  // Minimum accepted video ad duration (in seconds).
54
- minDuration: 5,
54
+ minduration: 5,
55
55
  // Maximum accepted video ad duration (in seconds).
56
- maxDuration: 35,
56
+ maxduration: 35,
57
57
  // Video protocols supported by the ad unit (see the OpenRTB 2.5 specifications,
58
58
  // section 5.8).
59
59
  protocols: [2, 3]
@@ -61,45 +61,7 @@ const adUnit = {
61
61
  },
62
62
  bids: [{
63
63
  bidder: 'adot',
64
- params: {
65
- video: {}
66
- }
67
- }]
68
- }
69
- ```
70
-
71
- #### Instream video ad unit
72
-
73
- Adot Bidder Adapter accepts instream video ad units using the following ad unit format:
74
-
75
- ```javascript
76
- const adUnit = {
77
- code: 'test-div',
78
- mediaTypes: {
79
- video: {
80
- // Video context. Must be 'instream'.
81
- context: 'instream',
82
- // Video dimensions supported by the video ad unit.
83
- // Each ad unit size is formatted as follows: [width, height].
84
- playerSize: [[300, 250]],
85
- // Content MIME types supported by the ad unit.
86
- mimes: ['video/mp4'],
87
- // Minimum accepted video ad duration (in seconds).
88
- minDuration: 5,
89
- // Maximum accepted video ad duration (in seconds).
90
- maxDuration: 35,
91
- // Video protocols supported by the ad unit (see the OpenRTB 2.5 specifications,
92
- // section 5.8).
93
- protocols: [2, 3]
94
- }
95
- },
96
- bids: [{
97
- bidder: 'adot',
98
- params: {
99
- video: {
100
- instreamContext: 'pre-roll'
101
- }
102
- }
64
+ params: {}
103
65
  }]
104
66
  }
105
67
  ```
package/modules/adpod.js CHANGED
@@ -122,7 +122,7 @@ function getPricePartForAdpodKey(bid) {
122
122
  const adpodDealPrefix = config.getConfig(`adpod.dealTier.${bid.bidderCode}.prefix`);
123
123
  pricePart = (adpodDealPrefix) ? adpodDealPrefix + deepAccess(bid, 'video.dealTier') : deepAccess(bid, 'video.dealTier');
124
124
  } else {
125
- const granularity = getPriceGranularity(bid.mediaType);
125
+ const granularity = getPriceGranularity(bid);
126
126
  pricePart = getPriceByGranularity(granularity)(bid);
127
127
  }
128
128
  return pricePart
@@ -223,10 +223,9 @@ function firePrebidCacheCall(auctionInstance, bidList, afterBidAdded) {
223
223
  * @param {*} auctionInstance running context of the auction
224
224
  * @param {Object} bidResponse incoming bid; if adpod, will be processed through hook function. If not adpod, returns to original function.
225
225
  * @param {Function} afterBidAdded callback function used when Prebid Cache responds
226
- * @param {Object} bidderRequest copy of bid's associated bidderRequest object
226
+ * @param {Object} videoConfig mediaTypes.video from the bid's adUnit
227
227
  */
228
- export function callPrebidCacheHook(fn, auctionInstance, bidResponse, afterBidAdded, bidderRequest) {
229
- let videoConfig = deepAccess(bidderRequest, 'mediaTypes.video');
228
+ export function callPrebidCacheHook(fn, auctionInstance, bidResponse, afterBidAdded, videoConfig) {
230
229
  if (videoConfig && videoConfig.context === ADPOD) {
231
230
  let brandCategoryExclusion = config.getConfig('adpod.brandCategoryExclusion');
232
231
  let adServerCatId = deepAccess(bidResponse, 'meta.adServerCatId');
@@ -250,7 +249,7 @@ export function callPrebidCacheHook(fn, auctionInstance, bidResponse, afterBidAd
250
249
  }
251
250
  }
252
251
  } else {
253
- fn.call(this, auctionInstance, bidResponse, afterBidAdded, bidderRequest);
252
+ fn.call(this, auctionInstance, bidResponse, afterBidAdded, videoConfig);
254
253
  }
255
254
  }
256
255
 
@@ -310,18 +309,17 @@ export function checkAdUnitSetupHook(fn, adUnits) {
310
309
  * (eg if range was [5, 15, 30] -> 2s is rounded to 5s; 17s is rounded back to 15s; 18s is rounded up to 30s)
311
310
  * - if the bid is above the range of the listed durations (and outside the buffer), reject the bid
312
311
  * - set the rounded duration value in the `bid.video.durationBucket` field for accepted bids
313
- * @param {Object} bidderRequest copy of the bidderRequest object associated to bidResponse
312
+ * @param {Object} videoMediaType 'mediaTypes.video' associated to bidResponse
314
313
  * @param {Object} bidResponse incoming bidResponse being evaluated by bidderFactory
315
314
  * @returns {boolean} return false if bid duration is deemed invalid as per adUnit configuration; return true if fine
316
315
  */
317
- function checkBidDuration(bidderRequest, bidResponse) {
316
+ function checkBidDuration(videoMediaType, bidResponse) {
318
317
  const buffer = 2;
319
318
  let bidDuration = deepAccess(bidResponse, 'video.durationSeconds');
320
- let videoConfig = deepAccess(bidderRequest, 'mediaTypes.video');
321
- let adUnitRanges = videoConfig.durationRangeSec;
319
+ let adUnitRanges = videoMediaType.durationRangeSec;
322
320
  adUnitRanges.sort((a, b) => a - b); // ensure the ranges are sorted in numeric order
323
321
 
324
- if (!videoConfig.requireExactDuration) {
322
+ if (!videoMediaType.requireExactDuration) {
325
323
  let max = Math.max(...adUnitRanges);
326
324
  if (bidDuration <= (max + buffer)) {
327
325
  let nextHighestRange = find(adUnitRanges, range => (range + buffer) >= bidDuration);
@@ -346,12 +344,12 @@ function checkBidDuration(bidderRequest, bidResponse) {
346
344
  * If it's found to not be an adpod bid, it will return to original function via hook logic
347
345
  * @param {Function} fn reference to original function (used by hook logic)
348
346
  * @param {Object} bid incoming bid object
349
- * @param {Object} bidRequest bidRequest object of associated bid
347
+ * @param {Object} adUnit adUnit object of associated bid
350
348
  * @param {Object} videoMediaType copy of the `bidRequest.mediaTypes.video` object; used in original function
351
349
  * @param {String} context value of the `bidRequest.mediaTypes.video.context` field; used in original function
352
350
  * @returns {boolean} this return is only used for adpod bids
353
351
  */
354
- export function checkVideoBidSetupHook(fn, bid, bidRequest, videoMediaType, context) {
352
+ export function checkVideoBidSetupHook(fn, bid, adUnit, videoMediaType, context) {
355
353
  if (context === ADPOD) {
356
354
  let result = true;
357
355
  let brandCategoryExclusion = config.getConfig('adpod.brandCategoryExclusion');
@@ -367,7 +365,7 @@ export function checkVideoBidSetupHook(fn, bid, bidRequest, videoMediaType, cont
367
365
  if (!deepAccess(bid, 'video.durationSeconds') || bid.video.durationSeconds <= 0) {
368
366
  result = false;
369
367
  } else {
370
- let isBidGood = checkBidDuration(bidRequest, bid);
368
+ let isBidGood = checkBidDuration(videoMediaType, bid);
371
369
  if (!isBidGood) result = false;
372
370
  }
373
371
  }
@@ -382,7 +380,7 @@ export function checkVideoBidSetupHook(fn, bid, bidRequest, videoMediaType, cont
382
380
 
383
381
  fn.bail(result);
384
382
  } else {
385
- fn.call(this, bid, bidRequest, videoMediaType, context);
383
+ fn.call(this, bid, adUnit, videoMediaType, context);
386
384
  }
387
385
  }
388
386
 
@@ -9,6 +9,7 @@ const VERSION = '1.0';
9
9
  const BIDDER_CODE = 'adyoulike';
10
10
  const DEFAULT_DC = 'hb-api';
11
11
  const CURRENCY = 'USD';
12
+ const GVLID = 259;
12
13
 
13
14
  const NATIVE_IMAGE = {
14
15
  image: {
@@ -36,6 +37,7 @@ const NATIVE_IMAGE = {
36
37
 
37
38
  export const spec = {
38
39
  code: BIDDER_CODE,
40
+ gvlid: GVLID,
39
41
  supportedMediaTypes: [BANNER, NATIVE, VIDEO],
40
42
  aliases: ['ayl'], // short code
41
43
  /**
@@ -1,4 +1,4 @@
1
- import { convertCamelToUnderscore, isArray, isNumber, isPlainObject, logError, logInfo, deepAccess, logMessage, convertTypes, isStr, getParameterByName, deepClone, chunk, logWarn, getBidRequest, createTrackPixelHtml, isEmpty, transformBidderParamKeywords, getMaxValueFromArray, fill, getMinValueFromArray, isArrayOfNums, isFn, isAllowZeroCpmBidsEnabled } from '../src/utils.js';
1
+ import { convertCamelToUnderscore, isArray, isNumber, isPlainObject, logError, logInfo, deepAccess, logMessage, convertTypes, isStr, getParameterByName, deepClone, chunk, logWarn, getBidRequest, createTrackPixelHtml, isEmpty, transformBidderParamKeywords, getMaxValueFromArray, fill, getMinValueFromArray, isArrayOfNums, isFn } from '../src/utils.js';
2
2
  import { Renderer } from '../src/Renderer.js';
3
3
  import { config } from '../src/config.js';
4
4
  import { registerBidder, getIabSubCategory } from '../src/adapters/bidderFactory.js';
@@ -8,6 +8,7 @@ import find from 'core-js-pure/features/array/find.js';
8
8
  import includes from 'core-js-pure/features/array/includes.js';
9
9
  import { OUTSTREAM, INSTREAM } from '../src/video.js';
10
10
  import { getStorageManager } from '../src/storageManager.js';
11
+ import { bidderSettings } from '../src/bidderSettings.js';
11
12
 
12
13
  const BIDDER_CODE = 'appnexus';
13
14
  const URL = 'https://ib.adnxs.com/ut/v3/prebid';
@@ -201,6 +202,17 @@ export const spec = {
201
202
  payload.app = appIdObj;
202
203
  }
203
204
 
205
+ let auctionKeywords = config.getConfig('appnexusAuctionKeywords');
206
+ if (isPlainObject(auctionKeywords)) {
207
+ let aucKeywords = transformBidderParamKeywords(auctionKeywords);
208
+
209
+ if (aucKeywords.length > 0) {
210
+ aucKeywords.forEach(deleteValues);
211
+ }
212
+
213
+ payload.keywords = aucKeywords;
214
+ }
215
+
204
216
  if (config.getConfig('adpod.brandCategoryExclusion')) {
205
217
  payload.brand_category_uniqueness = true;
206
218
  }
@@ -292,7 +304,7 @@ export const spec = {
292
304
  serverResponse.tags.forEach(serverBid => {
293
305
  const rtbBid = getRtbBid(serverBid);
294
306
  if (rtbBid) {
295
- const cpmCheck = (isAllowZeroCpmBidsEnabled(bidderRequest.bidderCode)) ? rtbBid.cpm >= 0 : rtbBid.cpm > 0;
307
+ const cpmCheck = (bidderSettings.get(bidderRequest.bidderCode, 'allowZeroCpmBids') === true) ? rtbBid.cpm >= 0 : rtbBid.cpm > 0;
296
308
  if (cpmCheck && includes(this.supportedMediaTypes, rtbBid.ad_type)) {
297
309
  const bid = newBid(serverBid, rtbBid, bidderRequest);
298
310
  bid.mediaType = parseMediaType(rtbBid);
@@ -0,0 +1,58 @@
1
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
2
+ import { BANNER } from '../src/mediaTypes.js';
3
+ import { config } from '../src/config.js';
4
+
5
+ export const BIDDER_CODE = 'aseal';
6
+ const SUPPORTED_AD_TYPES = [BANNER];
7
+ export const API_ENDPOINT = 'https://tkprebid.aotter.net/prebid/adapter';
8
+ export const HEADER_AOTTER_VERSION = 'prebid_0.0.1';
9
+
10
+ export const spec = {
11
+ code: BIDDER_CODE,
12
+ aliases: ['aotter', 'trek'],
13
+ supportedMediaTypes: SUPPORTED_AD_TYPES,
14
+
15
+ isBidRequestValid: (bid) => !!bid.params.placeUid && typeof bid.params.placeUid === 'string',
16
+
17
+ buildRequests: (validBidRequests, bidderRequest) => {
18
+ if (validBidRequests.length === 0) {
19
+ return [];
20
+ }
21
+
22
+ const clientId =
23
+ config.getConfig('aseal.clientId') || '';
24
+
25
+ const data = {
26
+ bids: validBidRequests,
27
+ refererInfo: bidderRequest.refererInfo,
28
+ };
29
+
30
+ const options = {
31
+ contentType: 'application/json',
32
+ withCredentials: true,
33
+ customHeaders: {
34
+ 'x-aotter-clientid': clientId,
35
+ 'x-aotter-version': HEADER_AOTTER_VERSION,
36
+ },
37
+ };
38
+
39
+ return [{
40
+ method: 'POST',
41
+ url: API_ENDPOINT,
42
+ data,
43
+ options,
44
+ }];
45
+ },
46
+
47
+ interpretResponse: (serverResponse, bidRequest) => {
48
+ if (!Array.isArray(serverResponse.body)) {
49
+ return [];
50
+ }
51
+
52
+ const bidResponses = serverResponse.body;
53
+
54
+ return bidResponses;
55
+ },
56
+ };
57
+
58
+ registerBidder(spec);
@@ -0,0 +1,52 @@
1
+ # Overview
2
+
3
+ ```
4
+ Module Name: Aseal Bid Adapter
5
+ Module Type: Bidder Adapter
6
+ Maintainer: tech-service@aotter.net
7
+ ```
8
+
9
+ # Description
10
+
11
+ Module that connects to Aseal server for bids.
12
+ Supported Ad Formats:
13
+
14
+ - Banner
15
+
16
+ # Configuration
17
+
18
+ Following configuration is required:
19
+
20
+ ```js
21
+ pbjs.setConfig({
22
+ aseal: {
23
+ clientId: "YOUR_CLIENT_ID"
24
+ }
25
+ });
26
+ ```
27
+
28
+ # Ad Unit Example
29
+
30
+ ```js
31
+ var adUnits = [
32
+ {
33
+ code: "banner-div",
34
+ mediaTypes: {
35
+ banner: {
36
+ sizes: [
37
+ [300, 250],
38
+ [300, 600]
39
+ ]
40
+ }
41
+ },
42
+ bids: [
43
+ {
44
+ bidder: "aseal",
45
+ params: {
46
+ placeUid: "f4a74f73-9a74-4a87-91c9-545c6316c23d"
47
+ }
48
+ }
49
+ ]
50
+ }
51
+ ];
52
+ ```
@@ -0,0 +1,168 @@
1
+ /**
2
+ * This module adds brandmetrics provider to the real time data module
3
+ * The {@link module:modules/realTimeData} module is required
4
+ * The module will load load the brandmetrics script and set survey- targeting to ad units of specific bidders.
5
+ * @module modules/brandmetricsRtdProvider
6
+ * @requires module:modules/realTimeData
7
+ */
8
+ import { config } from '../src/config.js'
9
+ import { submodule } from '../src/hook.js'
10
+ import { deepSetValue, mergeDeep, logError, deepAccess } from '../src/utils.js'
11
+ import {loadExternalScript} from '../src/adloader.js'
12
+ const MODULE_NAME = 'brandmetrics'
13
+ const MODULE_CODE = MODULE_NAME
14
+ const RECEIVED_EVENTS = []
15
+ const GVL_ID = 422
16
+ const TCF_PURPOSES = [1, 7]
17
+
18
+ function init (config, userConsent) {
19
+ const hasConsent = checkConsent(userConsent)
20
+
21
+ if (hasConsent) {
22
+ const moduleConfig = getMergedConfig(config)
23
+ initializeBrandmetrics(moduleConfig.params.scriptId)
24
+ }
25
+ return hasConsent
26
+ }
27
+
28
+ /**
29
+ * Checks TCF and USP consents
30
+ * @param {Object} userConsent
31
+ * @returns {boolean}
32
+ */
33
+ function checkConsent (userConsent) {
34
+ let consent = false
35
+
36
+ if (userConsent && userConsent.gdpr && userConsent.gdpr.gdprApplies) {
37
+ const gdpr = userConsent.gdpr
38
+
39
+ if (gdpr.vendorData) {
40
+ const vendor = gdpr.vendorData.vendor
41
+ const purpose = gdpr.vendorData.purpose
42
+
43
+ let vendorConsent = false
44
+ if (vendor.consents) {
45
+ vendorConsent = vendor.consents[GVL_ID]
46
+ }
47
+
48
+ if (vendor.legitimateInterests) {
49
+ vendorConsent = vendorConsent || vendor.legitimateInterests[GVL_ID]
50
+ }
51
+
52
+ const purposes = TCF_PURPOSES.map(id => {
53
+ return (purpose.consents && purpose.consents[id]) || (purpose.legitimateInterests && purpose.legitimateInterests[id])
54
+ })
55
+ const purposesValid = purposes.filter(p => p === true).length === TCF_PURPOSES.length
56
+ consent = vendorConsent && purposesValid
57
+ }
58
+ } else if (userConsent.usp) {
59
+ const usp = userConsent.usp
60
+ consent = usp[1] !== 'N' && usp[2] !== 'Y'
61
+ }
62
+
63
+ return consent
64
+ }
65
+
66
+ /**
67
+ * Add event- listeners to hook in to brandmetrics events
68
+ * @param {Object} reqBidsConfigObj
69
+ * @param {function} callback
70
+ */
71
+ function processBrandmetricsEvents (reqBidsConfigObj, moduleConfig, callback) {
72
+ const callBidTargeting = (event) => {
73
+ if (event.available && event.conf) {
74
+ const targetingConf = event.conf.displayOption || {}
75
+ if (targetingConf.type === 'pbjs') {
76
+ setBidderTargeting(reqBidsConfigObj, moduleConfig, targetingConf.targetKey || 'brandmetrics_survey', event.survey.measurementId)
77
+ }
78
+ }
79
+ callback()
80
+ }
81
+
82
+ if (RECEIVED_EVENTS.length > 0) {
83
+ callBidTargeting(RECEIVED_EVENTS[RECEIVED_EVENTS.length - 1])
84
+ } else {
85
+ window._brandmetrics = window._brandmetrics || []
86
+ window._brandmetrics.push({
87
+ cmd: '_addeventlistener',
88
+ val: {
89
+ event: 'surveyloaded',
90
+ reEmitLast: true,
91
+ handler: (ev) => {
92
+ RECEIVED_EVENTS.push(ev)
93
+ if (RECEIVED_EVENTS.length === 1) {
94
+ // Call bid targeting only for the first received event, if called subsequently, last event from the RECEIVED_EVENTS array is used
95
+ callBidTargeting(ev)
96
+ }
97
+ },
98
+ }
99
+ })
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Sets bid targeting of specific bidders
105
+ * @param {Object} reqBidsConfigObj
106
+ * @param {string} key Targeting key
107
+ * @param {string} val Targeting value
108
+ */
109
+ function setBidderTargeting (reqBidsConfigObj, moduleConfig, key, val) {
110
+ const bidders = deepAccess(moduleConfig, 'params.bidders')
111
+ if (bidders && bidders.length > 0) {
112
+ const ortb2 = {}
113
+ deepSetValue(ortb2, 'ortb2.user.ext.data.' + key, val)
114
+ config.setBidderConfig({
115
+ bidders: bidders,
116
+ config: ortb2
117
+ })
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Add the brandmetrics script to the page.
123
+ * @param {string} scriptId - The script- id provided by brandmetrics or brandmetrics partner
124
+ */
125
+ function initializeBrandmetrics(scriptId) {
126
+ if (scriptId) {
127
+ const path = 'https://cdn.brandmetrics.com/survey/script/'
128
+ const file = scriptId + '.js'
129
+ const url = path + file
130
+
131
+ loadExternalScript(url, MODULE_CODE)
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Merges a provided config with default values
137
+ * @param {Object} customConfig
138
+ * @returns
139
+ */
140
+ function getMergedConfig(customConfig) {
141
+ return mergeDeep({
142
+ waitForIt: false,
143
+ params: {
144
+ bidders: [],
145
+ scriptId: undefined,
146
+ }
147
+ }, customConfig)
148
+ }
149
+
150
+ /** @type {RtdSubmodule} */
151
+ export const brandmetricsSubmodule = {
152
+ name: MODULE_NAME,
153
+ getBidRequestData: function (reqBidsConfigObj, callback, customConfig) {
154
+ try {
155
+ const moduleConfig = getMergedConfig(customConfig)
156
+ if (moduleConfig.waitForIt) {
157
+ processBrandmetricsEvents(reqBidsConfigObj, moduleConfig, callback)
158
+ } else {
159
+ callback()
160
+ }
161
+ } catch (e) {
162
+ logError(e)
163
+ }
164
+ },
165
+ init: init
166
+ }
167
+
168
+ submodule('realTimeData', brandmetricsSubmodule)
@@ -0,0 +1,40 @@
1
+ # Brandmetrics Real-time Data Submodule
2
+ This module is intended to be used by brandmetrics (https://brandmetrics.com) partners and sets targeting keywords to bids if the browser is eligeble to see a brandmetrics survey.
3
+ The module hooks in to brandmetrics events and requires a brandmetrics script to be running. The module can optionally load and initialize brandmetrics by providing the 'scriptId'- parameter.
4
+
5
+ ## Usage
6
+ Compile the Brandmetrics RTD module into your Prebid build:
7
+ ```
8
+ gulp build --modules=rtdModule,brandmetricsRtdProvider
9
+ ```
10
+
11
+ > Note that the global RTD module, `rtdModule`, is a prerequisite of the Brandmetrics RTD module.
12
+
13
+ Enable the Brandmetrics RTD in your Prebid configuration, using the below format:
14
+
15
+ ```javascript
16
+ pbjs.setConfig({
17
+ ...,
18
+ realTimeData: {
19
+ auctionDelay: 500, // auction delay
20
+ dataProviders: [{
21
+ name: 'brandmetrics',
22
+ waitForIt: true // should be true if there's an `auctionDelay`,
23
+ params: {
24
+ scriptId: '00000000-0000-0000-0000-000000000000',
25
+ bidders: ['ozone']
26
+ }
27
+ }]
28
+ },
29
+ ...
30
+ })
31
+ ```
32
+
33
+ ## Parameters
34
+ | Name | Type | Description | Default |
35
+ | ----------------- | -------------------- | ------------------ | ------------------ |
36
+ | name | String | This should always be `brandmetrics` | - |
37
+ | waitForIt | Boolean | Should be `true` if there's an `auctionDelay` defined (recommended) | `false` |
38
+ | params | Object | | - |
39
+ | params.bidders | String[] | An array of bidders which should receive targeting keys. | `[]` |
40
+ | params.scriptId | String | A script- id GUID if the brandmetrics- script should be initialized. | `undefined` |
@@ -2,6 +2,7 @@ import { logWarn, isStr, deepAccess, isArray, getBidIdParameter, deepSetValue, i
2
2
  import {registerBidder} from '../src/adapters/bidderFactory.js';
3
3
  import {BANNER, VIDEO} from '../src/mediaTypes.js';
4
4
  import {getStorageManager} from '../src/storageManager.js';
5
+ import { config } from '../src/config.js';
5
6
 
6
7
  const GVLID = 24;
7
8
  export const storage = getStorageManager(GVLID);
@@ -76,6 +77,9 @@ export const spec = {
76
77
  displaymanager: 'Prebid.js',
77
78
  displaymanagerver: '$prebid.version$'
78
79
  };
80
+ if (bid.ortb2Imp) {
81
+ mergeDeep(imp, bid.ortb2Imp);
82
+ }
79
83
 
80
84
  copyOptProperty(bid.params.tag_id, imp, 'tagid');
81
85
 
@@ -167,6 +171,9 @@ export const spec = {
167
171
  payload.user = {ext: userExt};
168
172
  }
169
173
 
174
+ const firstPartyData = config.getConfig('ortb2') || {};
175
+ mergeDeep(payload, firstPartyData);
176
+
170
177
  return {
171
178
  method: 'POST',
172
179
  url: bidurl,
@@ -281,6 +281,7 @@ function checkNativeSendId(bidRequest) {
281
281
  */
282
282
  function buildCdbRequest(context, bidRequests, bidderRequest) {
283
283
  let networkId;
284
+ let schain;
284
285
  const request = {
285
286
  publisher: {
286
287
  url: context.url,
@@ -288,6 +289,7 @@ function buildCdbRequest(context, bidRequests, bidderRequest) {
288
289
  },
289
290
  slots: bidRequests.map(bidRequest => {
290
291
  networkId = bidRequest.params.networkId || networkId;
292
+ schain = bidRequest.schain || schain;
291
293
  const slot = {
292
294
  impid: bidRequest.adUnitCode,
293
295
  transactionid: bidRequest.transactionId,
@@ -344,6 +346,13 @@ function buildCdbRequest(context, bidRequests, bidderRequest) {
344
346
  if (networkId) {
345
347
  request.publisher.networkid = networkId;
346
348
  }
349
+ if (schain) {
350
+ request.source = {
351
+ ext: {
352
+ schain: schain
353
+ }
354
+ }
355
+ };
347
356
  request.user = {
348
357
  ext: bidderRequest.userExt
349
358
  };
@@ -20,6 +20,25 @@ export var currencyRates = {};
20
20
  var bidderCurrencyDefault = {};
21
21
  var defaultRates;
22
22
 
23
+ export const ready = (() => {
24
+ let isDone, resolver, promise;
25
+ function reset() {
26
+ isDone = false;
27
+ resolver = null;
28
+ promise = new Promise((resolve) => {
29
+ resolver = resolve;
30
+ if (isDone) resolve();
31
+ })
32
+ }
33
+ function done() {
34
+ isDone = true;
35
+ if (resolver != null) { resolver() }
36
+ }
37
+ reset();
38
+
39
+ return {done, reset, promise: () => promise}
40
+ })();
41
+
23
42
  /**
24
43
  * Configuration function for currency
25
44
  * @param {string} [config.adServerCurrency = 'USD']
@@ -138,11 +157,15 @@ function initCurrency(url) {
138
157
  logInfo('currencyRates set to ' + JSON.stringify(currencyRates));
139
158
  currencyRatesLoaded = true;
140
159
  processBidResponseQueue();
160
+ ready.done();
141
161
  } catch (e) {
142
162
  errorSettingsRates('Failed to parse currencyRates response: ' + response);
143
163
  }
144
164
  },
145
- error: errorSettingsRates
165
+ error: function (...args) {
166
+ errorSettingsRates(...args);
167
+ ready.done();
168
+ }
146
169
  }
147
170
  );
148
171
  }
@@ -197,6 +220,8 @@ export function addBidResponseHook(fn, adUnitCode, bid) {
197
220
  bidResponseQueue.push(wrapFunction(fn, this, [adUnitCode, bid]));
198
221
  if (!currencySupportEnabled || currencyRatesLoaded) {
199
222
  processBidResponseQueue();
223
+ } else {
224
+ fn.bail(ready.promise());
200
225
  }
201
226
  }
202
227
 
@@ -219,10 +244,7 @@ function wrapFunction(fn, context, params) {
219
244
  }
220
245
  } catch (e) {
221
246
  logWarn('Returning NO_BID, getCurrencyConversion threw error: ', e);
222
- params[1] = createBid(CONSTANTS.STATUS.NO_BID, {
223
- bidder: bid.bidderCode || bid.bidder,
224
- bidId: bid.requestId
225
- });
247
+ params[1] = createBid(CONSTANTS.STATUS.NO_BID, bid.getIdentifiers());
226
248
  }
227
249
  }
228
250
  return fn.apply(context, params);