prebid.js 6.2.0 → 6.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/.circleci/config.yml +1 -1
  2. package/gulpfile.js +87 -82
  3. package/integrationExamples/gpt/weboramaRtdProvider_example.html +23 -14
  4. package/karma.conf.maker.js +1 -1
  5. package/modules/.submodules.json +2 -1
  6. package/modules/33acrossBidAdapter.js +189 -102
  7. package/modules/adagioBidAdapter.js +1 -1
  8. package/modules/addefendBidAdapter.js +1 -0
  9. package/modules/adkernelBidAdapter.js +148 -62
  10. package/modules/adlooxAdServerVideo.js +2 -2
  11. package/modules/adlooxAnalyticsAdapter.js +4 -4
  12. package/modules/admanBidAdapter.js +11 -4
  13. package/modules/admixerBidAdapter.js +1 -1
  14. package/modules/adnuntiusBidAdapter.js +3 -1
  15. package/modules/adomikAnalyticsAdapter.js +27 -9
  16. package/modules/adqueryIdSystem.js +103 -0
  17. package/modules/adqueryIdSystem.md +35 -0
  18. package/modules/adxcgBidAdapter.js +311 -359
  19. package/modules/adxcgBidAdapter.md +22 -21
  20. package/modules/adyoulikeBidAdapter.js +13 -9
  21. package/modules/aniviewBidAdapter.js +1 -1
  22. package/modules/appnexusBidAdapter.js +0 -1
  23. package/modules/beopBidAdapter.js +6 -4
  24. package/modules/bidViewability.js +3 -3
  25. package/modules/bidViewabilityIO.js +3 -3
  26. package/modules/bliinkBidAdapter.js +3 -2
  27. package/modules/colossussspBidAdapter.js +7 -0
  28. package/modules/compassBidAdapter.js +208 -0
  29. package/modules/compassBidAdapter.md +79 -0
  30. package/modules/consentManagement.js +7 -1
  31. package/modules/criteoBidAdapter.js +1 -1
  32. package/modules/criteoIdSystem.js +29 -7
  33. package/modules/currency.js +2 -2
  34. package/modules/cwireBidAdapter.js +3 -0
  35. package/modules/dailyhuntBidAdapter.js +435 -0
  36. package/modules/dailyhuntBidAdapter.md +4 -0
  37. package/modules/docereeBidAdapter.js +10 -1
  38. package/modules/docereeBidAdapter.md +2 -0
  39. package/modules/dspxBidAdapter.js +1 -1
  40. package/modules/engageyaBidAdapter.js +1 -1
  41. package/modules/feedadBidAdapter.js +2 -2
  42. package/modules/feedadBidAdapter.md +4 -2
  43. package/modules/futureads.md +48 -0
  44. package/modules/glimpseBidAdapter.js +82 -47
  45. package/modules/gptPreAuction.js +55 -7
  46. package/modules/gridBidAdapter.js +4 -3
  47. package/modules/gumgumBidAdapter.js +2 -2
  48. package/modules/idImportLibrary.js +45 -8
  49. package/modules/idImportLibrary.md +4 -0
  50. package/modules/improvedigitalBidAdapter.js +42 -4
  51. package/modules/instreamTracking.js +4 -4
  52. package/modules/invibesBidAdapter.js +49 -5
  53. package/modules/invibesBidAdapter.md +2 -1
  54. package/modules/ixBidAdapter.js +53 -18
  55. package/modules/kinessoIdSystem.js +1 -1
  56. package/modules/limelightDigitalBidAdapter.js +2 -1
  57. package/modules/livewrappedAnalyticsAdapter.js +3 -1
  58. package/modules/livewrappedBidAdapter.js +8 -2
  59. package/modules/loglyliftBidAdapter.js +79 -0
  60. package/modules/loglyliftBidAdapter.md +55 -0
  61. package/modules/lotamePanoramaIdSystem.js +80 -8
  62. package/modules/mediasquareBidAdapter.js +1 -9
  63. package/modules/nextMillenniumBidAdapter.js +39 -7
  64. package/modules/oguryBidAdapter.js +9 -2
  65. package/modules/onetagBidAdapter.js +4 -2
  66. package/modules/optimeraRtdProvider.js +8 -1
  67. package/modules/ozoneBidAdapter.js +21 -64
  68. package/modules/prebidServerBidAdapter/index.js +16 -12
  69. package/modules/proxistoreBidAdapter.js +0 -2
  70. package/modules/pubgeniusBidAdapter.js +1 -1
  71. package/modules/pubmaticAnalyticsAdapter.js +16 -0
  72. package/modules/pubxaiAnalyticsAdapter.js +17 -0
  73. package/modules/richaudienceBidAdapter.js +4 -4
  74. package/modules/riseBidAdapter.js +1 -1
  75. package/modules/rtbhouseBidAdapter.js +14 -4
  76. package/modules/rtdModule/index.js +49 -18
  77. package/modules/rubiconBidAdapter.js +31 -19
  78. package/modules/sharedIdSystem.js +27 -1
  79. package/modules/showheroes-bsBidAdapter.js +13 -2
  80. package/modules/tappxBidAdapter.js +8 -5
  81. package/modules/targetVideoBidAdapter.js +187 -0
  82. package/modules/targetVideoBidAdapter.md +34 -0
  83. package/modules/teadsBidAdapter.js +1 -2
  84. package/modules/telariaBidAdapter.js +2 -2
  85. package/modules/trustxBidAdapter.js +8 -16
  86. package/modules/userId/eids.js +7 -1
  87. package/modules/userId/userId.md +8 -0
  88. package/modules/vidoomyBidAdapter.js +16 -10
  89. package/modules/weboramaRtdProvider.js +288 -73
  90. package/modules/weboramaRtdProvider.md +27 -10
  91. package/modules/welectBidAdapter.js +106 -0
  92. package/modules/yahoosspBidAdapter.js +5 -1
  93. package/modules/yieldmoBidAdapter.js +23 -5
  94. package/modules/zetaSspBidAdapter.md +33 -1
  95. package/modules/zeta_global_sspAnalyticsAdapter.js +97 -0
  96. package/modules/zeta_global_sspAnalyticsAdapter.md +24 -0
  97. package/modules/zeta_global_sspBidAdapter.js +22 -1
  98. package/package.json +1 -1
  99. package/plugins/pbjsGlobals.js +28 -1
  100. package/src/auction.js +2 -2
  101. package/src/config.js +27 -3
  102. package/src/hook.js +5 -1
  103. package/src/prebid.js +21 -6
  104. package/src/targeting.js +22 -1
  105. package/src/utils.js +46 -8
  106. package/test/helpers/prebidGlobal.js +1 -0
  107. package/test/spec/config_spec.js +279 -0
  108. package/test/spec/modules/33acrossBidAdapter_spec.js +300 -78
  109. package/test/spec/modules/adlooxAnalyticsAdapter_spec.js +6 -6
  110. package/test/spec/modules/admanBidAdapter_spec.js +2 -2
  111. package/test/spec/modules/adnuntiusBidAdapter_spec.js +17 -0
  112. package/test/spec/modules/adomikAnalyticsAdapter_spec.js +9 -1
  113. package/test/spec/modules/adqueryIdSystem_spec.js +74 -0
  114. package/test/spec/modules/adxcgBidAdapter_spec.js +820 -571
  115. package/test/spec/modules/adyoulikeBidAdapter_spec.js +49 -0
  116. package/test/spec/modules/beopBidAdapter_spec.js +1 -1
  117. package/test/spec/modules/bidViewabilityIO_spec.js +2 -2
  118. package/test/spec/modules/bidViewability_spec.js +4 -4
  119. package/test/spec/modules/bliinkBidAdapter_spec.js +2 -0
  120. package/test/spec/modules/colossussspBidAdapter_spec.js +9 -0
  121. package/test/spec/modules/compassBidAdapter_spec.js +398 -0
  122. package/test/spec/modules/consentManagement_spec.js +20 -0
  123. package/test/spec/modules/criteoIdSystem_spec.js +6 -3
  124. package/test/spec/modules/cwireBidAdapter_spec.js +10 -8
  125. package/test/spec/modules/dailyhuntBidAdapter_spec.js +404 -0
  126. package/test/spec/modules/docereeBidAdapter_spec.js +9 -1
  127. package/test/spec/modules/eids_spec.js +15 -0
  128. package/test/spec/modules/feedadBidAdapter_spec.js +15 -0
  129. package/test/spec/modules/glimpseBidAdapter_spec.js +0 -18
  130. package/test/spec/modules/gptPreAuction_spec.js +177 -2
  131. package/test/spec/modules/idImportLibrary_spec.js +197 -10
  132. package/test/spec/modules/improvedigitalBidAdapter_spec.js +45 -1
  133. package/test/spec/modules/invibesBidAdapter_spec.js +119 -0
  134. package/test/spec/modules/ixBidAdapter_spec.js +112 -62
  135. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +75 -17
  136. package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +22 -0
  137. package/test/spec/modules/livewrappedBidAdapter_spec.js +31 -0
  138. package/test/spec/modules/loglyliftBidAdapter_spec.js +172 -0
  139. package/test/spec/modules/lotamePanoramaIdSystem_spec.js +227 -0
  140. package/test/spec/modules/mediasquareBidAdapter_spec.js +4 -4
  141. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +26 -1
  142. package/test/spec/modules/oguryBidAdapter_spec.js +10 -2
  143. package/test/spec/modules/optimeraRtdProvider_spec.js +14 -1
  144. package/test/spec/modules/ozoneBidAdapter_spec.js +43 -31
  145. package/test/spec/modules/prebidServerBidAdapter_spec.js +43 -0
  146. package/test/spec/modules/pubgeniusBidAdapter_spec.js +3 -3
  147. package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +13 -1
  148. package/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +11 -0
  149. package/test/spec/modules/realTimeDataModule_spec.js +147 -48
  150. package/test/spec/modules/richaudienceBidAdapter_spec.js +42 -2
  151. package/test/spec/modules/riseBidAdapter_spec.js +1 -1
  152. package/test/spec/modules/rtbhouseBidAdapter_spec.js +20 -0
  153. package/test/spec/modules/rubiconBidAdapter_spec.js +65 -9
  154. package/test/spec/modules/sharedIdSystem_spec.js +52 -6
  155. package/test/spec/modules/showheroes-bsBidAdapter_spec.js +2 -0
  156. package/test/spec/modules/tappxBidAdapter_spec.js +0 -19
  157. package/test/spec/modules/targetVideoBidAdapter_spec.js +96 -0
  158. package/test/spec/modules/teadsBidAdapter_spec.js +14 -59
  159. package/test/spec/modules/userId_spec.js +68 -19
  160. package/test/spec/modules/weboramaRtdProvider_spec.js +408 -214
  161. package/test/spec/modules/welectBidAdapter_spec.js +211 -0
  162. package/test/spec/modules/yahoosspBidAdapter_spec.js +28 -1
  163. package/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js +427 -0
  164. package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +33 -1
  165. package/test/spec/unit/core/targeting_spec.js +72 -0
  166. package/test/spec/unit/pbjs_api_spec.js +3 -1
  167. package/test/spec/utils_spec.js +38 -0
  168. package/test/test_deps.js +3 -0
  169. package/test/test_index.js +1 -3
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isStr, isArray, isPlainObject, deepSetValue, isNumber, deepAccess, getAdUnitSizes, parseGPTSingleSizeArrayToRtbSize,
3
- cleanObj, contains, getDNT, parseUrl, createTrackPixelHtml, _each, isArrayOfNums
3
+ cleanObj, contains, getDNT, parseUrl, createTrackPixelHtml, _each, isArrayOfNums, mergeDeep, isEmpty, inIframe
4
4
  } from '../src/utils.js';
5
5
  import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js';
6
6
  import {registerBidder} from '../src/adapters/bidderFactory.js';
@@ -77,7 +77,8 @@ export const spec = {
77
77
  {code: 'unibots'},
78
78
  {code: 'catapultx'},
79
79
  {code: 'ergadx'},
80
- {code: 'turktelekom'}
80
+ {code: 'turktelekom'},
81
+ {code: 'felixads'}
81
82
  ],
82
83
  supportedMediaTypes: [BANNER, VIDEO, NATIVE],
83
84
 
@@ -103,17 +104,16 @@ export const spec = {
103
104
  * @returns {ServerRequest[]}
104
105
  */
105
106
  buildRequests: function (bidRequests, bidderRequest) {
106
- let impDispatch = dispatchImps(bidRequests, bidderRequest.refererInfo);
107
+ let impGroups = groupImpressionsByHostZone(bidRequests, bidderRequest.refererInfo);
107
108
  let requests = [];
108
109
  let schain = bidRequests[0].schain;
109
- Object.keys(impDispatch).forEach(host => {
110
- Object.keys(impDispatch[host]).forEach(zoneId => {
111
- const request = buildRtbRequest(impDispatch[host][zoneId], bidderRequest, schain);
112
- requests.push({
113
- method: 'POST',
114
- url: `https://${host}/hb?zone=${zoneId}&v=${VERSION}`,
115
- data: JSON.stringify(request)
116
- });
110
+ _each(impGroups, impGroup => {
111
+ let {host, zoneId, imps} = impGroup;
112
+ const request = buildRtbRequest(imps, bidderRequest, schain);
113
+ requests.push({
114
+ method: 'POST',
115
+ url: `https://${host}/hb?zone=${zoneId}&v=${VERSION}`,
116
+ data: JSON.stringify(request)
117
117
  });
118
118
  });
119
119
  return requests;
@@ -209,17 +209,19 @@ registerBidder(spec);
209
209
  * @param bidRequests {BidRequest[]}
210
210
  * @param refererInfo {refererInfo}
211
211
  */
212
- function dispatchImps(bidRequests, refererInfo) {
212
+ function groupImpressionsByHostZone(bidRequests, refererInfo) {
213
213
  let secure = (refererInfo && refererInfo.referer.indexOf('https:') === 0);
214
- return bidRequests.map(bidRequest => buildImp(bidRequest, secure))
215
- .reduce((acc, curr, index) => {
216
- let bidRequest = bidRequests[index];
217
- let {zoneId, host} = bidRequest.params;
218
- acc[host] = acc[host] || {};
219
- acc[host][zoneId] = acc[host][zoneId] || [];
220
- acc[host][zoneId].push(curr);
221
- return acc;
222
- }, {});
214
+ return Object.values(
215
+ bidRequests.map(bidRequest => buildImp(bidRequest, secure))
216
+ .reduce((acc, curr, index) => {
217
+ let bidRequest = bidRequests[index];
218
+ let {zoneId, host} = bidRequest.params;
219
+ let key = `${host}_${zoneId}`;
220
+ acc[key] = acc[key] || {host: host, zoneId: zoneId, imps: []};
221
+ acc[key].imps.push(curr);
222
+ return acc;
223
+ }, {})
224
+ );
223
225
  }
224
226
 
225
227
  function getBidFloor(bid, mediaType, sizes) {
@@ -365,57 +367,142 @@ function getAllowedSyncMethod(bidderCode) {
365
367
  }
366
368
 
367
369
  /**
368
- * Builds complete rtb request
369
- * @param imps {Object} Collection of rtb impressions
370
- * @param bidderRequest {BidderRequest}
371
- * @param schain {Object=} Supply chain config
372
- * @return {Object} Complete rtb request
370
+ * Create device object from fpd and host-collected data
371
+ * @param fpd {Object}
372
+ * @returns {{device: Object}}
373
373
  */
374
- function buildRtbRequest(imps, bidderRequest, schain) {
375
- let {bidderCode, gdprConsent, auctionId, refererInfo, timeout, uspConsent} = bidderRequest;
376
- let coppa = config.getConfig('coppa');
377
- let req = {
378
- 'id': auctionId,
379
- 'imp': imps,
380
- 'site': createSite(refererInfo),
381
- 'at': 1,
382
- 'device': {
383
- 'ip': 'caller',
384
- 'ipv6': 'caller',
385
- 'ua': 'caller',
386
- 'js': 1,
387
- 'language': getLanguage()
388
- },
389
- 'tmax': parseInt(timeout)
390
- };
374
+ function makeDevice(fpd) {
375
+ let device = mergeDeep({
376
+ 'ip': 'caller',
377
+ 'ipv6': 'caller',
378
+ 'ua': 'caller',
379
+ 'js': 1,
380
+ 'language': getLanguage()
381
+ }, fpd.device || {});
391
382
  if (getDNT()) {
392
- req.device.dnt = 1;
383
+ device.dnt = 1;
384
+ }
385
+ return {device: device};
386
+ }
387
+
388
+ /**
389
+ * Create site or app description object
390
+ * @param bidderRequest {BidderRequest}
391
+ * @param fpd {Object}
392
+ * @returns {{site: Object}|{app: Object}}
393
+ */
394
+ function makeSiteOrApp(bidderRequest, fpd) {
395
+ let {refererInfo} = bidderRequest;
396
+ let appConfig = config.getConfig('app');
397
+ if (isEmpty(appConfig)) {
398
+ return {site: createSite(refererInfo, fpd)}
399
+ } else {
400
+ return {app: appConfig};
393
401
  }
402
+ }
403
+
404
+ /**
405
+ * Create user description object
406
+ * @param bidderRequest {BidderRequest}
407
+ * @param fpd {Object}
408
+ * @returns {{user: Object} | undefined}
409
+ */
410
+ function makeUser(bidderRequest, fpd) {
411
+ let {gdprConsent} = bidderRequest;
412
+ let user = fpd.user || {};
413
+ if (gdprConsent && gdprConsent.consentString !== undefined) {
414
+ deepSetValue(user, 'ext.consent', gdprConsent.consentString);
415
+ }
416
+ let eids = getExtendedUserIds(bidderRequest);
417
+ if (eids) {
418
+ deepSetValue(user, 'ext.eids', eids);
419
+ }
420
+ if (!isEmpty(user)) { return {user: user}; }
421
+ }
422
+
423
+ /**
424
+ * Create privacy regulations object
425
+ * @param bidderRequest {BidderRequest}
426
+ * @returns {{regs: Object} | undefined}
427
+ */
428
+ function makeRegulations(bidderRequest) {
429
+ let {gdprConsent, uspConsent} = bidderRequest;
430
+ let regs = {};
394
431
  if (gdprConsent) {
395
432
  if (gdprConsent.gdprApplies !== undefined) {
396
- deepSetValue(req, 'regs.ext.gdpr', ~~gdprConsent.gdprApplies);
397
- }
398
- if (gdprConsent.consentString !== undefined) {
399
- deepSetValue(req, 'user.ext.consent', gdprConsent.consentString);
433
+ deepSetValue(regs, 'regs.ext.gdpr', ~~gdprConsent.gdprApplies);
400
434
  }
401
435
  }
402
436
  if (uspConsent) {
403
- deepSetValue(req, 'regs.ext.us_privacy', uspConsent);
437
+ deepSetValue(regs, 'regs.ext.us_privacy', uspConsent);
438
+ }
439
+ if (config.getConfig('coppa')) {
440
+ deepSetValue(regs, 'regs.coppa', 1);
404
441
  }
405
- if (coppa) {
406
- deepSetValue(req, 'regs.coppa', 1);
442
+ if (!isEmpty(regs)) {
443
+ return regs;
407
444
  }
445
+ }
446
+
447
+ /**
448
+ * Create top-level request object
449
+ * @param bidderRequest {BidderRequest}
450
+ * @param imps {Object} Impressions
451
+ * @param fpd {Object} First party data
452
+ * @returns
453
+ */
454
+ function makeBaseRequest(bidderRequest, imps, fpd) {
455
+ let {auctionId, timeout} = bidderRequest;
456
+ let request = {
457
+ 'id': auctionId,
458
+ 'imp': imps,
459
+ 'at': 1,
460
+ 'tmax': parseInt(timeout)
461
+ };
462
+ if (!isEmpty(fpd.bcat)) {
463
+ request.bcat = fpd.bcat;
464
+ }
465
+ if (!isEmpty(fpd.badv)) {
466
+ request.badv = fpd.badv;
467
+ }
468
+ return request;
469
+ }
470
+
471
+ /**
472
+ * Initialize sync capabilities
473
+ * @param bidderRequest {BidderRequest}
474
+ */
475
+ function makeSyncInfo(bidderRequest) {
476
+ let {bidderCode} = bidderRequest;
408
477
  let syncMethod = getAllowedSyncMethod(bidderCode);
409
478
  if (syncMethod) {
410
- deepSetValue(req, 'ext.adk_usersync', syncMethod);
479
+ let res = {};
480
+ deepSetValue(res, 'ext.adk_usersync', syncMethod);
481
+ return res;
411
482
  }
483
+ }
484
+
485
+ /**
486
+ * Builds complete rtb request
487
+ * @param imps {Object} Collection of rtb impressions
488
+ * @param bidderRequest {BidderRequest}
489
+ * @param schain {Object=} Supply chain config
490
+ * @return {Object} Complete rtb request
491
+ */
492
+ function buildRtbRequest(imps, bidderRequest, schain) {
493
+ let fpd = config.getConfig('ortb2') || {};
494
+
495
+ let req = mergeDeep(
496
+ makeBaseRequest(bidderRequest, imps, fpd),
497
+ makeDevice(fpd),
498
+ makeSiteOrApp(bidderRequest, fpd),
499
+ makeUser(bidderRequest, fpd),
500
+ makeRegulations(bidderRequest),
501
+ makeSyncInfo(bidderRequest)
502
+ );
412
503
  if (schain) {
413
504
  deepSetValue(req, 'source.ext.schain', schain);
414
505
  }
415
- let eids = getExtendedUserIds(bidderRequest);
416
- if (eids) {
417
- deepSetValue(req, 'user.ext.eids', eids);
418
- }
419
506
  return req;
420
507
  }
421
508
 
@@ -431,18 +518,17 @@ function getLanguage() {
431
518
  /**
432
519
  * Creates site description object
433
520
  */
434
- function createSite(refInfo) {
521
+ function createSite(refInfo, fpd) {
435
522
  let url = parseUrl(refInfo.referer);
436
523
  let site = {
437
524
  'domain': url.hostname,
438
525
  'page': `${url.protocol}://${url.hostname}${url.pathname}`
439
526
  };
440
- if (self === top && document.referrer) {
527
+ mergeDeep(site, fpd.site);
528
+ if (!inIframe() && document.referrer) {
441
529
  site.ref = document.referrer;
442
- }
443
- let keywords = document.getElementsByTagName('meta')['keywords'];
444
- if (keywords && keywords.content) {
445
- site.keywords = keywords.content;
530
+ } else {
531
+ delete site.ref;
446
532
  }
447
533
  return site;
448
534
  }
@@ -9,7 +9,7 @@
9
9
  import { registerVideoSupport } from '../src/adServerManager.js';
10
10
  import { command as analyticsCommand, COMMAND } from './adlooxAnalyticsAdapter.js';
11
11
  import { ajax } from '../src/ajax.js';
12
- import { EVENTS } from '../src/constants.json';
12
+ import CONSTANTS from '../src/constants.json';
13
13
  import { targeting } from '../src/targeting.js';
14
14
  import { logInfo, isFn, logError, isPlainObject, isStr, isBoolean, deepSetValue, deepClone, timestamp, logWarn } from '../src/utils.js';
15
15
 
@@ -74,7 +74,7 @@ function track(options, callback) {
74
74
  bid.ext.adloox.video.adserver = false;
75
75
 
76
76
  analyticsCommand(COMMAND.TRACK, {
77
- eventType: EVENTS.BID_WON,
77
+ eventType: CONSTANTS.EVENTS.BID_WON,
78
78
  args: bid
79
79
  });
80
80
  }
@@ -9,7 +9,7 @@ import adapter from '../src/AnalyticsAdapter.js';
9
9
  import { loadExternalScript } from '../src/adloader.js';
10
10
  import { auctionManager } from '../src/auctionManager.js';
11
11
  import { AUCTION_COMPLETED } from '../src/auction.js';
12
- import { EVENTS } from '../src/constants.json';
12
+ import CONSTANTS from '../src/constants.json';
13
13
  import find from 'core-js-pure/features/array/find.js';
14
14
  import {
15
15
  deepAccess, logInfo, isPlainObject, logError, isStr, isNumber, getGptSlotInfoForAdUnitCode,
@@ -199,9 +199,9 @@ analyticsAdapter.url = function(url, args, bid) {
199
199
  return url + a2qs(args);
200
200
  }
201
201
 
202
- analyticsAdapter[`handle_${EVENTS.AUCTION_END}`] = function(auctionDetails) {
202
+ analyticsAdapter[`handle_${CONSTANTS.EVENTS.AUCTION_END}`] = function(auctionDetails) {
203
203
  if (!(auctionDetails.auctionStatus == AUCTION_COMPLETED && auctionDetails.bidsReceived.length > 0)) return;
204
- analyticsAdapter[`handle_${EVENTS.AUCTION_END}`] = NOOP;
204
+ analyticsAdapter[`handle_${CONSTANTS.EVENTS.AUCTION_END}`] = NOOP;
205
205
 
206
206
  logMessage(MODULE, 'preloading verification JS');
207
207
 
@@ -214,7 +214,7 @@ analyticsAdapter[`handle_${EVENTS.AUCTION_END}`] = function(auctionDetails) {
214
214
  insertElement(link);
215
215
  }
216
216
 
217
- analyticsAdapter[`handle_${EVENTS.BID_WON}`] = function(bid) {
217
+ analyticsAdapter[`handle_${CONSTANTS.EVENTS.BID_WON}`] = function(bid) {
218
218
  if (deepAccess(bid, 'ext.adloox.video.adserver')) {
219
219
  logMessage(MODULE, `measuring '${bid.mediaType}' ad unit code '${bid.adUnitCode}' via Ad Server module`);
220
220
  return;
@@ -1,10 +1,11 @@
1
1
  import {registerBidder} from '../src/adapters/bidderFactory.js';
2
2
  import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
3
3
  import { isFn, deepAccess, logMessage } from '../src/utils.js';
4
+ import {config} from '../src/config.js';
4
5
 
5
6
  const BIDDER_CODE = 'adman';
6
7
  const AD_URL = 'https://pub.admanmedia.com/?c=o&m=multi';
7
- const URL_SYNC = 'https://pub.admanmedia.com/?c=o&m=sync';
8
+ const URL_SYNC = 'https://pub.admanmedia.com';
8
9
 
9
10
  function isBidResponseValid(bid) {
10
11
  if (!bid.requestId || !bid.cpm || !bid.creativeId ||
@@ -108,6 +109,7 @@ export const spec = {
108
109
  }
109
110
  if (bid.userId) {
110
111
  getUserId(placement.eids, bid.userId.uid2 && bid.userId.uid2.id, 'uidapi.com');
112
+ getUserId(placement.eids, bid.userId.lotamePanoramaId, 'lotame.com');
111
113
  }
112
114
  if (traff === VIDEO) {
113
115
  placement.playerSize = bid.mediaTypes[VIDEO].playerSize;
@@ -151,19 +153,24 @@ export const spec = {
151
153
  },
152
154
 
153
155
  getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => {
154
- let syncUrl = URL_SYNC
156
+ let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image';
157
+ let syncUrl = URL_SYNC + `/${syncType}?pbjs=1`;
155
158
  if (gdprConsent && gdprConsent.consentString) {
156
159
  if (typeof gdprConsent.gdprApplies === 'boolean') {
157
160
  syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`;
158
161
  } else {
159
- syncUrl += `&gdpr==0&gdpr_consent=${gdprConsent.consentString}`;
162
+ syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`;
160
163
  }
161
164
  }
162
165
  if (uspConsent && uspConsent.consentString) {
163
166
  syncUrl += `&ccpa_consent=${uspConsent.consentString}`;
164
167
  }
168
+
169
+ const coppa = config.getConfig('coppa') ? 1 : 0;
170
+ syncUrl += `&coppa=${coppa}`;
171
+
165
172
  return [{
166
- type: 'image',
173
+ type: syncType,
167
174
  url: syncUrl
168
175
  }];
169
176
  }
@@ -4,7 +4,7 @@ import {config} from '../src/config.js';
4
4
  import {BANNER, VIDEO, NATIVE} from '../src/mediaTypes.js';
5
5
 
6
6
  const BIDDER_CODE = 'admixer';
7
- const ALIASES = ['go2net', 'adblender', 'adsyield'];
7
+ const ALIASES = ['go2net', 'adblender', 'adsyield', 'futureads'];
8
8
  const ENDPOINT_URL = 'https://inv-nets.admixer.net/prebid.1.2.aspx';
9
9
  export const spec = {
10
10
  code: BIDDER_CODE,
@@ -56,6 +56,8 @@ export const spec = {
56
56
  const requests = [];
57
57
  const request = [];
58
58
  const ortb2 = config.getConfig('ortb2');
59
+ const bidderConfig = config.getConfig();
60
+
59
61
  const adnMeta = handleMeta()
60
62
  const usi = getUsi(adnMeta, ortb2, bidderRequest)
61
63
  const segments = getSegmentsFromOrtb(ortb2);
@@ -68,7 +70,7 @@ export const spec = {
68
70
  if (gdprApplies !== undefined) request.push('consentString=' + consentString);
69
71
  if (segments.length > 0) request.push('segments=' + segments.join(','));
70
72
  if (usi) request.push('userId=' + usi);
71
-
73
+ if (bidderConfig.useCookie === false) request.push('noCookies=true')
72
74
  for (var i = 0; i < validBidRequests.length; i++) {
73
75
  const bid = validBidRequests[i]
74
76
  const network = bid.params.network || 'network';
@@ -14,6 +14,8 @@ const bidWon = CONSTANTS.EVENTS.BID_WON;
14
14
  const bidTimeout = CONSTANTS.EVENTS.BID_TIMEOUT;
15
15
  const ua = navigator.userAgent;
16
16
 
17
+ var _sampled = true;
18
+
17
19
  let adomikAdapter = Object.assign(adapter({}),
18
20
  {
19
21
  // Track every event needed
@@ -76,9 +78,12 @@ adomikAdapter.sendTypedEvent = function() {
76
78
  const groupedTypedEvents = adomikAdapter.buildTypedEvents();
77
79
 
78
80
  const bulkEvents = {
81
+ testId: adomikAdapter.currentContext.testId,
82
+ testValue: adomikAdapter.currentContext.testValue,
79
83
  uid: adomikAdapter.currentContext.uid,
80
84
  ahbaid: adomikAdapter.currentContext.id,
81
85
  hostname: window.location.hostname,
86
+ sampling: adomikAdapter.currentContext.sampling,
82
87
  eventsByPlacementCode: groupedTypedEvents.map(function(typedEventsByType) {
83
88
  let sizes = [];
84
89
  const eventKeys = ['request', 'response', 'winner'];
@@ -126,6 +131,8 @@ adomikAdapter.sendTypedEvent = function() {
126
131
  };
127
132
 
128
133
  adomikAdapter.sendWonEvent = function (wonEvent) {
134
+ let keyValues = { testId: adomikAdapter.currentContext.testId, testValue: adomikAdapter.currentContext.testValue }
135
+ wonEvent = {...wonEvent, ...keyValues}
129
136
  const stringWonEvent = JSON.stringify(wonEvent)
130
137
  logInfo('Won event sent to adomik prebid analytic ' + stringWonEvent);
131
138
 
@@ -199,17 +206,28 @@ adomikAdapter.adapterEnableAnalytics = adomikAdapter.enableAnalytics;
199
206
 
200
207
  adomikAdapter.enableAnalytics = function (config) {
201
208
  adomikAdapter.currentContext = {};
202
-
203
209
  const initOptions = config.options;
204
- if (initOptions) {
205
- adomikAdapter.currentContext = {
206
- uid: initOptions.id,
207
- url: initOptions.url,
208
- id: '',
209
- timeouted: false,
210
+
211
+ _sampled = typeof config === 'undefined' ||
212
+ typeof config.sampling === 'undefined' ||
213
+ Math.random() < parseFloat(config.sampling);
214
+
215
+ if (_sampled) {
216
+ if (initOptions) {
217
+ adomikAdapter.currentContext = {
218
+ uid: initOptions.id,
219
+ url: initOptions.url,
220
+ testId: initOptions.testId,
221
+ testValue: initOptions.testValue,
222
+ id: '',
223
+ timeouted: false,
224
+ sampling: config.sampling
225
+ }
226
+ logInfo('Adomik Analytics enabled with config', initOptions);
227
+ adomikAdapter.adapterEnableAnalytics(config);
210
228
  }
211
- logInfo('Adomik Analytics enabled with config', initOptions);
212
- adomikAdapter.adapterEnableAnalytics(config);
229
+ } else {
230
+ logInfo('Adomik Analytics ignored for sampling', config.sampling);
213
231
  }
214
232
  };
215
233
 
@@ -0,0 +1,103 @@
1
+ /**
2
+ * This module adds Adquery QID to the User ID module
3
+ * The {@link module:modules/userId} module is required
4
+ * @module modules/adqueryIdSystem
5
+ * @requires module:modules/userId
6
+ */
7
+
8
+ import {ajax} from '../src/ajax.js';
9
+ import {getStorageManager} from '../src/storageManager.js';
10
+ import {submodule} from '../src/hook.js';
11
+ import * as utils from '../src/utils.js';
12
+
13
+ const MODULE_NAME = 'qid';
14
+ const AU_GVLID = 902;
15
+
16
+ export const storage = getStorageManager(AU_GVLID, 'qid');
17
+
18
+ /**
19
+ * Param or default.
20
+ * @param {String} param
21
+ * @param {String} defaultVal
22
+ */
23
+ function paramOrDefault(param, defaultVal, arg) {
24
+ if (utils.isFn(param)) {
25
+ return param(arg);
26
+ } else if (utils.isStr(param)) {
27
+ return param;
28
+ }
29
+ return defaultVal;
30
+ }
31
+
32
+ /** @type {Submodule} */
33
+ export const adqueryIdSubmodule = {
34
+ /**
35
+ * used to link submodule with config
36
+ * @type {string}
37
+ */
38
+ name: MODULE_NAME,
39
+
40
+ /**
41
+ * IAB TCF Vendor ID
42
+ * @type {string}
43
+ */
44
+ gvlid: AU_GVLID,
45
+
46
+ /**
47
+ * decode the stored id value for passing to bid requests
48
+ * @function
49
+ * @param {{value:string}} value
50
+ * @returns {{qid:Object}}
51
+ */
52
+ decode(value) {
53
+ let qid = storage.getDataFromLocalStorage('qid');
54
+ if (utils.isStr(qid)) {
55
+ return {qid: qid};
56
+ }
57
+ return (value && typeof value['qid'] === 'string') ? { 'qid': value['qid'] } : undefined;
58
+ },
59
+ /**
60
+ * performs action to obtain id and return a value in the callback's response argument
61
+ * @function
62
+ * @param {SubmoduleConfig} [config]
63
+ * @returns {IdResponse|undefined}
64
+ */
65
+ getId(config) {
66
+ if (!utils.isPlainObject(config.params)) {
67
+ config.params = {};
68
+ }
69
+ const url = paramOrDefault(config.params.url,
70
+ `https://bidder.adquery.io/prebid/qid`,
71
+ config.params.urlArg);
72
+
73
+ const resp = function (callback) {
74
+ let qid = storage.getDataFromLocalStorage('qid');
75
+ if (utils.isStr(qid)) {
76
+ const responseObj = {qid: qid};
77
+ callback(responseObj);
78
+ } else {
79
+ const callbacks = {
80
+ success: response => {
81
+ let responseObj;
82
+ if (response) {
83
+ try {
84
+ responseObj = JSON.parse(response);
85
+ } catch (error) {
86
+ utils.logError(error);
87
+ }
88
+ }
89
+ callback(responseObj);
90
+ },
91
+ error: error => {
92
+ utils.logError(`${MODULE_NAME}: ID fetch encountered an error`, error);
93
+ callback();
94
+ }
95
+ };
96
+ ajax(url, callbacks, undefined, {method: 'GET'});
97
+ }
98
+ };
99
+ return {callback: resp};
100
+ }
101
+ };
102
+
103
+ submodule('userId', adqueryIdSubmodule);
@@ -0,0 +1,35 @@
1
+ # Adquery QID
2
+
3
+ Adquery QID Module. For assistance setting up your module please contact us at [prebid@adquery.io](prebid@adquery.io).
4
+
5
+ ### Prebid Params
6
+
7
+ Individual params may be set for the Adquery ID Submodule. At least one identifier must be set in the params.
8
+
9
+ ```
10
+ pbjs.setConfig({
11
+ usersync: {
12
+ userIds: [{
13
+ name: 'qid',
14
+ storage: {
15
+ name: 'qid',
16
+ type: 'html5'
17
+ }
18
+ }]
19
+ }
20
+ });
21
+ ```
22
+ ## Parameter Descriptions for the `usersync` Configuration Section
23
+ The below parameters apply only to the Adquery User ID Module integration.
24
+
25
+ | Param under usersync.userIds[] | Scope | Type | Description | Example |
26
+ | --- | --- | --- | --- | --- |
27
+ | name | Required | String | ID value for the Adquery ID module - `"qid"` | `"qid"` |
28
+ | storage | Required | Object | The publisher must specify the local storage in which to store the results of the call to get the user ID. | |
29
+ | storage.type | Required | String | This is where the results of the user ID will be stored. The recommended method is `localStorage` by specifying `html5`. | `"html5"` |
30
+ | storage.name | Required | String | The name of the html5 local storage where the user ID will be stored. | `"qid"` |
31
+ | storage.expires | Optional | Integer | How long (in days) the user ID information will be stored. | `365` |
32
+ | value | Optional | Object | Used only if the page has a separate mechanism for storing the Adquery ID. The value is an object containing the values to be sent to the adapters. In this scenario, no URL is called and nothing is added to local storage | `{"qid": "2abf9f001fcd81241b67"}` |
33
+ | params | Optional | Object | Used to store params for the id system |
34
+ | params.url | Optional | String | Set an alternate GET url for qid with this parameter |
35
+ | params.urlArg | Optional | Object | Optional url parameter for params.url |