prebid.js 9.5.0 → 9.6.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 (197) hide show
  1. package/dist/33acrossAnalyticsAdapter.js +1 -1
  2. package/dist/33acrossBidAdapter.js +1 -1
  3. package/dist/33acrossIdSystem.js +1 -1
  4. package/dist/BTBidAdapter.js +1 -1
  5. package/dist/adagioAnalyticsAdapter.js +1 -1
  6. package/dist/adagioBidAdapter.js +1 -1
  7. package/dist/adagioUtils.js +1 -1
  8. package/dist/addefendBidAdapter.js +1 -1
  9. package/dist/adgenerationBidAdapter.js +1 -1
  10. package/dist/adkernelBidAdapter.js +1 -1
  11. package/dist/adlooxRtdProvider.js +1 -1
  12. package/dist/adqueryBidAdapter.js +1 -1
  13. package/dist/adrelevantisBidAdapter.js +1 -1
  14. package/dist/adstirBidAdapter.js +1 -1
  15. package/dist/adtrgtmeBidAdapter.js +1 -1
  16. package/dist/adxcgAnalyticsAdapter.js +1 -1
  17. package/dist/adxcgBidAdapter.js +1 -1
  18. package/dist/adyoulikeBidAdapter.js +1 -1
  19. package/dist/agmaAnalyticsAdapter.js +1 -1
  20. package/dist/aidemBidAdapter.js +1 -1
  21. package/dist/ajaBidAdapter.js +1 -1
  22. package/dist/amxBidAdapter.js +1 -1
  23. package/dist/amxIdSystem.js +1 -1
  24. package/dist/appierAnalyticsAdapter.js +1 -1
  25. package/dist/appnexusBidAdapter.js +1 -1
  26. package/dist/asoBidAdapter.js +1 -1
  27. package/dist/axonixBidAdapter.js +1 -1
  28. package/dist/bidglassBidAdapter.js +1 -1
  29. package/dist/big-richmediaBidAdapter.js +1 -1
  30. package/dist/bridBidAdapter.js +1 -1
  31. package/dist/bridgewellBidAdapter.js +1 -1
  32. package/dist/brightMountainMediaBidAdapter.js +1 -1
  33. package/dist/carodaBidAdapter.js +1 -1
  34. package/dist/chtnwBidAdapter.js +1 -1
  35. package/dist/chunk-core.js +1 -1
  36. package/dist/concertBidAdapter.js +1 -1
  37. package/dist/connectIdSystem.js +1 -1
  38. package/dist/connectadBidAdapter.js +1 -1
  39. package/dist/consumableBidAdapter.js +1 -1
  40. package/dist/conversantAnalyticsAdapter.js +1 -1
  41. package/dist/conversantBidAdapter.js +1 -1
  42. package/dist/craftBidAdapter.js +1 -1
  43. package/dist/criteoBidAdapter.js +1 -1
  44. package/dist/cwireBidAdapter.js +1 -1
  45. package/dist/dailymotionBidAdapter.js +1 -1
  46. package/dist/dependencies.json +26 -1
  47. package/dist/dspxBidAdapter.js +1 -1
  48. package/dist/dxkultureBidAdapter.js +1 -1
  49. package/dist/eplanningBidAdapter.js +1 -1
  50. package/dist/euidIdSystem.js +1 -1
  51. package/dist/exadsBidAdapter.js +1 -1
  52. package/dist/feedadBidAdapter.js +1 -1
  53. package/dist/finativeBidAdapter.js +1 -1
  54. package/dist/freewheel-sspBidAdapter.js +1 -1
  55. package/dist/gmosspBidAdapter.js +1 -1
  56. package/dist/goldbachBidAdapter.js +1 -1
  57. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  58. package/dist/greenbidsRtdProvider.js +1 -1
  59. package/dist/gridBidAdapter.js +1 -1
  60. package/dist/gumgumBidAdapter.js +1 -1
  61. package/dist/h12mediaBidAdapter.js +1 -1
  62. package/dist/hypelabBidAdapter.js +1 -1
  63. package/dist/id5AnalyticsAdapter.js +1 -1
  64. package/dist/id5IdSystem.js +1 -1
  65. package/dist/imdsBidAdapter.js +1 -1
  66. package/dist/improvedigitalBidAdapter.js +1 -1
  67. package/dist/insticatorBidAdapter.js +1 -1
  68. package/dist/intentIqAnalyticsAdapter.js +1 -1
  69. package/dist/ixBidAdapter.js +1 -1
  70. package/dist/jixieBidAdapter.js +1 -1
  71. package/dist/justpremiumBidAdapter.js +1 -1
  72. package/dist/kargoBidAdapter.js +1 -1
  73. package/dist/kimberliteBidAdapter.js +1 -1
  74. package/dist/konduitAnalyticsAdapter.js +1 -1
  75. package/dist/kueezBidAdapter.js +1 -1
  76. package/dist/lassoBidAdapter.js +1 -1
  77. package/dist/lifestreetBidAdapter.js +1 -1
  78. package/dist/liveIntentIdSystem.js +1 -1
  79. package/dist/logicadBidAdapter.js +1 -1
  80. package/dist/loglyliftBidAdapter.js +1 -1
  81. package/dist/luceadBidAdapter.js +1 -1
  82. package/dist/mabidderBidAdapter.js +1 -1
  83. package/dist/magniteAnalyticsAdapter.js +1 -1
  84. package/dist/malltvAnalyticsAdapter.js +1 -1
  85. package/dist/marsmediaBidAdapter.js +1 -1
  86. package/dist/mediafuseBidAdapter.js +1 -1
  87. package/dist/medianetAnalyticsAdapter.js +1 -1
  88. package/dist/medianetBidAdapter.js +1 -1
  89. package/dist/mediasquareBidAdapter.js +1 -1
  90. package/dist/mgidBidAdapter.js +1 -1
  91. package/dist/minutemediaBidAdapter.js +1 -1
  92. package/dist/missenaBidAdapter.js +1 -1
  93. package/dist/nexx360BidAdapter.js +1 -1
  94. package/dist/nobidAnalyticsAdapter.js +1 -1
  95. package/dist/nobidBidAdapter.js +1 -1
  96. package/dist/not-for-prod/prebid.js +163 -162
  97. package/dist/oguryBidAdapter.js +1 -1
  98. package/dist/onetagBidAdapter.js +1 -1
  99. package/dist/ooloAnalyticsAdapter.js +1 -1
  100. package/dist/openwebBidAdapter.js +1 -1
  101. package/dist/openxBidAdapter.js +1 -1
  102. package/dist/optidigitalBidAdapter.js +1 -1
  103. package/dist/orbidderBidAdapter.js +1 -1
  104. package/dist/outbrainBidAdapter.js +1 -1
  105. package/dist/pixfutureBidAdapter.js +1 -1
  106. package/dist/publinkIdSystem.js +1 -1
  107. package/dist/publirBidAdapter.js +1 -1
  108. package/dist/pubmaticAnalyticsAdapter.js +1 -1
  109. package/dist/pubmaticBidAdapter.js +1 -1
  110. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  111. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  112. package/dist/pxyzBidAdapter.js +1 -1
  113. package/dist/quantcastBidAdapter.js +1 -1
  114. package/dist/readpeakBidAdapter.js +1 -1
  115. package/dist/relaidoBidAdapter.js +1 -1
  116. package/dist/retailspotBidAdapter.js +1 -1
  117. package/dist/rhythmoneBidAdapter.js +1 -1
  118. package/dist/riseBidAdapter.js +1 -1
  119. package/dist/riseUtils.js +1 -0
  120. package/dist/rubiconBidAdapter.js +1 -1
  121. package/dist/seedingAllianceBidAdapter.js +1 -1
  122. package/dist/seedtagBidAdapter.js +1 -1
  123. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  124. package/dist/sharethroughBidAdapter.js +1 -1
  125. package/dist/shinezBidAdapter.js +1 -1
  126. package/dist/smaatoBidAdapter.js +1 -1
  127. package/dist/smartadserverBidAdapter.js +1 -1
  128. package/dist/smarthubBidAdapter.js +1 -1
  129. package/dist/smartxBidAdapter.js +1 -1
  130. package/dist/smilewantedBidAdapter.js +1 -1
  131. package/dist/snigelBidAdapter.js +1 -1
  132. package/dist/sonobiBidAdapter.js +1 -1
  133. package/dist/sovrnBidAdapter.js +1 -1
  134. package/dist/sspBCBidAdapter.js +1 -1
  135. package/dist/stnBidAdapter.js +1 -1
  136. package/dist/stvBidAdapter.js +1 -1
  137. package/dist/sublimeBidAdapter.js +1 -1
  138. package/dist/taboolaBidAdapter.js +1 -1
  139. package/dist/tappxBidAdapter.js +1 -1
  140. package/dist/targetVideoBidAdapter.js +1 -1
  141. package/dist/teadsBidAdapter.js +1 -1
  142. package/dist/telariaBidAdapter.js +1 -1
  143. package/dist/teqblazeUtils.js +1 -1
  144. package/dist/terceptAnalyticsAdapter.js +1 -1
  145. package/dist/themoneytizerBidAdapter.js +1 -1
  146. package/dist/trionBidAdapter.js +1 -1
  147. package/dist/tripleliftBidAdapter.js +1 -1
  148. package/dist/ttdBidAdapter.js +1 -1
  149. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  150. package/dist/uid2IdSystem.js +1 -1
  151. package/dist/uid2IdSystem_shared.js +1 -1
  152. package/dist/underdogmediaBidAdapter.js +1 -1
  153. package/dist/undertoneBidAdapter.js +1 -1
  154. package/dist/unrulyBidAdapter.js +1 -1
  155. package/dist/vidazooUtils.js +1 -1
  156. package/dist/videobyteBidAdapter.js +1 -1
  157. package/dist/visxBidAdapter.js +1 -1
  158. package/dist/vuukleBidAdapter.js +1 -1
  159. package/dist/widespaceBidAdapter.js +1 -1
  160. package/dist/winrBidAdapter.js +1 -1
  161. package/dist/yahooAdsBidAdapter.js +1 -1
  162. package/dist/yieldmoBidAdapter.js +1 -1
  163. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  164. package/libraries/riseUtils/index.js +330 -0
  165. package/libraries/teqblazeUtils/bidderUtils.js +15 -11
  166. package/modules/adagioAnalyticsAdapter.js +101 -84
  167. package/modules/adagioAnalyticsAdapter.md +4 -0
  168. package/modules/adagioBidAdapter.js +4 -16
  169. package/modules/adkernelBidAdapter.js +2 -2
  170. package/modules/aidemBidAdapter.js +2 -0
  171. package/modules/connectIdSystem.js +5 -3
  172. package/modules/insticatorBidAdapter.js +35 -31
  173. package/modules/kargoBidAdapter.js +11 -14
  174. package/modules/kimberliteBidAdapter.js +24 -7
  175. package/modules/kimberliteBidAdapter.md +30 -1
  176. package/modules/minutemediaBidAdapter.js +21 -398
  177. package/modules/nexx360BidAdapter.js +3 -2
  178. package/modules/openwebBidAdapter.js +18 -396
  179. package/modules/publirBidAdapter.js +20 -273
  180. package/modules/resetdigitalBidAdapter.md +54 -45
  181. package/modules/riseBidAdapter.js +19 -400
  182. package/modules/shinezBidAdapter.js +17 -361
  183. package/modules/smarthubBidAdapter.js +45 -177
  184. package/modules/stnBidAdapter.js +22 -398
  185. package/modules/telariaBidAdapter.js +2 -32
  186. package/modules/uid2IdSystem_shared.js +51 -39
  187. package/package.json +1 -1
  188. package/src/prebid.js +4 -0
  189. package/test/spec/modules/adagioAnalyticsAdapter_spec.js +231 -141
  190. package/test/spec/modules/adagioBidAdapter_spec.js +32 -66
  191. package/test/spec/modules/connectIdSystem_spec.js +27 -28
  192. package/test/spec/modules/insticatorBidAdapter_spec.js +8 -1
  193. package/test/spec/modules/kargoBidAdapter_spec.js +7 -8
  194. package/test/spec/modules/kimberliteBidAdapter_spec.js +137 -65
  195. package/test/spec/modules/nexx360BidAdapter_spec.js +1 -1
  196. package/test/spec/modules/smarthubBidAdapter_spec.js +6 -4
  197. package/test/spec/unit/pbjs_api_spec.js +11 -0
@@ -0,0 +1,330 @@
1
+ import {
2
+ isArray,
3
+ isFn,
4
+ deepAccess,
5
+ isEmpty,
6
+ contains,
7
+ isInteger,
8
+ getBidIdParameter
9
+ } from '../../src/utils.js';
10
+ import { BANNER, VIDEO } from '../../src/mediaTypes.js';
11
+ import {config} from '../../src/config.js';
12
+
13
+ export function getFloor(bid, mediaType) {
14
+ if (!isFn(bid.getFloor)) {
15
+ return 0;
16
+ }
17
+ let floorResult = bid.getFloor({
18
+ currency: 'USD',
19
+ mediaType: mediaType,
20
+ size: '*'
21
+ });
22
+ return floorResult.currency === 'USD' && floorResult.floor ? floorResult.floor : 0;
23
+ }
24
+
25
+ export function getSizesArray(bid, mediaType) {
26
+ let sizesArray = [];
27
+
28
+ if (deepAccess(bid, `mediaTypes.${mediaType}.sizes`)) {
29
+ sizesArray = bid.mediaTypes[mediaType].sizes;
30
+ } else if (Array.isArray(bid.sizes) && bid.sizes.length > 0) {
31
+ sizesArray = bid.sizes;
32
+ }
33
+
34
+ return sizesArray;
35
+ }
36
+
37
+ export function getSupplyChain(schainObject) {
38
+ if (isEmpty(schainObject)) {
39
+ return '';
40
+ }
41
+ let scStr = `${schainObject.ver},${schainObject.complete}`;
42
+ schainObject.nodes.forEach((node) => {
43
+ scStr += '!';
44
+ scStr += `${getEncodedValIfNotEmpty(node.asi)},`;
45
+ scStr += `${getEncodedValIfNotEmpty(node.sid)},`;
46
+ scStr += `${getEncodedValIfNotEmpty(node.hp)},`;
47
+ scStr += `${getEncodedValIfNotEmpty(node.rid)},`;
48
+ scStr += `${getEncodedValIfNotEmpty(node.name)},`;
49
+ scStr += `${getEncodedValIfNotEmpty(node.domain)}`;
50
+ });
51
+ return scStr;
52
+ }
53
+
54
+ export function getEncodedValIfNotEmpty(val) {
55
+ return (val !== '' && val !== undefined) ? encodeURIComponent(val) : '';
56
+ }
57
+
58
+ export function getAllowedSyncMethod(filterSettings, bidderCode) {
59
+ const iframeConfigsToCheck = ['all', 'iframe'];
60
+ const pixelConfigToCheck = 'image';
61
+ if (filterSettings && iframeConfigsToCheck.some(config => isSyncMethodAllowed(filterSettings[config], bidderCode))) {
62
+ return 'iframe';
63
+ }
64
+ if (!filterSettings || !filterSettings[pixelConfigToCheck] || isSyncMethodAllowed(filterSettings[pixelConfigToCheck], bidderCode)) {
65
+ return 'pixel';
66
+ }
67
+ }
68
+
69
+ export function isSyncMethodAllowed(syncRule, bidderCode) {
70
+ if (!syncRule) {
71
+ return false;
72
+ }
73
+ const isInclude = syncRule.filter === 'include';
74
+ const bidders = isArray(syncRule.bidders) ? syncRule.bidders : [bidderCode];
75
+ return isInclude && contains(bidders, bidderCode);
76
+ }
77
+
78
+ export function getEndpoint(testMode, baseUrl, modes) {
79
+ const protocol = baseUrl.startsWith('http') ? '' : 'https://';
80
+ const url = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`;
81
+ return testMode
82
+ ? `${protocol}${url}${modes.TEST}`
83
+ : `${protocol}${url}${modes.PRODUCTION}`;
84
+ }
85
+
86
+ export function getDeviceType(ua) {
87
+ if (/ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i.test(ua.toLowerCase())) {
88
+ return '5';
89
+ }
90
+ if (/iphone|ipod|android|blackberry|opera|mini|windows\\sce|palm|smartphone|iemobile/i.test(ua.toLowerCase())) {
91
+ return '4';
92
+ }
93
+ if (/smart[-_\\s]?tv|hbbtv|appletv|googletv|hdmi|netcast|viera|nettv|roku|\\bdtv\\b|sonydtv|inettvbrowser|\\btv\\b/i.test(ua.toLowerCase())) {
94
+ return '3';
95
+ }
96
+ return '1';
97
+ }
98
+
99
+ export function generateBidsParams(validBidRequests, bidderRequest) {
100
+ const bidsArray = [];
101
+
102
+ if (validBidRequests.length) {
103
+ validBidRequests.forEach(bid => {
104
+ bidsArray.push(generateBidParameters(bid, bidderRequest));
105
+ });
106
+ }
107
+
108
+ return bidsArray;
109
+ }
110
+
111
+ export function generateBidParameters(bid, bidderRequest) {
112
+ const { params } = bid;
113
+ const mediaType = isBanner(bid) ? BANNER : VIDEO;
114
+ const sizesArray = getSizesArray(bid, mediaType);
115
+
116
+ if (isNaN(params.floorPrice)) {
117
+ params.floorPrice = 0;
118
+ }
119
+
120
+ const bidObject = {
121
+ mediaType,
122
+ adUnitCode: getBidIdParameter('adUnitCode', bid),
123
+ sizes: sizesArray,
124
+ floorPrice: Math.max(getFloor(bid, mediaType), params.floorPrice),
125
+ bidId: getBidIdParameter('bidId', bid),
126
+ loop: getBidIdParameter('bidderRequestsCount', bid),
127
+ bidderRequestId: getBidIdParameter('bidderRequestId', bid),
128
+ transactionId: bid.ortb2Imp?.ext?.tid || '',
129
+ coppa: 0,
130
+ };
131
+
132
+ const pos = deepAccess(bid, `mediaTypes.${mediaType}.pos`);
133
+ if (pos) {
134
+ bidObject.pos = pos;
135
+ }
136
+
137
+ const gpid = deepAccess(bid, `ortb2Imp.ext.gpid`);
138
+ if (gpid) {
139
+ bidObject.gpid = gpid;
140
+ }
141
+
142
+ const placementId = params.placementId || deepAccess(bid, `mediaTypes.${mediaType}.name`);
143
+ if (placementId) {
144
+ bidObject.placementId = placementId;
145
+ }
146
+
147
+ const mimes = deepAccess(bid, `mediaTypes.${mediaType}.mimes`);
148
+ if (mimes) {
149
+ bidObject.mimes = mimes;
150
+ }
151
+
152
+ const api = deepAccess(bid, `mediaTypes.${mediaType}.api`);
153
+ if (api) {
154
+ bidObject.api = api;
155
+ }
156
+
157
+ const sua = deepAccess(bid, `ortb2.device.sua`);
158
+ if (sua) {
159
+ bidObject.sua = sua;
160
+ }
161
+
162
+ const coppa = deepAccess(bid, `ortb2.regs.coppa`);
163
+ if (coppa) {
164
+ bidObject.coppa = 1;
165
+ }
166
+
167
+ if (mediaType === VIDEO) {
168
+ const playbackMethod = deepAccess(bid, `mediaTypes.video.playbackmethod`);
169
+ let playbackMethodValue;
170
+
171
+ if (Array.isArray(playbackMethod) && isInteger(playbackMethod[0])) {
172
+ playbackMethodValue = playbackMethod[0];
173
+ } else if (isInteger(playbackMethod)) {
174
+ playbackMethodValue = playbackMethod;
175
+ }
176
+
177
+ if (playbackMethodValue) {
178
+ bidObject.playbackMethod = playbackMethodValue;
179
+ }
180
+
181
+ const placement = deepAccess(bid, `mediaTypes.video.placement`);
182
+ if (placement) {
183
+ bidObject.placement = placement;
184
+ }
185
+
186
+ const minDuration = deepAccess(bid, `mediaTypes.video.minduration`);
187
+ if (minDuration) {
188
+ bidObject.minDuration = minDuration;
189
+ }
190
+
191
+ const maxDuration = deepAccess(bid, `mediaTypes.video.maxduration`);
192
+ if (maxDuration) {
193
+ bidObject.maxDuration = maxDuration;
194
+ }
195
+
196
+ const skip = deepAccess(bid, `mediaTypes.video.skip`);
197
+ if (skip) {
198
+ bidObject.skip = skip;
199
+ }
200
+
201
+ const linearity = deepAccess(bid, `mediaTypes.video.linearity`);
202
+ if (linearity) {
203
+ bidObject.linearity = linearity;
204
+ }
205
+
206
+ const protocols = deepAccess(bid, `mediaTypes.video.protocols`);
207
+ if (protocols) {
208
+ bidObject.protocols = protocols;
209
+ }
210
+
211
+ const plcmt = deepAccess(bid, `mediaTypes.video.plcmt`);
212
+ if (plcmt) {
213
+ bidObject.plcmt = plcmt;
214
+ }
215
+ }
216
+
217
+ return bidObject;
218
+ }
219
+
220
+ export function buildBidResponse(adUnit, DEFAULT_CURRENCY, TTL, VIDEO, BANNER) {
221
+ const bidResponse = {
222
+ requestId: adUnit.requestId,
223
+ cpm: adUnit.cpm,
224
+ currency: adUnit.currency || DEFAULT_CURRENCY,
225
+ width: adUnit.width,
226
+ height: adUnit.height,
227
+ ttl: adUnit.ttl || TTL,
228
+ creativeId: adUnit.creativeId,
229
+ netRevenue: adUnit.netRevenue || true,
230
+ nurl: adUnit.nurl,
231
+ mediaType: adUnit.mediaType,
232
+ meta: {
233
+ mediaType: adUnit.mediaType
234
+ }
235
+ };
236
+
237
+ if (adUnit.mediaType === VIDEO) {
238
+ bidResponse.vastXml = adUnit.vastXml;
239
+ } else if (adUnit.mediaType === BANNER) {
240
+ bidResponse.ad = adUnit.ad;
241
+ }
242
+
243
+ if (adUnit.adomain && adUnit.adomain.length) {
244
+ bidResponse.meta.advertiserDomains = adUnit.adomain;
245
+ }
246
+
247
+ return bidResponse;
248
+ }
249
+
250
+ function isBanner(bid) {
251
+ return bid.mediaTypes && bid.mediaTypes.banner;
252
+ }
253
+
254
+ export function generateGeneralParams(generalObject, bidderRequest, adapterVersion) {
255
+ const domain = window.location.hostname;
256
+ const { syncEnabled, filterSettings } = config.getConfig('userSync') || {};
257
+ const { bidderCode } = bidderRequest;
258
+ const generalBidParams = generalObject.params;
259
+ const timeout = bidderRequest.timeout;
260
+ const adapVer = adapterVersion || '6.0.0';
261
+
262
+ const generalParams = {
263
+ wrapper_type: 'prebidjs',
264
+ wrapper_vendor: '$$PREBID_GLOBAL$$',
265
+ wrapper_version: '$prebid.version$',
266
+ adapter_version: adapVer,
267
+ auction_start: bidderRequest.auctionStart,
268
+ publisher_id: generalBidParams.org,
269
+ publisher_name: domain,
270
+ site_domain: domain,
271
+ dnt: (navigator.doNotTrack === 'yes' || navigator.doNotTrack === '1' || navigator.msDoNotTrack === '1') ? 1 : 0,
272
+ device_type: getDeviceType(navigator.userAgent),
273
+ ua: navigator.userAgent,
274
+ is_wrapper: !!generalBidParams.isWrapper,
275
+ session_id: generalBidParams.sessionId || getBidIdParameter('bidderRequestId', generalObject),
276
+ tmax: timeout
277
+ };
278
+
279
+ const userIdsParam = getBidIdParameter('userId', generalObject);
280
+ if (userIdsParam) {
281
+ generalParams.userIds = JSON.stringify(userIdsParam);
282
+ }
283
+
284
+ const ortb2Metadata = bidderRequest.ortb2 || {};
285
+ if (ortb2Metadata.site) {
286
+ generalParams.site_metadata = JSON.stringify(ortb2Metadata.site);
287
+ }
288
+ if (ortb2Metadata.user) {
289
+ generalParams.user_metadata = JSON.stringify(ortb2Metadata.user);
290
+ }
291
+
292
+ if (syncEnabled) {
293
+ const allowedSyncMethod = getAllowedSyncMethod(filterSettings, bidderCode);
294
+ if (allowedSyncMethod) {
295
+ generalParams.cs_method = allowedSyncMethod;
296
+ }
297
+ }
298
+
299
+ if (bidderRequest.uspConsent) {
300
+ generalParams.us_privacy = bidderRequest.uspConsent;
301
+ }
302
+
303
+ if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) {
304
+ generalParams.gdpr = bidderRequest.gdprConsent.gdprApplies;
305
+ generalParams.gdpr_consent = bidderRequest.gdprConsent.consentString;
306
+ }
307
+
308
+ if (bidderRequest.gppConsent) {
309
+ generalParams.gpp = bidderRequest.gppConsent.gppString;
310
+ generalParams.gpp_sid = bidderRequest.gppConsent.applicableSections;
311
+ } else if (bidderRequest.ortb2?.regs?.gpp) {
312
+ generalParams.gpp = bidderRequest.ortb2.regs.gpp;
313
+ generalParams.gpp_sid = bidderRequest.ortb2.regs.gpp_sid;
314
+ }
315
+
316
+ if (generalBidParams.ifa) {
317
+ generalParams.ifa = generalBidParams.ifa;
318
+ }
319
+
320
+ if (generalObject.schain) {
321
+ generalParams.schain = getSupplyChain(generalObject.schain);
322
+ }
323
+
324
+ if (bidderRequest && bidderRequest.refererInfo) {
325
+ generalParams.referrer = deepAccess(bidderRequest, 'refererInfo.ref');
326
+ generalParams.page_url = deepAccess(bidderRequest, 'refererInfo.page') || deepAccess(window, 'location.href');
327
+ }
328
+
329
+ return generalParams;
330
+ }
@@ -188,20 +188,24 @@ export const buildRequests = (adUrl) => (validBidRequests = [], bidderRequest =
188
188
  return buildRequestsBase({ adUrl, validBidRequests, bidderRequest, placementProcessingFunction });
189
189
  };
190
190
 
191
- export const interpretResponse = (serverResponse) => {
192
- let response = [];
193
- for (let i = 0; i < serverResponse.body.length; i++) {
194
- let resItem = serverResponse.body[i];
195
- if (isBidResponseValid(resItem)) {
196
- const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : [];
197
- resItem.meta = { ...resItem.meta, advertiserDomains };
198
-
199
- response.push(resItem);
191
+ export function interpretResponseBuilder({addtlBidValidation = (bid) => true} = {}) {
192
+ return function (serverResponse) {
193
+ let response = [];
194
+ for (let i = 0; i < serverResponse.body.length; i++) {
195
+ let resItem = serverResponse.body[i];
196
+ if (isBidResponseValid(resItem) && addtlBidValidation(resItem)) {
197
+ const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : [];
198
+ resItem.meta = { ...resItem.meta, advertiserDomains };
199
+
200
+ response.push(resItem);
201
+ }
200
202
  }
203
+
204
+ return response;
201
205
  }
206
+ }
202
207
 
203
- return response;
204
- };
208
+ export const interpretResponse = interpretResponseBuilder();
205
209
 
206
210
  export const getUserSyncs = (syncUrl) => (syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent) => {
207
211
  const type = syncOptions.iframeEnabled ? 'iframe' : 'image';
@@ -2,12 +2,13 @@
2
2
  * Analytics Adapter for Adagio
3
3
  */
4
4
 
5
+ import { _ADAGIO, getBestWindowForAdagio } from '../libraries/adagioUtils/adagioUtils.js';
6
+ import { deepAccess, logError, logInfo, logWarn } from '../src/utils.js';
7
+ import { BANNER } from '../src/mediaTypes.js';
8
+ import { EVENTS } from '../src/constants.js';
5
9
  import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
6
10
  import adapterManager from '../src/adapterManager.js';
7
- import { EVENTS } from '../src/constants.js';
8
11
  import { ajax } from '../src/ajax.js';
9
- import { BANNER } from '../src/mediaTypes.js';
10
- import { getWindowTop, getWindowSelf, deepAccess, logInfo, logError } from '../src/utils.js';
11
12
  import { getGlobal } from '../src/prebidGlobal.js';
12
13
 
13
14
  const emptyUrl = '';
@@ -19,6 +20,13 @@ const PREBID_VERSION = '$prebid.version$';
19
20
  const ENDPOINT = 'https://c.4dex.io/pba.gif';
20
21
  const CURRENCY_USD = 'USD';
21
22
  const ADAGIO_CODE = 'adagio';
23
+
24
+ export const _internal = {
25
+ getAdagioNs: function() {
26
+ return _ADAGIO;
27
+ }
28
+ };
29
+
22
30
  const cache = {
23
31
  auctions: {},
24
32
  getAuction: function(auctionId, adUnitCode) {
@@ -48,34 +56,6 @@ const cache = {
48
56
  };
49
57
  const enc = window.encodeURIComponent;
50
58
 
51
- /**
52
- /* BEGIN ADAGIO.JS CODE
53
- */
54
-
55
- function canAccessTopWindow() {
56
- try {
57
- if (getWindowTop().location.href) {
58
- return true;
59
- }
60
- } catch (error) {
61
- return false;
62
- }
63
- };
64
-
65
- function getCurrentWindow() {
66
- return currentWindow;
67
- };
68
-
69
- let currentWindow;
70
-
71
- const adagioEnqueue = function adagioEnqueue(action, data) {
72
- getCurrentWindow().ADAGIO.queue.push({ action, data, ts: Date.now() });
73
- };
74
-
75
- /**
76
- * END ADAGIO.JS CODE
77
- */
78
-
79
59
  /**
80
60
  * UTILS FUNCTIONS
81
61
  */
@@ -150,6 +130,10 @@ function getCurrencyData(bid) {
150
130
  * @param {Object} qp
151
131
  */
152
132
  function sendRequest(qp) {
133
+ if (!qp.org_id || !qp.site) {
134
+ logInfo('request is missing org_id or site, skipping beacon.');
135
+ return;
136
+ }
153
137
  // Removing null values
154
138
  qp = Object.keys(qp).reduce((acc, key) => {
155
139
  if (qp[key] !== null) {
@@ -194,37 +178,28 @@ function getTargetedAuctionId(bid) {
194
178
  */
195
179
 
196
180
  function handlerAuctionInit(event) {
197
- const w = getCurrentWindow();
181
+ const w = getBestWindowForAdagio();
198
182
 
199
183
  const prebidAuctionId = event.auctionId;
200
184
  const adUnitCodes = removeDuplicates(event.adUnitCodes, adUnitCode => adUnitCode);
201
185
 
202
186
  // Check if Adagio is on the bid requests.
203
- // If not, we don't need to track the auction.
204
187
  const adagioBidRequest = event.bidderRequests.find(bidRequest => isAdagio(bidRequest.bidderCode));
205
- if (!adagioBidRequest) {
206
- logInfo(`Adagio is not on the bid requests for auction '${prebidAuctionId}'`)
207
- return;
208
- }
188
+
189
+ const rtdUid = deepAccess(adagioBidRequest, 'ortb2.site.ext.data.adg_rtd.uid');
190
+ cache.addPrebidAuctionIdRef(prebidAuctionId, rtdUid);
209
191
 
210
192
  cache.auctions[prebidAuctionId] = {};
211
193
 
212
194
  adUnitCodes.forEach(adUnitCode => {
195
+ // event.adUnits are splitted by mediatypes
213
196
  const adUnits = event.adUnits.filter(adUnit => adUnit.code === adUnitCode);
214
197
 
215
- // Get all bidders configures for the ad unit.
216
- const bidders = removeDuplicates(
217
- adUnits.map(adUnit => adUnit.bids.map(bid => ({bidder: bid.bidder, params: bid.params}))).flat(),
218
- bidder => bidder.bidder
219
- );
220
-
221
- // Check if Adagio is configured for the ad unit.
222
- // If not, we don't need to track the ad unit.
223
- const adagioBidder = bidders.find(bidder => isAdagio(bidder.bidder));
224
- if (!adagioBidder) {
225
- logInfo(`Adagio is not configured for ad unit '${adUnitCode}'`);
226
- return;
227
- }
198
+ // Get all bidders configured for the ad unit.
199
+ // AdUnits with the same code can have a different bidder list, aggregate all of them.
200
+ const biddersAggregate = adUnits.reduce((bidders, adUnit) => bidders.concat(adUnit.bids.map(bid => bid.bidder)), [])
201
+ // remove duplicates
202
+ const bidders = [...new Set(biddersAggregate)];
228
203
 
229
204
  // Get all media types and banner sizes configured for the ad unit.
230
205
  const mediaTypes = adUnits.map(adUnit => adUnit.mediaTypes);
@@ -239,45 +214,56 @@ function handlerAuctionInit(event) {
239
214
  bannerSize => bannerSize
240
215
  ).sort();
241
216
 
242
- // Get all Adagio bids for the ad unit from the bidRequest.
243
- // If no bids, we don't need to track the ad unit.
244
- const adagioAdUnitBids = adagioBidRequest.bids.filter(bid => bid.adUnitCode === adUnitCode);
245
- if (deepAccess(adagioAdUnitBids, 'length', 0) <= 0) {
246
- logInfo(`Adagio is not on the bid requests for ad unit '${adUnitCode}' and auction '${prebidAuctionId}'`)
247
- return;
217
+ const sortedBidderCodes = bidders.sort()
218
+
219
+ const bidSrcMapper = (bidder) => {
220
+ const request = event.bidderRequests.find(br => br.bidderCode === bidder)
221
+ return request ? request.bids[0].src : null
248
222
  }
249
- // Get Adagio params from the first bid.
250
- // We assume that all Adagio bids for a same adunit have the same params.
251
- const params = adagioAdUnitBids[0].params;
223
+ const biddersSrc = sortedBidderCodes.map(bidSrcMapper).join(',');
252
224
 
253
- const adagioAuctionId = params.adagioAuctionId;
254
- cache.addPrebidAuctionIdRef(prebidAuctionId, adagioAuctionId);
225
+ // if adagio was involved in the auction we identified it with rtdUid, if not use the prebid auctionId
226
+ const auctionId = rtdUid || prebidAuctionId;
255
227
 
256
- // Get all media types requested for Adagio.
257
- const adagioMediaTypes = removeDuplicates(
258
- adagioAdUnitBids.map(bid => Object.keys(bid.mediaTypes)).flat(),
259
- mediaTypeKey => mediaTypeKey
260
- ).flat().map(mediaType => getMediaTypeAlias(mediaType)).sort();
228
+ const adgRtdSession = deepAccess(event.bidderRequests[0], 'ortb2.site.ext.data.adg_rtd.session', {});
261
229
 
262
230
  const qp = {
231
+ org_id: adagioAdapter.options.organizationId,
232
+ site: adagioAdapter.options.site,
263
233
  v: 0,
264
234
  pbjsv: PREBID_VERSION,
265
- org_id: params.organizationId,
266
- site: params.site,
267
- pv_id: params.pageviewId,
268
- auct_id: adagioAuctionId,
235
+ pv_id: _internal.getAdagioNs().pageviewId,
236
+ auct_id: auctionId,
269
237
  adu_code: adUnitCode,
270
238
  url_dmn: w.location.hostname,
271
- pgtyp: params.pagetype,
272
- plcmt: params.placement,
273
- t_n: params.testName || null,
274
- t_v: params.testVersion || null,
275
239
  mts: mediaTypesKeys.join(','),
276
240
  ban_szs: bannerSizes.join(','),
277
- bdrs: bidders.map(bidder => bidder.bidder).sort().join(','),
278
- adg_mts: adagioMediaTypes.join(',')
241
+ bdrs: sortedBidderCodes.join(','),
242
+ pgtyp: deepAccess(event.bidderRequests[0], 'ortb2.site.ext.data.pagetype', null),
243
+ plcmt: deepAccess(adUnits[0], 'ortb2Imp.ext.data.placement', null),
244
+ t_n: adgRtdSession.testName || null,
245
+ t_v: adgRtdSession.testVersion || null,
246
+ s_id: adgRtdSession.id || null,
247
+ s_new: adgRtdSession.new || null,
248
+ bdrs_src: biddersSrc,
279
249
  };
280
250
 
251
+ if (adagioBidRequest && adagioBidRequest.bids) {
252
+ const adagioAdUnitBids = adagioBidRequest.bids.filter(bid => bid.adUnitCode === adUnitCode);
253
+ if (adagioAdUnitBids.length > 0) {
254
+ // Get all media types requested for Adagio.
255
+ const adagioMediaTypes = removeDuplicates(
256
+ adagioAdUnitBids.map(bid => Object.keys(bid.mediaTypes)).flat(),
257
+ mediaTypeKey => mediaTypeKey
258
+ ).flat().map(mediaType => getMediaTypeAlias(mediaType)).sort();
259
+
260
+ qp.adg_mts = adagioMediaTypes.join(',');
261
+ // for backward compatibility: if we didn't find organizationId & site but we have a bid from adagio we might still find it in params
262
+ qp.org_id = qp.org_id || adagioAdUnitBids[0].params.organizationId;
263
+ qp.site = qp.site || adagioAdUnitBids[0].params.site;
264
+ }
265
+ }
266
+
281
267
  cache.auctions[prebidAuctionId][adUnitCode] = qp;
282
268
  sendNewBeacon(prebidAuctionId, adUnitCode);
283
269
  });
@@ -324,13 +310,21 @@ function handlerAuctionEnd(event) {
324
310
  return bid ? getCurrencyData(bid).netCpm : null
325
311
  }
326
312
 
313
+ const perfNavigation = performance.getEntriesByType('navigation')[0];
314
+
327
315
  cache.updateAuction(auctionId, adUnitCode, {
328
316
  bdrs_bid: cache.getBiddersFromAuction(auctionId, adUnitCode).map(bidResponseMapper).join(','),
329
- bdrs_cpm: cache.getBiddersFromAuction(auctionId, adUnitCode).map(bidCpmMapper).join(',')
317
+ bdrs_cpm: cache.getBiddersFromAuction(auctionId, adUnitCode).map(bidCpmMapper).join(','),
318
+ // check timings at the end of the auction to leave time to the browser to update it
319
+ dom_i: Math.round(perfNavigation['domInteractive']) || null,
320
+ dom_c: Math.round(perfNavigation['domComplete']) || null,
321
+ loa_e: Math.round(perfNavigation['loadEventEnd']) || null,
330
322
  });
323
+
331
324
  sendNewBeacon(auctionId, adUnitCode);
332
325
  });
333
326
  }
327
+
334
328
  function handlerBidWon(event) {
335
329
  let auctionId = getTargetedAuctionId(event);
336
330
 
@@ -345,6 +339,8 @@ function handlerBidWon(event) {
345
339
  ? cache.getAdagioAuctionId(event.auctionId)
346
340
  : null);
347
341
 
342
+ const perfNavigation = performance.getEntriesByType('navigation')[0];
343
+
348
344
  cache.updateAuction(auctionId, event.adUnitCode, {
349
345
  win_bdr: event.bidder,
350
346
  win_mt: getMediaTypeAlias(event.mediaType),
@@ -353,6 +349,11 @@ function handlerBidWon(event) {
353
349
  win_net_cpm: currencyData.netCpm,
354
350
  win_og_cpm: currencyData.orginalCpm,
355
351
 
352
+ // check timings at the end of the auction to leave time to the browser to update it
353
+ dom_i: Math.round(perfNavigation['domInteractive']) || null,
354
+ dom_c: Math.round(perfNavigation['domComplete']) || null,
355
+ loa_e: Math.round(perfNavigation['loadEventEnd']) || null,
356
+
356
357
  // cache bid id
357
358
  auct_id_c: adagioAuctionCacheId,
358
359
  });
@@ -407,7 +408,11 @@ let adagioAdapter = Object.assign(adapter({ emptyUrl, analyticsType }), {
407
408
 
408
409
  try {
409
410
  if (typeof args !== 'undefined' && events.indexOf(eventType) !== -1) {
410
- adagioEnqueue('pb-analytics-event', { eventName: eventType, args });
411
+ _internal.getAdagioNs().queue.push({
412
+ action: 'pb-analytics-event',
413
+ data: { eventName: eventType, args },
414
+ ts: Date.now()
415
+ });
411
416
  }
412
417
  } catch (error) {
413
418
  logError('Error on Adagio Analytics Adapter - adagio.js', error);
@@ -418,14 +423,26 @@ let adagioAdapter = Object.assign(adapter({ emptyUrl, analyticsType }), {
418
423
  adagioAdapter.originEnableAnalytics = adagioAdapter.enableAnalytics;
419
424
 
420
425
  adagioAdapter.enableAnalytics = config => {
421
- const w = (canAccessTopWindow()) ? getWindowTop() : getWindowSelf();
422
- currentWindow = w;
426
+ _internal.getAdagioNs().versions.adagioAnalyticsAdapter = VERSION;
423
427
 
424
- w.ADAGIO = w.ADAGIO || {};
425
- w.ADAGIO.queue = w.ADAGIO.queue || [];
426
- w.ADAGIO.versions = w.ADAGIO.versions || {};
427
- w.ADAGIO.versions.adagioAnalyticsAdapter = VERSION;
428
+ let modules = getGlobal().installedModules;
429
+ if (modules && (!modules.length || modules.indexOf('adagioRtdProvider') === -1 || modules.indexOf('rtdModule') === -1)) {
430
+ logError('Adagio Analytics Adapter requires rtdModule & adagioRtdProvider modules which are not installed. No beacon will be sent');
431
+ return;
432
+ }
428
433
 
434
+ adagioAdapter.options = config.options || {};
435
+ if (!adagioAdapter.options.organizationId) {
436
+ logWarn('Adagio Analytics Adapter: organizationId is required and is missing will try to fallback on params.');
437
+ } else {
438
+ adagioAdapter.options.organizationId = adagioAdapter.options.organizationId.toString(); // allows publisher to pass it as a number
439
+ }
440
+ if (!adagioAdapter.options.site) {
441
+ logWarn('Adagio Analytics Adapter: site is required and is missing will try to fallback on params.');
442
+ } else if (typeof adagioAdapter.options.site !== 'string') {
443
+ logWarn('Adagio Analytics Adapter: site should be a string will try to fallback on params.');
444
+ adagioAdapter.options.site = undefined;
445
+ }
429
446
  adagioAdapter.originEnableAnalytics(config);
430
447
  }
431
448
 
@@ -13,5 +13,9 @@ Analytics adapter for Adagio
13
13
  ```js
14
14
  pbjs.enableAnalytics({
15
15
  provider: 'adagio',
16
+ options: {
17
+ organizationId: '1000', // Required. Provided by Adagio
18
+ site: 'my-website', // Required. Provided by Adagio
19
+ }
16
20
  });
17
21
  ```