prebid.js 7.16.0 → 7.18.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/.circleci/config.yml +0 -18
- package/dist/1plusXRtdProvider.js +1 -1
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.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/audiencerunBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.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 -0
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectadBidAdapter.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/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- 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/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/mediagoBidAdapter.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 +121 -119
- 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/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/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/karma.conf.maker.js +2 -4
- package/modules/1plusXRtdProvider.js +27 -7
- package/modules/adagioBidAdapter.js +18 -3
- package/modules/adagioBidAdapter.md +11 -1
- package/modules/adqueryBidAdapter.js +4 -2
- package/modules/appnexusBidAdapter.js +24 -22
- package/modules/bidwatchAnalyticsAdapter.js +1 -1
- package/modules/carodaBidAdapter.js +217 -0
- package/modules/carodaBidAdapter.md +43 -0
- package/modules/gridBidAdapter.js +1 -1
- package/modules/growthCodeIdSystem.js +164 -0
- package/modules/growthCodeIdSystem.md +37 -0
- package/modules/improvedigitalBidAdapter.js +3 -1
- package/modules/ixBidAdapter.js +17 -12
- package/modules/mediagoBidAdapter.js +15 -11
- package/modules/mediasquareBidAdapter.js +1 -1
- package/modules/nativoBidAdapter.js +2 -1
- package/modules/nextMillenniumBidAdapter.js +34 -11
- package/modules/rubiconAnalyticsAdapter.js +2 -2
- package/modules/rubiconBidAdapter.js +16 -6
- package/modules/seedtagBidAdapter.js +4 -0
- package/modules/taboolaBidAdapter.js +3 -7
- package/modules/userId/eids.js +19 -0
- package/modules/vidazooBidAdapter.js +1 -1
- package/package.json +1 -1
- package/test/spec/modules/1plusXRtdProvider_spec.js +77 -1
- package/test/spec/modules/adagioBidAdapter_spec.js +46 -2
- package/test/spec/modules/adqueryBidAdapter_spec.js +11 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +76 -0
- package/test/spec/modules/bidwatchAnalyticsAdapter_spec.js +2 -0
- package/test/spec/modules/carodaBidAdapter_spec.js +494 -0
- package/test/spec/modules/growthCodeIdSystem_spec.js +83 -0
- package/test/spec/modules/improvedigitalBidAdapter_spec.js +10 -0
- package/test/spec/modules/ixBidAdapter_spec.js +32 -16
- package/test/spec/modules/mediasquareBidAdapter_spec.js +2 -0
- package/test/spec/modules/prebidServerBidAdapter_spec.js +12 -0
- package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +7 -7
- package/test/spec/modules/rubiconBidAdapter_spec.js +28 -35
- package/test/spec/modules/seedtagBidAdapter_spec.js +45 -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"` |
|
|
@@ -25,6 +25,7 @@ const BIDDER_CODE = 'improvedigital';
|
|
|
25
25
|
const CREATIVE_TTL = 300;
|
|
26
26
|
|
|
27
27
|
const AD_SERVER_URL = 'https://ad.360yield.com/pb';
|
|
28
|
+
const BASIC_ADS_URL = 'https://ad.360yield-basic.com/pb';
|
|
28
29
|
const EXTEND_URL = 'https://pbs.360yield.com/openrtb2/auction';
|
|
29
30
|
const IFRAME_SYNC_URL = 'https://hb.360yield.com/prebid-universal-creative/load-cookie.html';
|
|
30
31
|
|
|
@@ -282,9 +283,10 @@ const ID_REQUEST = {
|
|
|
282
283
|
if (transactionId) {
|
|
283
284
|
deepSetValue(request, 'source.tid', transactionId);
|
|
284
285
|
}
|
|
286
|
+
const adServerUrl = hasPurpose1Consent(bidderRequest?.gdprConsent) ? AD_SERVER_URL : BASIC_ADS_URL;
|
|
285
287
|
return {
|
|
286
288
|
method: 'POST',
|
|
287
|
-
url: extendMode ? EXTEND_URL :
|
|
289
|
+
url: extendMode ? EXTEND_URL : adServerUrl,
|
|
288
290
|
data: JSON.stringify(request),
|
|
289
291
|
bidderRequest
|
|
290
292
|
}
|
package/modules/ixBidAdapter.js
CHANGED
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
logError,
|
|
14
14
|
logWarn,
|
|
15
15
|
mergeDeep,
|
|
16
|
-
parseGPTSingleSizeArray,
|
|
17
16
|
parseQueryStringParameters
|
|
18
17
|
} from '../src/utils.js';
|
|
19
18
|
import {BANNER, VIDEO, NATIVE} from '../src/mediaTypes.js';
|
|
@@ -127,10 +126,6 @@ function bidToBannerImp(bid) {
|
|
|
127
126
|
if (impSize) {
|
|
128
127
|
imp.banner.w = impSize[0];
|
|
129
128
|
imp.banner.h = impSize[1];
|
|
130
|
-
// populate sid with size if not id
|
|
131
|
-
if (!deepAccess(imp, 'ext.sid')) {
|
|
132
|
-
imp.ext.sid = parseGPTSingleSizeArray(impSize);
|
|
133
|
-
}
|
|
134
129
|
}
|
|
135
130
|
|
|
136
131
|
imp.banner.topframe = inIframe() ? 0 : 1;
|
|
@@ -197,9 +192,6 @@ function bidToVideoImp(bid) {
|
|
|
197
192
|
if (impSize) {
|
|
198
193
|
imp.video.w = impSize[0];
|
|
199
194
|
imp.video.h = impSize[1];
|
|
200
|
-
if (!(deepAccess(imp, 'ext.sid'))) {
|
|
201
|
-
imp.ext.sid = parseGPTSingleSizeArray(impSize);
|
|
202
|
-
}
|
|
203
195
|
} else {
|
|
204
196
|
logWarn('IX Bid Adapter: Video size is missing in [mediaTypes.video]');
|
|
205
197
|
return {};
|
|
@@ -253,8 +245,8 @@ function bidToImp(bid) {
|
|
|
253
245
|
imp.ext = {};
|
|
254
246
|
imp.ext.siteID = bid.params.siteId.toString();
|
|
255
247
|
|
|
256
|
-
|
|
257
|
-
|
|
248
|
+
// populate imp level sid
|
|
249
|
+
if (bid.params.hasOwnProperty('id') && (typeof bid.params.id === 'string' || typeof bid.params.id === 'number')) {
|
|
258
250
|
imp.ext.sid = String(bid.params.id);
|
|
259
251
|
}
|
|
260
252
|
|
|
@@ -758,6 +750,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
|
|
|
758
750
|
const gpid = impressions[transactionIds[adUnitIndex]].gpid;
|
|
759
751
|
const dfpAdUnitCode = impressions[transactionIds[adUnitIndex]].dfp_ad_unit_code;
|
|
760
752
|
const tid = impressions[transactionIds[adUnitIndex]].tid;
|
|
753
|
+
const sid = impressions[transactionIds[adUnitIndex]].sid
|
|
761
754
|
|
|
762
755
|
if (impressionObjects.length && BANNER in impressionObjects[0]) {
|
|
763
756
|
const { id, banner: { topframe } } = impressionObjects[0];
|
|
@@ -769,16 +762,24 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
|
|
|
769
762
|
},
|
|
770
763
|
};
|
|
771
764
|
|
|
765
|
+
// We add sid in imp.ext.sid therefore, remove from banner.format[].ext
|
|
766
|
+
for (let bannerFormat of _bannerImpression.banner.format) {
|
|
767
|
+
if (bannerFormat.ext != null && bannerFormat.ext.sid != null) {
|
|
768
|
+
delete bannerFormat.ext.sid;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
|
|
772
772
|
const position = impressions[transactionIds[adUnitIndex]].pos;
|
|
773
773
|
if (isInteger(position)) {
|
|
774
774
|
_bannerImpression.banner.pos = position;
|
|
775
775
|
}
|
|
776
776
|
|
|
777
|
-
if (dfpAdUnitCode || gpid || tid) {
|
|
777
|
+
if (dfpAdUnitCode || gpid || tid || sid) {
|
|
778
778
|
_bannerImpression.ext = {};
|
|
779
779
|
_bannerImpression.ext.dfp_ad_unit_code = dfpAdUnitCode;
|
|
780
780
|
_bannerImpression.ext.gpid = gpid;
|
|
781
781
|
_bannerImpression.ext.tid = tid;
|
|
782
|
+
_bannerImpression.ext.sid = sid;
|
|
782
783
|
}
|
|
783
784
|
|
|
784
785
|
if ('bidfloor' in impressionObjects[0]) {
|
|
@@ -1040,6 +1041,11 @@ function createBannerImps(validBidRequest, missingBannerSizes, bannerImps) {
|
|
|
1040
1041
|
bannerImps[validBidRequest.transactionId].tagId = deepAccess(validBidRequest, 'params.tagId');
|
|
1041
1042
|
bannerImps[validBidRequest.transactionId].pos = deepAccess(validBidRequest, 'mediaTypes.banner.pos');
|
|
1042
1043
|
|
|
1044
|
+
const sid = deepAccess(validBidRequest, 'params.id');
|
|
1045
|
+
if (sid && (typeof sid === 'string' || typeof sid === 'number')) {
|
|
1046
|
+
bannerImps[validBidRequest.transactionId].sid = String(sid);
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1043
1049
|
const adUnitCode = validBidRequest.adUnitCode;
|
|
1044
1050
|
const divId = document.getElementById(adUnitCode) ? adUnitCode : getGptSlotInfoForAdUnitCode(adUnitCode).divId;
|
|
1045
1051
|
bannerImps[validBidRequest.transactionId].adUnitCode = adUnitCode;
|
|
@@ -1094,7 +1100,6 @@ function updateMissingSizes(validBidRequest, missingBannerSizes, imp) {
|
|
|
1094
1100
|
*/
|
|
1095
1101
|
function createMissingBannerImp(bid, imp, newSize) {
|
|
1096
1102
|
const newImp = deepClone(imp);
|
|
1097
|
-
newImp.ext.sid = parseGPTSingleSizeArray(newSize);
|
|
1098
1103
|
newImp.banner.w = newSize[0];
|
|
1099
1104
|
newImp.banner.h = newSize[1];
|
|
1100
1105
|
|
|
@@ -293,14 +293,19 @@ function getItems(validBidRequests, bidderRequest) {
|
|
|
293
293
|
*/
|
|
294
294
|
function getParam(validBidRequests, bidderRequest) {
|
|
295
295
|
const pubcid = utils.deepAccess(validBidRequests[0], 'crumbs.pubcid');
|
|
296
|
-
|
|
296
|
+
const sharedid =
|
|
297
|
+
utils.deepAccess(validBidRequests[0], 'userId.sharedid.id') ||
|
|
298
|
+
utils.deepAccess(validBidRequests[0], 'userId.pubcid');
|
|
297
299
|
let isMobile = isMobileAndTablet() ? 1 : 0;
|
|
298
300
|
let isTest = 0;
|
|
299
301
|
let auctionId = getProperty(bidderRequest, 'auctionId');
|
|
300
302
|
let items = getItems(validBidRequests, bidderRequest);
|
|
301
303
|
|
|
302
|
-
const domain =
|
|
303
|
-
|
|
304
|
+
const domain =
|
|
305
|
+
utils.deepAccess(bidderRequest, 'refererInfo.domain') || document.domain;
|
|
306
|
+
const location = utils.deepAccess(bidderRequest, 'refererInfo.location');
|
|
307
|
+
const page = utils.deepAccess(bidderRequest, 'refererInfo.page');
|
|
308
|
+
const referer = utils.deepAccess(bidderRequest, 'refererInfo.ref');
|
|
304
309
|
|
|
305
310
|
const timeout = bidderRequest.timeout || 2000;
|
|
306
311
|
|
|
@@ -323,14 +328,13 @@ function getParam(validBidRequests, bidderRequest) {
|
|
|
323
328
|
},
|
|
324
329
|
ext: {},
|
|
325
330
|
user: {
|
|
326
|
-
|
|
327
|
-
id: pubcid,
|
|
331
|
+
id: sharedid || pubcid || getUserID(),
|
|
328
332
|
},
|
|
329
333
|
site: {
|
|
330
334
|
name: domain,
|
|
331
335
|
domain: domain,
|
|
332
|
-
page: location,
|
|
333
|
-
ref:
|
|
336
|
+
page: page || location,
|
|
337
|
+
ref: referer,
|
|
334
338
|
mobile: isMobile,
|
|
335
339
|
cat: [], // todo
|
|
336
340
|
publisher: {
|
|
@@ -454,9 +458,9 @@ export const spec = {
|
|
|
454
458
|
* Register bidder specific code, which will execute when the adserver targeting has been set for a bid from this bidder
|
|
455
459
|
* @param {Bid} The bid of which the targeting has been set
|
|
456
460
|
*/
|
|
457
|
-
// onSetTargeting: function (bid) {
|
|
458
|
-
// // console.log('onSetTargeting', bid);
|
|
459
|
-
// // Bidder specific code
|
|
460
|
-
// },
|
|
461
|
+
// onSetTargeting: function (bid) {
|
|
462
|
+
// // console.log('onSetTargeting', bid);
|
|
463
|
+
// // Bidder specific code
|
|
464
|
+
// },
|
|
461
465
|
};
|
|
462
466
|
registerBidder(spec);
|
|
@@ -164,7 +164,7 @@ export const spec = {
|
|
|
164
164
|
// fires a pixel to confirm a winning bid
|
|
165
165
|
let params = {'pbjs': '$prebid.version$'};
|
|
166
166
|
let endpoint = document.location.search.match(/msq_test=true/) ? BIDDER_URL_TEST : BIDDER_URL_PROD;
|
|
167
|
-
let paramsToSearchFor = ['cpm', 'size', 'mediaType', 'currency', 'creativeId', 'adUnitCode', 'timeToRespond', 'requestId', 'auctionId']
|
|
167
|
+
let paramsToSearchFor = ['cpm', 'size', 'mediaType', 'currency', 'creativeId', 'adUnitCode', 'timeToRespond', 'requestId', 'auctionId', 'originalCpm', 'originalCurrency'];
|
|
168
168
|
if (bid.hasOwnProperty('mediasquare')) {
|
|
169
169
|
if (bid['mediasquare'].hasOwnProperty('bidder')) { params['bidder'] = bid['mediasquare']['bidder']; }
|
|
170
170
|
if (bid['mediasquare'].hasOwnProperty('code')) { params['code'] = bid['mediasquare']['code']; }
|
|
@@ -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,
|
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
logMessage,
|
|
9
9
|
parseUrl,
|
|
10
10
|
triggerPixel,
|
|
11
|
+
getDefinedParams,
|
|
12
|
+
parseGPTSingleSizeArrayToRtbSize,
|
|
11
13
|
} from '../src/utils.js';
|
|
12
14
|
|
|
13
15
|
import CONSTANTS from '../src/constants.json';
|
|
@@ -22,6 +24,10 @@ const ENDPOINT = 'https://pbs.nextmillmedia.com/openrtb2/auction';
|
|
|
22
24
|
const TEST_ENDPOINT = 'https://test.pbs.nextmillmedia.com/openrtb2/auction';
|
|
23
25
|
const SYNC_ENDPOINT = 'https://statics.nextmillmedia.com/load-cookie.html?v=4';
|
|
24
26
|
const TIME_TO_LIVE = 360;
|
|
27
|
+
const VIDEO_PARAMS = [
|
|
28
|
+
'api', 'linearity', 'maxduration', 'mimes', 'minduration', 'placement',
|
|
29
|
+
'playbackmethod', 'protocols', 'startdelay'
|
|
30
|
+
];
|
|
25
31
|
|
|
26
32
|
const EXPIRENCE_WURL = 20 * 60000;
|
|
27
33
|
const wurlMap = {};
|
|
@@ -72,21 +78,38 @@ export const spec = {
|
|
|
72
78
|
|
|
73
79
|
device,
|
|
74
80
|
site,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
'format': (sizes || []).map(s => { return {w: s[0], h: s[1]} })
|
|
78
|
-
},
|
|
81
|
+
imp: []
|
|
82
|
+
};
|
|
79
83
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
}
|
|
84
|
+
const imp = {
|
|
85
|
+
ext: {
|
|
86
|
+
prebid: {
|
|
87
|
+
storedrequest: {id}
|
|
86
88
|
}
|
|
87
|
-
}
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
if (deepAccess(bid, 'mediaTypes.banner')) {
|
|
93
|
+
imp.banner = {
|
|
94
|
+
format: (sizes || []).map(s => { return {w: s[0], h: s[1]} })
|
|
95
|
+
};
|
|
88
96
|
};
|
|
89
97
|
|
|
98
|
+
const video = deepAccess(bid, 'mediaTypes.video');
|
|
99
|
+
if (video) {
|
|
100
|
+
imp.video = getDefinedParams(video, VIDEO_PARAMS);
|
|
101
|
+
if (video.playerSize) {
|
|
102
|
+
imp.video = Object.assign(
|
|
103
|
+
imp.video, parseGPTSingleSizeArrayToRtbSize(video.playerSize[0]) || {}
|
|
104
|
+
);
|
|
105
|
+
} else if (video.w && video.h) {
|
|
106
|
+
imp.video.w = video.w;
|
|
107
|
+
imp.video.h = video.h;
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
postBody.imp.push(imp);
|
|
112
|
+
|
|
90
113
|
const gdprConsent = bidderRequest && bidderRequest.gdprConsent;
|
|
91
114
|
const uspConsent = bidderRequest && bidderRequest.uspConsent;
|
|
92
115
|
|
|
@@ -124,9 +124,9 @@ function formatSource(src) {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
function getBillingPayload(event) {
|
|
127
|
-
// for now we are mapping all events to type "general", later we will expand support for specific types
|
|
128
127
|
let billingEvent = deepClone(event);
|
|
129
|
-
|
|
128
|
+
// Pass along type if is string and not empty else general
|
|
129
|
+
billingEvent.type = (typeof event.type === 'string' && event.type) || 'general';
|
|
130
130
|
billingEvent.accountId = accountId;
|
|
131
131
|
// mark as sent
|
|
132
132
|
deepSetValue(cache.billing, `${event.vendor}.${event.billingId}`, true);
|
|
@@ -1109,15 +1109,25 @@ function mapSizes(sizes) {
|
|
|
1109
1109
|
|
|
1110
1110
|
/**
|
|
1111
1111
|
* Test if bid has mediaType or mediaTypes set for video.
|
|
1112
|
-
* Also
|
|
1112
|
+
* Also checks if the video object is present in the rubicon bidder params
|
|
1113
1113
|
* @param {BidRequest} bidRequest
|
|
1114
1114
|
* @returns {boolean}
|
|
1115
1115
|
*/
|
|
1116
|
-
export function
|
|
1117
|
-
|
|
1118
|
-
|
|
1116
|
+
export function classifiedAsVideo(bidRequest) {
|
|
1117
|
+
let isVideo = typeof deepAccess(bidRequest, `mediaTypes.${VIDEO}`) !== 'undefined';
|
|
1118
|
+
let isBanner = typeof deepAccess(bidRequest, `mediaTypes.${BANNER}`) !== 'undefined';
|
|
1119
|
+
let isMissingVideoParams = typeof deepAccess(bidRequest, 'params.video') !== 'object';
|
|
1120
|
+
// If an ad has both video and banner types, a legacy implementation allows choosing video over banner
|
|
1121
|
+
// based on whether or not there is a video object defined in the params
|
|
1122
|
+
// Given this legacy implementation, other code depends on params.video being defined
|
|
1123
|
+
|
|
1124
|
+
if (isBanner && isMissingVideoParams) {
|
|
1125
|
+
isVideo = false;
|
|
1119
1126
|
}
|
|
1120
|
-
|
|
1127
|
+
if (isVideo && isMissingVideoParams) {
|
|
1128
|
+
deepSetValue(bidRequest, 'params.video', {});
|
|
1129
|
+
}
|
|
1130
|
+
return isVideo;
|
|
1121
1131
|
}
|
|
1122
1132
|
|
|
1123
1133
|
/**
|
|
@@ -1128,7 +1138,7 @@ export function hasVideoMediaType(bidRequest) {
|
|
|
1128
1138
|
*/
|
|
1129
1139
|
function bidType(bid, log = false) {
|
|
1130
1140
|
// Is it considered video ad unit by rubicon
|
|
1131
|
-
if (
|
|
1141
|
+
if (classifiedAsVideo(bid)) {
|
|
1132
1142
|
// Removed legacy mediaType support. new way using mediaTypes.video object is now required
|
|
1133
1143
|
// We require either context as instream or outstream
|
|
1134
1144
|
if (['outstream', 'instream'].indexOf(deepAccess(bid, `mediaTypes.${VIDEO}.context`)) === -1) {
|
|
@@ -240,6 +240,10 @@ export const spec = {
|
|
|
240
240
|
payload['uspConsent'] = bidderRequest.uspConsent
|
|
241
241
|
}
|
|
242
242
|
|
|
243
|
+
if (validBidRequests[0].schain) {
|
|
244
|
+
payload.schain = validBidRequests[0].schain;
|
|
245
|
+
}
|
|
246
|
+
|
|
243
247
|
const payloadString = JSON.stringify(payload)
|
|
244
248
|
return {
|
|
245
249
|
method: 'POST',
|
|
@@ -60,14 +60,10 @@ export const userData = {
|
|
|
60
60
|
|
|
61
61
|
export const internal = {
|
|
62
62
|
getPageUrl: (refererInfo = {}) => {
|
|
63
|
-
return refererInfo
|
|
63
|
+
return refererInfo?.page || getWindowSelf().location.href;
|
|
64
64
|
},
|
|
65
65
|
getReferrer: (refererInfo = {}) => {
|
|
66
|
-
|
|
67
|
-
return refererInfo.ref;
|
|
68
|
-
} else {
|
|
69
|
-
return getWindowSelf().document.referrer;
|
|
70
|
-
}
|
|
66
|
+
return refererInfo?.ref || getWindowSelf().document.referrer;
|
|
71
67
|
}
|
|
72
68
|
}
|
|
73
69
|
|
|
@@ -160,7 +156,7 @@ function getSiteProperties({publisherId, bcat = []}, refererInfo) {
|
|
|
160
156
|
return {
|
|
161
157
|
id: publisherId,
|
|
162
158
|
name: publisherId,
|
|
163
|
-
domain: refererInfo?.domain || window.location
|
|
159
|
+
domain: refererInfo?.domain || window.location?.host,
|
|
164
160
|
page: getPageUrl(refererInfo),
|
|
165
161
|
ref: getReferrer(refererInfo),
|
|
166
162
|
publisher: {
|
package/modules/userId/eids.js
CHANGED
|
@@ -5,6 +5,25 @@ export const USER_IDS_CONFIG = {
|
|
|
5
5
|
|
|
6
6
|
// key-name : {config}
|
|
7
7
|
|
|
8
|
+
// GrowthCode
|
|
9
|
+
'growthCodeId': {
|
|
10
|
+
getValue: function(data) {
|
|
11
|
+
return data.gc_id
|
|
12
|
+
},
|
|
13
|
+
source: 'growthcode.io',
|
|
14
|
+
atype: 1,
|
|
15
|
+
getUidExt: function(data) {
|
|
16
|
+
const extendedData = pick(data, [
|
|
17
|
+
'h1',
|
|
18
|
+
'h2',
|
|
19
|
+
'h3',
|
|
20
|
+
]);
|
|
21
|
+
if (Object.keys(extendedData).length) {
|
|
22
|
+
return extendedData;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
|
|
8
27
|
// trustpid
|
|
9
28
|
'trustpid': {
|
|
10
29
|
source: 'trustpid.com',
|
|
@@ -10,7 +10,7 @@ const BIDDER_VERSION = '1.0.0';
|
|
|
10
10
|
const CURRENCY = 'USD';
|
|
11
11
|
const TTL_SECONDS = 60 * 5;
|
|
12
12
|
const DEAL_ID_EXPIRY = 1000 * 60 * 15;
|
|
13
|
-
const UNIQUE_DEAL_ID_EXPIRY = 1000 * 60 *
|
|
13
|
+
const UNIQUE_DEAL_ID_EXPIRY = 1000 * 60 * 60;
|
|
14
14
|
const SESSION_ID_KEY = 'vidSid';
|
|
15
15
|
export const SUPPORTED_ID_SYSTEMS = {
|
|
16
16
|
'britepoolid': 1,
|