prebid.js 7.45.0 → 7.47.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 (204) 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/admaticBidAdapter.js +1 -1
  7. package/dist/adnuntiusBidAdapter.js +1 -1
  8. package/dist/adrelevantisBidAdapter.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/amxBidAdapter.js +1 -1
  14. package/dist/amxIdSystem.js +1 -1
  15. package/dist/appierAnalyticsAdapter.js +1 -1
  16. package/dist/appnexusBidAdapter.js +1 -1
  17. package/dist/asoBidAdapter.js +1 -1
  18. package/dist/axonixBidAdapter.js +1 -1
  19. package/dist/bidglassBidAdapter.js +1 -1
  20. package/dist/bidwatchAnalyticsAdapter.js +1 -1
  21. package/dist/big-richmediaBidAdapter.js +1 -1
  22. package/dist/bridgewellBidAdapter.js +1 -1
  23. package/dist/brightMountainMediaBidAdapter.js +1 -1
  24. package/dist/carodaBidAdapter.js +1 -1
  25. package/dist/chtnwBidAdapter.js +1 -1
  26. package/dist/concertBidAdapter.js +1 -1
  27. package/dist/connectadBidAdapter.js +1 -1
  28. package/dist/consumableBidAdapter.js +1 -1
  29. package/dist/conversantAnalyticsAdapter.js +1 -1
  30. package/dist/conversantBidAdapter.js +1 -1
  31. package/dist/craftBidAdapter.js +1 -1
  32. package/dist/criteoBidAdapter.js +1 -1
  33. package/dist/criteoIdSystem.js +1 -1
  34. package/dist/cwireBidAdapter.js +1 -1
  35. package/dist/debugging-standalone.js +1 -1
  36. package/dist/dependencies.json +3 -0
  37. package/dist/dspxBidAdapter.js +1 -1
  38. package/dist/emtvBidAdapter.js +1 -0
  39. package/dist/eplanningBidAdapter.js +1 -1
  40. package/dist/eskimiBidAdapter.js +1 -0
  41. package/dist/feedadBidAdapter.js +1 -1
  42. package/dist/finativeBidAdapter.js +1 -1
  43. package/dist/freewheel-sspBidAdapter.js +1 -1
  44. package/dist/glimpseBidAdapter.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/gridBidAdapter.js +1 -1
  49. package/dist/gumgumBidAdapter.js +1 -1
  50. package/dist/h12mediaBidAdapter.js +1 -1
  51. package/dist/id5IdSystem.js +1 -1
  52. package/dist/improvedigitalBidAdapter.js +1 -1
  53. package/dist/inmarBidAdapter.js +1 -1
  54. package/dist/insticatorBidAdapter.js +1 -1
  55. package/dist/ixBidAdapter.js +1 -1
  56. package/dist/justpremiumBidAdapter.js +1 -1
  57. package/dist/kargoBidAdapter.js +1 -1
  58. package/dist/konduitAnalyticsAdapter.js +1 -1
  59. package/dist/kueezBidAdapter.js +1 -1
  60. package/dist/kueezRtbBidAdapter.js +1 -1
  61. package/dist/kulturemediaBidAdapter.js +1 -1
  62. package/dist/lassoBidAdapter.js +1 -1
  63. package/dist/lifestreetBidAdapter.js +1 -1
  64. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  65. package/dist/logicadBidAdapter.js +1 -1
  66. package/dist/loglyliftBidAdapter.js +1 -1
  67. package/dist/magniteAnalyticsAdapter.js +1 -1
  68. package/dist/malltvAnalyticsAdapter.js +1 -1
  69. package/dist/marsmediaBidAdapter.js +1 -1
  70. package/dist/mediafuseBidAdapter.js +1 -1
  71. package/dist/mediasquareBidAdapter.js +1 -1
  72. package/dist/mgidBidAdapter.js +1 -1
  73. package/dist/minutemediaBidAdapter.js +1 -1
  74. package/dist/minutemediaplusBidAdapter.js +1 -1
  75. package/dist/missenaBidAdapter.js +1 -1
  76. package/dist/nativoBidAdapter.js +1 -1
  77. package/dist/neuwoRtdProvider.js +1 -1
  78. package/dist/nextMillenniumBidAdapter.js +1 -1
  79. package/dist/nexx360BidAdapter.js +1 -1
  80. package/dist/not-for-prod/prebid.js +137 -135
  81. package/dist/oguryBidAdapter.js +1 -1
  82. package/dist/onetagBidAdapter.js +1 -1
  83. package/dist/ooloAnalyticsAdapter.js +1 -1
  84. package/dist/optidigitalBidAdapter.js +1 -1
  85. package/dist/ortbConverter.js +1 -1
  86. package/dist/outbrainBidAdapter.js +1 -1
  87. package/dist/pairIdSystem.js +1 -0
  88. package/dist/parrableIdSystem.js +1 -1
  89. package/dist/pixfutureBidAdapter.js +1 -1
  90. package/dist/prebid-core.js +1 -1
  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/rhythmoneBidAdapter.js +1 -1
  99. package/dist/riseBidAdapter.js +1 -1
  100. package/dist/rtbhouseBidAdapter.js +1 -1
  101. package/dist/rubiconAnalyticsAdapter.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/sspBCBidAdapter.js +1 -1
  116. package/dist/stvBidAdapter.js +1 -1
  117. package/dist/sublimeBidAdapter.js +1 -1
  118. package/dist/synacormediaBidAdapter.js +1 -1
  119. package/dist/targetVideoBidAdapter.js +1 -1
  120. package/dist/teadsBidAdapter.js +1 -1
  121. package/dist/trionBidAdapter.js +1 -1
  122. package/dist/tripleliftBidAdapter.js +1 -1
  123. package/dist/ttdBidAdapter.js +1 -1
  124. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  125. package/dist/uid2IdSystem.js +1 -1
  126. package/dist/underdogmediaBidAdapter.js +1 -1
  127. package/dist/undertoneBidAdapter.js +1 -1
  128. package/dist/userId.js +1 -1
  129. package/dist/vidazooBidAdapter.js +1 -1
  130. package/dist/videobyteBidAdapter.js +1 -1
  131. package/dist/vidoomyBidAdapter.js +1 -1
  132. package/dist/visxBidAdapter.js +1 -1
  133. package/dist/vuukleBidAdapter.js +1 -1
  134. package/dist/widespaceBidAdapter.js +1 -1
  135. package/dist/winrBidAdapter.js +1 -1
  136. package/dist/yahoosspBidAdapter.js +1 -1
  137. package/dist/yieldmoBidAdapter.js +1 -1
  138. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  139. package/integrationExamples/gpt/fledge_example.html +103 -0
  140. package/integrationExamples/gpt/prebidServer_fledge_example.html +111 -0
  141. package/libraries/ortbConverter/processors/video.js +1 -0
  142. package/modules/admaticBidAdapter.js +7 -2
  143. package/modules/adnuntiusBidAdapter.js +3 -1
  144. package/modules/appnexusBidAdapter.js +108 -102
  145. package/modules/bidwatchAnalyticsAdapter.js +2 -0
  146. package/modules/conversantBidAdapter.js +3 -0
  147. package/modules/criteoBidAdapter.js +5 -1
  148. package/modules/criteoIdSystem.js +27 -14
  149. package/modules/emtvBidAdapter.js +211 -0
  150. package/modules/emtvBidAdapter.md +79 -0
  151. package/modules/eskimiBidAdapter.js +72 -0
  152. package/modules/eskimiBidAdapter.md +34 -0
  153. package/modules/gridBidAdapter.js +42 -19
  154. package/modules/ixBidAdapter.js +30 -0
  155. package/modules/kargoBidAdapter.js +473 -246
  156. package/modules/kueezRtbBidAdapter.js +16 -4
  157. package/modules/mediasquareBidAdapter.js +2 -1
  158. package/modules/minutemediaplusBidAdapter.js +16 -4
  159. package/modules/missenaBidAdapter.js +1 -1
  160. package/modules/nativoBidAdapter.js +110 -21
  161. package/modules/neuwoRtdProvider.js +0 -2
  162. package/modules/nextMillenniumBidAdapter.js +2 -0
  163. package/modules/pairIdSystem.js +79 -0
  164. package/modules/pubmaticBidAdapter.js +12 -9
  165. package/modules/rtbhouseBidAdapter.js +3 -3
  166. package/modules/userId/eids.js +6 -0
  167. package/modules/vidoomyBidAdapter.js +30 -9
  168. package/modules/vidoomyBidAdapter.md +12 -2
  169. package/modules/yieldmoBidAdapter.js +15 -5
  170. package/package.json +1 -1
  171. package/src/config.js +78 -127
  172. package/test/spec/modules/1plusXRtdProvider_spec.js +8 -7
  173. package/test/spec/modules/adagioBidAdapter_spec.js +0 -25
  174. package/test/spec/modules/admaticBidAdapter_spec.js +1 -1
  175. package/test/spec/modules/adnuntiusBidAdapter_spec.js +2 -1
  176. package/test/spec/modules/appnexusBidAdapter_spec.js +464 -448
  177. package/test/spec/modules/axonixBidAdapter_spec.js +0 -27
  178. package/test/spec/modules/big-richmediaBidAdapter_spec.js +68 -64
  179. package/test/spec/modules/conversantBidAdapter_spec.js +1 -0
  180. package/test/spec/modules/criteoBidAdapter_spec.js +33 -1
  181. package/test/spec/modules/criteoIdSystem_spec.js +99 -9
  182. package/test/spec/modules/emtvBidAdapter_spec.js +400 -0
  183. package/test/spec/modules/eskimiBidAdapter_spec.js +155 -0
  184. package/test/spec/modules/gridBidAdapter_spec.js +8 -0
  185. package/test/spec/modules/ixBidAdapter_spec.js +57 -0
  186. package/test/spec/modules/kargoBidAdapter_spec.js +297 -140
  187. package/test/spec/modules/kueezRtbBidAdapter_spec.js +22 -2
  188. package/test/spec/modules/minutemediaplusBidAdapter_spec.js +22 -2
  189. package/test/spec/modules/nativoBidAdapter_spec.js +101 -0
  190. package/test/spec/modules/neuwoRtdProvider_spec.js +0 -1
  191. package/test/spec/modules/ooloAnalyticsAdapter_spec.js +1 -1
  192. package/test/spec/modules/pairIdSystem_spec.js +68 -0
  193. package/test/spec/modules/pubCommonId_spec.js +0 -17
  194. package/test/spec/modules/pubmaticBidAdapter_spec.js +868 -867
  195. package/test/spec/modules/realvuAnalyticsAdapter_spec.js +0 -5
  196. package/test/spec/modules/rtbhouseBidAdapter_spec.js +2 -2
  197. package/test/spec/modules/vidoomyBidAdapter_spec.js +72 -0
  198. package/test/spec/modules/yieldmoBidAdapter_spec.js +19 -1
  199. package/test/spec/unit/pbjs_api_spec.js +19 -3
  200. package/test/test_index.js +13 -3
  201. package/dist/gridNMBidAdapter.js +0 -1
  202. package/modules/gridNMBidAdapter.js +0 -422
  203. package/modules/gridNMBidAdapter.md +0 -39
  204. package/test/spec/modules/gridNMBidAdapter_spec.js +0 -636
@@ -333,14 +333,16 @@ export const spec = {
333
333
  payload.referrer_detection = refererinfo;
334
334
  }
335
335
 
336
- const hasAdPodBid = find(bidRequests, hasAdPod);
337
- if (hasAdPodBid) {
338
- bidRequests.filter(hasAdPod).forEach(adPodBid => {
339
- const adPodTags = createAdPodRequest(tags, adPodBid);
340
- // don't need the original adpod placement because it's in adPodTags
341
- const nonPodTags = payload.tags.filter(tag => tag.uuid !== adPodBid.bidId);
342
- payload.tags = [...nonPodTags, ...adPodTags];
343
- });
336
+ if (FEATURES.VIDEO) {
337
+ const hasAdPodBid = find(bidRequests, hasAdPod);
338
+ if (hasAdPodBid) {
339
+ bidRequests.filter(hasAdPod).forEach(adPodBid => {
340
+ const adPodTags = createAdPodRequest(tags, adPodBid);
341
+ // don't need the original adpod placement because it's in adPodTags
342
+ const nonPodTags = payload.tags.filter(tag => tag.uuid !== adPodBid.bidId);
343
+ payload.tags = [...nonPodTags, ...adPodTags];
344
+ });
345
+ }
344
346
  }
345
347
 
346
348
  if (bidRequests[0].userId) {
@@ -653,7 +655,7 @@ function newBid(serverBid, rtbBid, bidderRequest) {
653
655
  bid.meta = Object.assign({}, bid.meta, { brandId: rtbBid.brand_id });
654
656
  }
655
657
 
656
- if (rtbBid.rtb.video) {
658
+ if (FEATURES.VIDEO && rtbBid.rtb.video) {
657
659
  // shared video properties used for all 3 contexts
658
660
  Object.assign(bid, {
659
661
  width: rtbBid.rtb.video.player_width,
@@ -865,107 +867,111 @@ function bidToTag(bid) {
865
867
  }
866
868
  }
867
869
 
868
- const videoMediaType = deepAccess(bid, `mediaTypes.${VIDEO}`);
869
- const context = deepAccess(bid, 'mediaTypes.video.context');
870
-
871
- if (videoMediaType && context === 'adpod') {
872
- tag.hb_source = 7;
873
- } else {
874
- tag.hb_source = 1;
875
- }
876
- if (bid.mediaType === VIDEO || videoMediaType) {
877
- tag.ad_types.push(VIDEO);
878
- }
879
-
880
- // instream gets vastUrl, outstream gets vastXml
881
- if (bid.mediaType === VIDEO || (videoMediaType && context !== 'outstream')) {
882
- tag.require_asset_url = true;
883
- }
870
+ if (FEATURES.VIDEO) {
871
+ const videoMediaType = deepAccess(bid, `mediaTypes.${VIDEO}`);
872
+ const context = deepAccess(bid, 'mediaTypes.video.context');
884
873
 
885
- if (bid.params.video) {
886
- tag.video = {};
887
- // place any valid video params on the tag
888
- Object.keys(bid.params.video)
889
- .filter(param => includes(VIDEO_TARGETING, param))
890
- .forEach(param => {
891
- switch (param) {
892
- case 'context':
893
- case 'playback_method':
894
- let type = bid.params.video[param];
895
- type = (isArray(type)) ? type[0] : type;
896
- tag.video[param] = VIDEO_MAPPING[param][type];
897
- break;
898
- // Deprecating tags[].video.frameworks in favor of tags[].video_frameworks
899
- case 'frameworks':
900
- break;
901
- default:
902
- tag.video[param] = bid.params.video[param];
903
- }
904
- });
874
+ if (videoMediaType && context === 'adpod') {
875
+ tag.hb_source = 7;
876
+ } else {
877
+ tag.hb_source = 1;
878
+ }
879
+ if (bid.mediaType === VIDEO || videoMediaType) {
880
+ tag.ad_types.push(VIDEO);
881
+ }
905
882
 
906
- if (bid.params.video.frameworks && isArray(bid.params.video.frameworks)) {
907
- tag['video_frameworks'] = bid.params.video.frameworks;
883
+ // instream gets vastUrl, outstream gets vastXml
884
+ if (bid.mediaType === VIDEO || (videoMediaType && context !== 'outstream')) {
885
+ tag.require_asset_url = true;
908
886
  }
909
- }
910
887
 
911
- // use IAB ORTB values if the corresponding values weren't already set by bid.params.video
912
- if (videoMediaType) {
913
- tag.video = tag.video || {};
914
- Object.keys(videoMediaType)
915
- .filter(param => includes(VIDEO_RTB_TARGETING, param))
916
- .forEach(param => {
917
- switch (param) {
918
- case 'minduration':
919
- case 'maxduration':
920
- if (typeof tag.video[param] !== 'number') tag.video[param] = videoMediaType[param];
921
- break;
922
- case 'skip':
923
- if (typeof tag.video['skippable'] !== 'boolean') tag.video['skippable'] = (videoMediaType[param] === 1);
924
- break;
925
- case 'skipafter':
926
- if (typeof tag.video['skipoffset'] !== 'number') tag.video['skippoffset'] = videoMediaType[param];
927
- break;
928
- case 'playbackmethod':
929
- if (typeof tag.video['playback_method'] !== 'number') {
930
- let type = videoMediaType[param];
888
+ if (bid.params.video) {
889
+ tag.video = {};
890
+ // place any valid video params on the tag
891
+ Object.keys(bid.params.video)
892
+ .filter(param => includes(VIDEO_TARGETING, param))
893
+ .forEach(param => {
894
+ switch (param) {
895
+ case 'context':
896
+ case 'playback_method':
897
+ let type = bid.params.video[param];
931
898
  type = (isArray(type)) ? type[0] : type;
899
+ tag.video[param] = VIDEO_MAPPING[param][type];
900
+ break;
901
+ // Deprecating tags[].video.frameworks in favor of tags[].video_frameworks
902
+ case 'frameworks':
903
+ break;
904
+ default:
905
+ tag.video[param] = bid.params.video[param];
906
+ }
907
+ });
932
908
 
933
- // we only support iab's options 1-4 at this time.
934
- if (type >= 1 && type <= 4) {
935
- tag.video['playback_method'] = type;
936
- }
937
- }
938
- break;
939
- case 'api':
940
- if (!tag['video_frameworks'] && isArray(videoMediaType[param])) {
941
- // need to read thru array; remove 6 (we don't support it), swap 4 <> 5 if found (to match our adserver mapping for these specific values)
942
- let apiTmp = videoMediaType[param].map(val => {
943
- let v = (val === 4) ? 5 : (val === 5) ? 4 : val;
944
-
945
- if (v >= 1 && v <= 5) {
946
- return v;
909
+ if (bid.params.video.frameworks && isArray(bid.params.video.frameworks)) {
910
+ tag['video_frameworks'] = bid.params.video.frameworks;
911
+ }
912
+ }
913
+
914
+ // use IAB ORTB values if the corresponding values weren't already set by bid.params.video
915
+ if (videoMediaType) {
916
+ tag.video = tag.video || {};
917
+ Object.keys(videoMediaType)
918
+ .filter(param => includes(VIDEO_RTB_TARGETING, param))
919
+ .forEach(param => {
920
+ switch (param) {
921
+ case 'minduration':
922
+ case 'maxduration':
923
+ if (typeof tag.video[param] !== 'number') tag.video[param] = videoMediaType[param];
924
+ break;
925
+ case 'skip':
926
+ if (typeof tag.video['skippable'] !== 'boolean') tag.video['skippable'] = (videoMediaType[param] === 1);
927
+ break;
928
+ case 'skipafter':
929
+ if (typeof tag.video['skipoffset'] !== 'number') tag.video['skippoffset'] = videoMediaType[param];
930
+ break;
931
+ case 'playbackmethod':
932
+ if (typeof tag.video['playback_method'] !== 'number') {
933
+ let type = videoMediaType[param];
934
+ type = (isArray(type)) ? type[0] : type;
935
+
936
+ // we only support iab's options 1-4 at this time.
937
+ if (type >= 1 && type <= 4) {
938
+ tag.video['playback_method'] = type;
947
939
  }
948
- }).filter(v => v);
949
- tag['video_frameworks'] = apiTmp;
950
- }
951
- break;
952
-
953
- case 'startdelay':
954
- case 'placement':
955
- const contextKey = 'context';
956
- if (typeof tag.video[contextKey] !== 'number') {
957
- const placement = videoMediaType['placement'];
958
- const startdelay = videoMediaType['startdelay'];
959
- const context = getContextFromPlacement(placement) || getContextFromStartDelay(startdelay);
960
- tag.video[contextKey] = VIDEO_MAPPING[contextKey][context];
961
- }
962
- break;
963
- }
964
- });
965
- }
940
+ }
941
+ break;
942
+ case 'api':
943
+ if (!tag['video_frameworks'] && isArray(videoMediaType[param])) {
944
+ // need to read thru array; remove 6 (we don't support it), swap 4 <> 5 if found (to match our adserver mapping for these specific values)
945
+ let apiTmp = videoMediaType[param].map(val => {
946
+ let v = (val === 4) ? 5 : (val === 5) ? 4 : val;
947
+
948
+ if (v >= 1 && v <= 5) {
949
+ return v;
950
+ }
951
+ }).filter(v => v);
952
+ tag['video_frameworks'] = apiTmp;
953
+ }
954
+ break;
955
+
956
+ case 'startdelay':
957
+ case 'placement':
958
+ const contextKey = 'context';
959
+ if (typeof tag.video[contextKey] !== 'number') {
960
+ const placement = videoMediaType['placement'];
961
+ const startdelay = videoMediaType['startdelay'];
962
+ const context = getContextFromPlacement(placement) || getContextFromStartDelay(startdelay);
963
+ tag.video[contextKey] = VIDEO_MAPPING[contextKey][context];
964
+ }
965
+ break;
966
+ }
967
+ });
968
+ }
966
969
 
967
- if (bid.renderer) {
968
- tag.video = Object.assign({}, tag.video, { custom_renderer_present: true });
970
+ if (bid.renderer) {
971
+ tag.video = Object.assign({}, tag.video, { custom_renderer_present: true });
972
+ }
973
+ } else {
974
+ tag.hb_source = 1;
969
975
  }
970
976
 
971
977
  if (bid.params.frameworks && isArray(bid.params.frameworks)) {
@@ -2,6 +2,7 @@ import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
2
2
  import adapterManager from '../src/adapterManager.js';
3
3
  import CONSTANTS from '../src/constants.json';
4
4
  import { ajax } from '../src/ajax.js';
5
+ import { getRefererInfo } from '../src/refererDetection.js';
5
6
 
6
7
  const analyticsType = 'endpoint';
7
8
  const url = 'URL_TO_SERVER_ENDPOINT';
@@ -145,6 +146,7 @@ function handleBidWon(args) {
145
146
  });
146
147
  }
147
148
  args['cpmIncrement'] = increment;
149
+ args['referer'] = encodeURIComponent(getRefererInfo().page || getRefererInfo().topmostLocation);
148
150
  if (typeof saveEvents.bidRequested == 'object' && saveEvents.bidRequested.length > 0 && saveEvents.bidRequested[0].gdprConsent) { args.gdpr = saveEvents.bidRequested[0].gdprConsent; }
149
151
  ajax(endpoint + '.bidwatch.io/analytics/bid_won', null, JSON.stringify(args), {method: 'POST', withCredentials: true});
150
152
  }
@@ -124,6 +124,9 @@ export const spec = {
124
124
  const payload = {
125
125
  id: requestId,
126
126
  imp: conversantImps,
127
+ source: {
128
+ tid: requestId
129
+ },
127
130
  site: {
128
131
  id: siteId,
129
132
  mobile: document.querySelector('meta[name="viewport"][content*="width=device-width"]') !== null ? 1 : 0,
@@ -223,7 +223,7 @@ export const spec = {
223
223
  creativeId: slot.creativecode,
224
224
  width: slot.width,
225
225
  height: slot.height,
226
- dealId: slot.dealCode,
226
+ dealId: slot.deal,
227
227
  };
228
228
  if (body.ext?.paf?.transmission && slot.ext?.paf?.content_id) {
229
229
  const pafResponseMeta = {
@@ -514,6 +514,10 @@ function buildCdbRequest(context, bidRequests, bidderRequest) {
514
514
  if (bidderRequest && bidderRequest.uspConsent) {
515
515
  request.user.uspIab = bidderRequest.uspConsent;
516
516
  }
517
+ if (bidderRequest && bidderRequest.ortb2?.device?.sua) {
518
+ request.user.ext = request.user.ext || {};
519
+ request.user.ext.sua = bidderRequest.ortb2?.device?.sua || {};
520
+ }
517
521
  return request;
518
522
  }
519
523
 
@@ -9,12 +9,13 @@ import { timestamp, parseUrl, triggerPixel, logError } from '../src/utils.js';
9
9
  import { ajax } from '../src/ajax.js';
10
10
  import { getRefererInfo } from '../src/refererDetection.js';
11
11
  import { submodule } from '../src/hook.js';
12
- import {getStorageManager} from '../src/storageManager.js';
13
- import {MODULE_TYPE_UID} from '../src/activities/modules.js';
12
+ import { getStorageManager } from '../src/storageManager.js';
13
+ import { MODULE_TYPE_UID } from '../src/activities/modules.js';
14
+ import { gdprDataHandler, uspDataHandler, gppDataHandler } from '../src/adapterManager.js';
14
15
 
15
16
  const gvlid = 91;
16
17
  const bidderCode = 'criteo';
17
- export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: bidderCode});
18
+ export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: bidderCode });
18
19
 
19
20
  const bididStorageKey = 'cto_bidid';
20
21
  const bundleStorageKey = 'cto_bundle';
@@ -77,17 +78,33 @@ function getCriteoDataFromAllStorages() {
77
78
  }
78
79
  }
79
80
 
80
- function buildCriteoUsersyncUrl(topUrl, domain, bundle, dnaBundle, areCookiesWriteable, isLocalStorageWritable, isPublishertagPresent, gdprString) {
81
- const url = 'https://gum.criteo.com/sid/json?origin=prebid' +
81
+ function buildCriteoUsersyncUrl(topUrl, domain, bundle, dnaBundle, areCookiesWriteable, isLocalStorageWritable, isPublishertagPresent) {
82
+ let url = 'https://gum.criteo.com/sid/json?origin=prebid' +
82
83
  `${topUrl ? '&topUrl=' + encodeURIComponent(topUrl) : ''}` +
83
84
  `${domain ? '&domain=' + encodeURIComponent(domain) : ''}` +
84
85
  `${bundle ? '&bundle=' + encodeURIComponent(bundle) : ''}` +
85
86
  `${dnaBundle ? '&info=' + encodeURIComponent(dnaBundle) : ''}` +
86
- `${gdprString ? '&gdprString=' + encodeURIComponent(gdprString) : ''}` +
87
87
  `${areCookiesWriteable ? '&cw=1' : ''}` +
88
88
  `${isPublishertagPresent ? '&pbt=1' : ''}` +
89
89
  `${isLocalStorageWritable ? '&lsw=1' : ''}`;
90
90
 
91
+ const usPrivacyString = uspDataHandler.getConsentData();
92
+ if (usPrivacyString) {
93
+ url = url + `&us_privacy=${encodeURIComponent(usPrivacyString)}`;
94
+ }
95
+
96
+ const gdprConsent = gdprDataHandler.getConsentData()
97
+ if (gdprConsent) {
98
+ url = url + `${gdprConsent.consentString ? '&gdprString=' + encodeURIComponent(gdprConsent.consentString) : ''}`;
99
+ url = url + `&gdpr=${gdprConsent.gdprApplies === true ? 1 : 0}`;
100
+ }
101
+
102
+ const gppConsent = gppDataHandler.getConsentData();
103
+ if (gppConsent) {
104
+ url = url + `${gppConsent.gppString ? '&gpp=' + encodeURIComponent(gppConsent.gppString) : ''}`;
105
+ url = url + `${gppConsent.applicableSections ? '&gpp_sid=' + encodeURIComponent(gppConsent.applicableSections) : ''}`;
106
+ }
107
+
91
108
  return url;
92
109
  }
93
110
 
@@ -116,7 +133,7 @@ function callSyncPixel(domain, pixel) {
116
133
  }
117
134
  }
118
135
 
119
- function callCriteoUserSync(parsedCriteoData, gdprString, callback) {
136
+ function callCriteoUserSync(parsedCriteoData, callback) {
120
137
  const cw = storage.cookiesAreEnabled();
121
138
  const lsw = storage.localStorageIsEnabled();
122
139
  const topUrl = extractProtocolHost(getRefererInfo().page);
@@ -131,8 +148,7 @@ function callCriteoUserSync(parsedCriteoData, gdprString, callback) {
131
148
  parsedCriteoData.dnaBundle,
132
149
  cw,
133
150
  lsw,
134
- isPublishertagPresent,
135
- gdprString
151
+ isPublishertagPresent
136
152
  );
137
153
 
138
154
  const callbacks = {
@@ -191,13 +207,10 @@ export const criteoIdSubmodule = {
191
207
  * @param {ConsentData} [consentData]
192
208
  * @returns {{id: {criteoId: string} | undefined}}}
193
209
  */
194
- getId(config, consentData) {
195
- const hasGdprData = consentData && typeof consentData.gdprApplies === 'boolean' && consentData.gdprApplies;
196
- const gdprConsentString = hasGdprData ? consentData.consentString : undefined;
197
-
210
+ getId() {
198
211
  let localData = getCriteoDataFromAllStorages();
199
212
 
200
- const result = (callback) => callCriteoUserSync(localData, gdprConsentString, callback);
213
+ const result = (callback) => callCriteoUserSync(localData, callback);
201
214
 
202
215
  return {
203
216
  id: localData.bidId ? { criteoId: localData.bidId } : undefined,
@@ -0,0 +1,211 @@
1
+ import { isFn, deepAccess, logMessage, logError } from '../src/utils.js';
2
+ import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
3
+
4
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
5
+ import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
6
+ import { config } from '../src/config.js';
7
+
8
+ const BIDDER_CODE = 'emtv';
9
+ const AD_URL = 'https://us-east-ep.engagemedia.tv/pbjs';
10
+ const SYNC_URL = 'https://cs.engagemedia.tv';
11
+
12
+ function isBidResponseValid(bid) {
13
+ if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) {
14
+ return false;
15
+ }
16
+
17
+ switch (bid.mediaType) {
18
+ case BANNER:
19
+ return Boolean(bid.width && bid.height && bid.ad);
20
+ case VIDEO:
21
+ return Boolean(bid.vastUrl || bid.vastXml);
22
+ case NATIVE:
23
+ return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length);
24
+ default:
25
+ return false;
26
+ }
27
+ }
28
+
29
+ function getPlacementReqData(bid) {
30
+ const { params, bidId, mediaTypes } = bid;
31
+ const schain = bid.schain || {};
32
+ const { placementId, endpointId } = params;
33
+ const bidfloor = getBidFloor(bid);
34
+
35
+ const placement = {
36
+ bidId,
37
+ schain,
38
+ bidfloor
39
+ };
40
+
41
+ if (placementId) {
42
+ placement.placementId = placementId;
43
+ placement.type = 'publisher';
44
+ } else if (endpointId) {
45
+ placement.endpointId = endpointId;
46
+ placement.type = 'network';
47
+ }
48
+
49
+ if (mediaTypes && mediaTypes[BANNER]) {
50
+ placement.adFormat = BANNER;
51
+ placement.sizes = mediaTypes[BANNER].sizes;
52
+ } else if (mediaTypes && mediaTypes[VIDEO]) {
53
+ placement.adFormat = VIDEO;
54
+ placement.playerSize = mediaTypes[VIDEO].playerSize;
55
+ placement.minduration = mediaTypes[VIDEO].minduration;
56
+ placement.maxduration = mediaTypes[VIDEO].maxduration;
57
+ placement.mimes = mediaTypes[VIDEO].mimes;
58
+ placement.protocols = mediaTypes[VIDEO].protocols;
59
+ placement.startdelay = mediaTypes[VIDEO].startdelay;
60
+ placement.placement = mediaTypes[VIDEO].placement;
61
+ placement.skip = mediaTypes[VIDEO].skip;
62
+ placement.skipafter = mediaTypes[VIDEO].skipafter;
63
+ placement.minbitrate = mediaTypes[VIDEO].minbitrate;
64
+ placement.maxbitrate = mediaTypes[VIDEO].maxbitrate;
65
+ placement.delivery = mediaTypes[VIDEO].delivery;
66
+ placement.playbackmethod = mediaTypes[VIDEO].playbackmethod;
67
+ placement.api = mediaTypes[VIDEO].api;
68
+ placement.linearity = mediaTypes[VIDEO].linearity;
69
+ } else if (mediaTypes && mediaTypes[NATIVE]) {
70
+ placement.native = mediaTypes[NATIVE];
71
+ placement.adFormat = NATIVE;
72
+ }
73
+
74
+ return placement;
75
+ }
76
+
77
+ function getBidFloor(bid) {
78
+ if (!isFn(bid.getFloor)) {
79
+ return deepAccess(bid, 'params.bidfloor', 0);
80
+ }
81
+
82
+ try {
83
+ const bidFloor = bid.getFloor({
84
+ currency: 'USD',
85
+ mediaType: '*',
86
+ size: '*',
87
+ });
88
+ return bidFloor.floor;
89
+ } catch (err) {
90
+ logError(err);
91
+ return 0;
92
+ }
93
+ }
94
+
95
+ export const spec = {
96
+ code: BIDDER_CODE,
97
+ supportedMediaTypes: [BANNER, VIDEO, NATIVE],
98
+
99
+ isBidRequestValid: (bid = {}) => {
100
+ const { params, bidId, mediaTypes } = bid;
101
+ let valid = Boolean(bidId && params && (params.placementId || params.endpointId));
102
+
103
+ if (mediaTypes && mediaTypes[BANNER]) {
104
+ valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes);
105
+ } else if (mediaTypes && mediaTypes[VIDEO]) {
106
+ valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize);
107
+ } else if (mediaTypes && mediaTypes[NATIVE]) {
108
+ valid = valid && Boolean(mediaTypes[NATIVE]);
109
+ } else {
110
+ valid = false;
111
+ }
112
+ return valid;
113
+ },
114
+
115
+ buildRequests: (validBidRequests = [], bidderRequest = {}) => {
116
+ // convert Native ORTB definition to old-style prebid native definition
117
+ validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests);
118
+
119
+ let deviceWidth = 0;
120
+ let deviceHeight = 0;
121
+
122
+ let winLocation;
123
+ try {
124
+ const winTop = window.top;
125
+ deviceWidth = winTop.screen.width;
126
+ deviceHeight = winTop.screen.height;
127
+ winLocation = winTop.location;
128
+ } catch (e) {
129
+ logMessage(e);
130
+ winLocation = window.location;
131
+ }
132
+
133
+ const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page;
134
+ let refferLocation;
135
+ try {
136
+ refferLocation = refferUrl && new URL(refferUrl);
137
+ } catch (e) {
138
+ logMessage(e);
139
+ }
140
+ let location = refferLocation || winLocation;
141
+ const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : '';
142
+ const host = location.host;
143
+ const page = location.pathname;
144
+ const secure = location.protocol === 'https:' ? 1 : 0;
145
+ const placements = [];
146
+ const request = {
147
+ deviceWidth,
148
+ deviceHeight,
149
+ language,
150
+ secure,
151
+ host,
152
+ page,
153
+ placements,
154
+ coppa: config.getConfig('coppa') === true ? 1 : 0,
155
+ ccpa: bidderRequest.uspConsent || undefined,
156
+ gdpr: bidderRequest.gdprConsent || undefined,
157
+ tmax: config.getConfig('bidderTimeout')
158
+ };
159
+
160
+ const len = validBidRequests.length;
161
+ for (let i = 0; i < len; i++) {
162
+ const bid = validBidRequests[i];
163
+ placements.push(getPlacementReqData(bid));
164
+ }
165
+
166
+ return {
167
+ method: 'POST',
168
+ url: AD_URL,
169
+ data: request
170
+ };
171
+ },
172
+
173
+ interpretResponse: (serverResponse) => {
174
+ let response = [];
175
+ for (let i = 0; i < serverResponse.body.length; i++) {
176
+ let resItem = serverResponse.body[i];
177
+ if (isBidResponseValid(resItem)) {
178
+ const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : [];
179
+ resItem.meta = { ...resItem.meta, advertiserDomains };
180
+
181
+ response.push(resItem);
182
+ }
183
+ }
184
+ return response;
185
+ },
186
+
187
+ getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => {
188
+ let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image';
189
+ let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`;
190
+ if (gdprConsent && gdprConsent.consentString) {
191
+ if (typeof gdprConsent.gdprApplies === 'boolean') {
192
+ syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`;
193
+ } else {
194
+ syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`;
195
+ }
196
+ }
197
+ if (uspConsent && uspConsent.consentString) {
198
+ syncUrl += `&ccpa_consent=${uspConsent.consentString}`;
199
+ }
200
+
201
+ const coppa = config.getConfig('coppa') ? 1 : 0;
202
+ syncUrl += `&coppa=${coppa}`;
203
+
204
+ return [{
205
+ type: syncType,
206
+ url: syncUrl
207
+ }];
208
+ }
209
+ };
210
+
211
+ registerBidder(spec);
@@ -0,0 +1,79 @@
1
+ # Overview
2
+
3
+ ```
4
+ Module Name: EMTV Bidder Adapter
5
+ Module Type: EMTV Bidder Adapter
6
+ Maintainer: support@engagemedia.tv
7
+ ```
8
+
9
+ # Description
10
+
11
+ Connects to EMTV exchange for bids.
12
+ EMTV bid adapter supports Banner, Video (instream and outstream) and Native.
13
+
14
+ # Test Parameters
15
+ ```
16
+ var adUnits = [
17
+ // Will return static test banner
18
+ {
19
+ code: 'adunit1',
20
+ mediaTypes: {
21
+ banner: {
22
+ sizes: [ [300, 250], [320, 50] ],
23
+ }
24
+ },
25
+ bids: [
26
+ {
27
+ bidder: 'emtv',
28
+ params: {
29
+ placementId: 'testBanner',
30
+ }
31
+ }
32
+ ]
33
+ },
34
+ {
35
+ code: 'addunit2',
36
+ mediaTypes: {
37
+ video: {
38
+ playerSize: [ [640, 480] ],
39
+ context: 'instream',
40
+ minduration: 5,
41
+ maxduration: 60,
42
+ }
43
+ },
44
+ bids: [
45
+ {
46
+ bidder: 'emtv',
47
+ params: {
48
+ placementId: 'testVideo',
49
+ }
50
+ }
51
+ ]
52
+ },
53
+ {
54
+ code: 'addunit3',
55
+ mediaTypes: {
56
+ native: {
57
+ title: {
58
+ required: true
59
+ },
60
+ body: {
61
+ required: true
62
+ },
63
+ icon: {
64
+ required: true,
65
+ size: [64, 64]
66
+ }
67
+ }
68
+ },
69
+ bids: [
70
+ {
71
+ bidder: 'emtv',
72
+ params: {
73
+ placementId: 'testNative',
74
+ }
75
+ }
76
+ ]
77
+ }
78
+ ];
79
+ ```