prebid.js 8.1.0 → 8.3.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 (214) hide show
  1. package/.devcontainer/devcontainer.json +3 -1
  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/admanBidAdapter.js +1 -1
  8. package/dist/adqueryBidAdapter.js +1 -1
  9. package/dist/adrelevantisBidAdapter.js +1 -1
  10. package/dist/adtelligentBidAdapter.js +1 -1
  11. package/dist/adtrgtmeBidAdapter.js +1 -1
  12. package/dist/adxcgBidAdapter.js +1 -1
  13. package/dist/adyoulikeBidAdapter.js +1 -1
  14. package/dist/ajaBidAdapter.js +1 -1
  15. package/dist/amxBidAdapter.js +1 -1
  16. package/dist/amxIdSystem.js +1 -1
  17. package/dist/appierAnalyticsAdapter.js +1 -1
  18. package/dist/appnexusBidAdapter.js +1 -1
  19. package/dist/asoBidAdapter.js +1 -1
  20. package/dist/axonixBidAdapter.js +1 -1
  21. package/dist/beopBidAdapter.js +1 -1
  22. package/dist/bidglassBidAdapter.js +1 -1
  23. package/dist/big-richmediaBidAdapter.js +1 -1
  24. package/dist/bridBidAdapter.js +1 -0
  25. package/dist/bridgewellBidAdapter.js +1 -1
  26. package/dist/brightMountainMediaBidAdapter.js +1 -1
  27. package/dist/carodaBidAdapter.js +1 -1
  28. package/dist/categoryTranslation.js +1 -1
  29. package/dist/chtnwBidAdapter.js +1 -1
  30. package/dist/cmp.js +1 -0
  31. package/dist/concertBidAdapter.js +1 -1
  32. package/dist/connectadBidAdapter.js +1 -1
  33. package/dist/consentManagement.js +1 -1
  34. package/dist/consentManagementGpp.js +1 -1
  35. package/dist/consentManagementUsp.js +1 -1
  36. package/dist/consumableBidAdapter.js +1 -1
  37. package/dist/conversantAnalyticsAdapter.js +1 -1
  38. package/dist/conversantBidAdapter.js +1 -1
  39. package/dist/craftBidAdapter.js +1 -1
  40. package/dist/criteoBidAdapter.js +1 -1
  41. package/dist/cwireBidAdapter.js +1 -1
  42. package/dist/dependencies.json +15 -0
  43. package/dist/discoveryBidAdapter.js +1 -1
  44. package/dist/dspxBidAdapter.js +1 -1
  45. package/dist/eplanningBidAdapter.js +1 -1
  46. package/dist/euidIdSystem.js +1 -1
  47. package/dist/feedadBidAdapter.js +1 -1
  48. package/dist/finativeBidAdapter.js +1 -1
  49. package/dist/freewheel-sspBidAdapter.js +1 -1
  50. package/dist/gmosspBidAdapter.js +1 -1
  51. package/dist/goldbachBidAdapter.js +1 -1
  52. package/dist/gppControl_usnat.js +1 -0
  53. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  54. package/dist/greenbidsRtdProvider.js +1 -1
  55. package/dist/gridBidAdapter.js +1 -1
  56. package/dist/gumgumBidAdapter.js +1 -1
  57. package/dist/h12mediaBidAdapter.js +1 -1
  58. package/dist/holidBidAdapter.js +1 -1
  59. package/dist/hypelabBidAdapter.js +1 -1
  60. package/dist/id5IdSystem.js +1 -1
  61. package/dist/imdsBidAdapter.js +1 -1
  62. package/dist/improvedigitalBidAdapter.js +1 -1
  63. package/dist/insticatorBidAdapter.js +1 -1
  64. package/dist/intentIqIdSystem.js +1 -1
  65. package/dist/ixBidAdapter.js +1 -1
  66. package/dist/justpremiumBidAdapter.js +1 -1
  67. package/dist/kargoBidAdapter.js +1 -1
  68. package/dist/konduitAnalyticsAdapter.js +1 -1
  69. package/dist/kueezBidAdapter.js +1 -1
  70. package/dist/kueezRtbBidAdapter.js +1 -1
  71. package/dist/kulturemediaBidAdapter.js +1 -1
  72. package/dist/lassoBidAdapter.js +1 -1
  73. package/dist/lifestreetBidAdapter.js +1 -1
  74. package/dist/liveIntentIdSystem.js +1 -1
  75. package/dist/livewrappedAnalyticsAdapter.js +1 -1
  76. package/dist/logicadBidAdapter.js +1 -1
  77. package/dist/loglyliftBidAdapter.js +1 -1
  78. package/dist/magniteAnalyticsAdapter.js +1 -1
  79. package/dist/malltvAnalyticsAdapter.js +1 -1
  80. package/dist/marsmediaBidAdapter.js +1 -1
  81. package/dist/mediafuseBidAdapter.js +1 -1
  82. package/dist/mediagoBidAdapter.js +1 -1
  83. package/dist/mediasquareBidAdapter.js +1 -1
  84. package/dist/mgidBidAdapter.js +1 -1
  85. package/dist/minutemediaBidAdapter.js +1 -1
  86. package/dist/minutemediaplusBidAdapter.js +1 -1
  87. package/dist/mspa.js +1 -0
  88. package/dist/nexx360BidAdapter.js +1 -1
  89. package/dist/not-for-prod/prebid.js +144 -140
  90. package/dist/oguryBidAdapter.js +1 -1
  91. package/dist/onetagBidAdapter.js +1 -1
  92. package/dist/ooloAnalyticsAdapter.js +1 -1
  93. package/dist/optidigitalBidAdapter.js +1 -1
  94. package/dist/outbrainBidAdapter.js +1 -1
  95. package/dist/oxxionRtdProvider.js +1 -1
  96. package/dist/parrableIdSystem.js +1 -1
  97. package/dist/pixfutureBidAdapter.js +1 -1
  98. package/dist/prebid-core.js +1 -1
  99. package/dist/publinkIdSystem.js +1 -1
  100. package/dist/pubmaticBidAdapter.js +1 -1
  101. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  102. package/dist/pxyzBidAdapter.js +1 -1
  103. package/dist/quantcastBidAdapter.js +1 -1
  104. package/dist/readpeakBidAdapter.js +1 -1
  105. package/dist/relaidoBidAdapter.js +1 -1
  106. package/dist/retailspotBidAdapter.js +1 -1
  107. package/dist/rhythmoneBidAdapter.js +1 -1
  108. package/dist/riseBidAdapter.js +1 -1
  109. package/dist/rubiconBidAdapter.js +1 -1
  110. package/dist/seedingAllianceBidAdapter.js +1 -1
  111. package/dist/seedtagBidAdapter.js +1 -1
  112. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  113. package/dist/sharethroughBidAdapter.js +1 -1
  114. package/dist/shinezBidAdapter.js +1 -1
  115. package/dist/smaatoBidAdapter.js +1 -1
  116. package/dist/smartadserverBidAdapter.js +1 -1
  117. package/dist/smartxBidAdapter.js +1 -1
  118. package/dist/smartyadsBidAdapter.js +1 -1
  119. package/dist/smilewantedBidAdapter.js +1 -1
  120. package/dist/sonobiBidAdapter.js +1 -1
  121. package/dist/sovrnAnalyticsAdapter.js +1 -1
  122. package/dist/sovrnBidAdapter.js +1 -1
  123. package/dist/sspBCBidAdapter.js +1 -1
  124. package/dist/stvBidAdapter.js +1 -1
  125. package/dist/sublimeBidAdapter.js +1 -1
  126. package/dist/targetVideoBidAdapter.js +1 -1
  127. package/dist/teadsBidAdapter.js +1 -1
  128. package/dist/trafficgateBidAdapter.js +1 -1
  129. package/dist/trionBidAdapter.js +1 -1
  130. package/dist/tripleliftBidAdapter.js +1 -1
  131. package/dist/ttdBidAdapter.js +1 -1
  132. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  133. package/dist/uid2IdSystem.js +1 -1
  134. package/dist/underdogmediaBidAdapter.js +1 -1
  135. package/dist/undertoneBidAdapter.js +1 -1
  136. package/dist/userId.js +1 -1
  137. package/dist/vidazooBidAdapter.js +1 -1
  138. package/dist/videobyteBidAdapter.js +1 -1
  139. package/dist/visxBidAdapter.js +1 -1
  140. package/dist/vuukleBidAdapter.js +1 -1
  141. package/dist/widespaceBidAdapter.js +1 -1
  142. package/dist/winrBidAdapter.js +1 -1
  143. package/dist/yahoosspBidAdapter.js +1 -1
  144. package/dist/yieldmoBidAdapter.js +1 -1
  145. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  146. package/libraries/cmp/cmpClient.js +139 -0
  147. package/libraries/mspa/activityControls.js +91 -0
  148. package/modules/adagioBidAdapter.js +2 -1
  149. package/modules/admanBidAdapter.js +5 -0
  150. package/modules/adtelligentBidAdapter.js +8 -0
  151. package/modules/beopBidAdapter.js +6 -6
  152. package/modules/beopBidAdapter.md +35 -1
  153. package/modules/bridBidAdapter.js +223 -0
  154. package/modules/cadentApertureMXBidAdapter.md +2 -2
  155. package/modules/categoryTranslation.js +3 -2
  156. package/modules/consentManagement.js +12 -86
  157. package/modules/consentManagementGpp.js +47 -126
  158. package/modules/consentManagementUsp.js +19 -97
  159. package/modules/discoveryBidAdapter.js +1 -1
  160. package/modules/gppControl_usnat.js +11 -0
  161. package/modules/holidBidAdapter.js +49 -30
  162. package/modules/intentIqIdSystem.js +6 -5
  163. package/modules/ixBidAdapter.js +2 -1
  164. package/modules/liveIntentIdSystem.js +8 -3
  165. package/modules/livewrappedAnalyticsAdapter.js +33 -33
  166. package/modules/mediagoBidAdapter.js +1 -0
  167. package/modules/mediasquareBidAdapter.js +19 -23
  168. package/modules/oxxionRtdProvider.js +124 -11
  169. package/modules/oxxionRtdProvider.md +19 -4
  170. package/modules/smartyadsBidAdapter.js +6 -3
  171. package/modules/sovrnBidAdapter.js +5 -0
  172. package/modules/trafficgateBidAdapter.js +126 -72
  173. package/modules/tripleliftBidAdapter.js +21 -1
  174. package/modules/userId/eids.js +29 -0
  175. package/modules/userId/eids.md +19 -2
  176. package/modules/userId/index.js +78 -29
  177. package/modules/userId/userId.md +3 -0
  178. package/modules/vidazooBidAdapter.js +68 -16
  179. package/package.json +1 -1
  180. package/src/activities/params.js +4 -1
  181. package/test/spec/libraries/cmp/cmpClient_spec.js +233 -0
  182. package/test/spec/libraries/mspa/activityControls_spec.js +315 -0
  183. package/test/spec/modules/adagioBidAdapter_spec.js +2 -1
  184. package/test/spec/modules/admanBidAdapter_spec.js +8 -2
  185. package/test/spec/modules/adqueryBidAdapter_spec.js +5 -1
  186. package/test/spec/modules/adtelligentBidAdapter_spec.js +8 -0
  187. package/test/spec/modules/beopBidAdapter_spec.js +18 -2
  188. package/test/spec/modules/bridBidAdapter_spec.js +129 -0
  189. package/test/spec/modules/byDataAnalyticsAdapter_spec.js +9 -7
  190. package/test/spec/modules/cadentApertureMXBidAdapter_spec.js +1 -1
  191. package/test/spec/modules/chtnwBidAdapter_spec.js +4 -1
  192. package/test/spec/modules/consentManagementGpp_spec.js +84 -7
  193. package/test/spec/modules/consentManagement_spec.js +8 -18
  194. package/test/spec/modules/datablocksBidAdapter_spec.js +7 -3
  195. package/test/spec/modules/eids_spec.js +87 -0
  196. package/test/spec/modules/holidBidAdapter_spec.js +26 -6
  197. package/test/spec/modules/insticatorBidAdapter_spec.js +6 -2
  198. package/test/spec/modules/intentIqIdSystem_spec.js +36 -2
  199. package/test/spec/modules/ixBidAdapter_spec.js +52 -18
  200. package/test/spec/modules/lassoBidAdapter_spec.js +6 -4
  201. package/test/spec/modules/liveIntentIdMinimalSystem_spec.js +17 -2
  202. package/test/spec/modules/liveIntentIdSystem_spec.js +11 -6
  203. package/test/spec/modules/mediasquareBidAdapter_spec.js +3 -0
  204. package/test/spec/modules/onetagBidAdapter_spec.js +81 -75
  205. package/test/spec/modules/orbidderBidAdapter_spec.js +6 -3
  206. package/test/spec/modules/oxxionRtdProvider_spec.js +113 -1
  207. package/test/spec/modules/relaidoBidAdapter_spec.js +4 -3
  208. package/test/spec/modules/smartyadsBidAdapter_spec.js +1 -1
  209. package/test/spec/modules/sovrnBidAdapter_spec.js +34 -0
  210. package/test/spec/modules/trafficgateBidAdapter_spec.js +1349 -199
  211. package/test/spec/modules/tripleliftBidAdapter_spec.js +20 -1
  212. package/test/spec/modules/ucfunnelBidAdapter_spec.js +37 -16
  213. package/test/spec/modules/userId_spec.js +393 -6
  214. package/test/spec/modules/vidazooBidAdapter_spec.js +131 -0
@@ -1,4 +1,11 @@
1
- import {deepAccess, getBidIdParameter, isStr, logMessage, triggerPixel, } from '../src/utils.js';
1
+ import {
2
+ deepAccess,
3
+ deepSetValue,
4
+ getBidIdParameter,
5
+ isStr,
6
+ logMessage,
7
+ triggerPixel,
8
+ } from '../src/utils.js';
2
9
  import * as events from '../src/events.js';
3
10
  import CONSTANTS from '../src/constants.json';
4
11
  import {BANNER} from '../src/mediaTypes.js';
@@ -10,6 +17,7 @@ const GVLID = 1177
10
17
  const ENDPOINT = 'https://helloworld.holid.io/openrtb2/auction'
11
18
  const COOKIE_SYNC_ENDPOINT = 'https://null.holid.io/sync.html'
12
19
  const TIME_TO_LIVE = 300
20
+ const TMAX = 500
13
21
  let wurlMap = {}
14
22
 
15
23
  events.on(CONSTANTS.EVENTS.BID_WON, bidWonHandler)
@@ -23,12 +31,19 @@ export const spec = {
23
31
  return !!bid.params.adUnitID
24
32
  },
25
33
 
26
- buildRequests: function (validBidRequests, _bidderRequest) {
34
+ buildRequests: function (validBidRequests, bidderRequest) {
27
35
  return validBidRequests.map((bid) => {
28
36
  const requestData = {
29
37
  ...bid.ortb2,
30
- id: _bidderRequest.bidderRequestId,
38
+ source: {schain: bid.schain},
39
+ id: bidderRequest.bidderRequestId,
31
40
  imp: [getImp(bid)],
41
+ tmax: TMAX,
42
+ ...buildStoredRequest(bid)
43
+ }
44
+
45
+ if (bid.userIdAsEids) {
46
+ deepSetValue(requestData, 'user.ext.eids', bid.userIdAsEids)
32
47
  }
33
48
 
34
49
  return {
@@ -50,8 +65,6 @@ export const spec = {
50
65
  serverResponse.body.seatbid.map((response) => {
51
66
  response.bid.map((bid) => {
52
67
  const requestId = bidRequest.bidId
53
- // TODO: fix auctionId leak: https://github.com/prebid/Prebid.js/issues/9781
54
- const auctionId = bidRequest.auctionId
55
68
  const wurl = deepAccess(bid, 'ext.prebid.events.win')
56
69
  const bidResponse = {
57
70
  requestId,
@@ -65,7 +78,7 @@ export const spec = {
65
78
  ttl: TIME_TO_LIVE,
66
79
  }
67
80
 
68
- addWurl({ auctionId, requestId, wurl })
81
+ addWurl(requestId, wurl)
69
82
 
70
83
  bidResponses.push(bidResponse)
71
84
  })
@@ -75,11 +88,15 @@ export const spec = {
75
88
  },
76
89
 
77
90
  getUserSyncs(optionsType, serverResponse, gdprConsent, uspConsent) {
91
+ const syncs = [{
92
+ type: 'image',
93
+ url: 'https://track.adform.net/Serving/TrackPoint/?pm=2992097&lid=132720821'
94
+ }]
95
+
78
96
  if (!serverResponse || serverResponse.length === 0) {
79
- return []
97
+ return syncs
80
98
  }
81
99
 
82
- const syncs = []
83
100
  const bidders = getBidders(serverResponse)
84
101
 
85
102
  if (optionsType.iframeEnabled && bidders) {
@@ -100,24 +117,14 @@ export const spec = {
100
117
  type: 'iframe',
101
118
  url: COOKIE_SYNC_ENDPOINT + strQueryParams + '&type=iframe',
102
119
  })
103
-
104
- return syncs
105
120
  }
106
121
 
107
- return []
122
+ return syncs
108
123
  },
109
124
  }
110
125
 
111
126
  function getImp(bid) {
112
- const imp = {
113
- ext: {
114
- prebid: {
115
- storedrequest: {
116
- id: getBidIdParameter('adUnitID', bid.params),
117
- },
118
- },
119
- },
120
- }
127
+ const imp = buildStoredRequest(bid)
121
128
  const sizes =
122
129
  bid.sizes && !Array.isArray(bid.sizes[0]) ? [bid.sizes] : bid.sizes
123
130
 
@@ -132,6 +139,18 @@ function getImp(bid) {
132
139
  return imp
133
140
  }
134
141
 
142
+ function buildStoredRequest(bid) {
143
+ return {
144
+ ext: {
145
+ prebid: {
146
+ storedrequest: {
147
+ id: getBidIdParameter('adUnitID', bid.params),
148
+ },
149
+ },
150
+ },
151
+ }
152
+ }
153
+
135
154
  function getBidders(serverResponse) {
136
155
  const bidders = serverResponse
137
156
  .map((res) => Object.keys(res.body.ext.responsetimemillis || []))
@@ -142,28 +161,28 @@ function getBidders(serverResponse) {
142
161
  }
143
162
  }
144
163
 
145
- function addWurl(auctionId, adId, wurl) {
146
- if ([auctionId, adId].every(isStr)) {
147
- wurlMap[`${auctionId}${adId}`] = wurl
164
+ function addWurl(requestId, wurl) {
165
+ if (isStr(requestId)) {
166
+ wurlMap[requestId] = wurl
148
167
  }
149
168
  }
150
169
 
151
- function removeWurl(auctionId, adId) {
152
- delete wurlMap[`${auctionId}${adId}`]
170
+ function removeWurl(requestId) {
171
+ delete wurlMap[requestId]
153
172
  }
154
173
 
155
- function getWurl(auctionId, adId) {
156
- if ([auctionId, adId].every(isStr)) {
157
- return wurlMap[`${auctionId}${adId}`]
174
+ function getWurl(requestId) {
175
+ if (isStr(requestId)) {
176
+ return wurlMap[requestId]
158
177
  }
159
178
  }
160
179
 
161
180
  function bidWonHandler(bid) {
162
- const wurl = getWurl(bid.auctionId, bid.adId)
181
+ const wurl = getWurl(bid.requestId)
163
182
  if (wurl) {
164
183
  logMessage(`Invoking image pixel for wurl on BID_WIN: "${wurl}"`)
165
184
  triggerPixel(wurl)
166
- removeWurl(bid.auctionId, bid.adId)
185
+ removeWurl(bid.requestId)
167
186
  }
168
187
  }
169
188
 
@@ -59,7 +59,7 @@ export function readData(key) {
59
59
  * @param key
60
60
  * @param {string} value IntentIQ ID value to sintentIqIdSystem_spec.jstore
61
61
  */
62
- function storeData(key, value) {
62
+ function storeData(key, value, cookieStorageEnabled = false) {
63
63
  try {
64
64
  logInfo(MODULE_NAME + ': storing data: key=' + key + ' value=' + value);
65
65
 
@@ -68,7 +68,7 @@ function storeData(key, value) {
68
68
  storage.setDataInLocalStorage(key, value);
69
69
  }
70
70
  const expiresStr = (new Date(Date.now() + (PCID_EXPIRY * (60 * 60 * 24 * 1000)))).toUTCString();
71
- if (storage.cookiesAreEnabled()) {
71
+ if (storage.cookiesAreEnabled() && cookieStorageEnabled) {
72
72
  storage.setCookie(key, value, expiresStr, 'LAX');
73
73
  }
74
74
  }
@@ -119,6 +119,7 @@ export const intentIqIdSubmodule = {
119
119
  logError('User ID - intentIqId submodule requires a valid partner to be defined');
120
120
  return;
121
121
  }
122
+ const cookieStorageEnabled = typeof configParams.enableCookieStorage === 'boolean' ? configParams.enableCookieStorage : false
122
123
  if (!FIRST_PARTY_DATA_KEY.includes(configParams.partner)) { FIRST_PARTY_DATA_KEY += '_' + configParams.partner; }
123
124
  let rrttStrtTime = 0;
124
125
 
@@ -127,7 +128,7 @@ export const intentIqIdSubmodule = {
127
128
  if (!firstPartyData || !firstPartyData.pcid || firstPartyData.pcidDate) {
128
129
  const firstPartyId = generateGUID();
129
130
  firstPartyData = { 'pcid': firstPartyId, 'pcidDate': Date.now() };
130
- storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData));
131
+ storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), cookieStorageEnabled);
131
132
  }
132
133
 
133
134
  let partnerData = tryParse(readData(FIRST_PARTY_DATA_KEY));
@@ -172,8 +173,8 @@ export const intentIqIdSubmodule = {
172
173
  }
173
174
  if (shouldUpdateLs === true) {
174
175
  partnerData.date = Date.now();
175
- storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData));
176
- storeData(FIRST_PARTY_DATA_KEY, JSON.stringify(partnerData));
176
+ storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), cookieStorageEnabled);
177
+ storeData(FIRST_PARTY_DATA_KEY, JSON.stringify(partnerData), cookieStorageEnabled);
177
178
  }
178
179
  callback(respJson.data);
179
180
  } else {
@@ -76,7 +76,8 @@ const SOURCE_RTI_MAPPING = {
76
76
  'audigent.com': '', // Hadron ID from Audigent, hadronId
77
77
  'pubcid.org': '', // SharedID, pubcid
78
78
  'utiq.com': '', // Utiq
79
- 'intimatemerger.com': ''
79
+ 'intimatemerger.com': '',
80
+ '33across.com': ''
80
81
  };
81
82
  const PROVIDERS = [
82
83
  'britepoolid',
@@ -14,6 +14,7 @@ import {MODULE_TYPE_UID} from '../src/activities/modules.js';
14
14
 
15
15
  const EVENTS_TOPIC = 'pre_lips'
16
16
  const MODULE_NAME = 'liveIntentId';
17
+ const LI_PROVIDER_DOMAIN = 'liveintent.com';
17
18
  export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME});
18
19
  const defaultRequestedAttributes = {'nonId': true}
19
20
  const calls = {
@@ -189,15 +190,19 @@ export const liveIntentIdSubmodule = {
189
190
  // As adapters are applied in lexicographical order, we will always
190
191
  // be overwritten by the 'proper' uid2 module if it is present.
191
192
  if (value.uid2) {
192
- result.uid2 = { 'id': value.uid2 }
193
+ result.uid2 = { 'id': value.uid2, ext: { provider: LI_PROVIDER_DOMAIN } }
193
194
  }
194
195
 
195
196
  if (value.bidswitch) {
196
- result.bidswitch = { 'id': value.bidswitch }
197
+ result.bidswitch = { 'id': value.bidswitch, ext: { provider: LI_PROVIDER_DOMAIN } }
197
198
  }
198
199
 
199
200
  if (value.medianet) {
200
- result.medianet = { 'id': value.medianet }
201
+ result.medianet = { 'id': value.medianet, ext: { provider: LI_PROVIDER_DOMAIN } }
202
+ }
203
+
204
+ if (value.magnite) {
205
+ result.magnite = { 'id': value.magnite, ext: { provider: LI_PROVIDER_DOMAIN } }
201
206
  }
202
207
 
203
208
  return result
@@ -168,7 +168,7 @@ livewrappedAnalyticsAdapter.sendEvents = function() {
168
168
  requests: sentRequests.sentRequests,
169
169
  responses: getResponses(sentRequests.gdpr, sentRequests.auctionIds),
170
170
  wins: getWins(sentRequests.gdpr, sentRequests.auctionIds),
171
- timeouts: getTimeouts(sentRequests.auctionIds),
171
+ timeouts: getTimeouts(sentRequests.gdpr, sentRequests.auctionIds),
172
172
  bidAdUnits: getbidAdUnits(),
173
173
  rf: getAdRenderFailed(sentRequests.auctionIds),
174
174
  rcv: getAdblockerRecovered()
@@ -237,27 +237,9 @@ function getResponses(gdpr, auctionIds) {
237
237
  if (bid.readyToSend && !(bid.sendStatus & RESPONSESENT) && !bid.timeout) {
238
238
  bid.sendStatus |= RESPONSESENT;
239
239
 
240
- responses.push({
241
- timeStamp: auction.timeStamp,
242
- adUnit: bid.adUnit,
243
- adUnitId: bid.adUnitId,
244
- bidder: bid.bidder,
245
- width: bid.width,
246
- height: bid.height,
247
- cpm: bid.cpm,
248
- orgCpm: bid.originalCpm,
249
- ttr: bid.ttr,
250
- IsBid: bid.isBid,
251
- mediaType: bid.mediaType,
252
- gdpr: gdprPos,
253
- floor: bid.lwFloor ? bid.lwFloor : (bid.floorData ? bid.floorData.floorValue : undefined),
254
- floorCur: bid.floorData ? bid.floorData.floorCurrency : undefined,
255
- auctionId: auctionIdPos,
256
- auc: bid.auc,
257
- buc: bid.buc,
258
- lw: bid.lw,
259
- meta: bid.meta
260
- });
240
+ let response = getResponseObject(auction, bid, gdprPos, auctionIdPos);
241
+
242
+ responses.push(response);
261
243
  }
262
244
  });
263
245
  });
@@ -337,27 +319,45 @@ function getAuctionIdPos(auctionIds, auctionId) {
337
319
  return auctionIdPos;
338
320
  }
339
321
 
340
- function getTimeouts(auctionIds) {
322
+ function getResponseObject(auction, bid, gdprPos, auctionIdPos) {
323
+ return {
324
+ timeStamp: auction.timeStamp,
325
+ adUnit: bid.adUnit,
326
+ adUnitId: bid.adUnitId,
327
+ bidder: bid.bidder,
328
+ width: bid.width,
329
+ height: bid.height,
330
+ cpm: bid.cpm,
331
+ orgCpm: bid.originalCpm,
332
+ ttr: bid.ttr,
333
+ IsBid: bid.isBid,
334
+ mediaType: bid.mediaType,
335
+ gdpr: gdprPos,
336
+ floor: bid.lwFloor ? bid.lwFloor : (bid.floorData ? bid.floorData.floorValue : undefined),
337
+ floorCur: bid.floorData ? bid.floorData.floorCurrency : undefined,
338
+ auctionId: auctionIdPos,
339
+ auc: bid.auc,
340
+ buc: bid.buc,
341
+ lw: bid.lw,
342
+ meta: bid.meta
343
+ };
344
+ }
345
+
346
+ function getTimeouts(gdpr, auctionIds) {
341
347
  var timeouts = [];
342
348
 
343
349
  Object.keys(cache.auctions).forEach(auctionId => {
344
350
  let auctionIdPos = getAuctionIdPos(auctionIds, auctionId);
345
351
  Object.keys(cache.auctions[auctionId].bids).forEach(bidId => {
346
352
  let auction = cache.auctions[auctionId];
353
+ let gdprPos = getGdprPos(gdpr, auction);
347
354
  let bid = auction.bids[bidId];
348
355
  if (!(bid.sendStatus & TIMEOUTSENT) && bid.timeout) {
349
356
  bid.sendStatus |= TIMEOUTSENT;
350
357
 
351
- timeouts.push({
352
- bidder: bid.bidder,
353
- adUnit: bid.adUnit,
354
- adUnitId: bid.adUnitId,
355
- timeStamp: auction.timeStamp,
356
- auctionId: auctionIdPos,
357
- auc: bid.auc,
358
- buc: bid.buc,
359
- lw: bid.lw
360
- });
358
+ let timeout = getResponseObject(auction, bid, gdprPos, auctionIdPos);
359
+
360
+ timeouts.push(timeout);
361
361
  }
362
362
  });
363
363
  });
@@ -242,6 +242,7 @@ function getItems(validBidRequests, bidderRequest) {
242
242
  ext: {
243
243
  // gpid: gpid, // 加入后无法返回广告
244
244
  },
245
+ tagid: req.params && req.params.tagid,
245
246
  };
246
247
  itemMaps[id] = {
247
248
  req,
@@ -120,23 +120,17 @@ export const spec = {
120
120
  netRevenue: value['net_revenue'],
121
121
  ttl: value['ttl'],
122
122
  ad: value['ad'],
123
- mediasquare: {
124
- 'bidder': value['bidder'],
125
- 'code': value['code']
126
- },
123
+ mediasquare: {},
127
124
  meta: {
128
125
  'advertiserDomains': value['adomain']
129
126
  }
130
127
  };
131
- if ('context' in value) {
132
- bidResponse['mediasquare']['context'] = value['context'];
133
- }
134
- if ('match' in value) {
135
- bidResponse['mediasquare']['match'] = value['match'];
136
- }
137
- if ('hasConsent' in value) {
138
- bidResponse['mediasquare']['hasConsent'] = value['hasConsent'];
139
- }
128
+ let paramsToSearchFor = ['bidder', 'code', 'match', 'hasConsent', 'context', 'increment'];
129
+ paramsToSearchFor.forEach(param => {
130
+ if (param in value) {
131
+ bidResponse['mediasquare'][param] = value[param];
132
+ }
133
+ });
140
134
  if ('native' in value) {
141
135
  bidResponse['native'] = value['native'];
142
136
  bidResponse['mediaType'] = 'native';
@@ -180,21 +174,23 @@ export const spec = {
180
174
  }
181
175
  let params = { pbjs: '$prebid.version$', referer: encodeURIComponent(getRefererInfo().page || getRefererInfo().topmostLocation) };
182
176
  let endpoint = document.location.search.match(/msq_test=true/) ? BIDDER_URL_TEST : BIDDER_URL_PROD;
183
- let paramsToSearchFor = ['bidder', 'code', 'match', 'hasConsent', 'context'];
177
+ let paramsToSearchFor = ['bidder', 'code', 'match', 'hasConsent', 'context', 'increment'];
184
178
  if (bid.hasOwnProperty('mediasquare')) {
185
- for (let i = 0; i < paramsToSearchFor.length; i++) {
186
- if (bid['mediasquare'].hasOwnProperty(paramsToSearchFor[i])) {
187
- params[paramsToSearchFor[i]] = bid['mediasquare'][paramsToSearchFor[i]];
179
+ paramsToSearchFor.forEach(param => {
180
+ if (bid['mediasquare'].hasOwnProperty(param)) {
181
+ params[param] = bid['mediasquare'][param];
188
182
  }
189
- }
183
+ });
190
184
  };
191
185
  paramsToSearchFor = ['cpm', 'size', 'mediaType', 'currency', 'creativeId', 'adUnitCode', 'timeToRespond', 'requestId', 'auctionId', 'originalCpm', 'originalCurrency'];
192
- for (let i = 0; i < paramsToSearchFor.length; i++) {
193
- if (bid.hasOwnProperty(paramsToSearchFor[i])) {
194
- params[paramsToSearchFor[i]] = bid[paramsToSearchFor[i]];
195
- if (typeof params[paramsToSearchFor[i]] == 'number') { params[paramsToSearchFor[i]] = params[paramsToSearchFor[i]].toString() }
186
+ paramsToSearchFor.forEach(param => {
187
+ if (bid.hasOwnProperty(param)) {
188
+ params[param] = bid[param];
189
+ if (typeof params[param] == 'number') {
190
+ params[param] = params[param].toString();
191
+ }
196
192
  }
197
- }
193
+ });
198
194
  ajax(endpoint + BIDDER_ENDPOINT_WINNING, null, JSON.stringify(params), {method: 'POST', withCredentials: true});
199
195
  return true;
200
196
  }
@@ -1,10 +1,13 @@
1
1
  import { submodule } from '../src/hook.js'
2
- import { deepAccess, logInfo } from '../src/utils.js'
2
+ import { deepAccess, logInfo, logError } from '../src/utils.js'
3
+ import { ajax } from '../src/ajax.js';
4
+ import adapterManager from '../src/adapterManager.js';
3
5
 
4
6
  const oxxionRtdSearchFor = [ 'adUnitCode', 'auctionId', 'bidder', 'bidderCode', 'bidId', 'cpm', 'creativeId', 'currency', 'width', 'height', 'mediaType', 'netRevenue', 'originalCpm', 'originalCurrency', 'requestId', 'size', 'source', 'status', 'timeToRespond', 'transactionId', 'ttl', 'sizes', 'mediaTypes', 'src', 'userId', 'labelAny', 'adId' ];
5
7
  const LOG_PREFIX = 'oxxionRtdProvider submodule: ';
6
8
 
7
9
  const allAdUnits = [];
10
+ const bidderAliasRegistry = adapterManager.aliasRegistry || {};
8
11
 
9
12
  /** @type {RtdSubmodule} */
10
13
  export const oxxionSubmodule = {
@@ -12,23 +15,56 @@ export const oxxionSubmodule = {
12
15
  init: init,
13
16
  getBidRequestData: getAdUnits,
14
17
  onBidResponseEvent: insertVideoTracking,
18
+ getRequestsList: getRequestsList,
19
+ getFilteredAdUnitsOnBidRates: getFilteredAdUnitsOnBidRates,
15
20
  };
16
21
 
17
22
  function init(config, userConsent) {
18
- if (!config.params || !config.params.domain || !config.params.contexts || !Array.isArray(config.params.contexts) || config.params.contexts.length == 0) {
19
- return false
20
- }
21
- return true;
23
+ if (!config.params || !config.params.domain) { return false }
24
+ if (config.params.contexts && Array.isArray(config.params.contexts) && config.params.contexts.length > 0) { return true; }
25
+ if (typeof config.params.threshold != 'undefined' && typeof config.params.samplingRate == 'number') { return true }
26
+ return false;
22
27
  }
23
28
 
24
29
  function getAdUnits(reqBidsConfigObj, callback, config, userConsent) {
25
- const reqAdUnits = reqBidsConfigObj.adUnits;
26
- if (Array.isArray(reqAdUnits)) {
27
- reqAdUnits.forEach(adunit => {
28
- if (config.params.contexts.includes(deepAccess(adunit, 'mediaTypes.video.context'))) {
29
- allAdUnits.push(adunit);
30
+ logInfo(LOG_PREFIX + 'started with ', config);
31
+ if (typeof config.params.threshold != 'undefined' && typeof config.params.samplingRate == 'number') {
32
+ let filteredBids;
33
+ const requests = getRequestsList(reqBidsConfigObj);
34
+ const gdpr = userConsent && userConsent.gdpr ? userConsent.gdpr.consentString : null;
35
+ const payload = {
36
+ gdpr,
37
+ requests
38
+ };
39
+ const endpoint = 'https://' + config.params.domain + '.oxxion.io/analytics/bid_rate_interests';
40
+ getPromisifiedAjax(endpoint, JSON.stringify(payload), {
41
+ method: 'POST',
42
+ withCredentials: true
43
+ }).then(bidsRateInterests => {
44
+ if (bidsRateInterests.length) {
45
+ [reqBidsConfigObj.adUnits, filteredBids] = getFilteredAdUnitsOnBidRates(bidsRateInterests, reqBidsConfigObj.adUnits, config.params, true);
30
46
  }
31
- });
47
+ if (filteredBids.length > 0) {
48
+ getPromisifiedAjax('https://' + config.params.domain + '.oxxion.io/analytics/request_rejecteds', JSON.stringify({'bids': filteredBids, 'gdpr': gdpr}), {
49
+ method: 'POST',
50
+ withCredentials: true
51
+ });
52
+ }
53
+ if (typeof callback == 'function') { callback(); }
54
+ }).catch(error => logError(LOG_PREFIX, 'bidInterestError', error));
55
+ }
56
+ if (config.params.contexts && Array.isArray(config.params.contexts) && config.params.contexts.length > 0) {
57
+ const reqAdUnits = reqBidsConfigObj.adUnits;
58
+ if (Array.isArray(reqAdUnits)) {
59
+ reqAdUnits.forEach(adunit => {
60
+ if (config.params.contexts.includes(deepAccess(adunit, 'mediaTypes.video.context'))) {
61
+ allAdUnits.push(adunit);
62
+ }
63
+ });
64
+ }
65
+ if (!(typeof config.params.threshold != 'undefined' && typeof config.params.samplingRate == 'number') && typeof callback == 'function') {
66
+ callback();
67
+ }
32
68
  }
33
69
  }
34
70
 
@@ -94,4 +130,81 @@ function getImpUrl(config, data, maxCpm) {
94
130
  return trackingImpUrl + 'cpmIncrement=' + cpmIncrement + '&context=' + context;
95
131
  }
96
132
 
133
+ function getPromisifiedAjax (url, data = {}, options = {}) {
134
+ return new Promise((resolve, reject) => {
135
+ const callbacks = {
136
+ success(responseText, { response }) {
137
+ resolve(JSON.parse(response));
138
+ },
139
+ error(error) {
140
+ reject(error);
141
+ }
142
+ };
143
+ ajax(url, callbacks, data, options);
144
+ })
145
+ }
146
+
147
+ function getFilteredAdUnitsOnBidRates (bidsRateInterests, adUnits, params, useSampling) {
148
+ const { threshold, samplingRate } = params;
149
+ const filteredBids = [];
150
+ // Separate bidsRateInterests in two groups against threshold & samplingRate
151
+ const { interestingBidsRates, uninterestingBidsRates } = bidsRateInterests.reduce((acc, interestingBid) => {
152
+ const isBidRateUpper = typeof threshold == 'number' ? interestingBid.rate === true || interestingBid.rate > threshold : interestingBid.suggestion;
153
+ const isBidInteresting = isBidRateUpper || (getRandomNumber(100) < samplingRate && useSampling);
154
+ const key = isBidInteresting ? 'interestingBidsRates' : 'uninterestingBidsRates';
155
+ acc[key].push(interestingBid);
156
+ return acc;
157
+ }, {
158
+ interestingBidsRates: [],
159
+ uninterestingBidsRates: [] // Do something with later
160
+ });
161
+ logInfo(LOG_PREFIX, 'getFilteredAdUnitsOnBidRates()', interestingBidsRates, uninterestingBidsRates);
162
+ // Filter bids and adUnits against interesting bids rates
163
+ const newAdUnits = adUnits.filter(({ bids = [] }, adUnitIndex) => {
164
+ adUnits[adUnitIndex].bids = bids.filter(bid => {
165
+ if (!params.bidders || params.bidders.includes(bid.bidder)) {
166
+ const index = interestingBidsRates.findIndex(({ id }) => id === bid._id);
167
+ if (index == -1) {
168
+ let tmpBid = bid;
169
+ tmpBid['code'] = adUnits[adUnitIndex].code;
170
+ tmpBid['mediaTypes'] = adUnits[adUnitIndex].mediaTypes;
171
+ tmpBid['originalBidder'] = bidderAliasRegistry[bid.bidder] || bid.bidder;
172
+ if (tmpBid.floorData) {
173
+ delete tmpBid.floorData;
174
+ }
175
+ filteredBids.push(tmpBid);
176
+ }
177
+ delete bid._id;
178
+ return index !== -1;
179
+ } else {
180
+ return true;
181
+ }
182
+ });
183
+ return !!adUnits[adUnitIndex].bids.length;
184
+ });
185
+ return [newAdUnits, filteredBids];
186
+ }
187
+
188
+ function getRandomNumber (max = 10) {
189
+ return Math.round(Math.random() * max);
190
+ }
191
+
192
+ function getRequestsList(reqBidsConfigObj) {
193
+ let count = 0;
194
+ return reqBidsConfigObj.adUnits.flatMap(({
195
+ bids = [],
196
+ mediaTypes = {},
197
+ code = ''
198
+ }) => bids.reduce((acc, { bidder = '', params = {} }, index) => {
199
+ const id = count++;
200
+ bids[index]._id = id;
201
+ return acc.concat({
202
+ id,
203
+ adUnit: code,
204
+ bidder,
205
+ mediaTypes,
206
+ });
207
+ }, []));
208
+ }
209
+
97
210
  submodule('realTimeData', oxxionSubmodule);
@@ -7,12 +7,12 @@ Maintainer: tech@oxxion.io
7
7
  # Oxxion Real-Time-Data submodule
8
8
 
9
9
  Oxxion helps you to understand how your prebid stack performs.
10
- This Rtd module is to use in order to improve video events tracking.
10
+ This Rtd module is to use in order to improve video events tracking and/or to filter bidder requested.
11
11
 
12
12
  # Integration
13
13
 
14
14
  Make sure to have the following modules listed while building prebid : `rtdModule,oxxionRtdProvider`
15
- `rtbModule` is required to activate real-time-data submodules.
15
+ `rtdModule` is required to activate real-time-data submodules.
16
16
  For example :
17
17
  ```
18
18
  gulp build --modules=schain,priceFloors,currency,consentManagement,appnexusBidAdapter,rubiconBidAdapter,rtdModule,oxxionRtdProvider
@@ -23,7 +23,7 @@ Then add the oxxion Rtd module to your prebid configuration :
23
23
  pbjs.setConfig(
24
24
  ...
25
25
  realTimeData: {
26
- auctionDelay: 200,
26
+ auctionDelay: 300,
27
27
  dataProviders: [
28
28
  {
29
29
  name: "oxxionRtd",
@@ -31,6 +31,8 @@ pbjs.setConfig(
31
31
  params: {
32
32
  domain: "test.endpoint",
33
33
  contexts: ["instream"],
34
+ threshold: false,
35
+ samplingRate: 10,
34
36
  }
35
37
  }
36
38
  ]
@@ -39,10 +41,23 @@ pbjs.setConfig(
39
41
  )
40
42
  ```
41
43
 
42
- # setConfig Parameters
44
+ # setConfig Parameters General
43
45
 
44
46
  | Name | Type | Description |
45
47
  |:---------------------------------|:---------|:------------------------------------------------------------------------------------------------------------|
46
48
  | domain | String | This string identifies yourself in Oxxion's systems and is provided to you by your Oxxion representative. |
49
+
50
+ # setConfig Parameters for Video Tracking
51
+
52
+ | Name | Type | Description |
53
+ |:---------------------------------|:---------|:------------------------------------------------------------------------------------------------------------|
47
54
  | contexts | Array | Array defining which video contexts to add tracking events into. Values can be instream and/or outstream. |
48
55
 
56
+ # setConfig Parameters for bidder filtering
57
+
58
+ | Name | Type | Description |
59
+ |:---------------------------------|:-----------|:------------------------------------------------------------------------------------------------------------|
60
+ | threshold | Float/Bool | False or minimum expected bid rate to call a bidder (ex: 1.0 for 1% bid rate). |
61
+ | samplingRate | Integer | Percentage of request not meeting the criterias to run anyway in order to check for any change. |
62
+ | bidders | Array | Optional: If set, filtering will only be applied to bidders listed.
63
+
@@ -66,6 +66,9 @@ export const spec = {
66
66
  if (bidderRequest.gdprConsent) {
67
67
  request.gdpr = bidderRequest.gdprConsent
68
68
  }
69
+ if (bidderRequest.gppConsent) {
70
+ request.gpp = bidderRequest.gppConsent;
71
+ }
69
72
  }
70
73
  const len = validBidRequests.length;
71
74
 
@@ -102,19 +105,19 @@ export const spec = {
102
105
  return response;
103
106
  },
104
107
 
105
- getUserSyncs: (syncOptions, serverResponses = [], gdprConsent = {}, uspConsent = '') => {
108
+ getUserSyncs: (syncOptions, serverResponses = [], gdprConsent = {}, uspConsent = '', gppConsent = '') => {
106
109
  let syncs = [];
107
110
  let { gdprApplies, consentString = '' } = gdprConsent;
108
111
 
109
112
  if (syncOptions.iframeEnabled) {
110
113
  syncs.push({
111
114
  type: 'iframe',
112
- url: `${URL_SYNC}&gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${consentString}&type=iframe&us_privacy=${uspConsent}`
115
+ url: `${URL_SYNC}&gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${consentString}&type=iframe&us_privacy=${uspConsent}&gpp=${gppConsent}`
113
116
  });
114
117
  } else {
115
118
  syncs.push({
116
119
  type: 'image',
117
- url: `${URL_SYNC}&gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${consentString}&type=image&us_privacy=${uspConsent}`
120
+ url: `${URL_SYNC}&gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${consentString}&type=image&us_privacy=${uspConsent}&gpp=${gppConsent}`
118
121
  });
119
122
  }
120
123