prebid.js 8.1.0 → 8.2.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/.devcontainer/devcontainer.json +3 -1
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/33acrossIdSystem.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/admanBidAdapter.js +1 -1
- package/dist/adqueryBidAdapter.js +1 -1
- 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/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bridBidAdapter.js +1 -0
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/carodaBidAdapter.js +1 -1
- package/dist/categoryTranslation.js +1 -1
- package/dist/chtnwBidAdapter.js +1 -1
- package/dist/cmp.js +1 -0
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consentManagement.js +1 -1
- package/dist/consentManagementGpp.js +1 -1
- package/dist/consentManagementUsp.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantAnalyticsAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/cwireBidAdapter.js +1 -1
- package/dist/dependencies.json +12 -0
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/euidIdSystem.js +1 -1
- package/dist/feedadBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/freewheel-sspBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/gppControl_usnat.js +1 -0
- package/dist/greenbidsAnalyticsAdapter.js +1 -1
- package/dist/greenbidsRtdProvider.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/hypelabBidAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/imdsBidAdapter.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/intentIqIdSystem.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/kargoBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/kueezRtbBidAdapter.js +1 -1
- package/dist/kulturemediaBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/lifestreetBidAdapter.js +1 -1
- package/dist/liveIntentIdSystem.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/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/minutemediaplusBidAdapter.js +1 -1
- package/dist/mspa.js +1 -0
- package/dist/nexx360BidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +136 -132
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/optidigitalBidAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/oxxionRtdProvider.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.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/retailspotBidAdapter.js +1 -1
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseBidAdapter.js +1 -1
- package/dist/rubiconBidAdapter.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/sspBCBidAdapter.js +1 -1
- package/dist/stvBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.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/uid2IdSystem.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/videobyteBidAdapter.js +1 -1
- 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/libraries/cmp/cmpClient.js +139 -0
- package/libraries/mspa/activityControls.js +91 -0
- package/modules/admanBidAdapter.js +5 -0
- package/modules/bridBidAdapter.js +223 -0
- package/modules/categoryTranslation.js +3 -2
- package/modules/consentManagement.js +12 -86
- package/modules/consentManagementGpp.js +47 -126
- package/modules/consentManagementUsp.js +19 -97
- package/modules/gppControl_usnat.js +11 -0
- package/modules/intentIqIdSystem.js +6 -5
- package/modules/liveIntentIdSystem.js +8 -3
- package/modules/mediasquareBidAdapter.js +19 -23
- package/modules/oxxionRtdProvider.js +124 -11
- package/modules/oxxionRtdProvider.md +19 -4
- package/modules/tripleliftBidAdapter.js +21 -1
- package/modules/userId/eids.js +29 -0
- package/modules/userId/eids.md +19 -2
- package/modules/userId/index.js +78 -29
- package/modules/userId/userId.md +3 -0
- package/package.json +1 -1
- package/src/activities/params.js +4 -1
- package/test/spec/libraries/cmp/cmpClient_spec.js +233 -0
- package/test/spec/libraries/mspa/activityControls_spec.js +315 -0
- package/test/spec/modules/admanBidAdapter_spec.js +8 -2
- package/test/spec/modules/adqueryBidAdapter_spec.js +5 -1
- package/test/spec/modules/bridBidAdapter_spec.js +129 -0
- package/test/spec/modules/byDataAnalyticsAdapter_spec.js +9 -7
- package/test/spec/modules/chtnwBidAdapter_spec.js +4 -1
- package/test/spec/modules/consentManagementGpp_spec.js +84 -7
- package/test/spec/modules/consentManagement_spec.js +8 -18
- package/test/spec/modules/datablocksBidAdapter_spec.js +7 -3
- package/test/spec/modules/eids_spec.js +87 -0
- package/test/spec/modules/insticatorBidAdapter_spec.js +6 -2
- package/test/spec/modules/intentIqIdSystem_spec.js +36 -2
- package/test/spec/modules/ixBidAdapter_spec.js +40 -12
- package/test/spec/modules/lassoBidAdapter_spec.js +6 -4
- package/test/spec/modules/liveIntentIdMinimalSystem_spec.js +17 -2
- package/test/spec/modules/liveIntentIdSystem_spec.js +11 -6
- package/test/spec/modules/mediasquareBidAdapter_spec.js +3 -0
- package/test/spec/modules/onetagBidAdapter_spec.js +81 -75
- package/test/spec/modules/orbidderBidAdapter_spec.js +6 -3
- package/test/spec/modules/oxxionRtdProvider_spec.js +113 -1
- package/test/spec/modules/relaidoBidAdapter_spec.js +4 -3
- package/test/spec/modules/tripleliftBidAdapter_spec.js +20 -1
- package/test/spec/modules/ucfunnelBidAdapter_spec.js +37 -16
- package/test/spec/modules/userId_spec.js +393 -6
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { submodule } from '../src/hook.js'
|
|
2
|
-
import { deepAccess, logInfo } from '../src/utils.js'
|
|
2
|
+
import { deepAccess, logInfo, logError } from '../src/utils.js'
|
|
3
|
+
import { ajax } from '../src/ajax.js';
|
|
4
|
+
import adapterManager from '../src/adapterManager.js';
|
|
3
5
|
|
|
4
6
|
const oxxionRtdSearchFor = [ 'adUnitCode', 'auctionId', 'bidder', 'bidderCode', 'bidId', 'cpm', 'creativeId', 'currency', 'width', 'height', 'mediaType', 'netRevenue', 'originalCpm', 'originalCurrency', 'requestId', 'size', 'source', 'status', 'timeToRespond', 'transactionId', 'ttl', 'sizes', 'mediaTypes', 'src', 'userId', 'labelAny', 'adId' ];
|
|
5
7
|
const LOG_PREFIX = 'oxxionRtdProvider submodule: ';
|
|
6
8
|
|
|
7
9
|
const allAdUnits = [];
|
|
10
|
+
const bidderAliasRegistry = adapterManager.aliasRegistry || {};
|
|
8
11
|
|
|
9
12
|
/** @type {RtdSubmodule} */
|
|
10
13
|
export const oxxionSubmodule = {
|
|
@@ -12,23 +15,56 @@ export const oxxionSubmodule = {
|
|
|
12
15
|
init: init,
|
|
13
16
|
getBidRequestData: getAdUnits,
|
|
14
17
|
onBidResponseEvent: insertVideoTracking,
|
|
18
|
+
getRequestsList: getRequestsList,
|
|
19
|
+
getFilteredAdUnitsOnBidRates: getFilteredAdUnitsOnBidRates,
|
|
15
20
|
};
|
|
16
21
|
|
|
17
22
|
function init(config, userConsent) {
|
|
18
|
-
if (!config.params || !config.params.domain
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
return
|
|
23
|
+
if (!config.params || !config.params.domain) { return false }
|
|
24
|
+
if (config.params.contexts && Array.isArray(config.params.contexts) && config.params.contexts.length > 0) { return true; }
|
|
25
|
+
if (typeof config.params.threshold != 'undefined' && typeof config.params.samplingRate == 'number') { return true }
|
|
26
|
+
return false;
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
function getAdUnits(reqBidsConfigObj, callback, config, userConsent) {
|
|
25
|
-
|
|
26
|
-
if (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
logInfo(LOG_PREFIX + 'started with ', config);
|
|
31
|
+
if (typeof config.params.threshold != 'undefined' && typeof config.params.samplingRate == 'number') {
|
|
32
|
+
let filteredBids;
|
|
33
|
+
const requests = getRequestsList(reqBidsConfigObj);
|
|
34
|
+
const gdpr = userConsent && userConsent.gdpr ? userConsent.gdpr.consentString : null;
|
|
35
|
+
const payload = {
|
|
36
|
+
gdpr,
|
|
37
|
+
requests
|
|
38
|
+
};
|
|
39
|
+
const endpoint = 'https://' + config.params.domain + '.oxxion.io/analytics/bid_rate_interests';
|
|
40
|
+
getPromisifiedAjax(endpoint, JSON.stringify(payload), {
|
|
41
|
+
method: 'POST',
|
|
42
|
+
withCredentials: true
|
|
43
|
+
}).then(bidsRateInterests => {
|
|
44
|
+
if (bidsRateInterests.length) {
|
|
45
|
+
[reqBidsConfigObj.adUnits, filteredBids] = getFilteredAdUnitsOnBidRates(bidsRateInterests, reqBidsConfigObj.adUnits, config.params, true);
|
|
30
46
|
}
|
|
31
|
-
|
|
47
|
+
if (filteredBids.length > 0) {
|
|
48
|
+
getPromisifiedAjax('https://' + config.params.domain + '.oxxion.io/analytics/request_rejecteds', JSON.stringify({'bids': filteredBids, 'gdpr': gdpr}), {
|
|
49
|
+
method: 'POST',
|
|
50
|
+
withCredentials: true
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
if (typeof callback == 'function') { callback(); }
|
|
54
|
+
}).catch(error => logError(LOG_PREFIX, 'bidInterestError', error));
|
|
55
|
+
}
|
|
56
|
+
if (config.params.contexts && Array.isArray(config.params.contexts) && config.params.contexts.length > 0) {
|
|
57
|
+
const reqAdUnits = reqBidsConfigObj.adUnits;
|
|
58
|
+
if (Array.isArray(reqAdUnits)) {
|
|
59
|
+
reqAdUnits.forEach(adunit => {
|
|
60
|
+
if (config.params.contexts.includes(deepAccess(adunit, 'mediaTypes.video.context'))) {
|
|
61
|
+
allAdUnits.push(adunit);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (!(typeof config.params.threshold != 'undefined' && typeof config.params.samplingRate == 'number') && typeof callback == 'function') {
|
|
66
|
+
callback();
|
|
67
|
+
}
|
|
32
68
|
}
|
|
33
69
|
}
|
|
34
70
|
|
|
@@ -94,4 +130,81 @@ function getImpUrl(config, data, maxCpm) {
|
|
|
94
130
|
return trackingImpUrl + 'cpmIncrement=' + cpmIncrement + '&context=' + context;
|
|
95
131
|
}
|
|
96
132
|
|
|
133
|
+
function getPromisifiedAjax (url, data = {}, options = {}) {
|
|
134
|
+
return new Promise((resolve, reject) => {
|
|
135
|
+
const callbacks = {
|
|
136
|
+
success(responseText, { response }) {
|
|
137
|
+
resolve(JSON.parse(response));
|
|
138
|
+
},
|
|
139
|
+
error(error) {
|
|
140
|
+
reject(error);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
ajax(url, callbacks, data, options);
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function getFilteredAdUnitsOnBidRates (bidsRateInterests, adUnits, params, useSampling) {
|
|
148
|
+
const { threshold, samplingRate } = params;
|
|
149
|
+
const filteredBids = [];
|
|
150
|
+
// Separate bidsRateInterests in two groups against threshold & samplingRate
|
|
151
|
+
const { interestingBidsRates, uninterestingBidsRates } = bidsRateInterests.reduce((acc, interestingBid) => {
|
|
152
|
+
const isBidRateUpper = typeof threshold == 'number' ? interestingBid.rate === true || interestingBid.rate > threshold : interestingBid.suggestion;
|
|
153
|
+
const isBidInteresting = isBidRateUpper || (getRandomNumber(100) < samplingRate && useSampling);
|
|
154
|
+
const key = isBidInteresting ? 'interestingBidsRates' : 'uninterestingBidsRates';
|
|
155
|
+
acc[key].push(interestingBid);
|
|
156
|
+
return acc;
|
|
157
|
+
}, {
|
|
158
|
+
interestingBidsRates: [],
|
|
159
|
+
uninterestingBidsRates: [] // Do something with later
|
|
160
|
+
});
|
|
161
|
+
logInfo(LOG_PREFIX, 'getFilteredAdUnitsOnBidRates()', interestingBidsRates, uninterestingBidsRates);
|
|
162
|
+
// Filter bids and adUnits against interesting bids rates
|
|
163
|
+
const newAdUnits = adUnits.filter(({ bids = [] }, adUnitIndex) => {
|
|
164
|
+
adUnits[adUnitIndex].bids = bids.filter(bid => {
|
|
165
|
+
if (!params.bidders || params.bidders.includes(bid.bidder)) {
|
|
166
|
+
const index = interestingBidsRates.findIndex(({ id }) => id === bid._id);
|
|
167
|
+
if (index == -1) {
|
|
168
|
+
let tmpBid = bid;
|
|
169
|
+
tmpBid['code'] = adUnits[adUnitIndex].code;
|
|
170
|
+
tmpBid['mediaTypes'] = adUnits[adUnitIndex].mediaTypes;
|
|
171
|
+
tmpBid['originalBidder'] = bidderAliasRegistry[bid.bidder] || bid.bidder;
|
|
172
|
+
if (tmpBid.floorData) {
|
|
173
|
+
delete tmpBid.floorData;
|
|
174
|
+
}
|
|
175
|
+
filteredBids.push(tmpBid);
|
|
176
|
+
}
|
|
177
|
+
delete bid._id;
|
|
178
|
+
return index !== -1;
|
|
179
|
+
} else {
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
return !!adUnits[adUnitIndex].bids.length;
|
|
184
|
+
});
|
|
185
|
+
return [newAdUnits, filteredBids];
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function getRandomNumber (max = 10) {
|
|
189
|
+
return Math.round(Math.random() * max);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function getRequestsList(reqBidsConfigObj) {
|
|
193
|
+
let count = 0;
|
|
194
|
+
return reqBidsConfigObj.adUnits.flatMap(({
|
|
195
|
+
bids = [],
|
|
196
|
+
mediaTypes = {},
|
|
197
|
+
code = ''
|
|
198
|
+
}) => bids.reduce((acc, { bidder = '', params = {} }, index) => {
|
|
199
|
+
const id = count++;
|
|
200
|
+
bids[index]._id = id;
|
|
201
|
+
return acc.concat({
|
|
202
|
+
id,
|
|
203
|
+
adUnit: code,
|
|
204
|
+
bidder,
|
|
205
|
+
mediaTypes,
|
|
206
|
+
});
|
|
207
|
+
}, []));
|
|
208
|
+
}
|
|
209
|
+
|
|
97
210
|
submodule('realTimeData', oxxionSubmodule);
|
|
@@ -7,12 +7,12 @@ Maintainer: tech@oxxion.io
|
|
|
7
7
|
# Oxxion Real-Time-Data submodule
|
|
8
8
|
|
|
9
9
|
Oxxion helps you to understand how your prebid stack performs.
|
|
10
|
-
This Rtd module is to use in order to improve video events tracking.
|
|
10
|
+
This Rtd module is to use in order to improve video events tracking and/or to filter bidder requested.
|
|
11
11
|
|
|
12
12
|
# Integration
|
|
13
13
|
|
|
14
14
|
Make sure to have the following modules listed while building prebid : `rtdModule,oxxionRtdProvider`
|
|
15
|
-
`
|
|
15
|
+
`rtdModule` is required to activate real-time-data submodules.
|
|
16
16
|
For example :
|
|
17
17
|
```
|
|
18
18
|
gulp build --modules=schain,priceFloors,currency,consentManagement,appnexusBidAdapter,rubiconBidAdapter,rtdModule,oxxionRtdProvider
|
|
@@ -23,7 +23,7 @@ Then add the oxxion Rtd module to your prebid configuration :
|
|
|
23
23
|
pbjs.setConfig(
|
|
24
24
|
...
|
|
25
25
|
realTimeData: {
|
|
26
|
-
auctionDelay:
|
|
26
|
+
auctionDelay: 300,
|
|
27
27
|
dataProviders: [
|
|
28
28
|
{
|
|
29
29
|
name: "oxxionRtd",
|
|
@@ -31,6 +31,8 @@ pbjs.setConfig(
|
|
|
31
31
|
params: {
|
|
32
32
|
domain: "test.endpoint",
|
|
33
33
|
contexts: ["instream"],
|
|
34
|
+
threshold: false,
|
|
35
|
+
samplingRate: 10,
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
]
|
|
@@ -39,10 +41,23 @@ pbjs.setConfig(
|
|
|
39
41
|
)
|
|
40
42
|
```
|
|
41
43
|
|
|
42
|
-
# setConfig Parameters
|
|
44
|
+
# setConfig Parameters General
|
|
43
45
|
|
|
44
46
|
| Name | Type | Description |
|
|
45
47
|
|:---------------------------------|:---------|:------------------------------------------------------------------------------------------------------------|
|
|
46
48
|
| domain | String | This string identifies yourself in Oxxion's systems and is provided to you by your Oxxion representative. |
|
|
49
|
+
|
|
50
|
+
# setConfig Parameters for Video Tracking
|
|
51
|
+
|
|
52
|
+
| Name | Type | Description |
|
|
53
|
+
|:---------------------------------|:---------|:------------------------------------------------------------------------------------------------------------|
|
|
47
54
|
| contexts | Array | Array defining which video contexts to add tracking events into. Values can be instream and/or outstream. |
|
|
48
55
|
|
|
56
|
+
# setConfig Parameters for bidder filtering
|
|
57
|
+
|
|
58
|
+
| Name | Type | Description |
|
|
59
|
+
|:---------------------------------|:-----------|:------------------------------------------------------------------------------------------------------------|
|
|
60
|
+
| threshold | Float/Bool | False or minimum expected bid rate to call a bidder (ex: 1.0 for 1% bid rate). |
|
|
61
|
+
| samplingRate | Integer | Percentage of request not meeting the criterias to run anyway in order to check for any change. |
|
|
62
|
+
| bidders | Array | Optional: If set, filtering will only be applied to bidders listed.
|
|
63
|
+
|
|
@@ -56,6 +56,10 @@ export const tripleliftAdapterSpec = {
|
|
|
56
56
|
tlCall = tryAppendQueryString(tlCall, 'us_privacy', bidderRequest.uspConsent);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
if (bidderRequest && bidderRequest.fledgeEnabled) {
|
|
60
|
+
tlCall = tryAppendQueryString(tlCall, 'fledge', bidderRequest.fledgeEnabled);
|
|
61
|
+
}
|
|
62
|
+
|
|
59
63
|
if (config.getConfig('coppa') === true) {
|
|
60
64
|
tlCall = tryAppendQueryString(tlCall, 'coppa', true);
|
|
61
65
|
}
|
|
@@ -80,7 +84,7 @@ export const tripleliftAdapterSpec = {
|
|
|
80
84
|
});
|
|
81
85
|
},
|
|
82
86
|
|
|
83
|
-
getUserSyncs: function(syncOptions, responses, gdprConsent, usPrivacy) {
|
|
87
|
+
getUserSyncs: function(syncOptions, responses, gdprConsent, usPrivacy, gppConsent) {
|
|
84
88
|
let syncType = _getSyncType(syncOptions);
|
|
85
89
|
if (!syncType) return;
|
|
86
90
|
|
|
@@ -100,6 +104,15 @@ export const tripleliftAdapterSpec = {
|
|
|
100
104
|
syncEndpoint = tryAppendQueryString(syncEndpoint, 'us_privacy', usPrivacy);
|
|
101
105
|
}
|
|
102
106
|
|
|
107
|
+
if (gppConsent) {
|
|
108
|
+
if (gppConsent.gppString) {
|
|
109
|
+
syncEndpoint = tryAppendQueryString(syncEndpoint, 'gpp', gppConsent.gppString);
|
|
110
|
+
}
|
|
111
|
+
if (gppConsent.applicableSections && gppConsent.applicableSections.length !== 0) {
|
|
112
|
+
syncEndpoint = tryAppendQueryString(syncEndpoint, 'gpp_sid', _filterSid(gppConsent.applicableSections));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
103
116
|
return [{
|
|
104
117
|
type: syncType,
|
|
105
118
|
url: syncEndpoint
|
|
@@ -113,6 +126,13 @@ function _getSyncType(syncOptions) {
|
|
|
113
126
|
if (syncOptions.pixelEnabled) return 'image';
|
|
114
127
|
}
|
|
115
128
|
|
|
129
|
+
function _filterSid(sid) {
|
|
130
|
+
return sid.filter(element => {
|
|
131
|
+
return Number.isInteger(element);
|
|
132
|
+
})
|
|
133
|
+
.join(',');
|
|
134
|
+
}
|
|
135
|
+
|
|
116
136
|
function _buildPostBody(bidRequests, bidderRequest) {
|
|
117
137
|
let data = {};
|
|
118
138
|
let { schain } = bidRequests[0];
|
package/modules/userId/eids.js
CHANGED
|
@@ -158,6 +158,11 @@ export const USER_IDS_CONFIG = {
|
|
|
158
158
|
atype: 3,
|
|
159
159
|
getValue: function(data) {
|
|
160
160
|
return data.id;
|
|
161
|
+
},
|
|
162
|
+
getUidExt: function(data) {
|
|
163
|
+
if (data.ext) {
|
|
164
|
+
return data.ext;
|
|
165
|
+
}
|
|
161
166
|
}
|
|
162
167
|
},
|
|
163
168
|
|
|
@@ -167,6 +172,25 @@ export const USER_IDS_CONFIG = {
|
|
|
167
172
|
atype: 3,
|
|
168
173
|
getValue: function(data) {
|
|
169
174
|
return data.id;
|
|
175
|
+
},
|
|
176
|
+
getUidExt: function(data) {
|
|
177
|
+
if (data.ext) {
|
|
178
|
+
return data.ext;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
|
|
183
|
+
// magnite
|
|
184
|
+
'magnite': {
|
|
185
|
+
source: 'rubiconproject.com',
|
|
186
|
+
atype: 3,
|
|
187
|
+
getValue: function(data) {
|
|
188
|
+
return data.id;
|
|
189
|
+
},
|
|
190
|
+
getUidExt: function(data) {
|
|
191
|
+
if (data.ext) {
|
|
192
|
+
return data.ext;
|
|
193
|
+
}
|
|
170
194
|
}
|
|
171
195
|
},
|
|
172
196
|
|
|
@@ -288,6 +312,11 @@ export const USER_IDS_CONFIG = {
|
|
|
288
312
|
atype: 3,
|
|
289
313
|
getValue: function(data) {
|
|
290
314
|
return data.id;
|
|
315
|
+
},
|
|
316
|
+
getUidExt: function(data) {
|
|
317
|
+
if (data.ext) {
|
|
318
|
+
return data.ext;
|
|
319
|
+
}
|
|
291
320
|
}
|
|
292
321
|
},
|
|
293
322
|
|
package/modules/userId/eids.md
CHANGED
|
@@ -110,7 +110,10 @@ userIdAsEids = [
|
|
|
110
110
|
source: 'bidswitch.net',
|
|
111
111
|
uids: [{
|
|
112
112
|
id: 'some-random-id-value',
|
|
113
|
-
atype: 3
|
|
113
|
+
atype: 3,
|
|
114
|
+
ext: {
|
|
115
|
+
provider: 'liveintent.com'
|
|
116
|
+
}
|
|
114
117
|
}]
|
|
115
118
|
},
|
|
116
119
|
|
|
@@ -118,7 +121,21 @@ userIdAsEids = [
|
|
|
118
121
|
source: 'media.net',
|
|
119
122
|
uids: [{
|
|
120
123
|
id: 'some-random-id-value',
|
|
121
|
-
atype: 3
|
|
124
|
+
atype: 3,
|
|
125
|
+
ext: {
|
|
126
|
+
provider: 'liveintent.com'
|
|
127
|
+
}
|
|
128
|
+
}]
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
{
|
|
132
|
+
source: 'rubiconproject.com',
|
|
133
|
+
uids: [{
|
|
134
|
+
id: 'some-random-id-value',
|
|
135
|
+
atype: 3,
|
|
136
|
+
ext: {
|
|
137
|
+
provider: 'liveintent.com'
|
|
138
|
+
}
|
|
122
139
|
}]
|
|
123
140
|
},
|
|
124
141
|
|
package/modules/userId/index.js
CHANGED
|
@@ -130,7 +130,7 @@ import {find, includes} from '../../src/polyfill.js';
|
|
|
130
130
|
import {config} from '../../src/config.js';
|
|
131
131
|
import * as events from '../../src/events.js';
|
|
132
132
|
import {getGlobal} from '../../src/prebidGlobal.js';
|
|
133
|
-
import adapterManager, {gdprDataHandler} from '../../src/adapterManager.js';
|
|
133
|
+
import adapterManager, {gdprDataHandler, gppDataHandler} from '../../src/adapterManager.js';
|
|
134
134
|
import CONSTANTS from '../../src/constants.json';
|
|
135
135
|
import {module, ready as hooksReady} from '../../src/hook.js';
|
|
136
136
|
import {buildEidPermissions, createEidsArray, USER_IDS_CONFIG} from './eids.js';
|
|
@@ -195,6 +195,9 @@ let initializedSubmodules;
|
|
|
195
195
|
/** @type {SubmoduleConfig[]} */
|
|
196
196
|
let configRegistry = [];
|
|
197
197
|
|
|
198
|
+
/** @type {Object} */
|
|
199
|
+
let idPriority = {};
|
|
200
|
+
|
|
198
201
|
/** @type {Submodule[]} */
|
|
199
202
|
let submoduleRegistry = [];
|
|
200
203
|
|
|
@@ -406,7 +409,7 @@ function storedConsentDataMatchesConsentData(storedConsentData, consentData) {
|
|
|
406
409
|
* @param {SubmoduleContainer[]} submodules
|
|
407
410
|
* @param {function} cb - callback for after processing is done.
|
|
408
411
|
*/
|
|
409
|
-
function processSubmoduleCallbacks(submodules, cb) {
|
|
412
|
+
function processSubmoduleCallbacks(submodules, cb, allModules) {
|
|
410
413
|
cb = uidMetrics().fork().startTiming('userId.callbacks.total').stopBefore(cb);
|
|
411
414
|
const done = delayExecution(() => {
|
|
412
415
|
clearTimeout(timeoutID);
|
|
@@ -422,7 +425,7 @@ function processSubmoduleCallbacks(submodules, cb) {
|
|
|
422
425
|
}
|
|
423
426
|
// cache decoded value (this is copied to every adUnit bid)
|
|
424
427
|
submodule.idObj = submodule.submodule.decode(idObj, submodule.config);
|
|
425
|
-
updatePPID(
|
|
428
|
+
updatePPID(getCombinedSubmoduleIds(allModules));
|
|
426
429
|
} else {
|
|
427
430
|
logInfo(`${MODULE_NAME}: ${submodule.submodule.name} - request id responded with an empty value`);
|
|
428
431
|
}
|
|
@@ -447,14 +450,7 @@ function getCombinedSubmoduleIds(submodules) {
|
|
|
447
450
|
if (!Array.isArray(submodules) || !submodules.length) {
|
|
448
451
|
return {};
|
|
449
452
|
}
|
|
450
|
-
|
|
451
|
-
Object.keys(i.idObj).forEach(key => {
|
|
452
|
-
carry[key] = i.idObj[key];
|
|
453
|
-
});
|
|
454
|
-
return carry;
|
|
455
|
-
}, {});
|
|
456
|
-
|
|
457
|
-
return combinedSubmoduleIds;
|
|
453
|
+
return getPrioritizedCombinedSubmoduleIds(submodules)
|
|
458
454
|
}
|
|
459
455
|
|
|
460
456
|
/**
|
|
@@ -466,9 +462,14 @@ function getSubmoduleId(submodules, sourceName) {
|
|
|
466
462
|
if (!Array.isArray(submodules) || !submodules.length) {
|
|
467
463
|
return {};
|
|
468
464
|
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
465
|
+
|
|
466
|
+
const prioritisedIds = getPrioritizedCombinedSubmoduleIds(submodules);
|
|
467
|
+
const eligibleIdName = Object.keys(prioritisedIds).find(idName => {
|
|
468
|
+
const config = USER_IDS_CONFIG[idName];
|
|
469
|
+
return config?.source === sourceName || (isFn(config?.getSource) && config.getSource() === sourceName);
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
return eligibleIdName ? {[eligibleIdName]: prioritisedIds[eligibleIdName]} : [];
|
|
472
473
|
}
|
|
473
474
|
|
|
474
475
|
/**
|
|
@@ -480,15 +481,38 @@ function getCombinedSubmoduleIdsForBidder(submodules, bidder) {
|
|
|
480
481
|
if (!Array.isArray(submodules) || !submodules.length || !bidder) {
|
|
481
482
|
return {};
|
|
482
483
|
}
|
|
483
|
-
|
|
484
|
+
const eligibleSubmodules = submodules
|
|
484
485
|
.filter(i => !i.config.bidders || !isArray(i.config.bidders) || includes(i.config.bidders, bidder))
|
|
486
|
+
|
|
487
|
+
return getPrioritizedCombinedSubmoduleIds(eligibleSubmodules);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* @param {SubmoduleContainer[]} submodules
|
|
492
|
+
*/
|
|
493
|
+
function getPrioritizedCombinedSubmoduleIds(submodules) {
|
|
494
|
+
const combinedIdStates = submodules
|
|
485
495
|
.filter(i => isPlainObject(i.idObj) && Object.keys(i.idObj).length)
|
|
486
496
|
.reduce((carry, i) => {
|
|
487
497
|
Object.keys(i.idObj).forEach(key => {
|
|
488
|
-
|
|
498
|
+
const maybeCurrentIdPriority = idPriority[key]?.indexOf(i.submodule.name);
|
|
499
|
+
const currentIdPriority = isNumber(maybeCurrentIdPriority) ? maybeCurrentIdPriority : -1;
|
|
500
|
+
const currentIdState = {priority: currentIdPriority, value: i.idObj[key]};
|
|
501
|
+
if (carry[key]) {
|
|
502
|
+
const winnerIdState = currentIdState.priority > carry[key].priority ? currentIdState : carry[key];
|
|
503
|
+
carry[key] = winnerIdState;
|
|
504
|
+
} else {
|
|
505
|
+
carry[key] = currentIdState;
|
|
506
|
+
}
|
|
489
507
|
});
|
|
490
508
|
return carry;
|
|
491
509
|
}, {});
|
|
510
|
+
|
|
511
|
+
const result = {};
|
|
512
|
+
Object.keys(combinedIdStates).forEach(key => {
|
|
513
|
+
result[key] = combinedIdStates[key].value
|
|
514
|
+
});
|
|
515
|
+
return result;
|
|
492
516
|
}
|
|
493
517
|
|
|
494
518
|
/**
|
|
@@ -550,10 +574,13 @@ function idSystemInitializer({delay = GreedyPromise.timeout} = {}) {
|
|
|
550
574
|
function timeGdpr() {
|
|
551
575
|
return gdprDataHandler.promise.finally(initMetrics.startTiming('userId.init.gdpr'));
|
|
552
576
|
}
|
|
577
|
+
function timeGpp() {
|
|
578
|
+
return gppDataHandler.promise.finally(initMetrics.startTiming('userId.init.gpp'))
|
|
579
|
+
}
|
|
553
580
|
|
|
554
581
|
let done = cancelAndTry(
|
|
555
582
|
GreedyPromise.all([hooksReady, startInit.promise])
|
|
556
|
-
.then(timeGdpr)
|
|
583
|
+
.then(() => GreedyPromise.all([timeGdpr(), timeGpp()]).then(([gdpr]) => gdpr))
|
|
557
584
|
.then(checkRefs((consentData) => {
|
|
558
585
|
initSubmodules(initModules, allModules, consentData);
|
|
559
586
|
}))
|
|
@@ -561,7 +588,7 @@ function idSystemInitializer({delay = GreedyPromise.timeout} = {}) {
|
|
|
561
588
|
.then(checkRefs(() => {
|
|
562
589
|
const modWithCb = initModules.filter(item => isFn(item.callback));
|
|
563
590
|
if (modWithCb.length) {
|
|
564
|
-
return new GreedyPromise((resolve) => processSubmoduleCallbacks(modWithCb, resolve));
|
|
591
|
+
return new GreedyPromise((resolve) => processSubmoduleCallbacks(modWithCb, resolve, initModules));
|
|
565
592
|
}
|
|
566
593
|
}))
|
|
567
594
|
);
|
|
@@ -600,7 +627,7 @@ function idSystemInitializer({delay = GreedyPromise.timeout} = {}) {
|
|
|
600
627
|
return sm.callback != null;
|
|
601
628
|
});
|
|
602
629
|
if (cbModules.length) {
|
|
603
|
-
return new GreedyPromise((resolve) => processSubmoduleCallbacks(cbModules, resolve));
|
|
630
|
+
return new GreedyPromise((resolve) => processSubmoduleCallbacks(cbModules, resolve, initModules));
|
|
604
631
|
}
|
|
605
632
|
}))
|
|
606
633
|
);
|
|
@@ -783,7 +810,7 @@ function getUserIdsAsync() {
|
|
|
783
810
|
);
|
|
784
811
|
}
|
|
785
812
|
|
|
786
|
-
function populateSubmoduleId(submodule, consentData, storedConsentData, forceRefresh) {
|
|
813
|
+
function populateSubmoduleId(submodule, consentData, storedConsentData, forceRefresh, allSubmodules) {
|
|
787
814
|
// There are two submodule configuration types to handle: storage or value
|
|
788
815
|
// 1. storage: retrieve user id data from cookie/html storage or with the submodule's getId method
|
|
789
816
|
// 2. value: pass directly to bids
|
|
@@ -832,7 +859,7 @@ function populateSubmoduleId(submodule, consentData, storedConsentData, forceRef
|
|
|
832
859
|
if (response.id) { submodule.idObj = submodule.submodule.decode(response.id, submodule.config); }
|
|
833
860
|
}
|
|
834
861
|
}
|
|
835
|
-
updatePPID(
|
|
862
|
+
updatePPID(getCombinedSubmoduleIds(allSubmodules));
|
|
836
863
|
}
|
|
837
864
|
|
|
838
865
|
function updatePPID(userIds = getUserIds()) {
|
|
@@ -879,7 +906,7 @@ function initSubmodules(dest, submodules, consentData, forceRefresh = false) {
|
|
|
879
906
|
const initialized = submodules.reduce((carry, submodule) => {
|
|
880
907
|
return submoduleMetrics(submodule.submodule.name).measureTime('init', () => {
|
|
881
908
|
try {
|
|
882
|
-
populateSubmoduleId(submodule, consentData, storedConsentData, forceRefresh);
|
|
909
|
+
populateSubmoduleId(submodule, consentData, storedConsentData, forceRefresh, submodules);
|
|
883
910
|
carry.push(submodule);
|
|
884
911
|
} catch (e) {
|
|
885
912
|
logError(`Error in userID module '${submodule.submodule.name}':`, e);
|
|
@@ -1010,6 +1037,25 @@ function updateSubmodules() {
|
|
|
1010
1037
|
}
|
|
1011
1038
|
}
|
|
1012
1039
|
|
|
1040
|
+
/**
|
|
1041
|
+
* This function will update the idPriority according to the provided configuration
|
|
1042
|
+
* @param {Object} idPriorityConfig
|
|
1043
|
+
* @param {SubmoduleContainer[]} submodules
|
|
1044
|
+
*/
|
|
1045
|
+
function updateIdPriority(idPriorityConfig, submodules) {
|
|
1046
|
+
if (idPriorityConfig) {
|
|
1047
|
+
const result = {};
|
|
1048
|
+
const aliasToName = new Map(submodules.map(s => s.submodule.aliasName ? [s.submodule.aliasName, s.submodule.name] : []));
|
|
1049
|
+
Object.keys(idPriorityConfig).forEach(key => {
|
|
1050
|
+
const priority = isArray(idPriorityConfig[key]) ? [...idPriorityConfig[key]].reverse() : []
|
|
1051
|
+
result[key] = priority.map(s => aliasToName.has(s) ? aliasToName.get(s) : s);
|
|
1052
|
+
});
|
|
1053
|
+
idPriority = result;
|
|
1054
|
+
} else {
|
|
1055
|
+
idPriority = {};
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1013
1059
|
export function requestDataDeletion(next, ...args) {
|
|
1014
1060
|
logInfo('UserID: received data deletion request; deleting all stored IDs...')
|
|
1015
1061
|
submodules.forEach(submodule => {
|
|
@@ -1069,13 +1115,16 @@ export function init(config, {delay = GreedyPromise.timeout} = {}) {
|
|
|
1069
1115
|
configListener = config.getConfig('userSync', conf => {
|
|
1070
1116
|
// Note: support for 'usersync' was dropped as part of Prebid.js 4.0
|
|
1071
1117
|
const userSync = conf.userSync;
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1118
|
+
if (userSync) {
|
|
1119
|
+
ppidSource = userSync.ppid;
|
|
1120
|
+
if (userSync.userIds) {
|
|
1121
|
+
configRegistry = userSync.userIds;
|
|
1122
|
+
syncDelay = isNumber(userSync.syncDelay) ? userSync.syncDelay : DEFAULT_SYNC_DELAY;
|
|
1123
|
+
auctionDelay = isNumber(userSync.auctionDelay) ? userSync.auctionDelay : NO_AUCTION_DELAY;
|
|
1124
|
+
updateSubmodules();
|
|
1125
|
+
updateIdPriority(userSync.idPriority, submodules);
|
|
1126
|
+
initIdSystem({ready: true});
|
|
1127
|
+
}
|
|
1079
1128
|
}
|
|
1080
1129
|
});
|
|
1081
1130
|
|
package/modules/userId/userId.md
CHANGED
package/package.json
CHANGED
package/src/activities/params.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {MODULE_TYPE_BIDDER} from './modules.js';
|
|
2
|
+
import {hook} from '../hook.js';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Component ID - who is trying to perform the activity?
|
|
@@ -54,6 +55,8 @@ export function activityParamsBuilder(resolveAlias) {
|
|
|
54
55
|
if (moduleType === MODULE_TYPE_BIDDER) {
|
|
55
56
|
defaults[ACTIVITY_PARAM_ADAPTER_CODE] = resolveAlias(moduleName);
|
|
56
57
|
}
|
|
57
|
-
return Object.assign(defaults, params);
|
|
58
|
+
return buildActivityParams(Object.assign(defaults, params));
|
|
58
59
|
}
|
|
59
60
|
}
|
|
61
|
+
|
|
62
|
+
export const buildActivityParams = hook('sync', params => params);
|