prebid.js 6.1.0 → 6.5.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 (184) hide show
  1. package/.circleci/config.yml +1 -1
  2. package/README.md +1 -1
  3. package/browsers.json +13 -29
  4. package/gulpfile.js +87 -82
  5. package/integrationExamples/gpt/weboramaRtdProvider_example.html +23 -14
  6. package/karma.conf.maker.js +2 -2
  7. package/modules/33acrossBidAdapter.js +189 -102
  8. package/modules/adagioBidAdapter.js +1 -1
  9. package/modules/addefendBidAdapter.js +1 -0
  10. package/modules/adkernelBidAdapter.js +146 -61
  11. package/modules/adlooxAdServerVideo.js +2 -2
  12. package/modules/adlooxAnalyticsAdapter.js +4 -4
  13. package/modules/admanBidAdapter.js +1 -0
  14. package/modules/admixerBidAdapter.js +3 -2
  15. package/modules/adnuntiusBidAdapter.js +5 -2
  16. package/modules/adomikAnalyticsAdapter.js +6 -0
  17. package/modules/adplusBidAdapter.js +203 -0
  18. package/modules/adplusBidAdapter.md +39 -0
  19. package/modules/adxcgBidAdapter.js +311 -359
  20. package/modules/adxcgBidAdapter.md +22 -21
  21. package/modules/adyoulikeBidAdapter.js +20 -11
  22. package/modules/aniviewBidAdapter.js +1 -1
  23. package/modules/appnexusBidAdapter.js +19 -3
  24. package/modules/beachfrontBidAdapter.js +14 -17
  25. package/modules/beopBidAdapter.js +6 -4
  26. package/modules/bidViewability.js +3 -3
  27. package/modules/bidViewabilityIO.js +3 -3
  28. package/modules/bliinkBidAdapter.js +1 -1
  29. package/modules/colossussspBidAdapter.js +7 -0
  30. package/modules/compassBidAdapter.js +201 -0
  31. package/modules/compassBidAdapter.md +79 -0
  32. package/modules/consentManagement.js +7 -1
  33. package/modules/craftBidAdapter.js +5 -3
  34. package/modules/criteoBidAdapter.js +1 -1
  35. package/modules/currency.js +2 -2
  36. package/modules/cwireBidAdapter.js +3 -0
  37. package/modules/dailyhuntBidAdapter.js +435 -0
  38. package/modules/dailyhuntBidAdapter.md +4 -0
  39. package/modules/dchain.js +149 -0
  40. package/modules/dchain.md +45 -0
  41. package/modules/docereeBidAdapter.js +10 -1
  42. package/modules/docereeBidAdapter.md +2 -0
  43. package/modules/dspxBidAdapter.js +1 -1
  44. package/modules/emx_digitalBidAdapter.js +9 -1
  45. package/modules/engageyaBidAdapter.js +1 -1
  46. package/modules/feedadBidAdapter.js +2 -2
  47. package/modules/feedadBidAdapter.md +4 -2
  48. package/modules/freewheel-sspBidAdapter.js +6 -0
  49. package/modules/futureads.md +48 -0
  50. package/modules/glimpseBidAdapter.js +16 -3
  51. package/modules/goldbachBidAdapter.js +1176 -0
  52. package/modules/goldbachBidAdapter.md +151 -0
  53. package/modules/gptPreAuction.js +55 -7
  54. package/modules/gridBidAdapter.js +4 -3
  55. package/modules/gumgumBidAdapter.js +7 -3
  56. package/modules/improvedigitalBidAdapter.js +19 -3
  57. package/modules/instreamTracking.js +4 -4
  58. package/modules/intersectionRtdProvider.js +114 -0
  59. package/modules/invibesBidAdapter.js +64 -14
  60. package/modules/invibesBidAdapter.md +2 -1
  61. package/modules/ipromBidAdapter.js +79 -0
  62. package/modules/ixBidAdapter.js +53 -18
  63. package/modules/kinessoIdSystem.js +1 -1
  64. package/modules/limelightDigitalBidAdapter.js +3 -1
  65. package/modules/livewrappedAnalyticsAdapter.js +3 -1
  66. package/modules/livewrappedBidAdapter.js +8 -2
  67. package/modules/loglyliftBidAdapter.js +79 -0
  68. package/modules/loglyliftBidAdapter.md +55 -0
  69. package/modules/lotamePanoramaIdSystem.js +80 -8
  70. package/modules/luponmediaBidAdapter.js +570 -0
  71. package/modules/mediasquareBidAdapter.js +1 -9
  72. package/modules/missenaBidAdapter.js +89 -0
  73. package/modules/nextMillenniumBidAdapter.js +37 -7
  74. package/modules/optimeraRtdProvider.js +8 -1
  75. package/modules/ozoneBidAdapter.js +21 -64
  76. package/modules/prebidServerBidAdapter/index.js +16 -12
  77. package/modules/pubgeniusBidAdapter.js +1 -1
  78. package/modules/pubmaticBidAdapter.js +3 -3
  79. package/modules/pubxaiAnalyticsAdapter.js +17 -0
  80. package/modules/relaidoBidAdapter.js +86 -65
  81. package/modules/richaudienceBidAdapter.js +2 -3
  82. package/modules/rtdModule/index.js +48 -18
  83. package/modules/rubiconBidAdapter.js +31 -19
  84. package/modules/sharedIdSystem.js +27 -1
  85. package/modules/smaatoBidAdapter.js +4 -1
  86. package/modules/smartxBidAdapter.js +17 -1
  87. package/modules/tappxBidAdapter.js +3 -1
  88. package/modules/targetVideoBidAdapter.js +187 -0
  89. package/modules/targetVideoBidAdapter.md +34 -0
  90. package/modules/telariaBidAdapter.js +2 -2
  91. package/modules/trustxBidAdapter.js +8 -16
  92. package/modules/undertoneBidAdapter.js +8 -1
  93. package/modules/userId/index.js +27 -2
  94. package/modules/ventes.md +71 -0
  95. package/modules/ventesBidAdapter.js +104 -64
  96. package/modules/ventesBidAdapter.md +0 -1
  97. package/modules/vidoomyBidAdapter.js +16 -10
  98. package/modules/visxBidAdapter.js +19 -2
  99. package/modules/visxBidAdapter.md +4 -6
  100. package/modules/weboramaRtdProvider.js +288 -73
  101. package/modules/weboramaRtdProvider.md +27 -10
  102. package/modules/yahoosspBidAdapter.js +5 -1
  103. package/modules/yahoosspBidAdapter.md +1 -1
  104. package/modules/yieldmoBidAdapter.js +23 -5
  105. package/modules/yieldoneBidAdapter.js +115 -11
  106. package/modules/zetaSspBidAdapter.md +33 -1
  107. package/modules/zeta_global_sspAnalyticsAdapter.js +97 -0
  108. package/modules/zeta_global_sspAnalyticsAdapter.md +24 -0
  109. package/modules/zeta_global_sspBidAdapter.js +22 -1
  110. package/package.json +1 -1
  111. package/plugins/pbjsGlobals.js +28 -1
  112. package/src/auction.js +5 -4
  113. package/src/config.js +27 -3
  114. package/src/prebid.js +3 -2
  115. package/src/targeting.js +24 -3
  116. package/src/utils.js +53 -8
  117. package/test/helpers/prebidGlobal.js +1 -0
  118. package/test/spec/config_spec.js +279 -0
  119. package/test/spec/integration/faker/googletag.js +6 -0
  120. package/test/spec/modules/33acrossBidAdapter_spec.js +300 -78
  121. package/test/spec/modules/adlooxAnalyticsAdapter_spec.js +6 -6
  122. package/test/spec/modules/adnuntiusBidAdapter_spec.js +35 -0
  123. package/test/spec/modules/adomikAnalyticsAdapter_spec.js +6 -0
  124. package/test/spec/modules/adplusBidAdapter_spec.js +213 -0
  125. package/test/spec/modules/adxcgBidAdapter_spec.js +820 -571
  126. package/test/spec/modules/adyoulikeBidAdapter_spec.js +75 -0
  127. package/test/spec/modules/appnexusBidAdapter_spec.js +49 -1
  128. package/test/spec/modules/beachfrontBidAdapter_spec.js +65 -1
  129. package/test/spec/modules/beopBidAdapter_spec.js +1 -1
  130. package/test/spec/modules/bidViewabilityIO_spec.js +2 -2
  131. package/test/spec/modules/bidViewability_spec.js +4 -4
  132. package/test/spec/modules/colossussspBidAdapter_spec.js +9 -0
  133. package/test/spec/modules/compassBidAdapter_spec.js +397 -0
  134. package/test/spec/modules/consentManagement_spec.js +20 -0
  135. package/test/spec/modules/cwireBidAdapter_spec.js +10 -8
  136. package/test/spec/modules/dailyhuntBidAdapter_spec.js +404 -0
  137. package/test/spec/modules/dchain_spec.js +329 -0
  138. package/test/spec/modules/docereeBidAdapter_spec.js +9 -1
  139. package/test/spec/modules/emx_digitalBidAdapter_spec.js +10 -0
  140. package/test/spec/modules/feedadBidAdapter_spec.js +15 -0
  141. package/test/spec/modules/freewheel-sspBidAdapter_spec.js +19 -0
  142. package/test/spec/modules/goldbachBidAdapter_spec.js +1359 -0
  143. package/test/spec/modules/gptPreAuction_spec.js +177 -2
  144. package/test/spec/modules/gumgumBidAdapter_spec.js +6 -0
  145. package/test/spec/modules/improvedigitalBidAdapter_spec.js +3 -1
  146. package/test/spec/modules/intersectionRtdProvider_spec.js +141 -0
  147. package/test/spec/modules/invibesBidAdapter_spec.js +148 -4
  148. package/test/spec/modules/ipromBidAdapter_spec.js +195 -0
  149. package/test/spec/modules/ixBidAdapter_spec.js +112 -62
  150. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +84 -23
  151. package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +22 -0
  152. package/test/spec/modules/livewrappedBidAdapter_spec.js +31 -0
  153. package/test/spec/modules/loglyliftBidAdapter_spec.js +172 -0
  154. package/test/spec/modules/lotamePanoramaIdSystem_spec.js +227 -0
  155. package/test/spec/modules/luponmediaBidAdapter_spec.js +412 -0
  156. package/test/spec/modules/mediasquareBidAdapter_spec.js +4 -4
  157. package/test/spec/modules/missenaBidAdapter_spec.js +134 -0
  158. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +26 -1
  159. package/test/spec/modules/optimeraRtdProvider_spec.js +14 -1
  160. package/test/spec/modules/ozoneBidAdapter_spec.js +43 -31
  161. package/test/spec/modules/prebidServerBidAdapter_spec.js +43 -0
  162. package/test/spec/modules/pubgeniusBidAdapter_spec.js +3 -3
  163. package/test/spec/modules/pubmaticBidAdapter_spec.js +1 -1
  164. package/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +11 -0
  165. package/test/spec/modules/realTimeDataModule_spec.js +135 -49
  166. package/test/spec/modules/relaidoBidAdapter_spec.js +71 -63
  167. package/test/spec/modules/richaudienceBidAdapter_spec.js +2 -2
  168. package/test/spec/modules/rubiconBidAdapter_spec.js +65 -9
  169. package/test/spec/modules/sharedIdSystem_spec.js +52 -6
  170. package/test/spec/modules/smaatoBidAdapter_spec.js +31 -0
  171. package/test/spec/modules/smartxBidAdapter_spec.js +9 -0
  172. package/test/spec/modules/tappxBidAdapter_spec.js +4 -0
  173. package/test/spec/modules/targetVideoBidAdapter_spec.js +96 -0
  174. package/test/spec/modules/userId_spec.js +51 -0
  175. package/test/spec/modules/visxBidAdapter_spec.js +120 -4
  176. package/test/spec/modules/weboramaRtdProvider_spec.js +408 -214
  177. package/test/spec/modules/yahoosspBidAdapter_spec.js +28 -1
  178. package/test/spec/modules/yieldoneBidAdapter_spec.js +299 -53
  179. package/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js +427 -0
  180. package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +33 -1
  181. package/test/spec/unit/core/targeting_spec.js +116 -0
  182. package/test/spec/utils_spec.js +38 -0
  183. package/test/test_deps.js +3 -0
  184. 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';
@@ -103,17 +103,16 @@ export const spec = {
103
103
  * @returns {ServerRequest[]}
104
104
  */
105
105
  buildRequests: function (bidRequests, bidderRequest) {
106
- let impDispatch = dispatchImps(bidRequests, bidderRequest.refererInfo);
106
+ let impGroups = groupImpressionsByHostZone(bidRequests, bidderRequest.refererInfo);
107
107
  let requests = [];
108
108
  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
- });
109
+ _each(impGroups, impGroup => {
110
+ let {host, zoneId, imps} = impGroup;
111
+ const request = buildRtbRequest(imps, bidderRequest, schain);
112
+ requests.push({
113
+ method: 'POST',
114
+ url: `https://${host}/hb?zone=${zoneId}&v=${VERSION}`,
115
+ data: JSON.stringify(request)
117
116
  });
118
117
  });
119
118
  return requests;
@@ -209,17 +208,19 @@ registerBidder(spec);
209
208
  * @param bidRequests {BidRequest[]}
210
209
  * @param refererInfo {refererInfo}
211
210
  */
212
- function dispatchImps(bidRequests, refererInfo) {
211
+ function groupImpressionsByHostZone(bidRequests, refererInfo) {
213
212
  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
- }, {});
213
+ return Object.values(
214
+ bidRequests.map(bidRequest => buildImp(bidRequest, secure))
215
+ .reduce((acc, curr, index) => {
216
+ let bidRequest = bidRequests[index];
217
+ let {zoneId, host} = bidRequest.params;
218
+ let key = `${host}_${zoneId}`;
219
+ acc[key] = acc[key] || {host: host, zoneId: zoneId, imps: []};
220
+ acc[key].imps.push(curr);
221
+ return acc;
222
+ }, {})
223
+ );
223
224
  }
224
225
 
225
226
  function getBidFloor(bid, mediaType, sizes) {
@@ -365,57 +366,142 @@ function getAllowedSyncMethod(bidderCode) {
365
366
  }
366
367
 
367
368
  /**
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
369
+ * Create device object from fpd and host-collected data
370
+ * @param fpd {Object}
371
+ * @returns {{device: Object}}
373
372
  */
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
- };
373
+ function makeDevice(fpd) {
374
+ let device = mergeDeep({
375
+ 'ip': 'caller',
376
+ 'ipv6': 'caller',
377
+ 'ua': 'caller',
378
+ 'js': 1,
379
+ 'language': getLanguage()
380
+ }, fpd.device || {});
391
381
  if (getDNT()) {
392
- req.device.dnt = 1;
382
+ device.dnt = 1;
383
+ }
384
+ return {device: device};
385
+ }
386
+
387
+ /**
388
+ * Create site or app description object
389
+ * @param bidderRequest {BidderRequest}
390
+ * @param fpd {Object}
391
+ * @returns {{site: Object}|{app: Object}}
392
+ */
393
+ function makeSiteOrApp(bidderRequest, fpd) {
394
+ let {refererInfo} = bidderRequest;
395
+ let appConfig = config.getConfig('app');
396
+ if (isEmpty(appConfig)) {
397
+ return {site: createSite(refererInfo, fpd)}
398
+ } else {
399
+ return {app: appConfig};
393
400
  }
401
+ }
402
+
403
+ /**
404
+ * Create user description object
405
+ * @param bidderRequest {BidderRequest}
406
+ * @param fpd {Object}
407
+ * @returns {{user: Object} | undefined}
408
+ */
409
+ function makeUser(bidderRequest, fpd) {
410
+ let {gdprConsent} = bidderRequest;
411
+ let user = fpd.user || {};
412
+ if (gdprConsent && gdprConsent.consentString !== undefined) {
413
+ deepSetValue(user, 'ext.consent', gdprConsent.consentString);
414
+ }
415
+ let eids = getExtendedUserIds(bidderRequest);
416
+ if (eids) {
417
+ deepSetValue(user, 'ext.eids', eids);
418
+ }
419
+ if (!isEmpty(user)) { return {user: user}; }
420
+ }
421
+
422
+ /**
423
+ * Create privacy regulations object
424
+ * @param bidderRequest {BidderRequest}
425
+ * @returns {{regs: Object} | undefined}
426
+ */
427
+ function makeRegulations(bidderRequest) {
428
+ let {gdprConsent, uspConsent} = bidderRequest;
429
+ let regs = {};
394
430
  if (gdprConsent) {
395
431
  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);
432
+ deepSetValue(regs, 'regs.ext.gdpr', ~~gdprConsent.gdprApplies);
400
433
  }
401
434
  }
402
435
  if (uspConsent) {
403
- deepSetValue(req, 'regs.ext.us_privacy', uspConsent);
436
+ deepSetValue(regs, 'regs.ext.us_privacy', uspConsent);
437
+ }
438
+ if (config.getConfig('coppa')) {
439
+ deepSetValue(regs, 'regs.coppa', 1);
404
440
  }
405
- if (coppa) {
406
- deepSetValue(req, 'regs.coppa', 1);
441
+ if (!isEmpty(regs)) {
442
+ return regs;
407
443
  }
444
+ }
445
+
446
+ /**
447
+ * Create top-level request object
448
+ * @param bidderRequest {BidderRequest}
449
+ * @param imps {Object} Impressions
450
+ * @param fpd {Object} First party data
451
+ * @returns
452
+ */
453
+ function makeBaseRequest(bidderRequest, imps, fpd) {
454
+ let {auctionId, timeout} = bidderRequest;
455
+ let request = {
456
+ 'id': auctionId,
457
+ 'imp': imps,
458
+ 'at': 1,
459
+ 'tmax': parseInt(timeout)
460
+ };
461
+ if (!isEmpty(fpd.bcat)) {
462
+ request.bcat = fpd.bcat;
463
+ }
464
+ if (!isEmpty(fpd.badv)) {
465
+ request.badv = fpd.badv;
466
+ }
467
+ return request;
468
+ }
469
+
470
+ /**
471
+ * Initialize sync capabilities
472
+ * @param bidderRequest {BidderRequest}
473
+ */
474
+ function makeSyncInfo(bidderRequest) {
475
+ let {bidderCode} = bidderRequest;
408
476
  let syncMethod = getAllowedSyncMethod(bidderCode);
409
477
  if (syncMethod) {
410
- deepSetValue(req, 'ext.adk_usersync', syncMethod);
478
+ let res = {};
479
+ deepSetValue(res, 'ext.adk_usersync', syncMethod);
480
+ return res;
411
481
  }
482
+ }
483
+
484
+ /**
485
+ * Builds complete rtb request
486
+ * @param imps {Object} Collection of rtb impressions
487
+ * @param bidderRequest {BidderRequest}
488
+ * @param schain {Object=} Supply chain config
489
+ * @return {Object} Complete rtb request
490
+ */
491
+ function buildRtbRequest(imps, bidderRequest, schain) {
492
+ let fpd = config.getConfig('ortb2') || {};
493
+
494
+ let req = mergeDeep(
495
+ makeBaseRequest(bidderRequest, imps, fpd),
496
+ makeDevice(fpd),
497
+ makeSiteOrApp(bidderRequest, fpd),
498
+ makeUser(bidderRequest, fpd),
499
+ makeRegulations(bidderRequest),
500
+ makeSyncInfo(bidderRequest)
501
+ );
412
502
  if (schain) {
413
503
  deepSetValue(req, 'source.ext.schain', schain);
414
504
  }
415
- let eids = getExtendedUserIds(bidderRequest);
416
- if (eids) {
417
- deepSetValue(req, 'user.ext.eids', eids);
418
- }
419
505
  return req;
420
506
  }
421
507
 
@@ -431,18 +517,17 @@ function getLanguage() {
431
517
  /**
432
518
  * Creates site description object
433
519
  */
434
- function createSite(refInfo) {
520
+ function createSite(refInfo, fpd) {
435
521
  let url = parseUrl(refInfo.referer);
436
522
  let site = {
437
523
  'domain': url.hostname,
438
524
  'page': `${url.protocol}://${url.hostname}${url.pathname}`
439
525
  };
440
- if (self === top && document.referrer) {
526
+ mergeDeep(site, fpd.site);
527
+ if (!inIframe() && document.referrer) {
441
528
  site.ref = document.referrer;
442
- }
443
- let keywords = document.getElementsByTagName('meta')['keywords'];
444
- if (keywords && keywords.content) {
445
- site.keywords = keywords.content;
529
+ } else {
530
+ delete site.ref;
446
531
  }
447
532
  return site;
448
533
  }
@@ -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;
@@ -108,6 +108,7 @@ export const spec = {
108
108
  }
109
109
  if (bid.userId) {
110
110
  getUserId(placement.eids, bid.userId.uid2 && bid.userId.uid2.id, 'uidapi.com');
111
+ getUserId(placement.eids, bid.userId.lotamePanoramaId, 'lotame.com');
111
112
  }
112
113
  if (traff === VIDEO) {
113
114
  placement.playerSize = bid.mediaTypes[VIDEO].playerSize;
@@ -1,14 +1,15 @@
1
1
  import { logError } from '../src/utils.js';
2
2
  import {registerBidder} from '../src/adapters/bidderFactory.js';
3
3
  import {config} from '../src/config.js';
4
+ import {BANNER, VIDEO, NATIVE} from '../src/mediaTypes.js';
4
5
 
5
6
  const BIDDER_CODE = 'admixer';
6
- const ALIASES = ['go2net', 'adblender', 'adsyield'];
7
+ const ALIASES = ['go2net', 'adblender', 'adsyield', 'futureads'];
7
8
  const ENDPOINT_URL = 'https://inv-nets.admixer.net/prebid.1.2.aspx';
8
9
  export const spec = {
9
10
  code: BIDDER_CODE,
10
11
  aliases: ALIASES,
11
- supportedMediaTypes: ['banner', 'video'],
12
+ supportedMediaTypes: [BANNER, VIDEO, NATIVE],
12
13
  /**
13
14
  * Determines whether or not the given bid request is valid.
14
15
  */
@@ -37,7 +37,8 @@ const handleMeta = function () {
37
37
  }
38
38
 
39
39
  const getUsi = function (meta, ortb2, bidderRequest) {
40
- const usi = (meta !== null) ? meta.usi : false;
40
+ let usi = (meta !== null && meta.usi) ? meta.usi : false;
41
+ if (ortb2 && ortb2.user && ortb2.user.id) { usi = ortb2.user.id }
41
42
  return usi
42
43
  }
43
44
 
@@ -55,6 +56,8 @@ export const spec = {
55
56
  const requests = [];
56
57
  const request = [];
57
58
  const ortb2 = config.getConfig('ortb2');
59
+ const bidderConfig = config.getConfig();
60
+
58
61
  const adnMeta = handleMeta()
59
62
  const usi = getUsi(adnMeta, ortb2, bidderRequest)
60
63
  const segments = getSegmentsFromOrtb(ortb2);
@@ -67,7 +70,7 @@ export const spec = {
67
70
  if (gdprApplies !== undefined) request.push('consentString=' + consentString);
68
71
  if (segments.length > 0) request.push('segments=' + segments.join(','));
69
72
  if (usi) request.push('userId=' + usi);
70
-
73
+ if (bidderConfig.useCookie === false) request.push('noCookies=true')
71
74
  for (var i = 0; i < validBidRequests.length; i++) {
72
75
  const bid = validBidRequests[i]
73
76
  const network = bid.params.network || 'network';
@@ -76,6 +76,8 @@ adomikAdapter.sendTypedEvent = function() {
76
76
  const groupedTypedEvents = adomikAdapter.buildTypedEvents();
77
77
 
78
78
  const bulkEvents = {
79
+ testId: adomikAdapter.currentContext.testId,
80
+ testValue: adomikAdapter.currentContext.testValue,
79
81
  uid: adomikAdapter.currentContext.uid,
80
82
  ahbaid: adomikAdapter.currentContext.id,
81
83
  hostname: window.location.hostname,
@@ -126,6 +128,8 @@ adomikAdapter.sendTypedEvent = function() {
126
128
  };
127
129
 
128
130
  adomikAdapter.sendWonEvent = function (wonEvent) {
131
+ let keyValues = { testId: adomikAdapter.currentContext.testId, testValue: adomikAdapter.currentContext.testValue }
132
+ wonEvent = {...wonEvent, ...keyValues}
129
133
  const stringWonEvent = JSON.stringify(wonEvent)
130
134
  logInfo('Won event sent to adomik prebid analytic ' + stringWonEvent);
131
135
 
@@ -205,6 +209,8 @@ adomikAdapter.enableAnalytics = function (config) {
205
209
  adomikAdapter.currentContext = {
206
210
  uid: initOptions.id,
207
211
  url: initOptions.url,
212
+ testId: initOptions.testId,
213
+ testValue: initOptions.testValue,
208
214
  id: '',
209
215
  timeouted: false,
210
216
  }
@@ -0,0 +1,203 @@
1
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
2
+ import * as utils from '../src/utils.js';
3
+ import { BANNER } from '../src/mediaTypes.js';
4
+ import { getStorageManager } from '../src/storageManager.js';
5
+
6
+ // #region Constants
7
+ export const BIDDER_CODE = 'adplus';
8
+ export const ADPLUS_ENDPOINT = 'https://ssp.ad-plus.com.tr/server/headerBidding';
9
+ export const DGID_CODE = 'adplus_dg_id';
10
+ export const SESSION_CODE = 'adplus_s_id';
11
+ export const storage = getStorageManager(undefined, BIDDER_CODE);
12
+ const COOKIE_EXP = 1000 * 60 * 60 * 24; // 1 day
13
+ // #endregion
14
+
15
+ // #region Helpers
16
+ export function isValidUuid (uuid) {
17
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(
18
+ uuid
19
+ );
20
+ }
21
+
22
+ function getSessionId() {
23
+ let sid = storage.cookiesAreEnabled() && storage.getCookie(SESSION_CODE);
24
+
25
+ if (
26
+ !sid || !isValidUuid(sid)
27
+ ) {
28
+ sid = utils.generateUUID();
29
+ setSessionId(sid);
30
+ }
31
+
32
+ return sid;
33
+ }
34
+
35
+ function setSessionId(sid) {
36
+ if (storage.cookiesAreEnabled()) {
37
+ const expires = new Date(Date.now() + COOKIE_EXP).toISOString();
38
+
39
+ storage.setCookie(SESSION_CODE, sid, expires);
40
+ }
41
+ }
42
+ // #endregion
43
+
44
+ // #region Bid request validation
45
+ function isBidRequestValid(bid) {
46
+ if (!bid) {
47
+ utils.logError(BIDDER_CODE, 'bid, can not be empty', bid);
48
+ return false;
49
+ }
50
+
51
+ if (!bid.params) {
52
+ utils.logError(BIDDER_CODE, 'bid.params is required.');
53
+ return false;
54
+ }
55
+
56
+ if (!bid.params.adUnitId || typeof bid.params.adUnitId !== 'string') {
57
+ utils.logError(
58
+ BIDDER_CODE,
59
+ 'bid.params.adUnitId is missing or has wrong type.'
60
+ );
61
+ return false;
62
+ }
63
+
64
+ if (!bid.params.inventoryId || typeof bid.params.inventoryId !== 'string') {
65
+ utils.logError(
66
+ BIDDER_CODE,
67
+ 'bid.params.inventoryId is missing or has wrong type.'
68
+ );
69
+ return false;
70
+ }
71
+
72
+ if (
73
+ !bid.mediaTypes ||
74
+ !bid.mediaTypes[BANNER] ||
75
+ !utils.isArray(bid.mediaTypes[BANNER].sizes) ||
76
+ bid.mediaTypes[BANNER].sizes.length <= 0 ||
77
+ !utils.isArrayOfNums(bid.mediaTypes[BANNER].sizes[0])
78
+ ) {
79
+ utils.logError(BIDDER_CODE, 'Wrong or missing size parameters.');
80
+ return false;
81
+ }
82
+
83
+ return true;
84
+ }
85
+ // #endregion
86
+
87
+ // #region Building the bid requests
88
+ /**
89
+ *
90
+ * @param {object} bid
91
+ * @returns
92
+ */
93
+ function createBidRequest(bid) {
94
+ // Developer Params
95
+ const {
96
+ inventoryId,
97
+ adUnitId,
98
+ extraData,
99
+ yearOfBirth,
100
+ gender,
101
+ categories,
102
+ latitude,
103
+ longitude,
104
+ sdkVersion,
105
+ } = bid.params;
106
+
107
+ return {
108
+ method: 'GET',
109
+ url: ADPLUS_ENDPOINT,
110
+ data: utils.cleanObj({
111
+ bidId: bid.bidId,
112
+ inventoryId,
113
+ adUnitId,
114
+ adUnitWidth: bid.mediaTypes[BANNER].sizes[0][0],
115
+ adUnitHeight: bid.mediaTypes[BANNER].sizes[0][1],
116
+ extraData,
117
+ yearOfBirth,
118
+ gender,
119
+ categories,
120
+ latitude,
121
+ longitude,
122
+ sdkVersion: sdkVersion || '1',
123
+ session: getSessionId(),
124
+ interstitial: 0,
125
+ token: typeof window.top === 'object' && window.top[DGID_CODE] ? window.top[DGID_CODE] : undefined,
126
+ secure: window.location.protocol === 'https:' ? 1 : 0,
127
+ screenWidth: screen.width,
128
+ screenHeight: screen.height,
129
+ language: window.navigator.language || 'en-US',
130
+ pageUrl: window.location.href,
131
+ domain: window.location.hostname,
132
+ referrer: window.location.referrer,
133
+ }),
134
+ };
135
+ }
136
+
137
+ function buildRequests(validBidRequests, bidderRequest) {
138
+ return validBidRequests.map((req) => createBidRequest(req));
139
+ }
140
+ // #endregion
141
+
142
+ // #region Interpreting Responses
143
+ /**
144
+ *
145
+ * @param {HeaderBiddingResponse} responseData
146
+ * @param { object } bidParams
147
+ * @returns
148
+ */
149
+ function createAdResponse(responseData, bidParams) {
150
+ return {
151
+ requestId: responseData.requestID,
152
+ cpm: responseData.cpm,
153
+ currency: responseData.currency,
154
+ width: responseData.width,
155
+ height: responseData.height,
156
+ creativeId: responseData.creativeID,
157
+ dealId: responseData.dealID,
158
+ netRevenue: responseData.netRevenue,
159
+ ttl: responseData.ttl,
160
+ ad: responseData.ad,
161
+ mediaType: responseData.mediaType,
162
+ meta: {
163
+ advertiserDomains: responseData.advertiserDomains,
164
+ primaryCatId: utils.isArray(responseData.categoryIDs) && responseData.categoryIDs.length > 0
165
+ ? responseData.categoryIDs[0] : undefined,
166
+ secondaryCatIds: responseData.categoryIDs,
167
+ },
168
+ };
169
+ }
170
+
171
+ function interpretResponse(response, request) {
172
+ // In case of empty response
173
+ if (
174
+ response.body == null ||
175
+ !utils.isArray(response.body) ||
176
+ response.body.length === 0
177
+ ) {
178
+ return [];
179
+ }
180
+ const bids = response.body.map((bid) => createAdResponse(bid));
181
+ return bids;
182
+ }
183
+ // #endregion
184
+
185
+ // #region Bidder
186
+ export const spec = {
187
+ code: BIDDER_CODE,
188
+ supportedMediaTypes: [BANNER],
189
+ isBidRequestValid,
190
+ buildRequests,
191
+ interpretResponse,
192
+ onTimeout(timeoutData) {
193
+ utils.logError('Adplus adapter timed out for the auction.', timeoutData);
194
+ },
195
+ onBidWon(bid) {
196
+ utils.logInfo(
197
+ `Adplus adapter won the auction. Bid id: ${bid.bidId}, Ad Unit Id: ${bid.adUnitId}, Inventory Id: ${bid.inventoryId}`
198
+ );
199
+ },
200
+ };
201
+
202
+ registerBidder(spec);
203
+ // #endregion
@@ -0,0 +1,39 @@
1
+ # Overview
2
+
3
+ Module Name: AdPlus Bidder Adapter
4
+
5
+ Module Type: Bidder Adapter
6
+
7
+ Maintainer: adplus.destek@yaani.com.tr
8
+
9
+ # Description
10
+
11
+ AdPlus Prebid.js Bidder Adapter. Only banner formats are supported.
12
+
13
+ About us : https://ssp.ad-plus.com.tr/
14
+
15
+ # Test Parameters
16
+
17
+ ```javascript
18
+ var adUnits = [
19
+ {
20
+ code: "div-adplus",
21
+ mediaTypes: {
22
+ banner: {
23
+ sizes: [
24
+ [300, 250],
25
+ ],
26
+ },
27
+ },
28
+ bids: [
29
+ {
30
+ bidder: "adplus",
31
+ params: {
32
+ inventoryId: "-1",
33
+ adUnitId: "-3",
34
+ },
35
+ },
36
+ ],
37
+ },
38
+ ];
39
+ ```