prebid.js 7.17.0 → 7.19.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/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adfBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/adqueryBidAdapter.js +1 -1
- package/dist/adqueryIdSystem.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/audiencerunBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/{andBeyondMediaBidAdapter.js → beyondmediaBidAdapter.js} +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/bidwatchAnalyticsAdapter.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/carodaBidAdapter.js +1 -1
- package/dist/cleanioRtdProvider.js +1 -1
- package/dist/colossussspBidAdapter.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantAnalyticsAdapter.js +1 -0
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/debugging-standalone.js +1 -1
- package/dist/debugging.js +1 -1
- package/dist/dependencies.json +6 -0
- package/dist/dgkeywordRtdProvider.js +1 -1
- package/dist/dianomiBidAdapter.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/enrichmentFpdModule.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/fpd.js +1 -0
- package/dist/glimpseBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gridNMBidAdapter.js +1 -1
- package/dist/growthCodeIdSystem.js +1 -0
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.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/ixBidAdapter.js +1 -1
- package/dist/jixieBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/lifestreetBidAdapter.js +1 -1
- package/dist/liveIntentIdSystem.js +1 -1
- package/dist/liveyieldAnalyticsAdapter.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.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/minutemediaBidAdapter.js +1 -1
- package/dist/nativoBidAdapter.js +1 -1
- package/dist/nextMillenniumBidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +133 -130
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +1 -1
- package/dist/prebidServerBidAdapter.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/rubiconAnalyticsAdapter.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/sublimeBidAdapter.js +1 -1
- package/dist/synacormediaBidAdapter.js +1 -1
- package/dist/taboolaBidAdapter.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/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/yandexBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/libraries/fpd/sua.js +98 -0
- package/modules/adagioBidAdapter.js +2 -1
- package/modules/adfBidAdapter.js +1 -1
- package/modules/adkernelAdnBidAdapter.js +1 -0
- package/modules/adqueryBidAdapter.js +4 -2
- package/modules/adqueryIdSystem.js +8 -8
- package/modules/adxcgBidAdapter.js +1 -1
- package/modules/amxBidAdapter.js +1 -1
- package/modules/{andBeyondMediaBidAdapter.js → beyondmediaBidAdapter.js} +0 -0
- package/modules/{andBeyondMediaBidAdapter.md → beyondmediaBidAdapter.md} +1 -1
- package/modules/bidwatchAnalyticsAdapter.js +1 -1
- package/modules/cleanioRtdProvider.js +3 -4
- package/modules/colossussspBidAdapter.js +2 -1
- package/modules/conversantAnalyticsAdapter.js +560 -0
- package/modules/conversantAnalyticsAdapter.md +47 -0
- package/modules/criteoBidAdapter.js +1 -1
- package/modules/debugging/bidInterceptor.js +2 -2
- package/modules/debugging/debugging.js +10 -2
- package/modules/dgkeywordRtdProvider.js +21 -3
- package/modules/dianomiBidAdapter.js +1 -1
- package/modules/enrichmentFpdModule.js +33 -14
- package/modules/finativeBidAdapter.js +1 -1
- package/modules/gridBidAdapter.js +188 -118
- package/modules/growthCodeIdSystem.js +164 -0
- package/modules/growthCodeIdSystem.md +37 -0
- package/modules/improvedigitalBidAdapter.js +2 -2
- package/modules/ixBidAdapter.js +94 -23
- package/modules/liveIntentIdSystem.js +39 -5
- package/modules/mediakeysBidAdapter.js +6 -1
- package/modules/mediakeysBidAdapter.md +50 -40
- package/modules/nativoBidAdapter.js +3 -2
- package/modules/nextMillenniumBidAdapter.js +34 -11
- package/modules/prebidServerBidAdapter/index.js +44 -13
- package/modules/readpeakBidAdapter.js +1 -1
- package/modules/rubiconBidAdapter.js +2 -3
- package/modules/seedingAllianceBidAdapter.js +1 -1
- package/modules/seedtagBidAdapter.js +4 -0
- package/modules/sharethroughBidAdapter.js +1 -1
- package/modules/taboolaBidAdapter.js +4 -8
- package/modules/talkadsBidAdapter.js +1 -0
- package/modules/truereachBidAdapter.js +1 -0
- package/modules/ttdBidAdapter.js +1 -1
- package/modules/userId/eids.js +19 -0
- package/modules/vidazooBidAdapter.js +1 -1
- package/modules/vuukleBidAdapter.js +34 -3
- package/modules/yahoosspBidAdapter.js +3 -1
- package/modules/yandexBidAdapter.js +31 -8
- package/package.json +2 -2
- package/src/adapterManager.js +2 -4
- package/src/cpmBucketManager.js +22 -3
- package/src/native.js +1 -5
- package/src/prebid.js +3 -3
- package/test/spec/cpmBucketManager_spec.js +239 -177
- package/test/spec/fpd/sua_spec.js +244 -0
- package/test/spec/modules/adagioBidAdapter_spec.js +23 -0
- package/test/spec/modules/adfBidAdapter_spec.js +2 -3
- package/test/spec/modules/adqueryBidAdapter_spec.js +11 -0
- package/test/spec/modules/adqueryIdSystem_spec.js +0 -2
- package/test/spec/modules/adxcgBidAdapter_spec.js +2 -3
- package/test/spec/modules/amxBidAdapter_spec.js +3 -2
- package/test/spec/modules/{andBeyondMediaBidAdapter_spec.js → beyondmediaBidAdapter_spec.js} +1 -1
- package/test/spec/modules/bidwatchAnalyticsAdapter_spec.js +2 -0
- package/test/spec/modules/colossussspBidAdapter_spec.js +4 -2
- package/test/spec/modules/conversantAnalyticsAdapter_spec.js +963 -0
- package/test/spec/modules/debugging_mod_spec.js +9 -0
- package/test/spec/modules/dgkeywordRtdProvider_spec.js +83 -1
- package/test/spec/modules/dianomiBidAdapter_spec.js +2 -3
- package/test/spec/modules/enrichmentFpdModule_spec.js +50 -7
- package/test/spec/modules/fpdModule_spec.js +9 -0
- package/test/spec/modules/gridBidAdapter_spec.js +87 -31
- package/test/spec/modules/growthCodeIdSystem_spec.js +83 -0
- package/test/spec/modules/ixBidAdapter_spec.js +221 -2
- package/test/spec/modules/liveIntentIdMinimalSystem_spec.js +62 -8
- package/test/spec/modules/liveIntentIdSystem_spec.js +62 -8
- package/test/spec/modules/mediakeysBidAdapter_spec.js +20 -3
- package/test/spec/modules/nativoBidAdapter_spec.js +13 -2
- package/test/spec/modules/prebidServerBidAdapter_spec.js +171 -4
- package/test/spec/modules/seedtagBidAdapter_spec.js +42 -0
- package/test/spec/modules/sharethroughBidAdapter_spec.js +2 -1
- package/test/spec/modules/taboolaBidAdapter_spec.js +2 -2
- package/test/spec/modules/ttdBidAdapter_spec.js +3 -3
- package/test/spec/modules/vuukleBidAdapter_spec.js +87 -0
- package/test/spec/modules/yahoosspBidAdapter_spec.js +3 -1
- package/test/spec/modules/yandexBidAdapter_spec.js +8 -5
- package/test/spec/native_spec.js +5 -0
- package/test/spec/unit/pbjs_api_spec.js +44 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This module adds GrowthCodeId to the User ID module
|
|
3
|
+
* The {@link module:modules/userId} module is required
|
|
4
|
+
* @module modules/growthCodeIdSystem
|
|
5
|
+
* @requires module:modules/userId
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {logError, logInfo, tryAppendQueryString} from '../src/utils.js';
|
|
9
|
+
import {ajax} from '../src/ajax.js';
|
|
10
|
+
import { submodule } from '../src/hook.js'
|
|
11
|
+
import { getStorageManager } from '../src/storageManager.js';
|
|
12
|
+
|
|
13
|
+
const GCID_EXPIRY = 45;
|
|
14
|
+
const MODULE_NAME = 'growthCodeId';
|
|
15
|
+
const GC_DATA_KEY = '_gc_data';
|
|
16
|
+
const ENDPOINT_URL = 'https://p2.gcprivacy.com/v1/pb?'
|
|
17
|
+
|
|
18
|
+
export const storage = getStorageManager({ gvlid: undefined, moduleName: MODULE_NAME });
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Read GrowthCode data from cookie or local storage
|
|
22
|
+
* @param key
|
|
23
|
+
* @return {string}
|
|
24
|
+
*/
|
|
25
|
+
export function readData(key) {
|
|
26
|
+
try {
|
|
27
|
+
if (storage.hasLocalStorage()) {
|
|
28
|
+
return storage.getDataFromLocalStorage(key);
|
|
29
|
+
}
|
|
30
|
+
if (storage.cookiesAreEnabled()) {
|
|
31
|
+
return storage.getCookie(key);
|
|
32
|
+
}
|
|
33
|
+
} catch (error) {
|
|
34
|
+
logError(error);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Store GrowthCode data in either cookie or local storage
|
|
40
|
+
* expiration date: 45 days
|
|
41
|
+
* @param key
|
|
42
|
+
* @param {string} value
|
|
43
|
+
*/
|
|
44
|
+
function storeData(key, value) {
|
|
45
|
+
try {
|
|
46
|
+
logInfo(MODULE_NAME + ': storing data: key=' + key + ' value=' + value);
|
|
47
|
+
|
|
48
|
+
if (value) {
|
|
49
|
+
if (storage.hasLocalStorage()) {
|
|
50
|
+
storage.setDataInLocalStorage(key, value);
|
|
51
|
+
}
|
|
52
|
+
const expiresStr = (new Date(Date.now() + (GCID_EXPIRY * (60 * 60 * 24 * 1000)))).toUTCString();
|
|
53
|
+
if (storage.cookiesAreEnabled()) {
|
|
54
|
+
storage.setCookie(key, value, expiresStr, 'LAX');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
} catch (error) {
|
|
58
|
+
logError(error);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Parse json if possible, else return null
|
|
64
|
+
* @param data
|
|
65
|
+
* @param {object|null}
|
|
66
|
+
*/
|
|
67
|
+
function tryParse(data) {
|
|
68
|
+
try {
|
|
69
|
+
return JSON.parse(data);
|
|
70
|
+
} catch (err) {
|
|
71
|
+
logError(err);
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** @type {Submodule} */
|
|
77
|
+
export const growthCodeIdSubmodule = {
|
|
78
|
+
/**
|
|
79
|
+
* used to link submodule with config
|
|
80
|
+
* @type {string}
|
|
81
|
+
*/
|
|
82
|
+
name: MODULE_NAME,
|
|
83
|
+
/**
|
|
84
|
+
* decode the stored id value for passing to bid requests
|
|
85
|
+
* @function
|
|
86
|
+
* @param {{string}} value
|
|
87
|
+
* @returns {{growthCodeId: {string}}|undefined}
|
|
88
|
+
*/
|
|
89
|
+
decode(value) {
|
|
90
|
+
return value && value !== '' ? { 'growthCodeId': value } : undefined;
|
|
91
|
+
},
|
|
92
|
+
/**
|
|
93
|
+
* performs action to obtain id and return a value in the callback's response argument
|
|
94
|
+
* @function
|
|
95
|
+
* @param {SubmoduleConfig} [config]
|
|
96
|
+
* @returns {IdResponse|undefined}
|
|
97
|
+
*/
|
|
98
|
+
getId(config, consentData) {
|
|
99
|
+
const configParams = (config && config.params) || {};
|
|
100
|
+
if (!configParams || typeof configParams.pid !== 'string') {
|
|
101
|
+
logError('User ID - GrowthCodeID submodule requires a valid Partner ID to be defined');
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const gdpr = (consentData && typeof consentData.gdprApplies === 'boolean' && consentData.gdprApplies) ? 1 : 0;
|
|
106
|
+
const consentString = gdpr ? consentData.consentString : '';
|
|
107
|
+
if (gdpr && !consentString) {
|
|
108
|
+
logInfo('Consent string is required to call GrowthCode id.');
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
let publisherId = configParams.publisher_id ? configParams.publisher_id : '_sharedID';
|
|
113
|
+
|
|
114
|
+
let sharedId;
|
|
115
|
+
if (configParams.publisher_id_storage === 'html5') {
|
|
116
|
+
sharedId = storage.getDataFromLocalStorage(publisherId, null) ? (storage.getDataFromLocalStorage(publisherId, null)) : null;
|
|
117
|
+
} else {
|
|
118
|
+
sharedId = storage.getCookie(publisherId, null) ? (storage.getCookie(publisherId, null)) : null;
|
|
119
|
+
}
|
|
120
|
+
if (!sharedId) {
|
|
121
|
+
logError('User ID - Publisher ID is not correctly setup.');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const resp = function(callback) {
|
|
125
|
+
let gcData = tryParse(readData(GC_DATA_KEY));
|
|
126
|
+
if (gcData) {
|
|
127
|
+
callback(gcData);
|
|
128
|
+
} else {
|
|
129
|
+
let segment = window.location.pathname.substr(1).replace(/\/+$/, '');
|
|
130
|
+
if (segment === '') {
|
|
131
|
+
segment = 'home';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
let url = configParams.url ? configParams.url : ENDPOINT_URL;
|
|
135
|
+
url = tryAppendQueryString(url, 'pid', configParams.pid);
|
|
136
|
+
url = tryAppendQueryString(url, 'uid', sharedId);
|
|
137
|
+
url = tryAppendQueryString(url, 'u', window.location.href);
|
|
138
|
+
url = tryAppendQueryString(url, 'h', window.location.hostname);
|
|
139
|
+
url = tryAppendQueryString(url, 's', segment);
|
|
140
|
+
url = tryAppendQueryString(url, 'r', document.referrer);
|
|
141
|
+
|
|
142
|
+
ajax(url, {
|
|
143
|
+
success: response => {
|
|
144
|
+
let respJson = tryParse(response);
|
|
145
|
+
// If response is a valid json and should save is true
|
|
146
|
+
if (respJson) {
|
|
147
|
+
storeData(GC_DATA_KEY, JSON.stringify(respJson))
|
|
148
|
+
callback(respJson);
|
|
149
|
+
} else {
|
|
150
|
+
callback();
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
error: error => {
|
|
154
|
+
logError(MODULE_NAME + ': ID fetch encountered an error', error);
|
|
155
|
+
callback();
|
|
156
|
+
}
|
|
157
|
+
}, undefined, {method: 'GET', withCredentials: true})
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
return { callback: resp };
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
submodule('userId', growthCodeIdSubmodule);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
## GrowthCode User ID Submodule
|
|
2
|
+
|
|
3
|
+
GrowthCode provides Id Enrichment for requests.
|
|
4
|
+
|
|
5
|
+
## Building Prebid with GrowthCode Support
|
|
6
|
+
|
|
7
|
+
First, make sure to add the GrowthCode submodule to your Prebid.js package with:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
gulp build --modules=growthCodeIdSystem,userId
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The following configuration parameters are available:
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
pbjs.setConfig({
|
|
17
|
+
userSync: {
|
|
18
|
+
userIds: [{
|
|
19
|
+
name: 'growthCodeId',
|
|
20
|
+
params: {
|
|
21
|
+
pid: 'TEST01', // Set your Partner ID here for production (obtained from Growthcode)
|
|
22
|
+
publisher_id: '_sharedID',
|
|
23
|
+
publisher_id_storage: 'html5'
|
|
24
|
+
}
|
|
25
|
+
}]
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
| Param under userSync.userIds[] | Scope | Type | Description | Example |
|
|
31
|
+
|--------------------------------|----------|--------| --- |-----------------|
|
|
32
|
+
| name | Required | String | The name of this module. | `"growthCodeId"` |
|
|
33
|
+
| params | Required | Object | Details of module params. | |
|
|
34
|
+
| params.pid | Required | String | This is the Parter ID value obtained from GrowthCode | `"TEST01"` |
|
|
35
|
+
| params.url | Optional | String | Custom URL for server | |
|
|
36
|
+
| params.publisher_id | Optional | String | Name if the variable that holds your publisher ID | `"_sharedID"` |
|
|
37
|
+
| params.publisher_id_storage | Optional | String | Publisher ID storage (cookie, html5) | `"html5"` |
|
|
@@ -307,10 +307,10 @@ const ID_REQUEST = {
|
|
|
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
309
|
if (extendImps.length) {
|
|
310
|
-
requests.push(formatRequest(extendImps,
|
|
310
|
+
requests.push(formatRequest(extendImps, bidderRequest.auctionId, true));
|
|
311
311
|
}
|
|
312
312
|
if (adServerImps.length) {
|
|
313
|
-
requests.push(formatRequest(adServerImps,
|
|
313
|
+
requests.push(formatRequest(adServerImps, bidderRequest.auctionId, false));
|
|
314
314
|
}
|
|
315
315
|
|
|
316
316
|
return requests;
|
package/modules/ixBidAdapter.js
CHANGED
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
logError,
|
|
14
14
|
logWarn,
|
|
15
15
|
mergeDeep,
|
|
16
|
-
parseQueryStringParameters
|
|
16
|
+
parseQueryStringParameters,
|
|
17
|
+
safeJSONParse
|
|
17
18
|
} from '../src/utils.js';
|
|
18
19
|
import {BANNER, VIDEO, NATIVE} from '../src/mediaTypes.js';
|
|
19
20
|
import {config} from '../src/config.js';
|
|
@@ -99,8 +100,46 @@ const VIDEO_PARAMS_ALLOW_LIST = [
|
|
|
99
100
|
'playerSize', 'w', 'h'
|
|
100
101
|
];
|
|
101
102
|
const LOCAL_STORAGE_KEY = 'ixdiag';
|
|
103
|
+
export const LOCAL_STORAGE_FEATURE_TOGGLES_KEY = `${BIDDER_CODE}_features`;
|
|
102
104
|
let hasRegisteredHandler = false;
|
|
103
105
|
export const storage = getStorageManager({gvlid: GLOBAL_VENDOR_ID, bidderCode: BIDDER_CODE});
|
|
106
|
+
export const FEATURE_TOGGLES = {
|
|
107
|
+
featureToggles: {},
|
|
108
|
+
isFeatureEnabled: function(ft) {
|
|
109
|
+
return deepAccess(this.featureToggles, `features.${ft}.activated`)
|
|
110
|
+
},
|
|
111
|
+
getFeatureToggles: function() {
|
|
112
|
+
if (storage.localStorageIsEnabled()) {
|
|
113
|
+
const parsedToggles = safeJSONParse(storage.getDataFromLocalStorage(LOCAL_STORAGE_FEATURE_TOGGLES_KEY));
|
|
114
|
+
if (deepAccess(parsedToggles, 'expiry') && parsedToggles.expiry >= new Date().getTime()) {
|
|
115
|
+
this.featureToggles = parsedToggles
|
|
116
|
+
} else {
|
|
117
|
+
this.clearFeatureToggles();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
setFeatureToggles: function(serverResponse) {
|
|
122
|
+
const responseBody = serverResponse.body;
|
|
123
|
+
const expiryTime = new Date();
|
|
124
|
+
const toggles = deepAccess(responseBody, 'ext.features');
|
|
125
|
+
|
|
126
|
+
if (toggles) {
|
|
127
|
+
this.featureToggles = {
|
|
128
|
+
expiry: expiryTime.setHours(expiryTime.getHours() + 1),
|
|
129
|
+
features: toggles
|
|
130
|
+
}
|
|
131
|
+
if (storage.localStorageIsEnabled()) {
|
|
132
|
+
storage.setDataInLocalStorage(LOCAL_STORAGE_FEATURE_TOGGLES_KEY, JSON.stringify(this.featureToggles));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
clearFeatureToggles: function() {
|
|
137
|
+
this.featureToggles = {};
|
|
138
|
+
if (storage.localStorageIsEnabled()) {
|
|
139
|
+
storage.removeDataFromLocalStorage(LOCAL_STORAGE_FEATURE_TOGGLES_KEY);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
};
|
|
104
143
|
let siteID = 0;
|
|
105
144
|
let gdprConsent = '';
|
|
106
145
|
let usPrivacy = '';
|
|
@@ -578,6 +617,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
|
|
|
578
617
|
r.ext = {};
|
|
579
618
|
r.ext.source = 'prebid';
|
|
580
619
|
r.ext.ixdiag = {};
|
|
620
|
+
r.ext.ixdiag.ls = storage.localStorageIsEnabled();
|
|
581
621
|
r.imp = [];
|
|
582
622
|
r.at = 1;
|
|
583
623
|
|
|
@@ -602,13 +642,15 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
|
|
|
602
642
|
r.ext.ixdiag.err = cachedErrors;
|
|
603
643
|
}
|
|
604
644
|
|
|
645
|
+
// set source.tid to auctionId for outgoing request to Exchange.
|
|
646
|
+
r.source = {
|
|
647
|
+
tid: validBidRequests[0].auctionId,
|
|
648
|
+
}
|
|
649
|
+
|
|
605
650
|
// if an schain is provided, send it along
|
|
606
651
|
if (validBidRequests[0].schain) {
|
|
607
|
-
r.source = {
|
|
608
|
-
|
|
609
|
-
schain: validBidRequests[0].schain
|
|
610
|
-
}
|
|
611
|
-
};
|
|
652
|
+
r.source.ext = {};
|
|
653
|
+
r.source.ext.schain = validBidRequests[0].schain;
|
|
612
654
|
}
|
|
613
655
|
|
|
614
656
|
if (userEids.length > 0) {
|
|
@@ -665,14 +707,17 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
|
|
|
665
707
|
// Use the siteId in the first bid request as the main siteId.
|
|
666
708
|
siteID = validBidRequests[0].params.siteId;
|
|
667
709
|
payload.s = siteID;
|
|
668
|
-
if (version) {
|
|
669
|
-
payload.v = version;
|
|
670
|
-
}
|
|
671
|
-
payload.ac = 'j';
|
|
672
|
-
payload.sd = 1;
|
|
673
710
|
|
|
674
|
-
if (
|
|
675
|
-
|
|
711
|
+
if (!FEATURE_TOGGLES.isFeatureEnabled('pbjs_enable_post')) {
|
|
712
|
+
if (version) {
|
|
713
|
+
payload.v = version;
|
|
714
|
+
}
|
|
715
|
+
payload.ac = 'j';
|
|
716
|
+
payload.sd = 1;
|
|
717
|
+
|
|
718
|
+
if (version === VIDEO_ENDPOINT_VERSION) {
|
|
719
|
+
payload.nf = 1;
|
|
720
|
+
}
|
|
676
721
|
}
|
|
677
722
|
|
|
678
723
|
// Parse additional runtime configs.
|
|
@@ -718,9 +763,11 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
|
|
|
718
763
|
}
|
|
719
764
|
}
|
|
720
765
|
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
766
|
+
if (!FEATURE_TOGGLES.isFeatureEnabled('pbjs_enable_post')) {
|
|
767
|
+
// Create t in payload if timeout is configured.
|
|
768
|
+
if (typeof otherIxConfig.timeout === 'number') {
|
|
769
|
+
payload.t = otherIxConfig.timeout;
|
|
770
|
+
}
|
|
724
771
|
}
|
|
725
772
|
}
|
|
726
773
|
|
|
@@ -866,12 +913,27 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
|
|
|
866
913
|
requestSequenceNumber++;
|
|
867
914
|
clonedPayload.r = JSON.stringify(r);
|
|
868
915
|
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
916
|
+
let requestData;
|
|
917
|
+
|
|
918
|
+
if (FEATURE_TOGGLES.isFeatureEnabled('pbjs_enable_post')) {
|
|
919
|
+
requestData = {
|
|
920
|
+
method: 'POST',
|
|
921
|
+
url: baseUrl + '?s=' + payload.s,
|
|
922
|
+
data: deepClone(r),
|
|
923
|
+
option: {
|
|
924
|
+
contentType: 'text/plain',
|
|
925
|
+
},
|
|
926
|
+
validBidRequests
|
|
927
|
+
}
|
|
928
|
+
} else {
|
|
929
|
+
requestData = {
|
|
930
|
+
method: 'GET',
|
|
931
|
+
url: baseUrl,
|
|
932
|
+
data: clonedPayload,
|
|
933
|
+
validBidRequests
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
requests.push(requestData);
|
|
875
937
|
|
|
876
938
|
currentRequestSize = baseRequestSize;
|
|
877
939
|
r.imp = [];
|
|
@@ -1381,6 +1443,7 @@ export const spec = {
|
|
|
1381
1443
|
const videoImps = {}; // Stores created video impressions
|
|
1382
1444
|
const nativeImps = {}; // Stores created native impressions
|
|
1383
1445
|
const missingBannerSizes = {}; // To capture the missing sizes i.e not configured for ix
|
|
1446
|
+
FEATURE_TOGGLES.getFeatureToggles();
|
|
1384
1447
|
|
|
1385
1448
|
// Step 1: Create impresssions from IX params
|
|
1386
1449
|
validBidRequests.forEach((validBidRequest) => {
|
|
@@ -1451,6 +1514,7 @@ export const spec = {
|
|
|
1451
1514
|
let bid = null;
|
|
1452
1515
|
|
|
1453
1516
|
if (!serverResponse.hasOwnProperty('body') || !serverResponse.body.hasOwnProperty('seatbid')) {
|
|
1517
|
+
FEATURE_TOGGLES.setFeatureToggles(serverResponse);
|
|
1454
1518
|
return bids;
|
|
1455
1519
|
}
|
|
1456
1520
|
|
|
@@ -1463,7 +1527,13 @@ export const spec = {
|
|
|
1463
1527
|
|
|
1464
1528
|
// Transform rawBid in bid response to the format that will be accepted by prebid.
|
|
1465
1529
|
const innerBids = seatbid[i].bid;
|
|
1466
|
-
let requestBid
|
|
1530
|
+
let requestBid;
|
|
1531
|
+
|
|
1532
|
+
if (FEATURE_TOGGLES.isFeatureEnabled('pbjs_enable_post')) {
|
|
1533
|
+
requestBid = bidderRequest.data;
|
|
1534
|
+
} else {
|
|
1535
|
+
requestBid = safeJSONParse(bidderRequest.data.r);
|
|
1536
|
+
}
|
|
1467
1537
|
|
|
1468
1538
|
for (let j = 0; j < innerBids.length; j++) {
|
|
1469
1539
|
const bidRequest = getBidRequest(innerBids[j].impid, requestBid.imp, bidderRequest.validBidRequests);
|
|
@@ -1491,6 +1561,7 @@ export const spec = {
|
|
|
1491
1561
|
}
|
|
1492
1562
|
}
|
|
1493
1563
|
|
|
1564
|
+
FEATURE_TOGGLES.setFeatureToggles(serverResponse);
|
|
1494
1565
|
return bids;
|
|
1495
1566
|
},
|
|
1496
1567
|
|
|
@@ -14,6 +14,7 @@ import { MinimalLiveConnect } from 'live-connect-js/esm/minimal-live-connect.js'
|
|
|
14
14
|
|
|
15
15
|
const MODULE_NAME = 'liveIntentId';
|
|
16
16
|
export const storage = getStorageManager({gvlid: null, moduleName: MODULE_NAME});
|
|
17
|
+
const defaultRequestedAttributes = {'nonId': true}
|
|
17
18
|
const calls = {
|
|
18
19
|
ajaxGet: (url, onSuccess, onError, timeout) => {
|
|
19
20
|
ajaxBuilder(timeout)(
|
|
@@ -57,6 +58,23 @@ function parseLiveIntentCollectorConfig(collectConfig) {
|
|
|
57
58
|
return config;
|
|
58
59
|
}
|
|
59
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Create requestedAttributes array to pass to liveconnect
|
|
63
|
+
* @function
|
|
64
|
+
* @param {Object} overrides - object with boolean values that will override defaults { 'foo': true, 'bar': false }
|
|
65
|
+
* @returns {Array}
|
|
66
|
+
*/
|
|
67
|
+
function parseRequestedAttributes(overrides) {
|
|
68
|
+
function createParameterArray(config) {
|
|
69
|
+
return Object.entries(config).flatMap(([k, v]) => (typeof v === 'boolean' && v) ? [k] : []);
|
|
70
|
+
}
|
|
71
|
+
if (typeof overrides === 'object') {
|
|
72
|
+
return createParameterArray({...defaultRequestedAttributes, ...overrides})
|
|
73
|
+
} else {
|
|
74
|
+
return createParameterArray(defaultRequestedAttributes);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
60
78
|
function initializeLiveConnect(configParams) {
|
|
61
79
|
configParams = configParams || {};
|
|
62
80
|
if (liveConnect) {
|
|
@@ -66,7 +84,8 @@ function initializeLiveConnect(configParams) {
|
|
|
66
84
|
const publisherId = configParams.publisherId || 'any';
|
|
67
85
|
const identityResolutionConfig = {
|
|
68
86
|
source: 'prebid',
|
|
69
|
-
publisherId: publisherId
|
|
87
|
+
publisherId: publisherId,
|
|
88
|
+
requestedAttributes: parseRequestedAttributes(configParams.requestedAttributesOverrides)
|
|
70
89
|
};
|
|
71
90
|
if (configParams.url) {
|
|
72
91
|
identityResolutionConfig.url = configParams.url
|
|
@@ -136,9 +155,24 @@ export const liveIntentIdSubmodule = {
|
|
|
136
155
|
decode(value, config) {
|
|
137
156
|
const configParams = (config && config.params) || {};
|
|
138
157
|
function composeIdObject(value) {
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
158
|
+
const result = {};
|
|
159
|
+
|
|
160
|
+
// old versions stored lipbid in unifiedId. Ensure that we can still read the data.
|
|
161
|
+
const lipbid = value.nonId || value.unifiedId
|
|
162
|
+
if (lipbid) {
|
|
163
|
+
value.lipbid = lipbid
|
|
164
|
+
delete value.unifiedId
|
|
165
|
+
result.lipb = value
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Lift usage of uid2 by exposing uid2 if we were asked to resolve it.
|
|
169
|
+
// As adapters are applied in lexicographical order, we will always
|
|
170
|
+
// be overwritten by the 'proper' uid2 module if it is present.
|
|
171
|
+
if (value.uid2) {
|
|
172
|
+
result.uid2 = { 'id': value.uid2 }
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return result
|
|
142
176
|
}
|
|
143
177
|
|
|
144
178
|
if (!liveConnect) {
|
|
@@ -146,7 +180,7 @@ export const liveIntentIdSubmodule = {
|
|
|
146
180
|
}
|
|
147
181
|
tryFireEvent();
|
|
148
182
|
|
|
149
|
-
return
|
|
183
|
+
return composeIdObject(value);
|
|
150
184
|
},
|
|
151
185
|
|
|
152
186
|
/**
|
|
@@ -572,7 +572,12 @@ function nativeBidResponseHandler(bid) {
|
|
|
572
572
|
native.impressionTrackers.push(tracker.url);
|
|
573
573
|
break;
|
|
574
574
|
case 2:
|
|
575
|
-
|
|
575
|
+
const script = `<script async src=\"${tracker.url}\"></script>`;
|
|
576
|
+
if (!native.javascriptTrackers) {
|
|
577
|
+
native.javascriptTrackers = script;
|
|
578
|
+
} else {
|
|
579
|
+
native.javascriptTrackers += `\n${script}`;
|
|
580
|
+
}
|
|
576
581
|
break;
|
|
577
582
|
}
|
|
578
583
|
});
|
|
@@ -14,9 +14,10 @@ Connects to Mediakeys demand source to fetch bids.
|
|
|
14
14
|
|
|
15
15
|
## Banner only Ad Unit
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
The Mediakeys adapter accepts any valid OpenRTB Spec 2.5 property.
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
var adUnits = [{
|
|
20
21
|
code: 'test',
|
|
21
22
|
mediaTypes: {
|
|
22
23
|
banner: {
|
|
@@ -27,20 +28,26 @@ var adUnits = [
|
|
|
27
28
|
bidder: 'mediakeys',
|
|
28
29
|
params: {} // no params required.
|
|
29
30
|
}]
|
|
30
|
-
}
|
|
31
|
+
}]
|
|
31
32
|
```
|
|
32
33
|
|
|
33
34
|
## Native only Ad Unit
|
|
34
35
|
|
|
35
36
|
The Mediakeys adapter accepts two optional params for native requests. Please see the [OpenRTB Native Ads Specification](https://www.iab.com/wp-content/uploads/2018/03/OpenRTB-Native-Ads-Specification-Final-1.2.pdf) for valid values.
|
|
36
37
|
|
|
37
|
-
```
|
|
38
|
-
var adUnits = [
|
|
39
|
-
{
|
|
38
|
+
```javascript
|
|
39
|
+
var adUnits = [{
|
|
40
40
|
code: 'test',
|
|
41
41
|
mediaTypes: {
|
|
42
42
|
native: {
|
|
43
|
-
|
|
43
|
+
title: {
|
|
44
|
+
required: true,
|
|
45
|
+
len: 120
|
|
46
|
+
},
|
|
47
|
+
image: {
|
|
48
|
+
required: true,
|
|
49
|
+
sizes: [300, 250]
|
|
50
|
+
}
|
|
44
51
|
}
|
|
45
52
|
},
|
|
46
53
|
bids: [{
|
|
@@ -52,7 +59,7 @@ var adUnits = [
|
|
|
52
59
|
}
|
|
53
60
|
}
|
|
54
61
|
}]
|
|
55
|
-
}
|
|
62
|
+
}]
|
|
56
63
|
```
|
|
57
64
|
|
|
58
65
|
## Video only Ad Unit
|
|
@@ -61,63 +68,65 @@ The Mediakeys adapter accepts any valid openRTB 2.5 video property. Properties c
|
|
|
61
68
|
|
|
62
69
|
### Outstream context
|
|
63
70
|
|
|
64
|
-
```
|
|
65
|
-
var adUnits = [
|
|
66
|
-
{
|
|
71
|
+
```javascript
|
|
72
|
+
var adUnits = [{
|
|
67
73
|
code: 'test',
|
|
68
74
|
mediaTypes: {
|
|
69
75
|
video: {
|
|
70
76
|
context: 'outstream',
|
|
71
|
-
playerSize: [
|
|
77
|
+
playerSize: [1280, 720],
|
|
72
78
|
// additional OpenRTB video params
|
|
73
79
|
// placement: 2,
|
|
74
80
|
// api: [1],
|
|
75
81
|
// …
|
|
82
|
+
mimes: ['video/mp4'],
|
|
83
|
+
protocols: [2, 3],
|
|
84
|
+
skip: 0
|
|
76
85
|
}
|
|
77
86
|
},
|
|
78
87
|
renderer: {
|
|
79
88
|
url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js',
|
|
89
|
+
// the render method must fetch the vast xml document before displaying video
|
|
80
90
|
render: function (bid) {
|
|
81
|
-
var
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
content: text,
|
|
88
|
-
player_width: bid.width || bidReqConfig.mediaTypes.video.playerSize[0],
|
|
89
|
-
player_height: bid.height || bidReqConfig.mediaTypes.video.playerSize[1],
|
|
90
|
-
}
|
|
91
|
+
var adResponse = fetch(bid.vastUrl).then(resp => resp.text()).then(text => ({
|
|
92
|
+
ad: {
|
|
93
|
+
video: {
|
|
94
|
+
content: text,
|
|
95
|
+
player_height: bid.playerHeight,
|
|
96
|
+
player_width: bid.playerWidth
|
|
91
97
|
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
}
|
|
99
|
+
}))
|
|
100
|
+
|
|
101
|
+
adResponse.then((content) => {
|
|
102
|
+
bid.renderer.push(() => {
|
|
103
|
+
ANOutstreamVideo.renderAd({
|
|
104
|
+
targetId: bid.adUnitCode,
|
|
105
|
+
adResponse: content
|
|
100
106
|
});
|
|
101
|
-
})
|
|
102
|
-
}
|
|
107
|
+
});
|
|
108
|
+
})
|
|
103
109
|
}
|
|
104
110
|
},
|
|
105
111
|
bids: [{
|
|
106
112
|
bidder: 'mediakeys',
|
|
107
113
|
params: {
|
|
108
114
|
video: {
|
|
109
|
-
// additional OpenRTB video params.
|
|
115
|
+
// additional OpenRTB video params.
|
|
116
|
+
// will be merged with params defined at mediaTypes level
|
|
117
|
+
api: [1]
|
|
110
118
|
}
|
|
111
119
|
}
|
|
112
120
|
}]
|
|
113
|
-
}
|
|
121
|
+
}]
|
|
114
122
|
```
|
|
115
123
|
|
|
116
124
|
### Instream context
|
|
117
125
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
126
|
+
For Instream Video, you have to enable the Instream Tracking Module to have Prebid emit the onBidWon required event.
|
|
127
|
+
|
|
128
|
+
```javascript
|
|
129
|
+
var adUnits = [{
|
|
121
130
|
code: 'test',
|
|
122
131
|
mediaTypes: {
|
|
123
132
|
video: {
|
|
@@ -132,8 +141,9 @@ var adUnits = [
|
|
|
132
141
|
bids: [{
|
|
133
142
|
bidder: 'mediakeys',
|
|
134
143
|
params: {
|
|
135
|
-
// additional OpenRTB video params.
|
|
144
|
+
// additional OpenRTB video params.
|
|
145
|
+
// will be merged with params defined at mediaTypes level
|
|
136
146
|
}
|
|
137
147
|
}]
|
|
138
|
-
}
|
|
148
|
+
}]
|
|
139
149
|
```
|
|
@@ -145,7 +145,7 @@ export const spec = {
|
|
|
145
145
|
'params.url',
|
|
146
146
|
)
|
|
147
147
|
if (pageUrl == undefined || pageUrl === '') {
|
|
148
|
-
pageUrl = bidderRequest.refererInfo.
|
|
148
|
+
pageUrl = bidderRequest.refererInfo.location
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
placementId = deepAccess(bidRequest, 'params.placementId')
|
|
@@ -465,8 +465,9 @@ export function parseFloorPriceData(bidRequest) {
|
|
|
465
465
|
// Setup price floor data per media type
|
|
466
466
|
let mediaTypeData = bidMediaTypes[mediaType]
|
|
467
467
|
let mediaTypeFloorPriceData = {}
|
|
468
|
+
let mediaTypeSizes = mediaTypeData.sizes || mediaTypeData.playerSize || [];
|
|
468
469
|
// Step through each size of the media type so we can get floor data for each size per media type
|
|
469
|
-
|
|
470
|
+
mediaTypeSizes.forEach((size) => {
|
|
470
471
|
// Get floor price data per the getFloor method and respective media type / size combination
|
|
471
472
|
const priceFloorData = bidRequest.getFloor({
|
|
472
473
|
currency: FLOOR_PRICE_CURRENCY,
|