prebid.js 5.17.0 → 6.0.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/.babelrc.js +3 -6
- package/README.md +3 -1
- package/browsers.json +1 -8
- package/integrationExamples/gpt/akamaidap_segments_example.html +132 -0
- package/modules/.submodules.json +1 -0
- package/modules/adfBidAdapter.js +21 -16
- package/modules/adgenerationBidAdapter.js +28 -4
- package/modules/adkernelBidAdapter.js +2 -1
- package/modules/admixerBidAdapter.js +11 -0
- package/modules/adtelligentBidAdapter.js +2 -1
- package/modules/airgridRtdProvider.js +1 -1
- package/modules/akamaiDapRtdProvider.js +474 -0
- package/modules/akamaiDapRtdProvider.md +47 -0
- package/modules/aolBidAdapter.js +2 -1
- package/modules/appnexusBidAdapter.js +5 -3
- package/modules/atsAnalyticsAdapter.js +67 -46
- package/modules/atsAnalyticsAdapter.md +1 -0
- package/modules/betweenBidAdapter.js +20 -3
- package/modules/bliinkBidAdapter.js +58 -32
- package/modules/bliinkBidAdapter.md +29 -6
- 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/cwireBidAdapter.js +272 -0
- package/modules/cwireBidAdapter.md +43 -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/dgkeywordRtdProvider.js +0 -1
- 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/ixBidAdapter.js +8 -1
- package/modules/jixieBidAdapter.js +8 -2
- package/modules/justpremiumBidAdapter.js +6 -1
- package/modules/limelightDigitalBidAdapter.js +22 -2
- package/modules/livewrappedAnalyticsAdapter.js +53 -3
- package/modules/mediakeysBidAdapter.js +2 -1
- package/modules/multibid/index.js +3 -3
- package/modules/nativoBidAdapter.js +6 -2
- package/modules/nextMillenniumBidAdapter.js +12 -3
- package/modules/oguryBidAdapter.js +36 -7
- 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/pixfutureBidAdapter.js +24 -4
- package/modules/pixfutureBidAdapter.md +127 -0
- package/modules/playwireBidAdapter.md +61 -0
- package/modules/prebidServerBidAdapter/index.js +1 -1
- package/modules/proxistoreBidAdapter.js +4 -6
- package/modules/publinkIdSystem.js +11 -6
- package/modules/pubmaticBidAdapter.js +9 -0
- package/modules/pubmaticBidAdapter.md +1 -1
- package/modules/rtdModule/index.js +2 -2
- package/modules/sonobiBidAdapter.js +7 -0
- package/modules/sortableBidAdapter.js +1 -0
- package/modules/talkadsBidAdapter.js +129 -0
- package/modules/talkadsBidAdapter.md +60 -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/unicornBidAdapter.js +3 -3
- 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/visxBidAdapter.js +15 -22
- package/modules/yahoosspBidAdapter.js +637 -0
- package/modules/yahoosspBidAdapter.md +795 -0
- package/modules/yieldlabBidAdapter.js +48 -3
- package/modules/yieldlabBidAdapter.md +16 -1
- 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/adgenerationBidAdapter_spec.js +121 -50
- package/test/spec/modules/adtelligentBidAdapter_spec.js +1 -0
- package/test/spec/modules/akamaiDapRtdProvider_spec.js +246 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +2 -1
- package/test/spec/modules/atsAnalyticsAdapter_spec.js +42 -9
- package/test/spec/modules/betweenBidAdapter_spec.js +41 -0
- package/test/spec/modules/bliinkBidAdapter_spec.js +87 -36
- 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/cwireBidAdapter_spec.js +246 -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/gumgumBidAdapter_spec.js +5 -1
- 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 +67 -12
- 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 +125 -37
- 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/pubmaticBidAdapter_spec.js +39 -1
- package/test/spec/modules/sonobiBidAdapter_spec.js +34 -1
- package/test/spec/modules/sortableBidAdapter_spec.js +11 -0
- package/test/spec/modules/talkadsBidAdapter_spec.js +231 -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/unicornBidAdapter_spec.js +4 -4
- package/test/spec/modules/ventesBidAdapter_spec.js +845 -0
- package/test/spec/modules/videobyteBidAdapter_spec.js +2 -2
- package/test/spec/modules/visxBidAdapter_spec.js +48 -4
- package/test/spec/modules/yahoosspBidAdapter_spec.js +1332 -0
- package/test/spec/modules/yieldlabBidAdapter_spec.js +65 -1
- package/test/spec/modules/yieldmoSyntheticInventoryModule_spec.js +89 -0
- package/test/spec/unit/core/adapterManager_spec.js +32 -0
- 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
- package/wdio.conf.js +1 -1
- package/modules/turktelekomBidAdapter.md +0 -49
- package/yarn.lock +0 -13122
|
@@ -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,9 +81,11 @@ 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);
|
|
88
|
+
bidResponse.floorData = args.floorData;
|
|
84
89
|
if (!bidResponse.ttr) {
|
|
85
90
|
bidResponse.ttr = time - bidResponse.start;
|
|
86
91
|
}
|
|
@@ -108,10 +113,21 @@ let livewrappedAnalyticsAdapter = Object.assign(adapter({EMPTYURL, ANALYTICSTYPE
|
|
|
108
113
|
logInfo('LIVEWRAPPED_BID_WON:', args);
|
|
109
114
|
let wonBid = cache.auctions[args.auctionId].bids[args.requestId];
|
|
110
115
|
wonBid.won = true;
|
|
116
|
+
wonBid.floorData = args.floorData;
|
|
111
117
|
if (wonBid.sendStatus != 0) {
|
|
112
118
|
livewrappedAnalyticsAdapter.sendEvents();
|
|
113
119
|
}
|
|
114
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;
|
|
115
131
|
case CONSTANTS.EVENTS.BID_TIMEOUT:
|
|
116
132
|
logInfo('LIVEWRAPPED_BID_TIMEOUT:', args);
|
|
117
133
|
args.forEach(timeout => {
|
|
@@ -149,13 +165,15 @@ livewrappedAnalyticsAdapter.sendEvents = function() {
|
|
|
149
165
|
wins: getWins(sentRequests.gdpr, sentRequests.auctionIds),
|
|
150
166
|
timeouts: getTimeouts(sentRequests.auctionIds),
|
|
151
167
|
bidAdUnits: getbidAdUnits(),
|
|
168
|
+
rf: getAdRenderFailed(sentRequests.auctionIds),
|
|
152
169
|
rcv: getAdblockerRecovered()
|
|
153
170
|
};
|
|
154
171
|
|
|
155
172
|
if (events.requests.length == 0 &&
|
|
156
173
|
events.responses.length == 0 &&
|
|
157
174
|
events.wins.length == 0 &&
|
|
158
|
-
events.timeouts.length == 0
|
|
175
|
+
events.timeouts.length == 0 &&
|
|
176
|
+
events.rf.length == 0) {
|
|
159
177
|
return;
|
|
160
178
|
}
|
|
161
179
|
|
|
@@ -222,11 +240,12 @@ function getResponses(gdpr, auctionIds) {
|
|
|
222
240
|
width: bid.width,
|
|
223
241
|
height: bid.height,
|
|
224
242
|
cpm: bid.cpm,
|
|
243
|
+
orgCpm: bid.originalCpm,
|
|
225
244
|
ttr: bid.ttr,
|
|
226
245
|
IsBid: bid.isBid,
|
|
227
246
|
mediaType: bid.mediaType,
|
|
228
247
|
gdpr: gdprPos,
|
|
229
|
-
floor: bid.floorData ? bid.floorData.floorValue :
|
|
248
|
+
floor: bid.lwFloor ? bid.lwFloor : (bid.floorData ? bid.floorData.floorValue : undefined),
|
|
230
249
|
floorCur: bid.floorData ? bid.floorData.floorCurrency : undefined,
|
|
231
250
|
auctionId: auctionIdPos,
|
|
232
251
|
auc: bid.auc,
|
|
@@ -261,9 +280,10 @@ function getWins(gdpr, auctionIds) {
|
|
|
261
280
|
width: bid.width,
|
|
262
281
|
height: bid.height,
|
|
263
282
|
cpm: bid.cpm,
|
|
283
|
+
orgCpm: bid.originalCpm,
|
|
264
284
|
mediaType: bid.mediaType,
|
|
265
285
|
gdpr: gdprPos,
|
|
266
|
-
floor: bid.floorData ? bid.floorData.floorValue :
|
|
286
|
+
floor: bid.lwFloor ? bid.lwFloor : (bid.floorData ? bid.floorData.floorValue : undefined),
|
|
267
287
|
floorCur: bid.floorData ? bid.floorData.floorCurrency : undefined,
|
|
268
288
|
auctionId: auctionIdPos,
|
|
269
289
|
auc: bid.auc,
|
|
@@ -336,6 +356,36 @@ function getTimeouts(auctionIds) {
|
|
|
336
356
|
return timeouts;
|
|
337
357
|
}
|
|
338
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
|
+
|
|
339
389
|
function getbidAdUnits() {
|
|
340
390
|
var bidAdUnits = [];
|
|
341
391
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import find from 'core-js-pure/features/array/find.js';
|
|
2
|
+
import arrayFrom from 'core-js-pure/features/array/from';
|
|
2
3
|
import { getWindowTop, isFn, logWarn, getDNT, deepAccess, isArray, inIframe, mergeDeep, isStr, isEmpty, deepSetValue, deepClone, parseUrl, cleanObj, logError, triggerPixel, isInteger, isNumber } from '../src/utils.js';
|
|
3
4
|
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
4
5
|
import { config } from '../src/config.js';
|
|
@@ -54,7 +55,7 @@ const ORTB_VIDEO_PARAMS = {
|
|
|
54
55
|
skipmin: value => isInteger(value),
|
|
55
56
|
skipafter: value => isInteger(value),
|
|
56
57
|
sequence: value => isInteger(value),
|
|
57
|
-
battr: value => Array.isArray(value) && value.every(v =>
|
|
58
|
+
battr: value => Array.isArray(value) && value.every(v => arrayFrom({length: 17}, (_, i) => i + 1).indexOf(v) !== -1),
|
|
58
59
|
maxextended: value => isInteger(value),
|
|
59
60
|
minbitrate: value => isInteger(value),
|
|
60
61
|
maxbitrate: value => isInteger(value),
|
|
@@ -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);
|
|
@@ -71,7 +71,7 @@ export const spec = {
|
|
|
71
71
|
// Track if we've already requested for this ad unit code
|
|
72
72
|
adUnitsRequested[adUnit.adUnitCode] =
|
|
73
73
|
adUnitsRequested[adUnit.adUnitCode] !== undefined
|
|
74
|
-
? adUnitsRequested[adUnit.adUnitCode]
|
|
74
|
+
? adUnitsRequested[adUnit.adUnitCode] + 1
|
|
75
75
|
: 0
|
|
76
76
|
return {
|
|
77
77
|
adUnitCode: adUnit.adUnitCode,
|
|
@@ -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,13 +1,14 @@
|
|
|
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
|
|
|
8
8
|
const BIDDER_CODE = 'ogury';
|
|
9
9
|
const DEFAULT_TIMEOUT = 1000;
|
|
10
10
|
const BID_HOST = 'https://mweb-hb.presage.io/api/header-bidding-request';
|
|
11
|
+
const TIMEOUT_MONITORING_HOST = 'https://ms-ads-monitoring-events.presage.io';
|
|
11
12
|
const MS_COOKIE_SYNC_DOMAIN = 'https://ms-cookie-sync.presage.io';
|
|
12
13
|
|
|
13
14
|
function isBidRequestValid(bid) {
|
|
@@ -23,10 +24,16 @@ function isBidRequestValid(bid) {
|
|
|
23
24
|
function getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent) {
|
|
24
25
|
if (!syncOptions.pixelEnabled) return [];
|
|
25
26
|
|
|
26
|
-
return [
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
return [
|
|
28
|
+
{
|
|
29
|
+
type: 'image',
|
|
30
|
+
url: `${MS_COOKIE_SYNC_DOMAIN}/v1/init-sync/bid-switch?iab_string=${(gdprConsent && gdprConsent.consentString) || ''}&source=prebid`
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
type: 'image',
|
|
34
|
+
url: `${MS_COOKIE_SYNC_DOMAIN}/ttd/init-sync?iab_string=${(gdprConsent && gdprConsent.consentString) || ''}&source=prebid`
|
|
35
|
+
}
|
|
36
|
+
]
|
|
30
37
|
}
|
|
31
38
|
|
|
32
39
|
function buildRequests(validBidRequests, bidderRequest) {
|
|
@@ -40,7 +47,8 @@ function buildRequests(validBidRequests, bidderRequest) {
|
|
|
40
47
|
},
|
|
41
48
|
},
|
|
42
49
|
site: {
|
|
43
|
-
domain: location.hostname
|
|
50
|
+
domain: location.hostname,
|
|
51
|
+
page: location.href
|
|
44
52
|
},
|
|
45
53
|
user: {
|
|
46
54
|
ext: {
|
|
@@ -137,10 +145,29 @@ function getFloor(bid) {
|
|
|
137
145
|
return floorResult.currency === 'USD' ? floorResult.floor : 0;
|
|
138
146
|
}
|
|
139
147
|
|
|
148
|
+
function getWindowContext() {
|
|
149
|
+
try {
|
|
150
|
+
return getWindowTop()
|
|
151
|
+
} catch (e) {
|
|
152
|
+
return getWindowSelf()
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
140
156
|
function onBidWon(bid) {
|
|
157
|
+
const w = getWindowContext()
|
|
158
|
+
w.OG_PREBID_BID_OBJECT = {
|
|
159
|
+
...(bid && { ...bid }),
|
|
160
|
+
}
|
|
141
161
|
if (bid && bid.hasOwnProperty('nurl') && bid.nurl.length > 0) ajax(bid['nurl'], null);
|
|
142
162
|
}
|
|
143
163
|
|
|
164
|
+
function onTimeout(timeoutData) {
|
|
165
|
+
ajax(`${TIMEOUT_MONITORING_HOST}/bid_timeout`, null, JSON.stringify(timeoutData[0]), {
|
|
166
|
+
method: 'POST',
|
|
167
|
+
contentType: 'application/json'
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
144
171
|
export const spec = {
|
|
145
172
|
code: BIDDER_CODE,
|
|
146
173
|
supportedMediaTypes: [BANNER],
|
|
@@ -149,7 +176,9 @@ export const spec = {
|
|
|
149
176
|
buildRequests,
|
|
150
177
|
interpretResponse,
|
|
151
178
|
getFloor,
|
|
152
|
-
onBidWon
|
|
179
|
+
onBidWon,
|
|
180
|
+
getWindowContext,
|
|
181
|
+
onTimeout
|
|
153
182
|
}
|
|
154
183
|
|
|
155
184
|
registerBidder(spec);
|
|
@@ -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,
|