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.
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/aaxBlockmeterRtdProvider.js +1 -0
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/admaticBidAdapter.js +1 -0
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adtrgtmeBidAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/adyoulikeBidAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/analyticsAdapter.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/audiencerunBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/bidViewability.js +1 -1
- package/dist/bidViewabilityIO.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bluebillywigBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/browsiRtdProvider.js +1 -1
- package/dist/carodaBidAdapter.js +1 -1
- package/dist/chtnwBidAdapter.js +1 -0
- package/dist/cleanioRtdProvider.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectIdSystem.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consentManagement.js +1 -1
- package/dist/consentManagementUsp.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/currency.js +1 -1
- package/dist/dependencies.json +19 -0
- package/dist/dfpAdServerVideo.js +1 -1
- package/dist/dgkeywordRtdProvider.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/gdprEnforcement.js +1 -1
- package/dist/glimpseBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/googleAnalyticsAdapter.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gridNMBidAdapter.js +1 -1
- package/dist/growthCodeIdSystem.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/id5AnalyticsAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/impactifyBidAdapter.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/inmarBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/instreamTracking.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/jixieBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/jwplayerVideoProvider.js +1 -0
- package/dist/kargoBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/kueezRtbBidAdapter.js +1 -0
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/lifestreetBidAdapter.js +1 -1
- package/dist/liveyieldAnalyticsAdapter.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/magniteAnalyticsAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/mediakeysBidAdapter.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/mgidRtdProvider.js +1 -0
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/multibid.js +1 -1
- package/dist/not-for-prod/prebid.js +153 -141
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/openxOrtbBidAdapter.js +1 -1
- package/dist/ortbConverter.js +1 -0
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/oxxionRtdProvider.js +1 -0
- package/dist/parrableIdSystem.js +1 -1
- package/dist/pbsExtensions.js +1 -0
- package/dist/permutiveRtdProvider.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +1 -1
- package/dist/prebidServerBidAdapter.js +1 -1
- package/dist/priceFloors.js +1 -1
- package/dist/pubCommonId.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseBidAdapter.js +1 -1
- package/dist/rtdModule.js +1 -1
- package/dist/rubiconAnalyticsAdapter.js +1 -1
- package/dist/rubiconBidAdapter.js +1 -1
- package/dist/schain.js +1 -1
- package/dist/seedingAllianceBidAdapter.js +1 -1
- package/dist/seedtagBidAdapter.js +1 -1
- package/dist/sharethroughAnalyticsAdapter.js +1 -1
- package/dist/sharethroughBidAdapter.js +1 -1
- package/dist/shinezBidAdapter.js +1 -1
- package/dist/smaatoBidAdapter.js +1 -1
- package/dist/smartadserverBidAdapter.js +1 -1
- package/dist/smartxBidAdapter.js +1 -1
- package/dist/smilewantedBidAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnAnalyticsAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/spotxBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/synacormediaBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/teadsIdSystem.js +1 -1
- package/dist/trionBidAdapter.js +1 -1
- package/dist/tripleliftBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.js +1 -1
- package/dist/underdogmediaBidAdapter.js +1 -1
- package/dist/undertoneBidAdapter.js +1 -1
- package/dist/userId.js +1 -1
- package/dist/vidazooBidAdapter.js +1 -1
- package/dist/video.js +1 -0
- package/dist/videoModule.js +1 -0
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/videojsVideoProvider.js +1 -0
- package/dist/visxBidAdapter.js +1 -1
- package/dist/vuukleBidAdapter.js +1 -1
- package/dist/widespaceBidAdapter.js +1 -1
- package/dist/winrBidAdapter.js +1 -1
- package/dist/yahoosspBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/integrationExamples/gpt/mgidRtdProvider_example.html +143 -0
- package/integrationExamples/videoModule/jwplayer/bidMarkedAsUsed.html +98 -0
- package/integrationExamples/videoModule/jwplayer/bidRequestScheduling.html +89 -0
- package/integrationExamples/videoModule/jwplayer/eventListeners.html +244 -0
- package/integrationExamples/videoModule/jwplayer/gamAdServerMediation.html +122 -0
- package/integrationExamples/videoModule/jwplayer/mediaMetadata.html +80 -0
- package/integrationExamples/videoModule/jwplayer/playlist.html +122 -0
- package/integrationExamples/videoModule/videojs/bidMarkedAsUsed.html +126 -0
- package/integrationExamples/videoModule/videojs/bidRequestScheduling.html +132 -0
- package/integrationExamples/videoModule/videojs/eventListeners.html +238 -0
- package/integrationExamples/videoModule/videojs/gamAdServerMediation.html +138 -0
- package/integrationExamples/videoModule/videojs/mediaMetadata.html +103 -0
- package/integrationExamples/videoModule/videojs/playlist.html +151 -0
- package/libraries/ortbConverter/README.md +378 -0
- package/libraries/ortbConverter/converter.js +135 -0
- package/libraries/ortbConverter/lib/composer.js +43 -0
- package/libraries/ortbConverter/lib/mergeProcessors.js +9 -0
- package/libraries/ortbConverter/lib/sizes.js +14 -0
- package/libraries/ortbConverter/processors/banner.js +40 -0
- package/libraries/ortbConverter/processors/default.js +167 -0
- package/libraries/ortbConverter/processors/mediaType.js +21 -0
- package/libraries/ortbConverter/processors/native.js +37 -0
- package/libraries/ortbConverter/processors/video.js +66 -0
- package/libraries/pbsExtensions/pbsExtensions.js +12 -0
- package/libraries/pbsExtensions/processors/aliases.js +17 -0
- package/libraries/pbsExtensions/processors/mediaType.js +23 -0
- package/libraries/pbsExtensions/processors/params.js +22 -0
- package/libraries/pbsExtensions/processors/pbs.js +99 -0
- package/libraries/pbsExtensions/processors/requestExtPrebid.js +30 -0
- package/libraries/pbsExtensions/processors/video.js +23 -0
- package/libraries/video/constants/enums.js +5 -0
- package/libraries/video/constants/events.js +97 -0
- package/libraries/video/constants/ortb.js +169 -0
- package/libraries/video/constants/vendorCodes.js +6 -0
- package/libraries/video/shared/eventHandler.js +18 -0
- package/libraries/video/shared/parentModule.js +82 -0
- package/libraries/video/shared/state.js +47 -0
- package/libraries/video/shared/vastXmlBuilder.js +77 -0
- package/libraries/video/shared/vastXmlEditor.js +115 -0
- package/modules/.submodules.json +7 -1
- package/modules/aaxBlockmeterRtdProvider.js +59 -0
- package/modules/aaxBlockmeterRtdProvider.md +48 -0
- package/modules/admaticBidAdapter.js +147 -0
- package/modules/admaticBidAdapter.md +48 -0
- package/modules/amxBidAdapter.js +1 -0
- package/modules/appnexusBidAdapter.js +38 -1
- package/modules/chtnwBidAdapter.js +110 -0
- package/modules/chtnwBidAdapter.md +31 -0
- package/modules/concertBidAdapter.js +44 -2
- package/modules/connectIdSystem.js +36 -23
- package/modules/connectIdSystem.md +3 -2
- package/modules/consentManagement.js +22 -1
- package/modules/consentManagementUsp.js +29 -7
- package/modules/criteoBidAdapter.js +25 -5
- package/modules/currency.js +9 -0
- package/modules/dgkeywordRtdProvider.js +3 -3
- package/modules/gridNMBidAdapter.js +10 -14
- package/modules/growthCodeIdSystem.js +9 -5
- package/modules/gumgumBidAdapter.js +4 -0
- package/modules/improvedigitalBidAdapter.js +191 -470
- package/modules/ixBidAdapter.js +54 -71
- package/modules/jwplayerVideoProvider.js +929 -0
- package/modules/jwplayerVideoProvider.md +25 -0
- package/modules/kargoBidAdapter.js +1 -1
- package/modules/kueezRtbBidAdapter.js +278 -0
- package/modules/kueezRtbBidAdapter.md +35 -0
- package/modules/magniteAnalyticsAdapter.js +6 -1
- package/modules/mgidRtdProvider.js +190 -0
- package/modules/mgidRtdProvider.md +51 -0
- package/modules/multibid/index.js +12 -0
- package/modules/openxOrtbBidAdapter.js +120 -275
- package/modules/oxxionRtdProvider.js +119 -0
- package/modules/oxxionRtdProvider.md +48 -0
- package/modules/permutiveRtdProvider.js +2 -1
- package/modules/permutiveRtdProvider.md +36 -1
- package/modules/prebidServerBidAdapter/index.js +19 -716
- package/modules/prebidServerBidAdapter/ortbConverter.js +274 -0
- package/modules/priceFloors.js +73 -1
- package/modules/pubmaticBidAdapter.js +21 -29
- package/modules/rtdModule/index.js +22 -1
- package/modules/schain.js +24 -1
- package/modules/spotxBidAdapter.js +16 -15
- package/modules/synacormediaBidAdapter.js +1 -1
- package/modules/teadsIdSystem.js +5 -0
- package/modules/tripleliftBidAdapter.js +1 -1
- package/modules/userId/eids.js +3 -10
- package/modules/userId/index.js +64 -6
- package/modules/videoModule/addingSubmodule.md +521 -0
- package/modules/videoModule/coreVideo.js +234 -0
- package/modules/videoModule/gamAdServerSubmodule.js +27 -0
- package/modules/videoModule/index.js +244 -0
- package/modules/videoModule/videoImpressionVerifier.js +206 -0
- package/modules/videojsVideoProvider.js +854 -0
- package/modules/videojsVideoProvider.md +17 -0
- package/package.json +12 -8
- package/src/adRendering.js +1 -1
- package/src/adapterManager.js +56 -7
- package/src/adloader.js +3 -1
- package/src/auction.js +6 -1
- package/src/events.js +5 -1
- package/src/pbjsORTB.js +35 -0
- package/src/prebid.js +137 -112
- package/src/targeting.js +10 -2
- package/src/utils/currency.js +16 -0
- package/src/utils.js +21 -0
- package/test/spec/auctionmanager_spec.js +15 -0
- package/test/spec/modules/aaxBlockmeter_spec.js +58 -0
- package/test/spec/modules/admaticBidAdapter_spec.js +46 -0
- package/test/spec/modules/chtnwBidAdapter_spec.js +105 -0
- package/test/spec/modules/concertBidAdapter_spec.js +56 -0
- package/test/spec/modules/connectIdSystem_spec.js +175 -5
- package/test/spec/modules/consentManagementUsp_spec.js +64 -18
- package/test/spec/modules/criteoBidAdapter_spec.js +28 -0
- package/test/spec/modules/dgkeywordRtdProvider_spec.js +3 -3
- package/test/spec/modules/eids_spec.js +10 -7
- package/test/spec/modules/ftrackIdSystem_spec.js +34 -22
- package/test/spec/modules/gumgumBidAdapter_spec.js +15 -0
- package/test/spec/modules/improvedigitalBidAdapter_spec.js +231 -211
- package/test/spec/modules/ixBidAdapter_spec.js +412 -350
- package/test/spec/modules/kueezRtbBidAdapter_spec.js +396 -0
- package/test/spec/modules/magniteAnalyticsAdapter_spec.js +26 -0
- package/test/spec/modules/mgidRtdProvider_spec.js +366 -0
- package/test/spec/modules/openxOrtbBidAdapter_spec.js +77 -49
- package/test/spec/modules/oxxionRtdProvider_spec.js +142 -0
- package/test/spec/modules/permutiveRtdProvider_spec.js +64 -5
- package/test/spec/modules/prebidServerBidAdapter_spec.js +139 -137
- package/test/spec/modules/realTimeDataModule_spec.js +65 -0
- package/test/spec/modules/tripleliftBidAdapter_spec.js +14 -0
- package/test/spec/modules/userId_spec.js +67 -1
- package/test/spec/modules/videoModule/coreVideo_spec.js +98 -0
- package/test/spec/modules/videoModule/pbVideo_spec.js +362 -0
- package/test/spec/modules/videoModule/shared/parentModule_spec.js +73 -0
- package/test/spec/modules/videoModule/shared/state_spec.js +26 -0
- package/test/spec/modules/videoModule/shared/vastXmlBuilder_spec.js +103 -0
- package/test/spec/modules/videoModule/shared/vastXmlEditor_spec.js +209 -0
- package/test/spec/modules/videoModule/submodules/jwplayerVideoProvider_spec.js +846 -0
- package/test/spec/modules/videoModule/submodules/videojsVideoProvider_spec.js +391 -0
- package/test/spec/modules/videoModule/videoImpressionVerifier_spec.js +112 -0
- package/test/spec/ortbConverter/banner_spec.js +203 -0
- package/test/spec/ortbConverter/composer_spec.js +69 -0
- package/test/spec/ortbConverter/converter_spec.js +283 -0
- package/test/spec/ortbConverter/currency_spec.js +40 -0
- package/test/spec/ortbConverter/default_processors_spec.js +61 -0
- package/test/spec/ortbConverter/gdpr_spec.js +38 -0
- package/test/spec/ortbConverter/mediaTypes_spec.js +67 -0
- package/test/spec/ortbConverter/mergeProcessors_spec.js +59 -0
- package/test/spec/ortbConverter/multibid_spec.js +35 -0
- package/test/spec/ortbConverter/native_spec.js +95 -0
- package/test/spec/ortbConverter/pbjsORTB_spec.js +67 -0
- package/test/spec/ortbConverter/pbsExtensions/aliases_spec.js +57 -0
- package/test/spec/ortbConverter/pbsExtensions/params_spec.js +96 -0
- package/test/spec/ortbConverter/pbsExtensions/video_spec.js +52 -0
- package/test/spec/ortbConverter/priceFloors_spec.js +143 -0
- package/test/spec/ortbConverter/schain_spec.js +33 -0
- package/test/spec/ortbConverter/userId_spec.js +21 -0
- package/test/spec/ortbConverter/usp_spec.js +15 -0
- package/test/spec/ortbConverter/video_spec.js +189 -0
- package/test/spec/unit/core/adapterManager_spec.js +102 -0
- package/test/spec/unit/core/targeting_spec.js +34 -0
- package/test/spec/unit/pbjs_api_spec.js +124 -45
- package/test/spec/utils_spec.js +45 -1
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
import Adapter from '../../src/adapter.js';
|
|
2
|
-
import {createBid} from '../../src/bidfactory.js';
|
|
3
2
|
import {
|
|
4
3
|
bind,
|
|
5
|
-
createTrackPixelHtml,
|
|
6
|
-
deepAccess,
|
|
7
4
|
deepClone,
|
|
8
|
-
deepSetValue,
|
|
9
5
|
flatten,
|
|
10
6
|
generateUUID,
|
|
11
|
-
getBidRequest,
|
|
12
|
-
getDefinedParams,
|
|
13
7
|
getPrebidInternal,
|
|
14
8
|
insertUserSyncIframe,
|
|
15
|
-
isArray,
|
|
16
|
-
isEmpty,
|
|
17
9
|
isNumber,
|
|
18
10
|
isPlainObject,
|
|
19
11
|
isStr,
|
|
@@ -21,34 +13,27 @@ import {
|
|
|
21
13
|
logInfo,
|
|
22
14
|
logMessage,
|
|
23
15
|
logWarn,
|
|
24
|
-
mergeDeep,
|
|
25
|
-
parseSizesInput,
|
|
26
|
-
timestamp,
|
|
27
16
|
triggerPixel,
|
|
28
|
-
uniques
|
|
17
|
+
uniques,
|
|
18
|
+
deepAccess,
|
|
29
19
|
} from '../../src/utils.js';
|
|
30
20
|
import CONSTANTS from '../../src/constants.json';
|
|
31
21
|
import adapterManager from '../../src/adapterManager.js';
|
|
32
22
|
import {config} from '../../src/config.js';
|
|
33
|
-
import {NATIVE, VIDEO} from '../../src/mediaTypes.js';
|
|
34
23
|
import {isValid} from '../../src/adapters/bidderFactory.js';
|
|
35
24
|
import * as events from '../../src/events.js';
|
|
36
|
-
import {
|
|
25
|
+
import {includes} from '../../src/polyfill.js';
|
|
37
26
|
import {S2S_VENDORS} from './config.js';
|
|
38
27
|
import {ajax} from '../../src/ajax.js';
|
|
39
28
|
import {hook} from '../../src/hook.js';
|
|
40
|
-
import {getGlobal} from '../../src/prebidGlobal.js';
|
|
41
29
|
import {hasPurpose1Consent} from '../../src/utils/gpdr.js';
|
|
30
|
+
import {buildPBSRequest, interpretPBSResponse} from './ortbConverter.js';
|
|
42
31
|
import {useMetrics} from '../../src/utils/perfMetrics.js';
|
|
43
32
|
|
|
44
33
|
const getConfig = config.getConfig;
|
|
45
34
|
|
|
46
35
|
const TYPE = CONSTANTS.S2S.SRC;
|
|
47
36
|
let _syncCount = 0;
|
|
48
|
-
const DEFAULT_S2S_TTL = 60;
|
|
49
|
-
const DEFAULT_S2S_CURRENCY = 'USD';
|
|
50
|
-
const DEFAULT_S2S_NETREVENUE = true;
|
|
51
|
-
|
|
52
37
|
let _s2sConfigs;
|
|
53
38
|
|
|
54
39
|
let eidPermissions;
|
|
@@ -95,12 +80,13 @@ let eidPermissions;
|
|
|
95
80
|
* @property {boolean} [cacheMarkup] whether to cache the adm result
|
|
96
81
|
* @property {string} [syncEndpoint] endpoint URL for syncing cookies
|
|
97
82
|
* @property {Object} [extPrebid] properties will be merged into request.ext.prebid
|
|
83
|
+
* @property {Object} [ortbNative] base value for imp.native.request
|
|
98
84
|
*/
|
|
99
85
|
|
|
100
86
|
/**
|
|
101
87
|
* @type {S2SDefaultConfig}
|
|
102
88
|
*/
|
|
103
|
-
const s2sDefaultConfig = {
|
|
89
|
+
export const s2sDefaultConfig = {
|
|
104
90
|
bidders: Object.freeze([]),
|
|
105
91
|
timeout: 1000,
|
|
106
92
|
syncTimeout: 1000,
|
|
@@ -108,7 +94,14 @@ const s2sDefaultConfig = {
|
|
|
108
94
|
adapter: 'prebidServer',
|
|
109
95
|
allowUnknownBidderCodes: false,
|
|
110
96
|
adapterOptions: {},
|
|
111
|
-
syncUrlModifier: {}
|
|
97
|
+
syncUrlModifier: {},
|
|
98
|
+
ortbNative: {
|
|
99
|
+
context: 1,
|
|
100
|
+
plcmttype: 1,
|
|
101
|
+
eventtrackers: [
|
|
102
|
+
{event: 1, methods: [1]}
|
|
103
|
+
],
|
|
104
|
+
}
|
|
112
105
|
};
|
|
113
106
|
|
|
114
107
|
config.setDefaults({
|
|
@@ -355,97 +348,6 @@ function doClientSideSyncs(bidders, gdprConsent, uspConsent) {
|
|
|
355
348
|
});
|
|
356
349
|
}
|
|
357
350
|
|
|
358
|
-
function _appendSiteAppDevice(request, pageUrl, accountId) {
|
|
359
|
-
if (!request) return;
|
|
360
|
-
|
|
361
|
-
// ORTB specifies app OR site
|
|
362
|
-
if (typeof config.getConfig('app') === 'object') {
|
|
363
|
-
request.app = config.getConfig('app');
|
|
364
|
-
request.app.publisher = {id: accountId};
|
|
365
|
-
} else {
|
|
366
|
-
request.site = {};
|
|
367
|
-
if (isPlainObject(config.getConfig('site'))) {
|
|
368
|
-
request.site = config.getConfig('site');
|
|
369
|
-
}
|
|
370
|
-
// set publisher.id if not already defined
|
|
371
|
-
if (!deepAccess(request.site, 'publisher.id')) {
|
|
372
|
-
deepSetValue(request.site, 'publisher.id', accountId);
|
|
373
|
-
}
|
|
374
|
-
// set site.page if not already defined
|
|
375
|
-
if (!request.site.page) {
|
|
376
|
-
request.site.page = pageUrl;
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
if (typeof config.getConfig('device') === 'object') {
|
|
380
|
-
request.device = config.getConfig('device');
|
|
381
|
-
}
|
|
382
|
-
if (!request.device) {
|
|
383
|
-
request.device = {};
|
|
384
|
-
}
|
|
385
|
-
if (!request.device.w) {
|
|
386
|
-
request.device.w = window.innerWidth;
|
|
387
|
-
}
|
|
388
|
-
if (!request.device.h) {
|
|
389
|
-
request.device.h = window.innerHeight;
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
function addBidderFirstPartyDataToRequest(request, bidderFpd) {
|
|
394
|
-
const fpdConfigs = Object.entries(bidderFpd).reduce((acc, [bidder, bidderOrtb2]) => {
|
|
395
|
-
const ortb2 = mergeDeep({}, bidderOrtb2);
|
|
396
|
-
acc.push({
|
|
397
|
-
bidders: [ bidder ],
|
|
398
|
-
config: { ortb2 }
|
|
399
|
-
});
|
|
400
|
-
return acc;
|
|
401
|
-
}, []);
|
|
402
|
-
|
|
403
|
-
if (fpdConfigs.length) {
|
|
404
|
-
deepSetValue(request, 'ext.prebid.bidderconfig', fpdConfigs);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
// https://iabtechlab.com/wp-content/uploads/2016/07/OpenRTB-Native-Ads-Specification-Final-1.2.pdf#page=40
|
|
409
|
-
let nativeDataNames = Object.keys(CONSTANTS.PREBID_NATIVE_DATA_KEYS_TO_ORTB);
|
|
410
|
-
|
|
411
|
-
// returns object with legacy asset name as key and asset id as value:
|
|
412
|
-
// { "sponsoredBy": 1, ... }
|
|
413
|
-
let nativeDataIdMap = nativeDataNames.reduce((prev, key) => {
|
|
414
|
-
prev[key] = CONSTANTS.NATIVE_ASSET_TYPES[CONSTANTS.PREBID_NATIVE_DATA_KEYS_TO_ORTB[key]];
|
|
415
|
-
return prev;
|
|
416
|
-
}, {});
|
|
417
|
-
|
|
418
|
-
let nativeImgIdMap = {
|
|
419
|
-
icon: 1,
|
|
420
|
-
image: 3
|
|
421
|
-
};
|
|
422
|
-
|
|
423
|
-
let nativeEventTrackerEventMap = {
|
|
424
|
-
impression: 1,
|
|
425
|
-
'viewable-mrc50': 2,
|
|
426
|
-
'viewable-mrc100': 3,
|
|
427
|
-
'viewable-video50': 4,
|
|
428
|
-
};
|
|
429
|
-
|
|
430
|
-
let nativeEventTrackerMethodMap = {
|
|
431
|
-
img: 1,
|
|
432
|
-
js: 2
|
|
433
|
-
};
|
|
434
|
-
|
|
435
|
-
if (FEATURES.NATIVE) {
|
|
436
|
-
// enable reverse lookup
|
|
437
|
-
[
|
|
438
|
-
nativeDataIdMap,
|
|
439
|
-
nativeImgIdMap,
|
|
440
|
-
nativeEventTrackerEventMap,
|
|
441
|
-
nativeEventTrackerMethodMap
|
|
442
|
-
].forEach(map => {
|
|
443
|
-
Object.keys(map).forEach(key => {
|
|
444
|
-
map[map[key]] = key;
|
|
445
|
-
});
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
|
|
449
351
|
/**
|
|
450
352
|
* map wurl to auction id and adId for use in the BID_WON event
|
|
451
353
|
*/
|
|
@@ -462,18 +364,6 @@ function addWurl(auctionId, adId, wurl) {
|
|
|
462
364
|
}
|
|
463
365
|
}
|
|
464
366
|
|
|
465
|
-
function getPbsResponseData(bidderRequests, response, pbsName, pbjsName) {
|
|
466
|
-
const bidderValues = deepAccess(response, `ext.${pbsName}`);
|
|
467
|
-
if (bidderValues) {
|
|
468
|
-
Object.keys(bidderValues).forEach(bidder => {
|
|
469
|
-
let biddersReq = find(bidderRequests, bidderReq => bidderReq.bidderCode === bidder);
|
|
470
|
-
if (biddersReq) {
|
|
471
|
-
biddersReq[pbjsName] = bidderValues[bidder];
|
|
472
|
-
}
|
|
473
|
-
});
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
|
|
477
367
|
/**
|
|
478
368
|
* @param {string} auctionId
|
|
479
369
|
* @param {string} adId generated value set to bidObject.adId by bidderFactory Bid()
|
|
@@ -501,595 +391,6 @@ export function resetWurlMap() {
|
|
|
501
391
|
wurlMap = {};
|
|
502
392
|
}
|
|
503
393
|
|
|
504
|
-
function ORTB2(s2sBidRequest, bidderRequests, adUnits, requestedBidders) {
|
|
505
|
-
this.s2sBidRequest = s2sBidRequest;
|
|
506
|
-
this.bidderRequests = bidderRequests;
|
|
507
|
-
this.adUnits = adUnits;
|
|
508
|
-
this.s2sConfig = s2sBidRequest.s2sConfig;
|
|
509
|
-
this.requestedBidders = requestedBidders;
|
|
510
|
-
|
|
511
|
-
this.bidIdMap = {};
|
|
512
|
-
this.adUnitsByImp = {};
|
|
513
|
-
this.impRequested = {};
|
|
514
|
-
this.auctionId = bidderRequests.map(br => br.auctionId).reduce((l, r) => (l == null || l === r) && r);
|
|
515
|
-
this.requestTimestamp = timestamp();
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
Object.assign(ORTB2.prototype, {
|
|
519
|
-
buildRequest() {
|
|
520
|
-
const {s2sBidRequest, bidderRequests: bidRequests, adUnits, s2sConfig, requestedBidders} = this;
|
|
521
|
-
|
|
522
|
-
let imps = [];
|
|
523
|
-
let aliases = {};
|
|
524
|
-
const firstBidRequest = bidRequests[0];
|
|
525
|
-
let floorMin = null;
|
|
526
|
-
let floorMinCur = null;
|
|
527
|
-
|
|
528
|
-
// transform ad unit into array of OpenRTB impression objects
|
|
529
|
-
let impIds = new Set();
|
|
530
|
-
adUnits.forEach(adUnit => {
|
|
531
|
-
// TODO: support labels / conditional bids
|
|
532
|
-
// for now, just warn about them
|
|
533
|
-
adUnit.bids.forEach((bid) => {
|
|
534
|
-
if (bid.mediaTypes != null) {
|
|
535
|
-
logWarn(`Prebid Server adapter does not (yet) support bidder-specific mediaTypes for the same adUnit. Size mapping configuration will be ignored for adUnit: ${adUnit.code}, bidder: ${bid.bidder}`);
|
|
536
|
-
}
|
|
537
|
-
});
|
|
538
|
-
|
|
539
|
-
// in case there is a duplicate imp.id, add '-2' suffix to the second imp.id.
|
|
540
|
-
// e.g. if there are 2 adUnits (case of twin adUnit codes) with code 'test',
|
|
541
|
-
// first imp will have id 'test' and second imp will have id 'test-2'
|
|
542
|
-
let impressionId = adUnit.code;
|
|
543
|
-
let i = 1;
|
|
544
|
-
while (impIds.has(impressionId)) {
|
|
545
|
-
i++;
|
|
546
|
-
impressionId = `${adUnit.code}-${i}`;
|
|
547
|
-
}
|
|
548
|
-
impIds.add(impressionId);
|
|
549
|
-
this.adUnitsByImp[impressionId] = adUnit;
|
|
550
|
-
|
|
551
|
-
const videoParams = deepAccess(adUnit, 'mediaTypes.video');
|
|
552
|
-
const bannerParams = deepAccess(adUnit, 'mediaTypes.banner');
|
|
553
|
-
|
|
554
|
-
adUnit.bids.forEach(bid => {
|
|
555
|
-
this.setBidRequestId(impressionId, bid.bidder, bid.bid_id);
|
|
556
|
-
// check for and store valid aliases to add to the request
|
|
557
|
-
if (adapterManager.aliasRegistry[bid.bidder]) {
|
|
558
|
-
const bidder = adapterManager.bidderRegistry[bid.bidder];
|
|
559
|
-
// adding alias only if alias source bidder exists and alias isn't configured to be standalone
|
|
560
|
-
// pbs adapter
|
|
561
|
-
if (!bidder || !bidder.getSpec().skipPbsAliasing) {
|
|
562
|
-
aliases[bid.bidder] = adapterManager.aliasRegistry[bid.bidder];
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
});
|
|
566
|
-
|
|
567
|
-
let mediaTypes = {};
|
|
568
|
-
if (bannerParams && bannerParams.sizes) {
|
|
569
|
-
const sizes = parseSizesInput(bannerParams.sizes);
|
|
570
|
-
|
|
571
|
-
// get banner sizes in form [{ w: <int>, h: <int> }, ...]
|
|
572
|
-
const format = sizes.map(size => {
|
|
573
|
-
const [ width, height ] = size.split('x');
|
|
574
|
-
const w = parseInt(width, 10);
|
|
575
|
-
const h = parseInt(height, 10);
|
|
576
|
-
return { w, h };
|
|
577
|
-
});
|
|
578
|
-
|
|
579
|
-
mediaTypes['banner'] = {format};
|
|
580
|
-
|
|
581
|
-
if (bannerParams.pos) mediaTypes['banner'].pos = bannerParams.pos;
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
if (!isEmpty(videoParams)) {
|
|
585
|
-
if (videoParams.context === 'outstream' && !videoParams.renderer && !adUnit.renderer) {
|
|
586
|
-
// Don't push oustream w/o renderer to request object.
|
|
587
|
-
logError('Outstream bid without renderer cannot be sent to Prebid Server.');
|
|
588
|
-
} else {
|
|
589
|
-
if (videoParams.context === 'instream' && !videoParams.hasOwnProperty('placement')) {
|
|
590
|
-
videoParams.placement = 1;
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
mediaTypes['video'] = Object.keys(videoParams).filter(param => param !== 'context')
|
|
594
|
-
.reduce((result, param) => {
|
|
595
|
-
if (param === 'playerSize') {
|
|
596
|
-
result.w = deepAccess(videoParams, `${param}.0.0`);
|
|
597
|
-
result.h = deepAccess(videoParams, `${param}.0.1`);
|
|
598
|
-
} else {
|
|
599
|
-
result[param] = videoParams[param];
|
|
600
|
-
}
|
|
601
|
-
return result;
|
|
602
|
-
}, {});
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
const nativeReq = deepAccess(adUnit, 'nativeOrtbRequest');
|
|
606
|
-
if (FEATURES.NATIVE && nativeReq) {
|
|
607
|
-
const defaultRequest = {
|
|
608
|
-
// TODO: determine best way to pass these and if we allow defaults
|
|
609
|
-
context: 1,
|
|
610
|
-
plcmttype: 1,
|
|
611
|
-
eventtrackers: [
|
|
612
|
-
{ event: 1, methods: [1] }
|
|
613
|
-
],
|
|
614
|
-
// TODO: figure out how to support privacy field
|
|
615
|
-
// privacy: int
|
|
616
|
-
};
|
|
617
|
-
try {
|
|
618
|
-
const request = Object.assign(defaultRequest, nativeReq);
|
|
619
|
-
mediaTypes[NATIVE] = {
|
|
620
|
-
request: JSON.stringify(request),
|
|
621
|
-
ver: '1.2'
|
|
622
|
-
};
|
|
623
|
-
} catch (e) {
|
|
624
|
-
logError('error creating native request: ' + String(e));
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
// get bidder params in form { <bidder code>: {...params} }
|
|
629
|
-
// initialize reduce function with the user defined `ext` properties on the ad unit
|
|
630
|
-
const ext = adUnit.bids.reduce((acc, bid) => {
|
|
631
|
-
if (bid.bidder == null) return acc;
|
|
632
|
-
const adapter = adapterManager.bidderRegistry[bid.bidder];
|
|
633
|
-
if (adapter && adapter.getSpec().transformBidParams) {
|
|
634
|
-
bid.params = adapter.getSpec().transformBidParams(bid.params, true, adUnit, bidRequests);
|
|
635
|
-
}
|
|
636
|
-
deepSetValue(acc,
|
|
637
|
-
`prebid.bidder.${bid.bidder}`,
|
|
638
|
-
(s2sConfig.adapterOptions && s2sConfig.adapterOptions[bid.bidder]) ? Object.assign({}, bid.params, s2sConfig.adapterOptions[bid.bidder]) : bid.params
|
|
639
|
-
);
|
|
640
|
-
return acc;
|
|
641
|
-
}, {...deepAccess(adUnit, 'ortb2Imp.ext')});
|
|
642
|
-
|
|
643
|
-
const imp = { ...adUnit.ortb2Imp, id: impressionId, ext, secure: s2sConfig.secure };
|
|
644
|
-
|
|
645
|
-
const ortb2 = {...deepAccess(adUnit, 'ortb2Imp.ext.data')};
|
|
646
|
-
Object.keys(ortb2).forEach(prop => {
|
|
647
|
-
/**
|
|
648
|
-
* Prebid AdSlot
|
|
649
|
-
* @type {(string|undefined)}
|
|
650
|
-
*/
|
|
651
|
-
if (prop === 'pbadslot') {
|
|
652
|
-
if (typeof ortb2[prop] === 'string' && ortb2[prop]) {
|
|
653
|
-
deepSetValue(imp, 'ext.data.pbadslot', ortb2[prop]);
|
|
654
|
-
} else {
|
|
655
|
-
// remove pbadslot property if it doesn't meet the spec
|
|
656
|
-
delete imp.ext.data.pbadslot;
|
|
657
|
-
}
|
|
658
|
-
} else if (prop === 'adserver') {
|
|
659
|
-
/**
|
|
660
|
-
* Copy GAM AdUnit and Name to imp
|
|
661
|
-
*/
|
|
662
|
-
['name', 'adslot'].forEach(name => {
|
|
663
|
-
/** @type {(string|undefined)} */
|
|
664
|
-
const value = deepAccess(ortb2, `adserver.${name}`);
|
|
665
|
-
if (typeof value === 'string' && value) {
|
|
666
|
-
deepSetValue(imp, `ext.data.adserver.${name.toLowerCase()}`, value);
|
|
667
|
-
}
|
|
668
|
-
});
|
|
669
|
-
} else {
|
|
670
|
-
deepSetValue(imp, `ext.data.${prop}`, ortb2[prop]);
|
|
671
|
-
}
|
|
672
|
-
});
|
|
673
|
-
|
|
674
|
-
mergeDeep(imp, mediaTypes);
|
|
675
|
-
|
|
676
|
-
const convertCurrency = typeof getGlobal().convertCurrency !== 'function'
|
|
677
|
-
? (amount) => amount
|
|
678
|
-
: (amount, from, to) => {
|
|
679
|
-
if (from === to) return amount;
|
|
680
|
-
let result = null;
|
|
681
|
-
try {
|
|
682
|
-
result = getGlobal().convertCurrency(amount, from, to);
|
|
683
|
-
} catch (e) {
|
|
684
|
-
}
|
|
685
|
-
return result;
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
const floor = (() => {
|
|
689
|
-
// we have to pick a floor for the imp - here we attempt to find the minimum floor
|
|
690
|
-
// across all bids for this adUnit
|
|
691
|
-
const s2sCurrency = config.getConfig('currency.adServerCurrency') || DEFAULT_S2S_CURRENCY;
|
|
692
|
-
|
|
693
|
-
return adUnit.bids
|
|
694
|
-
.map((bid) => this.getBidRequest(imp.id, bid.bidder))
|
|
695
|
-
.map((bid) => {
|
|
696
|
-
if (!bid || typeof bid.getFloor !== 'function') return;
|
|
697
|
-
try {
|
|
698
|
-
const {currency, floor} = bid.getFloor({
|
|
699
|
-
currency: s2sCurrency
|
|
700
|
-
});
|
|
701
|
-
|
|
702
|
-
return {
|
|
703
|
-
currency,
|
|
704
|
-
floor: parseFloat(floor)
|
|
705
|
-
}
|
|
706
|
-
} catch (e) {
|
|
707
|
-
logError('PBS: getFloor threw an error: ', e);
|
|
708
|
-
}
|
|
709
|
-
})
|
|
710
|
-
.reduce((min, floor) => {
|
|
711
|
-
// if any bid does not have a valid floor, do not attempt to send any to PBS
|
|
712
|
-
if (floor == null || floor.currency == null || floor.floor == null || isNaN(floor.floor)) {
|
|
713
|
-
min.min = null;
|
|
714
|
-
}
|
|
715
|
-
if (min.min === null) {
|
|
716
|
-
return min;
|
|
717
|
-
}
|
|
718
|
-
// otherwise, pick the minimum one (or, in some strange confluence of circumstances, the one in the best currency)
|
|
719
|
-
if (min.ref == null) {
|
|
720
|
-
min.ref = min.min = floor;
|
|
721
|
-
} else {
|
|
722
|
-
const value = convertCurrency(floor.floor, floor.currency, min.ref.currency);
|
|
723
|
-
|
|
724
|
-
if (value != null && value < min.ref.floor) {
|
|
725
|
-
min.ref.floor = value;
|
|
726
|
-
min.min = floor;
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
return min;
|
|
731
|
-
}, {}).min
|
|
732
|
-
})();
|
|
733
|
-
|
|
734
|
-
if (floor) {
|
|
735
|
-
imp.bidfloor = floor.floor;
|
|
736
|
-
imp.bidfloorcur = floor.currency;
|
|
737
|
-
|
|
738
|
-
// logic below relates to https://github.com/prebid/Prebid.js/issues/8749 and does the following:
|
|
739
|
-
// 1. check client-side floors (ref bidfloor/bidfloorcur & ortb2Imp floorMin/floorMinCur (if present))
|
|
740
|
-
// 2. set pbs req wide floorMinCur to the first floor currency found when iterating over imp's
|
|
741
|
-
// (if currency conversion logic present, convert all imp floor values to this currency)
|
|
742
|
-
// 3. compare/store ref to lowest floorMin value as each imp is iterated over
|
|
743
|
-
// 4. set req wide floorMin and floorMinCur values for pbs after iterations are done
|
|
744
|
-
if (floorMinCur == null) { floorMinCur = floor.currency }
|
|
745
|
-
const ortb2ImpFloorMin = imp.ext?.prebid?.floors?.floorMin || imp.ext?.prebid?.floorMin;
|
|
746
|
-
const ortb2ImpFloorCur = imp.ext?.prebid?.floors?.floorMinCur || imp.ext?.prebid?.floorMinCur || floorMinCur;
|
|
747
|
-
|
|
748
|
-
const convertedFloorMinValue = convertCurrency(floor.floor, floor.currency, floorMinCur);
|
|
749
|
-
const convertedOrtb2ImpFloorMinValue = ortb2ImpFloorMin && ortb2ImpFloorCur ? convertCurrency(ortb2ImpFloorMin, ortb2ImpFloorCur, floorMinCur) : false;
|
|
750
|
-
|
|
751
|
-
const lowestImpFloorMin = convertedOrtb2ImpFloorMinValue && convertedOrtb2ImpFloorMinValue < convertedFloorMinValue
|
|
752
|
-
? convertedOrtb2ImpFloorMinValue
|
|
753
|
-
: convertedFloorMinValue;
|
|
754
|
-
|
|
755
|
-
deepSetValue(imp, 'ext.prebid.floors.floorMin', lowestImpFloorMin);
|
|
756
|
-
if (floorMin == null || floorMin > lowestImpFloorMin) { floorMin = lowestImpFloorMin }
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
if (imp.banner || imp.video || imp.native) {
|
|
760
|
-
imps.push(imp);
|
|
761
|
-
}
|
|
762
|
-
});
|
|
763
|
-
|
|
764
|
-
if (!imps.length) {
|
|
765
|
-
logError('Request to Prebid Server rejected due to invalid media type(s) in adUnit.');
|
|
766
|
-
return;
|
|
767
|
-
}
|
|
768
|
-
const request = {
|
|
769
|
-
id: firstBidRequest.auctionId,
|
|
770
|
-
source: {tid: firstBidRequest.auctionId},
|
|
771
|
-
tmax: s2sConfig.timeout,
|
|
772
|
-
imp: imps,
|
|
773
|
-
// to do: add setconfig option to pass test = 1
|
|
774
|
-
test: 0,
|
|
775
|
-
ext: {
|
|
776
|
-
prebid: {
|
|
777
|
-
// set ext.prebid.auctiontimestamp with the auction timestamp. Data type is long integer.
|
|
778
|
-
auctiontimestamp: firstBidRequest.auctionStart,
|
|
779
|
-
targeting: {
|
|
780
|
-
// includewinners is always true for openrtb
|
|
781
|
-
includewinners: true,
|
|
782
|
-
// includebidderkeys always false for openrtb
|
|
783
|
-
includebidderkeys: false
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
};
|
|
788
|
-
|
|
789
|
-
// If the price floors module is active, then we need to signal to PBS! If floorData obj is present is best way to check
|
|
790
|
-
if (typeof deepAccess(firstBidRequest, 'bids.0.floorData') === 'object') {
|
|
791
|
-
request.ext.prebid.floors = { enabled: false };
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
// This is no longer overwritten unless name and version explicitly overwritten by extPrebid (mergeDeep)
|
|
795
|
-
request.ext.prebid = Object.assign(request.ext.prebid, {channel: {name: 'pbjs', version: $$PREBID_GLOBAL$$.version}});
|
|
796
|
-
|
|
797
|
-
// set debug flag if in debug mode
|
|
798
|
-
if (getConfig('debug')) {
|
|
799
|
-
request.ext.prebid = Object.assign(request.ext.prebid, {debug: true});
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
// s2sConfig video.ext.prebid is passed through openrtb to PBS
|
|
803
|
-
if (s2sConfig.extPrebid && typeof s2sConfig.extPrebid === 'object') {
|
|
804
|
-
request.ext.prebid = mergeDeep(request.ext.prebid, s2sConfig.extPrebid);
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
// get reference to pbs config schain bidder names (if any exist)
|
|
808
|
-
const pbsSchainBidderNamesArr = request.ext.prebid?.schains ? request.ext.prebid.schains.flatMap(s => s.bidders) : [];
|
|
809
|
-
// create an schains object
|
|
810
|
-
const schains = Object.fromEntries(
|
|
811
|
-
(request.ext.prebid?.schains || []).map(({bidders, schain}) => [JSON.stringify(schain), {bidders: new Set(bidders), schain}])
|
|
812
|
-
);
|
|
813
|
-
|
|
814
|
-
// compare bidder specific schains with pbs specific schains
|
|
815
|
-
request.ext.prebid.schains = Object.values(
|
|
816
|
-
bidRequests
|
|
817
|
-
.map((req) => [req.bidderCode, req.bids[0].schain])
|
|
818
|
-
.reduce((chains, [bidder, chain]) => {
|
|
819
|
-
const chainKey = JSON.stringify(chain);
|
|
820
|
-
|
|
821
|
-
switch (true) {
|
|
822
|
-
// if pbjs bidder name is same as pbs bidder name, pbs bidder name always wins
|
|
823
|
-
case chainKey && pbsSchainBidderNamesArr.indexOf(bidder) !== -1:
|
|
824
|
-
logInfo(`bidder-specific schain for ${bidder} skipped due to existing entry`);
|
|
825
|
-
break;
|
|
826
|
-
// if a pbjs schain obj is equal to an schain obj that exists on the pbs side, add the bidder name on the pbs side
|
|
827
|
-
case chainKey && chains.hasOwnProperty(chainKey) && pbsSchainBidderNamesArr.indexOf(bidder) === -1:
|
|
828
|
-
chains[chainKey].bidders.add(bidder);
|
|
829
|
-
break;
|
|
830
|
-
// if a pbjs schain obj is not on the pbs side, add a new schain entry on the pbs side
|
|
831
|
-
case chainKey && !chains.hasOwnProperty(chainKey):
|
|
832
|
-
chains[chainKey] = {bidders: new Set(), schain: chain};
|
|
833
|
-
chains[chainKey].bidders.add(bidder);
|
|
834
|
-
break;
|
|
835
|
-
default:
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
return chains;
|
|
839
|
-
}, schains)
|
|
840
|
-
).map(({bidders, schain}) => ({bidders: Array.from(bidders), schain}));
|
|
841
|
-
// if schains evaluates to an empty array, remove it from the prebid object
|
|
842
|
-
if (request.ext.prebid.schains.length === 0) delete request.ext.prebid.schains;
|
|
843
|
-
|
|
844
|
-
/**
|
|
845
|
-
* @type {(string[]|string|undefined)} - OpenRTB property 'cur', currencies available for bids
|
|
846
|
-
*/
|
|
847
|
-
const adServerCur = config.getConfig('currency.adServerCurrency');
|
|
848
|
-
if (adServerCur && typeof adServerCur === 'string') {
|
|
849
|
-
// if the value is a string, wrap it with an array
|
|
850
|
-
request.cur = [adServerCur];
|
|
851
|
-
} else if (Array.isArray(adServerCur) && adServerCur.length) {
|
|
852
|
-
// if it's an array, get the first element
|
|
853
|
-
request.cur = [adServerCur[0]];
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
_appendSiteAppDevice(request, bidRequests[0].refererInfo.page, s2sConfig.accountId);
|
|
857
|
-
|
|
858
|
-
// pass schain object if it is present
|
|
859
|
-
const schain = deepAccess(bidRequests, '0.bids.0.schain');
|
|
860
|
-
if (schain) {
|
|
861
|
-
request.source.ext = {
|
|
862
|
-
schain: schain
|
|
863
|
-
};
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
if (!isEmpty(aliases)) {
|
|
867
|
-
request.ext.prebid.aliases = {...request.ext.prebid.aliases, ...aliases};
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
const bidUserIdAsEids = deepAccess(bidRequests, '0.bids.0.userIdAsEids');
|
|
871
|
-
if (isArray(bidUserIdAsEids) && bidUserIdAsEids.length > 0) {
|
|
872
|
-
deepSetValue(request, 'user.ext.eids', bidUserIdAsEids);
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
if (isArray(eidPermissions) && eidPermissions.length > 0) {
|
|
876
|
-
if (requestedBidders && isArray(requestedBidders)) {
|
|
877
|
-
eidPermissions.forEach(i => {
|
|
878
|
-
if (i.bidders) {
|
|
879
|
-
i.bidders = i.bidders.filter(bidder => includes(requestedBidders, bidder))
|
|
880
|
-
}
|
|
881
|
-
});
|
|
882
|
-
}
|
|
883
|
-
deepSetValue(request, 'ext.prebid.data.eidpermissions', eidPermissions);
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
const multibid = config.getConfig('multibid');
|
|
887
|
-
if (multibid) {
|
|
888
|
-
deepSetValue(request, 'ext.prebid.multibid', multibid.reduce((result, i) => {
|
|
889
|
-
let obj = {};
|
|
890
|
-
|
|
891
|
-
Object.keys(i).forEach(key => {
|
|
892
|
-
obj[key.toLowerCase()] = i[key];
|
|
893
|
-
});
|
|
894
|
-
|
|
895
|
-
result.push(obj);
|
|
896
|
-
|
|
897
|
-
return result;
|
|
898
|
-
}, []));
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
if (bidRequests) {
|
|
902
|
-
if (firstBidRequest.gdprConsent) {
|
|
903
|
-
// note - gdprApplies & consentString may be undefined in certain use-cases for consentManagement module
|
|
904
|
-
let gdprApplies;
|
|
905
|
-
if (typeof firstBidRequest.gdprConsent.gdprApplies === 'boolean') {
|
|
906
|
-
gdprApplies = firstBidRequest.gdprConsent.gdprApplies ? 1 : 0;
|
|
907
|
-
}
|
|
908
|
-
deepSetValue(request, 'regs.ext.gdpr', gdprApplies);
|
|
909
|
-
deepSetValue(request, 'user.ext.consent', firstBidRequest.gdprConsent.consentString);
|
|
910
|
-
if (firstBidRequest.gdprConsent.addtlConsent && typeof firstBidRequest.gdprConsent.addtlConsent === 'string') {
|
|
911
|
-
deepSetValue(request, 'user.ext.ConsentedProvidersSettings.consented_providers', firstBidRequest.gdprConsent.addtlConsent);
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
// US Privacy (CCPA) support
|
|
916
|
-
if (firstBidRequest.uspConsent) {
|
|
917
|
-
deepSetValue(request, 'regs.ext.us_privacy', firstBidRequest.uspConsent);
|
|
918
|
-
}
|
|
919
|
-
}
|
|
920
|
-
|
|
921
|
-
if (getConfig('coppa') === true) {
|
|
922
|
-
deepSetValue(request, 'regs.coppa', 1);
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
const commonFpd = s2sBidRequest.ortb2Fragments?.global || {};
|
|
926
|
-
mergeDeep(request, commonFpd);
|
|
927
|
-
|
|
928
|
-
addBidderFirstPartyDataToRequest(request, s2sBidRequest.ortb2Fragments?.bidder || {});
|
|
929
|
-
|
|
930
|
-
request.imp.forEach((imp) => this.impRequested[imp.id] = imp);
|
|
931
|
-
|
|
932
|
-
if (request.ext?.prebid?.floors?.enabled) {
|
|
933
|
-
request.ext.prebid.floors.floorMin = floorMin;
|
|
934
|
-
request.ext.prebid.floors.floorMinCur = floorMinCur;
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
return request;
|
|
938
|
-
},
|
|
939
|
-
|
|
940
|
-
interpretResponse(response) {
|
|
941
|
-
const {bidderRequests, s2sConfig} = this;
|
|
942
|
-
const bids = [];
|
|
943
|
-
|
|
944
|
-
[['errors', 'serverErrors'], ['responsetimemillis', 'serverResponseTimeMs']]
|
|
945
|
-
.forEach(info => getPbsResponseData(bidderRequests, response, info[0], info[1]))
|
|
946
|
-
|
|
947
|
-
if (response.seatbid) {
|
|
948
|
-
// a seatbid object contains a `bid` array and a `seat` string
|
|
949
|
-
response.seatbid.forEach(seatbid => {
|
|
950
|
-
(seatbid.bid || []).forEach(bid => {
|
|
951
|
-
let bidRequest = this.getBidRequest(bid.impid, seatbid.seat);
|
|
952
|
-
if (bidRequest == null) {
|
|
953
|
-
// for stored impression, a request was made with bidder code `null`. Pick it up here so that NO_BID, BID_WON, etc events
|
|
954
|
-
// can work as expected (otherwise, the original request will always result in NO_BID).
|
|
955
|
-
bidRequest = this.getBidRequest(bid.impid, null);
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
const cpm = bid.price;
|
|
959
|
-
const status = cpm !== 0 ? CONSTANTS.STATUS.GOOD : CONSTANTS.STATUS.NO_BID;
|
|
960
|
-
let bidObject = createBid(status, {
|
|
961
|
-
bidder: seatbid.seat,
|
|
962
|
-
src: TYPE,
|
|
963
|
-
bidId: bidRequest ? (bidRequest.bidId || bidRequest.bid_Id) : null,
|
|
964
|
-
transactionId: this.adUnitsByImp[bid.impid].transactionId,
|
|
965
|
-
auctionId: this.auctionId,
|
|
966
|
-
});
|
|
967
|
-
bidObject.requestBidder = bidRequest?.bidder;
|
|
968
|
-
bidObject.requestTimestamp = this.requestTimestamp;
|
|
969
|
-
bidObject.cpm = cpm;
|
|
970
|
-
if (bid?.ext?.prebid?.meta?.adaptercode) {
|
|
971
|
-
bidObject.adapterCode = bid.ext.prebid.meta.adaptercode;
|
|
972
|
-
} else if (bidRequest?.bidder) {
|
|
973
|
-
bidObject.adapterCode = bidRequest.bidder;
|
|
974
|
-
} else {
|
|
975
|
-
bidObject.adapterCode = seatbid.seat;
|
|
976
|
-
}
|
|
977
|
-
|
|
978
|
-
// temporarily leaving attaching it to each bidResponse so no breaking change
|
|
979
|
-
// BUT: this is a flat map, so it should be only attached to bidderRequest, a the change above does
|
|
980
|
-
let serverResponseTimeMs = deepAccess(response, ['ext', 'responsetimemillis', seatbid.seat].join('.'));
|
|
981
|
-
if (bidRequest && serverResponseTimeMs) {
|
|
982
|
-
bidRequest.serverResponseTimeMs = serverResponseTimeMs;
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
// Look for seatbid[].bid[].ext.prebid.bidid and place it in the bidResponse object for use in analytics adapters as 'pbsBidId'
|
|
986
|
-
const bidId = deepAccess(bid, 'ext.prebid.bidid');
|
|
987
|
-
if (isStr(bidId)) {
|
|
988
|
-
bidObject.pbsBidId = bidId;
|
|
989
|
-
}
|
|
990
|
-
|
|
991
|
-
// store wurl by auctionId and adId so it can be accessed from the BID_WON event handler
|
|
992
|
-
if (isStr(deepAccess(bid, 'ext.prebid.events.win'))) {
|
|
993
|
-
addWurl(this.auctionId, bidObject.adId, deepAccess(bid, 'ext.prebid.events.win'));
|
|
994
|
-
}
|
|
995
|
-
|
|
996
|
-
let extPrebidTargeting = deepAccess(bid, 'ext.prebid.targeting');
|
|
997
|
-
|
|
998
|
-
// If ext.prebid.targeting exists, add it as a property value named 'adserverTargeting'
|
|
999
|
-
// The removal of hb_winurl and hb_bidid targeting values is temporary
|
|
1000
|
-
// once we get through the transition, this block will be removed.
|
|
1001
|
-
if (isPlainObject(extPrebidTargeting)) {
|
|
1002
|
-
// If wurl exists, remove hb_winurl and hb_bidid targeting attributes
|
|
1003
|
-
if (isStr(deepAccess(bid, 'ext.prebid.events.win'))) {
|
|
1004
|
-
extPrebidTargeting = getDefinedParams(extPrebidTargeting, Object.keys(extPrebidTargeting)
|
|
1005
|
-
.filter(i => (i.indexOf('hb_winurl') === -1 && i.indexOf('hb_bidid') === -1)));
|
|
1006
|
-
}
|
|
1007
|
-
bidObject.adserverTargeting = extPrebidTargeting;
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
bidObject.seatBidId = bid.id;
|
|
1011
|
-
|
|
1012
|
-
if (deepAccess(bid, 'ext.prebid.type') === VIDEO) {
|
|
1013
|
-
bidObject.mediaType = VIDEO;
|
|
1014
|
-
const impReq = this.impRequested[bid.impid];
|
|
1015
|
-
[bidObject.playerWidth, bidObject.playerHeight] = [impReq.video.w, impReq.video.h];
|
|
1016
|
-
|
|
1017
|
-
// try to get cache values from 'response.ext.prebid.cache.js'
|
|
1018
|
-
// else try 'bid.ext.prebid.targeting' as fallback
|
|
1019
|
-
if (bid.ext.prebid.cache && typeof bid.ext.prebid.cache.vastXml === 'object' && bid.ext.prebid.cache.vastXml.cacheId && bid.ext.prebid.cache.vastXml.url) {
|
|
1020
|
-
bidObject.videoCacheKey = bid.ext.prebid.cache.vastXml.cacheId;
|
|
1021
|
-
bidObject.vastUrl = bid.ext.prebid.cache.vastXml.url;
|
|
1022
|
-
} else if (extPrebidTargeting && extPrebidTargeting.hb_uuid && extPrebidTargeting.hb_cache_host && extPrebidTargeting.hb_cache_path) {
|
|
1023
|
-
bidObject.videoCacheKey = extPrebidTargeting.hb_uuid;
|
|
1024
|
-
// build url using key and cache host
|
|
1025
|
-
bidObject.vastUrl = `https://${extPrebidTargeting.hb_cache_host}${extPrebidTargeting.hb_cache_path}?uuid=${extPrebidTargeting.hb_uuid}`;
|
|
1026
|
-
}
|
|
1027
|
-
|
|
1028
|
-
if (bid.adm) { bidObject.vastXml = bid.adm; }
|
|
1029
|
-
if (!bidObject.vastUrl && bid.nurl) { bidObject.vastUrl = bid.nurl; }
|
|
1030
|
-
} else if (FEATURES.NATIVE && deepAccess(bid, 'ext.prebid.type') === NATIVE) {
|
|
1031
|
-
bidObject.mediaType = NATIVE;
|
|
1032
|
-
let ortb;
|
|
1033
|
-
if (typeof bid.adm === 'string') {
|
|
1034
|
-
ortb = bidObject.adm = JSON.parse(bid.adm);
|
|
1035
|
-
} else {
|
|
1036
|
-
ortb = bidObject.adm = bid.adm;
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
if (isPlainObject(ortb) && Array.isArray(ortb.assets)) {
|
|
1040
|
-
bidObject.native = {
|
|
1041
|
-
ortb,
|
|
1042
|
-
};
|
|
1043
|
-
} else {
|
|
1044
|
-
logError('prebid server native response contained no assets');
|
|
1045
|
-
}
|
|
1046
|
-
} else { // banner
|
|
1047
|
-
if (bid.adm && bid.nurl) {
|
|
1048
|
-
bidObject.ad = bid.adm;
|
|
1049
|
-
bidObject.ad += createTrackPixelHtml(decodeURIComponent(bid.nurl));
|
|
1050
|
-
} else if (bid.adm) {
|
|
1051
|
-
bidObject.ad = bid.adm;
|
|
1052
|
-
} else if (bid.nurl) {
|
|
1053
|
-
bidObject.adUrl = bid.nurl;
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
|
|
1057
|
-
bidObject.width = bid.w;
|
|
1058
|
-
bidObject.height = bid.h;
|
|
1059
|
-
if (bid.dealid) { bidObject.dealId = bid.dealid; }
|
|
1060
|
-
bidObject.creative_id = bid.crid;
|
|
1061
|
-
bidObject.creativeId = bid.crid;
|
|
1062
|
-
if (bid.burl) { bidObject.burl = bid.burl; }
|
|
1063
|
-
bidObject.currency = (response.cur) ? response.cur : DEFAULT_S2S_CURRENCY;
|
|
1064
|
-
bidObject.meta = {};
|
|
1065
|
-
let extPrebidMeta = deepAccess(bid, 'ext.prebid.meta');
|
|
1066
|
-
if (extPrebidMeta && isPlainObject(extPrebidMeta)) { bidObject.meta = deepClone(extPrebidMeta); }
|
|
1067
|
-
if (bid.adomain) { bidObject.meta.advertiserDomains = bid.adomain; }
|
|
1068
|
-
|
|
1069
|
-
// the OpenRTB location for "TTL" as understood by Prebid.js is "exp" (expiration).
|
|
1070
|
-
const configTtl = s2sConfig.defaultTtl || DEFAULT_S2S_TTL;
|
|
1071
|
-
bidObject.ttl = (bid.exp) ? bid.exp : configTtl;
|
|
1072
|
-
bidObject.netRevenue = (bid.netRevenue) ? bid.netRevenue : DEFAULT_S2S_NETREVENUE;
|
|
1073
|
-
|
|
1074
|
-
bids.push({ adUnit: this.adUnitsByImp[bid.impid].code, bid: bidObject });
|
|
1075
|
-
});
|
|
1076
|
-
});
|
|
1077
|
-
}
|
|
1078
|
-
|
|
1079
|
-
return bids;
|
|
1080
|
-
},
|
|
1081
|
-
setBidRequestId(impId, bidderCode, bidId) {
|
|
1082
|
-
this.bidIdMap[this.impBidderKey(impId, bidderCode)] = bidId;
|
|
1083
|
-
},
|
|
1084
|
-
getBidRequest(impId, bidderCode) {
|
|
1085
|
-
const key = this.impBidderKey(impId, bidderCode);
|
|
1086
|
-
return this.bidIdMap[key] && getBidRequest(this.bidIdMap[key], this.bidderRequests);
|
|
1087
|
-
},
|
|
1088
|
-
impBidderKey(impId, bidderCode) {
|
|
1089
|
-
return `${impId}${bidderCode}`;
|
|
1090
|
-
}
|
|
1091
|
-
});
|
|
1092
|
-
|
|
1093
394
|
/**
|
|
1094
395
|
* BID_WON event to request the wurl
|
|
1095
396
|
* @param {Bid} bid the winning bid object
|
|
@@ -1161,6 +462,9 @@ export function PrebidServer() {
|
|
|
1161
462
|
} else {
|
|
1162
463
|
if (metrics.measureTime('addBidResponse.validate', () => isValid(adUnit, bid))) {
|
|
1163
464
|
addBidResponse(adUnit, bid);
|
|
465
|
+
if (bid.pbsWurl) {
|
|
466
|
+
addWurl(bid.auctionId, bid.adId, bid.pbsWurl);
|
|
467
|
+
}
|
|
1164
468
|
} else {
|
|
1165
469
|
addBidResponse.reject(adUnit, bid, CONSTANTS.REJECTION_REASON.INVALID);
|
|
1166
470
|
}
|
|
@@ -1200,8 +504,7 @@ export const processPBSRequest = hook('sync', function (s2sBidRequest, bidReques
|
|
|
1200
504
|
.reduce(flatten, [])
|
|
1201
505
|
.filter(uniques);
|
|
1202
506
|
|
|
1203
|
-
const
|
|
1204
|
-
const request = s2sBidRequest.metrics.measureTime('buildRequests', () => ortb2.buildRequest());
|
|
507
|
+
const request = s2sBidRequest.metrics.measureTime('buildRequests', () => buildPBSRequest(s2sBidRequest, bidRequests, adUnits, requestedBidders, eidPermissions));
|
|
1205
508
|
const requestJson = request && JSON.stringify(request);
|
|
1206
509
|
logInfo('BidRequest: ' + requestJson);
|
|
1207
510
|
const endpointUrl = getMatchingConsentUrl(s2sBidRequest.s2sConfig.endpoint, gdprConsent);
|
|
@@ -1215,7 +518,7 @@ export const processPBSRequest = hook('sync', function (s2sBidRequest, bidReques
|
|
|
1215
518
|
let result;
|
|
1216
519
|
try {
|
|
1217
520
|
result = JSON.parse(response);
|
|
1218
|
-
const bids = s2sBidRequest.metrics.measureTime('interpretResponse', () =>
|
|
521
|
+
const bids = s2sBidRequest.metrics.measureTime('interpretResponse', () => interpretPBSResponse(result, request).bids);
|
|
1219
522
|
bids.forEach(onBid);
|
|
1220
523
|
} catch (error) {
|
|
1221
524
|
logError(error);
|