prebid.js 7.22.0 → 7.24.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 (314) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/aaxBlockmeterRtdProvider.js +1 -0
  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 -0
  7. package/dist/adrelevantisBidAdapter.js +1 -1
  8. package/dist/adtrgtmeBidAdapter.js +1 -1
  9. package/dist/adxcgBidAdapter.js +1 -1
  10. package/dist/adyoulikeBidAdapter.js +1 -1
  11. package/dist/ajaBidAdapter.js +1 -1
  12. package/dist/amxBidAdapter.js +1 -1
  13. package/dist/amxIdSystem.js +1 -1
  14. package/dist/analyticsAdapter.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/audiencerunBidAdapter.js +1 -1
  19. package/dist/axonixBidAdapter.js +1 -1
  20. package/dist/bidViewability.js +1 -1
  21. package/dist/bidViewabilityIO.js +1 -1
  22. package/dist/bidglassBidAdapter.js +1 -1
  23. package/dist/big-richmediaBidAdapter.js +1 -1
  24. package/dist/bluebillywigBidAdapter.js +1 -1
  25. package/dist/bridgewellBidAdapter.js +1 -1
  26. package/dist/brightMountainMediaBidAdapter.js +1 -1
  27. package/dist/browsiRtdProvider.js +1 -1
  28. package/dist/carodaBidAdapter.js +1 -1
  29. package/dist/chtnwBidAdapter.js +1 -0
  30. package/dist/cleanioRtdProvider.js +1 -1
  31. package/dist/concertBidAdapter.js +1 -1
  32. package/dist/connectIdSystem.js +1 -1
  33. package/dist/connectadBidAdapter.js +1 -1
  34. package/dist/consentManagement.js +1 -1
  35. package/dist/consentManagementUsp.js +1 -1
  36. package/dist/consumableBidAdapter.js +1 -1
  37. package/dist/conversantBidAdapter.js +1 -1
  38. package/dist/craftBidAdapter.js +1 -1
  39. package/dist/criteoBidAdapter.js +1 -1
  40. package/dist/currency.js +1 -1
  41. package/dist/dependencies.json +19 -0
  42. package/dist/dfpAdServerVideo.js +1 -1
  43. package/dist/dgkeywordRtdProvider.js +1 -1
  44. package/dist/dspxBidAdapter.js +1 -1
  45. package/dist/eplanningBidAdapter.js +1 -1
  46. package/dist/finativeBidAdapter.js +1 -1
  47. package/dist/gdprEnforcement.js +1 -1
  48. package/dist/glimpseBidAdapter.js +1 -1
  49. package/dist/gmosspBidAdapter.js +1 -1
  50. package/dist/goldbachBidAdapter.js +1 -1
  51. package/dist/googleAnalyticsAdapter.js +1 -1
  52. package/dist/gridBidAdapter.js +1 -1
  53. package/dist/gridNMBidAdapter.js +1 -1
  54. package/dist/growthCodeIdSystem.js +1 -1
  55. package/dist/gumgumBidAdapter.js +1 -1
  56. package/dist/h12mediaBidAdapter.js +1 -1
  57. package/dist/id5AnalyticsAdapter.js +1 -1
  58. package/dist/id5IdSystem.js +1 -1
  59. package/dist/impactifyBidAdapter.js +1 -1
  60. package/dist/improvedigitalBidAdapter.js +1 -1
  61. package/dist/inmarBidAdapter.js +1 -1
  62. package/dist/insticatorBidAdapter.js +1 -1
  63. package/dist/instreamTracking.js +1 -1
  64. package/dist/ixBidAdapter.js +1 -1
  65. package/dist/jixieBidAdapter.js +1 -1
  66. package/dist/justpremiumBidAdapter.js +1 -1
  67. package/dist/jwplayerVideoProvider.js +1 -0
  68. package/dist/kargoBidAdapter.js +1 -1
  69. package/dist/konduitAnalyticsAdapter.js +1 -1
  70. package/dist/kueezBidAdapter.js +1 -1
  71. package/dist/kueezRtbBidAdapter.js +1 -0
  72. package/dist/lassoBidAdapter.js +1 -1
  73. package/dist/lifestreetBidAdapter.js +1 -1
  74. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  75. package/dist/logicadBidAdapter.js +1 -1
  76. package/dist/loglyliftBidAdapter.js +1 -1
  77. package/dist/magniteAnalyticsAdapter.js +1 -1
  78. package/dist/malltvAnalyticsAdapter.js +1 -1
  79. package/dist/marsmediaBidAdapter.js +1 -1
  80. package/dist/mediafuseBidAdapter.js +1 -1
  81. package/dist/mediakeysBidAdapter.js +1 -1
  82. package/dist/mediasquareBidAdapter.js +1 -1
  83. package/dist/mgidBidAdapter.js +1 -1
  84. package/dist/mgidRtdProvider.js +1 -0
  85. package/dist/minutemediaBidAdapter.js +1 -1
  86. package/dist/multibid.js +1 -1
  87. package/dist/not-for-prod/prebid.js +153 -141
  88. package/dist/oguryBidAdapter.js +1 -1
  89. package/dist/onetagBidAdapter.js +1 -1
  90. package/dist/ooloAnalyticsAdapter.js +1 -1
  91. package/dist/openxOrtbBidAdapter.js +1 -1
  92. package/dist/ortbConverter.js +1 -0
  93. package/dist/outbrainBidAdapter.js +1 -1
  94. package/dist/oxxionRtdProvider.js +1 -0
  95. package/dist/parrableIdSystem.js +1 -1
  96. package/dist/pbsExtensions.js +1 -0
  97. package/dist/permutiveRtdProvider.js +1 -1
  98. package/dist/pixfutureBidAdapter.js +1 -1
  99. package/dist/prebid-core.js +1 -1
  100. package/dist/prebidServerBidAdapter.js +1 -1
  101. package/dist/priceFloors.js +1 -1
  102. package/dist/pubCommonId.js +1 -1
  103. package/dist/publinkIdSystem.js +1 -1
  104. package/dist/pubmaticBidAdapter.js +1 -1
  105. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  106. package/dist/pxyzBidAdapter.js +1 -1
  107. package/dist/quantcastBidAdapter.js +1 -1
  108. package/dist/readpeakBidAdapter.js +1 -1
  109. package/dist/relaidoBidAdapter.js +1 -1
  110. package/dist/rhythmoneBidAdapter.js +1 -1
  111. package/dist/riseBidAdapter.js +1 -1
  112. package/dist/rtdModule.js +1 -1
  113. package/dist/rubiconAnalyticsAdapter.js +1 -1
  114. package/dist/rubiconBidAdapter.js +1 -1
  115. package/dist/schain.js +1 -1
  116. package/dist/seedingAllianceBidAdapter.js +1 -1
  117. package/dist/seedtagBidAdapter.js +1 -1
  118. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  119. package/dist/sharethroughBidAdapter.js +1 -1
  120. package/dist/shinezBidAdapter.js +1 -1
  121. package/dist/smaatoBidAdapter.js +1 -1
  122. package/dist/smartadserverBidAdapter.js +1 -1
  123. package/dist/smartxBidAdapter.js +1 -1
  124. package/dist/smilewantedBidAdapter.js +1 -1
  125. package/dist/sonobiBidAdapter.js +1 -1
  126. package/dist/sovrnAnalyticsAdapter.js +1 -1
  127. package/dist/sovrnBidAdapter.js +1 -1
  128. package/dist/spotxBidAdapter.js +1 -1
  129. package/dist/sspBCBidAdapter.js +1 -1
  130. package/dist/sublimeBidAdapter.js +1 -1
  131. package/dist/synacormediaBidAdapter.js +1 -1
  132. package/dist/targetVideoBidAdapter.js +1 -1
  133. package/dist/teadsBidAdapter.js +1 -1
  134. package/dist/teadsIdSystem.js +1 -1
  135. package/dist/trionBidAdapter.js +1 -1
  136. package/dist/tripleliftBidAdapter.js +1 -1
  137. package/dist/ttdBidAdapter.js +1 -1
  138. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  139. package/dist/underdogmediaBidAdapter.js +1 -1
  140. package/dist/undertoneBidAdapter.js +1 -1
  141. package/dist/userId.js +1 -1
  142. package/dist/vidazooBidAdapter.js +1 -1
  143. package/dist/video.js +1 -0
  144. package/dist/videoModule.js +1 -0
  145. package/dist/videobyteBidAdapter.js +1 -1
  146. package/dist/videojsVideoProvider.js +1 -0
  147. package/dist/visxBidAdapter.js +1 -1
  148. package/dist/vuukleBidAdapter.js +1 -1
  149. package/dist/widespaceBidAdapter.js +1 -1
  150. package/dist/winrBidAdapter.js +1 -1
  151. package/dist/yahoosspBidAdapter.js +1 -1
  152. package/dist/yieldmoBidAdapter.js +1 -1
  153. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  154. package/integrationExamples/gpt/mgidRtdProvider_example.html +143 -0
  155. package/integrationExamples/videoModule/jwplayer/bidMarkedAsUsed.html +98 -0
  156. package/integrationExamples/videoModule/jwplayer/bidRequestScheduling.html +89 -0
  157. package/integrationExamples/videoModule/jwplayer/eventListeners.html +244 -0
  158. package/integrationExamples/videoModule/jwplayer/gamAdServerMediation.html +122 -0
  159. package/integrationExamples/videoModule/jwplayer/mediaMetadata.html +80 -0
  160. package/integrationExamples/videoModule/jwplayer/playlist.html +122 -0
  161. package/integrationExamples/videoModule/videojs/bidMarkedAsUsed.html +126 -0
  162. package/integrationExamples/videoModule/videojs/bidRequestScheduling.html +132 -0
  163. package/integrationExamples/videoModule/videojs/eventListeners.html +238 -0
  164. package/integrationExamples/videoModule/videojs/gamAdServerMediation.html +138 -0
  165. package/integrationExamples/videoModule/videojs/mediaMetadata.html +103 -0
  166. package/integrationExamples/videoModule/videojs/playlist.html +151 -0
  167. package/libraries/ortbConverter/README.md +378 -0
  168. package/libraries/ortbConverter/converter.js +135 -0
  169. package/libraries/ortbConverter/lib/composer.js +43 -0
  170. package/libraries/ortbConverter/lib/mergeProcessors.js +9 -0
  171. package/libraries/ortbConverter/lib/sizes.js +14 -0
  172. package/libraries/ortbConverter/processors/banner.js +40 -0
  173. package/libraries/ortbConverter/processors/default.js +167 -0
  174. package/libraries/ortbConverter/processors/mediaType.js +21 -0
  175. package/libraries/ortbConverter/processors/native.js +37 -0
  176. package/libraries/ortbConverter/processors/video.js +66 -0
  177. package/libraries/pbsExtensions/pbsExtensions.js +12 -0
  178. package/libraries/pbsExtensions/processors/aliases.js +17 -0
  179. package/libraries/pbsExtensions/processors/mediaType.js +23 -0
  180. package/libraries/pbsExtensions/processors/params.js +22 -0
  181. package/libraries/pbsExtensions/processors/pbs.js +99 -0
  182. package/libraries/pbsExtensions/processors/requestExtPrebid.js +30 -0
  183. package/libraries/pbsExtensions/processors/video.js +23 -0
  184. package/libraries/video/constants/enums.js +5 -0
  185. package/libraries/video/constants/events.js +97 -0
  186. package/libraries/video/constants/ortb.js +169 -0
  187. package/libraries/video/constants/vendorCodes.js +6 -0
  188. package/libraries/video/shared/eventHandler.js +18 -0
  189. package/libraries/video/shared/parentModule.js +82 -0
  190. package/libraries/video/shared/state.js +47 -0
  191. package/libraries/video/shared/vastXmlBuilder.js +77 -0
  192. package/libraries/video/shared/vastXmlEditor.js +115 -0
  193. package/modules/.submodules.json +7 -1
  194. package/modules/aaxBlockmeterRtdProvider.js +59 -0
  195. package/modules/aaxBlockmeterRtdProvider.md +48 -0
  196. package/modules/admaticBidAdapter.js +147 -0
  197. package/modules/admaticBidAdapter.md +48 -0
  198. package/modules/amxBidAdapter.js +1 -0
  199. package/modules/appnexusBidAdapter.js +38 -1
  200. package/modules/chtnwBidAdapter.js +110 -0
  201. package/modules/chtnwBidAdapter.md +31 -0
  202. package/modules/concertBidAdapter.js +44 -2
  203. package/modules/connectIdSystem.js +36 -23
  204. package/modules/connectIdSystem.md +3 -2
  205. package/modules/consentManagement.js +22 -1
  206. package/modules/consentManagementUsp.js +29 -7
  207. package/modules/criteoBidAdapter.js +25 -5
  208. package/modules/currency.js +9 -0
  209. package/modules/dgkeywordRtdProvider.js +3 -3
  210. package/modules/gridNMBidAdapter.js +10 -14
  211. package/modules/growthCodeIdSystem.js +9 -5
  212. package/modules/gumgumBidAdapter.js +4 -0
  213. package/modules/improvedigitalBidAdapter.js +191 -470
  214. package/modules/ixBidAdapter.js +54 -71
  215. package/modules/jwplayerVideoProvider.js +929 -0
  216. package/modules/jwplayerVideoProvider.md +25 -0
  217. package/modules/kargoBidAdapter.js +1 -1
  218. package/modules/kueezRtbBidAdapter.js +278 -0
  219. package/modules/kueezRtbBidAdapter.md +35 -0
  220. package/modules/magniteAnalyticsAdapter.js +6 -1
  221. package/modules/mgidRtdProvider.js +190 -0
  222. package/modules/mgidRtdProvider.md +51 -0
  223. package/modules/multibid/index.js +12 -0
  224. package/modules/openxOrtbBidAdapter.js +120 -275
  225. package/modules/oxxionRtdProvider.js +119 -0
  226. package/modules/oxxionRtdProvider.md +48 -0
  227. package/modules/permutiveRtdProvider.js +2 -1
  228. package/modules/permutiveRtdProvider.md +36 -1
  229. package/modules/prebidServerBidAdapter/index.js +19 -716
  230. package/modules/prebidServerBidAdapter/ortbConverter.js +274 -0
  231. package/modules/priceFloors.js +73 -1
  232. package/modules/pubmaticBidAdapter.js +21 -29
  233. package/modules/rtdModule/index.js +22 -1
  234. package/modules/schain.js +24 -1
  235. package/modules/spotxBidAdapter.js +16 -15
  236. package/modules/synacormediaBidAdapter.js +1 -1
  237. package/modules/teadsIdSystem.js +5 -0
  238. package/modules/tripleliftBidAdapter.js +1 -1
  239. package/modules/userId/eids.js +3 -10
  240. package/modules/userId/index.js +64 -6
  241. package/modules/videoModule/addingSubmodule.md +521 -0
  242. package/modules/videoModule/coreVideo.js +234 -0
  243. package/modules/videoModule/gamAdServerSubmodule.js +27 -0
  244. package/modules/videoModule/index.js +244 -0
  245. package/modules/videoModule/videoImpressionVerifier.js +206 -0
  246. package/modules/videojsVideoProvider.js +854 -0
  247. package/modules/videojsVideoProvider.md +17 -0
  248. package/package.json +12 -8
  249. package/src/adRendering.js +1 -1
  250. package/src/adapterManager.js +56 -7
  251. package/src/adloader.js +3 -1
  252. package/src/auction.js +6 -1
  253. package/src/events.js +5 -1
  254. package/src/pbjsORTB.js +35 -0
  255. package/src/prebid.js +137 -112
  256. package/src/targeting.js +10 -2
  257. package/src/utils/currency.js +16 -0
  258. package/src/utils.js +21 -0
  259. package/test/spec/auctionmanager_spec.js +15 -0
  260. package/test/spec/modules/aaxBlockmeter_spec.js +58 -0
  261. package/test/spec/modules/admaticBidAdapter_spec.js +46 -0
  262. package/test/spec/modules/chtnwBidAdapter_spec.js +105 -0
  263. package/test/spec/modules/concertBidAdapter_spec.js +56 -0
  264. package/test/spec/modules/connectIdSystem_spec.js +175 -5
  265. package/test/spec/modules/consentManagementUsp_spec.js +64 -18
  266. package/test/spec/modules/criteoBidAdapter_spec.js +28 -0
  267. package/test/spec/modules/dgkeywordRtdProvider_spec.js +3 -3
  268. package/test/spec/modules/eids_spec.js +10 -7
  269. package/test/spec/modules/ftrackIdSystem_spec.js +34 -22
  270. package/test/spec/modules/gumgumBidAdapter_spec.js +15 -0
  271. package/test/spec/modules/improvedigitalBidAdapter_spec.js +231 -211
  272. package/test/spec/modules/ixBidAdapter_spec.js +412 -350
  273. package/test/spec/modules/kueezRtbBidAdapter_spec.js +396 -0
  274. package/test/spec/modules/magniteAnalyticsAdapter_spec.js +26 -0
  275. package/test/spec/modules/mgidRtdProvider_spec.js +366 -0
  276. package/test/spec/modules/openxOrtbBidAdapter_spec.js +77 -49
  277. package/test/spec/modules/oxxionRtdProvider_spec.js +142 -0
  278. package/test/spec/modules/permutiveRtdProvider_spec.js +64 -5
  279. package/test/spec/modules/prebidServerBidAdapter_spec.js +139 -137
  280. package/test/spec/modules/realTimeDataModule_spec.js +65 -0
  281. package/test/spec/modules/tripleliftBidAdapter_spec.js +14 -0
  282. package/test/spec/modules/userId_spec.js +67 -1
  283. package/test/spec/modules/videoModule/coreVideo_spec.js +98 -0
  284. package/test/spec/modules/videoModule/pbVideo_spec.js +362 -0
  285. package/test/spec/modules/videoModule/shared/parentModule_spec.js +73 -0
  286. package/test/spec/modules/videoModule/shared/state_spec.js +26 -0
  287. package/test/spec/modules/videoModule/shared/vastXmlBuilder_spec.js +103 -0
  288. package/test/spec/modules/videoModule/shared/vastXmlEditor_spec.js +209 -0
  289. package/test/spec/modules/videoModule/submodules/jwplayerVideoProvider_spec.js +846 -0
  290. package/test/spec/modules/videoModule/submodules/videojsVideoProvider_spec.js +391 -0
  291. package/test/spec/modules/videoModule/videoImpressionVerifier_spec.js +112 -0
  292. package/test/spec/ortbConverter/banner_spec.js +203 -0
  293. package/test/spec/ortbConverter/composer_spec.js +69 -0
  294. package/test/spec/ortbConverter/converter_spec.js +283 -0
  295. package/test/spec/ortbConverter/currency_spec.js +40 -0
  296. package/test/spec/ortbConverter/default_processors_spec.js +61 -0
  297. package/test/spec/ortbConverter/gdpr_spec.js +38 -0
  298. package/test/spec/ortbConverter/mediaTypes_spec.js +67 -0
  299. package/test/spec/ortbConverter/mergeProcessors_spec.js +59 -0
  300. package/test/spec/ortbConverter/multibid_spec.js +35 -0
  301. package/test/spec/ortbConverter/native_spec.js +95 -0
  302. package/test/spec/ortbConverter/pbjsORTB_spec.js +67 -0
  303. package/test/spec/ortbConverter/pbsExtensions/aliases_spec.js +57 -0
  304. package/test/spec/ortbConverter/pbsExtensions/params_spec.js +96 -0
  305. package/test/spec/ortbConverter/pbsExtensions/video_spec.js +52 -0
  306. package/test/spec/ortbConverter/priceFloors_spec.js +143 -0
  307. package/test/spec/ortbConverter/schain_spec.js +33 -0
  308. package/test/spec/ortbConverter/userId_spec.js +21 -0
  309. package/test/spec/ortbConverter/usp_spec.js +15 -0
  310. package/test/spec/ortbConverter/video_spec.js +189 -0
  311. package/test/spec/unit/core/adapterManager_spec.js +102 -0
  312. package/test/spec/unit/core/targeting_spec.js +34 -0
  313. package/test/spec/unit/pbjs_api_spec.js +124 -45
  314. package/test/spec/utils_spec.js +45 -1
@@ -0,0 +1,151 @@
1
+ <html>
2
+
3
+ <head>
4
+ <link href="https://vjs.zencdn.net/7.20.2/video-js.css" rel="stylesheet" />
5
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/videojs-contrib-ads/6.9.0/videojs-contrib-ads.css"
6
+ integrity="sha512-0gIqgiX1dWTChdWUl8XGIBDFvLo7aTvmd6FAhJjzWx5bzYsCJTiPJLKqLF3q31IN4Kfrc0NbTO+EthoT6O0olQ=="
7
+ crossorigin="anonymous" referrerpolicy="no-referrer" />
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/videojs-ima/2.1.0/videojs.ima.css"
9
+ integrity="sha512-vvsEsf+dZDp6wbommO1Jbb2bpFhVQjw6pIzfE5fUY5Fgkmsgn/16sQWegqrd236T69kK5F1SbGZ+yK46a9il5A=="
10
+ crossorigin="anonymous" referrerpolicy="no-referrer" />
11
+ <script src="https://vjs.zencdn.net/7.20.2/video.js"></script>
12
+ <script src="https://imasdk.googleapis.com/js/sdkloader/ima3.js"></script>
13
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-contrib-ads/6.9.0/videojs-contrib-ads.js"
14
+ integrity="sha512-XjyyAijQGlXZET35toG8igvVs8HvfVgKXGnbfAs2EpZ0o8vjJoIrxL9RBBQbQjzAODIe0jvWelFfZOA3Z/vdWg=="
15
+ crossorigin="anonymous" referrerpolicy="no-referrer"></script>
16
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-ima/2.1.0/videojs.ima.js"
17
+ integrity="sha512-SCLZezhUawfgEVvtAuWp8OpRjZVa30okAsUoUe4+wPO6BEj4dWV1rDDruNwgOUrNdKpJL0GBf0KRrslSO7nqrw=="
18
+ crossorigin="anonymous" referrerpolicy="no-referrer"></script>
19
+ <script src="../../../node_modules/videojs-playlist/dist/videojs-playlist.js"></script>
20
+
21
+ <script async src="../../../build/dev/prebid.js"></script>
22
+
23
+ <title>VideoJS with Playlist</title>
24
+
25
+ <!-- This Demo sets up the videojs instance with a playlist and requests a bid whenever a new media item is loaded -->
26
+
27
+ <script>
28
+ // Setup ad units
29
+ var adUnits = [{
30
+ code: 'div-gpt-ad-51545-0',
31
+ mediaTypes: {
32
+ video: {}
33
+ },
34
+ video: {
35
+ divId: 'player', // required to indicate which player is being used to render this ad unit.
36
+ },
37
+
38
+ bids: [{
39
+ bidder: 'ix',
40
+ params: {
41
+ siteId: '300',
42
+ }
43
+ }]
44
+ }];
45
+
46
+ var pbjs = pbjs || {};
47
+ pbjs.que = pbjs.que || [];
48
+
49
+ pbjs.que.push(function () {
50
+ pbjs.setConfig({
51
+ video: {
52
+ providers: [{
53
+ divId: 'player',
54
+ vendorCode: 2, // videojs vendorCode
55
+ playerConfig: {
56
+ params: {
57
+ adPluginConfig: {
58
+ numRedirects: 10
59
+ },
60
+ vendorConfig: {
61
+ controls: true,
62
+ autoplay: false,
63
+ preload: "auto",
64
+ }
65
+ }
66
+ }
67
+ },]
68
+ },
69
+ debugging: {
70
+ enabled: true,
71
+ intercept: [
72
+ {
73
+ when: {
74
+ adUnitCode: 'div-gpt-ad-51545-0',
75
+ },
76
+ then: {
77
+ cpm: 25,
78
+ mediaType: "video",
79
+ vastUrl: "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/single_ad_samples&sz=640x480&cust_params=sample_ct%3Dlinear&ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator=",
80
+ // vastXml: "<VAST version=\"3.0\"> <Ad id=\"123\"> <InLine> <AdSystem>PubMatic</AdSystem> <AdTitle>VAST 2.0 Instream Test</AdTitle> <Description>VAST 2.0 Instream Test</Description> <Error> <![CDATA[https://aktrack.pubmatic.com/er=[ERRORCODE]]]> </Error> <Impression> <![CDATA[https://aktrack.pubmatic.com?e=impression]]> </Impression> <Creatives> <Creative AdID=\"123\"> <Linear> <Duration>00:00:30</Duration> <TrackingEvents> <Tracking event=\"creativeView\"> <![CDATA[https://aktrack.pubmatic.com?e=creativeView]]> </Tracking> <Tracking event=\"start\"> <![CDATA[https://aktrack.pubmatic.com?e=start]]> </Tracking> <Tracking event=\"midpoint\"> <![CDATA[https://aktrack.pubmatic.com?e=midpoint]]> </Tracking> <Tracking event=\"firstQuartile\"> <![CDATA[https://aktrack.pubmatic.com?e=firstQuartile]]> </Tracking> <Tracking event=\"thirdQuartile\"> <![CDATA[https://aktrack.pubmatic.com?e=thirdQuartile]]> </Tracking> <Tracking event=\"complete\"> <![CDATA[https://aktrack.pubmatic.com?e=complete]]> </Tracking> </TrackingEvents> <VideoClicks> <ClickThrough> <![CDATA[https://www.pubmatic.com]]> </ClickThrough> </VideoClicks> <MediaFiles> <MediaFile delivery=\"progressive\" type=\"video/mp4\" bitrate=\"500\" width=\"480\" height=\"460\" scalable=\"true\" maintainAspectRatio=\"true\"> <![CDATA[https://staging.pubmatic.com:8443/test/spinning-logo-480x360_video.mp4]]> </MediaFile> <MediaFile delivery=\"progressive\" type=\"video/ogg\" bitrate=\"500\" width=\"480\" height=\"460\" scalable=\"true\" maintainAspectRatio=\"true\"> <![CDATA[https://staging.pubmatic.com:8443/test/spinning-logo-480x360_video.ogg]]> </MediaFile> <MediaFile delivery=\"progressive\" type=\"video/x-flv\" bitrate=\"500\" width=\"400\" height=\"300\" scalable=\"true\" maintainAspectRatio=\"true\"> <![CDATA[https://staging.pubmatic.com:8443/test/PubMatic_test_video.flv]]> </MediaFile> </MediaFiles> </Linear> </Creative> <Creative AdID=\"123\"> <NonLinearAds> <TrackingEvents></TrackingEvents> <NonLinear height=\"50\" width=\"300\" minSuggestedDuration=\"00:00:05\"> <StaticResource creativeType=\"image/jpeg\"> <![CDATA[https://staging.pubmatic.com:8443/test/PubMatic_LetsBeClear_300x50.jpeg]]> </StaticResource> <NonLinearClickThrough> <![CDATA[https://www.pubmatic.com]]> </NonLinearClickThrough> </NonLinear> </NonLinearAds> </Creative> <Creative AdID=\"123\"> <CompanionAds> <Companion width=\"300\" height=\"250\"> <StaticResource creativeType=\"image/jpeg\"> <![CDATA[https://staging.pubmatic.com:8443/test/PubMatic_LetsBeClear_320x250.jpg]]> </StaticResource> <CompanionClickThrough> <![CDATA[https://www.pubmatic.com]]> </CompanionClickThrough> </Companion> </CompanionAds> </Creative> </Creatives> </InLine> </Ad> </VAST>",
81
+ ad: "<VAST version=\"3.0\"> <Ad id=\"123\"> <InLine> <AdSystem>PubMatic</AdSystem> <AdTitle>VAST 2.0 Instream Test</AdTitle> <Description>VAST 2.0 Instream Test</Description> <Error> <![CDATA[https://aktrack.pubmatic.com/er=[ERRORCODE]]]> </Error> <Impression> <![CDATA[https://aktrack.pubmatic.com?e=impression]]> </Impression> <Creatives> <Creative AdID=\"123\"> <Linear> <Duration>00:00:30</Duration> <TrackingEvents> <Tracking event=\"creativeView\"> <![CDATA[https://aktrack.pubmatic.com?e=creativeView]]> </Tracking> <Tracking event=\"start\"> <![CDATA[https://aktrack.pubmatic.com?e=start]]> </Tracking> <Tracking event=\"midpoint\"> <![CDATA[https://aktrack.pubmatic.com?e=midpoint]]> </Tracking> <Tracking event=\"firstQuartile\"> <![CDATA[https://aktrack.pubmatic.com?e=firstQuartile]]> </Tracking> <Tracking event=\"thirdQuartile\"> <![CDATA[https://aktrack.pubmatic.com?e=thirdQuartile]]> </Tracking> <Tracking event=\"complete\"> <![CDATA[https://aktrack.pubmatic.com?e=complete]]> </Tracking> </TrackingEvents> <VideoClicks> <ClickThrough> <![CDATA[https://www.pubmatic.com]]> </ClickThrough> </VideoClicks> <MediaFiles> <MediaFile delivery=\"progressive\" type=\"video/mp4\" bitrate=\"500\" width=\"480\" height=\"460\" scalable=\"true\" maintainAspectRatio=\"true\"> <![CDATA[https://staging.pubmatic.com:8443/test/spinning-logo-480x360_video.mp4]]> </MediaFile> <MediaFile delivery=\"progressive\" type=\"video/ogg\" bitrate=\"500\" width=\"480\" height=\"460\" scalable=\"true\" maintainAspectRatio=\"true\"> <![CDATA[https://staging.pubmatic.com:8443/test/spinning-logo-480x360_video.ogg]]> </MediaFile> <MediaFile delivery=\"progressive\" type=\"video/x-flv\" bitrate=\"500\" width=\"400\" height=\"300\" scalable=\"true\" maintainAspectRatio=\"true\"> <![CDATA[https://staging.pubmatic.com:8443/test/PubMatic_test_video.flv]]> </MediaFile> </MediaFiles> </Linear> </Creative> <Creative AdID=\"123\"> <NonLinearAds> <TrackingEvents></TrackingEvents> <NonLinear height=\"50\" width=\"300\" minSuggestedDuration=\"00:00:05\"> <StaticResource creativeType=\"image/jpeg\"> <![CDATA[https://staging.pubmatic.com:8443/test/PubMatic_LetsBeClear_300x50.jpeg]]> </StaticResource> <NonLinearClickThrough> <![CDATA[https://www.pubmatic.com]]> </NonLinearClickThrough> </NonLinear> </NonLinearAds> </Creative> <Creative AdID=\"123\"> <CompanionAds> <Companion width=\"300\" height=\"250\"> <StaticResource creativeType=\"image/jpeg\"> <![CDATA[https://staging.pubmatic.com:8443/test/PubMatic_LetsBeClear_320x250.jpg]]> </StaticResource> <CompanionClickThrough> <![CDATA[https://www.pubmatic.com]]> </CompanionClickThrough> </Companion> </CompanionAds> </Creative> </Creatives> </InLine> </Ad> </VAST>"
82
+ }
83
+ },
84
+ ]
85
+ }
86
+ });
87
+ pbjs.addAdUnits(adUnits);
88
+
89
+ pbjs.onEvent('videoSetupComplete', e => {
90
+ const player = videojs('player');
91
+ // Load the playlist items with their metadata when the video player is done instantiating.
92
+ player.playlist([{
93
+ sources: [{
94
+ id: 'XYXYXYXY',
95
+ src: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/SubaruOutbackOnStreetAndDirt.mp4',
96
+ title: 'Subaru Outback On Street And Dirt',
97
+ description: 'Smoking Tire takes the all-new Subaru Outback to the highest point we can find in hopes our customer-appreciation Balloon Launch will get some free T-shirts into the hands of our viewers.',
98
+ type: 'video/mp4'
99
+ }]
100
+ }, {
101
+ sources: [{
102
+ id: 'ZAZAZAZA',
103
+ src : "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
104
+ title : "Big Buck Bunny",
105
+ description : "Big Buck Bunny tells the story of a giant rabbit with a heart bigger than himself. When one sunny day three rodents rudely harass him, something snaps... and the rabbit ain't no bunny anymore! In the typical cartoon tradition he prepares the nasty rodents a comical revenge.\n\nLicensed under the Creative Commons Attribution license\nhttp://www.bigbuckbunny.org",
106
+ type: 'video/mp4'
107
+ }]
108
+ }, {
109
+ sources: [{
110
+ id: 'WSWSWSWS',
111
+ src: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/Sintel.mp4",
112
+ title : "Sintel",
113
+ description: "Sintel is an independently produced short film, initiated by the Blender Foundation as a means to further improve and validate the free/open source 3D creation suite Blender. With initial funding provided by 1000s of donations via the internet community, it has again proven to be a viable development model for both open 3D technology as for independent animation film.\nThis 15 minute film has been realized in the studio of the Amsterdam Blender Institute, by an international team of artists and developers. In addition to that, several crucial technical and creative targets have been realized online, by developers and artists and teams all over the world.\nwww.sintel.org",
114
+ type: 'video/mp4'
115
+ }]
116
+ }]);
117
+
118
+ player.playlist.autoadvance(0);
119
+ });
120
+
121
+ pbjs.onEvent('videoSetupFailed', e => {
122
+ console.log('player setup failed: ', e);
123
+ });
124
+
125
+ pbjs.onEvent('videoPlaylist', (e) => {
126
+ console.log('videos pb playlist: ', e);
127
+ });
128
+
129
+ // request a bid when media is loaded
130
+ pbjs.onEvent('videoContentLoaded', (e) => {
131
+ console.log('videos pb contentLoaded: ', e);
132
+ pbjs.requestBids(adUnits);
133
+ });
134
+
135
+ pbjs.onEvent('videoComplete', (e) => {
136
+ console.log('videos pb complete: ', e);
137
+ });
138
+ });
139
+ </script>
140
+
141
+ </head>
142
+
143
+ <body>
144
+ <h2>VideoJS with Playlist</h2>
145
+
146
+ <h5>Div-1: Player placeholder div</h5>
147
+ <video-js id='player' class="vjs-big-play-centered">
148
+ </video-js>
149
+ </body>
150
+
151
+ </html>
@@ -0,0 +1,378 @@
1
+ # Prebid.js - ORTB conversion library
2
+
3
+ This library provides methods to convert Prebid.js bid request objects to ORTB requests,
4
+ and ORTB responses to Prebid.js bid response objects.
5
+
6
+ ## Usage
7
+
8
+ The simplest way to use this from an adapter is:
9
+
10
+ ```javascript
11
+ import {ortbConverter} from '../../libraries/ortbConverter/converter.js'
12
+
13
+ const converter = ortbConverter({
14
+ context: {
15
+ // `netRevenue` and `ttl` are required properties of bid responses - provide a default for them
16
+ netRevenue: true, // or false if your adapter should set bidResponse.netRevenue = false
17
+ ttl: 30 // default bidResponse.ttl (when not specified in ORTB response.seatbid[].bid[].exp)
18
+ }
19
+ });
20
+
21
+ registerBidder({
22
+ // ... rest of your spec goes here ...
23
+ buildRequests(bidRequests, bidderRequest) {
24
+ const data = converter.toORTB({bidRequests, bidderRequest})
25
+ // you may need to adjust `data` to suit your needs - see "customization" below
26
+ return [{
27
+ method: METHOD,
28
+ url: ENDPOINT_URL,
29
+ data
30
+ }]
31
+ },
32
+ interpretResponse(response, request) {
33
+ const bids = converter.fromORTB({response: response.body, request: request.data}).bids;
34
+ // likewise, you may need to adjust the bid response objects
35
+ return bids;
36
+ },
37
+ })
38
+ ```
39
+
40
+ Without any customization, the library will generate complete ORTB requests, but ignores your [bid params](#params).
41
+ If your endpoint sets `response.seatbid[].bid[].mtype` (part of the ORTB 2.6 spec), it will also parse the response into complete bidResponse objects. See [setting response mediaTypes](#response-mediaTypes) if that is not the case.
42
+
43
+ ### Module-specific conversions
44
+
45
+ Prebid.js features that require a module also require it for their corresponding ORTB conversion logic. For example, `imp.bidfloor` is only populated if the `priceFloors` module is active; `request.cur` needs the `currency` module, and so on. Notably, this means that to get those fields populated from your unit tests, you must import those modules first; see [this suite](https://github.com/prebid/Prebid.js/blob/master/test/spec/modules/openxOrtbBidAdapter_spec.js) for an example.
46
+
47
+ ## Customization
48
+
49
+ ### Modifying return values directly
50
+
51
+ You are free to modify the objects returned by both `toORTB` and `fromORTB`:
52
+
53
+ ```javascript
54
+ const data = converter.toORTB({bidRequests, bidderRequest});
55
+ deepSetValue(data.imp[0], 'ext.myCustomParam', bidRequests[0].params.myCustomParam);
56
+ ```
57
+
58
+ However, there are two restrictions (to avoid them, use the [other customization options](#fine-customization)):
59
+
60
+ - you may not change the `imp[].id` returned by `toORTB`; they ared used internally to match responses to their requests.
61
+ ```javascript
62
+ const data = converter.toORTB({bidRequests, bidderRequest});
63
+ data.imp[0].id = 'custom-imp-id' // do not do this - it will cause an error later in `fromORTB`
64
+ ```
65
+ See also [overriding `imp.id`](#imp-id).
66
+ - the `request` argument passed to `fromORTB` must be the same object returned by `toORTB`.
67
+ ```javascript
68
+ let data = converter.toORTB({bidRequests, bidderRequest});
69
+
70
+ data = mergeDeep( // the original object is lost
71
+ {ext: {myCustomParam: bidRequests[0].params.myCustomParam}}, // `fromORTB` will later throw an error
72
+ data
73
+ );
74
+
75
+ // do this instead:
76
+ mergeDeep(
77
+ data,
78
+ {ext: {myCustomParam: bidRequests[0].params.myCustomParam}},
79
+ data
80
+ )
81
+ ```
82
+
83
+ <a id="fine-customization" />
84
+ ### Fine grained customization - imp, request, bidResponse, response
85
+
86
+ When invoked, `toORTB({bidRequests, bidderRequest})` first loops through each request in `bidRequests`, converting them into ORTB `imp` objects.
87
+ It then packages them into a single ORTB request, adding other parameters that are not imp-specific (such as for example `request.tmax`).
88
+
89
+ Likewise, `fromORTB({request, response})` first loops through each `response.seatbid[].bid[]`, converting them into Prebid bidResponses; it then packages them into
90
+ a single return value.
91
+
92
+ You can customize each of these steps using the `ortbConverter` arguments `imp`, `request`, `bidResponse` and `response`:
93
+
94
+ ### <a id="imp" />Customizing imps: `imp(buildImp, bidRequest, context)`
95
+
96
+ Invoked once for each input `bidRequest`; should return the ORTB `imp` object to include in the request.
97
+ The arguments are:
98
+
99
+ - `buildImp`: a function taking `(bidRequest, context)` and returning an ORTB `imp` object;
100
+ - `bidRequest`: the bid request object to convert;
101
+ - `context`: a [context object](#context) that contains at least:
102
+ - `bidderRequest`: the `bidderRequest` argument passed to `toORTB`.
103
+
104
+ #### <a id="params" />Example: attaching custom bid params
105
+
106
+ ```javascript
107
+ const converter = ortbConverter({
108
+ imp(buildImp, bidRequest, context) {
109
+ const imp = buildImp(bidRequest, context);
110
+ deepSetValue(imp, 'ext.params', bidRequest.params);
111
+ return imp;
112
+ }
113
+ })
114
+ ```
115
+
116
+ #### <a id="imp-id" /> Example: overriding imp.id
117
+
118
+ ```javascript
119
+ const converter = ortbConverter({
120
+ imp(buildImp, bidRequest, context) {
121
+ const imp = buildImp(bidRequest, context);
122
+ imp.id = randomIdentifierStr();
123
+ return imp;
124
+ }
125
+ })
126
+ ```
127
+
128
+ ### <a id="request" /> Customizing the request: `request(buildRequest, imps, bidderRequest, context)`
129
+
130
+ Invoked once after all bidRequests have been converted into `imp`s; should return the complete ORTB request. The return value
131
+ of this function is also the return value of `toORTB`.
132
+ The arguments are:
133
+
134
+ - `buildRequest`: a function taking `(imps, bidderRequest, context)` and returning an ORTB request object;
135
+ - `imps` an array of ORTB `imp` objects that should be included in the request;
136
+ - `bidderRequest`: the `bidderRequest` argument passed to `toORTB`;
137
+ - `context`: a [context object](#context) that contains at least:
138
+ - `bidRequests`: the `bidRequests` argument passed to `toORTB`.
139
+
140
+ #### Example: setting additional request properties
141
+
142
+ ```javascript
143
+ const converter = ortbConverter({
144
+ request(buildRequest, imps, bidderRequest, context) {
145
+ const request = buildRequest(imps, bidderRequest, context);
146
+ deepSetValue(request, 'ext.adapterVersion', '0.0.1');
147
+ return request;
148
+ }
149
+ })
150
+ ```
151
+
152
+ ### <a id="bidResponse" /> Customizing bid responses: `bidResponse(buildBidResponse, bid, context)`
153
+
154
+ Invoked once for each `seatbid[].bid[]` in the response; should return the corresponding Prebid.js bid response object.
155
+ The arguments are:
156
+ - `buildBidResponse`: a function taking `(bid, context)` and returning a Prebid.js bid response object;
157
+ - `bid`: an ORTB `seatbid[].bid[]` object;
158
+ - `context`: a [context object](#context) that contains at least:
159
+ - `seatbid`: the ORTB `seatbid[]` object that encloses `bid`;
160
+ - `imp`: the ORTB request's `imp` object that matches `bid.impid`;
161
+ - `bidRequest`: the Prebid.js bid request object that was used to generate `context.imp`;
162
+ - `ortbRequest`: the `request` argument passed to `fromORTB`;
163
+ - `ortbResponse`: the `response` argument passed to `fromORTB`.
164
+
165
+ #### Example: setting a custom outstream renderer
166
+
167
+ ```javascript
168
+ const converter = ortbConverter({
169
+ bidResponse(buildBidResponse, bid, context) {
170
+ const bidResponse = buildBidResponse(bid, context);
171
+ const {bidRequest} = context;
172
+ if (bidResponse.mediaType === VIDEO && bidRequest.mediaTypes.video.context === 'outstream') {
173
+ bidResponse.renderer = Renderer.install({
174
+ url: RENDERER_URL,
175
+ id: bidRequest.bidId,
176
+ adUnitCode: bidRequest.adUnitCode
177
+ });
178
+ }
179
+ return bidResponse;
180
+ }
181
+ })
182
+ ```
183
+
184
+ #### <a id="response-mediaTypes" /> Example: setting response mediaType
185
+
186
+ In ORTB 2.5, bid responses do not specify their mediatype, which is something Prebid.js requires. You can provide it as
187
+ `context.mediaType`:
188
+
189
+ ```javascript
190
+ const converter = ortbConverter({
191
+ bidResponse(buildBidResponse, bid, context) {
192
+ context.mediaType = deepAccess(bid, 'ext.mediaType');
193
+ return buildBidResponse(bid, context)
194
+ }
195
+ })
196
+ ```
197
+
198
+ If you know that a particular ORTB request/response pair deals with exclusively one mediaType, you may also pass it directly in the [context parameter](#context).
199
+ Note that - compared to the above - this has additional effects, because `context.mediaType` is also considered during `imp` generation - see [special context properties](#special-context).
200
+
201
+ ```javascript
202
+ converter.toORTB({
203
+ bidRequests: bidRequests.filter(isVideoBid),
204
+ bidderRequest,
205
+ context: {mediaType: 'video'} // make everything in this request/response deal with video only
206
+ })
207
+ ```
208
+
209
+ Note that this will _not_ work as intended:
210
+
211
+ ```javascript
212
+
213
+ const converter = ortbConverter({
214
+ bidResponse(buildBidResponse, bid, context) {
215
+ const bidResponse = buildBidResponse(bid, context); // this throws; buildBidResponse needs to know the
216
+ // mediaType to properly populate bidResponse.ad,
217
+ // bidResponse.native etc
218
+ bidResponse.mediaType = deepAccess(bid, 'ext.mediaType'); // too late, use context.mediaType
219
+ return bidResponse;
220
+ }
221
+ });
222
+
223
+ ```
224
+
225
+ ### <a id="response" /> Customizing the response: `response(buildResponse, bidResponses, ortbResponse, context)`
226
+
227
+ Invoked once, after all `seatbid[].bid[]` objects have been converted to corresponding bid responses. The value returned
228
+ by this function is also the value returned by `fromORTB`.
229
+ The arguments are:
230
+
231
+ - `buildResponse`: a function that takes `(bidResponses, ortbResponse, context)` and returns `{bids: bidResponses}`. In the future, this may contain additional response data not necessarily tied to any bid (for example fledge auction configuration).
232
+ - `bidResponses`: array of Prebid.js bid response objects
233
+ - `ortbResponse`: the `response` argument passed to `fromORTB`
234
+ - `context`: a [context object](#context) that contains at least:
235
+ - `ortbRequest`: the `request` argument passed to `fromORTB`;
236
+ - `bidderRequest`: the `bidderRequest` argument passed to `toORTB`;
237
+ - `bidRequests`: the `bidRequests` argument passed to `toORTB`.
238
+
239
+ #### Example: logging server-side errors
240
+
241
+ ```javascript
242
+ const converter = ortbConverter({
243
+ response(buildResponse, bidResponses, ortbResponse, context) {
244
+ (deepAccess(ortbResponse, 'ext.errors') || []).forEach((e) => logWarn('Server error', e));
245
+ return buildResponse(bidResponses, ortbResponse, context);
246
+ }
247
+ })
248
+ ```
249
+
250
+ ### Even finer grained customization - processor overrides
251
+
252
+ Each of the four conversion steps described above - imp, request, bidResponse and response - is further broken down into
253
+ smaller units of work (called _processors_). For example, when the currency module is included, it adds a _request processor_
254
+ that sets `request.cur`; the priceFloors module adds an _imp processor_ that sets `imp.bidfloor` and `imp.bidfloorcur`, and so on.
255
+
256
+ Each processor can be overridden or disabled through the `overrides` argument:
257
+
258
+ #### Example: disabling currency
259
+ ```javascript
260
+ const converter = ortbConverter({
261
+ overrides: {
262
+ request: {
263
+ currency: false
264
+ }
265
+ }
266
+ })
267
+ ```
268
+
269
+ The above is similar in effect to:
270
+
271
+ ```javascript
272
+ const converter = ortbConverter({
273
+ request(buildRequest, imps, bidderRequest, context) {
274
+ const request = buildRequest(imps, bidderRequest, context);
275
+ delete request.cur;
276
+ return request;
277
+ }
278
+ })
279
+ ```
280
+
281
+ With the main difference being that setting `currency: false` will disable currency logic entirely, while the `request`
282
+ version will still set `request.cur`, then delete it. If the currency processor is ever updated to deal with more than just `request.cur`, the `request`
283
+ function will also need to be updated accordingly.
284
+
285
+ #### Example: taking video parameters from `bidRequest.params.video`
286
+
287
+ Processors can also be overridden:
288
+
289
+ ```javascript
290
+ const converter = ortbConverter({
291
+ overrides: {
292
+ imp: {
293
+ video(orig, imp, bidRequest, context) {
294
+ // `orig` is the video imp processor, which looks at bidRequest.mediaTypes[VIDEO]
295
+ // to populate imp.video
296
+ // alter its input `bidRequest` to also pick up parameters from `bidRequest.params`
297
+ let videoParams = bidRequest.mediaTypes[VIDEO];
298
+ if (videoParams) {
299
+ videoParams = Object.assign({}, videoParams, bidRequest.params.video);
300
+ bidRequest = {...bidRequest, mediaTypes: {[VIDEO]: videoParams}}
301
+ }
302
+ orig(imp, bidRequest, context);
303
+ }
304
+ }
305
+ }
306
+ });
307
+ ```
308
+
309
+ #### Processor override functions
310
+
311
+ Processor overrides are similar to the override options described above, except that they take the object to process as argument:
312
+
313
+ - `imp` processor overrides take `(orig, imp, bidRequest, context)`, where:
314
+ - `orig` is the processor function being overridden, which itself takes `(imp, bidRequest, context)`;
315
+ - `imp` is the (partial) imp object to modify;
316
+ - `bidRequest` and `context` are the same arguments passed to [imp](#imp).
317
+ - `request` processor overrides take `(orig, ortbRequest, bidderRequest, context)`, where:
318
+ - `orig` is the processor function being overridden, and takes `(ortbRequest, bidderRequest, context)`;
319
+ - `ortbRequest` is the partial request to modify;
320
+ - `bidderRequest` and `context` are the same arguments passed to [request](#reuqest).
321
+ - `bidResponse` processor overrides take `(orig, bidResponse, bid, context)`, where:
322
+ - `orig` is the processor function being overridden, and takes `(bidResponse, bid, context)`;
323
+ - `bidResponse` is the partial bid response to modify;
324
+ - `bid` and `context` are the same arguments passed to [bidResponse](#bidResponse)
325
+ - `response` processor overrides take `(orig, response, ortbResponse, context)`, where:
326
+ - `orig` is the processor function being overriden, and takes `(response, ortbResponse, context)`;
327
+ - `response` is the partial response to modify;
328
+ - `ortbRespones` and `context` are the same arguments passed to [response](#response).
329
+
330
+ ### <a id="context" /> The `context` argument
331
+
332
+ All customization functions take a `context` argument. This is a plain JS object that is shared between `request` and its corresponding `response`; and between `imp` and its corresponding `bidResponse`:
333
+
334
+ ```javascript
335
+ const converter = ortbConverter({
336
+ imp(buildImp, bidRequest, context) {
337
+ // `context` here will be later passed to `bidResponse` (if one matches the imp generated here)
338
+ context.someData = somethingInterestingAbout(bidRequest);
339
+ return buildImp(bidRequest, context);
340
+ },
341
+ bidResponse(buildBidResponse, bid, context) {
342
+ const bidResponse = buildBidResponse(bid, context);
343
+ doSomethingWith(context.someData);
344
+ return bidResponse;
345
+ }
346
+ })
347
+ ```
348
+
349
+ `ortbConverter` automatically populates `context` with some values of interest, such as `bidRequest`, `bidderRequest`, etc - as detailed above. In addition, you may pass additional context properties through:
350
+
351
+ - the `context` argument of `ortbConverter`: e.g. `ortbConverter({context: {ttl: 30}})`. This will set `context.ttl = 30` globally for the converter.
352
+ - the `context` argument of `toORTB`: e.g. `converter.toORTB({bidRequests, bidderRequest, context: {ttl: 30}})`. This will set `context.ttl = 30` only for this request.
353
+
354
+ ### <a id="special-context"/> Special `context` properties
355
+
356
+ For ease of use, the conversion logic gives special meaning to some context properties:
357
+
358
+ - `currency`: a currency string (e.g. `'EUR'`). If specified, overrides the currency to use for computing price floors and `request.cur`. If omitted, both default to `getConfig('currency.adServerCurrency')`.
359
+ - `mediaType`: a bid mediaType (`'banner'`, `'video'`, or `'native'`). If specified:
360
+ - disables `imp` generation for other media types (i.e., if `context.mediaType === 'banner'`, only `imp.banner` will be populated; `imp.video` and `imp.native` will not, even if the bid request specifies them);
361
+ - is passed as the `mediaType` option to `bidRequest.getFloor` when computing price floors;
362
+ - sets `bidResponse.mediaType`.
363
+ - `nativeRequest`: a plain object that serves as the base value for `imp.native.request` (and is relevant only for native bid requests).
364
+ If not specified, the only property that is guaranteed to be populated is `assets`, since Prebid does not require anything else to define a native adUnit. You can use `context.nativeRequest` to provide other properties; for example, you may want to signal support for native impression trackers by setting it to `{eventtrackers: [{event: 1, methods: [1, 2]}]}` (see also the [ORTB Native spec](https://www.iab.com/wp-content/uploads/2018/03/OpenRTB-Native-Ads-Specification-Final-1.2.pdf)).
365
+ - `netRevenue`: the value to set as `bidResponse.netRevenue`. This is a required property of bid responses that does not have a clear ORTB counterpart.
366
+ - `ttl`: the default value to use for `bidResponse.ttl` (if the ORTB response does not provide one in `seatbid[].bid[].exp`).
367
+
368
+ ## Prebid Server extensions
369
+
370
+ If your endpoint is a Prebid Server instance, you may take advantage of the `pbsExtension` companion library, which adds a number of processors that can populate and parse PBS-specific extensions (typically prefixed `ext.prebid`); these include bidder params (with `transformBidParams`), bidder aliases, targeting keys, and others.
371
+
372
+ ```javascript
373
+ import {pbsExtensions} from '../../libraries/pbsExtensions/pbsExtensions.js'
374
+
375
+ const pbsConverter = ortbConverter({
376
+ processors: pbsExtensions
377
+ })
378
+ ```
@@ -0,0 +1,135 @@
1
+ import {compose} from './lib/composer.js';
2
+ import {logError, memoize} from '../../src/utils.js';
3
+ import {DEFAULT_PROCESSORS} from './processors/default.js';
4
+ import {BID_RESPONSE, DEFAULT, getProcessors, IMP, REQUEST, RESPONSE} from '../../src/pbjsORTB.js';
5
+ import {mergeProcessors} from './lib/mergeProcessors.js';
6
+
7
+ export function ortbConverter({
8
+ context: defaultContext = {},
9
+ processors = defaultProcessors,
10
+ overrides = {},
11
+ imp,
12
+ request,
13
+ bidResponse,
14
+ response,
15
+ } = {}) {
16
+ const REQ_CTX = new WeakMap();
17
+
18
+ function builder(slot, wrapperFn, builderFn, errorHandler) {
19
+ let build;
20
+ return function () {
21
+ if (build == null) {
22
+ build = (function () {
23
+ let delegate = builderFn.bind(this, compose(processors()[slot] || {}, overrides[slot] || {}));
24
+ if (wrapperFn) {
25
+ delegate = wrapperFn.bind(this, delegate);
26
+ }
27
+ return function () {
28
+ try {
29
+ return delegate.apply(this, arguments);
30
+ } catch (e) {
31
+ errorHandler.call(this, e, ...arguments);
32
+ }
33
+ }
34
+ })();
35
+ }
36
+ return build.apply(this, arguments);
37
+ }
38
+ }
39
+
40
+ const buildImp = builder(IMP, imp,
41
+ function (process, bidRequest, context) {
42
+ const imp = {};
43
+ process(imp, bidRequest, context);
44
+ return imp;
45
+ },
46
+ function (error, bidRequest, context) {
47
+ logError('Error while converting bidRequest to ORTB imp; request skipped.', {error, bidRequest, context});
48
+ }
49
+ );
50
+
51
+ const buildRequest = builder(REQUEST, request,
52
+ function (process, imps, bidderRequest, context) {
53
+ const ortbRequest = {imp: imps};
54
+ process(ortbRequest, bidderRequest, context);
55
+ return ortbRequest;
56
+ },
57
+ function (error, imps, bidderRequest, context) {
58
+ logError('Error while converting to ORTB request', {error, imps, bidderRequest, context});
59
+ throw error;
60
+ }
61
+ );
62
+
63
+ const buildBidResponse = builder(BID_RESPONSE, bidResponse,
64
+ function (process, bid, context) {
65
+ const bidResponse = {};
66
+ process(bidResponse, bid, context);
67
+ return bidResponse;
68
+ },
69
+ function (error, bid, context) {
70
+ logError('Error while converting ORTB seatbid.bid to bidResponse; bid skipped.', {error, bid, context});
71
+ }
72
+ );
73
+
74
+ const buildResponse = builder(RESPONSE, response,
75
+ function (process, bidResponses, ortbResponse, context) {
76
+ const response = {bids: bidResponses};
77
+ process(response, ortbResponse, context);
78
+ return response;
79
+ },
80
+ function (error, bidResponses, ortbResponse, context) {
81
+ logError('Error while converting from ORTB response', {error, bidResponses, ortbResponse, context});
82
+ throw error;
83
+ }
84
+ );
85
+
86
+ return {
87
+ toORTB({bidderRequest, bidRequests, context = {}}) {
88
+ bidRequests = bidRequests || bidderRequest.bids;
89
+ const ctx = {
90
+ req: Object.assign({bidRequests}, defaultContext, context),
91
+ imp: {}
92
+ }
93
+ const imps = bidRequests.map(bidRequest => {
94
+ const impContext = Object.assign({bidderRequest, reqContext: ctx.req}, defaultContext, context);
95
+ const result = buildImp(bidRequest, impContext);
96
+ if (result != null) {
97
+ if (result.hasOwnProperty('id')) {
98
+ impContext.bidRequest = bidRequest;
99
+ ctx.imp[result.id] = impContext;
100
+ return result;
101
+ }
102
+ logError('Converted ORTB imp does not specify an id, ignoring bid request', bidRequest, result);
103
+ }
104
+ }).filter(Boolean);
105
+
106
+ const request = buildRequest(imps, bidderRequest, ctx.req);
107
+ ctx.req.bidderRequest = bidderRequest;
108
+ if (request != null) {
109
+ REQ_CTX.set(request, ctx);
110
+ }
111
+ return request;
112
+ },
113
+ fromORTB({request, response}) {
114
+ const ctx = REQ_CTX.get(request);
115
+ if (ctx == null) {
116
+ throw new Error('ortbRequest passed to `fromORTB` must be the same object returned by `toORTB`')
117
+ }
118
+ function augmentContext(ctx, extraParams = {}) {
119
+ return Object.assign({ortbRequest: request}, extraParams, ctx);
120
+ }
121
+ const impsById = Object.fromEntries((request.imp || []).map(imp => [imp.id, imp]));
122
+ const bidResponses = (response.seatbid || []).flatMap(seatbid =>
123
+ (seatbid.bid || []).map((bid) => {
124
+ if (impsById.hasOwnProperty(bid.impid) && ctx.imp.hasOwnProperty(bid.impid)) {
125
+ return buildBidResponse(bid, augmentContext(ctx.imp[bid.impid], {imp: impsById[bid.impid], seatbid, ortbResponse: response}));
126
+ }
127
+ logError('ORTB response seatbid[].bid[].impid does not match any imp in request; ignoring bid', bid);
128
+ })
129
+ ).filter(Boolean);
130
+ return buildResponse(bidResponses, response, augmentContext(ctx.req));
131
+ }
132
+ }
133
+ }
134
+
135
+ export const defaultProcessors = memoize(() => mergeProcessors(DEFAULT_PROCESSORS, getProcessors(DEFAULT)));