prebid.js 7.48.0 → 7.50.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 (219) 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/beopBidAdapter.js +1 -1
  21. package/dist/bidglassBidAdapter.js +1 -1
  22. package/dist/big-richmediaBidAdapter.js +1 -1
  23. package/dist/bridgewellBidAdapter.js +1 -1
  24. package/dist/brightMountainMediaBidAdapter.js +1 -1
  25. package/dist/carodaBidAdapter.js +1 -1
  26. package/dist/chtnwBidAdapter.js +1 -1
  27. package/dist/concertBidAdapter.js +1 -1
  28. package/dist/confiantRtdProvider.js +1 -1
  29. package/dist/connectadBidAdapter.js +1 -1
  30. package/dist/consumableBidAdapter.js +1 -1
  31. package/dist/conversantAnalyticsAdapter.js +1 -1
  32. package/dist/conversantBidAdapter.js +1 -1
  33. package/dist/craftBidAdapter.js +1 -1
  34. package/dist/criteoBidAdapter.js +1 -1
  35. package/dist/cwireBidAdapter.js +1 -1
  36. package/dist/dependencies.json +3 -0
  37. package/dist/dspxBidAdapter.js +1 -1
  38. package/dist/eplanningBidAdapter.js +1 -1
  39. package/dist/feedadBidAdapter.js +1 -1
  40. package/dist/finativeBidAdapter.js +1 -1
  41. package/dist/freewheel-sspBidAdapter.js +1 -1
  42. package/dist/glimpseBidAdapter.js +1 -1
  43. package/dist/gmosspBidAdapter.js +1 -1
  44. package/dist/goldbachBidAdapter.js +1 -1
  45. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  46. package/dist/greenbidsRtdProvider.js +1 -1
  47. package/dist/gridBidAdapter.js +1 -1
  48. package/dist/gumgumBidAdapter.js +1 -1
  49. package/dist/h12mediaBidAdapter.js +1 -1
  50. package/dist/id5IdSystem.js +1 -1
  51. package/dist/improvedigitalBidAdapter.js +1 -1
  52. package/dist/inmarBidAdapter.js +1 -1
  53. package/dist/insticatorBidAdapter.js +1 -1
  54. package/dist/ixBidAdapter.js +1 -1
  55. package/dist/justpremiumBidAdapter.js +1 -1
  56. package/dist/kargoBidAdapter.js +1 -1
  57. package/dist/konduitAnalyticsAdapter.js +1 -1
  58. package/dist/kueezBidAdapter.js +1 -1
  59. package/dist/kueezRtbBidAdapter.js +1 -1
  60. package/dist/kulturemediaBidAdapter.js +1 -1
  61. package/dist/lassoBidAdapter.js +1 -1
  62. package/dist/lifestreetBidAdapter.js +1 -1
  63. package/dist/liveIntentIdSystem.js +1 -1
  64. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  65. package/dist/logicadBidAdapter.js +1 -1
  66. package/dist/loglyliftBidAdapter.js +1 -1
  67. package/dist/magniteAnalyticsAdapter.js +1 -1
  68. package/dist/malltvAnalyticsAdapter.js +1 -1
  69. package/dist/marsmediaBidAdapter.js +1 -1
  70. package/dist/mediafuseBidAdapter.js +1 -1
  71. package/dist/mediasquareBidAdapter.js +1 -1
  72. package/dist/mgidBidAdapter.js +1 -1
  73. package/dist/minutemediaBidAdapter.js +1 -1
  74. package/dist/minutemediaplusBidAdapter.js +1 -1
  75. package/dist/nexx360BidAdapter.js +1 -1
  76. package/dist/not-for-prod/prebid.js +136 -134
  77. package/dist/oguryBidAdapter.js +1 -1
  78. package/dist/onetagBidAdapter.js +1 -1
  79. package/dist/ooloAnalyticsAdapter.js +1 -1
  80. package/dist/optidigitalBidAdapter.js +1 -1
  81. package/dist/outbrainBidAdapter.js +1 -1
  82. package/dist/parrableIdSystem.js +1 -1
  83. package/dist/permutiveRtdProvider.js +1 -1
  84. package/dist/pixfutureBidAdapter.js +1 -1
  85. package/dist/prebid-core.js +1 -1
  86. package/dist/prebidServerBidAdapter.js +1 -1
  87. package/dist/publinkIdSystem.js +1 -1
  88. package/dist/pubmaticAnalyticsAdapter.js +1 -1
  89. package/dist/pubmaticBidAdapter.js +1 -1
  90. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  91. package/dist/pxyzBidAdapter.js +1 -1
  92. package/dist/quantcastBidAdapter.js +1 -1
  93. package/dist/readpeakBidAdapter.js +1 -1
  94. package/dist/relaidoBidAdapter.js +1 -1
  95. package/dist/retailspotBidAdapter.js +1 -0
  96. package/dist/rhythmoneBidAdapter.js +1 -1
  97. package/dist/riseBidAdapter.js +1 -1
  98. package/dist/rubiconAnalyticsAdapter.js +1 -1
  99. package/dist/rubiconBidAdapter.js +1 -1
  100. package/dist/seedingAllianceBidAdapter.js +1 -1
  101. package/dist/seedtagBidAdapter.js +1 -1
  102. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  103. package/dist/sharethroughBidAdapter.js +1 -1
  104. package/dist/shinezBidAdapter.js +1 -1
  105. package/dist/silverpushBidAdapter.js +1 -0
  106. package/dist/smaatoBidAdapter.js +1 -1
  107. package/dist/smartadserverBidAdapter.js +1 -1
  108. package/dist/smartxBidAdapter.js +1 -1
  109. package/dist/smilewantedBidAdapter.js +1 -1
  110. package/dist/sonobiBidAdapter.js +1 -1
  111. package/dist/sovrnAnalyticsAdapter.js +1 -1
  112. package/dist/sovrnBidAdapter.js +1 -1
  113. package/dist/sspBCBidAdapter.js +1 -1
  114. package/dist/stvBidAdapter.js +1 -1
  115. package/dist/sublimeBidAdapter.js +1 -1
  116. package/dist/synacormediaBidAdapter.js +1 -1
  117. package/dist/targetVideoBidAdapter.js +1 -1
  118. package/dist/teadsBidAdapter.js +1 -1
  119. package/dist/trionBidAdapter.js +1 -1
  120. package/dist/tripleliftBidAdapter.js +1 -1
  121. package/dist/ttdBidAdapter.js +1 -1
  122. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  123. package/dist/uid2IdSystem.js +1 -1
  124. package/dist/underdogmediaBidAdapter.js +1 -1
  125. package/dist/undertoneBidAdapter.js +1 -1
  126. package/dist/vidazooBidAdapter.js +1 -1
  127. package/dist/video.js +1 -1
  128. package/dist/videoModule.js +1 -1
  129. package/dist/videobyteBidAdapter.js +1 -1
  130. package/dist/visxBidAdapter.js +1 -1
  131. package/dist/vuukleBidAdapter.js +1 -1
  132. package/dist/widespaceBidAdapter.js +1 -1
  133. package/dist/winrBidAdapter.js +1 -1
  134. package/dist/yahoosspBidAdapter.js +1 -1
  135. package/dist/yieldlabBidAdapter.js +1 -1
  136. package/dist/yieldmoBidAdapter.js +1 -1
  137. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  138. package/integrationExamples/videoModule/eventsUI/eventsUI.css +205 -0
  139. package/integrationExamples/videoModule/eventsUI/eventsUI.js +181 -0
  140. package/integrationExamples/videoModule/jwplayer/eventsUI.html +295 -0
  141. package/integrationExamples/videoModule/videojs/eventsUI.html +319 -0
  142. package/libraries/video/shared/helpers.js +14 -0
  143. package/modules/33acrossBidAdapter.js +1 -1
  144. package/modules/adgenerationBidAdapter.js +24 -15
  145. package/modules/admixerBidAdapter.js +15 -9
  146. package/modules/aidemBidAdapter.js +3 -1
  147. package/modules/appnexusBidAdapter.js +1 -0
  148. package/modules/beopBidAdapter.js +1 -0
  149. package/modules/confiantRtdProvider.js +15 -12
  150. package/modules/conversantAnalyticsAdapter.js +7 -5
  151. package/modules/conversantBidAdapter.js +1 -1
  152. package/modules/criteoBidAdapter.js +17 -1
  153. package/modules/gridBidAdapter.js +3 -0
  154. package/modules/ixBidAdapter.js +65 -47
  155. package/modules/kueezRtbBidAdapter.js +30 -33
  156. package/modules/liveIntentIdSystem.js +8 -4
  157. package/modules/magniteAnalyticsAdapter.js +26 -3
  158. package/modules/mgidBidAdapter.js +9 -8
  159. package/modules/minutemediaBidAdapter.js +6 -0
  160. package/modules/minutemediaplusBidAdapter.js +30 -32
  161. package/modules/nexx360BidAdapter.js +2 -1
  162. package/modules/permutiveRtdProvider.js +9 -38
  163. package/modules/prebidServerBidAdapter/index.js +1 -3
  164. package/modules/prebidServerBidAdapter/ortbConverter.js +5 -1
  165. package/modules/pubmaticAnalyticsAdapter.js +3 -2
  166. package/modules/retailspotBidAdapter .md +32 -0
  167. package/modules/retailspotBidAdapter.js +186 -0
  168. package/modules/riseBidAdapter.js +6 -0
  169. package/modules/rubiconBidAdapter.js +6 -2
  170. package/modules/silverpushBidAdapter.js +326 -0
  171. package/modules/silverpushBidAdapter.md +107 -0
  172. package/modules/ttdBidAdapter.js +23 -22
  173. package/modules/underdogmediaBidAdapter.js +2 -2
  174. package/modules/vidazooBidAdapter.js +28 -32
  175. package/modules/videoModule/adQueue.js +2 -2
  176. package/modules/videoModule/index.js +9 -5
  177. package/modules/yahoosspBidAdapter.js +6 -0
  178. package/modules/yahoosspBidAdapter.md +37 -0
  179. package/modules/yieldlabBidAdapter.js +27 -5
  180. package/package.json +1 -1
  181. package/src/adapterManager.js +4 -0
  182. package/src/adapters/bidderFactory.js +1 -0
  183. package/src/auction.js +2 -0
  184. package/src/prebid.js +36 -12
  185. package/src/utils/cpm.js +4 -1
  186. package/test/spec/modules/33acrossBidAdapter_spec.js +4 -3
  187. package/test/spec/modules/adgenerationBidAdapter_spec.js +6 -6
  188. package/test/spec/modules/admixerBidAdapter_spec.js +64 -25
  189. package/test/spec/modules/aidemBidAdapter_spec.js +3 -0
  190. package/test/spec/modules/beopBidAdapter_spec.js +4 -0
  191. package/test/spec/modules/confiantRtdProvider_spec.js +4 -1
  192. package/test/spec/modules/conversantBidAdapter_spec.js +2 -1
  193. package/test/spec/modules/criteoBidAdapter_spec.js +109 -0
  194. package/test/spec/modules/gridBidAdapter_spec.js +3 -0
  195. package/test/spec/modules/ixBidAdapter_spec.js +66 -1
  196. package/test/spec/modules/kueezRtbBidAdapter_spec.js +3 -2
  197. package/test/spec/modules/liveIntentIdMinimalSystem_spec.js +28 -0
  198. package/test/spec/modules/liveIntentIdSystem_spec.js +45 -0
  199. package/test/spec/modules/magniteAnalyticsAdapter_spec.js +16 -36
  200. package/test/spec/modules/mass_spec.js +2 -0
  201. package/test/spec/modules/mgidBidAdapter_spec.js +9 -9
  202. package/test/spec/modules/minutemediaBidAdapter_spec.js +18 -0
  203. package/test/spec/modules/minutemediaplusBidAdapter_spec.js +3 -2
  204. package/test/spec/modules/permutiveRtdProvider_spec.js +0 -20
  205. package/test/spec/modules/prebidServerBidAdapter_spec.js +96 -1
  206. package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +6 -1
  207. package/test/spec/modules/retailspotBidAdapter_spec.js +426 -0
  208. package/test/spec/modules/riseBidAdapter_spec.js +18 -0
  209. package/test/spec/modules/rubiconBidAdapter_spec.js +143 -67
  210. package/test/spec/modules/silverpushBidAdapter_spec.js +394 -0
  211. package/test/spec/modules/ttdBidAdapter_spec.js +129 -2
  212. package/test/spec/modules/underdogmediaBidAdapter_spec.js +1 -1
  213. package/test/spec/modules/vidazooBidAdapter_spec.js +3 -2
  214. package/test/spec/modules/videoModule/shared/helpers_spec.js +22 -0
  215. package/test/spec/modules/yahoosspBidAdapter_spec.js +60 -1
  216. package/test/spec/modules/yieldlabBidAdapter_spec.js +8 -1
  217. package/test/spec/unit/core/bidderFactory_spec.js +9 -9
  218. package/test/spec/unit/pbjs_api_spec.js +59 -1
  219. package/test/spec/unit/utils/cpm_spec.js +56 -1
@@ -635,7 +635,8 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
635
635
  r = applyRegulations(r, bidderRequest);
636
636
 
637
637
  let payload = {};
638
- createPayload(validBidRequests, bidderRequest, r, baseUrl, requests, payload);
638
+ siteID = validBidRequests[0].params.siteId;
639
+ payload.s = siteID;
639
640
 
640
641
  const transactionIds = Object.keys(impressions);
641
642
  let isFpdAdded = false;
@@ -649,15 +650,13 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
649
650
 
650
651
  const fpd = deepAccess(bidderRequest, 'ortb2') || {};
651
652
  const site = { ...(fpd.site || fpd.context) };
653
+
654
+ // update page URL with IX FPD KVs if they exist
655
+ site.page = getIxFirstPartyDataPageUrl(bidderRequest);
656
+
652
657
  const user = { ...fpd.user };
653
658
  if (!isEmpty(fpd) && !isFpdAdded) {
654
659
  r = addFPD(bidderRequest, r, fpd, site, user);
655
-
656
- const clonedRObject = deepClone(r);
657
-
658
- clonedRObject.site = mergeDeep({}, clonedRObject.site, site);
659
- clonedRObject.user = mergeDeep({}, clonedRObject.user, user);
660
-
661
660
  r.site = mergeDeep({}, r.site, site);
662
661
  r.user = mergeDeep({}, r.user, user);
663
662
  isFpdAdded = true;
@@ -856,46 +855,6 @@ function applyRegulations(r, bidderRequest) {
856
855
  return r
857
856
  }
858
857
 
859
- /**
860
- * createPayload creates the payload to be sent with the request.
861
- *
862
- * @param {array} validBidRequests A list of valid bid request config objects.
863
- * @param {object} bidderRequest An object containing other info like gdprConsent.
864
- * @param {object} r Reuqest object.
865
- * @param {string} baseUrl Base exchagne URL.
866
- * @param {array} requests List of request obejcts.
867
- * @param {object} payload Request payload object.
868
- */
869
- function createPayload(validBidRequests, bidderRequest, r, baseUrl, requests, payload) {
870
- // Use the siteId in the first bid request as the main siteId.
871
- siteID = validBidRequests[0].params.siteId;
872
- payload.s = siteID;
873
-
874
- // Parse additional runtime configs.
875
- const bidderCode = (bidderRequest && bidderRequest.bidderCode) || 'ix';
876
- const otherIxConfig = config.getConfig(bidderCode);
877
-
878
- if (otherIxConfig) {
879
- // Append firstPartyData to r.site.page if firstPartyData exists.
880
- if (typeof otherIxConfig.firstPartyData === 'object') {
881
- const firstPartyData = otherIxConfig.firstPartyData;
882
- let firstPartyString = '?';
883
- for (const key in firstPartyData) {
884
- if (firstPartyData.hasOwnProperty(key)) {
885
- firstPartyString += `${encodeURIComponent(key)}=${encodeURIComponent(firstPartyData[key])}&`;
886
- }
887
- }
888
- firstPartyString = firstPartyString.slice(0, -1);
889
-
890
- if ('page' in r.site) {
891
- r.site.page += firstPartyString;
892
- } else {
893
- r.site.page = firstPartyString;
894
- }
895
- }
896
- }
897
- }
898
-
899
858
  /**
900
859
  * addImpressions adds impressions to request object
901
860
  *
@@ -977,6 +936,65 @@ function addImpressions(impressions, transactionIds, r, adUnitIndex) {
977
936
  return r;
978
937
  }
979
938
 
939
+ /**
940
+ This function retrieves the page URL and appends first party data query parameters
941
+ to it without adding duplicate query parameters. Returns original referer URL if no IX FPD exists.
942
+ @param {Object} bidderRequest - The bidder request object containing information about the bid and the page.
943
+ @returns {string} - The modified page URL with first party data query parameters appended.
944
+ */
945
+ function getIxFirstPartyDataPageUrl (bidderRequest) {
946
+ // Parse additional runtime configs.
947
+ const bidderCode = (bidderRequest && bidderRequest.bidderCode) || 'ix';
948
+ const otherIxConfig = config.getConfig(bidderCode);
949
+
950
+ let pageUrl = '';
951
+ if (deepAccess(bidderRequest, 'ortb2.site.page')) {
952
+ pageUrl = bidderRequest.ortb2.site.page;
953
+ } else {
954
+ pageUrl = deepAccess(bidderRequest, 'refererInfo.page');
955
+ }
956
+
957
+ if (otherIxConfig) {
958
+ // Append firstPartyData to r.site.page if firstPartyData exists.
959
+ if (typeof otherIxConfig.firstPartyData === 'object') {
960
+ const firstPartyData = otherIxConfig.firstPartyData;
961
+ return appendIXQueryParams(bidderRequest, pageUrl, firstPartyData);
962
+ }
963
+ }
964
+
965
+ return pageUrl
966
+ }
967
+
968
+ /**
969
+ This function appends the provided query parameters to the given URL without adding duplicate query parameters.
970
+ @param {Object} bidderRequest - The bidder request object containing information about the bid and the page to be used as fallback in case url is not valid.
971
+ @param {string} url - The base URL to which query parameters will be appended.
972
+ @param {Object} params - An object containing key-value pairs of query parameters to append.
973
+ @returns {string} - The modified URL with the provided query parameters appended.
974
+ */
975
+ function appendIXQueryParams(bidderRequest, url, params) {
976
+ let urlObj;
977
+ try {
978
+ urlObj = new URL(url);
979
+ } catch (error) {
980
+ logWarn(`IX Bid Adapter: Invalid URL set in ortb2.site.page: ${url}. Using referer URL instead.`);
981
+ urlObj = new URL(deepAccess(bidderRequest, 'refererInfo.page'));
982
+ }
983
+
984
+ const searchParams = new URLSearchParams(urlObj.search);
985
+
986
+ // Loop through the provided query parameters and append them
987
+ for (const [key, value] of Object.entries(params)) {
988
+ if (!searchParams.has(key)) {
989
+ searchParams.append(key, value);
990
+ }
991
+ }
992
+
993
+ // Construct the final URL with the updated query parameters
994
+ urlObj.search = searchParams.toString();
995
+ return urlObj.toString();
996
+ }
997
+
980
998
  /**
981
999
  * addFPD adds ortb2 first party data to request object.
982
1000
  *
@@ -2,7 +2,7 @@ import {_each, deepAccess, parseSizesInput, parseUrl, uniques, isFn} from '../sr
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
+ import {config} from '../src/config.js';
6
6
 
7
7
  const GVLID = 1165;
8
8
  const DEFAULT_SUB_DOMAIN = 'exchange';
@@ -11,18 +11,6 @@ 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
- };
26
14
  const storage = getStorageManager({bidderCode: BIDDER_CODE});
27
15
 
28
16
  function getTopWindowQueryParams() {
@@ -161,25 +149,23 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) {
161
149
  function appendUserIdsToRequestPayload(payloadRef, userIds) {
162
150
  let key;
163
151
  _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
- }
152
+ key = `uid.${idSystemProviderName}`;
153
+
154
+ switch (idSystemProviderName) {
155
+ case 'digitrustid':
156
+ payloadRef[key] = deepAccess(userId, 'data.id');
157
+ break;
158
+ case 'lipb':
159
+ payloadRef[key] = userId.lipbid;
160
+ break;
161
+ case 'parrableId':
162
+ payloadRef[key] = userId.eid;
163
+ break;
164
+ case 'id5id':
165
+ payloadRef[key] = userId.uid;
166
+ break;
167
+ default:
168
+ payloadRef[key] = userId;
183
169
  }
184
170
  });
185
171
  }
@@ -207,7 +193,18 @@ function interpretResponse(serverResponse, request) {
207
193
 
208
194
  try {
209
195
  results.forEach(result => {
210
- const {creativeId, ad, price, exp, width, height, currency, metaData, advertiserDomains, mediaType = BANNER} = result;
196
+ const {
197
+ creativeId,
198
+ ad,
199
+ price,
200
+ exp,
201
+ width,
202
+ height,
203
+ currency,
204
+ metaData,
205
+ advertiserDomains,
206
+ mediaType = BANNER
207
+ } = result;
211
208
  if (!ad || !price) {
212
209
  return;
213
210
  }
@@ -92,21 +92,25 @@ function initializeLiveConnect(configParams) {
92
92
 
93
93
  const publisherId = configParams.publisherId || 'any';
94
94
  const identityResolutionConfig = {
95
- source: 'prebid',
96
95
  publisherId: publisherId,
97
96
  requestedAttributes: parseRequestedAttributes(configParams.requestedAttributesOverrides)
98
97
  };
99
98
  if (configParams.url) {
100
99
  identityResolutionConfig.url = configParams.url
101
100
  }
102
- if (configParams.partner) {
103
- identityResolutionConfig.source = configParams.partner
104
- }
105
101
  if (configParams.ajaxTimeout) {
106
102
  identityResolutionConfig.ajaxTimeout = configParams.ajaxTimeout;
107
103
  }
108
104
 
109
105
  const liveConnectConfig = parseLiveIntentCollectorConfig(configParams.liCollectConfig);
106
+
107
+ if (!liveConnectConfig.appId && configParams.distributorId) {
108
+ liveConnectConfig.distributorId = configParams.distributorId;
109
+ identityResolutionConfig.source = configParams.distributorId;
110
+ } else {
111
+ identityResolutionConfig.source = configParams.partner || 'prebid'
112
+ }
113
+
110
114
  liveConnectConfig.wrapperName = 'prebid';
111
115
  liveConnectConfig.identityResolutionConfig = identityResolutionConfig;
112
116
  liveConnectConfig.identifiersToResolve = configParams.identifiersToResolve || [];
@@ -702,6 +702,25 @@ magniteAdapter.onDataDeletionRequest = function () {
702
702
  magniteAdapter.MODULE_INITIALIZED_TIME = Date.now();
703
703
  magniteAdapter.referrerHostname = '';
704
704
 
705
+ const getLatencies = (args, auctionStart) => {
706
+ try {
707
+ const metrics = args.metrics.getMetrics();
708
+ const src = args.src || args.source;
709
+ return {
710
+ total: parseInt(metrics[`adapter.${src}.total`]),
711
+ // If it is array, get slowest
712
+ net: parseInt(Array.isArray(metrics[`adapter.${src}.net`]) ? metrics[`adapter.${src}.net`][metrics[`adapter.${src}.net`].length - 1] : metrics[`adapter.${src}.net`])
713
+ }
714
+ } catch (error) {
715
+ // default to old way if not able to get better ones
716
+ const latency = Date.now() - auctionStart;
717
+ return {
718
+ total: latency,
719
+ net: latency
720
+ }
721
+ }
722
+ }
723
+
705
724
  let browser;
706
725
  magniteAdapter.track = ({ eventType, args }) => {
707
726
  switch (eventType) {
@@ -872,7 +891,9 @@ magniteAdapter.track = ({ eventType, args }) => {
872
891
  code: 'request-error'
873
892
  };
874
893
  }
875
- bid.clientLatencyMillis = args.timeToRespond || Date.now() - cache.auctions[args.auctionId].auction.auctionStart;
894
+ const latencies = getLatencies(args, auctionEntry.auctionStart);
895
+ bid.clientLatencyMillis = latencies.total;
896
+ bid.httpLatencyMillis = latencies.net;
876
897
  bid.bidResponse = parseBidResponse(args, bid.bidResponse);
877
898
 
878
899
  // if pbs gave us back a bidId, we need to use it and update our bidId to PBA
@@ -904,8 +925,10 @@ magniteAdapter.track = ({ eventType, args }) => {
904
925
  }
905
926
 
906
927
  // set client latency if not done yet
907
- if (!cachedBid.clientLatencyMillis) {
908
- cachedBid.clientLatencyMillis = Date.now() - cache.auctions[args.auctionId].auction.auctionStart;
928
+ if (!cachedBid.clientLatencyMillis || !cachedBid.httpLatencyMillis) {
929
+ const latencies = getLatencies(bid, deepAccess(cache, `auctions.${args.auctionId}.auction.auctionStart`));
930
+ cachedBid.clientLatencyMillis = cachedBid.clientLatencyMillis || latencies.total;
931
+ cachedBid.httpLatencyMillis = cachedBid.httpLatencyMillis || latencies.net;
909
932
  }
910
933
  });
911
934
  break;
@@ -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({
@@ -201,6 +201,12 @@ function updateOrtbConfig(bidder, currConfig, segmentIDs, sspSegmentIDs, transfo
201
201
  logger.logInfo(`Extending ortb2.user.ext.data with "${PERMUTIVE_CUSTOM_COHORTS_KEYWORD}"`, customCohortsData)
202
202
  }
203
203
 
204
+ // Set site extensions
205
+ if (segmentIDs.length > 0) {
206
+ deepSetValue(ortbConfig, `ortb2.site.ext.permutive.${PERMUTIVE_STANDARD_KEYWORD}`, segmentIDs)
207
+ logger.logInfo(`Extending ortb2.site.ext.permutive with "${PERMUTIVE_STANDARD_KEYWORD}"`, segmentIDs)
208
+ }
209
+
204
210
  logger.logInfo(`Updated ortb2 config`, { bidder, config: ortbConfig })
205
211
  return ortbConfig
206
212
  }
@@ -230,12 +236,11 @@ function setSegments (reqBidsConfigObj, moduleConfig, segmentData) {
230
236
  }
231
237
  const acEnabled = isAcEnabled(moduleConfig, bidder)
232
238
  const customFn = getCustomBidderFn(moduleConfig, bidder)
233
- const defaultFn = getDefaultBidderFn(bidder)
234
239
 
235
240
  if (customFn) {
236
- customFn(bid, segmentData, acEnabled, utils, defaultFn)
237
- } else if (defaultFn) {
238
- defaultFn(bid, segmentData, acEnabled)
241
+ // For backwards compatibility we pass an identity function to any custom bidder function set by a publisher
242
+ const bidIdentity = (bid) => bid
243
+ customFn(bid, segmentData, acEnabled, utils, bidIdentity)
239
244
  }
240
245
  })
241
246
  })
@@ -263,40 +268,6 @@ function getCustomBidderFn (moduleConfig, bidder) {
263
268
  }
264
269
  }
265
270
 
266
- /**
267
- * Returns a function that receives a `bid` object, a `data` object and a `acEnabled` boolean
268
- * and which will set the right segment targeting keys for `bid` based on `data` and `acEnabled`
269
- * @param {string} bidder - Bidder name
270
- * @return {Object} Bidder function
271
- */
272
- function getDefaultBidderFn (bidder) {
273
- const isPStandardTargetingEnabled = (data, acEnabled) => {
274
- return (acEnabled && data.ac && data.ac.length) || (data.ssp && data.ssp.cohorts && data.ssp.cohorts.length)
275
- }
276
- const pStandardTargeting = (data, acEnabled) => {
277
- const ac = (acEnabled) ? (data.ac ?? []) : []
278
- const ssp = data?.ssp?.cohorts ?? []
279
- return [...new Set([...ac, ...ssp])]
280
- }
281
- const bidderMap = {
282
- ozone: function (bid, data, acEnabled) {
283
- if (isPStandardTargetingEnabled(data, acEnabled)) {
284
- const segments = pStandardTargeting(data, acEnabled)
285
- deepSetValue(bid, 'params.customData.0.targeting.p_standard', segments)
286
- }
287
-
288
- return bid
289
- }
290
- }
291
-
292
- // On no default bidder just return the same bid as passed in
293
- function bidIdentity(bid) {
294
- return bid
295
- }
296
-
297
- return bidderMap[bidder] || bidIdentity
298
- }
299
-
300
271
  /**
301
272
  * Check whether ac is enabled for bidder
302
273
  * @param {Object} moduleConfig - Module configuration
@@ -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
+ ```