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
@@ -1,74 +1,29 @@
1
- import {
2
- cleanObj,
3
- deepAccess,
4
- deepClone,
5
- deepSetValue,
6
- getBidIdParameter,
7
- getBidRequest,
8
- getDNT,
9
- getUniqueIdentifierStr,
10
- isFn,
11
- isPlainObject,
12
- logWarn,
13
- mergeDeep
14
- } from '../src/utils.js';
1
+ import {deepAccess, deepSetValue, getBidIdParameter, getUniqueIdentifierStr, logWarn, mergeDeep} from '../src/utils.js';
15
2
  import {registerBidder} from '../src/adapters/bidderFactory.js';
16
3
  import {config} from '../src/config.js';
17
4
  import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js';
18
5
  import {Renderer} from '../src/Renderer.js';
19
- import {createEidsArray} from './userId/eids.js';
20
6
  import {hasPurpose1Consent} from '../src/utils/gpdr.js';
21
- import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
7
+ import {ortbConverter} from '../libraries/ortbConverter/converter.js';
22
8
  import {loadExternalScript} from '../src/adloader.js';
23
9
 
24
10
  const BIDDER_CODE = 'improvedigital';
25
11
  const CREATIVE_TTL = 300;
26
12
 
27
- const AD_SERVER_URL = 'https://ad.360yield.com/pb';
28
- const BASIC_ADS_URL = 'https://ad.360yield-basic.com/pb';
13
+ const AD_SERVER_BASE_URL = 'https://ad.360yield.com';
14
+ const BASIC_ADS_BASE_URL = 'https://ad.360yield-basic.com';
15
+ const PB_ENDPOINT = 'pb';
29
16
  const EXTEND_URL = 'https://pbs.360yield.com/openrtb2/auction';
30
17
  const IFRAME_SYNC_URL = 'https://hb.360yield.com/prebid-universal-creative/load-cookie.html';
31
18
 
32
19
  const VIDEO_PARAMS = {
33
20
  DEFAULT_MIMES: ['video/mp4'],
34
- SUPPORTED_PROPERTIES: ['mimes', 'minduration', 'maxduration', 'protocols', 'w', 'h', 'startdelay', 'placement', 'linearity', 'skip', 'skipmin',
35
- 'skipafter', 'sequence', 'battr', 'maxextended', 'minbitrate', 'maxbitrate', 'boxingallowed', 'playbackmethod', 'playbackend', 'delivery', 'pos', 'companionad',
36
- 'api', 'companiontype', 'ext'],
37
21
  PLACEMENT_TYPE: {
38
22
  INSTREAM: 1,
39
23
  OUTSTREAM: 3,
40
24
  }
41
25
  };
42
26
 
43
- const NATIVE_DATA = {
44
- VERSION: '1.2',
45
- ASSET_TYPES: {
46
- TITLE: 'title',
47
- IMG: 'img',
48
- DATA: 'data',
49
- },
50
- ASSETS: {
51
- title: {id: 0, name: 'title', assetType: 'title', default: {len: 140}},
52
- sponsoredBy: {id: 1, name: 'sponsoredBy', assetType: 'data', type: 1},
53
- icon: {id: 2, name: 'icon', assetType: 'img', type: 2},
54
- body: {id: 3, name: 'body', assetType: 'data', type: 2},
55
- image: {id: 4, name: 'image', assetType: 'img', type: 3},
56
- rating: {id: 5, name: 'rating', assetType: 'data', type: 3},
57
- likes: {id: 6, name: 'likes', assetType: 'data', type: 4},
58
- downloads: {id: 7, name: 'downloads', assetType: 'data', type: 5},
59
- price: {id: 8, name: 'price', assetType: 'data', type: 6},
60
- salePrice: {id: 9, name: 'salePrice', assetType: 'data', type: 7},
61
- phone: {id: 10, name: 'phone', assetType: 'data', type: 8},
62
- address: {id: 11, name: 'address', assetType: 'data', type: 9},
63
- body2: {id: 12, name: 'body2', assetType: 'data', type: 10},
64
- displayUrl: {id: 13, name: 'displayUrl', assetType: 'data', type: 11},
65
- cta: {id: 14, name: 'cta', assetType: 'data', type: 12},
66
- },
67
- getAssetById(id) {
68
- return Object.values(this.ASSETS).find(asset => id === asset.id);
69
- }
70
- };
71
-
72
27
  export const spec = {
73
28
  code: BIDDER_CODE,
74
29
  gvlid: 253,
@@ -94,85 +49,9 @@ export const spec = {
94
49
  * @return ServerRequest Info describing the request to the server.
95
50
  */
96
51
  buildRequests(bidRequests, bidderRequest) {
97
- // convert Native ORTB definition to old-style prebid native definition
98
- bidRequests = convertOrtbRequestToProprietaryNative(bidRequests);
99
-
100
- const request = {
101
- cur: [config.getConfig('currency.adServerCurrency') || 'USD'],
102
- ext: {
103
- improvedigital: {
104
- sdk: {
105
- name: 'pbjs',
106
- version: '$prebid.version$',
107
- }
108
- }
109
- }
110
- };
111
-
112
- // Device
113
- request.device = (typeof config.getConfig('device') === 'object') ? config.getConfig('device') : {};
114
- request.device.w = request.device.w || window.innerWidth;
115
- request.device.h = request.device.h || window.innerHeight;
116
- if (getDNT()) {
117
- request.device.dnt = 1;
118
- }
119
-
120
- // Coppa
121
- const coppa = config.getConfig('coppa');
122
- if (typeof coppa === 'boolean') {
123
- deepSetValue(request, 'regs.coppa', Number(coppa));
124
- }
125
-
126
- if (bidderRequest) {
127
- // GDPR
128
- const gdprConsent = deepAccess(bidderRequest, 'gdprConsent');
129
- if (gdprConsent) {
130
- if (typeof gdprConsent.gdprApplies === 'boolean') {
131
- deepSetValue(request, 'regs.ext.gdpr', Number(gdprConsent.gdprApplies));
132
- }
133
- deepSetValue(request, 'user.ext.consent', gdprConsent.consentString);
134
-
135
- // Additional Consent String
136
- const additionalConsent = deepAccess(gdprConsent, 'addtlConsent');
137
- if (additionalConsent && additionalConsent.indexOf('~') !== -1) {
138
- // Google Ad Tech Provider IDs
139
- const atpIds = additionalConsent.substring(additionalConsent.indexOf('~') + 1);
140
- if (atpIds) {
141
- deepSetValue(
142
- request,
143
- 'user.ext.consented_providers_settings.consented_providers',
144
- atpIds.split('.').map(id => parseInt(id, 10))
145
- );
146
- }
147
- }
148
- }
149
-
150
- // Timeout
151
- if (bidderRequest.timeout) {
152
- request.tmax = parseInt(bidderRequest.timeout);
153
- }
154
- // US Privacy
155
- if (typeof bidderRequest.uspConsent !== typeof undefined) {
156
- deepSetValue(request, 'regs.ext.us_privacy', bidderRequest.uspConsent);
157
- }
158
- }
159
-
160
- ID_REQUEST.buildSiteOrApp(request, bidderRequest);
161
-
162
- const bidRequest0 = bidRequests[0];
163
-
164
- deepSetValue(request, 'source.ext.schain', bidRequest0.schain);
165
- deepSetValue(request, 'source.tid', bidRequest0.transactionId);
166
-
167
52
  // Save a placement id to send it to the ad server when fetching the user syncs
168
- this.syncStore.placementId = this.syncStore.placementId || bidRequest0.params.placementId;
169
-
170
- if (bidRequest0.userId) {
171
- const eids = createEidsArray(bidRequest0.userId);
172
- deepSetValue(request, 'user.ext.eids', eids.length ? eids : undefined);
173
- }
174
-
175
- return ID_REQUEST.buildServerRequests(request, bidRequests, bidderRequest);
53
+ this.syncStore.placementId = this.syncStore.placementId || bidRequests[0].params.placementId;
54
+ return ID_REQUEST.buildServerRequests(bidRequests, bidderRequest);
176
55
  },
177
56
 
178
57
  /**
@@ -182,48 +61,8 @@ export const spec = {
182
61
  * @param bidderRequest
183
62
  * @return {Bid[]} An array of bids which were nested inside the server.
184
63
  */
185
- interpretResponse(serverResponse, { bidderRequest }) {
186
- if (!Array.isArray(deepAccess(serverResponse, 'body.seatbid'))) {
187
- return [];
188
- }
189
-
190
- const bids = [];
191
-
192
- serverResponse.body.seatbid.forEach(seatbid => {
193
- if (!Array.isArray(seatbid.bid)) return;
194
-
195
- seatbid.bid.forEach(bidObject => {
196
- if (!bidObject.adm || !bidObject.price || bidObject.hasOwnProperty('errorCode')) {
197
- return;
198
- }
199
- const bidRequest = getBidRequest(bidObject.impid, [bidderRequest]);
200
- const idExt = deepAccess(bidObject, `ext.${BIDDER_CODE}`, {});
201
-
202
- const bid = {
203
- requestId: bidObject.impid,
204
- cpm: bidObject.price,
205
- creativeId: bidObject.crid,
206
- currency: serverResponse.body.cur.toUpperCase() || 'USD',
207
- dealId: (typeof idExt.buying_type === 'string' && idExt.buying_type !== 'rtb') ? idExt.line_item_id : undefined,
208
- meta: {
209
- advertiserDomains: bidObject.adomain ? bidObject.adomain : []
210
- },
211
- netRevenue: idExt.is_net || false,
212
- ttl: CREATIVE_TTL
213
- }
214
-
215
- ID_RESPONSE.buildAd(bid, bidRequest, bidObject);
216
-
217
- ID_RAZR.forwardBid({
218
- bidRequest,
219
- bid
220
- });
221
-
222
- bids.push(bid);
223
- });
224
- });
225
-
226
- return bids;
64
+ interpretResponse(serverResponse, { ortbRequest }) {
65
+ return CONVERTER.fromORTB({request: ortbRequest, response: serverResponse.body}).bids;
227
66
  },
228
67
 
229
68
  /**
@@ -241,6 +80,13 @@ export const spec = {
241
80
  const syncs = [];
242
81
  if ((this.syncStore.extendMode || !syncOptions.pixelEnabled) && syncOptions.iframeEnabled) {
243
82
  const { gdprApplies, consentString } = gdprConsent || {};
83
+ const bidders = new Set();
84
+ if (this.syncStore.extendMode && serverResponses) {
85
+ serverResponses.forEach(response => {
86
+ if (!response?.body?.ext?.responsetimemillis) return;
87
+ Object.keys(response.body.ext.responsetimemillis).forEach(b => bidders.add(b))
88
+ })
89
+ }
244
90
  syncs.push({
245
91
  type: 'iframe',
246
92
  url: IFRAME_SYNC_URL +
@@ -248,7 +94,8 @@ export const spec = {
248
94
  (this.syncStore.extendMode ? '&pbs=1' : '') +
249
95
  (typeof gdprApplies === 'boolean' ? `&gdpr=${Number(gdprApplies)}` : '') +
250
96
  (consentString ? `&gdpr_consent=${consentString}` : '') +
251
- (uspConsent ? `&us_privacy=${encodeURIComponent(uspConsent)}` : '')
97
+ (uspConsent ? `&us_privacy=${encodeURIComponent(uspConsent)}` : '') +
98
+ (bidders.size ? `&bidders=${[...bidders].join(',')}` : '')
252
99
  });
253
100
  } else if (syncOptions.pixelEnabled) {
254
101
  serverResponses.forEach(response => {
@@ -267,38 +114,191 @@ export const spec = {
267
114
 
268
115
  registerBidder(spec);
269
116
 
117
+ export const CONVERTER = ortbConverter({
118
+ context: {
119
+ ttl: CREATIVE_TTL,
120
+ nativeRequest: {
121
+ eventtrackers: [
122
+ {event: 1, methods: [1, 2]},
123
+ ]
124
+ }
125
+ },
126
+ imp(buildImp, bidRequest, context) {
127
+ const imp = buildImp(bidRequest, context);
128
+ imp.secure = Number(window.location.protocol === 'https:');
129
+ if (!imp.bidfloor && bidRequest.params.bidFloor) {
130
+ imp.bidfloor = bidRequest.params.bidFloor;
131
+ imp.bidfloorcur = getBidIdParameter('bidFloorCur', bidRequest.params).toUpperCase() || 'USD'
132
+ }
133
+ const bidderParamsPath = context.extendMode ? 'ext.prebid.bidder.improvedigital' : 'ext.bidder';
134
+ const placementId = bidRequest.params.placementId;
135
+ if (placementId) {
136
+ deepSetValue(imp, `${bidderParamsPath}.placementId`, placementId);
137
+ if (context.extendMode) {
138
+ deepSetValue(imp, 'ext.prebid.storedrequest.id', '' + placementId);
139
+ }
140
+ } else {
141
+ deepSetValue(imp, `${bidderParamsPath}.publisherId`, getBidIdParameter('publisherId', bidRequest.params));
142
+ deepSetValue(imp, `${bidderParamsPath}.placementKey`, getBidIdParameter('placementKey', bidRequest.params));
143
+ }
144
+ deepSetValue(imp, `${bidderParamsPath}.keyValues`, getBidIdParameter('keyValues', bidRequest.params) || undefined);
145
+
146
+ return imp;
147
+ },
148
+ request(buildRequest, imps, bidderRequest, context) {
149
+ const request = buildRequest(imps, bidderRequest, context);
150
+ mergeDeep(request, {
151
+ id: getUniqueIdentifierStr(),
152
+ source: {
153
+ // TODO: once https://github.com/prebid/Prebid.js/issues/8573 is resolved, this should be handled by the base ortbConverter logic
154
+ tid: context.bidRequests[0].transactionId,
155
+ },
156
+ ext: {
157
+ improvedigital: {
158
+ sdk: {
159
+ name: 'pbjs',
160
+ version: '$prebid.version$',
161
+ }
162
+ }
163
+ },
164
+ });
165
+ return request;
166
+ },
167
+ bidResponse(buildBidResponse, bid, context) {
168
+ if (!bid.adm || !bid.price || bid.hasOwnProperty('errorCode')) {
169
+ return;
170
+ }
171
+ const {bidRequest} = context;
172
+ context.mediaType = (() => {
173
+ const requestMediaTypes = Object.keys(bidRequest.mediaTypes);
174
+ if (requestMediaTypes.length === 1) return requestMediaTypes[0];
175
+ // Detect media type for multi-format response
176
+ if (bid.adm.search(/^(<\?xml|<vast)/i) !== -1) {
177
+ return VIDEO;
178
+ } else if (bid.adm[0] === '{') {
179
+ return NATIVE;
180
+ } else {
181
+ return BANNER;
182
+ }
183
+ })();
184
+ const bidResponse = buildBidResponse(bid, context);
185
+ const idExt = deepAccess(bid, `ext.${BIDDER_CODE}`, {});
186
+ Object.assign(bidResponse, {
187
+ dealId: (typeof idExt.buying_type === 'string' && idExt.buying_type !== 'rtb') ? idExt.line_item_id : undefined,
188
+ netRevenue: idExt.is_net || false,
189
+ })
190
+ if (bidResponse.mediaType === VIDEO && ID_REQUEST.isOutstreamVideo(bidRequest)) {
191
+ Object.assign(bidResponse, {
192
+ adResponse: { content: bidResponse.vastXml },
193
+ renderer: ID_OUTSTREAM.createRenderer(bidRequest)
194
+ })
195
+ }
196
+ ID_RAZR.forwardBid({bidRequest, bid: bidResponse});
197
+ return bidResponse;
198
+ },
199
+ overrides: {
200
+ imp: {
201
+ banner(fillImpBanner, imp, bidRequest, context) {
202
+ // override to disregard banner.sizes if usePrebidSizes is not set
203
+ if (!bidRequest.mediaTypes[BANNER]) return;
204
+ if (config.getConfig('improvedigital.usePrebidSizes') !== true) {
205
+ const banner = Object.assign({}, bidRequest.mediaTypes[BANNER], {sizes: null});
206
+ bidRequest = {...bidRequest, mediaTypes: {[BANNER]: banner}}
207
+ }
208
+ fillImpBanner(imp, bidRequest, context);
209
+ },
210
+ video(fillImpVideo, imp, bidRequest, context) {
211
+ // override to use video params from both mediaTypes.video and bidRequest.params.video
212
+ if (!bidRequest.mediaTypes[VIDEO]) return;
213
+ const video = Object.assign(
214
+ {mimes: VIDEO_PARAMS.DEFAULT_MIMES},
215
+ bidRequest.mediaTypes[VIDEO],
216
+ bidRequest.params?.video
217
+ )
218
+ fillImpVideo(
219
+ imp,
220
+ {...bidRequest, mediaTypes: {[VIDEO]: video}},
221
+ context
222
+ );
223
+ deepSetValue(imp, 'ext.is_rewarded_inventory', (video.rewarded === 1 || deepAccess(video, 'ext.rewarded') === 1) || undefined);
224
+ if (!imp.video.placement && ID_REQUEST.isOutstreamVideo(bidRequest)) {
225
+ // fillImpVideo will have already set placement = 1 for instream
226
+ imp.video.placement = VIDEO_PARAMS.PLACEMENT_TYPE.OUTSTREAM;
227
+ }
228
+ }
229
+ },
230
+ request: {
231
+ gdprAddtlConsent(setAddtlConsent, ortbRequest, bidderRequest) {
232
+ const additionalConsent = bidderRequest?.gdprConsent?.addtlConsent;
233
+ if (!additionalConsent) {
234
+ return;
235
+ }
236
+ if (spec.syncStore.extendMode) {
237
+ setAddtlConsent(ortbRequest, bidderRequest);
238
+ return;
239
+ }
240
+ if (additionalConsent && additionalConsent.indexOf('~') !== -1) {
241
+ // Google Ad Tech Provider IDs
242
+ const atpIds = additionalConsent.substring(additionalConsent.indexOf('~') + 1);
243
+ if (atpIds) {
244
+ deepSetValue(
245
+ ortbRequest,
246
+ 'user.ext.consented_providers_settings.consented_providers',
247
+ atpIds.split('.').map(id => parseInt(id, 10))
248
+ );
249
+ }
250
+ }
251
+ }
252
+ }
253
+ }
254
+ })
255
+
270
256
  const ID_REQUEST = {
271
- buildServerRequests(basicRequest, bidRequests, bidderRequest) {
257
+ buildServerRequests(bidRequests, bidderRequest) {
272
258
  const globalExtendMode = config.getConfig('improvedigital.extend') === true;
273
259
  const requests = [];
274
260
  const singleRequestMode = config.getConfig('improvedigital.singleRequest') === true;
275
261
 
276
- const extendImps = [];
277
- const adServerImps = [];
262
+ const extendBids = [];
263
+ const adServerBids = [];
278
264
 
279
- function formatRequest(imps, transactionId, extendMode) {
280
- const request = deepClone(basicRequest);
281
- request.imp = imps;
282
- request.id = getUniqueIdentifierStr();
283
- if (transactionId) {
284
- deepSetValue(request, 'source.tid', transactionId);
265
+ function adServerUrl(extendMode, publisherId) {
266
+ if (extendMode) {
267
+ return EXTEND_URL;
285
268
  }
286
- const adServerUrl = hasPurpose1Consent(bidderRequest?.gdprConsent) ? AD_SERVER_URL : BASIC_ADS_URL;
269
+ const urlSegments = [];
270
+ urlSegments.push(hasPurpose1Consent(bidderRequest?.gdprConsent) ? AD_SERVER_BASE_URL : BASIC_ADS_BASE_URL)
271
+ if (publisherId) {
272
+ urlSegments.push(publisherId)
273
+ }
274
+ urlSegments.push(PB_ENDPOINT)
275
+ return urlSegments.join('/');
276
+ }
277
+
278
+ function formatRequest(bidRequests, publisherId, extendMode) {
279
+ const ortbRequest = CONVERTER.toORTB({bidRequests, bidderRequest, context: {extendMode}});
287
280
  return {
288
281
  method: 'POST',
289
- url: extendMode ? EXTEND_URL : adServerUrl,
290
- data: JSON.stringify(request),
282
+ url: adServerUrl(extendMode, publisherId),
283
+ data: JSON.stringify(ortbRequest),
284
+ ortbRequest,
291
285
  bidderRequest
292
286
  }
293
- };
287
+ }
294
288
 
289
+ let publisherId = null;
295
290
  bidRequests.map((bidRequest) => {
291
+ const bidParamsPublisherId = bidRequest.params.publisherId;
296
292
  const extendModeEnabled = this.isExtendModeEnabled(globalExtendMode, bidRequest.params);
297
- const imp = this.buildImp(bidRequest, extendModeEnabled);
298
293
  if (singleRequestMode) {
299
- extendModeEnabled ? extendImps.push(imp) : adServerImps.push(imp);
294
+ if (!publisherId) {
295
+ publisherId = bidParamsPublisherId;
296
+ } else if (bidParamsPublisherId && publisherId !== bidParamsPublisherId) {
297
+ throw new Error(`All Improve Digital placements in a single call must have the same publisherId. Please check your 'params.publisherId' or turn off the single request mode.`);
298
+ }
299
+ extendModeEnabled ? extendBids.push(bidRequest) : adServerBids.push(bidRequest);
300
300
  } else {
301
- requests.push(formatRequest([imp], bidRequest.transactionId, extendModeEnabled));
301
+ requests.push(formatRequest([bidRequest], bidParamsPublisherId, extendModeEnabled));
302
302
  }
303
303
  });
304
304
 
@@ -306,11 +306,11 @@ const ID_REQUEST = {
306
306
  return requests;
307
307
  }
308
308
  // In the single request mode, split imps between those going to the ad server and those going to extend server
309
- if (extendImps.length) {
310
- requests.push(formatRequest(extendImps, bidderRequest.auctionId, true));
309
+ if (extendBids.length) {
310
+ requests.push(formatRequest(extendBids, publisherId, true));
311
311
  }
312
- if (adServerImps.length) {
313
- requests.push(formatRequest(adServerImps, bidderRequest.auctionId, false));
312
+ if (adServerBids.length) {
313
+ requests.push(formatRequest(adServerBids, publisherId, false));
314
314
  }
315
315
 
316
316
  return requests;
@@ -324,289 +324,10 @@ const ID_REQUEST = {
324
324
  return extendMode;
325
325
  },
326
326
 
327
- buildImp(bidRequest, extendMode) {
328
- const imp = {
329
- id: getBidIdParameter('bidId', bidRequest) || getUniqueIdentifierStr(),
330
- secure: Number(window.location.protocol === 'https:'),
331
- };
332
-
333
- // Floor
334
- const bidFloor = this.getBidFloor(bidRequest) || getBidIdParameter('bidFloor', bidRequest.params);
335
- if (bidFloor) {
336
- const bidFloorCur = getBidIdParameter('bidFloorCur', bidRequest.params) || 'USD';
337
- deepSetValue(imp, 'bidfloor', bidFloor);
338
- deepSetValue(imp, 'bidfloorcur', bidFloorCur ? bidFloorCur.toUpperCase() : undefined);
339
- }
340
-
341
- const bidderParamsPath = extendMode ? 'ext.prebid.bidder.improvedigital' : 'ext.bidder';
342
- const placementId = getBidIdParameter('placementId', bidRequest.params);
343
- if (placementId) {
344
- deepSetValue(imp, `${bidderParamsPath}.placementId`, placementId);
345
- if (extendMode) {
346
- deepSetValue(imp, 'ext.prebid.storedrequest.id', '' + placementId);
347
- }
348
- } else {
349
- deepSetValue(imp, `${bidderParamsPath}.publisherId`, getBidIdParameter('publisherId', bidRequest.params));
350
- deepSetValue(imp, `${bidderParamsPath}.placementKey`, getBidIdParameter('placementKey', bidRequest.params));
351
- }
352
-
353
- deepSetValue(imp, `${bidderParamsPath}.keyValues`, getBidIdParameter('keyValues', bidRequest.params) || undefined);
354
-
355
- // Adding GPID
356
- const gpid = deepAccess(bidRequest, 'ortb2Imp.ext.gpid') ||
357
- deepAccess(bidRequest, 'ortb2Imp.ext.data.pbadslot') ||
358
- deepAccess(bidRequest, 'ortb2Imp.ext.data.adserver.adslot');
359
-
360
- deepSetValue(imp, 'ext.gpid', gpid);
361
-
362
- // Adding Interstitial Signal
363
- if (deepAccess(bidRequest, 'ortb2Imp.instl')) {
364
- imp.instl = 1;
365
- }
366
-
367
- const videoParams = deepAccess(bidRequest, 'mediaTypes.video');
368
- if (videoParams) {
369
- imp.video = this.buildVideoRequest(bidRequest);
370
- deepSetValue(imp, 'ext.is_rewarded_inventory', (videoParams.rewarded === 1 || deepAccess(videoParams, 'ext.rewarded') === 1) || undefined);
371
- }
372
-
373
- if (deepAccess(bidRequest, 'mediaTypes.banner')) {
374
- imp.banner = this.buildBannerRequest(bidRequest);
375
- }
376
-
377
- if (deepAccess(bidRequest, 'mediaTypes.native')) {
378
- const nativeImp = this.buildNativeRequest(bidRequest);
379
- if (nativeImp) {
380
- imp.native = nativeImp;
381
- }
382
- }
383
-
384
- return imp;
385
- },
386
-
387
- buildVideoRequest(bidRequest) {
388
- const videoParams = deepClone(bidRequest.mediaTypes.video);
389
- const videoImproveParams = deepClone(deepAccess(bidRequest, 'params.video', {}));
390
- const video = {...videoParams, ...videoImproveParams};
391
-
392
- if (Array.isArray(video.playerSize)) {
393
- // Player size can be defined as [w, h] or [[w, h]]
394
- const size = Array.isArray(video.playerSize[0]) ? video.playerSize[0] : video.playerSize;
395
- video.w = size[0];
396
- video.h = size[1];
397
- }
398
- video.placement = this.isOutstreamVideo(bidRequest) ? VIDEO_PARAMS.PLACEMENT_TYPE.OUTSTREAM : VIDEO_PARAMS.PLACEMENT_TYPE.INSTREAM;
399
-
400
- // Mimes is required
401
- if (!video.mimes) {
402
- video.mimes = VIDEO_PARAMS.DEFAULT_MIMES;
403
- }
404
-
405
- // skip must be 0 or 1
406
- if (video.skip !== 1) {
407
- delete video.skipmin;
408
- delete video.skipafter;
409
- if (video.skip !== 0) {
410
- logWarn(`video.skip: invalid value '${video.skip}'. Expected 0 or 1`);
411
- delete video.skip;
412
- }
413
- }
414
-
415
- Object.keys(video).forEach(prop => {
416
- if (VIDEO_PARAMS.SUPPORTED_PROPERTIES.indexOf(prop) === -1) delete video[prop];
417
- });
418
- return video;
419
- },
420
-
421
- buildBannerRequest(bidRequest) {
422
- // Set the desired creative sizes
423
- // Input Format: array of pairs, i.e. [[300, 250], [250, 250]]
424
- // Unless improvedigital.usePrebidSizes == true, no sizes are sent to the server
425
- // and the sizes defined in the server for the placement will be used
426
- const banner = {};
427
- if (config.getConfig('improvedigital.usePrebidSizes') === true && bidRequest.sizes) {
428
- // Convert sizes from [x, y] to { w: x, h: y}
429
- banner.format = bidRequest.sizes.map(sizePair => ({w: sizePair[0], h: sizePair[1]}));
430
- }
431
- return banner;
432
- },
433
-
434
- buildNativeRequest(bidRequest) {
435
- const nativeParams = bidRequest.nativeParams;
436
- if (!nativeParams) {
437
- return null;
438
- }
439
- const request = {
440
- eventtrackers: [
441
- {event: 1, methods: [1, 2]}
442
- ],
443
- assets: [],
444
- }
445
- for (let i of Object.keys(nativeParams)) {
446
- const assetOrtbParams = NATIVE_DATA.ASSETS[i];
447
- if (assetOrtbParams) {
448
- const assetParams = nativeParams[i];
449
- const asset = {
450
- id: assetOrtbParams.id,
451
- required: Number(assetParams.required),
452
- };
453
- switch (assetOrtbParams.assetType) {
454
- case NATIVE_DATA.ASSET_TYPES.TITLE:
455
- asset.title = {len: assetParams.len || assetOrtbParams.default.len};
456
- break;
457
- case NATIVE_DATA.ASSET_TYPES.DATA:
458
- asset.data = cleanObj({type: assetOrtbParams.type, len: assetParams.len})
459
- break;
460
- case NATIVE_DATA.ASSET_TYPES.IMG:
461
- asset.img = cleanObj({
462
- type: assetOrtbParams.type,
463
- w: deepAccess(assetParams, 'sizes.0'),
464
- h: deepAccess(assetParams, 'sizes.1'),
465
- wmin: deepAccess(assetParams, 'aspect_ratios.0.min_width'),
466
- hmin: deepAccess(assetParams, 'aspect_ratios.0.min_height')
467
- });
468
- break;
469
- default:
470
- return;
471
- }
472
- request.assets.push(asset);
473
- }
474
- }
475
- if (!request.assets.length) {
476
- logWarn('No native assets recognized. Ignoring native ad request');
477
- return null;
478
- }
479
- return { ver: NATIVE_DATA.VERSION, request: JSON.stringify(request) };
480
- },
481
-
482
327
  isOutstreamVideo(bidRequest) {
483
328
  return deepAccess(bidRequest, 'mediaTypes.video.context') === 'outstream';
484
329
  },
485
330
 
486
- getBidFloor(bidRequest) {
487
- if (!isFn(bidRequest.getFloor)) {
488
- return null;
489
- }
490
- const floor = bidRequest.getFloor({
491
- currency: 'USD',
492
- mediaType: '*',
493
- size: '*'
494
- });
495
- if (isPlainObject(floor) && !isNaN(floor.floor) && floor.currency === 'USD') {
496
- return floor.floor;
497
- }
498
- return null;
499
- },
500
-
501
- buildSiteOrApp(request, bidderRequest) {
502
- const app = {};
503
- const configAppSettings = config.getConfig('app') || {};
504
- const fpdAppSettings = bidderRequest.ortb2?.app || {};
505
- mergeDeep(app, configAppSettings, fpdAppSettings);
506
-
507
- if (Object.keys(app).length !== 0) {
508
- request.app = app;
509
- } else {
510
- const site = {};
511
- const url = deepAccess(bidderRequest, 'refererInfo.page');
512
- if (url) {
513
- site.page = url;
514
- site.domain = bidderRequest.refererInfo.domain;
515
- }
516
- const configSiteSettings = config.getConfig('site') || {};
517
- const fpdSiteSettings = deepAccess(bidderRequest, 'ortb2.site') || {};
518
- mergeDeep(site, configSiteSettings, fpdSiteSettings);
519
- request.site = site;
520
- }
521
- },
522
- };
523
-
524
- const ID_RESPONSE = {
525
- buildAd(bid, bidRequest, bidResponse) {
526
- if (bidRequest.mediaTypes && Object.keys(bidRequest.mediaTypes).length === 1) {
527
- if (deepAccess(bidRequest, 'mediaTypes.video')) {
528
- this.buildVideoAd(bid, bidRequest, bidResponse);
529
- } else if (deepAccess(bidRequest, 'mediaTypes.banner')) {
530
- this.buildBannerAd(bid, bidRequest, bidResponse);
531
- } else if (deepAccess(bidRequest, 'mediaTypes.native')) {
532
- this.buildNativeAd(bid, bidRequest, bidResponse)
533
- }
534
- } else {
535
- // Detect media type for multi-format response
536
- if (bidResponse.adm.search(/^(<\?xml|<vast)/i) !== -1) {
537
- this.buildVideoAd(bid, bidRequest, bidResponse);
538
- } else if (bidResponse.adm[0] === '{') {
539
- this.buildNativeAd(bid, bidRequest, bidResponse);
540
- } else {
541
- this.buildBannerAd(bid, bidRequest, bidResponse);
542
- }
543
- }
544
- },
545
-
546
- buildVideoAd(bid, bidRequest, bidResponse) {
547
- bid.mediaType = VIDEO;
548
- bid.vastXml = bidResponse.adm;
549
- if (ID_REQUEST.isOutstreamVideo(bidRequest)) {
550
- bid.adResponse = { content: bid.vastXml };
551
- bid.renderer = ID_OUTSTREAM.createRenderer(bidRequest);
552
- }
553
- },
554
-
555
- buildBannerAd(bid, bidRequest, bidResponse) {
556
- bid.mediaType = BANNER;
557
- bid.ad = bidResponse.adm;
558
- bid.width = bidResponse.w;
559
- bid.height = bidResponse.h;
560
- },
561
-
562
- buildNativeAd(bid, bidRequest, bidResponse) {
563
- bid.mediaType = NATIVE;
564
- const nativeResponse = JSON.parse(bidResponse.adm);
565
- const nativeAd = {
566
- clickUrl: deepAccess(nativeResponse, 'link.url'),
567
- clickTrackers: deepAccess(nativeResponse, 'link.clicktrackers'),
568
- privacyLink: nativeResponse.privacy
569
- }
570
- // Trackers
571
- if (nativeResponse.eventtrackers) {
572
- nativeAd.impressionTrackers = [];
573
- nativeResponse.eventtrackers.forEach(tracker => {
574
- // Only handle impression event. Viewability events are not supported yet.
575
- if (tracker.event !== 1) return;
576
- switch (tracker.method) {
577
- case 1: // img
578
- nativeAd.impressionTrackers.push(tracker.url);
579
- break;
580
- case 2: // js
581
- // javascriptTrackers is a string. If there's more than one JS tracker in bid response, the last script will be used.
582
- nativeAd.javascriptTrackers = `<script src=\"${tracker.url}\"></script>`;
583
- break;
584
- }
585
- });
586
- } else {
587
- nativeAd.impressionTrackers = nativeResponse.imptrackers || [];
588
- nativeAd.javascriptTrackers = nativeResponse.jstracker;
589
- }
590
- nativeResponse.assets.map(asset => {
591
- const assetParams = NATIVE_DATA.getAssetById(asset.id);
592
- switch (assetParams.assetType) {
593
- case NATIVE_DATA.ASSET_TYPES.TITLE:
594
- nativeAd.title = asset.title.text;
595
- break;
596
- case NATIVE_DATA.ASSET_TYPES.DATA:
597
- nativeAd[assetParams.name] = asset.data.value;
598
- break;
599
- case NATIVE_DATA.ASSET_TYPES.IMG:
600
- nativeAd[assetParams.name] = {
601
- url: asset.img.url,
602
- width: asset.img.w,
603
- height: asset.img.h,
604
- };
605
- break;
606
- }
607
- });
608
- bid.native = nativeAd;
609
- },
610
331
  };
611
332
 
612
333
  const ID_OUTSTREAM = {