prebid.js 6.2.0 → 6.3.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/gulpfile.js +0 -8
- package/integrationExamples/gpt/weboramaRtdProvider_example.html +23 -14
- package/modules/33acrossBidAdapter.js +189 -102
- package/modules/adagioBidAdapter.js +1 -1
- package/modules/addefendBidAdapter.js +1 -0
- package/modules/admanBidAdapter.js +1 -0
- package/modules/admixerBidAdapter.js +1 -1
- package/modules/adnuntiusBidAdapter.js +3 -1
- package/modules/adxcgBidAdapter.js +311 -359
- package/modules/adxcgBidAdapter.md +22 -21
- package/modules/appnexusBidAdapter.js +0 -1
- package/modules/beopBidAdapter.js +5 -3
- package/modules/colossussspBidAdapter.js +7 -0
- package/modules/criteoBidAdapter.js +1 -1
- package/modules/cwireBidAdapter.js +3 -0
- package/modules/dspxBidAdapter.js +1 -1
- package/modules/futureads.md +48 -0
- package/modules/glimpseBidAdapter.js +16 -3
- package/modules/gumgumBidAdapter.js +2 -2
- package/modules/kinessoIdSystem.js +1 -1
- package/modules/lotamePanoramaIdSystem.js +80 -8
- package/modules/mediasquareBidAdapter.js +1 -9
- package/modules/nextMillenniumBidAdapter.js +29 -1
- package/modules/prebidServerBidAdapter/index.js +16 -12
- package/modules/richaudienceBidAdapter.js +1 -2
- package/modules/rtdModule/index.js +48 -18
- package/modules/rubiconBidAdapter.js +10 -8
- package/modules/sharedIdSystem.js +27 -1
- package/modules/targetVideoBidAdapter.js +187 -0
- package/modules/targetVideoBidAdapter.md +34 -0
- package/modules/vidoomyBidAdapter.js +16 -10
- package/modules/weboramaRtdProvider.js +288 -73
- package/modules/weboramaRtdProvider.md +27 -10
- package/modules/yahoosspBidAdapter.js +5 -1
- package/modules/zetaSspBidAdapter.md +33 -1
- package/modules/zeta_global_sspBidAdapter.js +22 -1
- package/package.json +1 -1
- package/plugins/pbjsGlobals.js +28 -1
- package/src/prebid.js +1 -2
- package/src/targeting.js +22 -1
- package/src/utils.js +34 -7
- package/test/spec/modules/33acrossBidAdapter_spec.js +300 -78
- package/test/spec/modules/adnuntiusBidAdapter_spec.js +17 -0
- package/test/spec/modules/adxcgBidAdapter_spec.js +820 -571
- package/test/spec/modules/colossussspBidAdapter_spec.js +9 -0
- package/test/spec/modules/cwireBidAdapter_spec.js +10 -8
- package/test/spec/modules/lotamePanoramaIdSystem_spec.js +227 -0
- package/test/spec/modules/mediasquareBidAdapter_spec.js +4 -4
- package/test/spec/modules/nextMillenniumBidAdapter_spec.js +18 -0
- package/test/spec/modules/prebidServerBidAdapter_spec.js +43 -0
- package/test/spec/modules/realTimeDataModule_spec.js +135 -49
- package/test/spec/modules/richaudienceBidAdapter_spec.js +2 -2
- package/test/spec/modules/rubiconBidAdapter_spec.js +17 -0
- package/test/spec/modules/sharedIdSystem_spec.js +52 -6
- package/test/spec/modules/targetVideoBidAdapter_spec.js +96 -0
- package/test/spec/modules/weboramaRtdProvider_spec.js +408 -214
- package/test/spec/modules/yahoosspBidAdapter_spec.js +28 -1
- package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +33 -1
- package/test/spec/unit/core/targeting_spec.js +72 -0
- package/test/spec/utils_spec.js +38 -0
|
@@ -34,31 +34,34 @@ Module that connects to an Adxcg.com zone to fetch bids.
|
|
|
34
34
|
code: 'native-ad-div',
|
|
35
35
|
mediaTypes: {
|
|
36
36
|
native: {
|
|
37
|
-
|
|
37
|
+
image: {
|
|
38
38
|
sendId: false,
|
|
39
|
-
required:
|
|
40
|
-
sizes: [
|
|
39
|
+
required: false,
|
|
40
|
+
sizes: [127, 83]
|
|
41
41
|
},
|
|
42
42
|
icon: {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
brand: {
|
|
43
|
+
sizes: [80, 80],
|
|
44
|
+
required: false,
|
|
46
45
|
sendId: true,
|
|
47
46
|
},
|
|
48
47
|
title: {
|
|
49
48
|
sendId: false,
|
|
50
|
-
required:
|
|
49
|
+
required: false,
|
|
51
50
|
len: 75
|
|
52
51
|
},
|
|
53
52
|
body: {
|
|
54
53
|
sendId: false,
|
|
55
|
-
required:
|
|
54
|
+
required: false,
|
|
56
55
|
len: 200
|
|
57
56
|
},
|
|
58
|
-
|
|
57
|
+
cta: {
|
|
59
58
|
sendId: false,
|
|
60
59
|
required: false,
|
|
61
|
-
len:
|
|
60
|
+
len: 75
|
|
61
|
+
},
|
|
62
|
+
sponsoredBy: {
|
|
63
|
+
sendId: false,
|
|
64
|
+
required: false
|
|
62
65
|
}
|
|
63
66
|
}
|
|
64
67
|
},
|
|
@@ -73,21 +76,19 @@ Module that connects to an Adxcg.com zone to fetch bids.
|
|
|
73
76
|
code: 'video-div',
|
|
74
77
|
mediaTypes: {
|
|
75
78
|
video: {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
playerSize: [640, 480],
|
|
80
|
+
context: 'instream',
|
|
81
|
+
mimes: ['video/mp4'],
|
|
82
|
+
protocols: [2, 3, 5, 6, 8],
|
|
83
|
+
playback_method: ['auto_play_sound_off'],
|
|
84
|
+
maxduration: 100,
|
|
85
|
+
skip: 1
|
|
86
|
+
}
|
|
82
87
|
},
|
|
83
88
|
bids: [{
|
|
84
89
|
bidder: 'adxcg',
|
|
85
90
|
params: {
|
|
86
|
-
adzoneid: '20'
|
|
87
|
-
video: {
|
|
88
|
-
maxduration: 100,
|
|
89
|
-
skippable: true
|
|
90
|
-
}
|
|
91
|
+
adzoneid: '20'
|
|
91
92
|
}
|
|
92
93
|
}]
|
|
93
94
|
}
|
|
@@ -99,16 +99,18 @@ export const spec = {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
function buildTrackingParams(data, info, value) {
|
|
102
|
+
const accountId = data.params.accountId;
|
|
102
103
|
return {
|
|
103
|
-
pid: data.
|
|
104
|
+
pid: accountId === undefined ? data.ad.match(/account: \“([a-f\d]{24})\“/)[1] : accountId,
|
|
104
105
|
nid: data.params.networkId,
|
|
105
106
|
nptnid: data.params.networkPartnerId,
|
|
106
|
-
bid: data.bidId,
|
|
107
|
+
bid: data.bidId || data.requestId,
|
|
107
108
|
sl_n: data.adUnitCode,
|
|
108
109
|
aid: data.auctionId,
|
|
109
110
|
se_ca: 'bid',
|
|
110
111
|
se_ac: info,
|
|
111
|
-
se_va: value
|
|
112
|
+
se_va: value,
|
|
113
|
+
url: window.location.href
|
|
112
114
|
};
|
|
113
115
|
}
|
|
114
116
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getWindowTop, deepAccess, logMessage } from '../src/utils.js';
|
|
2
2
|
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
3
3
|
import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
|
|
4
|
+
import { ajax } from '../src/ajax.js';
|
|
4
5
|
|
|
5
6
|
const BIDDER_CODE = 'colossusssp';
|
|
6
7
|
const G_URL = 'https://colossusssp.com/?c=o&m=multi';
|
|
@@ -175,6 +176,12 @@ export const spec = {
|
|
|
175
176
|
type: 'image',
|
|
176
177
|
url: G_URL_SYNC
|
|
177
178
|
}];
|
|
179
|
+
},
|
|
180
|
+
|
|
181
|
+
onBidWon: (bid) => {
|
|
182
|
+
if (bid.nurl) {
|
|
183
|
+
ajax(bid.nurl, null);
|
|
184
|
+
}
|
|
178
185
|
}
|
|
179
186
|
};
|
|
180
187
|
|
|
@@ -24,7 +24,7 @@ const LOG_PREFIX = 'Criteo: ';
|
|
|
24
24
|
Unminified source code can be found in the privately shared repo: https://github.com/Prebid-org/prebid-js-external-js-criteo/blob/master/dist/prod.js
|
|
25
25
|
*/
|
|
26
26
|
const FAST_BID_VERSION_PLACEHOLDER = '%FAST_BID_VERSION%';
|
|
27
|
-
export const FAST_BID_VERSION_CURRENT =
|
|
27
|
+
export const FAST_BID_VERSION_CURRENT = 116;
|
|
28
28
|
const FAST_BID_VERSION_LATEST = 'latest';
|
|
29
29
|
const FAST_BID_VERSION_NONE = 'none';
|
|
30
30
|
const PUBLISHER_TAG_URL_TEMPLATE = 'https://static.criteo.net/js/ld/publishertag.prebid' + FAST_BID_VERSION_PLACEHOLDER + '.js';
|
|
@@ -26,6 +26,7 @@ export const RENDERER_URL = 'https://cdn.cwi.re/prebid/renderer/LATEST/renderer.
|
|
|
26
26
|
export const CW_PAGE_VIEW_ID = generateUUID();
|
|
27
27
|
const LS_CWID_KEY = 'cw_cwid';
|
|
28
28
|
const CW_GROUPS_QUERY = 'cwgroups';
|
|
29
|
+
const CW_CREATIVE_QUERY = 'cwcreative';
|
|
29
30
|
|
|
30
31
|
const storage = getStorageManager();
|
|
31
32
|
|
|
@@ -161,6 +162,7 @@ export const spec = {
|
|
|
161
162
|
|
|
162
163
|
let refgroups = [];
|
|
163
164
|
|
|
165
|
+
const cwCreativeId = getQueryVariable(CW_CREATIVE_QUERY);
|
|
164
166
|
const rgQuery = getQueryVariable(CW_GROUPS_QUERY);
|
|
165
167
|
if (rgQuery !== null) {
|
|
166
168
|
refgroups = rgQuery.split(',');
|
|
@@ -171,6 +173,7 @@ export const spec = {
|
|
|
171
173
|
const payload = {
|
|
172
174
|
cwid: localStorageCWID,
|
|
173
175
|
refgroups,
|
|
176
|
+
cwcreative: cwCreativeId,
|
|
174
177
|
slots: slots,
|
|
175
178
|
httpRef: referer || '',
|
|
176
179
|
pageViewId: CW_PAGE_VIEW_ID,
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
Module Name: Future Ads Bidder Adapter
|
|
3
|
+
Module Type: Bidder Adapter
|
|
4
|
+
Maintainer: contact@futureads.io
|
|
5
|
+
# Description
|
|
6
|
+
Connects to Future Ads demand source to fetch bids.
|
|
7
|
+
Banner and Video formats are supported.
|
|
8
|
+
Please use ```futureads``` as the bidder code.
|
|
9
|
+
# Test Parameters
|
|
10
|
+
```
|
|
11
|
+
var adUnits = [
|
|
12
|
+
{
|
|
13
|
+
code: 'desktop-banner-ad-div',
|
|
14
|
+
sizes: [[300, 250]], // a display size
|
|
15
|
+
bids: [
|
|
16
|
+
{
|
|
17
|
+
bidder: "futureads",
|
|
18
|
+
params: {
|
|
19
|
+
zone: '2eb6bd58-865c-47ce-af7f-a918108c3fd2'
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
},{
|
|
24
|
+
code: 'mobile-banner-ad-div',
|
|
25
|
+
sizes: [[300, 50]], // a mobile size
|
|
26
|
+
bids: [
|
|
27
|
+
{
|
|
28
|
+
bidder: "futureads",
|
|
29
|
+
params: {
|
|
30
|
+
zone: '62211486-c50b-4356-9f0f-411778d31fcc'
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
},{
|
|
35
|
+
code: 'video-ad',
|
|
36
|
+
sizes: [[300, 50]],
|
|
37
|
+
mediaType: 'video',
|
|
38
|
+
bids: [
|
|
39
|
+
{
|
|
40
|
+
bidder: "futureads",
|
|
41
|
+
params: {
|
|
42
|
+
zone: 'ebeb1e79-8cb4-4473-b2d0-2e24b7ff47fd'
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
```
|
|
@@ -138,11 +138,17 @@ function getReferer(bidderRequest) {
|
|
|
138
138
|
function getGdprConsentChoice(bidderRequest) {
|
|
139
139
|
const hasGdprConsent =
|
|
140
140
|
hasValue(bidderRequest) &&
|
|
141
|
-
hasValue(bidderRequest.gdprConsent)
|
|
142
|
-
hasStringValue(bidderRequest.gdprConsent.consentString)
|
|
141
|
+
hasValue(bidderRequest.gdprConsent)
|
|
143
142
|
|
|
144
143
|
if (hasGdprConsent) {
|
|
145
|
-
|
|
144
|
+
const gdprConsent = bidderRequest.gdprConsent
|
|
145
|
+
const hasGdprApplies = hasBooleanValue(gdprConsent.gdprApplies)
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
consentString: gdprConsent.consentString || '',
|
|
149
|
+
vendorData: gdprConsent.vendorData || {},
|
|
150
|
+
gdprApplies: hasGdprApplies ? gdprConsent.gdprApplies : true,
|
|
151
|
+
}
|
|
146
152
|
}
|
|
147
153
|
|
|
148
154
|
return {
|
|
@@ -177,6 +183,13 @@ function hasValue(value) {
|
|
|
177
183
|
)
|
|
178
184
|
}
|
|
179
185
|
|
|
186
|
+
function hasBooleanValue(value) {
|
|
187
|
+
return (
|
|
188
|
+
hasValue(value) &&
|
|
189
|
+
typeof value === 'boolean'
|
|
190
|
+
)
|
|
191
|
+
}
|
|
192
|
+
|
|
180
193
|
function hasStringValue(value) {
|
|
181
194
|
return (
|
|
182
195
|
hasValue(value) &&
|
|
@@ -296,8 +296,8 @@ function buildRequests(validBidRequests, bidderRequest) {
|
|
|
296
296
|
let gpid = '';
|
|
297
297
|
|
|
298
298
|
const date = new Date();
|
|
299
|
-
const lt = date
|
|
300
|
-
const to = date
|
|
299
|
+
const lt = date.getTime();
|
|
300
|
+
const to = date.getTimezoneOffset();
|
|
301
301
|
if (to) {
|
|
302
302
|
lt && (data.lt = lt);
|
|
303
303
|
data.to = to;
|
|
@@ -180,7 +180,7 @@ function kinessoSyncUrl(accountId, consentData) {
|
|
|
180
180
|
const usPrivacyString = uspDataHandler.getConsentData();
|
|
181
181
|
let kinessoSyncUrl = `${ID_SVC}?accountid=${accountId}`;
|
|
182
182
|
if (usPrivacyString) {
|
|
183
|
-
kinessoSyncUrl = `${kinessoSyncUrl}
|
|
183
|
+
kinessoSyncUrl = `${kinessoSyncUrl}&us_privacy=${usPrivacyString}`;
|
|
184
184
|
}
|
|
185
185
|
if (!consentData || typeof consentData.gdprApplies !== 'boolean' || !consentData.gdprApplies) return kinessoSyncUrl;
|
|
186
186
|
|
|
@@ -4,10 +4,20 @@
|
|
|
4
4
|
* @module modules/lotamePanoramaId
|
|
5
5
|
* @requires module:modules/userId
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
timestamp,
|
|
9
|
+
isStr,
|
|
10
|
+
logError,
|
|
11
|
+
isBoolean,
|
|
12
|
+
buildUrl,
|
|
13
|
+
isEmpty,
|
|
14
|
+
isArray,
|
|
15
|
+
isEmptyStr
|
|
16
|
+
} from '../src/utils.js';
|
|
8
17
|
import { ajax } from '../src/ajax.js';
|
|
9
18
|
import { submodule } from '../src/hook.js';
|
|
10
19
|
import { getStorageManager } from '../src/storageManager.js';
|
|
20
|
+
import { uspDataHandler } from '../src/adapterManager.js';
|
|
11
21
|
|
|
12
22
|
const KEY_ID = 'panoramaId';
|
|
13
23
|
const KEY_EXPIRY = `${KEY_ID}_expiry`;
|
|
@@ -115,14 +125,23 @@ function saveLotameCache(
|
|
|
115
125
|
|
|
116
126
|
/**
|
|
117
127
|
* Retrieve all the cached values from cookies and/or local storage
|
|
128
|
+
* @param {Number} clientId
|
|
118
129
|
*/
|
|
119
|
-
function getLotameLocalCache() {
|
|
130
|
+
function getLotameLocalCache(clientId = undefined) {
|
|
120
131
|
let cache = {
|
|
121
132
|
data: getFromStorage(KEY_ID),
|
|
122
133
|
expiryTimestampMs: 0,
|
|
134
|
+
clientExpiryTimestampMs: 0,
|
|
123
135
|
};
|
|
124
136
|
|
|
125
137
|
try {
|
|
138
|
+
if (clientId) {
|
|
139
|
+
const rawClientExpiry = getFromStorage(`${KEY_EXPIRY}_${clientId}`);
|
|
140
|
+
if (isStr(rawClientExpiry)) {
|
|
141
|
+
cache.clientExpiryTimestampMs = parseInt(rawClientExpiry, 10);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
126
145
|
const rawExpiry = getFromStorage(KEY_EXPIRY);
|
|
127
146
|
if (isStr(rawExpiry)) {
|
|
128
147
|
cache.expiryTimestampMs = parseInt(rawExpiry, 10);
|
|
@@ -191,11 +210,25 @@ export const lotamePanoramaIdSubmodule = {
|
|
|
191
210
|
*/
|
|
192
211
|
getId(config, consentData, cacheIdObj) {
|
|
193
212
|
cookieDomain = lotamePanoramaIdSubmodule.findRootDomain();
|
|
194
|
-
|
|
213
|
+
const configParams = (config && config.params) || {};
|
|
214
|
+
const clientId = configParams.clientId;
|
|
215
|
+
const hasCustomClientId = !isEmpty(clientId);
|
|
216
|
+
const localCache = getLotameLocalCache(clientId);
|
|
195
217
|
|
|
196
|
-
|
|
218
|
+
const hasExpiredPanoId = Date.now() > localCache.expiryTimestampMs;
|
|
219
|
+
|
|
220
|
+
if (hasCustomClientId) {
|
|
221
|
+
const hasFreshClientNoConsent = Date.now() < localCache.clientExpiryTimestampMs;
|
|
222
|
+
if (hasFreshClientNoConsent) {
|
|
223
|
+
// There is no consent
|
|
224
|
+
return {
|
|
225
|
+
id: undefined,
|
|
226
|
+
reason: 'NO_CLIENT_CONSENT',
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
}
|
|
197
230
|
|
|
198
|
-
if (!
|
|
231
|
+
if (!hasExpiredPanoId) {
|
|
199
232
|
return {
|
|
200
233
|
id: localCache.data,
|
|
201
234
|
};
|
|
@@ -203,6 +236,18 @@ export const lotamePanoramaIdSubmodule = {
|
|
|
203
236
|
|
|
204
237
|
const storedUserId = getProfileId();
|
|
205
238
|
|
|
239
|
+
// Add CCPA Consent data handling
|
|
240
|
+
const usp = uspDataHandler.getConsentData();
|
|
241
|
+
|
|
242
|
+
let usPrivacy;
|
|
243
|
+
if (typeof usp !== 'undefined' && !isEmpty(usp) && !isEmptyStr(usp)) {
|
|
244
|
+
usPrivacy = usp;
|
|
245
|
+
}
|
|
246
|
+
if (!usPrivacy) {
|
|
247
|
+
// fallback to 1st party cookie
|
|
248
|
+
usPrivacy = getFromStorage('us_privacy');
|
|
249
|
+
}
|
|
250
|
+
|
|
206
251
|
const resolveIdFunction = function (callback) {
|
|
207
252
|
let queryParams = {};
|
|
208
253
|
if (storedUserId) {
|
|
@@ -226,6 +271,17 @@ export const lotamePanoramaIdSubmodule = {
|
|
|
226
271
|
if (consentString) {
|
|
227
272
|
queryParams.gdpr_consent = consentString;
|
|
228
273
|
}
|
|
274
|
+
|
|
275
|
+
// Add usPrivacy to the url
|
|
276
|
+
if (usPrivacy) {
|
|
277
|
+
queryParams.us_privacy = usPrivacy;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Add clientId to the url
|
|
281
|
+
if (hasCustomClientId) {
|
|
282
|
+
queryParams.c = clientId;
|
|
283
|
+
}
|
|
284
|
+
|
|
229
285
|
const url = buildUrl({
|
|
230
286
|
protocol: 'https',
|
|
231
287
|
host: `id.crwdcntrl.net`,
|
|
@@ -239,15 +295,31 @@ export const lotamePanoramaIdSubmodule = {
|
|
|
239
295
|
if (response) {
|
|
240
296
|
try {
|
|
241
297
|
let responseObj = JSON.parse(response);
|
|
242
|
-
const
|
|
298
|
+
const hasNoConsentErrors = !(
|
|
243
299
|
isArray(responseObj.errors) &&
|
|
244
300
|
responseObj.errors.indexOf(MISSING_CORE_CONSENT) !== -1
|
|
245
301
|
);
|
|
246
302
|
|
|
303
|
+
if (hasCustomClientId) {
|
|
304
|
+
if (hasNoConsentErrors) {
|
|
305
|
+
clearLotameCache(`${KEY_EXPIRY}_${clientId}`);
|
|
306
|
+
} else if (isStr(responseObj.no_consent) && responseObj.no_consent === 'CLIENT') {
|
|
307
|
+
saveLotameCache(
|
|
308
|
+
`${KEY_EXPIRY}_${clientId}`,
|
|
309
|
+
responseObj.expiry_ts,
|
|
310
|
+
responseObj.expiry_ts
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
// End Processing
|
|
314
|
+
callback();
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
247
319
|
saveLotameCache(KEY_EXPIRY, responseObj.expiry_ts, responseObj.expiry_ts);
|
|
248
320
|
|
|
249
321
|
if (isStr(responseObj.profile_id)) {
|
|
250
|
-
if (
|
|
322
|
+
if (hasNoConsentErrors) {
|
|
251
323
|
setProfileId(responseObj.profile_id);
|
|
252
324
|
}
|
|
253
325
|
|
|
@@ -262,7 +334,7 @@ export const lotamePanoramaIdSubmodule = {
|
|
|
262
334
|
clearLotameCache(KEY_ID);
|
|
263
335
|
}
|
|
264
336
|
} else {
|
|
265
|
-
if (
|
|
337
|
+
if (hasNoConsentErrors) {
|
|
266
338
|
clearLotameCache(KEY_PROFILE);
|
|
267
339
|
}
|
|
268
340
|
clearLotameCache(KEY_ID);
|
|
@@ -7,7 +7,6 @@ const BIDDER_CODE = 'mediasquare';
|
|
|
7
7
|
const BIDDER_URL_PROD = 'https://pbs-front.mediasquare.fr/'
|
|
8
8
|
const BIDDER_URL_TEST = 'https://bidder-test.mediasquare.fr/'
|
|
9
9
|
const BIDDER_ENDPOINT_AUCTION = 'msq_prebid';
|
|
10
|
-
const BIDDER_ENDPOINT_SYNC = 'cookie_sync';
|
|
11
10
|
const BIDDER_ENDPOINT_WINNING = 'winning';
|
|
12
11
|
|
|
13
12
|
export const spec = {
|
|
@@ -132,18 +131,11 @@ export const spec = {
|
|
|
132
131
|
* @return {UserSync[]} The user syncs which should be dropped.
|
|
133
132
|
*/
|
|
134
133
|
getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) {
|
|
135
|
-
let params = '';
|
|
136
|
-
let endpoint = document.location.search.match(/msq_test=true/) ? BIDDER_URL_TEST : BIDDER_URL_PROD;
|
|
137
134
|
if (typeof serverResponses === 'object' && serverResponses != null && serverResponses.length > 0 && serverResponses[0].hasOwnProperty('body') &&
|
|
138
135
|
serverResponses[0].body.hasOwnProperty('cookies') && typeof serverResponses[0].body.cookies === 'object') {
|
|
139
136
|
return serverResponses[0].body.cookies;
|
|
140
137
|
} else {
|
|
141
|
-
|
|
142
|
-
if (uspConsent && typeof uspConsent === 'string') { params += '&uspConsent=' + uspConsent }
|
|
143
|
-
return {
|
|
144
|
-
type: 'iframe',
|
|
145
|
-
url: endpoint + BIDDER_ENDPOINT_SYNC + '?type=iframe' + params
|
|
146
|
-
};
|
|
138
|
+
return [];
|
|
147
139
|
}
|
|
148
140
|
},
|
|
149
141
|
|
|
@@ -4,6 +4,7 @@ import { BANNER } from '../src/mediaTypes.js';
|
|
|
4
4
|
|
|
5
5
|
const BIDDER_CODE = 'nextMillennium';
|
|
6
6
|
const ENDPOINT = 'https://pbs.nextmillmedia.com/openrtb2/auction';
|
|
7
|
+
const SYNC_ENDPOINT = 'https://statics.nextmillmedia.com/load-cookie.html?v=4';
|
|
7
8
|
const TIME_TO_LIVE = 360;
|
|
8
9
|
|
|
9
10
|
export const spec = {
|
|
@@ -18,10 +19,13 @@ export const spec = {
|
|
|
18
19
|
|
|
19
20
|
buildRequests: function(validBidRequests, bidderRequest) {
|
|
20
21
|
const requests = [];
|
|
22
|
+
window.nmmRefreshCounts = window.nmmRefreshCounts || {};
|
|
21
23
|
|
|
22
24
|
_each(validBidRequests, function(bid) {
|
|
25
|
+
window.nmmRefreshCounts[bid.adUnitCode] = window.nmmRefreshCounts[bid.adUnitCode] || 0;
|
|
23
26
|
const postBody = {
|
|
24
27
|
'id': bid.auctionId,
|
|
28
|
+
'refresh_count': window.nmmRefreshCounts[bid.adUnitCode]++,
|
|
25
29
|
'ext': {
|
|
26
30
|
'prebid': {
|
|
27
31
|
'storedrequest': {
|
|
@@ -89,7 +93,31 @@ export const spec = {
|
|
|
89
93
|
});
|
|
90
94
|
|
|
91
95
|
return bidResponses;
|
|
92
|
-
}
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent) {
|
|
99
|
+
if (!syncOptions.iframeEnabled) {
|
|
100
|
+
return
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
let syncurl = gdprConsent && gdprConsent.gdprApplies ? `${SYNC_ENDPOINT}&gdpr=1&gdpr_consent=${gdprConsent.consentString}` : SYNC_ENDPOINT
|
|
104
|
+
|
|
105
|
+
let bidders = []
|
|
106
|
+
if (responses) {
|
|
107
|
+
_each(responses, (response) => {
|
|
108
|
+
_each(Object.keys(response.body.ext.responsetimemillis), b => bidders.push(b))
|
|
109
|
+
})
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (bidders.length) {
|
|
113
|
+
syncurl += `&bidders=${bidders.join(',')}`
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return [{
|
|
117
|
+
type: 'iframe',
|
|
118
|
+
url: syncurl
|
|
119
|
+
}];
|
|
120
|
+
},
|
|
93
121
|
};
|
|
94
122
|
|
|
95
123
|
registerBidder(spec);
|
|
@@ -56,6 +56,7 @@ let eidPermissions;
|
|
|
56
56
|
* @property {string} [adapter='prebidServer'] adapter code to use for S2S
|
|
57
57
|
* @property {boolean} [enabled=false] enables S2S bidding
|
|
58
58
|
* @property {number} [timeout=1000] timeout for S2S bidders - should be lower than `pbjs.requestBids({timeout})`
|
|
59
|
+
* @property {number} [syncTimeout=1000] timeout for cookie sync iframe / image rendering
|
|
59
60
|
* @property {number} [maxBids=1]
|
|
60
61
|
* @property {AdapterOptions} [adapterOptions] adds arguments to resulting OpenRTB payload to Prebid Server
|
|
61
62
|
* @property {Object} [syncUrlModifier]
|
|
@@ -77,6 +78,7 @@ let eidPermissions;
|
|
|
77
78
|
*/
|
|
78
79
|
const s2sDefaultConfig = {
|
|
79
80
|
timeout: 1000,
|
|
81
|
+
syncTimeout: 1000,
|
|
80
82
|
maxBids: 1,
|
|
81
83
|
adapter: 'prebidServer',
|
|
82
84
|
adapterOptions: {},
|
|
@@ -274,11 +276,9 @@ function doAllSyncs(bidders, s2sConfig) {
|
|
|
274
276
|
*/
|
|
275
277
|
function doPreBidderSync(type, url, bidder, done, s2sConfig) {
|
|
276
278
|
if (s2sConfig.syncUrlModifier && typeof s2sConfig.syncUrlModifier[bidder] === 'function') {
|
|
277
|
-
|
|
278
|
-
doBidderSync(type, newSyncUrl, bidder, done)
|
|
279
|
-
} else {
|
|
280
|
-
doBidderSync(type, url, bidder, done)
|
|
279
|
+
url = s2sConfig.syncUrlModifier[bidder](type, url, bidder);
|
|
281
280
|
}
|
|
281
|
+
doBidderSync(type, url, bidder, done, s2sConfig.syncTimeout)
|
|
282
282
|
}
|
|
283
283
|
|
|
284
284
|
/**
|
|
@@ -288,17 +288,18 @@ function doPreBidderSync(type, url, bidder, done, s2sConfig) {
|
|
|
288
288
|
* @param {string} url the url to sync
|
|
289
289
|
* @param {string} bidder name of bidder doing sync for
|
|
290
290
|
* @param {function} done an exit callback; to signify this pixel has either: finished rendering or something went wrong
|
|
291
|
+
* @param {number} timeout: maximum time to wait for rendering in milliseconds
|
|
291
292
|
*/
|
|
292
|
-
function doBidderSync(type, url, bidder, done) {
|
|
293
|
+
function doBidderSync(type, url, bidder, done, timeout) {
|
|
293
294
|
if (!url) {
|
|
294
295
|
logError(`No sync url for bidder "${bidder}": ${url}`);
|
|
295
296
|
done();
|
|
296
297
|
} else if (type === 'image' || type === 'redirect') {
|
|
297
298
|
logMessage(`Invoking image pixel user sync for bidder: "${bidder}"`);
|
|
298
|
-
triggerPixel(url, done);
|
|
299
|
-
} else if (type
|
|
299
|
+
triggerPixel(url, done, timeout);
|
|
300
|
+
} else if (type === 'iframe') {
|
|
300
301
|
logMessage(`Invoking iframe user sync for bidder: "${bidder}"`);
|
|
301
|
-
insertUserSyncIframe(url, done);
|
|
302
|
+
insertUserSyncIframe(url, done, timeout);
|
|
302
303
|
} else {
|
|
303
304
|
logError(`User sync type "${type}" not supported for bidder: "${bidder}"`);
|
|
304
305
|
done();
|
|
@@ -539,10 +540,13 @@ const OPEN_RTB_PROTOCOL = {
|
|
|
539
540
|
}
|
|
540
541
|
if (Array.isArray(params.aspect_ratios)) {
|
|
541
542
|
// pass aspect_ratios as ext data I guess?
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
543
|
+
const aspectRatios = params.aspect_ratios
|
|
544
|
+
.filter((ar) => ar.ratio_width && ar.ratio_height)
|
|
545
|
+
.map(ratio => `${ratio.ratio_width}:${ratio.ratio_height}`);
|
|
546
|
+
if (aspectRatios.length > 0) {
|
|
547
|
+
asset.ext = {
|
|
548
|
+
aspectratios: aspectRatios
|
|
549
|
+
}
|
|
546
550
|
}
|
|
547
551
|
}
|
|
548
552
|
assets.push(newAsset({
|
|
@@ -58,11 +58,10 @@ export const spec = {
|
|
|
58
58
|
REFERER = (typeof bidderRequest.refererInfo.referer != 'undefined' ? encodeURIComponent(bidderRequest.refererInfo.referer) : null)
|
|
59
59
|
|
|
60
60
|
payload.gdpr_consent = '';
|
|
61
|
-
payload.gdpr =
|
|
61
|
+
payload.gdpr = bidderRequest.gdprConsent.gdprApplies;
|
|
62
62
|
|
|
63
63
|
if (bidderRequest && bidderRequest.gdprConsent) {
|
|
64
64
|
payload.gdpr_consent = bidderRequest.gdprConsent.consentString;
|
|
65
|
-
payload.gdpr = bidderRequest.gdprConsent.gdprApplies;
|
|
66
65
|
}
|
|
67
66
|
|
|
68
67
|
var payloadString = JSON.stringify(payload);
|