prebid.js 7.48.0 → 7.49.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/README.md +3 -0
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/33acrossIdSystem.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/admixerBidAdapter.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/aidemBidAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/carodaBidAdapter.js +1 -1
- package/dist/chtnwBidAdapter.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 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/cwireBidAdapter.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/feedadBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/freewheel-sspBidAdapter.js +1 -1
- package/dist/glimpseBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/greenbidsAnalyticsAdapter.js +1 -1
- package/dist/greenbidsRtdProvider.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/id5IdSystem.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/justpremiumBidAdapter.js +1 -1
- package/dist/kargoBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/kueezRtbBidAdapter.js +1 -1
- package/dist/kulturemediaBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/lifestreetBidAdapter.js +1 -1
- package/dist/liveyieldAnalyticsAdapter.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/magniteAnalyticsAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/minutemediaplusBidAdapter.js +1 -1
- package/dist/nexx360BidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +129 -128
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/optidigitalBidAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/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/pubmaticAnalyticsAdapter.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/retailspotBidAdapter.js +1 -0
- 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/stvBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/synacormediaBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/trionBidAdapter.js +1 -1
- package/dist/tripleliftBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.js +1 -1
- package/dist/uid2IdSystem.js +1 -1
- package/dist/underdogmediaBidAdapter.js +1 -1
- package/dist/undertoneBidAdapter.js +1 -1
- package/dist/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/yieldlabBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/modules/adgenerationBidAdapter.js +24 -15
- package/modules/admixerBidAdapter.js +15 -9
- package/modules/aidemBidAdapter.js +3 -1
- package/modules/ixBidAdapter.js +65 -47
- package/modules/kueezRtbBidAdapter.js +30 -33
- package/modules/mgidBidAdapter.js +9 -8
- package/modules/minutemediaBidAdapter.js +6 -0
- package/modules/minutemediaplusBidAdapter.js +30 -32
- package/modules/nexx360BidAdapter.js +2 -1
- package/modules/prebidServerBidAdapter/index.js +1 -3
- package/modules/prebidServerBidAdapter/ortbConverter.js +5 -1
- package/modules/pubmaticAnalyticsAdapter.js +3 -2
- package/modules/retailspotBidAdapter .md +32 -0
- package/modules/retailspotBidAdapter.js +186 -0
- package/modules/riseBidAdapter.js +6 -0
- package/modules/ttdBidAdapter.js +23 -22
- package/modules/vidazooBidAdapter.js +28 -32
- package/modules/yieldlabBidAdapter.js +27 -5
- package/package.json +1 -1
- package/src/adapterManager.js +4 -0
- package/src/adapters/bidderFactory.js +1 -0
- package/src/auction.js +2 -0
- package/src/prebid.js +36 -12
- package/src/utils/cpm.js +4 -1
- package/test/spec/modules/adgenerationBidAdapter_spec.js +6 -6
- package/test/spec/modules/admixerBidAdapter_spec.js +64 -25
- package/test/spec/modules/aidemBidAdapter_spec.js +3 -0
- package/test/spec/modules/ixBidAdapter_spec.js +66 -1
- package/test/spec/modules/kueezRtbBidAdapter_spec.js +3 -2
- package/test/spec/modules/mgidBidAdapter_spec.js +9 -9
- package/test/spec/modules/minutemediaBidAdapter_spec.js +18 -0
- package/test/spec/modules/minutemediaplusBidAdapter_spec.js +3 -2
- package/test/spec/modules/prebidServerBidAdapter_spec.js +96 -1
- package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +6 -1
- package/test/spec/modules/retailspotBidAdapter_spec.js +426 -0
- package/test/spec/modules/riseBidAdapter_spec.js +18 -0
- package/test/spec/modules/ttdBidAdapter_spec.js +129 -2
- package/test/spec/modules/vidazooBidAdapter_spec.js +3 -2
- package/test/spec/modules/yieldlabBidAdapter_spec.js +8 -1
- package/test/spec/unit/core/bidderFactory_spec.js +9 -9
- package/test/spec/unit/pbjs_api_spec.js +59 -1
- package/test/spec/unit/utils/cpm_spec.js +56 -1
|
@@ -380,15 +380,15 @@ export const spec = {
|
|
|
380
380
|
|
|
381
381
|
const syncs = [];
|
|
382
382
|
const query = [];
|
|
383
|
-
query.push('cbuster='
|
|
384
|
-
query.push('
|
|
383
|
+
query.push('cbuster={cbuster}');
|
|
384
|
+
query.push('gdpr_consent=' + encodeURIComponent(isPlainObject(gdprConsent) && isStr(gdprConsent?.consentString) ? gdprConsent.consentString : ''));
|
|
385
385
|
if (isPlainObject(gdprConsent) && typeof gdprConsent?.gdprApplies === 'boolean' && gdprConsent.gdprApplies) {
|
|
386
|
-
query.push('
|
|
386
|
+
query.push('gdpr=1');
|
|
387
387
|
} else {
|
|
388
|
-
query.push('
|
|
388
|
+
query.push('gdpr=0');
|
|
389
389
|
}
|
|
390
390
|
if (isPlainObject(uspConsent) && uspConsent?.consentString) {
|
|
391
|
-
query.push(`
|
|
391
|
+
query.push(`us_privacy=${encodeURIComponent(uspConsent?.consentString)}`);
|
|
392
392
|
}
|
|
393
393
|
if (isPlainObject(gppConsent) && gppConsent?.gppString) {
|
|
394
394
|
query.push(`gppString=${encodeURIComponent(gppConsent?.gppString)}`);
|
|
@@ -396,24 +396,25 @@ export const spec = {
|
|
|
396
396
|
if (config.getConfig('coppa')) {
|
|
397
397
|
query.push('coppa=1')
|
|
398
398
|
}
|
|
399
|
+
const q = query.join('&')
|
|
399
400
|
if (syncOptions.iframeEnabled) {
|
|
400
401
|
syncs.push({
|
|
401
402
|
type: 'iframe',
|
|
402
|
-
url: 'https://cm.mgid.com/i.html?' +
|
|
403
|
+
url: 'https://cm.mgid.com/i.html?' + q.replace('{cbuster}', Math.round(new Date().getTime()))
|
|
403
404
|
});
|
|
404
405
|
} else if (syncOptions.pixelEnabled) {
|
|
405
406
|
if (pixels.length === 0) {
|
|
406
407
|
for (let i = 0; i < spb; i++) {
|
|
407
408
|
syncs.push({
|
|
408
409
|
type: 'image',
|
|
409
|
-
url: 'https://cm.mgid.com/i.gif?' +
|
|
410
|
+
url: 'https://cm.mgid.com/i.gif?' + q.replace('{cbuster}', Math.round(new Date().getTime())) // randomly selects partner if sync required
|
|
410
411
|
});
|
|
411
412
|
}
|
|
412
413
|
} else {
|
|
413
414
|
for (let i = 0; i < spb && i < pixels.length; i++) {
|
|
414
415
|
syncs.push({
|
|
415
416
|
type: 'image',
|
|
416
|
-
url: pixels[i] + (pixels[i].indexOf('?') > 0 ? '&' : '?') +
|
|
417
|
+
url: pixels[i] + (pixels[i].indexOf('?') > 0 ? '&' : '?') + q.replace('{cbuster}', Math.round(new Date().getTime()))
|
|
417
418
|
});
|
|
418
419
|
}
|
|
419
420
|
}
|
|
@@ -289,6 +289,7 @@ function generateBidParameters(bid, bidderRequest) {
|
|
|
289
289
|
loop: getBidIdParameter('bidderRequestsCount', bid),
|
|
290
290
|
bidderRequestId: getBidIdParameter('bidderRequestId', bid),
|
|
291
291
|
transactionId: getBidIdParameter('transactionId', bid),
|
|
292
|
+
coppa: 0
|
|
292
293
|
};
|
|
293
294
|
|
|
294
295
|
const pos = deepAccess(bid, `mediaTypes.${mediaType}.pos`);
|
|
@@ -346,6 +347,11 @@ function generateBidParameters(bid, bidderRequest) {
|
|
|
346
347
|
if (linearity) {
|
|
347
348
|
bidObject.linearity = linearity;
|
|
348
349
|
}
|
|
350
|
+
|
|
351
|
+
const coppa = deepAccess(bid, `ortb2.regs.coppa`);
|
|
352
|
+
if (coppa) {
|
|
353
|
+
bidObject.coppa = 1;
|
|
354
|
+
}
|
|
349
355
|
}
|
|
350
356
|
|
|
351
357
|
return bidObject;
|
|
@@ -11,18 +11,7 @@ const BIDDER_VERSION = '1.0.0';
|
|
|
11
11
|
const CURRENCY = 'USD';
|
|
12
12
|
const TTL_SECONDS = 60 * 5;
|
|
13
13
|
const UNIQUE_DEAL_ID_EXPIRY = 1000 * 60 * 15;
|
|
14
|
-
|
|
15
|
-
'britepoolid': 1,
|
|
16
|
-
'criteoId': 1,
|
|
17
|
-
'id5id': 1,
|
|
18
|
-
'idl_env': 1,
|
|
19
|
-
'lipb': 1,
|
|
20
|
-
'netId': 1,
|
|
21
|
-
'parrableId': 1,
|
|
22
|
-
'pubcid': 1,
|
|
23
|
-
'tdid': 1,
|
|
24
|
-
'pubProvidedId': 1
|
|
25
|
-
};
|
|
14
|
+
|
|
26
15
|
const storage = getStorageManager({bidderCode: BIDDER_CODE});
|
|
27
16
|
|
|
28
17
|
function getTopWindowQueryParams() {
|
|
@@ -161,25 +150,23 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) {
|
|
|
161
150
|
function appendUserIdsToRequestPayload(payloadRef, userIds) {
|
|
162
151
|
let key;
|
|
163
152
|
_each(userIds, (userId, idSystemProviderName) => {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
payloadRef[key] = userId;
|
|
182
|
-
}
|
|
153
|
+
key = `uid.${idSystemProviderName}`;
|
|
154
|
+
|
|
155
|
+
switch (idSystemProviderName) {
|
|
156
|
+
case 'digitrustid':
|
|
157
|
+
payloadRef[key] = deepAccess(userId, 'data.id');
|
|
158
|
+
break;
|
|
159
|
+
case 'lipb':
|
|
160
|
+
payloadRef[key] = userId.lipbid;
|
|
161
|
+
break;
|
|
162
|
+
case 'parrableId':
|
|
163
|
+
payloadRef[key] = userId.eid;
|
|
164
|
+
break;
|
|
165
|
+
case 'id5id':
|
|
166
|
+
payloadRef[key] = userId.uid;
|
|
167
|
+
break;
|
|
168
|
+
default:
|
|
169
|
+
payloadRef[key] = userId;
|
|
183
170
|
}
|
|
184
171
|
});
|
|
185
172
|
}
|
|
@@ -207,7 +194,18 @@ function interpretResponse(serverResponse, request) {
|
|
|
207
194
|
|
|
208
195
|
try {
|
|
209
196
|
results.forEach(result => {
|
|
210
|
-
const {
|
|
197
|
+
const {
|
|
198
|
+
creativeId,
|
|
199
|
+
ad,
|
|
200
|
+
price,
|
|
201
|
+
exp,
|
|
202
|
+
width,
|
|
203
|
+
height,
|
|
204
|
+
currency,
|
|
205
|
+
metaData,
|
|
206
|
+
advertiserDomains,
|
|
207
|
+
mediaType = BANNER
|
|
208
|
+
} = result;
|
|
211
209
|
if (!ad || !price) {
|
|
212
210
|
return;
|
|
213
211
|
}
|
|
@@ -21,7 +21,8 @@ const ALIASES = [
|
|
|
21
21
|
{ code: 'revenuemaker' },
|
|
22
22
|
{ code: 'first-id', gvlid: 1178 },
|
|
23
23
|
{ code: 'adwebone' },
|
|
24
|
-
{ code: 'league-m', gvlid: 965 }
|
|
24
|
+
{ code: 'league-m', gvlid: 965 },
|
|
25
|
+
{ code: 'prjads' },
|
|
25
26
|
];
|
|
26
27
|
|
|
27
28
|
export const storage = getStorageManager({
|
|
@@ -260,9 +260,7 @@ function queueSync(bidderCodes, gdprConsent, uspConsent, gppConsent, s2sConfig)
|
|
|
260
260
|
}
|
|
261
261
|
|
|
262
262
|
if (gppConsent) {
|
|
263
|
-
|
|
264
|
-
// update - leaving this param as an array, since it's part of a POST payload where the [] characters shouldn't matter too much
|
|
265
|
-
payload.gpp_sid = gppConsent.applicableSections
|
|
263
|
+
payload.gpp_sid = gppConsent.applicableSections.join();
|
|
266
264
|
// should we add check if applicableSections was not equal to -1 (where user was out of scope)?
|
|
267
265
|
// this would be similar to what was done above for TCF
|
|
268
266
|
payload.gpp = gppConsent.gppString;
|
|
@@ -167,7 +167,11 @@ const PBS_CONVERTER = ortbConverter({
|
|
|
167
167
|
deepSetValue(ortbRequest, 'ext.prebid', mergeDeep(ortbRequest.ext?.prebid || {}, context.s2sBidRequest.s2sConfig.extPrebid));
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
const fpdConfigs = Object.entries(context.s2sBidRequest.ortb2Fragments?.bidder || {}).
|
|
170
|
+
const fpdConfigs = Object.entries(context.s2sBidRequest.ortb2Fragments?.bidder || {}).filter(([bidder]) => {
|
|
171
|
+
const bidders = context.s2sBidRequest.s2sConfig.bidders;
|
|
172
|
+
const allowUnknownBidderCodes = context.s2sBidRequest.s2sConfig.allowUnknownBidderCodes;
|
|
173
|
+
return allowUnknownBidderCodes || (bidders && bidders.includes(bidder));
|
|
174
|
+
}).map(([bidder, ortb2]) => ({
|
|
171
175
|
bidders: [bidder],
|
|
172
176
|
config: {ortb2}
|
|
173
177
|
}));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _each, pick, logWarn, isStr, isArray, logError } from '../src/utils.js';
|
|
1
|
+
import { _each, pick, logWarn, isStr, isArray, logError, getGptSlotInfoForAdUnitCode } from '../src/utils.js';
|
|
2
2
|
import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
|
|
3
3
|
import adapterManager from '../src/adapterManager.js';
|
|
4
4
|
import CONSTANTS from '../src/constants.json';
|
|
@@ -353,9 +353,10 @@ function executeBidsLoggerCall(e, highestCpmBids) {
|
|
|
353
353
|
outputObj.s = Object.keys(auctionCache.adUnitCodes).reduce(function(slotsArray, adUnitId) {
|
|
354
354
|
let adUnit = auctionCache.adUnitCodes[adUnitId];
|
|
355
355
|
let origAdUnit = getAdUnit(auctionCache.origAdUnits, adUnitId) || {};
|
|
356
|
+
// getGptSlotInfoForAdUnitCode returns gptslot corresponding to adunit provided as input.
|
|
356
357
|
let slotObject = {
|
|
357
358
|
'sn': adUnitId,
|
|
358
|
-
'au': origAdUnit.adUnitId || adUnitId,
|
|
359
|
+
'au': origAdUnit.adUnitId || getGptSlotInfoForAdUnitCode(adUnitId)?.gptSlot || adUnitId,
|
|
359
360
|
'mt': getAdUnitAdFormats(origAdUnit),
|
|
360
361
|
'sz': getSizesForAdUnit(adUnit, adUnitId),
|
|
361
362
|
'ps': gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestCpmBids.filter(bid => bid.adUnitCode === adUnitId)),
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
Module Name: RetailSpot Bidder Adapter
|
|
4
|
+
Module Type: Bidder Adapter
|
|
5
|
+
Maintainer: guillaume@retail-spot.io
|
|
6
|
+
|
|
7
|
+
# Description
|
|
8
|
+
|
|
9
|
+
Module that connects to RetailSpot demand sources.
|
|
10
|
+
Banner and Video ad formats are supported.
|
|
11
|
+
|
|
12
|
+
# Test Parameters
|
|
13
|
+
```
|
|
14
|
+
var adUnits = {
|
|
15
|
+
"code": "test-div",
|
|
16
|
+
"mediaTypes": {
|
|
17
|
+
"banner": {
|
|
18
|
+
"sizes": ["300x250"]
|
|
19
|
+
},
|
|
20
|
+
"video": {
|
|
21
|
+
context: "instream",
|
|
22
|
+
playerSize: [[640, 480]]
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
bids: [{
|
|
26
|
+
bidder: "retailspot",
|
|
27
|
+
params: {
|
|
28
|
+
placement: "test-12345"
|
|
29
|
+
}
|
|
30
|
+
}]
|
|
31
|
+
};
|
|
32
|
+
```
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import {buildUrl, deepAccess, parseSizesInput} from '../src/utils.js';
|
|
2
|
+
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
3
|
+
import {BANNER, VIDEO} from '../src/mediaTypes.js';
|
|
4
|
+
|
|
5
|
+
const BIDDER_CODE = 'retailspot';
|
|
6
|
+
const DEFAULT_SUBDOMAIN = 'ssp';
|
|
7
|
+
const PREPROD_SUBDOMAIN = 'ssp-preprod';
|
|
8
|
+
const HOST = 'retail-spot.io';
|
|
9
|
+
const ENDPOINT = '/prebid';
|
|
10
|
+
const DEV_URL = 'http://localhost:8090/prebid';
|
|
11
|
+
|
|
12
|
+
export const spec = {
|
|
13
|
+
code: BIDDER_CODE,
|
|
14
|
+
supportedMediaTypes: [BANNER, VIDEO],
|
|
15
|
+
aliases: ['rs'], // short code
|
|
16
|
+
/**
|
|
17
|
+
* Determines whether or not the given bid request is valid.
|
|
18
|
+
*
|
|
19
|
+
* @param {BidRequest} bid The bid params to validate.
|
|
20
|
+
* @return boolean True if this is a valid bid, and false otherwise.
|
|
21
|
+
*/
|
|
22
|
+
isBidRequestValid: function (bid) {
|
|
23
|
+
const sizes = getSize(getSizeArray(bid));
|
|
24
|
+
const sizeValid = sizes.width > 0 && sizes.height > 0;
|
|
25
|
+
|
|
26
|
+
return deepAccess(bid, 'params.placement') && sizeValid;
|
|
27
|
+
},
|
|
28
|
+
/**
|
|
29
|
+
* Make a server request from the list of BidRequests.
|
|
30
|
+
*
|
|
31
|
+
* @param {bidRequests} - bidRequests.bids[] is an array of AdUnits and bids
|
|
32
|
+
* @return ServerRequest Info describing the request to the server.
|
|
33
|
+
*/
|
|
34
|
+
buildRequests: function (bidRequests, bidderRequest) {
|
|
35
|
+
const payload = bidderRequest;
|
|
36
|
+
payload.rs_pbjs_version = '$prebid.version$';
|
|
37
|
+
|
|
38
|
+
const data = JSON.stringify(payload);
|
|
39
|
+
const options = {
|
|
40
|
+
withCredentials: true
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const envParam = bidRequests[0].params.env;
|
|
44
|
+
var subDomain = DEFAULT_SUBDOMAIN;
|
|
45
|
+
if (envParam === 'preprod') {
|
|
46
|
+
subDomain = PREPROD_SUBDOMAIN;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let url = buildUrl({
|
|
50
|
+
protocol: 'https',
|
|
51
|
+
host: `${subDomain}.${HOST}`,
|
|
52
|
+
pathname: ENDPOINT
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
if (envParam === 'dev') {
|
|
56
|
+
url = DEV_URL;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
method: 'POST',
|
|
61
|
+
url,
|
|
62
|
+
data,
|
|
63
|
+
options
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
/**
|
|
67
|
+
* Unpack the response from the server into a list of bids.
|
|
68
|
+
*
|
|
69
|
+
* @param {*} serverResponse A successful response from the server.
|
|
70
|
+
* @return {Bid[]} An array of bids which were nested inside the server.
|
|
71
|
+
*/
|
|
72
|
+
interpretResponse: function (serverResponse, request) {
|
|
73
|
+
const bidResponses = [];
|
|
74
|
+
var bidRequests = {};
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
bidRequests = JSON.parse(request.data).bids;
|
|
78
|
+
} catch (err) {
|
|
79
|
+
// json error initial request can't be read
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// For this adapter, serverResponse is a list
|
|
83
|
+
serverResponse.body.forEach(response => {
|
|
84
|
+
const bid = createBid(response, bidRequests);
|
|
85
|
+
if (bid) {
|
|
86
|
+
bidResponses.push(bid);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
return bidResponses;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function getSizeArray(bid) {
|
|
95
|
+
let inputSize = bid.sizes || [];
|
|
96
|
+
|
|
97
|
+
if (bid.mediaTypes && bid.mediaTypes.banner) {
|
|
98
|
+
inputSize = bid.mediaTypes.banner.sizes || [];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// handle size in bid.params in formats: [w, h] and [[w,h]].
|
|
102
|
+
if (bid.params && Array.isArray(bid.params.size)) {
|
|
103
|
+
inputSize = bid.params.size;
|
|
104
|
+
if (!Array.isArray(inputSize[0])) {
|
|
105
|
+
inputSize = [inputSize]
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return parseSizesInput(inputSize);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/* Get parsed size from request size */
|
|
113
|
+
function getSize(sizesArray) {
|
|
114
|
+
const parsed = {};
|
|
115
|
+
// the main requested size is the first one
|
|
116
|
+
const size = sizesArray[0];
|
|
117
|
+
|
|
118
|
+
if (typeof size !== 'string') {
|
|
119
|
+
return parsed;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const parsedSize = size.toUpperCase().split('X');
|
|
123
|
+
const width = parseInt(parsedSize[0], 10);
|
|
124
|
+
if (width) {
|
|
125
|
+
parsed.width = width;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const height = parseInt(parsedSize[1], 10);
|
|
129
|
+
if (height) {
|
|
130
|
+
parsed.height = height;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return parsed;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* Create bid from response */
|
|
137
|
+
function createBid(response, bidRequests) {
|
|
138
|
+
if (!response || !response.mediaType ||
|
|
139
|
+
(response.mediaType === 'video' && !response.vastXml) ||
|
|
140
|
+
(response.mediaType === 'banner' && !response.ad)) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const request = bidRequests && bidRequests.length && bidRequests.find(itm => response.requestId === itm.bidId);
|
|
145
|
+
// In case we don't retreive the size from the adserver, use the given one.
|
|
146
|
+
if (request) {
|
|
147
|
+
if (!response.width || response.width === '0') {
|
|
148
|
+
response.width = request.width;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (!response.height || response.height === '0') {
|
|
152
|
+
response.height = request.height;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const bid = {
|
|
157
|
+
bidderCode: BIDDER_CODE,
|
|
158
|
+
width: response.width,
|
|
159
|
+
height: response.height,
|
|
160
|
+
requestId: response.requestId,
|
|
161
|
+
ttl: response.ttl || 3600,
|
|
162
|
+
creativeId: response.creativeId,
|
|
163
|
+
cpm: response.cpm,
|
|
164
|
+
netRevenue: response.netRevenue,
|
|
165
|
+
currency: response.currency,
|
|
166
|
+
meta: response.meta || { advertiserDomains: ['retail-spot.io'] },
|
|
167
|
+
mediaType: response.mediaType
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// retreive video response if present
|
|
171
|
+
if (response.mediaType === 'video') {
|
|
172
|
+
bid.vastXml = window.atob(response.vastXml);
|
|
173
|
+
} else {
|
|
174
|
+
bid.ad = response.ad;
|
|
175
|
+
}
|
|
176
|
+
if (response.adId) {
|
|
177
|
+
bid.adId = response.adId;
|
|
178
|
+
}
|
|
179
|
+
if (response.dealId) {
|
|
180
|
+
bid.dealId = response.dealId;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return bid;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
registerBidder(spec);
|
|
@@ -292,6 +292,7 @@ function generateBidParameters(bid, bidderRequest) {
|
|
|
292
292
|
bidderRequestId: getBidIdParameter('bidderRequestId', bid),
|
|
293
293
|
loop: getBidIdParameter('bidderRequestsCount', bid),
|
|
294
294
|
transactionId: getBidIdParameter('transactionId', bid),
|
|
295
|
+
coppa: 0
|
|
295
296
|
};
|
|
296
297
|
|
|
297
298
|
const pos = deepAccess(bid, `mediaTypes.${mediaType}.pos`);
|
|
@@ -364,6 +365,11 @@ function generateBidParameters(bid, bidderRequest) {
|
|
|
364
365
|
if (protocols) {
|
|
365
366
|
bidObject.protocols = protocols;
|
|
366
367
|
}
|
|
368
|
+
|
|
369
|
+
const coppa = deepAccess(bid, 'ortb2.regs.coppa')
|
|
370
|
+
if (coppa) {
|
|
371
|
+
bidObject.coppa = 1;
|
|
372
|
+
}
|
|
367
373
|
}
|
|
368
374
|
|
|
369
375
|
return bidObject;
|
package/modules/ttdBidAdapter.js
CHANGED
|
@@ -2,6 +2,7 @@ import * as utils from '../src/utils.js';
|
|
|
2
2
|
import { config } from '../src/config.js';
|
|
3
3
|
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
4
4
|
import { BANNER, VIDEO } from '../src/mediaTypes.js';
|
|
5
|
+
import {isNumber} from '../src/utils.js';
|
|
5
6
|
|
|
6
7
|
const BIDADAPTERVERSION = 'TTD-PREBID-2022.06.28';
|
|
7
8
|
const BIDDER_CODE = 'ttd';
|
|
@@ -75,7 +76,7 @@ function getSource(validBidRequests) {
|
|
|
75
76
|
return source;
|
|
76
77
|
}
|
|
77
78
|
|
|
78
|
-
function getDevice() {
|
|
79
|
+
function getDevice(firstPartyData) {
|
|
79
80
|
const language = navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage;
|
|
80
81
|
let device = {
|
|
81
82
|
ua: navigator.userAgent,
|
|
@@ -84,6 +85,8 @@ function getDevice() {
|
|
|
84
85
|
connectiontype: getConnectionType()
|
|
85
86
|
};
|
|
86
87
|
|
|
88
|
+
utils.mergeDeep(device, firstPartyData.device)
|
|
89
|
+
|
|
87
90
|
return device;
|
|
88
91
|
};
|
|
89
92
|
|
|
@@ -114,7 +117,7 @@ function getConnectionType() {
|
|
|
114
117
|
}
|
|
115
118
|
}
|
|
116
119
|
|
|
117
|
-
function getUser(bidderRequest) {
|
|
120
|
+
function getUser(bidderRequest, firstPartyData) {
|
|
118
121
|
let user = {};
|
|
119
122
|
if (bidderRequest.gdprConsent) {
|
|
120
123
|
utils.deepSetValue(user, 'ext.consent', bidderRequest.gdprConsent.consentString);
|
|
@@ -129,13 +132,8 @@ function getUser(bidderRequest) {
|
|
|
129
132
|
utils.deepSetValue(user, 'ext.eids', eids);
|
|
130
133
|
}
|
|
131
134
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (ortb2UserData && ortb2UserData.length) {
|
|
135
|
-
user = utils.mergeDeep(user, {
|
|
136
|
-
data: [...ortb2UserData]
|
|
137
|
-
});
|
|
138
|
-
};
|
|
135
|
+
utils.mergeDeep(user, firstPartyData.user)
|
|
136
|
+
|
|
139
137
|
return user;
|
|
140
138
|
}
|
|
141
139
|
|
|
@@ -163,16 +161,6 @@ function getImpression(bidRequest) {
|
|
|
163
161
|
};
|
|
164
162
|
|
|
165
163
|
const gpid = utils.deepAccess(bidRequest, 'ortb2Imp.ext.gpid');
|
|
166
|
-
const tid = utils.deepAccess(bidRequest, 'ortb2Imp.ext.tid');
|
|
167
|
-
const rwdd = utils.deepAccess(bidRequest, 'ortb2Imp.rwdd');
|
|
168
|
-
if (gpid || tid) {
|
|
169
|
-
impression.ext = {}
|
|
170
|
-
if (gpid) { impression.ext.gpid = gpid }
|
|
171
|
-
if (tid) { impression.ext.tid = tid }
|
|
172
|
-
}
|
|
173
|
-
if (rwdd) {
|
|
174
|
-
impression.rwdd = rwdd;
|
|
175
|
-
}
|
|
176
164
|
const tagid = gpid || bidRequest.params.placementId;
|
|
177
165
|
if (tagid) {
|
|
178
166
|
impression.tagid = tagid;
|
|
@@ -197,6 +185,11 @@ function getImpression(bidRequest) {
|
|
|
197
185
|
impression.bidfloorcur = 'USD';
|
|
198
186
|
}
|
|
199
187
|
|
|
188
|
+
const secure = utils.deepAccess(bidRequest, 'ortb2Imp.secure');
|
|
189
|
+
impression.secure = isNumber(secure) ? secure : 1
|
|
190
|
+
|
|
191
|
+
utils.mergeDeep(impression, bidRequest.ortb2Imp)
|
|
192
|
+
|
|
200
193
|
return impression;
|
|
201
194
|
}
|
|
202
195
|
|
|
@@ -416,8 +409,8 @@ export const spec = {
|
|
|
416
409
|
id: bidderRequest.auctionId,
|
|
417
410
|
imp: validBidRequests.map(bidRequest => getImpression(bidRequest)),
|
|
418
411
|
site: getSite(bidderRequest, firstPartyData),
|
|
419
|
-
device: getDevice(),
|
|
420
|
-
user: getUser(bidderRequest),
|
|
412
|
+
device: getDevice(firstPartyData),
|
|
413
|
+
user: getUser(bidderRequest, firstPartyData),
|
|
421
414
|
at: 1,
|
|
422
415
|
cur: ['USD'],
|
|
423
416
|
regs: getRegs(bidderRequest),
|
|
@@ -433,6 +426,14 @@ export const spec = {
|
|
|
433
426
|
topLevel.badv = firstPartyData.badv;
|
|
434
427
|
}
|
|
435
428
|
|
|
429
|
+
if (firstPartyData && firstPartyData.app) {
|
|
430
|
+
topLevel.app = firstPartyData.app
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (firstPartyData && firstPartyData.pmp) {
|
|
434
|
+
topLevel.pmp = firstPartyData.pmp
|
|
435
|
+
}
|
|
436
|
+
|
|
436
437
|
let url = BIDDER_ENDPOINT + bidderRequest.bids[0].params.supplySourceId;
|
|
437
438
|
|
|
438
439
|
let serverRequest = {
|
|
@@ -468,7 +469,7 @@ export const spec = {
|
|
|
468
469
|
* @param {ttdResponseObj} bidResponse A successful response from ttd.
|
|
469
470
|
* @param {ServerRequest} serverRequest The result of buildRequests() that lead to this response.
|
|
470
471
|
* @return {Bid[]} An array of formatted bids.
|
|
471
|
-
|
|
472
|
+
*/
|
|
472
473
|
interpretResponse: function (response, serverRequest) {
|
|
473
474
|
let seatBidsInResponse = utils.deepAccess(response, 'body.seatbid');
|
|
474
475
|
const currency = utils.deepAccess(response, 'body.cur');
|
|
@@ -15,18 +15,6 @@ const DEAL_ID_EXPIRY = 1000 * 60 * 15;
|
|
|
15
15
|
const UNIQUE_DEAL_ID_EXPIRY = 1000 * 60 * 60;
|
|
16
16
|
const SESSION_ID_KEY = 'vidSid';
|
|
17
17
|
const OPT_CACHE_KEY = 'vdzwopt';
|
|
18
|
-
export const SUPPORTED_ID_SYSTEMS = {
|
|
19
|
-
'britepoolid': 1,
|
|
20
|
-
'criteoId': 1,
|
|
21
|
-
'id5id': 1,
|
|
22
|
-
'idl_env': 1,
|
|
23
|
-
'lipb': 1,
|
|
24
|
-
'netId': 1,
|
|
25
|
-
'parrableId': 1,
|
|
26
|
-
'pubcid': 1,
|
|
27
|
-
'tdid': 1,
|
|
28
|
-
'pubProvidedId': 1
|
|
29
|
-
};
|
|
30
18
|
export const webSessionId = 'wsid_' + parseInt(Date.now() * Math.random());
|
|
31
19
|
const storage = getStorageManager({bidderCode: BIDDER_CODE});
|
|
32
20
|
|
|
@@ -180,25 +168,22 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) {
|
|
|
180
168
|
function appendUserIdsToRequestPayload(payloadRef, userIds) {
|
|
181
169
|
let key;
|
|
182
170
|
_each(userIds, (userId, idSystemProviderName) => {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
default:
|
|
200
|
-
payloadRef[key] = userId;
|
|
201
|
-
}
|
|
171
|
+
key = `uid.${idSystemProviderName}`;
|
|
172
|
+
switch (idSystemProviderName) {
|
|
173
|
+
case 'digitrustid':
|
|
174
|
+
payloadRef[key] = deepAccess(userId, 'data.id');
|
|
175
|
+
break;
|
|
176
|
+
case 'lipb':
|
|
177
|
+
payloadRef[key] = userId.lipbid;
|
|
178
|
+
break;
|
|
179
|
+
case 'parrableId':
|
|
180
|
+
payloadRef[key] = userId.eid;
|
|
181
|
+
break;
|
|
182
|
+
case 'id5id':
|
|
183
|
+
payloadRef[key] = userId.uid;
|
|
184
|
+
break;
|
|
185
|
+
default:
|
|
186
|
+
payloadRef[key] = userId;
|
|
202
187
|
}
|
|
203
188
|
});
|
|
204
189
|
}
|
|
@@ -227,7 +212,18 @@ function interpretResponse(serverResponse, request) {
|
|
|
227
212
|
|
|
228
213
|
try {
|
|
229
214
|
results.forEach(result => {
|
|
230
|
-
const {
|
|
215
|
+
const {
|
|
216
|
+
creativeId,
|
|
217
|
+
ad,
|
|
218
|
+
price,
|
|
219
|
+
exp,
|
|
220
|
+
width,
|
|
221
|
+
height,
|
|
222
|
+
currency,
|
|
223
|
+
advertiserDomains,
|
|
224
|
+
metaData,
|
|
225
|
+
mediaType = BANNER
|
|
226
|
+
} = result;
|
|
231
227
|
if (!ad || !price) {
|
|
232
228
|
return;
|
|
233
229
|
}
|