prebid.js 8.6.0 → 8.8.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 (222) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/33acrossIdSystem.js +1 -1
  3. package/dist/a1MediaRtdProvider.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/admaticBidAdapter.js +1 -1
  8. package/dist/adqueryBidAdapter.js +1 -1
  9. package/dist/adqueryIdSystem.js +1 -1
  10. package/dist/adrelevantisBidAdapter.js +1 -1
  11. package/dist/adsinteractiveBidAdapter.js +1 -1
  12. package/dist/adtrgtmeBidAdapter.js +1 -1
  13. package/dist/adxcgBidAdapter.js +1 -1
  14. package/dist/adyoulikeBidAdapter.js +1 -1
  15. package/dist/ajaBidAdapter.js +1 -1
  16. package/dist/alkimiBidAdapter.js +1 -1
  17. package/dist/amxBidAdapter.js +1 -1
  18. package/dist/amxIdSystem.js +1 -1
  19. package/dist/appierAnalyticsAdapter.js +1 -1
  20. package/dist/appnexusBidAdapter.js +1 -1
  21. package/dist/asoBidAdapter.js +1 -1
  22. package/dist/automatadAnalyticsAdapter.js +1 -0
  23. package/dist/axonixBidAdapter.js +1 -1
  24. package/dist/bidViewability.js +1 -1
  25. package/dist/bidglassBidAdapter.js +1 -1
  26. package/dist/big-richmediaBidAdapter.js +1 -1
  27. package/dist/brandmetricsRtdProvider.js +1 -1
  28. package/dist/bridBidAdapter.js +1 -1
  29. package/dist/bridgewellBidAdapter.js +1 -1
  30. package/dist/brightMountainMediaBidAdapter.js +1 -1
  31. package/dist/carodaBidAdapter.js +1 -1
  32. package/dist/chtnwBidAdapter.js +1 -1
  33. package/dist/concertBidAdapter.js +1 -1
  34. package/dist/connatixBidAdapter.js +1 -0
  35. package/dist/connectadBidAdapter.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 +7 -1
  43. package/dist/dspxBidAdapter.js +1 -1
  44. package/dist/eplanningBidAdapter.js +1 -1
  45. package/dist/euidIdSystem.js +1 -1
  46. package/dist/feedadBidAdapter.js +1 -1
  47. package/dist/finativeBidAdapter.js +1 -1
  48. package/dist/freepassBidAdapter.js +1 -1
  49. package/dist/freewheel-sspBidAdapter.js +1 -1
  50. package/dist/geoedgeRtdProvider.js +1 -1
  51. package/dist/gmosspBidAdapter.js +1 -1
  52. package/dist/goldbachBidAdapter.js +1 -1
  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/hypelabBidAdapter.js +1 -1
  59. package/dist/id5IdSystem.js +1 -1
  60. package/dist/imdsBidAdapter.js +1 -1
  61. package/dist/improvedigitalBidAdapter.js +1 -1
  62. package/dist/insticatorBidAdapter.js +1 -1
  63. package/dist/ixBidAdapter.js +1 -1
  64. package/dist/justpremiumBidAdapter.js +1 -1
  65. package/dist/kargoBidAdapter.js +1 -1
  66. package/dist/konduitAnalyticsAdapter.js +1 -1
  67. package/dist/kueezBidAdapter.js +1 -1
  68. package/dist/kueezRtbBidAdapter.js +1 -1
  69. package/dist/kulturemediaBidAdapter.js +1 -1
  70. package/dist/lassoBidAdapter.js +1 -1
  71. package/dist/lifestreetBidAdapter.js +1 -1
  72. package/dist/liveIntentIdSystem.js +1 -1
  73. package/dist/logicadBidAdapter.js +1 -1
  74. package/dist/loglyliftBidAdapter.js +1 -1
  75. package/dist/magniteAnalyticsAdapter.js +1 -1
  76. package/dist/malltvAnalyticsAdapter.js +1 -1
  77. package/dist/marsmediaBidAdapter.js +1 -1
  78. package/dist/mediafuseBidAdapter.js +1 -1
  79. package/dist/medianetBidAdapter.js +1 -1
  80. package/dist/mediasquareBidAdapter.js +1 -1
  81. package/dist/mgidBidAdapter.js +1 -1
  82. package/dist/minutemediaBidAdapter.js +1 -1
  83. package/dist/minutemediaplusBidAdapter.js +1 -1
  84. package/dist/nativoBidAdapter.js +1 -1
  85. package/dist/nexx360BidAdapter.js +1 -1
  86. package/dist/not-for-prod/prebid.js +145 -142
  87. package/dist/oguryBidAdapter.js +1 -1
  88. package/dist/onetagBidAdapter.js +1 -1
  89. package/dist/ooloAnalyticsAdapter.js +1 -1
  90. package/dist/operaadsBidAdapter.js +1 -1
  91. package/dist/operaadsIdSystem.js +1 -0
  92. package/dist/optidigitalBidAdapter.js +1 -1
  93. package/dist/outbrainBidAdapter.js +1 -1
  94. package/dist/oxxionAnalyticsAdapter.js +1 -1
  95. package/dist/parrableIdSystem.js +1 -1
  96. package/dist/pixfutureBidAdapter.js +1 -1
  97. package/dist/prebid-core.js +1 -1
  98. package/dist/publinkIdSystem.js +1 -1
  99. package/dist/pubmaticBidAdapter.js +1 -1
  100. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  101. package/dist/pxyzBidAdapter.js +1 -1
  102. package/dist/quantcastBidAdapter.js +1 -1
  103. package/dist/readpeakBidAdapter.js +1 -1
  104. package/dist/relaidoBidAdapter.js +1 -1
  105. package/dist/retailspotBidAdapter.js +1 -1
  106. package/dist/rhythmoneBidAdapter.js +1 -1
  107. package/dist/riseBidAdapter.js +1 -1
  108. package/dist/rubiconBidAdapter.js +1 -1
  109. package/dist/seedingAllianceBidAdapter.js +1 -1
  110. package/dist/seedtagBidAdapter.js +1 -1
  111. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  112. package/dist/sharethroughBidAdapter.js +1 -1
  113. package/dist/shinezBidAdapter.js +1 -1
  114. package/dist/smaatoBidAdapter.js +1 -1
  115. package/dist/smartadserverBidAdapter.js +1 -1
  116. package/dist/smartxBidAdapter.js +1 -1
  117. package/dist/smartyadsBidAdapter.js +1 -1
  118. package/dist/smilewantedBidAdapter.js +1 -1
  119. package/dist/snigelBidAdapter.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/tappxBidAdapter.js +1 -1
  127. package/dist/targetVideoBidAdapter.js +1 -1
  128. package/dist/teadsBidAdapter.js +1 -1
  129. package/dist/topicsFpdModule.js +1 -1
  130. package/dist/trionBidAdapter.js +1 -1
  131. package/dist/tripleliftBidAdapter.js +1 -1
  132. package/dist/ttdBidAdapter.js +1 -1
  133. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  134. package/dist/uid2IdSystem.js +1 -1
  135. package/dist/underdogmediaBidAdapter.js +1 -1
  136. package/dist/undertoneBidAdapter.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/integrationExamples/topics/topics-server.js +72 -0
  147. package/modules/.submodules.json +2 -1
  148. package/modules/a1MediaRtdProvider.js +1 -1
  149. package/modules/adagioBidAdapter.js +15 -1
  150. package/modules/adgenerationBidAdapter.js +4 -3
  151. package/modules/admaticBidAdapter.js +5 -0
  152. package/modules/adqueryBidAdapter.js +23 -21
  153. package/modules/adqueryIdSystem.js +45 -30
  154. package/modules/adrelevantisBidAdapter.js +2 -0
  155. package/modules/adsinteractiveBidAdapter.js +2 -0
  156. package/modules/alkimiBidAdapter.js +19 -7
  157. package/modules/automatadAnalyticsAdapter.js +325 -0
  158. package/modules/automatadAnalyticsAdapter.md +23 -0
  159. package/modules/bidViewability.js +7 -0
  160. package/modules/bidViewability.md +9 -8
  161. package/modules/brandmetricsRtdProvider.js +30 -27
  162. package/modules/connatixBidAdapter.js +185 -0
  163. package/modules/connatixBidAdapter.md +37 -0
  164. package/modules/criteoBidAdapter.js +73 -50
  165. package/modules/freepassBidAdapter.js +20 -1
  166. package/modules/freepassBidAdapter.md +4 -1
  167. package/modules/geoedgeRtdProvider.js +43 -13
  168. package/modules/geoedgeRtdProvider.md +2 -1
  169. package/modules/gridBidAdapter.js +1 -8
  170. package/modules/liveIntentIdSystem.js +16 -1
  171. package/modules/medianetBidAdapter.js +7 -4
  172. package/modules/mediasquareBidAdapter.js +3 -0
  173. package/modules/nativoBidAdapter.js +21 -3
  174. package/modules/onetagBidAdapter.js +3 -0
  175. package/modules/operaadsBidAdapter.js +5 -0
  176. package/modules/operaadsBidAdapter.md +5 -5
  177. package/modules/operaadsIdSystem.js +106 -0
  178. package/modules/operaadsIdSystem.md +52 -0
  179. package/modules/optidigitalBidAdapter.js +25 -16
  180. package/modules/oxxionAnalyticsAdapter.js +22 -5
  181. package/modules/rubiconBidAdapter.js +2 -2
  182. package/modules/smartyadsBidAdapter.js +18 -1
  183. package/modules/snigelBidAdapter.js +69 -16
  184. package/modules/snigelBidAdapter.md +9 -3
  185. package/modules/tappxBidAdapter.js +17 -14
  186. package/modules/topicsFpdModule.js +35 -9
  187. package/modules/undertoneBidAdapter.md +1 -1
  188. package/modules/userId/eids.md +7 -0
  189. package/modules/visxBidAdapter.js +51 -1
  190. package/package.json +2 -2
  191. package/src/adloader.js +1 -0
  192. package/src/native.js +2 -2
  193. package/test/spec/modules/adagioBidAdapter_spec.js +89 -0
  194. package/test/spec/modules/adgenerationBidAdapter_spec.js +6 -6
  195. package/test/spec/modules/admaticBidAdapter_spec.js +5 -0
  196. package/test/spec/modules/adqueryIdSystem_spec.js +13 -24
  197. package/test/spec/modules/alkimiBidAdapter_spec.js +3 -9
  198. package/test/spec/modules/automatadAnalyticsAdapter_spec.js +533 -0
  199. package/test/spec/modules/bidViewability_spec.js +32 -1
  200. package/test/spec/modules/brandmetricsRtdProvider_spec.js +6 -0
  201. package/test/spec/modules/connatixBidAdapter_spec.js +366 -0
  202. package/test/spec/modules/criteoBidAdapter_spec.js +249 -0
  203. package/test/spec/modules/eids_spec.js +48 -0
  204. package/test/spec/modules/freepassBidAdapter_spec.js +44 -0
  205. package/test/spec/modules/geoedgeRtdProvider_spec.js +44 -24
  206. package/test/spec/modules/gridBidAdapter_spec.js +68 -0
  207. package/test/spec/modules/liveIntentIdMinimalSystem_spec.js +5 -0
  208. package/test/spec/modules/liveIntentIdSystem_spec.js +5 -0
  209. package/test/spec/modules/medianetBidAdapter_spec.js +18 -18
  210. package/test/spec/modules/mediasquareBidAdapter_spec.js +5 -0
  211. package/test/spec/modules/nativoBidAdapter_spec.js +6 -1
  212. package/test/spec/modules/onetagBidAdapter_spec.js +69 -0
  213. package/test/spec/modules/operaadsIdSystem_spec.js +53 -0
  214. package/test/spec/modules/optidigitalBidAdapter_spec.js +9 -2
  215. package/test/spec/modules/oxxionAnalyticsAdapter_spec.js +6 -1
  216. package/test/spec/modules/rubiconBidAdapter_spec.js +24 -0
  217. package/test/spec/modules/smartyadsBidAdapter_spec.js +49 -0
  218. package/test/spec/modules/snigelBidAdapter_spec.js +57 -6
  219. package/test/spec/modules/tappxBidAdapter_spec.js +19 -0
  220. package/test/spec/modules/topicsFpdModule_spec.js +102 -1
  221. package/test/spec/modules/visxBidAdapter_spec.js +151 -1
  222. package/test/spec/native_spec.js +5 -3
@@ -0,0 +1,52 @@
1
+ # Opera ID System
2
+
3
+ For help adding this module, please contact [adtech-prebid-group@opera.com](adtech-prebid-group@opera.com).
4
+
5
+ ### Prebid Configuration
6
+
7
+ You should configure this module under your `userSync.userIds[]` configuration:
8
+
9
+ ```javascript
10
+ pbjs.setConfig({
11
+ userSync: {
12
+ userIds: [
13
+ {
14
+ name: "operaId",
15
+ storage: {
16
+ name: "operaId",
17
+ type: "html5",
18
+ expires: 14
19
+ },
20
+ params: {
21
+ pid: "your-pulisher-ID-here"
22
+ }
23
+ }
24
+ ]
25
+ }
26
+ })
27
+ ```
28
+ <br>
29
+
30
+ | Param under `userSync.userIds[]` | Scope | Type | Description | Example |
31
+ | -------------------------------- | -------- | ------ | ----------------------------- | ----------------------------------------- |
32
+ | name | Required | string | ID for the operaId module | `"operaId"` |
33
+ | storage | Optional | Object | Settings for operaId storage | See [storage settings](#storage-settings) |
34
+ | params | Required | Object | Parameters for opreaId module | See [params](#params) |
35
+ <br>
36
+
37
+ ### Params
38
+
39
+ | Param under `params` | Scope | Type | Description | Example |
40
+ | -------------------- | -------- | ------ | ------------------------------ | --------------- |
41
+ | pid | Required | string | Publisher ID assigned by Opera | `"pub12345678"` |
42
+ <br>
43
+
44
+ ### Storage Settings
45
+
46
+ The following settings are suggested for the `storage` property in the `userSync.userIds[]` object:
47
+
48
+ | Param under `storage` | Type | Description | Example |
49
+ | --------------------- | ------------- | -------------------------------------------------------------------------------- | ----------- |
50
+ | name | String | Where the ID will be stored | `"operaId"` |
51
+ | type | String | For best performance, this should be `"html5"` | `"html5"` |
52
+ | expires | Number <= 30 | number of days until the stored ID expires. **Must be less than or equal to 30** | `14` |
@@ -7,6 +7,7 @@ const GVL_ID = 915;
7
7
  const ENDPOINT_URL = 'https://pbs.optidigital.com/bidder';
8
8
  const USER_SYNC_URL_IFRAME = 'https://scripts.opti-digital.com/js/presync.html?endpoint=optidigital';
9
9
  let CUR = 'USD';
10
+ let isSynced = false;
10
11
 
11
12
  export const spec = {
12
13
  code: BIDDER_CODE,
@@ -46,8 +47,6 @@ export const spec = {
46
47
  referrer: (bidderRequest.refererInfo && bidderRequest.refererInfo.page) ? bidderRequest.refererInfo.page : '',
47
48
  hb_version: '$prebid.version$',
48
49
  deviceWidth: document.documentElement.clientWidth,
49
- // TODO: fix auctionId leak: https://github.com/prebid/Prebid.js/issues/9781
50
- auctionId: deepAccess(validBidRequests[0], 'auctionId'),
51
50
  bidderRequestId: deepAccess(validBidRequests[0], 'bidderRequestId'),
52
51
  publisherId: deepAccess(validBidRequests[0], 'params.publisherId'),
53
52
  imp: validBidRequests.map(bidRequest => buildImp(bidRequest, ortb2)),
@@ -56,6 +55,10 @@ export const spec = {
56
55
  bapp: deepAccess(validBidRequests[0], 'params.bapp') || []
57
56
  }
58
57
 
58
+ if (validBidRequests[0].auctionId) {
59
+ payload.auctionId = validBidRequests[0].auctionId;
60
+ }
61
+
59
62
  if (validBidRequests[0].params.pageTemplate && validBidRequests[0].params.pageTemplate !== '') {
60
63
  payload.pageTemplate = validBidRequests[0].params.pageTemplate;
61
64
  }
@@ -136,21 +139,23 @@ export const spec = {
136
139
  */
137
140
  getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) {
138
141
  let syncurl = '';
142
+ if (!isSynced) {
143
+ // Attaching GDPR Consent Params in UserSync url
144
+ if (gdprConsent) {
145
+ syncurl += '&gdpr=' + (gdprConsent.gdprApplies ? 1 : 0);
146
+ syncurl += '&gdpr_consent=' + encodeURIComponent(gdprConsent.consentString || '');
147
+ }
148
+ if (uspConsent && uspConsent.consentString) {
149
+ syncurl += `&ccpa_consent=${uspConsent.consentString}`;
150
+ }
139
151
 
140
- // Attaching GDPR Consent Params in UserSync url
141
- if (gdprConsent) {
142
- syncurl += '&gdpr=' + (gdprConsent.gdprApplies ? 1 : 0);
143
- syncurl += '&gdpr_consent=' + encodeURIComponent(gdprConsent.consentString || '');
144
- }
145
- if (uspConsent && uspConsent.consentString) {
146
- syncurl += `&ccpa_consent=${uspConsent.consentString}`;
147
- }
148
-
149
- if (syncOptions.iframeEnabled) {
150
- return [{
151
- type: 'iframe',
152
- url: USER_SYNC_URL_IFRAME + syncurl
153
- }];
152
+ if (syncOptions.iframeEnabled) {
153
+ isSynced = true;
154
+ return [{
155
+ type: 'iframe',
156
+ url: USER_SYNC_URL_IFRAME + syncurl
157
+ }];
158
+ }
154
159
  }
155
160
  },
156
161
  };
@@ -218,4 +223,8 @@ function _getFloor (bid, sizes, currency) {
218
223
  return floor !== null ? floor : bid.params.floor;
219
224
  }
220
225
 
226
+ export function resetSync() {
227
+ isSynced = false;
228
+ }
229
+
221
230
  registerBidder(spec);
@@ -21,6 +21,7 @@ let saveEvents = {}
21
21
  let allEvents = {}
22
22
  let auctionEnd = {}
23
23
  let initOptions = {}
24
+ let mode = {};
24
25
  let endpoint = 'https://default'
25
26
  let requestsAttributes = ['adUnitCode', 'auctionId', 'bidder', 'bidderCode', 'bidId', 'cpm', 'creativeId', 'currency', 'width', 'height', 'mediaType', 'netRevenue', 'originalCpm', 'originalCurrency', 'requestId', 'size', 'source', 'status', 'timeToRespond', 'transactionId', 'ttl', 'sizes', 'mediaTypes', 'src', 'params', 'userId', 'labelAny', 'bids', 'adId'];
26
27
 
@@ -41,16 +42,27 @@ function filterAttributes(arg, removead) {
41
42
  }
42
43
  if (typeof arg['gdprConsent'] != 'undefined') {
43
44
  response['gdprConsent'] = {};
44
- if (typeof arg['gdprConsent']['consentString'] != 'undefined') { response['gdprConsent']['consentString'] = arg['gdprConsent']['consentString']; }
45
+ if (typeof arg['gdprConsent']['consentString'] != 'undefined') {
46
+ response['gdprConsent']['consentString'] = arg['gdprConsent']['consentString'];
47
+ }
45
48
  }
46
- if (typeof arg['meta'] == 'object' && typeof arg['meta']['advertiserDomains'] != 'undefined') {
47
- response['meta'] = {'advertiserDomains': arg['meta']['advertiserDomains']};
49
+ if (typeof arg['meta'] == 'object') {
50
+ response['meta'] = {};
51
+ if (typeof arg['meta']['advertiserDomains'] != 'undefined') {
52
+ response['meta']['advertiserDomains'] = arg['meta']['advertiserDomains'];
53
+ }
54
+ if (typeof arg['meta']['demandSource'] == 'string') {
55
+ response['meta']['demandSource'] = arg['meta']['demandSource'];
56
+ }
48
57
  }
49
58
  requestsAttributes.forEach((attr) => {
50
59
  if (typeof arg[attr] != 'undefined') { response[attr] = arg[attr]; }
51
60
  });
52
- if (typeof response['creativeId'] == 'number') { response['creativeId'] = response['creativeId'].toString(); }
61
+ if (typeof response['creativeId'] == 'number') {
62
+ response['creativeId'] = response['creativeId'].toString();
63
+ }
53
64
  }
65
+ response['oxxionMode'] = mode;
54
66
  return response;
55
67
  }
56
68
 
@@ -229,7 +241,12 @@ oxxionAnalytics.originEnableAnalytics = oxxionAnalytics.enableAnalytics;
229
241
  oxxionAnalytics.enableAnalytics = function (config) {
230
242
  oxxionAnalytics.originEnableAnalytics(config); // call the base class function
231
243
  initOptions = config.options;
232
- if (initOptions.domain) { endpoint = 'https://' + initOptions.domain; }
244
+ if (initOptions.domain) {
245
+ endpoint = 'https://' + initOptions.domain;
246
+ }
247
+ if (window.OXXION_MODE) {
248
+ mode = window.OXXION_MODE;
249
+ }
233
250
  };
234
251
 
235
252
  adapterManager.registerAnalyticsAdapter({
@@ -27,7 +27,7 @@ const DEFAULT_PBS_INTEGRATION = 'pbjs';
27
27
  const DEFAULT_RENDERER_URL = 'https://video-outstream.rubiconproject.com/apex-2.2.1.js';
28
28
  // renderer code at https://github.com/rubicon-project/apex2
29
29
 
30
- let rubiConf = {};
30
+ let rubiConf = config.getConfig('rubicon') || {};
31
31
  // we are saving these as global to this module so that if a pub accidentally overwrites the entire
32
32
  // rubicon object, then we do not lose other data
33
33
  config.getConfig('rubicon', config => {
@@ -322,7 +322,7 @@ export const spec = {
322
322
  )
323
323
  );
324
324
  });
325
- if (config.getConfig('rubicon.singleRequest') !== true) {
325
+ if (rubiConf.singleRequest !== true) {
326
326
  // bids are not grouped if single request mode is not enabled
327
327
  requests = filteredHttpRequest.concat(bannerBidRequests.map(bidRequest => {
328
328
  const bidParams = spec.createSlotParams(bidRequest, bidderRequest);
@@ -3,6 +3,7 @@ import {registerBidder} from '../src/adapters/bidderFactory.js';
3
3
  import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
4
4
  import { config } from '../src/config.js';
5
5
  import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
6
+ import { ajax } from '../src/ajax.js';
6
7
 
7
8
  const BIDDER_CODE = 'smartyads';
8
9
  const AD_URL = 'https://n1.smartyads.com/?c=o&m=prebid&secret_key=prebid_js';
@@ -122,7 +123,23 @@ export const spec = {
122
123
  }
123
124
 
124
125
  return syncs
125
- }
126
+ },
127
+
128
+ onBidWon: function(bid) {
129
+ if (bid.winUrl) {
130
+ ajax(bid.winUrl, () => {}, JSON.stringify(bid));
131
+ } else {
132
+ ajax('https://et-nd43.itdsmr.com/?c=o&m=prebid&secret_key=prebid_js&winTest=1', () => {}, JSON.stringify(bid));
133
+ }
134
+ },
135
+
136
+ onTimeout: function(bid) {
137
+ ajax('https://et-nd43.itdsmr.com/?c=o&m=prebid&secret_key=prebid_js&bidTimeout=1', () => {}, JSON.stringify(bid));
138
+ },
139
+
140
+ onBidderError: function(bid) {
141
+ ajax('https://et-nd43.itdsmr.com/?c=o&m=prebid&secret_key=prebid_js&bidderError=1', () => {}, JSON.stringify(bid));
142
+ },
126
143
 
127
144
  };
128
145
 
@@ -1,7 +1,7 @@
1
1
  import {config} from '../src/config.js';
2
2
  import {registerBidder} from '../src/adapters/bidderFactory.js';
3
3
  import {BANNER} from '../src/mediaTypes.js';
4
- import {deepAccess, isArray, isFn, isPlainObject} from '../src/utils.js';
4
+ import {deepAccess, isArray, isFn, isPlainObject, inIframe, getDNT} from '../src/utils.js';
5
5
  import {hasPurpose1Consent} from '../src/utils/gpdr.js';
6
6
  import {getGlobal} from '../src/prebidGlobal.js';
7
7
 
@@ -13,6 +13,7 @@ const DEFAULT_CURRENCIES = ['USD'];
13
13
  const FLOOR_MATCH_ALL_SIZES = '*';
14
14
 
15
15
  const getConfig = config.getConfig;
16
+ const refreshes = {};
16
17
 
17
18
  export const spec = {
18
19
  code: BIDDER_CODE,
@@ -29,12 +30,15 @@ export const spec = {
29
30
  method: 'POST',
30
31
  url: getEndpoint(),
31
32
  data: JSON.stringify({
32
- id: bidderRequest.bidderRequestId,
33
+ id: bidderRequest.auctionId,
34
+ accountId: deepAccess(bidRequests, '0.params.accountId'),
35
+ site: deepAccess(bidRequests, '0.params.site'),
33
36
  cur: getCurrencies(),
34
37
  test: getTestFlag(),
35
- devw: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
36
- devh: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight,
37
38
  version: getGlobal().version,
39
+ gpp: deepAccess(bidderRequest, 'gppConsent.gppString') || deepAccess(bidderRequest, 'ortb2.regs.gpp'),
40
+ gpp_sid:
41
+ deepAccess(bidderRequest, 'gppConsent.applicableSections') || deepAccess(bidderRequest, 'ortb2.regs.gpp_sid'),
38
42
  gdprApplies: gdprApplies,
39
43
  gdprConsentString: gdprApplies === true ? deepAccess(bidderRequest, 'gdprConsent.consentString') : undefined,
40
44
  gdprConsentProv: gdprApplies === true ? deepAccess(bidderRequest, 'gdprConsent.addtlConsent') : undefined,
@@ -43,12 +47,24 @@ export const spec = {
43
47
  eids: deepAccess(bidRequests, '0.userIdAsEids'),
44
48
  schain: deepAccess(bidRequests, '0.schain'),
45
49
  page: getPage(bidderRequest),
50
+ topframe: inIframe() === true ? 0 : 1,
51
+ device: {
52
+ w: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
53
+ h: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight,
54
+ dnt: getDNT() ? 1 : 0,
55
+ language: getLanguage(),
56
+ },
46
57
  placements: bidRequests.map((r) => {
47
58
  return {
48
- uuid: r.bidId,
59
+ id: r.adUnitCode,
60
+ tid: r.transactionId,
61
+ gpid: deepAccess(r, 'ortb2Imp.ext.gpid'),
62
+ pbadslot: deepAccess(r, 'ortb2Imp.ext.data.pbadslot') || deepAccess(r, 'ortb2Imp.ext.gpid'),
49
63
  name: r.params.placement,
50
64
  sizes: r.sizes,
51
65
  floor: getPriceFloor(r, BANNER, FLOOR_MATCH_ALL_SIZES),
66
+ refresh: getRefreshInformation(r.adUnitCode),
67
+ params: r.params.additionalParams,
52
68
  };
53
69
  }),
54
70
  }),
@@ -56,14 +72,14 @@ export const spec = {
56
72
  };
57
73
  },
58
74
 
59
- interpretResponse: function (serverResponse) {
75
+ interpretResponse: function (serverResponse, bidRequest) {
60
76
  if (!serverResponse.body || !serverResponse.body.bids) {
61
77
  return [];
62
78
  }
63
79
 
64
80
  return serverResponse.body.bids.map((bid) => {
65
81
  return {
66
- requestId: bid.uuid,
82
+ requestId: mapIdToRequestId(bid.id, bidRequest),
67
83
  cpm: bid.price,
68
84
  creativeId: bid.crid,
69
85
  currency: serverResponse.body.cur,
@@ -77,9 +93,9 @@ export const spec = {
77
93
  });
78
94
  },
79
95
 
80
- getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent) {
96
+ getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent, gppConsent) {
81
97
  const syncUrl = getSyncUrl(responses || []);
82
- if (syncUrl && syncOptions.iframeEnabled && hasSyncConsent(gdprConsent, uspConsent)) {
98
+ if (syncUrl && syncOptions.iframeEnabled && hasSyncConsent(gdprConsent, uspConsent, gppConsent)) {
83
99
  return [{type: 'iframe', url: getSyncEndpoint(syncUrl, gdprConsent)}];
84
100
  }
85
101
  },
@@ -101,6 +117,14 @@ function getTestFlag() {
101
117
  return getConfig(`${BIDDER_CODE}.test`) === true;
102
118
  }
103
119
 
120
+ function getLanguage() {
121
+ return navigator && navigator.language
122
+ ? navigator.language.indexOf('-') != -1
123
+ ? navigator.language.split('-')[0]
124
+ : navigator.language
125
+ : undefined;
126
+ }
127
+
104
128
  function getCurrencies() {
105
129
  const currencyOverrides = getConfig(`${BIDDER_CODE}.cur`);
106
130
  if (currencyOverrides !== undefined && (!isArray(currencyOverrides) || currencyOverrides.length === 0)) {
@@ -130,14 +154,43 @@ function getPriceFloor(bidRequest, mediaType, size) {
130
154
  }
131
155
  }
132
156
 
133
- function hasSyncConsent(gdprConsent, uspConsent) {
134
- if (gdprConsent?.gdprApplies && !hasPurpose1Consent(gdprConsent)) {
135
- return false;
136
- } else if (uspConsent && uspConsent[1] === 'Y' && uspConsent[2] === 'Y') {
137
- return false;
138
- } else {
139
- return true;
157
+ function getRefreshInformation(adUnitCode) {
158
+ const refresh = refreshes[adUnitCode];
159
+ if (!refresh) {
160
+ refreshes[adUnitCode] = {
161
+ count: 0,
162
+ previousTime: new Date(),
163
+ };
164
+ return undefined;
140
165
  }
166
+
167
+ const currentTime = new Date();
168
+ const timeDifferenceSeconds = Math.floor((currentTime - refresh.previousTime) / 1000);
169
+ refresh.count += 1;
170
+ refresh.previousTime = currentTime;
171
+ return {
172
+ count: refresh.count,
173
+ time: timeDifferenceSeconds,
174
+ };
175
+ }
176
+
177
+ function mapIdToRequestId(id, bidRequest) {
178
+ return bidRequest.bidderRequest.bids.filter((bid) => bid.adUnitCode === id)[0].bidId;
179
+ }
180
+
181
+ function hasUspConsent(uspConsent) {
182
+ return typeof uspConsent !== 'string' || !(uspConsent[0] === '1' && uspConsent[2] === 'Y');
183
+ }
184
+
185
+ function hasGppConsent(gppConsent) {
186
+ return (
187
+ !(gppConsent && Array.isArray(gppConsent.applicableSections)) ||
188
+ gppConsent.applicableSections.every((section) => typeof section === 'number' && section <= 5)
189
+ );
190
+ }
191
+
192
+ function hasSyncConsent(gdprConsent, uspConsent, gppConsent) {
193
+ return hasPurpose1Consent(gdprConsent) && hasUspConsent(uspConsent) && hasGppConsent(gppConsent);
141
194
  }
142
195
 
143
196
  function getSyncUrl(responses) {
@@ -15,9 +15,13 @@ Please reach out to us [through our contact form](https://snigel.com/get-in-touc
15
15
 
16
16
  # Parameters
17
17
 
18
- | Name | Required | Description | Example |
19
- | :--- | :-------- | :---------- | :------ |
20
- | placement | Yes | Placement identifier | top_leaderboard |
18
+ | Name | Required | Description |
19
+ | :-------- | :------- | :------------------- |
20
+ | accountId | Yes | Account identifier |
21
+ | site | Yes | Site identifier |
22
+ | placement | Yes | Placement identifier |
23
+
24
+ Snigel will provide all of these parameters to you.
21
25
 
22
26
  # Test
23
27
 
@@ -37,6 +41,8 @@ var adUnits = [
37
41
  {
38
42
  bidder: "snigel",
39
43
  params: {
44
+ accountId: "1000",
45
+ site: "test.com",
40
46
  placement: "prebid_test_placement",
41
47
  },
42
48
  },
@@ -12,7 +12,7 @@ const BIDDER_CODE = 'tappx';
12
12
  const GVLID_CODE = 628;
13
13
  const TTL = 360;
14
14
  const CUR = 'USD';
15
- const TAPPX_BIDDER_VERSION = '0.1.2';
15
+ const TAPPX_BIDDER_VERSION = '0.1.3';
16
16
  const TYPE_CNN = 'prebidjs';
17
17
  const LOG_PREFIX = '[TAPPX]: ';
18
18
  const VIDEO_SUPPORT = ['instream', 'outstream'];
@@ -146,22 +146,22 @@ function validBasic(bid) {
146
146
  return false;
147
147
  }
148
148
 
149
- if (bid.params.tappxkey == null) {
149
+ if (!bid.params.tappxkey) {
150
150
  logWarn(LOG_PREFIX, 'Please review the mandatory Tappxkey parameter.');
151
151
  return false;
152
152
  }
153
153
 
154
- if (bid.params.host == null) {
154
+ if (!bid.params.host) {
155
155
  logWarn(LOG_PREFIX, 'Please review the mandatory Host parameter.');
156
156
  return false;
157
157
  }
158
158
 
159
- let classicEndpoint = true
159
+ let classicEndpoint = true;
160
160
  if ((new RegExp(`^(vz.*|zz.*)\\.*$`, 'i')).test(bid.params.host)) {
161
- classicEndpoint = false
161
+ classicEndpoint = false;
162
162
  }
163
163
 
164
- if (classicEndpoint && bid.params.endpoint == null) {
164
+ if (classicEndpoint && !bid.params.endpoint) {
165
165
  logWarn(LOG_PREFIX, 'Please review the mandatory endpoint Tappx parameters.');
166
166
  return false;
167
167
  }
@@ -191,7 +191,7 @@ function validMediaType(bid) {
191
191
  */
192
192
  function interpretBid(serverBid, request) {
193
193
  let bidReturned = {
194
- requestId: request.bids.bidId,
194
+ requestId: request.bids?.bidId,
195
195
  cpm: serverBid.price,
196
196
  currency: serverBid.cur ? serverBid.cur : CUR,
197
197
  width: serverBid.w,
@@ -206,7 +206,7 @@ function interpretBid(serverBid, request) {
206
206
  if (typeof serverBid.nurl != 'undefined') { bidReturned.nurl = serverBid.nurl }
207
207
  if (typeof serverBid.burl != 'undefined') { bidReturned.burl = serverBid.burl }
208
208
 
209
- if (typeof request.bids.mediaTypes !== 'undefined' && typeof request.bids.mediaTypes.video !== 'undefined') {
209
+ if (typeof request.bids?.mediaTypes !== 'undefined' && typeof request.bids?.mediaTypes.video !== 'undefined') {
210
210
  bidReturned.vastXml = serverBid.adm;
211
211
  bidReturned.vastUrl = serverBid.lurl;
212
212
  bidReturned.ad = serverBid.adm;
@@ -214,13 +214,12 @@ function interpretBid(serverBid, request) {
214
214
  bidReturned.width = serverBid.w;
215
215
  bidReturned.height = serverBid.h;
216
216
 
217
- if (request.bids.mediaTypes.video.context === 'outstream') {
218
- const url = (serverBid.ext.purl) ? serverBid.ext.purl : false;
219
- if (typeof url === 'undefined') {
217
+ if (request.bids?.mediaTypes.video.context === 'outstream') {
218
+ if (!serverBid.ext.purl) {
220
219
  logWarn(LOG_PREFIX, 'Error getting player outstream from tappx');
221
220
  return false;
222
221
  }
223
- bidReturned.renderer = createRenderer(bidReturned, request, url);
222
+ bidReturned.renderer = createRenderer(bidReturned, request, serverBid.ext.purl);
224
223
  }
225
224
  } else {
226
225
  bidReturned.ad = serverBid.adm;
@@ -228,7 +227,7 @@ function interpretBid(serverBid, request) {
228
227
  }
229
228
 
230
229
  if (typeof bidReturned.adomain !== 'undefined' || bidReturned.adomain !== null) {
231
- bidReturned.meta = { advertiserDomains: request.bids.adomain };
230
+ bidReturned.meta = { advertiserDomains: request.bids?.adomain };
232
231
  }
233
232
 
234
233
  return bidReturned;
@@ -305,6 +304,8 @@ function buildOneRequest(validBidRequests, bidderRequest) {
305
304
  let h;
306
305
 
307
306
  if (bannerMediaType) {
307
+ if (!Array.isArray(bannerMediaType.sizes)) { logWarn(LOG_PREFIX, 'Banner sizes array not found.'); }
308
+
308
309
  let banner = {};
309
310
  w = bannerMediaType.sizes[0][0];
310
311
  h = bannerMediaType.sizes[0][1];
@@ -342,7 +343,9 @@ function buildOneRequest(validBidRequests, bidderRequest) {
342
343
  }
343
344
 
344
345
  if ((video.w === undefined || video.w == null || video.w <= 0) ||
345
- (video.h === undefined || video.h == null || video.h <= 0)) {
346
+ (video.h === undefined || video.h == null || video.h <= 0)) {
347
+ if (!Array.isArray(videoMediaType.playerSize)) { logWarn(LOG_PREFIX, 'Video playerSize array not found.'); }
348
+
346
349
  w = videoMediaType.playerSize[0][0];
347
350
  h = videoMediaType.playerSize[0][1];
348
351
  video.w = w;
@@ -12,6 +12,7 @@ import {MODULE_TYPE_BIDDER} from '../src/activities/modules.js';
12
12
 
13
13
  const MODULE_NAME = 'topicsFpd';
14
14
  const DEFAULT_EXPIRATION_DAYS = 21;
15
+ const DEFAULT_FETCH_RATE_IN_DAYS = 1;
15
16
  let LOAD_TOPICS_INITIALISE = false;
16
17
 
17
18
  export function reset() {
@@ -85,6 +86,7 @@ export function getTopicsData(name, topics, taxonomies = TAXONOMIES) {
85
86
  if (name != null) {
86
87
  datum.name = name;
87
88
  }
89
+
88
90
  return datum;
89
91
  })
90
92
  );
@@ -96,6 +98,7 @@ function isTopicsSupported(doc = document) {
96
98
 
97
99
  export function getTopics(doc = document) {
98
100
  let topics = null;
101
+
99
102
  try {
100
103
  if (isTopicsSupported(doc)) {
101
104
  topics = GreedyPromise.resolve(doc.browsingTopics());
@@ -106,6 +109,7 @@ export function getTopics(doc = document) {
106
109
  if (topics == null) {
107
110
  topics = GreedyPromise.resolve([]);
108
111
  }
112
+
109
113
  return topics;
110
114
  }
111
115
 
@@ -165,7 +169,7 @@ export function receiveMessage(evt) {
165
169
  let data = safeJSONParse(evt.data);
166
170
  if (includes(getLoadedIframeURL(), evt.origin) && data && data.segment && !isEmpty(data.segment.topics)) {
167
171
  const {domain, topics, bidder} = data.segment;
168
- const iframeTopicsData = getTopicsData(domain, topics)[0];
172
+ const iframeTopicsData = getTopicsData(domain, topics);
169
173
  iframeTopicsData && storeInLocalStorage(bidder, iframeTopicsData);
170
174
  }
171
175
  } catch (err) { }
@@ -178,13 +182,15 @@ Function to store Topics data recieved from iframe in storage(name: "prebid:topi
178
182
  */
179
183
  export function storeInLocalStorage(bidder, topics) {
180
184
  const storedSegments = new Map(safeJSONParse(coreStorage.getDataFromLocalStorage(topicStorageName)));
181
- if (storedSegments.has(bidder)) {
182
- storedSegments.get(bidder)[topics['ext']['segclass']] = topics;
183
- storedSegments.get(bidder)[lastUpdated] = new Date().getTime();
184
- storedSegments.set(bidder, storedSegments.get(bidder));
185
- } else {
186
- storedSegments.set(bidder, {[topics.ext.segclass]: topics, [lastUpdated]: new Date().getTime()})
187
- }
185
+ const topicsObj = {
186
+ [lastUpdated]: new Date().getTime()
187
+ };
188
+
189
+ topics.forEach((topic) => {
190
+ topicsObj[topic.ext.segclass] = topic;
191
+ });
192
+
193
+ storedSegments.set(bidder, topicsObj);
188
194
  coreStorage.setDataInLocalStorage(topicStorageName, JSON.stringify([...storedSegments]));
189
195
  }
190
196
 
@@ -215,10 +221,11 @@ function listenMessagesFromTopicIframe() {
215
221
  export function loadTopicsForBidders(doc = document) {
216
222
  if (!isTopicsSupported(doc)) return;
217
223
  const topics = config.getConfig('userSync.topics') || bidderIframeList;
224
+
218
225
  if (topics) {
219
226
  listenMessagesFromTopicIframe();
220
227
  const randomBidders = getRandomBidders(topics.bidders || [], topics.maxTopicCaller || 1)
221
- randomBidders && randomBidders.forEach(({ bidder, iframeURL }) => {
228
+ randomBidders && randomBidders.forEach(({ bidder, iframeURL, fetchUrl, fetchRate }) => {
222
229
  if (bidder && iframeURL) {
223
230
  let ifrm = doc.createElement('iframe');
224
231
  ifrm.name = 'ifrm_'.concat(bidder);
@@ -227,6 +234,25 @@ export function loadTopicsForBidders(doc = document) {
227
234
  setLoadedIframeURL(new URL(iframeURL).origin);
228
235
  iframeURL && doc.documentElement.appendChild(ifrm);
229
236
  }
237
+
238
+ if (bidder && fetchUrl) {
239
+ let storedSegments = new Map(safeJSONParse(coreStorage.getDataFromLocalStorage(topicStorageName)));
240
+ const bidderLsEntry = storedSegments.get(bidder);
241
+
242
+ if (!bidderLsEntry || (bidderLsEntry && isCachedDataExpired(bidderLsEntry[lastUpdated], fetchRate || DEFAULT_FETCH_RATE_IN_DAYS))) {
243
+ window.fetch(`${fetchUrl}?bidder=${bidder}`, {browsingTopics: true})
244
+ .then(response => {
245
+ return response.json();
246
+ })
247
+ .then(data => {
248
+ if (data && data.segment && !isEmpty(data.segment.topics)) {
249
+ const {domain, topics, bidder} = data.segment;
250
+ const fetchTopicsData = getTopicsData(domain, topics);
251
+ fetchTopicsData && storeInLocalStorage(bidder, fetchTopicsData);
252
+ }
253
+ });
254
+ }
255
+ }
230
256
  })
231
257
  } else {
232
258
  logWarn(`Topics config not defined under userSync Object`);
@@ -23,7 +23,7 @@ Module that connects to Undertone's demand sources
23
23
  {
24
24
  bidder: "undertone",
25
25
  params: {
26
- placementId: '10433394',
26
+ placementId: 1234,
27
27
  publisherId: 12345
28
28
  }
29
29
  }
@@ -272,6 +272,13 @@ userIdAsEids = [
272
272
  id: 'some-random-id-value',
273
273
  atype: 3
274
274
  }]
275
+ },
276
+ {
277
+ source: 'euid.eu',
278
+ uids: [{
279
+ id: 'some-random-id-value',
280
+ atype: 3
281
+ }]
275
282
  }
276
283
  ]
277
284
  ```