prebid.js 8.5.0 → 8.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 (203) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/33acrossIdSystem.js +1 -1
  3. package/dist/adagioBidAdapter.js +1 -1
  4. package/dist/adbookpspBidAdapter.js +1 -1
  5. package/dist/adgenerationBidAdapter.js +1 -1
  6. package/dist/adqueryBidAdapter.js +1 -1
  7. package/dist/adrelevantisBidAdapter.js +1 -1
  8. package/dist/adsinteractiveBidAdapter.js +1 -1
  9. package/dist/adtrgtmeBidAdapter.js +1 -1
  10. package/dist/adxcgBidAdapter.js +1 -1
  11. package/dist/adyoulikeBidAdapter.js +1 -1
  12. package/dist/ajaBidAdapter.js +1 -1
  13. package/dist/alkimiBidAdapter.js +1 -1
  14. package/dist/amxBidAdapter.js +1 -1
  15. package/dist/amxIdSystem.js +1 -1
  16. package/dist/appierAnalyticsAdapter.js +1 -1
  17. package/dist/appnexusBidAdapter.js +1 -1
  18. package/dist/asoBidAdapter.js +1 -1
  19. package/dist/automatadAnalyticsAdapter.js +1 -0
  20. package/dist/axonixBidAdapter.js +1 -1
  21. package/dist/bidglassBidAdapter.js +1 -1
  22. package/dist/big-richmediaBidAdapter.js +1 -1
  23. package/dist/bridBidAdapter.js +1 -1
  24. package/dist/bridgewellBidAdapter.js +1 -1
  25. package/dist/brightMountainMediaBidAdapter.js +1 -1
  26. package/dist/carodaBidAdapter.js +1 -1
  27. package/dist/chtnwBidAdapter.js +1 -1
  28. package/dist/concertBidAdapter.js +1 -1
  29. package/dist/connatixBidAdapter.js +1 -0
  30. package/dist/connectadBidAdapter.js +1 -1
  31. package/dist/consumableBidAdapter.js +1 -1
  32. package/dist/conversantAnalyticsAdapter.js +1 -1
  33. package/dist/conversantBidAdapter.js +1 -1
  34. package/dist/craftBidAdapter.js +1 -1
  35. package/dist/criteoBidAdapter.js +1 -1
  36. package/dist/cwireBidAdapter.js +1 -1
  37. package/dist/dependencies.json +6 -0
  38. package/dist/dspxBidAdapter.js +1 -1
  39. package/dist/eplanningBidAdapter.js +1 -1
  40. package/dist/euidIdSystem.js +1 -1
  41. package/dist/feedadBidAdapter.js +1 -1
  42. package/dist/finativeBidAdapter.js +1 -1
  43. package/dist/freepassBidAdapter.js +1 -1
  44. package/dist/freewheel-sspBidAdapter.js +1 -1
  45. package/dist/gmosspBidAdapter.js +1 -1
  46. package/dist/goldbachBidAdapter.js +1 -1
  47. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  48. package/dist/greenbidsRtdProvider.js +1 -1
  49. package/dist/gridBidAdapter.js +1 -1
  50. package/dist/growthCodeAnalyticsAdapter.js +1 -1
  51. package/dist/gumgumBidAdapter.js +1 -1
  52. package/dist/h12mediaBidAdapter.js +1 -1
  53. package/dist/hypelabBidAdapter.js +1 -1
  54. package/dist/id5IdSystem.js +1 -1
  55. package/dist/imdsBidAdapter.js +1 -1
  56. package/dist/improvedigitalBidAdapter.js +1 -1
  57. package/dist/insticatorBidAdapter.js +1 -1
  58. package/dist/ixBidAdapter.js +1 -1
  59. package/dist/justpremiumBidAdapter.js +1 -1
  60. package/dist/kargoBidAdapter.js +1 -1
  61. package/dist/konduitAnalyticsAdapter.js +1 -1
  62. package/dist/kueezBidAdapter.js +1 -1
  63. package/dist/kueezRtbBidAdapter.js +1 -1
  64. package/dist/kulturemediaBidAdapter.js +1 -1
  65. package/dist/lassoBidAdapter.js +1 -1
  66. package/dist/lifestreetBidAdapter.js +1 -1
  67. package/dist/logicadBidAdapter.js +1 -1
  68. package/dist/loglyliftBidAdapter.js +1 -1
  69. package/dist/magniteAnalyticsAdapter.js +1 -1
  70. package/dist/malltvAnalyticsAdapter.js +1 -1
  71. package/dist/marsmediaBidAdapter.js +1 -1
  72. package/dist/mediafuseBidAdapter.js +1 -1
  73. package/dist/medianetBidAdapter.js +1 -1
  74. package/dist/mediasquareBidAdapter.js +1 -1
  75. package/dist/mgidBidAdapter.js +1 -1
  76. package/dist/minutemediaBidAdapter.js +1 -1
  77. package/dist/minutemediaplusBidAdapter.js +1 -1
  78. package/dist/mspa.js +1 -1
  79. package/dist/newspassidBidAdapter.js +1 -1
  80. package/dist/nexx360BidAdapter.js +1 -1
  81. package/dist/not-for-prod/prebid.js +140 -136
  82. package/dist/oguryBidAdapter.js +1 -1
  83. package/dist/onetagBidAdapter.js +1 -1
  84. package/dist/ooloAnalyticsAdapter.js +1 -1
  85. package/dist/optidigitalBidAdapter.js +1 -1
  86. package/dist/outbrainBidAdapter.js +1 -1
  87. package/dist/parrableIdSystem.js +1 -1
  88. package/dist/pixfutureBidAdapter.js +1 -1
  89. package/dist/prebid-core.js +1 -1
  90. package/dist/pubCircleBidAdapter.js +1 -0
  91. package/dist/publinkIdSystem.js +1 -1
  92. package/dist/pubmaticBidAdapter.js +1 -1
  93. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  94. package/dist/pxyzBidAdapter.js +1 -1
  95. package/dist/quantcastBidAdapter.js +1 -1
  96. package/dist/readpeakBidAdapter.js +1 -1
  97. package/dist/relaidoBidAdapter.js +1 -1
  98. package/dist/relevadRtdProvider.js +1 -1
  99. package/dist/retailspotBidAdapter.js +1 -1
  100. package/dist/rhythmoneBidAdapter.js +1 -1
  101. package/dist/riseBidAdapter.js +1 -1
  102. package/dist/rubiconBidAdapter.js +1 -1
  103. package/dist/seedingAllianceBidAdapter.js +1 -1
  104. package/dist/seedtagBidAdapter.js +1 -1
  105. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  106. package/dist/sharethroughBidAdapter.js +1 -1
  107. package/dist/shinezBidAdapter.js +1 -1
  108. package/dist/smaatoBidAdapter.js +1 -1
  109. package/dist/smartadserverBidAdapter.js +1 -1
  110. package/dist/smartxBidAdapter.js +1 -1
  111. package/dist/smilewantedBidAdapter.js +1 -1
  112. package/dist/sonobiBidAdapter.js +1 -1
  113. package/dist/sovrnAnalyticsAdapter.js +1 -1
  114. package/dist/sovrnBidAdapter.js +1 -1
  115. package/dist/ssmasBidAdapter.js +1 -1
  116. package/dist/sspBCBidAdapter.js +1 -1
  117. package/dist/stvBidAdapter.js +1 -1
  118. package/dist/sublimeBidAdapter.js +1 -1
  119. package/dist/tappxBidAdapter.js +1 -1
  120. package/dist/targetVideoBidAdapter.js +1 -1
  121. package/dist/teadsBidAdapter.js +1 -1
  122. package/dist/topicsFpdModule.js +1 -1
  123. package/dist/trionBidAdapter.js +1 -1
  124. package/dist/tripleliftBidAdapter.js +1 -1
  125. package/dist/ttdBidAdapter.js +1 -1
  126. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  127. package/dist/uid2IdSystem.js +1 -1
  128. package/dist/underdogmediaBidAdapter.js +1 -1
  129. package/dist/undertoneBidAdapter.js +1 -1
  130. package/dist/viantOrtbBidAdapter.js +1 -0
  131. package/dist/vidazooBidAdapter.js +1 -1
  132. package/dist/videobyteBidAdapter.js +1 -1
  133. package/dist/videojsVideoProvider.js +1 -1
  134. package/dist/visxBidAdapter.js +1 -1
  135. package/dist/vuukleBidAdapter.js +1 -1
  136. package/dist/widespaceBidAdapter.js +1 -1
  137. package/dist/winrBidAdapter.js +1 -1
  138. package/dist/yahoosspBidAdapter.js +1 -1
  139. package/dist/yieldmoBidAdapter.js +1 -1
  140. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  141. package/integrationExamples/videoModule/jwplayer/bidMarkedAsUsed.html +1 -1
  142. package/integrationExamples/videoModule/jwplayer/bidRequestScheduling.html +1 -1
  143. package/integrationExamples/videoModule/jwplayer/bidsBackHandlerOverride.html +137 -0
  144. package/integrationExamples/videoModule/jwplayer/eventListeners.html +1 -1
  145. package/integrationExamples/videoModule/jwplayer/eventsUI.html +1 -1
  146. package/integrationExamples/videoModule/jwplayer/gamAdServerMediation.html +1 -1
  147. package/integrationExamples/videoModule/jwplayer/mediaMetadata.html +1 -1
  148. package/integrationExamples/videoModule/jwplayer/playlist.html +1 -1
  149. package/integrationExamples/videoModule/videojs/bidsBackHandlerOverride.html +164 -0
  150. package/libraries/mspa/activityControls.js +51 -32
  151. package/modules/adagioBidAdapter.js +15 -1
  152. package/modules/adgenerationBidAdapter.js +5 -4
  153. package/modules/adsinteractiveBidAdapter.js +4 -2
  154. package/modules/alkimiBidAdapter.js +19 -7
  155. package/modules/appnexusBidAdapter.js +1 -1
  156. package/modules/automatadAnalyticsAdapter.js +325 -0
  157. package/modules/automatadAnalyticsAdapter.md +23 -0
  158. package/modules/connatixBidAdapter.js +185 -0
  159. package/modules/connatixBidAdapter.md +37 -0
  160. package/modules/criteoBidAdapter.js +18 -0
  161. package/modules/cwireBidAdapter.js +19 -0
  162. package/modules/freepassBidAdapter.js +20 -1
  163. package/modules/freepassBidAdapter.md +4 -1
  164. package/modules/gridBidAdapter.js +1 -8
  165. package/modules/growthCodeAnalyticsAdapter.js +7 -2
  166. package/modules/medianetBidAdapter.js +7 -4
  167. package/modules/mediasquareBidAdapter.js +3 -0
  168. package/modules/newspassid.md +76 -0
  169. package/modules/newspassidBidAdapter.js +44 -18
  170. package/modules/optidigitalBidAdapter.js +25 -16
  171. package/modules/pubCircleBidAdapter.js +231 -0
  172. package/modules/pubCircleBidAdapter.md +79 -0
  173. package/modules/relevadRtdProvider.js +6 -7
  174. package/modules/ssmasBidAdapter.js +2 -2
  175. package/modules/tappxBidAdapter.js +27 -15
  176. package/modules/tappxBidAdapter.md +17 -0
  177. package/modules/topicsFpdModule.js +21 -48
  178. package/modules/undertoneBidAdapter.md +1 -1
  179. package/modules/userId/eids.md +7 -0
  180. package/modules/viantOrtbBidAdapter.js +113 -0
  181. package/modules/viantOrtbBidAdapter.md +54 -0
  182. package/modules/vidazooBidAdapter.js +9 -2
  183. package/modules/videojsVideoProvider.js +9 -2
  184. package/package.json +1 -1
  185. package/test/spec/libraries/mspa/activityControls_spec.js +145 -212
  186. package/test/spec/modules/adagioBidAdapter_spec.js +89 -0
  187. package/test/spec/modules/adgenerationBidAdapter_spec.js +6 -6
  188. package/test/spec/modules/alkimiBidAdapter_spec.js +3 -9
  189. package/test/spec/modules/appnexusBidAdapter_spec.js +12 -1
  190. package/test/spec/modules/automatadAnalyticsAdapter_spec.js +533 -0
  191. package/test/spec/modules/connatixBidAdapter_spec.js +366 -0
  192. package/test/spec/modules/criteoBidAdapter_spec.js +52 -3
  193. package/test/spec/modules/cwireBidAdapter_spec.js +47 -0
  194. package/test/spec/modules/freepassBidAdapter_spec.js +44 -0
  195. package/test/spec/modules/gridBidAdapter_spec.js +68 -0
  196. package/test/spec/modules/medianetBidAdapter_spec.js +18 -18
  197. package/test/spec/modules/mediasquareBidAdapter_spec.js +5 -0
  198. package/test/spec/modules/newspassidBidAdapter_spec.js +6 -0
  199. package/test/spec/modules/optidigitalBidAdapter_spec.js +9 -2
  200. package/test/spec/modules/pubCircleBidAdapter_spec.js +399 -0
  201. package/test/spec/modules/tappxBidAdapter_spec.js +19 -0
  202. package/test/spec/modules/topicsFpdModule_spec.js +343 -365
  203. package/test/spec/modules/viantOrtbBidAdapter_spec.js +432 -0
@@ -8,7 +8,13 @@ import {
8
8
  import {gppDataHandler} from '../../src/adapterManager.js';
9
9
 
10
10
  // default interpretation for MSPA consent(s):
11
- // https://docs.google.com/document/d/1yPEVx3bBdSkIw-QNkQR5qi1ztmn9zoXk-LaGQB6iw7Q
11
+ // https://docs.prebid.org/features/mspa-usnat.html
12
+
13
+ const SENSITIVE_DATA_GEO = 7;
14
+
15
+ function isApplicable(val) {
16
+ return val != null && val !== 0
17
+ }
12
18
 
13
19
  export function isBasicConsentDenied(cd) {
14
20
  // service provider mode is always consent denied
@@ -18,47 +24,60 @@ export function isBasicConsentDenied(cd) {
18
24
  // minors 13+ who have not given consent
19
25
  cd.KnownChildSensitiveDataConsents[0] === 1 ||
20
26
  // minors under 13 cannot consent
21
- cd.KnownChildSensitiveDataConsents[1] !== 0 ||
22
- // sensitive category consent impossible without notice
23
- (cd.SensitiveDataProcessing.some(element => element === 2) && (cd.SensitiveDataLimitUseNotice !== 1 || cd.SensitiveDataProcessingOptOutNotice !== 1));
27
+ isApplicable(cd.KnownChildSensitiveDataConsents[1]);
24
28
  }
25
29
 
26
- export function isSensitiveNoticeMissing(cd) {
27
- return ['SensitiveDataProcessingOptOutNotice', 'SensitiveDataLimitUseNotice'].some(prop => cd[prop] === 2)
30
+ export function sensitiveNoticeIs(cd, value) {
31
+ return ['SensitiveDataProcessingOptOutNotice', 'SensitiveDataLimitUseNotice'].some(prop => cd[prop] === value)
28
32
  }
29
33
 
30
34
  export function isConsentDenied(cd) {
31
35
  return isBasicConsentDenied(cd) ||
32
- // user opts out
33
- (['SaleOptOut', 'SharingOptOut', 'TargetedAdvertisingOptOut'].some(prop => cd[prop] === 1)) ||
34
- // notice not given
35
- (['SaleOptOutNotice', 'SharingNotice', 'SharingOptOutNotice', 'TargetedAdvertisingOptOutNotice'].some(prop => cd[prop] === 2)) ||
36
- // sale opted in but notice does not apply
37
- ((cd.SaleOptOut === 2 && cd.SaleOptOutNotice === 0)) ||
38
- // targeted opted in but notice does not apply
39
- ((cd.TargetedAdvertisingOptOut === 2 && cd.TargetedAdvertisingOptOutNotice === 0)) ||
40
- // sharing opted in but notices do not apply
41
- ((cd.SharingOptOut === 2 && (cd.SharingNotice === 0 || cd.SharingOptOutNotice === 0)));
36
+ ['Sale', 'Sharing', 'TargetedAdvertising'].some(scope => {
37
+ const oo = cd[`${scope}OptOut`];
38
+ const notice = cd[`${scope}OptOutNotice`];
39
+ // user opted out
40
+ return oo === 1 ||
41
+ // opt-out notice was not given
42
+ notice === 2 ||
43
+ // do not trust CMP if it signals opt-in but no opt-out notice was given
44
+ (oo === 2 && notice === 0);
45
+ }) ||
46
+ // no sharing notice was given ...
47
+ cd.SharingNotice === 2 ||
48
+ // ... or the CMP says it was not applicable, while also claiming it got consent
49
+ (cd.SharingOptOut === 2 && cd.SharingNotice === 0);
42
50
  }
43
51
 
44
- export function isTransmitUfpdConsentDenied(cd) {
45
- // SensitiveDataProcessing[1-5,11]=1 OR SensitiveDataProcessing[6,7,9,10,12]<>0 OR
46
- const mustBeZero = [6, 7, 9, 10, 12];
47
- const mustBeZeroSubtractedVector = mustBeZero.map((number) => number - 1);
48
- const SensitiveDataProcessingMustBeZero = cd.SensitiveDataProcessing.filter(index => mustBeZeroSubtractedVector.includes(index));
49
- const cannotBeOne = [1, 2, 3, 4, 5, 11];
50
- const cannotBeOneSubtractedVector = cannotBeOne.map((number) => number - 1);
51
- const SensitiveDataProcessingCannotBeOne = cd.SensitiveDataProcessing.filter(index => cannotBeOneSubtractedVector.includes(index));
52
- return isConsentDenied(cd) ||
53
- isSensitiveNoticeMissing(cd) ||
54
- SensitiveDataProcessingCannotBeOne.some(val => val === 1) ||
55
- SensitiveDataProcessingMustBeZero.some(val => val !== 0);
56
- }
52
+ export const isTransmitUfpdConsentDenied = (() => {
53
+ // deny anything that smells like: genetic, biometric, state/national ID, financial, union membership,
54
+ // or personal communication data
55
+ const cannotBeInScope = [6, 7, 9, 10, 12].map(el => --el);
56
+ // require consent for everything else (except geo, which is treated separately)
57
+ const allExceptGeo = Array.from(Array(12).keys()).filter((el) => el !== SENSITIVE_DATA_GEO)
58
+ const mustHaveConsent = allExceptGeo.filter(el => !cannotBeInScope.includes(el));
59
+
60
+ return function (cd) {
61
+ return isConsentDenied(cd) ||
62
+ // no notice about sensitive data was given
63
+ sensitiveNoticeIs(cd, 2) ||
64
+ // extra-sensitive data is applicable
65
+ cannotBeInScope.some(i => isApplicable(cd.SensitiveDataProcessing[i])) ||
66
+ // user opted out for not-as-sensitive data
67
+ mustHaveConsent.some(i => cd.SensitiveDataProcessing[i] === 1) ||
68
+ // CMP says it has consent, but did not give notice about it
69
+ (sensitiveNoticeIs(cd, 0) && allExceptGeo.some(i => cd.SensitiveDataProcessing[i] === 2))
70
+ }
71
+ })();
57
72
 
58
73
  export function isTransmitGeoConsentDenied(cd) {
59
- return isBasicConsentDenied(cd) ||
60
- isSensitiveNoticeMissing(cd) ||
61
- cd.SensitiveDataProcessing[7] === 1
74
+ const geoConsent = cd.SensitiveDataProcessing[SENSITIVE_DATA_GEO];
75
+ return geoConsent === 1 ||
76
+ isBasicConsentDenied(cd) ||
77
+ // no sensitive data notice was given
78
+ sensitiveNoticeIs(cd, 2) ||
79
+ // do not trust CMP if it says it has consent for geo but didn't show a sensitive data notice
80
+ (sensitiveNoticeIs(cd, 0) && geoConsent === 2)
62
81
  }
63
82
 
64
83
  const CONSENT_RULES = {
@@ -399,6 +399,17 @@ function _getUspConsent(bidderRequest) {
399
399
  return (deepAccess(bidderRequest, 'uspConsent')) ? { uspConsent: bidderRequest.uspConsent } : false;
400
400
  }
401
401
 
402
+ function _getGppConsent(bidderRequest) {
403
+ let gpp = deepAccess(bidderRequest, 'gppConsent.gppString')
404
+ let gppSid = deepAccess(bidderRequest, 'gppConsent.applicableSections')
405
+
406
+ if (!gpp || !gppSid) {
407
+ gpp = deepAccess(bidderRequest, 'ortb2.regs.gpp', '')
408
+ gppSid = deepAccess(bidderRequest, 'ortb2.regs.gpp_sid', [])
409
+ }
410
+ return { gpp, gppSid }
411
+ }
412
+
402
413
  function _getSchain(bidRequest) {
403
414
  return deepAccess(bidRequest, 'schain');
404
415
  }
@@ -976,6 +987,7 @@ export const spec = {
976
987
  const gdprConsent = _getGdprConsent(bidderRequest) || {};
977
988
  const uspConsent = _getUspConsent(bidderRequest) || {};
978
989
  const coppa = _getCoppa();
990
+ const gppConsent = _getGppConsent(bidderRequest)
979
991
  const schain = _getSchain(validBidRequests[0]);
980
992
  const eids = _getEids(validBidRequests[0]) || [];
981
993
  const syncEnabled = deepAccess(config.getConfig('userSync'), 'syncEnabled')
@@ -1143,7 +1155,9 @@ export const spec = {
1143
1155
  regs: {
1144
1156
  gdpr: gdprConsent,
1145
1157
  coppa: coppa,
1146
- ccpa: uspConsent
1158
+ ccpa: uspConsent,
1159
+ gpp: gppConsent.gpp,
1160
+ gppSid: gppConsent.gppSid
1147
1161
  },
1148
1162
  schain: schain,
1149
1163
  user: {
@@ -28,7 +28,7 @@ export const spec = {
28
28
  buildRequests: function (validBidRequests, bidderRequest) {
29
29
  // convert Native ORTB definition to old-style prebid native definition
30
30
  validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests);
31
- const ADGENE_PREBID_VERSION = '1.6.0';
31
+ const ADGENE_PREBID_VERSION = '1.6.2';
32
32
  let serverRequests = [];
33
33
  for (let i = 0, len = validBidRequests.length; i < len; i++) {
34
34
  const validReq = validBidRequests[i];
@@ -41,6 +41,7 @@ export const spec = {
41
41
  const imuid = deepAccess(validReq, 'userId.imuid');
42
42
  const gpid = deepAccess(validReq, 'ortb2Imp.ext.gpid');
43
43
  const sua = deepAccess(validReq, 'ortb2.device.sua');
44
+ const uid2 = deepAccess(validReq, 'userId.uid2.id');
44
45
  let data = ``;
45
46
  data = tryAppendQueryString(data, 'posall', 'SSPLOC');
46
47
  const id = getBidIdParameter('id', validReq.params);
@@ -58,10 +59,10 @@ export const spec = {
58
59
  data = tryAppendQueryString(data, 'adgext_id5_id', id5id);
59
60
  data = tryAppendQueryString(data, 'adgext_id5_id_link_type', id5LinkType);
60
61
  data = tryAppendQueryString(data, 'adgext_imuid', imuid);
61
- data = tryAppendQueryString(data, 'adgext_uid2', validReq.userId ? validReq.userId.uid2 : null);
62
- data = tryAppendQueryString(data, 'gpid', gpid ? encodeURIComponent(gpid) : null);
62
+ data = tryAppendQueryString(data, 'adgext_uid2', uid2);
63
+ data = tryAppendQueryString(data, 'gpid', gpid);
63
64
  data = tryAppendQueryString(data, 'uach', sua ? JSON.stringify(sua) : null);
64
- data = tryAppendQueryString(data, 'schain', validReq.schain ? encodeURIComponent(JSON.stringify(validReq.schain)) : null);
65
+ data = tryAppendQueryString(data, 'schain', validReq.schain ? JSON.stringify(validReq.schain) : null);
65
66
 
66
67
  // native以外にvideo等の対応が入った場合は要修正
67
68
  if (!validReq.mediaTypes || !validReq.mediaTypes.native) {
@@ -6,12 +6,14 @@ import { registerBidder } from '../src/adapters/bidderFactory.js';
6
6
  import { BANNER } from '../src/mediaTypes.js';
7
7
 
8
8
  const ADSINTERACTIVE_CODE = 'adsinteractive';
9
- const USER_SYNC_URL_IMAGE = 'https://pb.adsinteractive.com/img';
10
- const USER_SYNC_URL_IFRAME = 'https://pb.adsinteractive.com/sync';
9
+ const USER_SYNC_URL_IMAGE = 'https://sync.adsinteractive.com/img';
10
+ const USER_SYNC_URL_IFRAME = 'https://sync.adsinteractive.com/sync';
11
+ const GVLID = 1212;
11
12
 
12
13
  export const spec = {
13
14
  code: ADSINTERACTIVE_CODE,
14
15
  supportedMediaTypes: [BANNER],
16
+ gvlid: GVLID,
15
17
 
16
18
  isBidRequestValid: (bid) => {
17
19
  return (
@@ -1,5 +1,5 @@
1
1
  import {registerBidder} from '../src/adapters/bidderFactory.js';
2
- import {deepAccess, deepClone} from '../src/utils.js';
2
+ import {deepAccess, deepClone, getDNT, generateUUID} from '../src/utils.js';
3
3
  import {ajax} from '../src/ajax.js';
4
4
  import {VIDEO} from '../src/mediaTypes.js';
5
5
  import {config} from '../src/config.js';
@@ -12,7 +12,7 @@ export const spec = {
12
12
  supportedMediaTypes: ['banner', 'video'],
13
13
 
14
14
  isBidRequestValid: function (bid) {
15
- return !!(bid.params && bid.params.bidFloor && bid.params.token);
15
+ return !!(bid.params && bid.params.token);
16
16
  },
17
17
 
18
18
  buildRequests: function (validBidRequests, bidderRequest) {
@@ -28,12 +28,15 @@ export const spec = {
28
28
 
29
29
  bids.push({
30
30
  token: bidRequest.params.token,
31
- pos: bidRequest.params.pos,
31
+ instl: bidRequest.params.instl,
32
+ exp: bidRequest.params.exp,
32
33
  bidFloor: getBidFloor(bidRequest, formatTypes),
33
34
  sizes: prepareSizes(deepAccess(bidRequest, 'mediaTypes.banner.sizes')),
34
35
  playerSizes: prepareSizes(deepAccess(bidRequest, 'mediaTypes.video.playerSize')),
35
36
  impMediaTypes: formatTypes,
36
- adUnitCode: bidRequest.adUnitCode
37
+ adUnitCode: bidRequest.adUnitCode,
38
+ video: deepAccess(bidRequest, 'mediaTypes.video'),
39
+ banner: deepAccess(bidRequest, 'mediaTypes.banner')
37
40
  })
38
41
  bidIds.push(bidRequest.bidId)
39
42
  })
@@ -41,14 +44,23 @@ export const spec = {
41
44
  const alkimiConfig = config.getConfig('alkimi');
42
45
 
43
46
  let payload = {
44
- // TODO: fix auctionId leak: https://github.com/prebid/Prebid.js/issues/9781
45
- requestId: bidderRequest.auctionId,
47
+ requestId: generateUUID(),
46
48
  signRequest: {bids, randomUUID: alkimiConfig && alkimiConfig.randomUUID},
47
49
  bidIds,
48
50
  referer: bidderRequest.refererInfo.page,
49
51
  signature: alkimiConfig && alkimiConfig.signature,
50
52
  schain: validBidRequests[0].schain,
51
- cpp: config.getConfig('coppa') ? 1 : 0
53
+ cpp: config.getConfig('coppa') ? 1 : 0,
54
+ device: {
55
+ dnt: getDNT() ? 1 : 0,
56
+ w: screen.width,
57
+ h: screen.height
58
+ },
59
+ ortb2: {
60
+ at: bidderRequest.ortb2?.at,
61
+ bcat: bidderRequest.ortb2?.bcat,
62
+ wseat: bidderRequest.ortb2?.wseat
63
+ }
52
64
  }
53
65
 
54
66
  if (bidderRequest && bidderRequest.gdprConsent) {
@@ -788,7 +788,7 @@ function bidToTag(bid) {
788
788
  tag.keywords = auKeywords;
789
789
  }
790
790
 
791
- let gpid = deepAccess(bid, 'ortb2Imp.ext.data.pbadslot');
791
+ let gpid = deepAccess(bid, 'ortb2Imp.ext.gpid') || deepAccess(bid, 'ortb2Imp.ext.data.pbadslot');
792
792
  if (gpid) {
793
793
  tag.gpid = gpid;
794
794
  }
@@ -0,0 +1,325 @@
1
+ import {
2
+ logError,
3
+ logInfo,
4
+ logMessage
5
+ } from '../src/utils.js';
6
+
7
+ import CONSTANTS from '../src/constants.json';
8
+ import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
9
+ import adapterManager from '../src/adapterManager.js';
10
+ import { config } from '../src/config.js'
11
+
12
+ /** Prebid Event Handlers */
13
+
14
+ const ADAPTER_CODE = 'automatadAnalytics'
15
+ const trialCountMilsMapping = [1500, 3000, 5000, 10000];
16
+
17
+ var isLoggingEnabled; var queuePointer = 0; var retryCount = 0; var timer = null; var __atmtdAnalyticsQueue = [];
18
+
19
+ const prettyLog = (level, text, isGroup = false, cb = () => {}) => {
20
+ if (self.isLoggingEnabled === undefined) {
21
+ if (window.localStorage.getItem('__aggLoggingEnabled')) {
22
+ self.isLoggingEnabled = true
23
+ } else {
24
+ const queryParams = new URLSearchParams(new URL(window.location.href).search)
25
+ self.isLoggingEnabled = queryParams.has('aggLoggingEnabled')
26
+ }
27
+ }
28
+
29
+ if (self.isLoggingEnabled) {
30
+ if (isGroup) {
31
+ logInfo(`ATD Analytics Adapter: ${level.toUpperCase()}: ${text} --- Group Start ---`)
32
+ try {
33
+ cb();
34
+ } catch (error) {
35
+ logError(`ATD Analytics Adapter: ERROR: ${'Error during cb function in prettyLog'}`)
36
+ }
37
+ logInfo(`ATD Analytics Adapter: ${level.toUpperCase()}: ${text} --- Group End ---`)
38
+ } else {
39
+ logInfo(`ATD Analytics Adapter: ${level.toUpperCase()}: ${text}`)
40
+ }
41
+ }
42
+ }
43
+
44
+ const processEvents = () => {
45
+ if (self.retryCount === trialCountMilsMapping.length) {
46
+ self.prettyLog('error', `Aggregator still hasn't loaded. Processing que stopped`, trialCountMilsMapping, self.retryCount)
47
+ return;
48
+ }
49
+
50
+ self.prettyLog('status', `Que has been inactive for a while. Adapter starting to process que now... Trial Count = ${self.retryCount + 1}`)
51
+
52
+ let shouldTryAgain = false
53
+
54
+ while (self.queuePointer < self.__atmtdAnalyticsQueue.length) {
55
+ const eventType = self.__atmtdAnalyticsQueue[self.queuePointer][0]
56
+ const args = self.__atmtdAnalyticsQueue[self.queuePointer][1]
57
+
58
+ try {
59
+ switch (eventType) {
60
+ case CONSTANTS.EVENTS.AUCTION_INIT:
61
+ if (window.atmtdAnalytics && window.atmtdAnalytics.auctionInitHandler) {
62
+ window.atmtdAnalytics.auctionInitHandler(args);
63
+ } else {
64
+ shouldTryAgain = true
65
+ }
66
+ break;
67
+ case CONSTANTS.EVENTS.BID_REQUESTED:
68
+ if (window.atmtdAnalytics && window.atmtdAnalytics.bidRequestedHandler) {
69
+ window.atmtdAnalytics.bidRequestedHandler(args);
70
+ }
71
+ break;
72
+ case CONSTANTS.EVENTS.BID_RESPONSE:
73
+ if (window.atmtdAnalytics && window.atmtdAnalytics.bidResponseHandler) {
74
+ window.atmtdAnalytics.bidResponseHandler(args);
75
+ }
76
+ break;
77
+ case CONSTANTS.EVENTS.BID_REJECTED:
78
+ if (window.atmtdAnalytics && window.atmtdAnalytics.bidRejectedHandler) {
79
+ window.atmtdAnalytics.bidRejectedHandler(args);
80
+ }
81
+ break;
82
+ case CONSTANTS.EVENTS.BIDDER_DONE:
83
+ if (window.atmtdAnalytics && window.atmtdAnalytics.bidderDoneHandler) {
84
+ window.atmtdAnalytics.bidderDoneHandler(args);
85
+ }
86
+ break;
87
+ case CONSTANTS.EVENTS.BID_WON:
88
+ if (window.atmtdAnalytics && window.atmtdAnalytics.bidWonHandler) {
89
+ window.atmtdAnalytics.bidWonHandler(args);
90
+ }
91
+ break;
92
+ case CONSTANTS.EVENTS.NO_BID:
93
+ if (window.atmtdAnalytics && window.atmtdAnalytics.noBidHandler) {
94
+ window.atmtdAnalytics.noBidHandler(args);
95
+ }
96
+ break;
97
+ case CONSTANTS.EVENTS.BID_TIMEOUT:
98
+ if (window.atmtdAnalytics && window.atmtdAnalytics.bidderTimeoutHandler) {
99
+ window.atmtdAnalytics.bidderTimeoutHandler(args);
100
+ }
101
+ break;
102
+ case CONSTANTS.EVENTS.AUCTION_DEBUG:
103
+ if (window.atmtdAnalytics && window.atmtdAnalytics.auctionDebugHandler) {
104
+ window.atmtdAnalytics.auctionDebugHandler(args);
105
+ }
106
+ break;
107
+ case 'slotRenderEnded':
108
+ if (window.atmtdAnalytics && window.atmtdAnalytics.slotRenderEndedGPTHandler) {
109
+ window.atmtdAnalytics.slotRenderEndedGPTHandler(args);
110
+ } else {
111
+ shouldTryAgain = true
112
+ }
113
+ break;
114
+ case 'impressionViewable':
115
+ if (window.atmtdAnalytics && window.atmtdAnalytics.impressionViewableHandler) {
116
+ window.atmtdAnalytics.impressionViewableHandler(args);
117
+ } else {
118
+ shouldTryAgain = true
119
+ }
120
+ break;
121
+ }
122
+
123
+ if (shouldTryAgain) break;
124
+ } catch (error) {
125
+ self.prettyLog('error', `Unhandled Error while processing ${eventType} of ${self.queuePointer}th index in the que. Will not be retrying this raw event ...`, true, () => {
126
+ logError(`The error is `, error)
127
+ })
128
+ }
129
+
130
+ self.queuePointer = self.queuePointer + 1
131
+ }
132
+
133
+ if (shouldTryAgain) {
134
+ if (trialCountMilsMapping[self.retryCount]) self.prettyLog('warn', `Adapter failed to process event as aggregator has not loaded. Retrying in ${trialCountMilsMapping[self.retryCount]}ms ...`);
135
+ setTimeout(self.processEvents, trialCountMilsMapping[self.retryCount])
136
+ self.retryCount = self.retryCount + 1
137
+ }
138
+ }
139
+
140
+ const addGPTHandlers = () => {
141
+ const googletag = window.googletag || {}
142
+ googletag.cmd = googletag.cmd || []
143
+ googletag.cmd.push(() => {
144
+ googletag.pubads().addEventListener('slotRenderEnded', (event) => {
145
+ if (window.atmtdAnalytics && window.atmtdAnalytics.slotRenderEndedGPTHandler) {
146
+ if (window.__atmtdAggregatorFirstAuctionInitialized === true) {
147
+ window.atmtdAnalytics.slotRenderEndedGPTHandler(event)
148
+ return;
149
+ }
150
+ }
151
+ self.__atmtdAnalyticsQueue.push(['slotRenderEnded', event])
152
+ self.prettyLog(`warn`, `Aggregator not initialised at auctionInit, exiting slotRenderEnded handler and pushing to que instead`)
153
+ })
154
+
155
+ googletag.pubads().addEventListener('impressionViewable', (event) => {
156
+ if (window.atmtdAnalytics && window.atmtdAnalytics.impressionViewableHandler) {
157
+ if (window.__atmtdAggregatorFirstAuctionInitialized === true) {
158
+ window.atmtdAnalytics.impressionViewableHandler(event)
159
+ return;
160
+ }
161
+ }
162
+ self.__atmtdAnalyticsQueue.push(['impressionViewable', event])
163
+ self.prettyLog(`warn`, `Aggregator not initialised at auctionInit, exiting impressionViewable handler and pushing to que instead`)
164
+ })
165
+ })
166
+ }
167
+
168
+ const initializeQueue = () => {
169
+ self.__atmtdAnalyticsQueue.push = (args) => {
170
+ Array.prototype.push.apply(self.__atmtdAnalyticsQueue, [args]);
171
+ if (timer) {
172
+ clearTimeout(timer);
173
+ timer = null;
174
+ }
175
+
176
+ if (args[0] === CONSTANTS.EVENTS.AUCTION_INIT) {
177
+ const timeout = parseInt(config.getConfig('bidderTimeout')) + 1500
178
+ timer = setTimeout(() => {
179
+ self.processEvents()
180
+ }, timeout);
181
+ } else {
182
+ timer = setTimeout(() => {
183
+ self.processEvents()
184
+ }, 1500);
185
+ }
186
+ };
187
+ }
188
+
189
+ // ANALYTICS ADAPTER
190
+
191
+ let baseAdapter = adapter({analyticsType: 'bundle'});
192
+ let atmtdAdapter = Object.assign({}, baseAdapter, {
193
+
194
+ disableAnalytics() {
195
+ baseAdapter.disableAnalytics.apply(this, arguments);
196
+ },
197
+
198
+ track({eventType, args}) {
199
+ switch (eventType) {
200
+ case CONSTANTS.EVENTS.AUCTION_INIT:
201
+ if (window.atmtdAnalytics && window.atmtdAnalytics.auctionInitHandler) {
202
+ self.prettyLog('status', 'Aggregator loaded, initialising auction through handlers');
203
+ window.atmtdAnalytics.auctionInitHandler(args);
204
+ } else {
205
+ self.prettyLog('warn', 'Aggregator not loaded, initialising auction through que ...');
206
+ self.__atmtdAnalyticsQueue.push([eventType, args])
207
+ }
208
+ break;
209
+ case CONSTANTS.EVENTS.BID_REQUESTED:
210
+ if (window.atmtdAnalytics && window.atmtdAnalytics.bidRequestedHandler) {
211
+ window.atmtdAnalytics.bidRequestedHandler(args);
212
+ } else {
213
+ self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
214
+ self.__atmtdAnalyticsQueue.push([eventType, args])
215
+ }
216
+ break;
217
+ case CONSTANTS.EVENTS.BID_REJECTED:
218
+ if (window.atmtdAnalytics && window.atmtdAnalytics.bidRejectedHandler) {
219
+ window.atmtdAnalytics.bidRejectedHandler(args);
220
+ } else {
221
+ self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
222
+ self.__atmtdAnalyticsQueue.push([eventType, args])
223
+ }
224
+ break;
225
+ case CONSTANTS.EVENTS.BID_RESPONSE:
226
+ if (window.atmtdAnalytics && window.atmtdAnalytics.bidResponseHandler) {
227
+ window.atmtdAnalytics.bidResponseHandler(args);
228
+ } else {
229
+ self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
230
+ self.__atmtdAnalyticsQueue.push([eventType, args])
231
+ }
232
+ break;
233
+ case CONSTANTS.EVENTS.BIDDER_DONE:
234
+ if (window.atmtdAnalytics && window.atmtdAnalytics.bidderDoneHandler) {
235
+ window.atmtdAnalytics.bidderDoneHandler(args);
236
+ } else {
237
+ self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
238
+ self.__atmtdAnalyticsQueue.push([eventType, args])
239
+ }
240
+ break;
241
+ case CONSTANTS.EVENTS.BID_WON:
242
+ if (window.atmtdAnalytics && window.atmtdAnalytics.bidWonHandler) {
243
+ window.atmtdAnalytics.bidWonHandler(args);
244
+ } else {
245
+ self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
246
+ self.__atmtdAnalyticsQueue.push([eventType, args])
247
+ }
248
+ break;
249
+ case CONSTANTS.EVENTS.NO_BID:
250
+ if (window.atmtdAnalytics && window.atmtdAnalytics.noBidHandler) {
251
+ window.atmtdAnalytics.noBidHandler(args);
252
+ } else {
253
+ self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
254
+ self.__atmtdAnalyticsQueue.push([eventType, args])
255
+ }
256
+ break;
257
+ case CONSTANTS.EVENTS.AUCTION_DEBUG:
258
+ if (window.atmtdAnalytics && window.atmtdAnalytics.auctionDebugHandler) {
259
+ window.atmtdAnalytics.auctionDebugHandler(args);
260
+ } else {
261
+ self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
262
+ self.__atmtdAnalyticsQueue.push([eventType, args])
263
+ }
264
+ break;
265
+ case CONSTANTS.EVENTS.BID_TIMEOUT:
266
+ if (window.atmtdAnalytics && window.atmtdAnalytics.bidderTimeoutHandler) {
267
+ window.atmtdAnalytics.bidderTimeoutHandler(args);
268
+ } else {
269
+ self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
270
+ self.__atmtdAnalyticsQueue.push([eventType, args])
271
+ }
272
+ break;
273
+ }
274
+ }
275
+ });
276
+
277
+ atmtdAdapter.originEnableAnalytics = atmtdAdapter.enableAnalytics
278
+
279
+ atmtdAdapter.enableAnalytics = function (configuration) {
280
+ if ((configuration === undefined && typeof configuration !== 'object') || configuration.options === undefined) {
281
+ logError('A valid configuration must be passed to the Atmtd Analytics Adapter.');
282
+ return;
283
+ }
284
+
285
+ const conf = configuration.options
286
+
287
+ if (conf === undefined || typeof conf !== 'object' || conf.siteID === undefined || conf.publisherID === undefined) {
288
+ logError('A valid publisher ID and siteID must be passed to the Atmtd Analytics Adapter.');
289
+ return;
290
+ }
291
+
292
+ self.initializeQueue()
293
+ self.addGPTHandlers()
294
+
295
+ window.__atmtdSDKConfig = {
296
+ publisherID: conf.publisherID,
297
+ siteID: conf.siteID,
298
+ collectDebugMessages: conf.logDebug ? conf.logDebug : false
299
+ }
300
+
301
+ logMessage(`Automatad Analytics Adapter enabled with sdk config`, window.__atmtdSDKConfig)
302
+
303
+ // eslint-disable-next-line
304
+ atmtdAdapter.originEnableAnalytics(configuration)
305
+ };
306
+
307
+ /// /////////// ADAPTER REGISTRATION //////////////
308
+
309
+ adapterManager.registerAnalyticsAdapter({
310
+ adapter: atmtdAdapter,
311
+ code: ADAPTER_CODE
312
+ });
313
+
314
+ export var self = {
315
+ __atmtdAnalyticsQueue,
316
+ processEvents,
317
+ initializeQueue,
318
+ addGPTHandlers,
319
+ prettyLog,
320
+ queuePointer,
321
+ retryCount,
322
+ isLoggingEnabled
323
+ }
324
+
325
+ export default atmtdAdapter;
@@ -0,0 +1,23 @@
1
+
2
+ # Overview
3
+
4
+ Module Name: Automatad Analytics Adapter
5
+ Module Type: Analytics Adapter
6
+ Maintainer: tech@automatad.com
7
+
8
+ # Description
9
+
10
+ Analytics adapter for automatad.com. Contact tech@automatad.com for information.
11
+
12
+ # Test Parameters
13
+
14
+ ```
15
+ {
16
+ provider: 'automatadAnalytics',
17
+ options: {
18
+ publisherID: 'N8vZLx',
19
+ siteID: 'PXfvBq'
20
+ }
21
+ }
22
+
23
+ ```