prebid.js 6.3.0 → 6.7.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 (157) hide show
  1. package/.circleci/config.yml +1 -1
  2. package/gulpfile.js +87 -74
  3. package/integrationExamples/gpt/amp/creative.html +11 -33
  4. package/karma.conf.maker.js +1 -1
  5. package/modules/.submodules.json +2 -1
  6. package/modules/adbookpspBidAdapter.js +27 -10
  7. package/modules/adhashBidAdapter.js +3 -3
  8. package/modules/adkernelBidAdapter.js +148 -62
  9. package/modules/adlooxAdServerVideo.js +2 -2
  10. package/modules/adlooxAnalyticsAdapter.js +4 -4
  11. package/modules/admanBidAdapter.js +10 -4
  12. package/modules/adomikAnalyticsAdapter.js +27 -9
  13. package/modules/adqueryIdSystem.js +103 -0
  14. package/modules/adqueryIdSystem.md +35 -0
  15. package/modules/adyoulikeBidAdapter.js +13 -9
  16. package/modules/aniviewBidAdapter.js +1 -1
  17. package/modules/beopBidAdapter.js +1 -1
  18. package/modules/bidViewability.js +3 -3
  19. package/modules/bidViewabilityIO.js +3 -3
  20. package/modules/bliinkBidAdapter.js +3 -2
  21. package/modules/colossussspBidAdapter.js +12 -8
  22. package/modules/colossussspBidAdapter.md +15 -1
  23. package/modules/compassBidAdapter.js +208 -0
  24. package/modules/compassBidAdapter.md +79 -0
  25. package/modules/consentManagement.js +7 -1
  26. package/modules/consumableBidAdapter.md +1 -1
  27. package/modules/criteoBidAdapter.js +1 -1
  28. package/modules/criteoIdSystem.js +29 -7
  29. package/modules/currency.js +2 -2
  30. package/modules/dailyhuntBidAdapter.js +435 -0
  31. package/modules/dailyhuntBidAdapter.md +4 -0
  32. package/modules/docereeBidAdapter.js +10 -1
  33. package/modules/docereeBidAdapter.md +2 -0
  34. package/modules/engageyaBidAdapter.js +1 -1
  35. package/modules/feedadBidAdapter.js +2 -2
  36. package/modules/feedadBidAdapter.md +4 -2
  37. package/modules/glimpseBidAdapter.js +66 -44
  38. package/modules/gnetBidAdapter.js +3 -3
  39. package/modules/gnetBidAdapter.md +4 -4
  40. package/modules/gptPreAuction.js +55 -7
  41. package/modules/gridBidAdapter.js +4 -3
  42. package/modules/gumgumBidAdapter.js +4 -4
  43. package/modules/idImportLibrary.js +45 -8
  44. package/modules/idImportLibrary.md +4 -0
  45. package/modules/improvedigitalBidAdapter.js +42 -4
  46. package/modules/instreamTracking.js +4 -4
  47. package/modules/invibesBidAdapter.js +49 -5
  48. package/modules/invibesBidAdapter.md +2 -1
  49. package/modules/ixBidAdapter.js +53 -18
  50. package/modules/jwplayerRtdProvider.js +71 -6
  51. package/modules/jwplayerRtdProvider.md +27 -11
  52. package/modules/kargoBidAdapter.js +2 -2
  53. package/modules/limelightDigitalBidAdapter.js +2 -1
  54. package/modules/livewrappedAnalyticsAdapter.js +3 -1
  55. package/modules/livewrappedBidAdapter.js +8 -2
  56. package/modules/loglyliftBidAdapter.js +79 -0
  57. package/modules/loglyliftBidAdapter.md +55 -0
  58. package/modules/nextMillenniumBidAdapter.js +11 -7
  59. package/modules/oguryBidAdapter.js +9 -2
  60. package/modules/onetagBidAdapter.js +4 -2
  61. package/modules/optimeraRtdProvider.js +8 -1
  62. package/modules/ozoneBidAdapter.js +21 -64
  63. package/modules/pilotxBidAdapter.js +147 -0
  64. package/modules/pilotxBidAdapter.md +50 -0
  65. package/modules/proxistoreBidAdapter.js +0 -2
  66. package/modules/pubgeniusBidAdapter.js +1 -1
  67. package/modules/pubmaticAnalyticsAdapter.js +16 -0
  68. package/modules/pubxaiAnalyticsAdapter.js +17 -0
  69. package/modules/richaudienceBidAdapter.js +3 -2
  70. package/modules/riseBidAdapter.js +1 -1
  71. package/modules/rtbhouseBidAdapter.js +14 -4
  72. package/modules/rtdModule/index.js +14 -15
  73. package/modules/rubiconAnalyticsAdapter.js +3 -2
  74. package/modules/rubiconBidAdapter.js +21 -11
  75. package/modules/seedingAllianceBidAdapter.js +3 -3
  76. package/modules/sharethroughBidAdapter.js +12 -17
  77. package/modules/showheroes-bsBidAdapter.js +13 -2
  78. package/modules/synacormediaBidAdapter.js +31 -10
  79. package/modules/tappxBidAdapter.js +8 -5
  80. package/modules/teadsBidAdapter.js +1 -2
  81. package/modules/telariaBidAdapter.js +2 -2
  82. package/modules/trustxBidAdapter.js +8 -16
  83. package/modules/userId/eids.js +7 -1
  84. package/modules/userId/userId.md +8 -0
  85. package/modules/viewability.js +177 -0
  86. package/modules/viewability.md +87 -0
  87. package/modules/welectBidAdapter.js +106 -0
  88. package/modules/yieldmoBidAdapter.js +23 -5
  89. package/modules/zeta_global_sspAnalyticsAdapter.js +97 -0
  90. package/modules/zeta_global_sspAnalyticsAdapter.md +24 -0
  91. package/package.json +1 -1
  92. package/src/auction.js +2 -2
  93. package/src/config.js +27 -3
  94. package/src/hook.js +5 -1
  95. package/src/prebid.js +20 -4
  96. package/src/secureCreatives.js +3 -2
  97. package/src/utils.js +12 -1
  98. package/test/helpers/prebidGlobal.js +1 -0
  99. package/test/spec/config_spec.js +279 -0
  100. package/test/spec/modules/adbookpspBidAdapter_spec.js +17 -3
  101. package/test/spec/modules/adhashBidAdapter_spec.js +2 -2
  102. package/test/spec/modules/adlooxAnalyticsAdapter_spec.js +6 -6
  103. package/test/spec/modules/admanBidAdapter_spec.js +2 -2
  104. package/test/spec/modules/adomikAnalyticsAdapter_spec.js +9 -1
  105. package/test/spec/modules/adqueryIdSystem_spec.js +74 -0
  106. package/test/spec/modules/adyoulikeBidAdapter_spec.js +49 -0
  107. package/test/spec/modules/beopBidAdapter_spec.js +1 -1
  108. package/test/spec/modules/bidViewabilityIO_spec.js +2 -2
  109. package/test/spec/modules/bidViewability_spec.js +4 -4
  110. package/test/spec/modules/bliinkBidAdapter_spec.js +2 -0
  111. package/test/spec/modules/colossussspBidAdapter_spec.js +5 -2
  112. package/test/spec/modules/compassBidAdapter_spec.js +398 -0
  113. package/test/spec/modules/consentManagement_spec.js +20 -0
  114. package/test/spec/modules/criteoIdSystem_spec.js +6 -3
  115. package/test/spec/modules/dailyhuntBidAdapter_spec.js +404 -0
  116. package/test/spec/modules/docereeBidAdapter_spec.js +9 -1
  117. package/test/spec/modules/eids_spec.js +15 -0
  118. package/test/spec/modules/feedadBidAdapter_spec.js +15 -0
  119. package/test/spec/modules/glimpseBidAdapter_spec.js +0 -18
  120. package/test/spec/modules/gnetBidAdapter_spec.js +6 -6
  121. package/test/spec/modules/gptPreAuction_spec.js +177 -2
  122. package/test/spec/modules/idImportLibrary_spec.js +197 -10
  123. package/test/spec/modules/improvedigitalBidAdapter_spec.js +45 -1
  124. package/test/spec/modules/invibesBidAdapter_spec.js +119 -0
  125. package/test/spec/modules/ixBidAdapter_spec.js +112 -62
  126. package/test/spec/modules/jwplayerRtdProvider_spec.js +195 -2
  127. package/test/spec/modules/kargoBidAdapter_spec.js +1 -1
  128. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +75 -17
  129. package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +22 -0
  130. package/test/spec/modules/livewrappedBidAdapter_spec.js +31 -0
  131. package/test/spec/modules/loglyliftBidAdapter_spec.js +172 -0
  132. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +9 -2
  133. package/test/spec/modules/oguryBidAdapter_spec.js +10 -2
  134. package/test/spec/modules/optimeraRtdProvider_spec.js +14 -1
  135. package/test/spec/modules/ozoneBidAdapter_spec.js +43 -31
  136. package/test/spec/modules/pilotxBidAdapter_spec.js +244 -0
  137. package/test/spec/modules/pubgeniusBidAdapter_spec.js +3 -3
  138. package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +13 -1
  139. package/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +11 -0
  140. package/test/spec/modules/realTimeDataModule_spec.js +67 -5
  141. package/test/spec/modules/richaudienceBidAdapter_spec.js +40 -0
  142. package/test/spec/modules/riseBidAdapter_spec.js +1 -1
  143. package/test/spec/modules/rtbhouseBidAdapter_spec.js +20 -0
  144. package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +30 -0
  145. package/test/spec/modules/rubiconBidAdapter_spec.js +48 -9
  146. package/test/spec/modules/sharethroughBidAdapter_spec.js +91 -6
  147. package/test/spec/modules/showheroes-bsBidAdapter_spec.js +2 -0
  148. package/test/spec/modules/synacormediaBidAdapter_spec.js +70 -0
  149. package/test/spec/modules/tappxBidAdapter_spec.js +0 -19
  150. package/test/spec/modules/teadsBidAdapter_spec.js +14 -59
  151. package/test/spec/modules/userId_spec.js +68 -19
  152. package/test/spec/modules/viewability_spec.js +280 -0
  153. package/test/spec/modules/welectBidAdapter_spec.js +211 -0
  154. package/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js +427 -0
  155. package/test/spec/unit/pbjs_api_spec.js +3 -1
  156. package/test/test_deps.js +3 -0
  157. package/test/test_index.js +1 -3
@@ -21,6 +21,14 @@ let events = {
21
21
  deviceDetail: {}
22
22
  };
23
23
 
24
+ function getStorage() {
25
+ try {
26
+ return window.top['sessionStorage'];
27
+ } catch (e) {
28
+ return null;
29
+ }
30
+ }
31
+
24
32
  var pubxaiAnalyticsAdapter = Object.assign(adapter(
25
33
  {
26
34
  emptyUrl,
@@ -132,6 +140,7 @@ pubxaiAnalyticsAdapter.shouldFireEventRequest = function (samplingRate = 1) {
132
140
  function send(data, status) {
133
141
  if (pubxaiAnalyticsAdapter.shouldFireEventRequest(initOptions.samplingRate)) {
134
142
  let location = getWindowLocation();
143
+ const storage = getStorage();
135
144
  data.initOptions = initOptions;
136
145
  if (typeof data !== 'undefined' && typeof data.auctionInit !== 'undefined') {
137
146
  Object.assign(data.pageDetail, {
@@ -142,6 +151,13 @@ function send(data, status) {
142
151
  });
143
152
  data.initOptions.auctionId = data.auctionInit.auctionId;
144
153
  delete data.auctionInit;
154
+
155
+ data.pmcDetail = {}
156
+ Object.assign(data.pmcDetail, {
157
+ bidDensity: storage ? storage.getItem('pbx:dpbid') : null,
158
+ maxBid: storage ? storage.getItem('pbx:mxbid') : null,
159
+ auctionId: storage ? storage.getItem('pbx:aucid') : null,
160
+ });
145
161
  }
146
162
  data.deviceDetail = {};
147
163
  Object.assign(data.deviceDetail, {
@@ -150,6 +166,7 @@ function send(data, status) {
150
166
  deviceOS: getOS(),
151
167
  browser: getBrowser()
152
168
  });
169
+
153
170
  let pubxaiAnalyticsRequestUrl = buildUrl({
154
171
  protocol: 'https',
155
172
  hostname: (initOptions && initOptions.hostName) || defaultHost,
@@ -1,4 +1,4 @@
1
- import { isEmpty, deepAccess, isStr } from '../src/utils.js';
1
+ import {isEmpty, deepAccess, isStr} from '../src/utils.js';
2
2
  import {registerBidder} from '../src/adapters/bidderFactory.js';
3
3
  import {config} from '../src/config.js';
4
4
  import {BANNER, VIDEO} from '../src/mediaTypes.js';
@@ -52,7 +52,8 @@ export const spec = {
52
52
  videoData: raiGetVideoInfo(bid),
53
53
  scr_rsl: raiGetResolution(),
54
54
  cpuc: (typeof window.navigator != 'undefined' ? window.navigator.hardwareConcurrency : null),
55
- kws: (!isEmpty(bid.params.keywords) ? bid.params.keywords : null)
55
+ kws: (!isEmpty(bid.params.keywords) ? bid.params.keywords : null),
56
+ schain: bid.schain
56
57
  };
57
58
 
58
59
  REFERER = (typeof bidderRequest.refererInfo.referer != 'undefined' ? encodeURIComponent(bidderRequest.refererInfo.referer) : null)
@@ -159,7 +159,7 @@ function getSupplyChain(schainObject) {
159
159
  scStr += '!';
160
160
  scStr += `${getEncodedValIfNotEmpty(node.asi)},`;
161
161
  scStr += `${getEncodedValIfNotEmpty(node.sid)},`;
162
- scStr += `${getEncodedValIfNotEmpty(node.hp)},`;
162
+ scStr += `${node.hp ? encodeURIComponent(node.hp) : ''},`;
163
163
  scStr += `${getEncodedValIfNotEmpty(node.rid)},`;
164
164
  scStr += `${getEncodedValIfNotEmpty(node.name)},`;
165
165
  scStr += `${getEncodedValIfNotEmpty(node.domain)}`;
@@ -165,16 +165,26 @@ function mapBanner(slot) {
165
165
  * @returns {object} Site by OpenRTB 2.5 §3.2.13
166
166
  */
167
167
  function mapSite(slot, bidderRequest) {
168
- const pubId = slot && slot.length > 0
169
- ? slot[0].params.publisherId
170
- : 'unknown';
171
- return {
168
+ let pubId = 'unknown';
169
+ let channel = null;
170
+ if (slot && slot.length > 0) {
171
+ pubId = slot[0].params.publisherId;
172
+ channel = slot[0].params.channel &&
173
+ slot[0].params.channel
174
+ .toString()
175
+ .slice(0, 50);
176
+ }
177
+ let siteData = {
172
178
  publisher: {
173
179
  id: pubId.toString(),
174
180
  },
175
181
  page: bidderRequest.refererInfo.referer,
176
182
  name: getOrigin()
183
+ };
184
+ if (channel) {
185
+ siteData.channel = channel;
177
186
  }
187
+ return siteData;
178
188
  }
179
189
 
180
190
  /**
@@ -152,7 +152,7 @@
152
152
 
153
153
  import {config} from '../../src/config.js';
154
154
  import {module} from '../../src/hook.js';
155
- import {logError, logWarn} from '../../src/utils.js';
155
+ import {logError, logInfo, logWarn} from '../../src/utils.js';
156
156
  import events from '../../src/events.js';
157
157
  import CONSTANTS from '../../src/constants.json';
158
158
  import {gdprDataHandler, uspDataHandler} from '../../src/adapterManager.js';
@@ -197,12 +197,13 @@ const setEventsListeners = (function () {
197
197
  return function setEventsListeners() {
198
198
  if (!registered) {
199
199
  Object.entries({
200
- [CONSTANTS.EVENTS.AUCTION_INIT]: 'onAuctionInitEvent',
201
- [CONSTANTS.EVENTS.AUCTION_END]: 'onAuctionEndEvent',
202
- [CONSTANTS.EVENTS.BID_RESPONSE]: 'onBidResponseEvent',
203
- [CONSTANTS.EVENTS.BID_REQUESTED]: 'onBidRequestEvent'
204
- }).forEach(([ev, handler]) => {
200
+ [CONSTANTS.EVENTS.AUCTION_INIT]: ['onAuctionInitEvent'],
201
+ [CONSTANTS.EVENTS.AUCTION_END]: ['onAuctionEndEvent', getAdUnitTargeting],
202
+ [CONSTANTS.EVENTS.BID_RESPONSE]: ['onBidResponseEvent'],
203
+ [CONSTANTS.EVENTS.BID_REQUESTED]: ['onBidRequestEvent']
204
+ }).forEach(([ev, [handler, preprocess]]) => {
205
205
  events.on(ev, (args) => {
206
+ preprocess && preprocess(args);
206
207
  subModules.forEach(sm => {
207
208
  try {
208
209
  sm[handler] && sm[handler](args, sm.config, _userConsent)
@@ -255,6 +256,7 @@ function initSubModules() {
255
256
  }
256
257
  });
257
258
  subModules = subModulesByOrder;
259
+ logInfo(`Real time data module enabled, using submodules: ${subModules.map((m) => m.name).join(', ')}`);
258
260
  }
259
261
 
260
262
  /**
@@ -289,18 +291,12 @@ export function setBidRequestsData(fn, reqBidsConfigObj) {
289
291
  return exitHook();
290
292
  }
291
293
 
292
- if (shouldDelayAuction) {
293
- waitTimeout = setTimeout(exitHook, _moduleConfig.auctionDelay);
294
- }
294
+ waitTimeout = setTimeout(exitHook, shouldDelayAuction ? _moduleConfig.auctionDelay : 0);
295
295
 
296
296
  relevantSubModules.forEach(sm => {
297
297
  sm.getBidRequestData(reqBidsConfigObj, onGetBidRequestDataCallback.bind(sm), sm.config, _userConsent)
298
298
  });
299
299
 
300
- if (!shouldDelayAuction) {
301
- return exitHook();
302
- }
303
-
304
300
  function onGetBidRequestDataCallback() {
305
301
  if (isDone) {
306
302
  return;
@@ -308,12 +304,15 @@ export function setBidRequestsData(fn, reqBidsConfigObj) {
308
304
  if (this.config && this.config.waitForIt) {
309
305
  callbacksExpected--;
310
306
  }
311
- if (callbacksExpected <= 0) {
312
- return exitHook();
307
+ if (callbacksExpected === 0) {
308
+ setTimeout(exitHook, 0);
313
309
  }
314
310
  }
315
311
 
316
312
  function exitHook() {
313
+ if (isDone) {
314
+ return;
315
+ }
317
316
  isDone = true;
318
317
  clearTimeout(waitTimeout);
319
318
  fn.call(this, reqBidsConfigObj);
@@ -384,8 +384,9 @@ export function parseBidResponse(bid, previousBidResponse, auctionFloorData) {
384
384
  'floorRuleValue', () => deepAccess(bid, 'floorData.floorRuleValue'),
385
385
  'floorRule', () => debugTurnedOn() ? deepAccess(bid, 'floorData.floorRule') : undefined,
386
386
  'adomains', () => {
387
- let adomains = deepAccess(bid, 'meta.advertiserDomains');
388
- return Array.isArray(adomains) && adomains.length > 0 ? adomains.slice(0, 10) : undefined
387
+ const adomains = deepAccess(bid, 'meta.advertiserDomains');
388
+ const validAdomains = Array.isArray(adomains) && adomains.filter(domain => typeof domain === 'string');
389
+ return validAdomains && validAdomains.length > 0 ? validAdomains.slice(0, 10) : undefined
389
390
  }
390
391
  ]);
391
392
  }
@@ -994,6 +994,8 @@ function applyFPD(bidRequest, mediaType, data) {
994
994
 
995
995
  let fpd = mergeDeep({}, config.getConfig('ortb2') || {}, BID_FPD);
996
996
  let impData = deepAccess(bidRequest.ortb2Imp, 'ext.data') || {};
997
+
998
+ const gpid = deepAccess(bidRequest, 'ortb2Imp.ext.gpid');
997
999
  const SEGTAX = {user: [4], site: [1, 2, 5, 6]};
998
1000
  const MAP = {user: 'tg_v.', site: 'tg_i.', adserver: 'tg_i.dfp_ad_unit_code', pbadslot: 'tg_i.pbadslot', keywords: 'kw'};
999
1001
  const validate = function(prop, key, parentName) {
@@ -1022,16 +1024,6 @@ function applyFPD(bidRequest, mediaType, data) {
1022
1024
  data[loc] = (data[loc]) ? data[loc].concat(',', val) : val;
1023
1025
  }
1024
1026
 
1025
- Object.keys(impData).forEach((key) => {
1026
- if (key === 'adserver') {
1027
- ['name', 'adslot'].forEach(prop => {
1028
- if (impData[key][prop]) impData[key][prop] = impData[key][prop].toString().replace(/^\/+/, '');
1029
- });
1030
- } else if (key === 'pbadslot') {
1031
- impData[key] = impData[key].toString().replace(/^\/+/, '');
1032
- }
1033
- });
1034
-
1035
1027
  if (mediaType === BANNER) {
1036
1028
  ['site', 'user'].forEach(name => {
1037
1029
  Object.keys(fpd[name]).forEach((key) => {
@@ -1047,12 +1039,30 @@ function applyFPD(bidRequest, mediaType, data) {
1047
1039
  });
1048
1040
  });
1049
1041
  Object.keys(impData).forEach((key) => {
1050
- (key === 'adserver') ? addBannerData(impData[key].adslot, name, key) : addBannerData(impData[key], 'site', key);
1042
+ if (key !== 'adserver') {
1043
+ addBannerData(impData[key], 'site', key);
1044
+ } else if (impData[key].name === 'gam') {
1045
+ addBannerData(impData[key].adslot, name, key)
1046
+ }
1051
1047
  });
1048
+
1049
+ // add in gpid
1050
+ if (gpid) {
1051
+ data['p_gpid'] = gpid;
1052
+ }
1053
+
1054
+ // only send one of pbadslot or dfp adunit code (prefer pbadslot)
1055
+ if (data['tg_i.pbadslot']) {
1056
+ delete data['tg_i.dfp_ad_unit_code'];
1057
+ }
1052
1058
  } else {
1053
1059
  if (Object.keys(impData).length) {
1054
1060
  mergeDeep(data.imp[0].ext, {data: impData});
1055
1061
  }
1062
+ // add in gpid
1063
+ if (gpid) {
1064
+ data.imp[0].ext.gpid = gpid;
1065
+ }
1056
1066
 
1057
1067
  mergeDeep(data, fpd);
1058
1068
  }
@@ -152,10 +152,10 @@ export const spec = {
152
152
 
153
153
  const { seatbid, cur } = serverResponse.body;
154
154
 
155
- const bidResponses = flatten(seatbid.map(seat => seat.bid)).reduce((result, bid) => {
155
+ const bidResponses = (typeof seatbid != 'undefined') ? flatten(seatbid.map(seat => seat.bid)).reduce((result, bid) => {
156
156
  result[bid.impid - 1] = bid;
157
157
  return result;
158
- }, []);
158
+ }, []) : [];
159
159
 
160
160
  return bids
161
161
  .map((bid, id) => {
@@ -167,7 +167,7 @@ export const spec = {
167
167
  cpm: bidResponse.price,
168
168
  creativeId: bidResponse.crid,
169
169
  ttl: 1000,
170
- netRevenue: bid.netRevenue === 'net',
170
+ netRevenue: (!bid.netRevenue || bid.netRevenue === 'net'),
171
171
  currency: cur,
172
172
  mediaType: NATIVE,
173
173
  bidderCode: BIDDER_CODE,
@@ -1,10 +1,10 @@
1
- import { generateUUID, deepAccess, inIframe } from '../src/utils.js';
1
+ import { deepAccess, generateUUID, inIframe } from '../src/utils.js';
2
2
  import { registerBidder } from '../src/adapters/bidderFactory.js';
3
3
  import { config } from '../src/config.js';
4
4
  import { BANNER, VIDEO } from '../src/mediaTypes.js';
5
5
  import { createEidsArray } from './userId/eids.js';
6
6
 
7
- const VERSION = '4.0.1';
7
+ const VERSION = '4.1.0';
8
8
  const BIDDER_CODE = 'sharethrough';
9
9
  const SUPPLY_ID = 'WYu2BXv1';
10
10
 
@@ -23,6 +23,7 @@ export const sharethroughAdapterSpec = {
23
23
 
24
24
  buildRequests: (bidRequests, bidderRequest) => {
25
25
  const timeout = config.getConfig('bidderTimeout');
26
+ const firstPartyData = config.getConfig('ortb2') || {};
26
27
 
27
28
  const nonHttp = sharethroughInternal.getProtocol().indexOf('http') < 0;
28
29
  const secure = nonHttp || (sharethroughInternal.getProtocol().indexOf('https') > -1);
@@ -35,12 +36,8 @@ export const sharethroughAdapterSpec = {
35
36
  site: {
36
37
  domain: window.location.hostname,
37
38
  page: window.location.href,
38
- ref: bidderRequest.refererInfo ? bidderRequest.refererInfo.referer || null : null,
39
- },
40
- user: {
41
- ext: {
42
- eids: userIdAsEids(bidRequests[0]),
43
- },
39
+ ref: deepAccess(bidderRequest, 'refererInfo.referer'),
40
+ ...firstPartyData.site,
44
41
  },
45
42
  device: {
46
43
  ua: navigator.userAgent,
@@ -66,6 +63,10 @@ export const sharethroughAdapterSpec = {
66
63
  test: 0,
67
64
  };
68
65
 
66
+ req.user = nullish(firstPartyData.user, {});
67
+ if (!req.user.ext) req.user.ext = {};
68
+ req.user.ext.eids = userIdAsEids(bidRequests[0]);
69
+
69
70
  if (bidderRequest.gdprConsent) {
70
71
  const gdprApplies = bidderRequest.gdprConsent.gdprApplies === true;
71
72
  req.regs.ext.gdpr = gdprApplies ? 1 : 0;
@@ -86,15 +87,9 @@ export const sharethroughAdapterSpec = {
86
87
  impression.ext = { gpid: gpid };
87
88
  }
88
89
 
89
- // if request is for video, we only support instream
90
- if (bidReq.mediaTypes && bidReq.mediaTypes.video && bidReq.mediaTypes.video.context === 'outstream') {
91
- // return null so we can easily remove this imp from the array of imps that we send to adserver
92
- return null;
93
- }
94
-
95
- if (bidReq.mediaTypes && bidReq.mediaTypes.video) {
96
- const videoRequest = bidReq.mediaTypes.video;
90
+ const videoRequest = deepAccess(bidReq, 'mediaTypes.video');
97
91
 
92
+ if (videoRequest) {
98
93
  // default playerSize, only change this if we know width and height are properly defined in the request
99
94
  let [w, h] = [640, 360];
100
95
  if (videoRequest.playerSize && videoRequest.playerSize[0] && videoRequest.playerSize[1]) {
@@ -117,9 +112,9 @@ export const sharethroughAdapterSpec = {
117
112
  startdelay: nullish(videoRequest.startdelay, 0),
118
113
  skipmin: nullish(videoRequest.skipmin, 0),
119
114
  skipafter: nullish(videoRequest.skipafter, 0),
115
+ placement: videoRequest.context === 'instream' ? 1 : +deepAccess(videoRequest, 'placement', 4),
120
116
  };
121
117
 
122
- if (videoRequest.placement) impression.video.placement = videoRequest.placement;
123
118
  if (videoRequest.delivery) impression.video.delivery = videoRequest.delivery;
124
119
  if (videoRequest.companiontype) impression.video.companiontype = videoRequest.companiontype;
125
120
  if (videoRequest.companionad) impression.video.companionad = videoRequest.companionad;
@@ -61,15 +61,24 @@ export const spec = {
61
61
  }
62
62
  }
63
63
 
64
+ const consentData = bidderRequest.gdprConsent || {};
65
+
66
+ const gdprConsent = {
67
+ apiVersion: consentData.apiVersion || 2,
68
+ gdprApplies: consentData.gdprApplies || 0,
69
+ consentString: consentData.consentString || '',
70
+ }
71
+
64
72
  return {
65
73
  type: streamType,
74
+ adUnitCode: bid.adUnitCode,
66
75
  bidId: bid.bidId,
67
76
  mediaType: type,
68
77
  context: context,
69
78
  playerId: getBidIdParameter('playerId', bid.params),
70
79
  auctionId: bidderRequest.auctionId,
71
80
  bidderCode: BIDDER_CODE,
72
- gdprConsent: bidderRequest.gdprConsent,
81
+ gdprConsent: gdprConsent,
73
82
  start: +new Date(),
74
83
  timeout: 3000,
75
84
  size: {
@@ -159,6 +168,7 @@ function createBids(bidRes, reqData) {
159
168
  let bidUnit = {};
160
169
  bidUnit.cpm = bid.cpm;
161
170
  bidUnit.requestId = bid.bidId;
171
+ bidUnit.adUnitCode = reqBid.adUnitCode;
162
172
  bidUnit.currency = bid.currency;
163
173
  bidUnit.mediaType = bid.mediaType || VIDEO;
164
174
  bidUnit.ttl = TTL;
@@ -183,7 +193,8 @@ function createBids(bidRes, reqData) {
183
193
  } else if (bid.context === 'outstream') {
184
194
  const renderer = Renderer.install({
185
195
  id: bid.bidId,
186
- url: '//',
196
+ url: 'https://static.showheroes.com/renderer.js',
197
+ adUnitCode: reqBid.adUnitCode,
187
198
  config: {
188
199
  playerId: reqBid.playerId,
189
200
  width: bid.size.width,
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- import { getAdUnitSizes, logWarn, deepSetValue } from '../src/utils.js';
3
+ import { getAdUnitSizes, logWarn, deepSetValue, isFn, isPlainObject } from '../src/utils.js';
4
4
  import { registerBidder } from '../src/adapters/bidderFactory.js';
5
5
  import { BANNER, VIDEO } from '../src/mediaTypes.js';
6
6
  import includes from 'core-js-pure/features/array/includes.js';
@@ -67,11 +67,7 @@ export const spec = {
67
67
  } else {
68
68
  seatId = bid.params.seatId;
69
69
  }
70
- const tagIdOrplacementId = bid.params.tagId || bid.params.placementId;
71
- const bidFloor = bid.params.bidfloor ? parseFloat(bid.params.bidfloor) : null;
72
- if (isNaN(bidFloor)) {
73
- logWarn(`Synacormedia: there is an invalid bid floor: ${bid.params.bidfloor}`);
74
- }
70
+ const tagIdOrPlacementId = bid.params.tagId || bid.params.placementId;
75
71
  let pos = parseInt(bid.params.pos, 10);
76
72
  if (isNaN(pos)) {
77
73
  logWarn(`Synacormedia: there is an invalid POS: ${bid.params.pos}`);
@@ -83,9 +79,9 @@ export const spec = {
83
79
 
84
80
  let imps = [];
85
81
  if (videoOrBannerKey === 'banner') {
86
- imps = this.buildBannerImpressions(adSizes, bid, tagIdOrplacementId, pos, bidFloor, videoOrBannerKey);
82
+ imps = this.buildBannerImpressions(adSizes, bid, tagIdOrPlacementId, pos, videoOrBannerKey);
87
83
  } else if (videoOrBannerKey === 'video') {
88
- imps = this.buildVideoImpressions(adSizes, bid, tagIdOrplacementId, pos, bidFloor, videoOrBannerKey);
84
+ imps = this.buildVideoImpressions(adSizes, bid, tagIdOrPlacementId, pos, videoOrBannerKey);
89
85
  }
90
86
  if (imps.length > 0) {
91
87
  imps.forEach(i => openRtbBidRequest.imp.push(i));
@@ -128,7 +124,7 @@ export const spec = {
128
124
  return eids;
129
125
  },
130
126
 
131
- buildBannerImpressions: function (adSizes, bid, tagIdOrPlacementId, pos, bidFloor, videoOrBannerKey) {
127
+ buildBannerImpressions: function (adSizes, bid, tagIdOrPlacementId, pos, videoOrBannerKey) {
132
128
  let format = [];
133
129
  let imps = [];
134
130
  adSizes.forEach((size, i) => {
@@ -151,6 +147,10 @@ export const spec = {
151
147
  },
152
148
  tagid: tagIdOrPlacementId,
153
149
  };
150
+ const bidFloor = getBidFloor(bid, 'banner', '*');
151
+ if (isNaN(bidFloor)) {
152
+ logWarn(`Synacormedia: there is an invalid bid floor: ${bid.params.bidfloor}`);
153
+ }
154
154
  if (bidFloor !== null && !isNaN(bidFloor)) {
155
155
  imp.bidfloor = bidFloor;
156
156
  }
@@ -159,7 +159,7 @@ export const spec = {
159
159
  return imps;
160
160
  },
161
161
 
162
- buildVideoImpressions: function(adSizes, bid, tagIdOrPlacementId, pos, bidFloor, videoOrBannerKey) {
162
+ buildVideoImpressions: function(adSizes, bid, tagIdOrPlacementId, pos, videoOrBannerKey) {
163
163
  let imps = [];
164
164
  adSizes.forEach((size, i) => {
165
165
  if (!size || size.length != 2) {
@@ -171,6 +171,11 @@ export const spec = {
171
171
  id: `${videoOrBannerKey.substring(0, 1)}${bid.bidId}-${size0}x${size1}`,
172
172
  tagid: tagIdOrPlacementId
173
173
  };
174
+ const bidFloor = getBidFloor(bid, 'video', size);
175
+ if (isNaN(bidFloor)) {
176
+ logWarn(`Synacormedia: there is an invalid bid floor: ${bid.params.bidfloor}`);
177
+ }
178
+
174
179
  if (bidFloor !== null && !isNaN(bidFloor)) {
175
180
  imp.bidfloor = bidFloor;
176
181
  }
@@ -287,4 +292,20 @@ export const spec = {
287
292
  }
288
293
  };
289
294
 
295
+ function getBidFloor(bid, mediaType, size) {
296
+ if (!isFn(bid.getFloor)) {
297
+ return bid.params.bidfloor ? parseFloat(bid.params.bidfloor) : null;
298
+ }
299
+ let floor = bid.getFloor({
300
+ currency: 'USD',
301
+ mediaType,
302
+ size
303
+ });
304
+
305
+ if (isPlainObject(floor) && !isNaN(floor.floor) && floor.currency === 'USD') {
306
+ return floor.floor;
307
+ }
308
+ return null;
309
+ }
310
+
290
311
  registerBidder(spec);
@@ -53,7 +53,14 @@ export const spec = {
53
53
  * @return boolean True if this is a valid bid, and false otherwise.
54
54
  */
55
55
  isBidRequestValid: function(bid) {
56
- return validBasic(bid) && validMediaType(bid)
56
+ // bid.params.host
57
+ if ((new RegExp(`^(vz.*|zz.*)\\.*$`, 'i')).test(bid.params.host)) { // New endpoint
58
+ if ((new RegExp(`^(zz.*)\\.*$`, 'i')).test(bid.params.host)) return validBasic(bid)
59
+ else return validBasic(bid) && validMediaType(bid)
60
+ } else { // This is backward compatible feature. It will be remove in the future
61
+ if ((new RegExp(`^(ZZ.*)\\.*$`, 'i')).test(bid.params.endpoint)) return validBasic(bid)
62
+ else return validBasic(bid) && validMediaType(bid)
63
+ }
57
64
  },
58
65
 
59
66
  /**
@@ -169,10 +176,6 @@ function validMediaType(bid) {
169
176
  logWarn(LOG_PREFIX, 'Please review the mandatory Tappx parameters for Video. Video context not supported.');
170
177
  return false;
171
178
  }
172
- if (typeof video.mimes == 'undefined') {
173
- logWarn(LOG_PREFIX, 'Please review the mandatory Tappx parameters for Video. Mimes param is mandatory.');
174
- return false;
175
- }
176
179
  }
177
180
 
178
181
  return true;
@@ -190,8 +190,7 @@ function buildRequestObject(bid) {
190
190
  const reqObj = {};
191
191
  let placementId = getValue(bid.params, 'placementId');
192
192
  let pageId = getValue(bid.params, 'pageId');
193
- const impressionData = deepAccess(bid, 'ortb2Imp.ext.data');
194
- const gpid = deepAccess(impressionData, 'pbadslot') || deepAccess(impressionData, 'adserver.adslot');
193
+ const gpid = deepAccess(bid, 'ortb2Imp.ext.gpid');
195
194
 
196
195
  reqObj.sizes = getSizes(bid);
197
196
  reqObj.bidId = getBidIdParameter('bidId', bid);
@@ -2,7 +2,7 @@ import { logError, isEmpty, deepAccess, triggerPixel, logWarn, isArray } from '.
2
2
  import {createBid as createBidFactory} from '../src/bidfactory.js';
3
3
  import {registerBidder} from '../src/adapters/bidderFactory.js';
4
4
  import {VIDEO} from '../src/mediaTypes.js';
5
- import {STATUS} from '../src/constants.json';
5
+ import CONSTANTS from '../src/constants.json';
6
6
 
7
7
  const BIDDER_CODE = 'telaria';
8
8
  const DOMAIN = 'tremorhub.com';
@@ -86,7 +86,7 @@ export const spec = {
86
86
  logError(errorMessage);
87
87
  } else if (!isEmpty(bidResult.seatbid)) {
88
88
  bidResult.seatbid[0].bid.forEach(tag => {
89
- bids.push(createBid(STATUS.GOOD, bidderRequest, tag, width, height, BIDDER_CODE));
89
+ bids.push(createBid(CONSTANTS.STATUS.GOOD, bidderRequest, tag, width, height, BIDDER_CODE));
90
90
  });
91
91
  }
92
92
 
@@ -6,9 +6,8 @@ import { config } from '../src/config.js';
6
6
 
7
7
  const BIDDER_CODE = 'trustx';
8
8
  const ENDPOINT_URL = 'https://grid.bidswitch.net/hbjson?sp=trustx';
9
- const ADDITIONAL_SYNC_URL = 'https://x.bidswitch.net/sync?ssp=themediagrid';
10
9
  const TIME_TO_LIVE = 360;
11
- const ADAPTER_SYNC_URL = 'https://sofia.trustx.org/push_sync';
10
+ const ADAPTER_SYNC_URL = 'https://x.bidswitch.net/sync?ssp=themediagrid';
12
11
  const RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js';
13
12
 
14
13
  const LOG_ERROR_MESS = {
@@ -281,12 +280,12 @@ export const spec = {
281
280
  },
282
281
  getUserSyncs: function(syncOptions, responses, gdprConsent, uspConsent) {
283
282
  if (syncOptions.pixelEnabled) {
284
- const syncsPerBidder = config.getConfig('userSync.syncsPerBidder');
285
283
  let params = [];
286
- if (gdprConsent && typeof gdprConsent.consentString === 'string') {
284
+ if (gdprConsent) {
287
285
  if (typeof gdprConsent.gdprApplies === 'boolean') {
288
- params.push(`gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`);
289
- } else {
286
+ params.push(`gdpr=${Number(gdprConsent.gdprApplies)}`);
287
+ }
288
+ if (typeof gdprConsent.consentString === 'string') {
290
289
  params.push(`gdpr_consent=${gdprConsent.consentString}`);
291
290
  }
292
291
  }
@@ -294,17 +293,10 @@ export const spec = {
294
293
  params.push(`us_privacy=${uspConsent}`);
295
294
  }
296
295
  const stringParams = params.join('&');
297
- const syncs = [{
296
+ return {
298
297
  type: 'image',
299
- url: ADAPTER_SYNC_URL + (stringParams ? `?${stringParams}` : '')
300
- }];
301
- if (syncsPerBidder > 1) {
302
- syncs.push({
303
- type: 'image',
304
- url: ADDITIONAL_SYNC_URL + (stringParams ? `&${stringParams}` : '')
305
- });
306
- }
307
- return syncs;
298
+ url: ADAPTER_SYNC_URL + stringParams
299
+ };
308
300
  }
309
301
  }
310
302
  }
@@ -257,7 +257,13 @@ const USER_IDS_CONFIG = {
257
257
  'connectId': {
258
258
  source: 'yahoo.com',
259
259
  atype: 3
260
- }
260
+ },
261
+
262
+ // Adquery ID
263
+ 'qid': {
264
+ source: 'adquery.io',
265
+ atype: 1
266
+ },
261
267
  };
262
268
 
263
269
  // this function will create an eid object for the given UserId sub-module
@@ -297,6 +297,14 @@ pbjs.setConfig({
297
297
  type: 'html5',
298
298
  expires: 15
299
299
  }
300
+ }
301
+ {
302
+ name: "qid",
303
+ storage: {
304
+ type: "html5",
305
+ name: "qid",
306
+ expires: 365
307
+ }
300
308
  }],
301
309
  syncDelay: 5000
302
310
  }