prebid.js 5.18.0 → 5.20.2
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/browsers.json +1 -0
- package/integrationExamples/gpt/akamaidap_segments_example.html +132 -0
- package/modules/.submodules.json +1 -0
- package/modules/adfBidAdapter.js +21 -16
- package/modules/adtelligentBidAdapter.js +2 -1
- package/modules/adxcgBidAdapter.js +311 -359
- package/modules/airgridRtdProvider.js +1 -1
- package/modules/akamaiDapRtdProvider.js +474 -0
- package/modules/akamaiDapRtdProvider.md +47 -0
- package/modules/appnexusBidAdapter.js +9 -3
- package/modules/atsAnalyticsAdapter.js +67 -46
- package/modules/atsAnalyticsAdapter.md +1 -0
- package/modules/betweenBidAdapter.js +20 -3
- package/modules/browsiRtdProvider.js +106 -18
- package/modules/cleanioRtdProvider.js +192 -0
- package/modules/cleanioRtdProvider.md +59 -0
- package/modules/codefuelBidAdapter.js +183 -0
- package/modules/codefuelBidAdapter.md +111 -0
- package/modules/connectIdSystem.js +104 -0
- package/modules/connectIdSystem.md +33 -0
- package/modules/deepintentBidAdapter.js +106 -9
- package/modules/deepintentBidAdapter.md +36 -1
- package/modules/deltaprojectsBidAdapter.js +252 -0
- package/modules/deltaprojectsBidAdapter.md +32 -0
- package/modules/engageyaBidAdapter.js +157 -0
- package/modules/gridBidAdapter.js +1 -0
- package/modules/gumgumBidAdapter.js +8 -0
- package/modules/inskinBidAdapter.js +7 -3
- package/modules/ipromBidAdapter.js +79 -0
- package/modules/ixBidAdapter.js +8 -1
- package/modules/jixieBidAdapter.js +8 -2
- package/modules/justpremiumBidAdapter.js +6 -1
- package/modules/kinessoIdSystem.js +1 -1
- package/modules/limelightDigitalBidAdapter.js +22 -2
- package/modules/livewrappedAnalyticsAdapter.js +49 -1
- package/modules/multibid/index.js +3 -3
- package/modules/nativoBidAdapter.js +5 -1
- package/modules/nextMillenniumBidAdapter.js +12 -3
- package/modules/oguryBidAdapter.js +14 -1
- package/modules/openxBidAdapter.js +34 -22
- package/modules/operaadsBidAdapter.js +21 -1
- package/modules/otmBidAdapter.js +146 -0
- package/modules/otmBidAdapter.md +27 -26
- package/modules/outbrainBidAdapter.js +5 -0
- package/modules/playwireBidAdapter.md +61 -0
- package/modules/publinkIdSystem.js +11 -6
- package/modules/rtdModule/index.js +2 -2
- package/modules/sonobiBidAdapter.js +7 -0
- package/modules/sortableBidAdapter.js +1 -0
- package/modules/teadsBidAdapter.js +3 -0
- package/modules/tripleliftBidAdapter.js +22 -5
- package/modules/trustxBidAdapter.js +8 -6
- package/modules/undertoneBidAdapter.js +9 -5
- package/modules/undertoneBidAdapter.md +5 -1
- package/modules/userId/eids.js +18 -0
- package/modules/userId/eids.md +7 -0
- package/modules/userId/userId.md +12 -0
- package/modules/ventesBidAdapter.js +370 -0
- package/modules/ventesBidAdapter.md +94 -0
- package/modules/videobyteBidAdapter.js +13 -6
- package/modules/videobyteBidAdapter.md +49 -0
- package/modules/yahoosspBidAdapter.js +6 -6
- package/modules/yieldmoSyntheticInventoryModule.js +46 -0
- package/modules/yieldmoSyntheticInventoryModule.md +68 -0
- package/package.json +1 -1
- package/src/adapterManager.js +5 -0
- package/src/adapters/bidderFactory.js +4 -3
- package/src/auction.js +11 -11
- package/src/constants.json +1 -0
- package/src/secureCreatives.js +6 -7
- package/src/targeting.js +11 -9
- package/test/spec/modules/adfBidAdapter_spec.js +83 -29
- package/test/spec/modules/adtelligentBidAdapter_spec.js +1 -0
- package/test/spec/modules/adxcgBidAdapter_spec.js +827 -571
- package/test/spec/modules/akamaiDapRtdProvider_spec.js +246 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +16 -1
- package/test/spec/modules/atsAnalyticsAdapter_spec.js +42 -9
- package/test/spec/modules/betweenBidAdapter_spec.js +41 -0
- package/test/spec/modules/browsiRtdProvider_spec.js +62 -7
- package/test/spec/modules/cleanioRtdProvider_spec.js +188 -0
- package/test/spec/modules/codefuelBidAdapter_spec.js +316 -0
- package/test/spec/modules/connectIdSystem_spec.js +189 -0
- package/test/spec/modules/deepintentBidAdapter_spec.js +153 -3
- package/test/spec/modules/deltaprojectsBidAdapter_spec.js +399 -0
- package/test/spec/modules/engageyaBidAdapter_spec.js +286 -0
- package/test/spec/modules/eplanningBidAdapter_spec.js +8 -8
- package/test/spec/modules/gumgumBidAdapter_spec.js +5 -1
- package/test/spec/modules/ipromBidAdapter_spec.js +195 -0
- package/test/spec/modules/ixBidAdapter_spec.js +13 -3
- package/test/spec/modules/jixieBidAdapter_spec.js +13 -11
- package/test/spec/modules/justpremiumBidAdapter_spec.js +9 -2
- package/test/spec/modules/limelightDigitalBidAdapter_spec.js +155 -1
- package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +52 -7
- package/test/spec/modules/multibid_spec.js +31 -31
- package/test/spec/modules/nextMillenniumBidAdapter_spec.js +13 -1
- package/test/spec/modules/oguryBidAdapter_spec.js +53 -12
- package/test/spec/modules/openxBidAdapter_spec.js +85 -13
- package/test/spec/modules/operaadsBidAdapter_spec.js +38 -6
- package/test/spec/modules/otmBidAdapter_spec.js +67 -0
- package/test/spec/modules/outbrainBidAdapter_spec.js +18 -0
- package/test/spec/modules/publinkIdSystem_spec.js +6 -6
- package/test/spec/modules/sonobiBidAdapter_spec.js +34 -1
- package/test/spec/modules/sortableBidAdapter_spec.js +11 -0
- package/test/spec/modules/teadsBidAdapter_spec.js +132 -0
- package/test/spec/modules/tripleliftBidAdapter_spec.js +128 -0
- package/test/spec/modules/trustxBidAdapter_spec.js +3 -3
- package/test/spec/modules/undertoneBidAdapter_spec.js +52 -0
- package/test/spec/modules/ventesBidAdapter_spec.js +845 -0
- package/test/spec/modules/videobyteBidAdapter_spec.js +2 -2
- package/test/spec/modules/yieldmoSyntheticInventoryModule_spec.js +89 -0
- package/test/spec/unit/core/adapterManager_spec.js +37 -2
- package/test/spec/unit/core/bidderFactory_spec.js +61 -1
- package/test/spec/unit/pbjs_api_spec.js +37 -2
- package/test/spec/unit/secureCreatives_spec.js +54 -25
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { logMessage, groupBy, uniques } from '../src/utils.js';
|
|
1
|
+
import { logMessage, groupBy, uniques, flatten, deepAccess } from '../src/utils.js';
|
|
2
2
|
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
3
3
|
import { BANNER, VIDEO } from '../src/mediaTypes.js';
|
|
4
4
|
import {ajax} from '../src/ajax.js';
|
|
@@ -92,6 +92,26 @@ export const spec = {
|
|
|
92
92
|
}
|
|
93
93
|
return bidResponses;
|
|
94
94
|
},
|
|
95
|
+
|
|
96
|
+
getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => {
|
|
97
|
+
const syncs = serverResponses.map(response => response.body).reduce(flatten, [])
|
|
98
|
+
.map(response => deepAccess(response, 'ext.sync')).filter(Boolean);
|
|
99
|
+
const iframeSyncUrls = !syncOptions.iframeEnabled ? [] : syncs.map(sync => sync.iframe).filter(Boolean)
|
|
100
|
+
.filter(uniques).map(url => {
|
|
101
|
+
return {
|
|
102
|
+
type: 'iframe',
|
|
103
|
+
url: url
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
const pixelSyncUrls = !syncOptions.pixelEnabled ? [] : syncs.map(sync => sync.pixel).filter(Boolean)
|
|
107
|
+
.filter(uniques).map(url => {
|
|
108
|
+
return {
|
|
109
|
+
type: 'image',
|
|
110
|
+
url: url
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
return [iframeSyncUrls, pixelSyncUrls].reduce(flatten, []);
|
|
114
|
+
}
|
|
95
115
|
};
|
|
96
116
|
|
|
97
117
|
registerBidder(spec);
|
|
@@ -125,7 +145,7 @@ function buildPlacement(bidRequest) {
|
|
|
125
145
|
break;
|
|
126
146
|
}
|
|
127
147
|
}
|
|
128
|
-
sizes = (sizes || []).concat(bidRequest.sizes || [])
|
|
148
|
+
sizes = (sizes || []).concat(bidRequest.sizes || []);
|
|
129
149
|
return {
|
|
130
150
|
host: bidRequest.params.host,
|
|
131
151
|
adUnit: {
|
|
@@ -3,6 +3,7 @@ import {ajax} from '../src/ajax.js';
|
|
|
3
3
|
import adapter from '../src/AnalyticsAdapter.js';
|
|
4
4
|
import CONSTANTS from '../src/constants.json';
|
|
5
5
|
import adapterManager from '../src/adapterManager.js';
|
|
6
|
+
import { getGlobal } from '../src/prebidGlobal.js';
|
|
6
7
|
|
|
7
8
|
const ANALYTICSTYPE = 'endpoint';
|
|
8
9
|
const URL = 'https://lwadm.com/analytics/10';
|
|
@@ -11,8 +12,10 @@ const REQUESTSENT = 1;
|
|
|
11
12
|
const RESPONSESENT = 2;
|
|
12
13
|
const WINSENT = 4;
|
|
13
14
|
const TIMEOUTSENT = 8;
|
|
15
|
+
const ADRENDERFAILEDSENT = 16;
|
|
14
16
|
|
|
15
17
|
let initOptions;
|
|
18
|
+
let prebidGlobal = getGlobal();
|
|
16
19
|
export const BID_WON_TIMEOUT = 500;
|
|
17
20
|
|
|
18
21
|
const cache = {
|
|
@@ -78,6 +81,7 @@ let livewrappedAnalyticsAdapter = Object.assign(adapter({EMPTYURL, ANALYTICSTYPE
|
|
|
78
81
|
bidResponse.width = args.width;
|
|
79
82
|
bidResponse.height = args.height;
|
|
80
83
|
bidResponse.cpm = args.cpm;
|
|
84
|
+
bidResponse.originalCpm = prebidGlobal.convertCurrency(args.originalCpm, args.originalCurrency, args.currency);
|
|
81
85
|
bidResponse.ttr = args.timeToRespond;
|
|
82
86
|
bidResponse.readyToSend = 1;
|
|
83
87
|
bidResponse.mediaType = args.mediaType == 'native' ? 2 : (args.mediaType == 'video' ? 4 : 1);
|
|
@@ -114,6 +118,16 @@ let livewrappedAnalyticsAdapter = Object.assign(adapter({EMPTYURL, ANALYTICSTYPE
|
|
|
114
118
|
livewrappedAnalyticsAdapter.sendEvents();
|
|
115
119
|
}
|
|
116
120
|
break;
|
|
121
|
+
case CONSTANTS.EVENTS.AD_RENDER_FAILED:
|
|
122
|
+
logInfo('LIVEWRAPPED_AD_RENDER_FAILED:', args);
|
|
123
|
+
let adRenderFailedBid = cache.auctions[args.bid.auctionId].bids[args.bid.requestId];
|
|
124
|
+
adRenderFailedBid.adRenderFailed = true;
|
|
125
|
+
adRenderFailedBid.reason = args.reason;
|
|
126
|
+
adRenderFailedBid.message = args.message;
|
|
127
|
+
if (adRenderFailedBid.sendStatus != 0) {
|
|
128
|
+
livewrappedAnalyticsAdapter.sendEvents();
|
|
129
|
+
}
|
|
130
|
+
break;
|
|
117
131
|
case CONSTANTS.EVENTS.BID_TIMEOUT:
|
|
118
132
|
logInfo('LIVEWRAPPED_BID_TIMEOUT:', args);
|
|
119
133
|
args.forEach(timeout => {
|
|
@@ -151,13 +165,15 @@ livewrappedAnalyticsAdapter.sendEvents = function() {
|
|
|
151
165
|
wins: getWins(sentRequests.gdpr, sentRequests.auctionIds),
|
|
152
166
|
timeouts: getTimeouts(sentRequests.auctionIds),
|
|
153
167
|
bidAdUnits: getbidAdUnits(),
|
|
168
|
+
rf: getAdRenderFailed(sentRequests.auctionIds),
|
|
154
169
|
rcv: getAdblockerRecovered()
|
|
155
170
|
};
|
|
156
171
|
|
|
157
172
|
if (events.requests.length == 0 &&
|
|
158
173
|
events.responses.length == 0 &&
|
|
159
174
|
events.wins.length == 0 &&
|
|
160
|
-
events.timeouts.length == 0
|
|
175
|
+
events.timeouts.length == 0 &&
|
|
176
|
+
events.rf.length == 0) {
|
|
161
177
|
return;
|
|
162
178
|
}
|
|
163
179
|
|
|
@@ -224,6 +240,7 @@ function getResponses(gdpr, auctionIds) {
|
|
|
224
240
|
width: bid.width,
|
|
225
241
|
height: bid.height,
|
|
226
242
|
cpm: bid.cpm,
|
|
243
|
+
orgCpm: bid.originalCpm,
|
|
227
244
|
ttr: bid.ttr,
|
|
228
245
|
IsBid: bid.isBid,
|
|
229
246
|
mediaType: bid.mediaType,
|
|
@@ -263,6 +280,7 @@ function getWins(gdpr, auctionIds) {
|
|
|
263
280
|
width: bid.width,
|
|
264
281
|
height: bid.height,
|
|
265
282
|
cpm: bid.cpm,
|
|
283
|
+
orgCpm: bid.originalCpm,
|
|
266
284
|
mediaType: bid.mediaType,
|
|
267
285
|
gdpr: gdprPos,
|
|
268
286
|
floor: bid.lwFloor ? bid.lwFloor : (bid.floorData ? bid.floorData.floorValue : undefined),
|
|
@@ -338,6 +356,36 @@ function getTimeouts(auctionIds) {
|
|
|
338
356
|
return timeouts;
|
|
339
357
|
}
|
|
340
358
|
|
|
359
|
+
function getAdRenderFailed(auctionIds) {
|
|
360
|
+
var adRenderFails = [];
|
|
361
|
+
|
|
362
|
+
Object.keys(cache.auctions).forEach(auctionId => {
|
|
363
|
+
let auctionIdPos = getAuctionIdPos(auctionIds, auctionId);
|
|
364
|
+
Object.keys(cache.auctions[auctionId].bids).forEach(bidId => {
|
|
365
|
+
let auction = cache.auctions[auctionId];
|
|
366
|
+
let bid = auction.bids[bidId];
|
|
367
|
+
if (!(bid.sendStatus & ADRENDERFAILEDSENT) && bid.adRenderFailed) {
|
|
368
|
+
bid.sendStatus |= ADRENDERFAILEDSENT;
|
|
369
|
+
|
|
370
|
+
adRenderFails.push({
|
|
371
|
+
bidder: bid.bidder,
|
|
372
|
+
adUnit: bid.adUnit,
|
|
373
|
+
adUnitId: bid.adUnitId,
|
|
374
|
+
timeStamp: auction.timeStamp,
|
|
375
|
+
auctionId: auctionIdPos,
|
|
376
|
+
auc: bid.auc,
|
|
377
|
+
buc: bid.buc,
|
|
378
|
+
lw: bid.lw,
|
|
379
|
+
rsn: bid.reason,
|
|
380
|
+
msg: bid.message
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
return adRenderFails;
|
|
387
|
+
}
|
|
388
|
+
|
|
341
389
|
function getbidAdUnits() {
|
|
342
390
|
var bidAdUnits = [];
|
|
343
391
|
|
|
@@ -112,7 +112,7 @@ export function addBidResponseHook(fn, adUnitCode, bid) {
|
|
|
112
112
|
if (multiConfig[bid.bidderCode].prefix) bid.multibidPrefix = multiConfig[bid.bidderCode].prefix;
|
|
113
113
|
bid.originalBidder = bid.bidderCode;
|
|
114
114
|
// Check if stored bids for auction include adUnitCode.bidder and max limit not reach for ad unit
|
|
115
|
-
if (deepAccess(multibidUnits,
|
|
115
|
+
if (deepAccess(multibidUnits, [adUnitCode, bid.bidderCode])) {
|
|
116
116
|
// Store request id under new property originalRequestId, create new unique bidId,
|
|
117
117
|
// and push bid into multibid stored bids for auction if max not reached and bid cpm above floor
|
|
118
118
|
if (!multibidUnits[adUnitCode][bid.bidderCode].maxReached && (!floor || floor <= bid.cpm)) {
|
|
@@ -131,9 +131,9 @@ export function addBidResponseHook(fn, adUnitCode, bid) {
|
|
|
131
131
|
logWarn(`Filtering multibid received from bidder ${bid.bidderCode}: ` + ((multibidUnits[adUnitCode][bid.bidderCode].maxReached) ? `Maximum bid limit reached for ad unit code ${adUnitCode}` : 'Bid cpm under floors value.'));
|
|
132
132
|
}
|
|
133
133
|
} else {
|
|
134
|
-
if (deepAccess(bid, 'floorData.floorValue')) deepSetValue(multibidUnits,
|
|
134
|
+
if (deepAccess(bid, 'floorData.floorValue')) deepSetValue(multibidUnits, [adUnitCode, bid.bidderCode], {floor: deepAccess(bid, 'floorData.floorValue')});
|
|
135
135
|
|
|
136
|
-
deepSetValue(multibidUnits,
|
|
136
|
+
deepSetValue(multibidUnits, [adUnitCode, bid.bidderCode], {ads: [bid]});
|
|
137
137
|
if (multibidUnits[adUnitCode][bid.bidderCode].ads.length === multiConfig[bid.bidderCode].maxbids) multibidUnits[adUnitCode][bid.bidderCode].maxReached = true;
|
|
138
138
|
|
|
139
139
|
fn.call(this, adUnitCode, bid);
|
|
@@ -98,7 +98,11 @@ export const spec = {
|
|
|
98
98
|
]
|
|
99
99
|
|
|
100
100
|
if (placementIds.size > 0) {
|
|
101
|
-
|
|
101
|
+
// Convert Set to Array (IE 11 Safe)
|
|
102
|
+
const placements = []
|
|
103
|
+
placementIds.forEach((value) => placements.push(value))
|
|
104
|
+
// Append to query string paramters
|
|
105
|
+
params.unshift({ key: 'ntv_ptd', value: placements.join(',') })
|
|
102
106
|
}
|
|
103
107
|
|
|
104
108
|
if (bidderRequest.gdprConsent) {
|
|
@@ -30,14 +30,23 @@ export const spec = {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
+
|
|
33
34
|
const gdprConsent = bidderRequest && bidderRequest.gdprConsent;
|
|
35
|
+
const uspConsent = bidderRequest && bidderRequest.uspConsent
|
|
36
|
+
|
|
37
|
+
if (gdprConsent || uspConsent) {
|
|
38
|
+
postBody.regs = { ext: {} }
|
|
34
39
|
|
|
35
|
-
|
|
40
|
+
if (uspConsent) {
|
|
41
|
+
postBody.regs.ext.us_privacy = uspConsent;
|
|
42
|
+
}
|
|
36
43
|
if (typeof gdprConsent.gdprApplies !== 'undefined') {
|
|
37
|
-
postBody.
|
|
44
|
+
postBody.regs.ext.gdpr = gdprConsent.gdprApplies ? 1 : 0;
|
|
38
45
|
}
|
|
39
46
|
if (typeof gdprConsent.consentString !== 'undefined') {
|
|
40
|
-
postBody.
|
|
47
|
+
postBody.user = {
|
|
48
|
+
ext: { consent: gdprConsent.consentString }
|
|
49
|
+
}
|
|
41
50
|
}
|
|
42
51
|
}
|
|
43
52
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
import { BANNER } from '../src/mediaTypes.js';
|
|
4
|
-
import { getAdUnitSizes, logWarn, isFn } from '../src/utils.js';
|
|
4
|
+
import { getAdUnitSizes, logWarn, isFn, getWindowTop, getWindowSelf } from '../src/utils.js';
|
|
5
5
|
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
6
6
|
import { ajax } from '../src/ajax.js'
|
|
7
7
|
|
|
@@ -145,7 +145,19 @@ function getFloor(bid) {
|
|
|
145
145
|
return floorResult.currency === 'USD' ? floorResult.floor : 0;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
+
function getWindowContext() {
|
|
149
|
+
try {
|
|
150
|
+
return getWindowTop()
|
|
151
|
+
} catch (e) {
|
|
152
|
+
return getWindowSelf()
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
148
156
|
function onBidWon(bid) {
|
|
157
|
+
const w = getWindowContext()
|
|
158
|
+
w.OG_PREBID_BID_OBJECT = {
|
|
159
|
+
...(bid && { ...bid }),
|
|
160
|
+
}
|
|
149
161
|
if (bid && bid.hasOwnProperty('nurl') && bid.nurl.length > 0) ajax(bid['nurl'], null);
|
|
150
162
|
}
|
|
151
163
|
|
|
@@ -165,6 +177,7 @@ export const spec = {
|
|
|
165
177
|
interpretResponse,
|
|
166
178
|
getFloor,
|
|
167
179
|
onBidWon,
|
|
180
|
+
getWindowContext,
|
|
168
181
|
onTimeout
|
|
169
182
|
}
|
|
170
183
|
|
|
@@ -256,27 +256,14 @@ function buildCommonQueryParamsFromBids(bids, bidderRequest) {
|
|
|
256
256
|
nocache: new Date().getTime()
|
|
257
257
|
};
|
|
258
258
|
|
|
259
|
-
const
|
|
260
|
-
if (
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
data.name.length > 0)
|
|
268
|
-
)
|
|
269
|
-
.reduce((acc, data) => {
|
|
270
|
-
const name = typeof data.ext === 'object' && data.ext.segtax ? `${data.name}/${data.ext.segtax}` : data.name;
|
|
271
|
-
acc[name] = (acc[name] || []).concat(data.segment.map(seg => seg.id));
|
|
272
|
-
return acc;
|
|
273
|
-
}, {})
|
|
274
|
-
const sm = Object.keys(fpd)
|
|
275
|
-
.map((name, _) => name + ':' + fpd[name].join('|'))
|
|
276
|
-
.join(',')
|
|
277
|
-
if (sm.length > 0) {
|
|
278
|
-
defaultParams.sm = encodeURIComponent(sm);
|
|
279
|
-
}
|
|
259
|
+
const userDataSegments = buildFpdQueryParams('ortb2.user.data');
|
|
260
|
+
if (userDataSegments.length > 0) {
|
|
261
|
+
defaultParams.sm = userDataSegments;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const siteContentDataSegments = buildFpdQueryParams('ortb2.site.content.data');
|
|
265
|
+
if (siteContentDataSegments.length > 0) {
|
|
266
|
+
defaultParams.scsm = siteContentDataSegments;
|
|
280
267
|
}
|
|
281
268
|
|
|
282
269
|
if (bids[0].params.platform) {
|
|
@@ -317,12 +304,37 @@ function buildCommonQueryParamsFromBids(bids, bidderRequest) {
|
|
|
317
304
|
return defaultParams;
|
|
318
305
|
}
|
|
319
306
|
|
|
307
|
+
function buildFpdQueryParams(fpdPath) {
|
|
308
|
+
const firstPartyData = config.getConfig(fpdPath);
|
|
309
|
+
if (!Array.isArray(firstPartyData) || !firstPartyData.length) {
|
|
310
|
+
return '';
|
|
311
|
+
}
|
|
312
|
+
const fpd = firstPartyData
|
|
313
|
+
.filter(
|
|
314
|
+
data => (Array.isArray(data.segment) &&
|
|
315
|
+
data.segment.length > 0 &&
|
|
316
|
+
data.name !== undefined &&
|
|
317
|
+
data.name.length > 0)
|
|
318
|
+
)
|
|
319
|
+
.reduce((acc, data) => {
|
|
320
|
+
const name = typeof data.ext === 'object' && data.ext.segtax ? `${data.name}/${data.ext.segtax}` : data.name;
|
|
321
|
+
acc[name] = (acc[name] || []).concat(data.segment.map(seg => seg.id));
|
|
322
|
+
return acc;
|
|
323
|
+
}, {})
|
|
324
|
+
return Object.keys(fpd)
|
|
325
|
+
.map((name, _) => name + ':' + fpd[name].join('|'))
|
|
326
|
+
.join(',')
|
|
327
|
+
}
|
|
328
|
+
|
|
320
329
|
function appendUserIdsToQueryParams(queryParams, userIds) {
|
|
321
330
|
_each(userIds, (userIdObjectOrValue, userIdProviderKey) => {
|
|
322
331
|
const key = USER_ID_CODE_TO_QUERY_ARG[userIdProviderKey];
|
|
323
332
|
|
|
324
333
|
if (USER_ID_CODE_TO_QUERY_ARG.hasOwnProperty(userIdProviderKey)) {
|
|
325
334
|
switch (userIdProviderKey) {
|
|
335
|
+
case 'merkleId':
|
|
336
|
+
queryParams[key] = userIdObjectOrValue.id;
|
|
337
|
+
break;
|
|
326
338
|
case 'flocId':
|
|
327
339
|
queryParams[key] = userIdObjectOrValue.id;
|
|
328
340
|
break;
|
|
@@ -333,7 +345,7 @@ function appendUserIdsToQueryParams(queryParams, userIds) {
|
|
|
333
345
|
queryParams[key] = userIdObjectOrValue.lipbid;
|
|
334
346
|
if (Array.isArray(userIdObjectOrValue.segments) && userIdObjectOrValue.segments.length > 0) {
|
|
335
347
|
const liveIntentSegments = 'liveintent:' + userIdObjectOrValue.segments.join('|')
|
|
336
|
-
queryParams.sm = `${queryParams.sm ? queryParams.sm +
|
|
348
|
+
queryParams.sm = `${queryParams.sm ? queryParams.sm + ',' : ''}${liveIntentSegments}`;
|
|
337
349
|
}
|
|
338
350
|
break;
|
|
339
351
|
case 'parrableId':
|
|
@@ -8,6 +8,7 @@ import { OUTSTREAM } from '../src/video.js';
|
|
|
8
8
|
const BIDDER_CODE = 'operaads';
|
|
9
9
|
|
|
10
10
|
const ENDPOINT = 'https://s.adx.opera.com/ortb/v2/';
|
|
11
|
+
const USER_SYNC_ENDPOINT = 'https://s.adx.opera.com/usersync/page';
|
|
11
12
|
|
|
12
13
|
const OUTSTREAM_RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js';
|
|
13
14
|
|
|
@@ -137,6 +138,25 @@ export const spec = {
|
|
|
137
138
|
* @return {UserSync[]} The user syncs which should be dropped.
|
|
138
139
|
*/
|
|
139
140
|
getUserSyncs: function (syncOptions, serverResponses, gdprConsent, uspConsent) {
|
|
141
|
+
if ('iframeEnabled' in syncOptions && syncOptions.iframeEnabled) {
|
|
142
|
+
return [{
|
|
143
|
+
type: 'iframe',
|
|
144
|
+
url: USER_SYNC_ENDPOINT
|
|
145
|
+
}];
|
|
146
|
+
}
|
|
147
|
+
if ('pixelEnabled' in syncOptions && syncOptions.pixelEnabled) {
|
|
148
|
+
const pixels = deepAccess(serverResponses, '0.body.pixels')
|
|
149
|
+
if (Array.isArray(pixels)) {
|
|
150
|
+
const userSyncPixels = []
|
|
151
|
+
for (const pixel of pixels) {
|
|
152
|
+
userSyncPixels.push({
|
|
153
|
+
type: 'image',
|
|
154
|
+
url: pixel
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
return userSyncPixels;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
140
160
|
return [];
|
|
141
161
|
},
|
|
142
162
|
|
|
@@ -212,7 +232,7 @@ function buildOpenRtbBidRequest(bidRequest, bidderRequest) {
|
|
|
212
232
|
ext: {}
|
|
213
233
|
},
|
|
214
234
|
user: {
|
|
215
|
-
|
|
235
|
+
buyeruid: getUserId(bidRequest)
|
|
216
236
|
}
|
|
217
237
|
}
|
|
218
238
|
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
2
|
+
import {logInfo, logError, getBidIdParameter, _each, getValue, isFn, isPlainObject} from '../src/utils.js';
|
|
3
|
+
import { BANNER } from '../src/mediaTypes.js';
|
|
4
|
+
|
|
5
|
+
const BIDDER_CODE = 'otm';
|
|
6
|
+
const OTM_BID_URL = 'https://ssp.otm-r.com/adjson';
|
|
7
|
+
const DEF_CUR = 'RUB'
|
|
8
|
+
|
|
9
|
+
export const spec = {
|
|
10
|
+
|
|
11
|
+
code: BIDDER_CODE,
|
|
12
|
+
url: OTM_BID_URL,
|
|
13
|
+
supportedMediaTypes: [ BANNER ],
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Determines whether or not the given bid request is valid.
|
|
17
|
+
*
|
|
18
|
+
* @param {object} bid The bid to validate.
|
|
19
|
+
* @return boolean True if this is a valid bid, and false otherwise.
|
|
20
|
+
*/
|
|
21
|
+
isBidRequestValid: function (bid) {
|
|
22
|
+
return !!bid.params.tid;
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Build bidder requests.
|
|
27
|
+
*
|
|
28
|
+
* @param validBidRequests
|
|
29
|
+
* @param bidderRequest
|
|
30
|
+
* @returns {[]}
|
|
31
|
+
*/
|
|
32
|
+
buildRequests: function (validBidRequests, bidderRequest) {
|
|
33
|
+
logInfo('validBidRequests', validBidRequests);
|
|
34
|
+
|
|
35
|
+
const bidRequests = [];
|
|
36
|
+
let tz = new Date().getTimezoneOffset()
|
|
37
|
+
let referrer = '';
|
|
38
|
+
if (bidderRequest && bidderRequest.refererInfo) {
|
|
39
|
+
referrer = bidderRequest.refererInfo.referer;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
_each(validBidRequests, (bid) => {
|
|
43
|
+
let domain = getValue(bid.params, 'domain') || ''
|
|
44
|
+
let tid = getValue(bid.params, 'tid')
|
|
45
|
+
let cur = getValue(bid.params, 'currency') || DEF_CUR
|
|
46
|
+
let bidid = getBidIdParameter('bidId', bid)
|
|
47
|
+
let transactionid = getBidIdParameter('transactionId', bid)
|
|
48
|
+
let auctionid = getBidIdParameter('auctionId', bid)
|
|
49
|
+
let bidfloor = _getBidFloor(bid)
|
|
50
|
+
|
|
51
|
+
_each(bid.sizes, size => {
|
|
52
|
+
let width = 0;
|
|
53
|
+
let height = 0;
|
|
54
|
+
if (size.length && typeof size[0] === 'number' && typeof size[1] === 'number') {
|
|
55
|
+
width = size[0];
|
|
56
|
+
height = size[1];
|
|
57
|
+
}
|
|
58
|
+
bidRequests.push({
|
|
59
|
+
method: 'GET',
|
|
60
|
+
url: OTM_BID_URL,
|
|
61
|
+
data: {
|
|
62
|
+
tz: tz,
|
|
63
|
+
w: width,
|
|
64
|
+
h: height,
|
|
65
|
+
domain: domain,
|
|
66
|
+
l: referrer,
|
|
67
|
+
s: tid,
|
|
68
|
+
cur: cur,
|
|
69
|
+
bidid: bidid,
|
|
70
|
+
transactionid: transactionid,
|
|
71
|
+
auctionid: auctionid,
|
|
72
|
+
bidfloor: bidfloor,
|
|
73
|
+
},
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
return bidRequests;
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Generate response.
|
|
82
|
+
*
|
|
83
|
+
* @param serverResponse
|
|
84
|
+
* @param request
|
|
85
|
+
* @returns {[]|*[]}
|
|
86
|
+
*/
|
|
87
|
+
interpretResponse: function (serverResponse, request) {
|
|
88
|
+
logInfo('serverResponse', serverResponse.body);
|
|
89
|
+
|
|
90
|
+
const responsesBody = serverResponse ? serverResponse.body : {};
|
|
91
|
+
const bidResponses = [];
|
|
92
|
+
try {
|
|
93
|
+
if (responsesBody.length === 0) {
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
_each(responsesBody, (bid) => {
|
|
98
|
+
if (bid.ad) {
|
|
99
|
+
bidResponses.push({
|
|
100
|
+
requestId: bid.bidid,
|
|
101
|
+
cpm: bid.cpm,
|
|
102
|
+
width: bid.w,
|
|
103
|
+
height: bid.h,
|
|
104
|
+
creativeId: bid.creativeid,
|
|
105
|
+
currency: bid.currency || 'RUB',
|
|
106
|
+
netRevenue: true,
|
|
107
|
+
ad: bid.ad,
|
|
108
|
+
ttl: bid.ttl,
|
|
109
|
+
transactionId: bid.transactionid,
|
|
110
|
+
meta: {
|
|
111
|
+
advertiserDomains: bid.adDomain ? [bid.adDomain] : []
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
} catch (error) {
|
|
117
|
+
logError(error);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return bidResponses;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Get floor value
|
|
126
|
+
* @param bid
|
|
127
|
+
* @returns {null|*}
|
|
128
|
+
* @private
|
|
129
|
+
*/
|
|
130
|
+
function _getBidFloor(bid) {
|
|
131
|
+
if (!isFn(bid.getFloor)) {
|
|
132
|
+
return bid.params.bidfloor ? bid.params.bidfloor : 0;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
let floor = bid.getFloor({
|
|
136
|
+
currency: DEF_CUR,
|
|
137
|
+
mediaType: '*',
|
|
138
|
+
size: '*'
|
|
139
|
+
});
|
|
140
|
+
if (isPlainObject(floor) && !isNaN(floor.floor) && floor.currency === DEF_CUR) {
|
|
141
|
+
return floor.floor;
|
|
142
|
+
}
|
|
143
|
+
return 0;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
registerBidder(spec);
|
package/modules/otmBidAdapter.md
CHANGED
|
@@ -1,36 +1,37 @@
|
|
|
1
1
|
# Overview
|
|
2
2
|
|
|
3
|
-
Module Name
|
|
4
|
-
Module Type
|
|
5
|
-
Maintainer
|
|
3
|
+
**Module Name**: OTM Bidder Adapter
|
|
4
|
+
**Module Type**: Bidder Adapter
|
|
5
|
+
**Maintainer**: e.kretsu@otm-r.com
|
|
6
6
|
|
|
7
7
|
# Description
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
OTM Bidder Adapter for Prebid.js. About: https://otm-r.com
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Use `otm` as bidder:
|
|
12
12
|
|
|
13
|
+
# Params
|
|
14
|
+
- `tid` required, specific id AdUnit slot.
|
|
15
|
+
- `domain` optional, specific custom domain.
|
|
16
|
+
- `bidfloor` optional.
|
|
13
17
|
|
|
14
|
-
|
|
15
|
-
```javascript
|
|
16
|
-
var adUnits = [
|
|
17
|
-
{
|
|
18
|
-
code: 'div-otm-example',
|
|
19
|
-
sizes: [[320, 480]],
|
|
20
|
-
bids: [
|
|
21
|
-
{
|
|
22
|
-
bidder: "otm",
|
|
23
|
-
params: {
|
|
24
|
-
tid: "99",
|
|
25
|
-
bidfloor: 20
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
]
|
|
29
|
-
}
|
|
30
|
-
];
|
|
18
|
+
## AdUnits configuration example
|
|
31
19
|
```
|
|
20
|
+
var adUnits = [{
|
|
21
|
+
code: 'your-slot', //use exactly the same code as your slot div id.
|
|
22
|
+
mediaTypes: {
|
|
23
|
+
banner: {
|
|
24
|
+
sizes: [[320, 480]]
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
bids: [{
|
|
28
|
+
bidder: 'otm',
|
|
29
|
+
params: {
|
|
30
|
+
tid: 'XXXXX',
|
|
31
|
+
domain: 'specific custom domain, if needed',
|
|
32
|
+
bidfloor: 20
|
|
33
|
+
}
|
|
34
|
+
}]
|
|
35
|
+
}];
|
|
32
36
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
* tid - A tag id (should have low cardinality)
|
|
36
|
-
* bidfloor - Floor price
|
|
37
|
+
```
|
|
@@ -40,6 +40,7 @@ export const spec = {
|
|
|
40
40
|
const publisher = setOnAny(validBidRequests, 'params.publisher');
|
|
41
41
|
const bcat = setOnAny(validBidRequests, 'params.bcat');
|
|
42
42
|
const badv = setOnAny(validBidRequests, 'params.badv');
|
|
43
|
+
const eids = setOnAny(validBidRequests, 'userIdAsEids')
|
|
43
44
|
const cur = CURRENCY;
|
|
44
45
|
const endpointUrl = config.getConfig('outbrain.bidderUrl');
|
|
45
46
|
const timeout = bidderRequest.timeout;
|
|
@@ -105,6 +106,10 @@ export const spec = {
|
|
|
105
106
|
deepSetValue(request, 'regs.coppa', config.getConfig('coppa') & 1)
|
|
106
107
|
}
|
|
107
108
|
|
|
109
|
+
if (eids) {
|
|
110
|
+
deepSetValue(request, 'user.ext.eids', eids);
|
|
111
|
+
}
|
|
112
|
+
|
|
108
113
|
return {
|
|
109
114
|
method: 'POST',
|
|
110
115
|
url: endpointUrl,
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
Module Name: Playwire Bidder Adapter
|
|
4
|
+
Module Type: Bidder Adapter
|
|
5
|
+
Maintainer: grid-tech@themediagrid.com
|
|
6
|
+
|
|
7
|
+
# Description
|
|
8
|
+
|
|
9
|
+
Module that connects to Grid demand source to fetch bids.
|
|
10
|
+
The adapter is GDPR compliant and supports banner and video (instream and outstream).
|
|
11
|
+
|
|
12
|
+
# Test Parameters
|
|
13
|
+
```
|
|
14
|
+
var adUnits = [
|
|
15
|
+
{
|
|
16
|
+
code: 'test-div',
|
|
17
|
+
sizes: [[300, 250]],
|
|
18
|
+
bids: [
|
|
19
|
+
{
|
|
20
|
+
bidder: "playwire",
|
|
21
|
+
params: {
|
|
22
|
+
uid: '1',
|
|
23
|
+
bidFloor: 0.5
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
},{
|
|
28
|
+
code: 'test-div',
|
|
29
|
+
sizes: [[728, 90]],
|
|
30
|
+
bids: [
|
|
31
|
+
{
|
|
32
|
+
bidder: "playwire",
|
|
33
|
+
params: {
|
|
34
|
+
uid: 2,
|
|
35
|
+
keywords: {
|
|
36
|
+
brandsafety: ['disaster'],
|
|
37
|
+
topic: ['stress', 'fear']
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
code: 'test-div',
|
|
45
|
+
sizes: [[728, 90]],
|
|
46
|
+
mediaTypes: { video: {
|
|
47
|
+
context: 'instream',
|
|
48
|
+
playerSize: [728, 90],
|
|
49
|
+
mimes: ['video/mp4']
|
|
50
|
+
},
|
|
51
|
+
bids: [
|
|
52
|
+
{
|
|
53
|
+
bidder: "playwire",
|
|
54
|
+
params: {
|
|
55
|
+
uid: 11
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
];
|
|
61
|
+
```
|