prebid.js 7.40.0 → 7.41.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/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/aduptechBidAdapter.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/browsiBidAdapter.js +1 -0
- package/dist/carodaBidAdapter.js +1 -1
- package/dist/chtnwBidAdapter.js +1 -1
- package/dist/cleanmedianetBidAdapter.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantAnalyticsAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/cwireBidAdapter.js +1 -1
- package/dist/dfpAdServerVideo.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/feedadBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/freewheel-sspBidAdapter.js +1 -1
- package/dist/glimpseBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gridNMBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/inmarBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/kargoBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/kueezRtbBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/lifestreetBidAdapter.js +1 -1
- package/dist/liveyieldAnalyticsAdapter.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/magniteAnalyticsAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/minutemediaplusBidAdapter.js +1 -1
- package/dist/missenaBidAdapter.js +1 -1
- package/dist/nexx360BidAdapter.js +1 -1
- package/dist/nobidBidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +130 -129
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/optidigitalBidAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/permutiveRtdProvider.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pubwiseBidAdapter.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/smilewantedBidAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnAnalyticsAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/stvBidAdapter.js +1 -0
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/synacormediaBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/trionBidAdapter.js +1 -1
- package/dist/tripleliftBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.js +1 -1
- package/dist/uid2IdSystem.js +1 -1
- package/dist/underdogmediaBidAdapter.js +1 -1
- package/dist/undertoneBidAdapter.js +1 -1
- package/dist/vidazooBidAdapter.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/visxBidAdapter.js +1 -1
- package/dist/vuukleBidAdapter.js +1 -1
- package/dist/widespaceBidAdapter.js +1 -1
- package/dist/winrBidAdapter.js +1 -1
- package/dist/yahoosspBidAdapter.js +1 -1
- package/dist/yandexBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/integrationExamples/gpt/x-domain/creative.html +1 -1
- package/modules/aduptechBidAdapter.js +43 -37
- package/modules/browsiBidAdapter.js +171 -0
- package/modules/browsiBidAdapter.md +38 -0
- package/modules/cleanmedianetBidAdapter.js +191 -126
- package/modules/cleanmedianetBidAdapter.md +64 -18
- package/modules/conversantBidAdapter.js +4 -0
- package/modules/dfpAdServerVideo.js +8 -8
- package/modules/freewheel-sspBidAdapter.js +9 -0
- package/modules/gridBidAdapter.js +12 -1
- package/modules/ixBidAdapter.js +1 -1
- package/modules/missenaBidAdapter.js +2 -1
- package/modules/neuwoRtdProvider.js +1 -1
- package/modules/nobidBidAdapter.js +13 -2
- package/modules/nobidBidAdapter.md +2 -2
- package/modules/permutiveRtdProvider.js +8 -2
- package/modules/pubwiseBidAdapter.js +265 -33
- package/modules/stvBidAdapter.js +330 -0
- package/modules/stvBidAdapter.md +62 -0
- package/modules/yandexBidAdapter.js +259 -71
- package/modules/yandexBidAdapter.md +52 -15
- package/package.json +1 -1
- package/src/videoCache.js +4 -4
- package/test/spec/modules/browsiBidAdapter_spec.js +209 -0
- package/test/spec/modules/cleanmedianetBidAdapter_spec.js +462 -407
- package/test/spec/modules/conversantBidAdapter_spec.js +8 -0
- package/test/spec/modules/dfpAdServerVideo_spec.js +36 -4
- package/test/spec/modules/freewheel-sspBidAdapter_spec.js +19 -0
- package/test/spec/modules/gridBidAdapter_spec.js +24 -0
- package/test/spec/modules/ixBidAdapter_spec.js +4 -4
- package/test/spec/modules/nobidBidAdapter_spec.js +32 -0
- package/test/spec/modules/permutiveRtdProvider_spec.js +61 -4
- package/test/spec/modules/pubwiseBidAdapter_spec.js +313 -3
- package/test/spec/modules/stvBidAdapter_spec.js +402 -0
- package/test/spec/modules/yandexBidAdapter_spec.js +315 -45
- package/test/spec/videoCache_spec.js +23 -0
- package/dist/flocIdSystem.js +0 -1
- package/modules/flocIdSystem.js +0 -0
|
@@ -90,7 +90,7 @@ export const spec = {
|
|
|
90
90
|
let userExt = null;
|
|
91
91
|
let endpoint = null;
|
|
92
92
|
let forceBidderName = false;
|
|
93
|
-
let {bidderRequestId, auctionId, gdprConsent, uspConsent, timeout, refererInfo} = bidderRequest || {};
|
|
93
|
+
let {bidderRequestId, auctionId, gdprConsent, uspConsent, timeout, refererInfo, gppConsent} = bidderRequest || {};
|
|
94
94
|
|
|
95
95
|
const referer = refererInfo ? encodeURIComponent(refererInfo.page) : '';
|
|
96
96
|
const tmax = timeout || config.getConfig('bidderTimeout');
|
|
@@ -340,11 +340,22 @@ export const spec = {
|
|
|
340
340
|
}
|
|
341
341
|
};
|
|
342
342
|
}
|
|
343
|
+
const ortb2Regs = deepAccess(bidderRequest, 'ortb2.regs') || {};
|
|
344
|
+
if (gppConsent || ortb2Regs?.gpp) {
|
|
345
|
+
const gpp = {
|
|
346
|
+
gpp: gppConsent?.gppString ?? ortb2Regs?.gpp,
|
|
347
|
+
gpp_sid: gppConsent?.applicableSections ?? ortb2Regs?.gpp_sid
|
|
348
|
+
};
|
|
349
|
+
request.regs = mergeDeep(request?.regs ?? {}, gpp);
|
|
350
|
+
}
|
|
343
351
|
|
|
344
352
|
if (uspConsent) {
|
|
345
353
|
if (!request.regs) {
|
|
346
354
|
request.regs = {ext: {}};
|
|
347
355
|
}
|
|
356
|
+
if (!request.regs.ext) {
|
|
357
|
+
request.regs.ext = {};
|
|
358
|
+
}
|
|
348
359
|
request.regs.ext.us_privacy = uspConsent;
|
|
349
360
|
}
|
|
350
361
|
|
package/modules/ixBidAdapter.js
CHANGED
|
@@ -833,7 +833,7 @@ function applyRegulations(r, bidderRequest) {
|
|
|
833
833
|
|
|
834
834
|
if (gdprConsent.hasOwnProperty('addtlConsent') && gdprConsent.addtlConsent) {
|
|
835
835
|
r.user.ext.consented_providers_settings = {
|
|
836
|
-
|
|
836
|
+
addtl_consent: gdprConsent.addtlConsent
|
|
837
837
|
};
|
|
838
838
|
}
|
|
839
839
|
}
|
|
@@ -60,6 +60,7 @@ export const spec = {
|
|
|
60
60
|
if (bidRequest.params.isInternal) {
|
|
61
61
|
payload.is_internal = bidRequest.params.isInternal;
|
|
62
62
|
}
|
|
63
|
+
payload.userEids = bidRequest.userIdAsEids || [];
|
|
63
64
|
return {
|
|
64
65
|
method: 'POST',
|
|
65
66
|
url: baseUrl + '?' + formatQS({ t: bidRequest.params.apiKey }),
|
|
@@ -127,7 +128,7 @@ export const spec = {
|
|
|
127
128
|
protocol: 'https',
|
|
128
129
|
hostname,
|
|
129
130
|
pathname: '/v1/bidsuccess',
|
|
130
|
-
search: { t: bid.params[0].apiKey },
|
|
131
|
+
search: { t: bid.params[0].apiKey, provider: bid.meta?.networkName, cpm: bid.cpm, currency: bid.currency },
|
|
131
132
|
})
|
|
132
133
|
);
|
|
133
134
|
logInfo('Missena - Bid won', bid);
|
|
@@ -11,7 +11,7 @@ const CATTAX_IAB = 6 // IAB Tech Lab Content Taxonomy 2.2
|
|
|
11
11
|
const RESPONSE_IAB_TIER_1 = 'marketing_categories.iab_tier_1'
|
|
12
12
|
const RESPONSE_IAB_TIER_2 = 'marketing_categories.iab_tier_2'
|
|
13
13
|
|
|
14
|
-
function init(config = {}, userConsent
|
|
14
|
+
function init(config = {}, userConsent) {
|
|
15
15
|
config.params = config.params || {}
|
|
16
16
|
// ignore module if publicToken is missing (module setup failure)
|
|
17
17
|
if (!config.params.publicToken) {
|
|
@@ -8,7 +8,7 @@ import {hasPurpose1Consent} from '../src/utils/gpdr.js';
|
|
|
8
8
|
const GVLID = 816;
|
|
9
9
|
const BIDDER_CODE = 'nobid';
|
|
10
10
|
const storage = getStorageManager({gvlid: GVLID, bidderCode: BIDDER_CODE});
|
|
11
|
-
window.nobidVersion = '1.3.
|
|
11
|
+
window.nobidVersion = '1.3.3';
|
|
12
12
|
window.nobid = window.nobid || {};
|
|
13
13
|
window.nobid.bidResponses = window.nobid.bidResponses || {};
|
|
14
14
|
window.nobid.timeoutTotal = 0;
|
|
@@ -175,6 +175,9 @@ function nobidBuildRequests(bids, bidderRequest) {
|
|
|
175
175
|
if (adunitObject.div) {
|
|
176
176
|
a.d = adunitObject.div;
|
|
177
177
|
}
|
|
178
|
+
if (adunitObject.floor) {
|
|
179
|
+
a.floor = adunitObject.floor;
|
|
180
|
+
}
|
|
178
181
|
if (adunitObject.targeting) {
|
|
179
182
|
a.g = adunitObject.targeting;
|
|
180
183
|
} else {
|
|
@@ -201,6 +204,12 @@ function nobidBuildRequests(bids, bidderRequest) {
|
|
|
201
204
|
adunits.push(a);
|
|
202
205
|
return adunits;
|
|
203
206
|
}
|
|
207
|
+
function getFloor (bid) {
|
|
208
|
+
if (bid && typeof bid.getFloor === 'function' && bid.getFloor().floor) {
|
|
209
|
+
return bid.getFloor().floor;
|
|
210
|
+
}
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
204
213
|
if (typeof window.nobid.refreshLimit !== 'undefined') {
|
|
205
214
|
if (window.nobid.refreshLimit < window.nobid.refreshCount) return false;
|
|
206
215
|
}
|
|
@@ -227,6 +236,7 @@ function nobidBuildRequests(bids, bidderRequest) {
|
|
|
227
236
|
if (bid.mediaType === VIDEO || (videoMediaType && (context === 'instream' || context === 'outstream'))) {
|
|
228
237
|
adType = 'video';
|
|
229
238
|
}
|
|
239
|
+
const floor = getFloor(bid);
|
|
230
240
|
|
|
231
241
|
if (siteId) {
|
|
232
242
|
newAdunit({
|
|
@@ -235,7 +245,8 @@ function nobidBuildRequests(bids, bidderRequest) {
|
|
|
235
245
|
siteId: siteId,
|
|
236
246
|
placementId: placementId,
|
|
237
247
|
ad_type: adType,
|
|
238
|
-
params: bid.params
|
|
248
|
+
params: bid.params,
|
|
249
|
+
floor: floor
|
|
239
250
|
},
|
|
240
251
|
adunits);
|
|
241
252
|
}
|
|
@@ -4,7 +4,7 @@ title: Nobid
|
|
|
4
4
|
description: Prebid Nobid Bidder Adaptor
|
|
5
5
|
biddercode: nobid
|
|
6
6
|
hide: true
|
|
7
|
-
media_types: banner
|
|
7
|
+
media_types: banner, video
|
|
8
8
|
gdpr_supported: true
|
|
9
9
|
usp_supported: true
|
|
10
10
|
---
|
|
@@ -51,4 +51,4 @@ usp_supported: true
|
|
|
51
51
|
]
|
|
52
52
|
}
|
|
53
53
|
];
|
|
54
|
-
```
|
|
54
|
+
```
|
|
@@ -146,12 +146,17 @@ function updateOrtbConfig(bidder, currConfig, segmentIDs, sspSegmentIDs, transfo
|
|
|
146
146
|
.filter(({ id }) => ortb2UserDataTransformations.hasOwnProperty(id))
|
|
147
147
|
.map(({ id, config }) => ortb2UserDataTransformations[id](permutiveUserData, config))
|
|
148
148
|
|
|
149
|
+
const customCohortsUserData = {
|
|
150
|
+
name: PERMUTIVE_CUSTOM_COHORTS_KEYWORD,
|
|
151
|
+
segment: customCohortsData.map(cohortID => ({ id: cohortID })),
|
|
152
|
+
}
|
|
153
|
+
|
|
149
154
|
const ortbConfig = mergeDeep({}, currConfig)
|
|
150
155
|
const currentUserData = deepAccess(ortbConfig, 'ortb2.user.data') || []
|
|
151
156
|
|
|
152
157
|
const updatedUserData = currentUserData
|
|
153
|
-
.filter(el => el.name !== name)
|
|
154
|
-
.concat(permutiveUserData, transformedUserData)
|
|
158
|
+
.filter(el => el.name !== permutiveUserData.name && el.name !== customCohortsUserData.name)
|
|
159
|
+
.concat(permutiveUserData, transformedUserData, customCohortsUserData)
|
|
155
160
|
|
|
156
161
|
deepSetValue(ortbConfig, 'ortb2.user.data', updatedUserData)
|
|
157
162
|
|
|
@@ -311,6 +316,7 @@ export function getSegments (maxSegs) {
|
|
|
311
316
|
|
|
312
317
|
const segments = {
|
|
313
318
|
ac: [..._pcrprs, ..._ppam, ...legacySegs],
|
|
319
|
+
ix: readSegments('_pindexs', []),
|
|
314
320
|
rubicon: readSegments('_prubicons', []),
|
|
315
321
|
appnexus: readSegments('_papns', []),
|
|
316
322
|
gam: readSegments('_pdfps', []),
|
|
@@ -1,19 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
1
|
+
|
|
2
|
+
import { _each, isBoolean, isEmptyStr, isNumber, isStr, deepClone, isArray, deepSetValue, inIframe, mergeDeep, deepAccess, logMessage, logInfo, logWarn, logError } from '../src/utils.js';
|
|
3
3
|
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
4
|
-
import { BANNER, NATIVE } from '../src/mediaTypes.js';
|
|
5
|
-
|
|
4
|
+
import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
|
|
5
|
+
import { config } from '../src/config.js';
|
|
6
|
+
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
|
|
7
|
+
import { OUTSTREAM, INSTREAM } from '../src/video.js';
|
|
8
|
+
|
|
9
|
+
const VERSION = '0.3.0';
|
|
6
10
|
const GVLID = 842;
|
|
7
11
|
const NET_REVENUE = true;
|
|
8
12
|
const UNDEFINED = undefined;
|
|
9
13
|
const DEFAULT_CURRENCY = 'USD';
|
|
10
14
|
const AUCTION_TYPE = 1;
|
|
11
15
|
const BIDDER_CODE = 'pwbid';
|
|
16
|
+
const LOG_PREFIX = 'PubWise: ';
|
|
12
17
|
const ENDPOINT_URL = 'https://bid.pubwise.io/prebid';
|
|
18
|
+
// const ENDPOINT_URL = 'https://bid.pubwise.io/prebid'; // testing observable endpoint
|
|
13
19
|
const DEFAULT_WIDTH = 0;
|
|
14
20
|
const DEFAULT_HEIGHT = 0;
|
|
15
21
|
const PREBID_NATIVE_HELP_LINK = 'https://prebid.org/dev-docs/show-native-ads.html';
|
|
16
22
|
// const USERSYNC_URL = '//127.0.0.1:8080/usersync'
|
|
23
|
+
const MSG_VIDEO_PLACEMENT_MISSING = 'Video.Placement param missing';
|
|
24
|
+
|
|
25
|
+
const MEDIATYPE = [
|
|
26
|
+
BANNER,
|
|
27
|
+
VIDEO,
|
|
28
|
+
NATIVE
|
|
29
|
+
]
|
|
17
30
|
|
|
18
31
|
const CUSTOM_PARAMS = {
|
|
19
32
|
'gender': '', // User gender
|
|
@@ -22,6 +35,32 @@ const CUSTOM_PARAMS = {
|
|
|
22
35
|
'lon': '', // User Location - Longitude
|
|
23
36
|
};
|
|
24
37
|
|
|
38
|
+
const DATA_TYPES = {
|
|
39
|
+
'NUMBER': 'number',
|
|
40
|
+
'STRING': 'string',
|
|
41
|
+
'BOOLEAN': 'boolean',
|
|
42
|
+
'ARRAY': 'array',
|
|
43
|
+
'OBJECT': 'object'
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const VIDEO_CUSTOM_PARAMS = {
|
|
47
|
+
'mimes': DATA_TYPES.ARRAY,
|
|
48
|
+
'minduration': DATA_TYPES.NUMBER,
|
|
49
|
+
'maxduration': DATA_TYPES.NUMBER,
|
|
50
|
+
'startdelay': DATA_TYPES.NUMBER,
|
|
51
|
+
'playbackmethod': DATA_TYPES.ARRAY,
|
|
52
|
+
'api': DATA_TYPES.ARRAY,
|
|
53
|
+
'protocols': DATA_TYPES.ARRAY,
|
|
54
|
+
'w': DATA_TYPES.NUMBER,
|
|
55
|
+
'h': DATA_TYPES.NUMBER,
|
|
56
|
+
'battr': DATA_TYPES.ARRAY,
|
|
57
|
+
'linearity': DATA_TYPES.NUMBER,
|
|
58
|
+
'placement': DATA_TYPES.NUMBER,
|
|
59
|
+
'minbitrate': DATA_TYPES.NUMBER,
|
|
60
|
+
'maxbitrate': DATA_TYPES.NUMBER,
|
|
61
|
+
'skip': DATA_TYPES.NUMBER
|
|
62
|
+
}
|
|
63
|
+
|
|
25
64
|
// rtb native types are meant to be dynamic and extendable
|
|
26
65
|
// the extendable data asset types are nicely aligned
|
|
27
66
|
// in practice we set an ID that is distinct for each real type of return
|
|
@@ -88,7 +127,7 @@ _each(NATIVE_ASSETS, anAsset => { NATIVE_ASSET_KEY_TO_ASSET_MAP[anAsset.KEY] = a
|
|
|
88
127
|
export const spec = {
|
|
89
128
|
code: BIDDER_CODE,
|
|
90
129
|
gvlid: GVLID,
|
|
91
|
-
supportedMediaTypes: [BANNER, NATIVE],
|
|
130
|
+
supportedMediaTypes: [BANNER, VIDEO, NATIVE],
|
|
92
131
|
/**
|
|
93
132
|
* Determines whether or not the given bid request is valid.
|
|
94
133
|
*
|
|
@@ -96,18 +135,40 @@ export const spec = {
|
|
|
96
135
|
* @return boolean True if this is a valid bid, and false otherwise.
|
|
97
136
|
*/
|
|
98
137
|
isBidRequestValid: function (bid) {
|
|
99
|
-
// siteId is required
|
|
138
|
+
// siteId is required for any type
|
|
100
139
|
if (bid.params && bid.params.siteId) {
|
|
101
140
|
// it must be a string
|
|
102
141
|
if (!isStr(bid.params.siteId)) {
|
|
103
142
|
_logWarn('siteId is required for bid', bid);
|
|
104
143
|
return false;
|
|
105
144
|
}
|
|
106
|
-
|
|
107
|
-
|
|
145
|
+
|
|
146
|
+
// video ad validation
|
|
147
|
+
if (bid.hasOwnProperty('mediaTypes') && bid.mediaTypes.hasOwnProperty(VIDEO)) {
|
|
148
|
+
// bid.mediaTypes.video.mimes OR bid.params.video.mimes should be present and must be a non-empty array
|
|
149
|
+
let mediaTypesVideoMimes = deepAccess(bid.mediaTypes, 'video.mimes');
|
|
150
|
+
let paramsVideoMimes = deepAccess(bid, 'params.video.mimes');
|
|
151
|
+
if (_isNonEmptyArray(mediaTypesVideoMimes) === false && _isNonEmptyArray(paramsVideoMimes) === false) {
|
|
152
|
+
_logWarn('Error: For video ads, bid.mediaTypes.video.mimes OR bid.params.video.mimes should be present and must be a non-empty array. Call suppressed:', JSON.stringify(bid));
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (!bid.mediaTypes[VIDEO].hasOwnProperty('context')) {
|
|
157
|
+
_logError(`no context specified in bid. Rejecting bid: `, JSON.stringify(bid));
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (bid.mediaTypes[VIDEO].context === 'outstream') {
|
|
162
|
+
delete bid.mediaTypes[VIDEO];
|
|
163
|
+
_logWarn(`outstream not currently supported `, JSON.stringify(bid));
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return true;
|
|
108
169
|
}
|
|
109
170
|
|
|
110
|
-
return
|
|
171
|
+
return false;
|
|
111
172
|
},
|
|
112
173
|
/**
|
|
113
174
|
* Make a server request from the list of BidRequests.
|
|
@@ -116,6 +177,7 @@ export const spec = {
|
|
|
116
177
|
* @return ServerRequest Info describing the request to the server.
|
|
117
178
|
*/
|
|
118
179
|
buildRequests: function (validBidRequests, bidderRequest) {
|
|
180
|
+
validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests);
|
|
119
181
|
var refererInfo;
|
|
120
182
|
if (bidderRequest && bidderRequest.refererInfo) {
|
|
121
183
|
refererInfo = bidderRequest.refererInfo;
|
|
@@ -210,7 +272,7 @@ export const spec = {
|
|
|
210
272
|
|
|
211
273
|
return {
|
|
212
274
|
method: 'POST',
|
|
213
|
-
url:
|
|
275
|
+
url: _getEndpointURL(bid),
|
|
214
276
|
data: payload,
|
|
215
277
|
options: options,
|
|
216
278
|
bidderRequest: bidderRequest,
|
|
@@ -231,6 +293,7 @@ export const spec = {
|
|
|
231
293
|
|
|
232
294
|
// try {
|
|
233
295
|
if (response.body && response.body.seatbid && isArray(response.body.seatbid)) {
|
|
296
|
+
_logInfo('interpretResponse response body', response.body);
|
|
234
297
|
// Supporting multiple bid responses for same adSize
|
|
235
298
|
respCur = response.body.cur || respCur;
|
|
236
299
|
response.body.seatbid.forEach(seatbidder => {
|
|
@@ -254,10 +317,24 @@ export const spec = {
|
|
|
254
317
|
if (parsedRequest.imp && parsedRequest.imp.length > 0) {
|
|
255
318
|
parsedRequest.imp.forEach(req => {
|
|
256
319
|
if (bid.impid === req.id) {
|
|
257
|
-
_checkMediaType(bid
|
|
320
|
+
_checkMediaType(bid, newBid);
|
|
258
321
|
switch (newBid.mediaType) {
|
|
259
322
|
case BANNER:
|
|
260
323
|
break;
|
|
324
|
+
case VIDEO:
|
|
325
|
+
const videoContext = deepAccess(request, 'mediaTypes.video.context');
|
|
326
|
+
switch (videoContext) {
|
|
327
|
+
case OUTSTREAM:
|
|
328
|
+
// not currently supported
|
|
329
|
+
break;
|
|
330
|
+
case INSTREAM:
|
|
331
|
+
break;
|
|
332
|
+
}
|
|
333
|
+
newBid.width = bid.hasOwnProperty('w') ? bid.w : req.video.w;
|
|
334
|
+
newBid.height = bid.hasOwnProperty('h') ? bid.h : req.video.h;
|
|
335
|
+
newBid.vastXml = bid.adm;
|
|
336
|
+
newBid.vastUrl = bid.vastUrl;
|
|
337
|
+
break;
|
|
261
338
|
case NATIVE:
|
|
262
339
|
_parseNativeResponse(bid, newBid);
|
|
263
340
|
break;
|
|
@@ -289,20 +366,31 @@ export const spec = {
|
|
|
289
366
|
}
|
|
290
367
|
}
|
|
291
368
|
|
|
292
|
-
function _checkMediaType(
|
|
293
|
-
//
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
369
|
+
function _checkMediaType(bid, newBid) {
|
|
370
|
+
// Check Various ADM Aspects to Determine Media Type
|
|
371
|
+
if (bid.ext && bid.ext['bidtype'] != undefined) {
|
|
372
|
+
// this is the most explicity check
|
|
373
|
+
newBid.mediaType = MEDIATYPE[bid.ext.bidtype];
|
|
374
|
+
} else {
|
|
375
|
+
_logInfo('bid.ext.bidtype does not exist, checking alternatively for mediaType');
|
|
376
|
+
var adm = bid.adm;
|
|
377
|
+
var videoRegex = new RegExp(/VAST\s+version/);
|
|
378
|
+
|
|
379
|
+
if (adm.indexOf('"ver":') >= 0) {
|
|
380
|
+
try {
|
|
381
|
+
var admJSON = '';
|
|
382
|
+
admJSON = JSON.parse(adm.replace(/\\/g, ''));
|
|
383
|
+
if (admJSON && admJSON.assets) {
|
|
384
|
+
newBid.mediaType = NATIVE;
|
|
385
|
+
}
|
|
386
|
+
} catch (e) {
|
|
387
|
+
_logWarn('Error: Cannot parse native reponse for ad response: ', adm);
|
|
300
388
|
}
|
|
301
|
-
}
|
|
302
|
-
|
|
389
|
+
} else if (videoRegex.test(adm)) {
|
|
390
|
+
newBid.mediaType = VIDEO;
|
|
391
|
+
} else {
|
|
392
|
+
newBid.mediaType = BANNER;
|
|
303
393
|
}
|
|
304
|
-
} else {
|
|
305
|
-
newBid.mediaType = BANNER;
|
|
306
394
|
}
|
|
307
395
|
}
|
|
308
396
|
|
|
@@ -416,7 +504,8 @@ function _createOrtbTemplate(conf) {
|
|
|
416
504
|
dnt: (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0,
|
|
417
505
|
h: screen.height,
|
|
418
506
|
w: screen.width,
|
|
419
|
-
language: navigator.language
|
|
507
|
+
language: navigator.language,
|
|
508
|
+
devicetype: _getDeviceType()
|
|
420
509
|
},
|
|
421
510
|
user: {},
|
|
422
511
|
ext: {
|
|
@@ -428,6 +517,7 @@ function _createOrtbTemplate(conf) {
|
|
|
428
517
|
function _createImpressionObject(bid, conf) {
|
|
429
518
|
var impObj = {};
|
|
430
519
|
var bannerObj;
|
|
520
|
+
var videoObj;
|
|
431
521
|
var nativeObj = {};
|
|
432
522
|
var mediaTypes = '';
|
|
433
523
|
|
|
@@ -459,6 +549,12 @@ function _createImpressionObject(bid, conf) {
|
|
|
459
549
|
_logWarn('Error: Error in Native adunit ' + bid.params.adUnit + '. Ignoring the adunit. Refer to ' + PREBID_NATIVE_HELP_LINK + ' for more details.');
|
|
460
550
|
}
|
|
461
551
|
break;
|
|
552
|
+
case VIDEO:
|
|
553
|
+
videoObj = _createVideoRequest(bid);
|
|
554
|
+
if (videoObj !== UNDEFINED) {
|
|
555
|
+
impObj.video = videoObj;
|
|
556
|
+
}
|
|
557
|
+
break;
|
|
462
558
|
}
|
|
463
559
|
}
|
|
464
560
|
} else {
|
|
@@ -468,7 +564,8 @@ function _createImpressionObject(bid, conf) {
|
|
|
468
564
|
_addFloorFromFloorModule(impObj, bid);
|
|
469
565
|
|
|
470
566
|
return impObj.hasOwnProperty(BANNER) ||
|
|
471
|
-
impObj.hasOwnProperty(NATIVE)
|
|
567
|
+
impObj.hasOwnProperty(NATIVE) ||
|
|
568
|
+
impObj.hasOwnProperty(VIDEO) ? impObj : UNDEFINED;
|
|
472
569
|
}
|
|
473
570
|
|
|
474
571
|
function _parseSlotParam(paramName, paramValue) {
|
|
@@ -492,7 +589,7 @@ function _parseSlotParam(paramName, paramValue) {
|
|
|
492
589
|
}
|
|
493
590
|
|
|
494
591
|
function _parseAdSlot(bid) {
|
|
495
|
-
_logInfo('parseAdSlot bid', bid)
|
|
592
|
+
_logInfo('parseAdSlot bid', bid);
|
|
496
593
|
if (bid.adUnitCode) {
|
|
497
594
|
bid.params.adUnit = bid.adUnitCode;
|
|
498
595
|
} else {
|
|
@@ -504,7 +601,7 @@ function _parseAdSlot(bid) {
|
|
|
504
601
|
|
|
505
602
|
if (bid.hasOwnProperty('mediaTypes')) {
|
|
506
603
|
if (bid.mediaTypes.hasOwnProperty(BANNER) &&
|
|
507
|
-
|
|
604
|
+
bid.mediaTypes.banner.hasOwnProperty('sizes')) { // if its a banner, has mediaTypes and sizes
|
|
508
605
|
var i = 0;
|
|
509
606
|
var sizeArray = [];
|
|
510
607
|
for (;i < bid.mediaTypes.banner.sizes.length; i++) {
|
|
@@ -522,7 +619,7 @@ function _parseAdSlot(bid) {
|
|
|
522
619
|
}
|
|
523
620
|
}
|
|
524
621
|
} else {
|
|
525
|
-
_logWarn('MediaTypes are Required for all Adunit Configs', bid)
|
|
622
|
+
_logWarn('MediaTypes are Required for all Adunit Configs', bid);
|
|
526
623
|
}
|
|
527
624
|
}
|
|
528
625
|
|
|
@@ -558,7 +655,7 @@ function _addFloorFromFloorModule(impObj, bid) {
|
|
|
558
655
|
|
|
559
656
|
// get lowest floor from floorModule
|
|
560
657
|
if (typeof bid.getFloor === 'function' && !config.getConfig('pubwise.disableFloors')) {
|
|
561
|
-
[BANNER, NATIVE].forEach(mediaType => {
|
|
658
|
+
[BANNER, VIDEO, NATIVE].forEach(mediaType => {
|
|
562
659
|
if (impObj.hasOwnProperty(mediaType)) {
|
|
563
660
|
let floorInfo = bid.getFloor({ currency: impObj.bidFloorCur, mediaType: mediaType, size: '*' });
|
|
564
661
|
if (typeof floorInfo === 'object' && floorInfo.currency === impObj.bidFloorCur && !isNaN(parseInt(floorInfo.floor))) {
|
|
@@ -746,28 +843,162 @@ function _createBannerRequest(bid) {
|
|
|
746
843
|
_logWarn('Error: mediaTypes.banner.size missing for adunit: ' + bid.params.adUnit + '. Ignoring the banner impression in the adunit.');
|
|
747
844
|
bannerObj = UNDEFINED;
|
|
748
845
|
}
|
|
846
|
+
|
|
749
847
|
return bannerObj;
|
|
750
848
|
}
|
|
751
849
|
|
|
752
850
|
// various error levels are not always used
|
|
753
851
|
// eslint-disable-next-line no-unused-vars
|
|
754
852
|
function _logMessage(textValue, objectValue) {
|
|
755
|
-
|
|
853
|
+
objectValue = objectValue || '';
|
|
854
|
+
logMessage(LOG_PREFIX + textValue, objectValue);
|
|
756
855
|
}
|
|
757
856
|
|
|
758
857
|
// eslint-disable-next-line no-unused-vars
|
|
759
858
|
function _logInfo(textValue, objectValue) {
|
|
760
|
-
|
|
859
|
+
objectValue = objectValue || '';
|
|
860
|
+
logInfo(LOG_PREFIX + textValue, objectValue);
|
|
761
861
|
}
|
|
762
862
|
|
|
763
863
|
// eslint-disable-next-line no-unused-vars
|
|
764
864
|
function _logWarn(textValue, objectValue) {
|
|
765
|
-
|
|
865
|
+
objectValue = objectValue || '';
|
|
866
|
+
logWarn(LOG_PREFIX + textValue, objectValue);
|
|
766
867
|
}
|
|
767
868
|
|
|
768
869
|
// eslint-disable-next-line no-unused-vars
|
|
769
870
|
function _logError(textValue, objectValue) {
|
|
770
|
-
|
|
871
|
+
objectValue = objectValue || '';
|
|
872
|
+
logError(LOG_PREFIX + textValue, objectValue);
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
function _checkVideoPlacement(videoData, adUnitCode) {
|
|
876
|
+
// Check for video.placement property. If property is missing display log message.
|
|
877
|
+
if (!deepAccess(videoData, 'placement')) {
|
|
878
|
+
_logWarn(`${MSG_VIDEO_PLACEMENT_MISSING} for ${adUnitCode}`, adUnitCode);
|
|
879
|
+
};
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
function _createVideoRequest(bid) {
|
|
883
|
+
var videoData = mergeDeep(deepAccess(bid.mediaTypes, 'video'), bid.params.video);
|
|
884
|
+
var videoObj;
|
|
885
|
+
|
|
886
|
+
if (videoData !== UNDEFINED) {
|
|
887
|
+
videoObj = {};
|
|
888
|
+
_checkVideoPlacement(videoData, bid.adUnitCode);
|
|
889
|
+
for (var key in VIDEO_CUSTOM_PARAMS) {
|
|
890
|
+
if (videoData.hasOwnProperty(key)) {
|
|
891
|
+
videoObj[key] = _checkParamDataType(key, videoData[key], VIDEO_CUSTOM_PARAMS[key]);
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
// read playersize and assign to h and w.
|
|
895
|
+
if (isArray(bid.mediaTypes.video.playerSize[0])) {
|
|
896
|
+
videoObj.w = parseInt(bid.mediaTypes.video.playerSize[0][0], 10);
|
|
897
|
+
videoObj.h = parseInt(bid.mediaTypes.video.playerSize[0][1], 10);
|
|
898
|
+
} else if (isNumber(bid.mediaTypes.video.playerSize[0])) {
|
|
899
|
+
videoObj.w = parseInt(bid.mediaTypes.video.playerSize[0], 10);
|
|
900
|
+
videoObj.h = parseInt(bid.mediaTypes.video.playerSize[1], 10);
|
|
901
|
+
}
|
|
902
|
+
} else {
|
|
903
|
+
videoObj = UNDEFINED;
|
|
904
|
+
_logWarn('Error: Video config params missing for adunit: ' + bid.params.adUnit + ' with mediaType set as video. Ignoring video impression in the adunit.', bid.params);
|
|
905
|
+
}
|
|
906
|
+
return videoObj;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
/**
|
|
910
|
+
* Determines if the array has values
|
|
911
|
+
*
|
|
912
|
+
* @param {object} test
|
|
913
|
+
* @returns {boolean}
|
|
914
|
+
*/
|
|
915
|
+
function _isNonEmptyArray(test) {
|
|
916
|
+
if (isArray(test) === true) {
|
|
917
|
+
if (test.length > 0) {
|
|
918
|
+
return true;
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
return false;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
/**
|
|
925
|
+
* Returns the overridden bid endpoint_url if it is set, primarily used for testing
|
|
926
|
+
*
|
|
927
|
+
* @param {object} bid the current bid
|
|
928
|
+
* @returns
|
|
929
|
+
*/
|
|
930
|
+
function _getEndpointURL(bid) {
|
|
931
|
+
if (!isEmptyStr(bid?.params?.endpoint_url) && bid?.params?.endpoint_url != UNDEFINED) {
|
|
932
|
+
return bid.params.endpoint_url;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
return ENDPOINT_URL;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
/**
|
|
939
|
+
*
|
|
940
|
+
* @param {object} key
|
|
941
|
+
* @param {object}} value
|
|
942
|
+
* @param {object} datatype
|
|
943
|
+
* @returns
|
|
944
|
+
*/
|
|
945
|
+
function _checkParamDataType(key, value, datatype) {
|
|
946
|
+
var errMsg = 'Ignoring param key: ' + key + ', expects ' + datatype + ', found ' + typeof value;
|
|
947
|
+
var functionToExecute;
|
|
948
|
+
switch (datatype) {
|
|
949
|
+
case DATA_TYPES.BOOLEAN:
|
|
950
|
+
functionToExecute = isBoolean;
|
|
951
|
+
break;
|
|
952
|
+
case DATA_TYPES.NUMBER:
|
|
953
|
+
functionToExecute = isNumber;
|
|
954
|
+
break;
|
|
955
|
+
case DATA_TYPES.STRING:
|
|
956
|
+
functionToExecute = isStr;
|
|
957
|
+
break;
|
|
958
|
+
case DATA_TYPES.ARRAY:
|
|
959
|
+
functionToExecute = isArray;
|
|
960
|
+
break;
|
|
961
|
+
}
|
|
962
|
+
if (functionToExecute(value)) {
|
|
963
|
+
return value;
|
|
964
|
+
}
|
|
965
|
+
_logWarn(errMsg, key);
|
|
966
|
+
return UNDEFINED;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
function _isMobile() {
|
|
970
|
+
if (navigator.userAgentData && navigator.userAgentData.mobile) {
|
|
971
|
+
return true;
|
|
972
|
+
} else {
|
|
973
|
+
return (/(mobi)/i).test(navigator.userAgent);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
function _isConnectedTV() {
|
|
978
|
+
return (/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(navigator.userAgent);
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
function _isTablet() {
|
|
982
|
+
return (/ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i.test(navigator.userAgent.toLowerCase()));
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
/**
|
|
986
|
+
* Very high level device detection, order matters
|
|
987
|
+
*/
|
|
988
|
+
function _getDeviceType() {
|
|
989
|
+
if (_isTablet()) {
|
|
990
|
+
return 5;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
if (_isMobile()) {
|
|
994
|
+
return 4;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
if (_isConnectedTV()) {
|
|
998
|
+
return 3;
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
return 2;
|
|
771
1002
|
}
|
|
772
1003
|
|
|
773
1004
|
// function _decorateLog() {
|
|
@@ -777,6 +1008,7 @@ function _logError(textValue, objectValue) {
|
|
|
777
1008
|
|
|
778
1009
|
// these are exported only for testing so maintaining the JS convention of _ to indicate the intent
|
|
779
1010
|
export {
|
|
1011
|
+
_checkVideoPlacement,
|
|
780
1012
|
_checkMediaType,
|
|
781
1013
|
_parseAdSlot
|
|
782
1014
|
}
|