prebid.js 7.34.0 → 7.35.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/.devcontainer/devcontainer.json +2 -1
- package/.github/workflows/issue_tracker.yml +1 -1
- 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/adrelevantisBidAdapter.js +1 -1
- package/dist/adtrgtmeBidAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/adyoulikeBidAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/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/consentManagement.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/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/glimpseBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gridNMBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/hadronIdSystem.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/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/kueezRtbBidAdapter.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/nexx360BidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +127 -137
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/permutiveRtdProvider.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +1 -1
- package/dist/priceFloors.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pulsepointBidAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseBidAdapter.js +1 -1
- package/dist/rubiconAnalyticsAdapter.js +1 -1
- package/dist/rubiconBidAdapter.js +1 -1
- package/dist/seedingAllianceBidAdapter.js +1 -1
- package/dist/seedtagBidAdapter.js +1 -1
- package/dist/sharethroughAnalyticsAdapter.js +1 -1
- package/dist/sharethroughBidAdapter.js +1 -1
- package/dist/shinezBidAdapter.js +1 -1
- package/dist/smaatoBidAdapter.js +1 -1
- package/dist/smartadserverBidAdapter.js +1 -1
- package/dist/smartxBidAdapter.js +1 -1
- package/dist/smartytechBidAdapter.js +1 -1
- package/dist/smilewantedBidAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnAnalyticsAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/synacormediaBidAdapter.js +1 -1
- package/dist/taboolaBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/trionBidAdapter.js +1 -1
- package/dist/tripleliftBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.js +1 -1
- package/dist/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/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/dist/zeta_global_sspBidAdapter.js +1 -1
- package/dist/zeusPrimeRtdProvider.js +4 -14
- package/integrationExamples/gpt/hello_world.html +0 -0
- package/modules/adyoulikeBidAdapter.js +2 -0
- package/modules/consentManagement.js +33 -5
- package/modules/cwireBidAdapter.js +169 -242
- package/modules/cwireBidAdapter.md +15 -14
- package/modules/hadronIdSystem.js +37 -32
- package/modules/nexx360BidAdapter.js +1 -2
- package/modules/onetagBidAdapter.js +12 -1
- package/modules/outbrainBidAdapter.js +103 -6
- package/modules/permutiveRtdProvider.js +17 -12
- package/modules/priceFloors.js +7 -8
- package/modules/pulsepointBidAdapter.js +2 -0
- package/modules/smartadserverBidAdapter.js +39 -28
- package/modules/smartyadsBidAdapter.md +9 -0
- package/modules/smartytechBidAdapter.js +67 -10
- package/modules/smartytechBidAdapter.md +44 -33
- package/modules/sonobiBidAdapter.js +17 -10
- package/modules/taboolaBidAdapter.js +2 -1
- package/modules/vidazooBidAdapter.js +56 -22
- package/modules/zeta_global_sspBidAdapter.js +15 -0
- package/modules/zeusPrimeRtdProvider.js +3 -323
- package/modules/zeusPrimeRtdProvider.md +3 -0
- package/package.json +1 -1
- package/src/auction.js +2 -11
- package/src/prebid.js +8 -0
- package/src/utils/cpm.js +17 -0
- package/test/spec/modules/adyoulikeBidAdapter_spec.js +3 -0
- package/test/spec/modules/consentManagement_spec.js +49 -1
- package/test/spec/modules/cwireBidAdapter_spec.js +249 -335
- package/test/spec/modules/hadronIdSystem_spec.js +4 -6
- package/test/spec/modules/nexx360BidAdapter_spec.js +0 -4
- package/test/spec/modules/onetagBidAdapter_spec.js +43 -0
- package/test/spec/modules/outbrainBidAdapter_spec.js +182 -18
- package/test/spec/modules/pulsepointBidAdapter_spec.js +11 -1
- package/test/spec/modules/smartadserverBidAdapter_spec.js +116 -5
- package/test/spec/modules/smartytechBidAdapter_spec.js +172 -14
- package/test/spec/modules/sonobiBidAdapter_spec.js +2 -1
- package/test/spec/modules/taboolaBidAdapter_spec.js +12 -3
- package/test/spec/modules/userId_spec.js +19 -14
- package/test/spec/modules/vidazooBidAdapter_spec.js +61 -22
- package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +8 -0
- package/test/spec/unit/pbjs_api_spec.js +14 -0
- package/test/spec/unit/utils/cpm_spec.js +64 -0
- package/test/spec/modules/zeusPrimeRtdProvider_spec.js +0 -410
|
@@ -61,6 +61,12 @@ function buildRequests(validBidRequests, bidderRequest) {
|
|
|
61
61
|
consentRequired: bidderRequest.gdprConsent.gdprApplies
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
|
+
if (bidderRequest && bidderRequest.gppConsent) {
|
|
65
|
+
payload.gppConsent = {
|
|
66
|
+
consentString: bidderRequest.gppConsent.gppString,
|
|
67
|
+
applicableSections: bidderRequest.gppConsent.applicableSections
|
|
68
|
+
}
|
|
69
|
+
}
|
|
64
70
|
if (bidderRequest && bidderRequest.uspConsent) {
|
|
65
71
|
payload.usPrivacy = bidderRequest.uspConsent;
|
|
66
72
|
}
|
|
@@ -340,7 +346,7 @@ function getSizes(sizes) {
|
|
|
340
346
|
return ret;
|
|
341
347
|
}
|
|
342
348
|
|
|
343
|
-
function getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent) {
|
|
349
|
+
function getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent) {
|
|
344
350
|
let syncs = [];
|
|
345
351
|
let params = '';
|
|
346
352
|
if (gdprConsent) {
|
|
@@ -351,6 +357,11 @@ function getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent) {
|
|
|
351
357
|
params += '&gdpr_consent=' + gdprConsent.consentString;
|
|
352
358
|
}
|
|
353
359
|
}
|
|
360
|
+
if (gppConsent) {
|
|
361
|
+
if (typeof gppConsent.gppString === 'string') {
|
|
362
|
+
params += '&gpp_consent=' + gppConsent.gppString;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
354
365
|
if (uspConsent && typeof uspConsent === 'string') {
|
|
355
366
|
params += '&us_privacy=' + uspConsent;
|
|
356
367
|
}
|
|
@@ -4,11 +4,13 @@
|
|
|
4
4
|
import {
|
|
5
5
|
registerBidder
|
|
6
6
|
} from '../src/adapters/bidderFactory.js';
|
|
7
|
-
import { NATIVE, BANNER } from '../src/mediaTypes.js';
|
|
8
|
-
import {
|
|
7
|
+
import { NATIVE, BANNER, VIDEO } from '../src/mediaTypes.js';
|
|
8
|
+
import { OUTSTREAM } from '../src/video.js';
|
|
9
|
+
import { deepAccess, deepSetValue, replaceAuctionPrice, _map, isArray, logWarn } from '../src/utils.js';
|
|
9
10
|
import { ajax } from '../src/ajax.js';
|
|
10
11
|
import { config } from '../src/config.js';
|
|
11
12
|
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
|
|
13
|
+
import { Renderer } from '../src/Renderer.js';
|
|
12
14
|
|
|
13
15
|
const BIDDER_CODE = 'outbrain';
|
|
14
16
|
const GVLID = 164;
|
|
@@ -22,11 +24,12 @@ const NATIVE_PARAMS = {
|
|
|
22
24
|
body: { id: 4, name: 'data', type: 2 },
|
|
23
25
|
cta: { id: 1, type: 12, name: 'data' }
|
|
24
26
|
};
|
|
27
|
+
const OUTSTREAM_RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js';
|
|
25
28
|
|
|
26
29
|
export const spec = {
|
|
27
30
|
code: BIDDER_CODE,
|
|
28
31
|
gvlid: GVLID,
|
|
29
|
-
supportedMediaTypes: [ NATIVE, BANNER ],
|
|
32
|
+
supportedMediaTypes: [ NATIVE, BANNER, VIDEO ],
|
|
30
33
|
isBidRequestValid: (bid) => {
|
|
31
34
|
if (typeof bid.params !== 'object') {
|
|
32
35
|
return false;
|
|
@@ -50,7 +53,7 @@ export const spec = {
|
|
|
50
53
|
|
|
51
54
|
return (
|
|
52
55
|
!!config.getConfig('outbrain.bidderUrl') &&
|
|
53
|
-
!!(bid.nativeParams || bid.sizes)
|
|
56
|
+
(!!(bid.nativeParams || bid.sizes) || isValidVideoRequest(bid))
|
|
54
57
|
);
|
|
55
58
|
},
|
|
56
59
|
buildRequests: (validBidRequests, bidderRequest) => {
|
|
@@ -85,6 +88,8 @@ export const spec = {
|
|
|
85
88
|
assets: getNativeAssets(bid)
|
|
86
89
|
})
|
|
87
90
|
}
|
|
91
|
+
} else if (isVideoRequest(bid)) {
|
|
92
|
+
imp.video = getVideoAsset(bid);
|
|
88
93
|
} else {
|
|
89
94
|
imp.banner = {
|
|
90
95
|
format: transformSizes(bid.sizes)
|
|
@@ -163,7 +168,12 @@ export const spec = {
|
|
|
163
168
|
return bids.map((bid, id) => {
|
|
164
169
|
const bidResponse = bidResponses[id];
|
|
165
170
|
if (bidResponse) {
|
|
166
|
-
|
|
171
|
+
let type = BANNER;
|
|
172
|
+
if (bid.nativeParams) {
|
|
173
|
+
type = NATIVE;
|
|
174
|
+
} else if (isVideoRequest(bid)) {
|
|
175
|
+
type = VIDEO;
|
|
176
|
+
}
|
|
167
177
|
const bidObject = {
|
|
168
178
|
requestId: bid.bidId,
|
|
169
179
|
cpm: bidResponse.price,
|
|
@@ -176,10 +186,16 @@ export const spec = {
|
|
|
176
186
|
};
|
|
177
187
|
if (type === NATIVE) {
|
|
178
188
|
bidObject.native = parseNative(bidResponse);
|
|
179
|
-
} else {
|
|
189
|
+
} else if (type === BANNER) {
|
|
180
190
|
bidObject.ad = bidResponse.adm;
|
|
181
191
|
bidObject.width = bidResponse.w;
|
|
182
192
|
bidObject.height = bidResponse.h;
|
|
193
|
+
} else if (type === VIDEO) {
|
|
194
|
+
bidObject.vastXml = bidResponse.adm;
|
|
195
|
+
const videoContext = deepAccess(bid, 'mediaTypes.video.context');
|
|
196
|
+
if (videoContext === OUTSTREAM) {
|
|
197
|
+
bidObject.renderer = createRenderer(bid);
|
|
198
|
+
}
|
|
183
199
|
}
|
|
184
200
|
bidObject.meta = {};
|
|
185
201
|
if (bidResponse.adomain && bidResponse.adomain.length > 0) {
|
|
@@ -304,6 +320,27 @@ function getNativeAssets(bid) {
|
|
|
304
320
|
}).filter(Boolean);
|
|
305
321
|
}
|
|
306
322
|
|
|
323
|
+
function getVideoAsset(bid) {
|
|
324
|
+
const sizes = flatten(bid.mediaTypes.video.playerSize);
|
|
325
|
+
return {
|
|
326
|
+
w: parseInt(sizes[0], 10),
|
|
327
|
+
h: parseInt(sizes[1], 10),
|
|
328
|
+
protocols: bid.mediaTypes.video.protocols,
|
|
329
|
+
playbackmethod: bid.mediaTypes.video.playbackmethod,
|
|
330
|
+
mimes: bid.mediaTypes.video.mimes,
|
|
331
|
+
skip: bid.mediaTypes.video.skip,
|
|
332
|
+
delivery: bid.mediaTypes.video.delivery,
|
|
333
|
+
api: bid.mediaTypes.video.api,
|
|
334
|
+
minbitrate: bid.mediaTypes.video.minbitrate,
|
|
335
|
+
maxbitrate: bid.mediaTypes.video.maxbitrate,
|
|
336
|
+
minduration: bid.mediaTypes.video.minduration,
|
|
337
|
+
maxduration: bid.mediaTypes.video.maxduration,
|
|
338
|
+
startdelay: bid.mediaTypes.video.startdelay,
|
|
339
|
+
placement: bid.mediaTypes.video.placement,
|
|
340
|
+
linearity: bid.mediaTypes.video.linearity
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
|
|
307
344
|
/* Turn bid request sizes into ut-compatible format */
|
|
308
345
|
function transformSizes(requestSizes) {
|
|
309
346
|
if (!isArray(requestSizes)) {
|
|
@@ -338,3 +375,63 @@ function _getFloor(bid, type) {
|
|
|
338
375
|
}
|
|
339
376
|
return null;
|
|
340
377
|
}
|
|
378
|
+
|
|
379
|
+
function isVideoRequest(bid) {
|
|
380
|
+
return bid.mediaType === 'video' || !!deepAccess(bid, 'mediaTypes.video');
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
function createRenderer(bid) {
|
|
384
|
+
let config = {};
|
|
385
|
+
let playerUrl = OUTSTREAM_RENDERER_URL;
|
|
386
|
+
let render = function (bid) {
|
|
387
|
+
bid.renderer.push(() => {
|
|
388
|
+
window.ANOutstreamVideo.renderAd({
|
|
389
|
+
sizes: bid.sizes,
|
|
390
|
+
targetId: bid.adUnitCode,
|
|
391
|
+
adResponse: { content: bid.vastXml }
|
|
392
|
+
});
|
|
393
|
+
});
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
let externalRenderer = deepAccess(bid, 'mediaTypes.video.renderer');
|
|
397
|
+
if (!externalRenderer) {
|
|
398
|
+
externalRenderer = deepAccess(bid, 'renderer');
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
if (externalRenderer) {
|
|
402
|
+
config = externalRenderer.options;
|
|
403
|
+
playerUrl = externalRenderer.url;
|
|
404
|
+
render = externalRenderer.render;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
const renderer = Renderer.install({
|
|
408
|
+
id: bid.adUnitCode,
|
|
409
|
+
url: playerUrl,
|
|
410
|
+
config: config,
|
|
411
|
+
adUnitCode: bid.adUnitCode,
|
|
412
|
+
loaded: false
|
|
413
|
+
});
|
|
414
|
+
try {
|
|
415
|
+
renderer.setRender(render);
|
|
416
|
+
} catch (err) {
|
|
417
|
+
logWarn('Prebid Error calling setRender on renderer', err);
|
|
418
|
+
}
|
|
419
|
+
return renderer;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
function isValidVideoRequest(bid) {
|
|
423
|
+
const videoAdUnit = deepAccess(bid, 'mediaTypes.video')
|
|
424
|
+
if (!videoAdUnit) {
|
|
425
|
+
return false;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if (!Array.isArray(videoAdUnit.playerSize)) {
|
|
429
|
+
return false;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
if (videoAdUnit.context == '') {
|
|
433
|
+
return false;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
return true;
|
|
437
|
+
}
|
|
@@ -311,16 +311,19 @@ export function isPermutiveOnPage () {
|
|
|
311
311
|
* @return {Object}
|
|
312
312
|
*/
|
|
313
313
|
export function getSegments (maxSegs) {
|
|
314
|
-
const legacySegs = readSegments('_psegs').map(Number).filter(seg => seg >= 1000000).map(String)
|
|
315
|
-
const _ppam = readSegments('_ppam')
|
|
316
|
-
const _pcrprs = readSegments('_pcrprs')
|
|
314
|
+
const legacySegs = readSegments('_psegs', []).map(Number).filter(seg => seg >= 1000000).map(String)
|
|
315
|
+
const _ppam = readSegments('_ppam', [])
|
|
316
|
+
const _pcrprs = readSegments('_pcrprs', [])
|
|
317
317
|
|
|
318
318
|
const segments = {
|
|
319
319
|
ac: [..._pcrprs, ..._ppam, ...legacySegs],
|
|
320
|
-
rubicon: readSegments('_prubicons'),
|
|
321
|
-
appnexus: readSegments('_papns'),
|
|
322
|
-
gam: readSegments('_pdfps'),
|
|
323
|
-
ssp: readSegments('_pssps'
|
|
320
|
+
rubicon: readSegments('_prubicons', []),
|
|
321
|
+
appnexus: readSegments('_papns', []),
|
|
322
|
+
gam: readSegments('_pdfps', []),
|
|
323
|
+
ssp: readSegments('_pssps', {
|
|
324
|
+
cohorts: [],
|
|
325
|
+
ssps: []
|
|
326
|
+
}),
|
|
324
327
|
}
|
|
325
328
|
|
|
326
329
|
for (const bidder in segments) {
|
|
@@ -338,15 +341,17 @@ export function getSegments (maxSegs) {
|
|
|
338
341
|
|
|
339
342
|
/**
|
|
340
343
|
* Gets an array of segment IDs from LocalStorage
|
|
341
|
-
* or
|
|
344
|
+
* or return the default value provided.
|
|
345
|
+
* @template A
|
|
342
346
|
* @param {string} key
|
|
343
|
-
* @
|
|
347
|
+
* @param {A} defaultValue
|
|
348
|
+
* @return {A}
|
|
344
349
|
*/
|
|
345
|
-
function readSegments (key) {
|
|
350
|
+
function readSegments (key, defaultValue) {
|
|
346
351
|
try {
|
|
347
|
-
return JSON.parse(storage.getDataFromLocalStorage(key) ||
|
|
352
|
+
return JSON.parse(storage.getDataFromLocalStorage(key)) || defaultValue
|
|
348
353
|
} catch (e) {
|
|
349
|
-
return
|
|
354
|
+
return defaultValue
|
|
350
355
|
}
|
|
351
356
|
}
|
|
352
357
|
|
package/modules/priceFloors.js
CHANGED
|
@@ -28,6 +28,7 @@ import {auctionManager} from '../src/auctionManager.js';
|
|
|
28
28
|
import {IMP, PBS, registerOrtbProcessor, REQUEST} from '../src/pbjsORTB.js';
|
|
29
29
|
import {timedAuctionHook, timedBidResponseHook} from '../src/utils/perfMetrics.js';
|
|
30
30
|
import {beConvertCurrency} from '../src/utils/currency.js';
|
|
31
|
+
import {adjustCpm} from '../src/utils/cpm.js';
|
|
31
32
|
|
|
32
33
|
/**
|
|
33
34
|
* @summary This Module is intended to provide users with the ability to dynamically set and enforce price floors on a per auction basis.
|
|
@@ -179,12 +180,8 @@ function generatePossibleEnumerations(arrayOfFields, delimiter) {
|
|
|
179
180
|
/**
|
|
180
181
|
* @summary If a the input bidder has a registered cpmadjustment it returns the input CPM after being adjusted
|
|
181
182
|
*/
|
|
182
|
-
export function getBiddersCpmAdjustment(
|
|
183
|
-
|
|
184
|
-
if (adjustmentFunction) {
|
|
185
|
-
return parseFloat(adjustmentFunction(inputCpm, { ...bid, cpm: inputCpm }, bidRequest));
|
|
186
|
-
}
|
|
187
|
-
return parseFloat(inputCpm);
|
|
183
|
+
export function getBiddersCpmAdjustment(inputCpm, bid, bidRequest) {
|
|
184
|
+
return parseFloat(adjustCpm(inputCpm, {...bid, cpm: inputCpm}, bidRequest));
|
|
188
185
|
}
|
|
189
186
|
|
|
190
187
|
/**
|
|
@@ -254,7 +251,7 @@ export function getFloor(requestParams = {currency: 'USD', mediaType: '*', size:
|
|
|
254
251
|
if (inverseFunction) {
|
|
255
252
|
floorInfo.matchingFloor = inverseFunction(floorInfo.matchingFloor, bidRequest);
|
|
256
253
|
} else {
|
|
257
|
-
let cpmAdjustment = getBiddersCpmAdjustment(
|
|
254
|
+
let cpmAdjustment = getBiddersCpmAdjustment(floorInfo.matchingFloor, null, bidRequest);
|
|
258
255
|
floorInfo.matchingFloor = cpmAdjustment ? calculateAdjustedFloor(floorInfo.matchingFloor, cpmAdjustment) : floorInfo.matchingFloor;
|
|
259
256
|
}
|
|
260
257
|
}
|
|
@@ -313,6 +310,8 @@ export function getFloorDataFromAdUnits(adUnits) {
|
|
|
313
310
|
// copy over the new rules into our values object
|
|
314
311
|
Object.assign(accum.values, newRules);
|
|
315
312
|
}
|
|
313
|
+
} else if (adUnit.floors != null) {
|
|
314
|
+
logWarn(`adUnit '${adUnit.code}' provides an invalid \`floor\` definition, it will be ignored for floor calculations`, adUnit);
|
|
316
315
|
}
|
|
317
316
|
return accum;
|
|
318
317
|
}, {});
|
|
@@ -737,7 +736,7 @@ export const addBidResponseHook = timedBidResponseHook('priceFloors', function a
|
|
|
737
736
|
}
|
|
738
737
|
|
|
739
738
|
// ok we got the bid response cpm in our desired currency. Now we need to run the bidders CPMAdjustment function if it exists
|
|
740
|
-
adjustedCpm = getBiddersCpmAdjustment(
|
|
739
|
+
adjustedCpm = getBiddersCpmAdjustment(adjustedCpm, bid, matchingBidRequest);
|
|
741
740
|
|
|
742
741
|
// add necessary data information for analytics adapters / floor providers would possibly need
|
|
743
742
|
addFloorDataToBid(floorData, floorInfo, bid, adjustedCpm);
|
|
@@ -16,6 +16,7 @@ const DEFAULT_BID_TTL = 20;
|
|
|
16
16
|
const DEFAULT_CURRENCY = 'USD';
|
|
17
17
|
const DEFAULT_NET_REVENUE = true;
|
|
18
18
|
const KNOWN_PARAMS = ['cp', 'ct', 'cf', 'video', 'battr', 'bcat', 'badv', 'bidfloor'];
|
|
19
|
+
const DEFAULT_TMAX = 500;
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* PulsePoint Bid Adapter.
|
|
@@ -54,6 +55,7 @@ export const spec = {
|
|
|
54
55
|
user: user(bidRequests[0], bidderRequest),
|
|
55
56
|
regs: regs(bidderRequest),
|
|
56
57
|
source: source(bidRequests[0].schain),
|
|
58
|
+
tmax: bidderRequest.timeout || DEFAULT_TMAX,
|
|
57
59
|
};
|
|
58
60
|
return {
|
|
59
61
|
method: 'POST',
|
|
@@ -13,6 +13,7 @@ export const spec = {
|
|
|
13
13
|
gvlid: GVL_ID,
|
|
14
14
|
aliases: ['smart'], // short code
|
|
15
15
|
supportedMediaTypes: [BANNER, VIDEO],
|
|
16
|
+
|
|
16
17
|
/**
|
|
17
18
|
* Determines whether or not the given bid request is valid.
|
|
18
19
|
*
|
|
@@ -131,7 +132,6 @@ export const spec = {
|
|
|
131
132
|
*/
|
|
132
133
|
buildRequests: function (validBidRequests, bidderRequest) {
|
|
133
134
|
// use bidderRequest.bids[] to get bidder-dependent request info
|
|
134
|
-
|
|
135
135
|
const adServerCurrency = config.getConfig('currency.adServerCurrency');
|
|
136
136
|
const sellerDefinedAudience = deepAccess(bidderRequest, 'ortb2.user.data', config.getAnyConfig('ortb2.user.data'));
|
|
137
137
|
const sellerDefinedContext = deepAccess(bidderRequest, 'ortb2.site.content.data', config.getAnyConfig('ortb2.site.content.data'));
|
|
@@ -144,7 +144,6 @@ export const spec = {
|
|
|
144
144
|
pageid: bid.params.pageId,
|
|
145
145
|
formatid: bid.params.formatId,
|
|
146
146
|
currencyCode: adServerCurrency,
|
|
147
|
-
bidfloor: bid.params.bidfloor || spec.getBidFloor(bid, adServerCurrency),
|
|
148
147
|
targeting: bid.params.target && bid.params.target !== '' ? bid.params.target : undefined,
|
|
149
148
|
buid: bid.params.buId && bid.params.buId !== '' ? bid.params.buId : undefined,
|
|
150
149
|
appname: bid.params.appName && bid.params.appName !== '' ? bid.params.appName : undefined,
|
|
@@ -161,10 +160,21 @@ export const spec = {
|
|
|
161
160
|
sdc: sellerDefinedContext
|
|
162
161
|
};
|
|
163
162
|
|
|
164
|
-
if (bidderRequest
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
163
|
+
if (bidderRequest) {
|
|
164
|
+
if (bidderRequest.gdprConsent) {
|
|
165
|
+
payload.addtl_consent = bidderRequest.gdprConsent.addtlConsent;
|
|
166
|
+
payload.gdpr_consent = bidderRequest.gdprConsent.consentString;
|
|
167
|
+
payload.gdpr = bidderRequest.gdprConsent.gdprApplies; // we're handling the undefined case server side
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (bidderRequest.gppConsent) {
|
|
171
|
+
payload.gpp = bidderRequest.gppConsent.gppString;
|
|
172
|
+
payload.gpp_sid = bidderRequest.gppConsent.applicableSections;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (bidderRequest.uspConsent) {
|
|
176
|
+
payload.us_privacy = bidderRequest.uspConsent;
|
|
177
|
+
}
|
|
168
178
|
}
|
|
169
179
|
|
|
170
180
|
if (bid && bid.userId) {
|
|
@@ -175,24 +185,28 @@ export const spec = {
|
|
|
175
185
|
payload.us_privacy = bidderRequest.uspConsent;
|
|
176
186
|
}
|
|
177
187
|
|
|
178
|
-
const videoMediaType = deepAccess(bid, 'mediaTypes.video');
|
|
179
188
|
const bannerMediaType = deepAccess(bid, 'mediaTypes.banner');
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
// If there are video and banner media types in the ad unit, we clone the payload
|
|
189
|
-
// to create a specific one for video.
|
|
190
|
-
let videoPayload = deepClone(payload);
|
|
189
|
+
const videoMediaType = deepAccess(bid, 'mediaTypes.video');
|
|
190
|
+
const isSupportedVideoContext = videoMediaType && (videoMediaType.context === 'instream' || videoMediaType.context === 'outstream');
|
|
191
|
+
|
|
192
|
+
if (bannerMediaType || isSupportedVideoContext) {
|
|
193
|
+
let type;
|
|
194
|
+
if (bannerMediaType) {
|
|
195
|
+
type = BANNER;
|
|
196
|
+
payload.sizes = spec.adaptBannerSizes(bannerMediaType.sizes);
|
|
191
197
|
|
|
192
|
-
|
|
193
|
-
|
|
198
|
+
if (isSupportedVideoContext) {
|
|
199
|
+
let videoPayload = deepClone(payload);
|
|
200
|
+
spec.fillPayloadForVideoBidRequest(videoPayload, videoMediaType, bid.params.video);
|
|
201
|
+
videoPayload.bidfloor = bid.params.bidfloor || spec.getBidFloor(bid, adServerCurrency, VIDEO);
|
|
202
|
+
bidRequests.push(spec.createServerRequest(videoPayload, bid.params.domain));
|
|
203
|
+
}
|
|
204
|
+
} else {
|
|
205
|
+
type = VIDEO;
|
|
206
|
+
spec.fillPayloadForVideoBidRequest(payload, videoMediaType, bid.params.video);
|
|
207
|
+
}
|
|
194
208
|
|
|
195
|
-
payload.
|
|
209
|
+
payload.bidfloor = bid.params.bidfloor || spec.getBidFloor(bid, adServerCurrency, type);
|
|
196
210
|
bidRequests.push(spec.createServerRequest(payload, bid.params.domain));
|
|
197
211
|
} else {
|
|
198
212
|
bidRequests.push({});
|
|
@@ -253,24 +267,21 @@ export const spec = {
|
|
|
253
267
|
*
|
|
254
268
|
* @param {object} bid Bid request object
|
|
255
269
|
* @param {string} currency Ad server currency
|
|
270
|
+
* @param {string} mediaType Bid media type
|
|
256
271
|
* @return {number} Floor price
|
|
257
272
|
*/
|
|
258
|
-
getBidFloor: function (bid, currency) {
|
|
273
|
+
getBidFloor: function (bid, currency, mediaType) {
|
|
259
274
|
if (!isFn(bid.getFloor)) {
|
|
260
275
|
return DEFAULT_FLOOR;
|
|
261
276
|
}
|
|
262
277
|
|
|
263
278
|
const floor = bid.getFloor({
|
|
264
279
|
currency: currency || 'USD',
|
|
265
|
-
mediaType
|
|
280
|
+
mediaType,
|
|
266
281
|
size: '*'
|
|
267
282
|
});
|
|
268
283
|
|
|
269
|
-
|
|
270
|
-
return floor.floor;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
return DEFAULT_FLOOR;
|
|
284
|
+
return isPlainObject(floor) && !isNaN(floor.floor) ? floor.floor : DEFAULT_FLOOR;
|
|
274
285
|
},
|
|
275
286
|
|
|
276
287
|
/**
|
|
@@ -10,6 +10,15 @@ Maintainer: supply@smartyads.com
|
|
|
10
10
|
|
|
11
11
|
Module that connects to SmartyAds' demand sources
|
|
12
12
|
|
|
13
|
+
# Parameters
|
|
14
|
+
|
|
15
|
+
| Name | Scope | Description | Example |
|
|
16
|
+
| :------------ | :------- | :------------------------ | :------------------- |
|
|
17
|
+
| `sourceid` | required (for prebid.js) | placement ID | "0" |
|
|
18
|
+
| `host` | required (for prebid-server) | const value, set to "prebid" | "prebid" |
|
|
19
|
+
| `accountid` | required (for prebid-server) | partner ID | "1901" |
|
|
20
|
+
| `traffic` | optional (for prebid.js) | Configures the mediaType that should be used. Values can be banner, native or video | "banner" |
|
|
21
|
+
|
|
13
22
|
# Test Parameters
|
|
14
23
|
```
|
|
15
24
|
var adUnits = [
|
|
@@ -1,29 +1,77 @@
|
|
|
1
|
+
import {buildUrl, deepAccess} from '../src/utils.js'
|
|
2
|
+
import { BANNER, VIDEO } from '../src/mediaTypes.js';
|
|
1
3
|
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
2
|
-
import {buildUrl} from '../src/utils.js'
|
|
3
4
|
|
|
4
5
|
const BIDDER_CODE = 'smartytech';
|
|
5
6
|
export const ENDPOINT_PROTOCOL = 'https';
|
|
6
7
|
export const ENDPOINT_DOMAIN = 'server.smartytech.io';
|
|
7
|
-
export const ENDPOINT_PATH = '/hb/bidder';
|
|
8
|
+
export const ENDPOINT_PATH = '/hb/v2/bidder';
|
|
8
9
|
|
|
9
10
|
export const spec = {
|
|
11
|
+
supportedMediaTypes: [ BANNER, VIDEO ],
|
|
10
12
|
code: BIDDER_CODE,
|
|
11
13
|
|
|
12
14
|
isBidRequestValid: function (bidRequest) {
|
|
13
|
-
return
|
|
15
|
+
return (
|
|
16
|
+
!!parseInt(bidRequest.params.endpointId) &&
|
|
17
|
+
spec._validateBanner(bidRequest) &&
|
|
18
|
+
spec._validateVideo(bidRequest)
|
|
19
|
+
);
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
_validateBanner: function(bidRequest) {
|
|
23
|
+
const bannerAdUnit = deepAccess(bidRequest, 'mediaTypes.banner');
|
|
24
|
+
|
|
25
|
+
if (bannerAdUnit === undefined) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (!Array.isArray(bannerAdUnit.sizes)) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return true;
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
_validateVideo: function(bidRequest) {
|
|
37
|
+
const videoAdUnit = deepAccess(bidRequest, 'mediaTypes.video');
|
|
38
|
+
|
|
39
|
+
if (videoAdUnit === undefined) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (!Array.isArray(videoAdUnit.playerSize)) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (!videoAdUnit.context) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return true;
|
|
14
52
|
},
|
|
15
53
|
|
|
16
54
|
buildRequests: function (validBidRequests, bidderRequest) {
|
|
17
55
|
const referer = bidderRequest?.refererInfo?.page || window.location.href;
|
|
18
56
|
|
|
19
57
|
const bidRequests = validBidRequests.map((validBidRequest) => {
|
|
20
|
-
|
|
58
|
+
let video = deepAccess(validBidRequest, 'mediaTypes.video', false);
|
|
59
|
+
let banner = deepAccess(validBidRequest, 'mediaTypes.banner', false);
|
|
60
|
+
|
|
61
|
+
let oneRequest = {
|
|
21
62
|
endpointId: validBidRequest.params.endpointId,
|
|
22
63
|
adUnitCode: validBidRequest.adUnitCode,
|
|
23
|
-
|
|
24
|
-
bidId: validBidRequest.bidId
|
|
25
|
-
referer: referer
|
|
64
|
+
referer: referer,
|
|
65
|
+
bidId: validBidRequest.bidId
|
|
26
66
|
};
|
|
67
|
+
|
|
68
|
+
if (video) {
|
|
69
|
+
oneRequest.video = video;
|
|
70
|
+
} else if (banner) {
|
|
71
|
+
oneRequest.banner = banner;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return oneRequest
|
|
27
75
|
});
|
|
28
76
|
|
|
29
77
|
let adPartnerRequestUrl = buildUrl({
|
|
@@ -55,12 +103,14 @@ export const spec = {
|
|
|
55
103
|
bid: validBids.find(b => b.adUnitCode === key),
|
|
56
104
|
response: responseBody[key]
|
|
57
105
|
}
|
|
58
|
-
}).map(item => spec.
|
|
106
|
+
}).map(item => spec._adResponse(item.bid, item.response));
|
|
59
107
|
},
|
|
60
108
|
|
|
61
|
-
|
|
109
|
+
_adResponse: function (request, response) {
|
|
62
110
|
const bidObject = {
|
|
63
|
-
requestId,
|
|
111
|
+
requestId: request.bidId,
|
|
112
|
+
adUnitCode: request.adUnitCode,
|
|
113
|
+
bidderCode: BIDDER_CODE,
|
|
64
114
|
ad: response.ad,
|
|
65
115
|
cpm: response.cpm,
|
|
66
116
|
width: response.width,
|
|
@@ -69,7 +119,14 @@ export const spec = {
|
|
|
69
119
|
creativeId: response.creativeId,
|
|
70
120
|
netRevenue: true,
|
|
71
121
|
currency: response.currency,
|
|
122
|
+
mediaType: BANNER
|
|
72
123
|
}
|
|
124
|
+
|
|
125
|
+
if (response.mediaType === VIDEO) {
|
|
126
|
+
bidObject.vastXml = response.ad;
|
|
127
|
+
bidObject.mediaType = VIDEO;
|
|
128
|
+
}
|
|
129
|
+
|
|
73
130
|
return bidObject;
|
|
74
131
|
},
|
|
75
132
|
|
|
@@ -1,44 +1,55 @@
|
|
|
1
1
|
# Overview
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Module Type:
|
|
6
|
-
|
|
3
|
+
```
|
|
4
|
+
Module Name: SmartyTech Bid Adapter
|
|
5
|
+
Module Type: Bidder Adapter
|
|
7
6
|
Maintainer: info@adpartner.pro
|
|
7
|
+
```
|
|
8
8
|
|
|
9
9
|
# Description
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Connects to SmartyTech's exchange for bids.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
SmartyTech bid adapter supports Banner and Video
|
|
14
14
|
|
|
15
|
-
#
|
|
15
|
+
# Sample Ad Unit: For Publishers
|
|
16
|
+
## Sample Banner Ad Unit
|
|
17
|
+
```
|
|
18
|
+
var adUnits = [{
|
|
19
|
+
code: '/123123123/prebidjs-banner',
|
|
20
|
+
mediaTypes: {
|
|
21
|
+
banner: {
|
|
22
|
+
sizes: [
|
|
23
|
+
[300, 301],
|
|
24
|
+
[300, 250]
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
bids: [{
|
|
29
|
+
bidder: 'smartytech',
|
|
30
|
+
params: {
|
|
31
|
+
endpointId: 12
|
|
32
|
+
}
|
|
33
|
+
}]
|
|
34
|
+
}];
|
|
35
|
+
```
|
|
16
36
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
]
|
|
37
|
+
## Sample Video Ad Unit
|
|
38
|
+
```
|
|
39
|
+
var videoAdUnit = {
|
|
40
|
+
code: '/123123123/video-vast-banner',
|
|
41
|
+
mediaTypes: {
|
|
42
|
+
video: {
|
|
43
|
+
context: 'instream',
|
|
44
|
+
playerSize: [640, 480],
|
|
45
|
+
mimes: ['video/mp4'],
|
|
46
|
+
}
|
|
30
47
|
},
|
|
31
|
-
{
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
endpointId: 14
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
]
|
|
42
|
-
}
|
|
43
|
-
];
|
|
48
|
+
bids: [{
|
|
49
|
+
bidder: 'smartytech',
|
|
50
|
+
params: {
|
|
51
|
+
endpointId: 12
|
|
52
|
+
}
|
|
53
|
+
}]
|
|
54
|
+
};
|
|
44
55
|
```
|