prebid.js 8.45.0 → 8.46.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/33acrossAnalyticsAdapter.js +1 -1
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/33acrossIdSystem.js +1 -1
- package/dist/BTBidAdapter.js +1 -1
- package/dist/adagioAnalyticsAdapter.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/adnuntiusBidAdapter.js +1 -1
- package/dist/adqueryBidAdapter.js +1 -1
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adstirBidAdapter.js +1 -1
- package/dist/adtrgtmeBidAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/adyoulikeBidAdapter.js +1 -1
- package/dist/agmaAnalyticsAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/alkimiBidAdapter.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/bridBidAdapter.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/chunk-core.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/dependencies.json +12 -3
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/dxkultureBidAdapter.js +1 -1
- package/dist/engageyaBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/euidIdSystem.js +1 -1
- package/dist/feedadBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/freewheel-sspBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/greenbidsAnalyticsAdapter.js +1 -1
- package/dist/greenbidsRtdProvider.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/hypelabBidAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/illuminBidAdapter.js +1 -1
- package/dist/imdsBidAdapter.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/jixieBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/jwplayerBidAdapter.js +1 -0
- package/dist/kargoBidAdapter.js +1 -1
- package/dist/kimberliteBidAdapter.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/liveIntentIdSystem.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/luceadBidAdapter.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/not-for-prod/prebid.js +154 -152
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/openwebBidAdapter.js +1 -1
- package/dist/openxBidAdapter.js +1 -1
- package/dist/optableBidAdapter.js +1 -0
- package/dist/optidigitalBidAdapter.js +1 -1
- package/dist/ortbConverter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/publirBidAdapter.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/retailspotBidAdapter.js +1 -1
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseBidAdapter.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/shinezRtbBidAdapter.js +1 -1
- package/dist/sirdataRtdProvider.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/stnBidAdapter.js +1 -1
- package/dist/stroeerCoreBidAdapter.js +1 -1
- package/dist/stvBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/taboolaBidAdapter.js +1 -1
- package/dist/tagorasBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/themoneytizerBidAdapter.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/unrulyBidAdapter.js +1 -1
- package/dist/viantOrtbBidAdapter.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/yandexAnalyticsAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/integrationExamples/noadserver/jwplayerBidAdapter_sample.html +75 -0
- package/integrationExamples/realTimeData/jwplayerRtdProvider_example.html +7 -0
- package/integrationExamples/videoModule/jwplayer/bidMarkedAsUsed.html +7 -0
- package/integrationExamples/videoModule/jwplayer/bidRequestScheduling.html +9 -4
- package/integrationExamples/videoModule/jwplayer/bidsBackHandlerOverride.html +7 -0
- package/integrationExamples/videoModule/jwplayer/eventListeners.html +7 -0
- package/integrationExamples/videoModule/jwplayer/eventsUI.html +7 -0
- package/integrationExamples/videoModule/jwplayer/gamAdServerMediation.html +7 -0
- package/integrationExamples/videoModule/jwplayer/mediaMetadata.html +7 -0
- package/integrationExamples/videoModule/jwplayer/playlist.html +7 -0
- package/integrationExamples/videoModule/videojs/bidMarkedAsUsed.html +7 -0
- package/integrationExamples/videoModule/videojs/bidRequestScheduling.html +7 -0
- package/integrationExamples/videoModule/videojs/bidsBackHandlerOverride.html +7 -0
- package/integrationExamples/videoModule/videojs/eventListeners.html +7 -0
- package/integrationExamples/videoModule/videojs/eventsUI.html +7 -0
- package/integrationExamples/videoModule/videojs/gamAdServerMediation.html +7 -0
- package/integrationExamples/videoModule/videojs/mediaMetadata.html +7 -0
- package/integrationExamples/videoModule/videojs/playlist.html +7 -0
- package/libraries/ortbConverter/processors/banner.js +2 -2
- package/modules/adgenerationBidAdapter.js +6 -10
- package/modules/adnuntiusBidAdapter.js +5 -0
- package/modules/alkimiBidAdapter.js +48 -8
- package/modules/engageyaBidAdapter.js +1 -1
- package/modules/gumgumBidAdapter.js +1 -1
- package/modules/jwplayerBidAdapter.js +412 -0
- package/modules/jwplayerBidAdapter.md +72 -0
- package/modules/optableBidAdapter.js +42 -0
- package/modules/optableBidAdapter.md +41 -0
- package/modules/optidigitalBidAdapter.js +20 -4
- package/modules/pubmaticBidAdapter.js +21 -1
- package/modules/relaidoBidAdapter.js +70 -9
- package/modules/sirdataRtdProvider.js +33 -43
- package/modules/stroeerCoreBidAdapter.js +7 -5
- package/modules/viantOrtbBidAdapter.js +2 -0
- package/modules/yandexAnalyticsAdapter.js +6 -0
- package/package.json +1 -1
- package/src/utils.js +15 -2
- package/test/spec/modules/adgenerationBidAdapter_spec.js +6 -6
- package/test/spec/modules/adnuntiusBidAdapter_spec.js +18 -1
- package/test/spec/modules/alkimiBidAdapter_spec.js +11 -5
- package/test/spec/modules/gumgumBidAdapter_spec.js +1 -1
- package/test/spec/modules/jwplayerBidAdapter_spec.js +412 -0
- package/test/spec/modules/liveIntentIdSystem_spec.js +13 -15
- package/test/spec/modules/optableBidAdapter_spec.js +89 -0
- package/test/spec/modules/optidigitalBidAdapter_spec.js +34 -4
- package/test/spec/modules/pubmaticBidAdapter_spec.js +24 -1
- package/test/spec/modules/relaidoBidAdapter_spec.js +62 -0
- package/test/spec/modules/stroeerCoreBidAdapter_spec.js +21 -0
- package/test/spec/utils_spec.js +17 -1
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
2
2
|
import {deepAccess, deepClone, getDNT, generateUUID, replaceAuctionPrice} from '../src/utils.js';
|
|
3
3
|
import {ajax} from '../src/ajax.js';
|
|
4
|
+
import {getStorageManager} from '../src/storageManager.js';
|
|
4
5
|
import {VIDEO, BANNER} from '../src/mediaTypes.js';
|
|
5
6
|
import {config} from '../src/config.js';
|
|
6
7
|
|
|
7
8
|
const BIDDER_CODE = 'alkimi';
|
|
8
9
|
const GVLID = 1169;
|
|
10
|
+
const USER_ID_KEY = 'alkimiUserID';
|
|
9
11
|
export const ENDPOINT = 'https://exchange.alkimi-onboarding.com/bid?prebid=true';
|
|
12
|
+
export const storage = getStorageManager({bidderCode: BIDDER_CODE});
|
|
10
13
|
|
|
11
14
|
export const spec = {
|
|
12
15
|
code: BIDDER_CODE,
|
|
@@ -43,11 +46,16 @@ export const spec = {
|
|
|
43
46
|
bidIds.push(bidRequest.bidId)
|
|
44
47
|
})
|
|
45
48
|
|
|
49
|
+
const ortb2 = bidderRequest.ortb2
|
|
50
|
+
const site = ortb2?.site
|
|
51
|
+
|
|
52
|
+
const id = getUserId()
|
|
46
53
|
const alkimiConfig = config.getConfig('alkimi')
|
|
47
|
-
const
|
|
48
|
-
const source =
|
|
54
|
+
const fpa = ortb2?.source?.ext?.fpa
|
|
55
|
+
const source = fpa != undefined ? { ext: { fpa } } : undefined
|
|
49
56
|
const walletID = alkimiConfig && alkimiConfig.walletID
|
|
50
|
-
const
|
|
57
|
+
const userParams = alkimiConfig && alkimiConfig.userParams
|
|
58
|
+
const user = (walletID != undefined || userParams != undefined || id != undefined) ? { id, ext: { walletID, userParams } } : undefined
|
|
51
59
|
|
|
52
60
|
let payload = {
|
|
53
61
|
requestId: generateUUID(),
|
|
@@ -66,11 +74,14 @@ export const spec = {
|
|
|
66
74
|
source,
|
|
67
75
|
user,
|
|
68
76
|
site: {
|
|
69
|
-
keywords:
|
|
77
|
+
keywords: site?.keywords,
|
|
78
|
+
sectioncat: site?.sectioncat,
|
|
79
|
+
pagecat: site?.pagecat,
|
|
80
|
+
cat: site?.cat
|
|
70
81
|
},
|
|
71
|
-
at:
|
|
72
|
-
bcat:
|
|
73
|
-
wseat:
|
|
82
|
+
at: ortb2?.at,
|
|
83
|
+
bcat: ortb2?.bcat,
|
|
84
|
+
wseat: ortb2?.wseat
|
|
74
85
|
}
|
|
75
86
|
}
|
|
76
87
|
|
|
@@ -111,7 +122,7 @@ export const spec = {
|
|
|
111
122
|
}
|
|
112
123
|
|
|
113
124
|
const {prebidResponse} = serverBody;
|
|
114
|
-
if (!prebidResponse
|
|
125
|
+
if (!Array.isArray(prebidResponse)) {
|
|
115
126
|
return [];
|
|
116
127
|
}
|
|
117
128
|
|
|
@@ -141,6 +152,24 @@ export const spec = {
|
|
|
141
152
|
return true;
|
|
142
153
|
}
|
|
143
154
|
return false;
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
getUserSyncs: function(syncOptions, serverResponses, gdprConsent) {
|
|
158
|
+
if (syncOptions.iframeEnabled && serverResponses.length > 0) {
|
|
159
|
+
const serverBody = serverResponses[0].body;
|
|
160
|
+
if (!serverBody || typeof serverBody !== 'object') return [];
|
|
161
|
+
|
|
162
|
+
const { iframeList } = serverBody;
|
|
163
|
+
if (!Array.isArray(iframeList)) return [];
|
|
164
|
+
|
|
165
|
+
const urls = [];
|
|
166
|
+
iframeList.forEach(url => {
|
|
167
|
+
urls.push({type: 'iframe', url});
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
return urls;
|
|
171
|
+
}
|
|
172
|
+
return [];
|
|
144
173
|
}
|
|
145
174
|
}
|
|
146
175
|
|
|
@@ -175,4 +204,15 @@ const getFormatType = bidRequest => {
|
|
|
175
204
|
return formats
|
|
176
205
|
}
|
|
177
206
|
|
|
207
|
+
const getUserId = () => {
|
|
208
|
+
if (storage.localStorageIsEnabled()) {
|
|
209
|
+
let userId = storage.getDataFromLocalStorage(USER_ID_KEY)
|
|
210
|
+
if (!userId) {
|
|
211
|
+
userId = generateUUID()
|
|
212
|
+
storage.setDataInLocalStorage(USER_ID_KEY, userId)
|
|
213
|
+
}
|
|
214
|
+
return userId
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
178
218
|
registerBidder(spec);
|
|
@@ -81,7 +81,7 @@ function parseBannerResponse(rec, response) {
|
|
|
81
81
|
const title = rec.title && rec.title.trim() ? `<div class="eng_tag_ttl" style="display: none">${rec.title}</div>` : '';
|
|
82
82
|
const displayName = rec.displayName && title ? `<div class="eng_tag_brnd" style="display: none">${rec.displayName}</div>` : '';
|
|
83
83
|
const trackers = getImpressionTrackers(rec, response)
|
|
84
|
-
.map(createTrackPixelHtml)
|
|
84
|
+
.map((url) => createTrackPixelHtml(url))
|
|
85
85
|
.join('');
|
|
86
86
|
return `<html><body>${style}<div id="ENG_TAG"><a href="${rec.clickUrl}" target=_blank><img class="eng_tag_img" src="${getImageSrc(rec)}" style="width:${response.imageWidth}px;height:${response.imageHeight}px;" alt="${rec.title}"/>${displayName}${title}</a>${trackers}</div></body></html>`;
|
|
87
87
|
}
|
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
2
|
+
import { VIDEO } from '../src/mediaTypes.js';
|
|
3
|
+
import { isArray, isFn, deepAccess, deepSetValue, getDNT, logError, logWarn } from '../src/utils.js';
|
|
4
|
+
import { config } from '../src/config.js';
|
|
5
|
+
import { hasPurpose1Consent } from '../src/utils/gpdr.js';
|
|
6
|
+
|
|
7
|
+
const BIDDER_CODE = 'jwplayer';
|
|
8
|
+
const BASE_URL = 'https://vpb-server.jwplayer.com/';
|
|
9
|
+
const AUCTION_URL = BASE_URL + 'openrtb2/auction';
|
|
10
|
+
const USER_SYNC_URL = BASE_URL + 'setuid';
|
|
11
|
+
const GVLID = 1046;
|
|
12
|
+
const SUPPORTED_AD_TYPES = [VIDEO];
|
|
13
|
+
|
|
14
|
+
const VIDEO_ORTB_PARAMS = [
|
|
15
|
+
'pos',
|
|
16
|
+
'w',
|
|
17
|
+
'h',
|
|
18
|
+
'playbackend',
|
|
19
|
+
'mimes',
|
|
20
|
+
'minduration',
|
|
21
|
+
'maxduration',
|
|
22
|
+
'protocols',
|
|
23
|
+
'startdelay',
|
|
24
|
+
'placement',
|
|
25
|
+
'plcmt',
|
|
26
|
+
'skip',
|
|
27
|
+
'skipafter',
|
|
28
|
+
'minbitrate',
|
|
29
|
+
'maxbitrate',
|
|
30
|
+
'delivery',
|
|
31
|
+
'playbackmethod',
|
|
32
|
+
'api',
|
|
33
|
+
'linearity'
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
function getBidAdapter() {
|
|
37
|
+
function isBidRequestValid(bid) {
|
|
38
|
+
const params = bid && bid.params;
|
|
39
|
+
if (!params) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return !!params.placementId && !!params.publisherId && !!params.siteId;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function buildRequests(bidRequests, bidderRequest) {
|
|
47
|
+
if (!bidRequests) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!hasContentUrl(bidderRequest.ortb2)) {
|
|
52
|
+
logError(`${BIDDER_CODE}: cannot bid without a valid Content URL. Please populate ortb2.site.content.url`);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const warnings = getWarnings(bidderRequest);
|
|
57
|
+
warnings.forEach(warning => {
|
|
58
|
+
logWarn(`${BIDDER_CODE}: ${warning}`);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
return bidRequests.map(bidRequest => {
|
|
62
|
+
const payload = buildRequest(bidRequest, bidderRequest);
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
method: 'POST',
|
|
66
|
+
url: AUCTION_URL,
|
|
67
|
+
data: payload
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function interpretResponse(serverResponse) {
|
|
73
|
+
const outgoingBidResponses = [];
|
|
74
|
+
const serverResponseBody = serverResponse.body;
|
|
75
|
+
|
|
76
|
+
logResponseWarnings(serverResponseBody);
|
|
77
|
+
|
|
78
|
+
const seatBids = serverResponseBody && serverResponseBody.seatbid;
|
|
79
|
+
if (!isArray(seatBids)) {
|
|
80
|
+
return outgoingBidResponses;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const cur = serverResponseBody.cur;
|
|
84
|
+
|
|
85
|
+
seatBids.forEach(seatBid => {
|
|
86
|
+
seatBid.bid.forEach(bid => {
|
|
87
|
+
const bidResponse = {
|
|
88
|
+
requestId: serverResponseBody.id,
|
|
89
|
+
cpm: bid.price,
|
|
90
|
+
currency: cur,
|
|
91
|
+
width: bid.w,
|
|
92
|
+
height: bid.h,
|
|
93
|
+
ad: bid.adm,
|
|
94
|
+
vastXml: bid.adm,
|
|
95
|
+
ttl: bid.ttl || 3600,
|
|
96
|
+
netRevenue: false,
|
|
97
|
+
creativeId: bid.adid,
|
|
98
|
+
dealId: bid.dealid,
|
|
99
|
+
meta: {
|
|
100
|
+
advertiserDomains: bid.adomain,
|
|
101
|
+
mediaType: VIDEO,
|
|
102
|
+
primaryCatId: bid.cat,
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
outgoingBidResponses.push(bidResponse);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
return outgoingBidResponses;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent) {
|
|
114
|
+
if (!hasPurpose1Consent(gdprConsent)) {
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const userSyncs = [];
|
|
119
|
+
const consentQueryParams = getUserSyncConsentQueryParams(gdprConsent);
|
|
120
|
+
const url = `https://ib.adnxs.com/getuid?${USER_SYNC_URL}?bidder=jwplayer&uid=$UID&f=i` + consentQueryParams
|
|
121
|
+
|
|
122
|
+
if (syncOptions.iframeEnabled) {
|
|
123
|
+
userSyncs.push({
|
|
124
|
+
type: 'iframe',
|
|
125
|
+
url
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (syncOptions.pixelEnabled) {
|
|
130
|
+
userSyncs.push({
|
|
131
|
+
type: 'image',
|
|
132
|
+
url
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return userSyncs;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
code: BIDDER_CODE,
|
|
141
|
+
gvlid: GVLID,
|
|
142
|
+
supportedMediaTypes: SUPPORTED_AD_TYPES,
|
|
143
|
+
isBidRequestValid,
|
|
144
|
+
buildRequests,
|
|
145
|
+
interpretResponse,
|
|
146
|
+
getUserSyncs
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function getUserSyncConsentQueryParams(gdprConsent) {
|
|
150
|
+
if (!gdprConsent) {
|
|
151
|
+
return '';
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const consentString = gdprConsent.consentString;
|
|
155
|
+
if (!consentString) {
|
|
156
|
+
return '';
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
let gdpr = 0;
|
|
160
|
+
const gdprApplies = gdprConsent.gdprApplies;
|
|
161
|
+
if (typeof gdprApplies === 'boolean') {
|
|
162
|
+
gdpr = Number(gdprApplies)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return `&gdpr=${gdpr}&gdpr_consent=${consentString}`;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function buildRequest(bidRequest, bidderRequest) {
|
|
169
|
+
const openrtbRequest = {
|
|
170
|
+
id: bidRequest.bidId,
|
|
171
|
+
imp: getRequestImpressions(bidRequest, bidderRequest),
|
|
172
|
+
site: getRequestSite(bidRequest, bidderRequest),
|
|
173
|
+
device: getRequestDevice(bidderRequest.ortb2),
|
|
174
|
+
user: getRequestUser(bidderRequest.ortb2),
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
// GDPR Consent Params
|
|
178
|
+
if (bidderRequest.gdprConsent) {
|
|
179
|
+
deepSetValue(openrtbRequest, 'user.ext.consent', bidderRequest.gdprConsent.consentString);
|
|
180
|
+
deepSetValue(openrtbRequest, 'regs.ext.gdpr', (bidderRequest.gdprConsent.gdprApplies ? 1 : 0));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// CCPA
|
|
184
|
+
if (bidderRequest.uspConsent) {
|
|
185
|
+
deepSetValue(openrtbRequest, 'regs.ext.us_privacy', bidderRequest.uspConsent);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (bidRequest.schain) {
|
|
189
|
+
deepSetValue(openrtbRequest, 'source.schain', bidRequest.schain);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
openrtbRequest.tmax = bidderRequest.timeout || 200;
|
|
193
|
+
|
|
194
|
+
return JSON.stringify(openrtbRequest);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function getRequestImpressions(bidRequest) {
|
|
198
|
+
const impressionObject = {
|
|
199
|
+
id: bidRequest.adUnitCode,
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
impressionObject.video = getImpressionVideo(bidRequest);
|
|
203
|
+
|
|
204
|
+
const bidFloorData = getBidFloorData(bidRequest);
|
|
205
|
+
if (bidFloorData) {
|
|
206
|
+
impressionObject.bidfloor = bidFloorData.floor;
|
|
207
|
+
impressionObject.bidfloorcur = bidFloorData.currency;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
impressionObject.ext = getImpressionExtension(bidRequest);
|
|
211
|
+
|
|
212
|
+
return [impressionObject];
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function getImpressionVideo(bidRequest) {
|
|
216
|
+
const videoParams = deepAccess(bidRequest, 'mediaTypes.video', {});
|
|
217
|
+
|
|
218
|
+
const video = {};
|
|
219
|
+
|
|
220
|
+
VIDEO_ORTB_PARAMS.forEach((param) => {
|
|
221
|
+
if (videoParams.hasOwnProperty(param)) {
|
|
222
|
+
video[param] = videoParams[param];
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
setPlayerSize(video, videoParams);
|
|
227
|
+
|
|
228
|
+
if (!videoParams.plcmt) {
|
|
229
|
+
logWarn(`${BIDDER_CODE}: Please set a value to mediaTypes.video.plcmt`);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return video;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function getImpressionExtension(bidRequest) {
|
|
236
|
+
return {
|
|
237
|
+
prebid: {
|
|
238
|
+
bidder: {
|
|
239
|
+
jwplayer: {
|
|
240
|
+
placementId: bidRequest.params.placementId
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function setPlayerSize(videoImp, videoParams) {
|
|
248
|
+
if (videoImp.w !== undefined && videoImp.h !== undefined) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const playerSize = getNormalizedPlayerSize(videoParams.playerSize);
|
|
253
|
+
if (!playerSize.length) {
|
|
254
|
+
logWarn(logWarn(`${BIDDER_CODE}: Video size has not been set. Please set values in video.h and video.w`));
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (videoImp.w === undefined) {
|
|
259
|
+
videoImp.w = playerSize[0];
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (videoImp.h === undefined) {
|
|
263
|
+
videoImp.h = playerSize[1];
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function getNormalizedPlayerSize(playerSize) {
|
|
268
|
+
if (!Array.isArray(playerSize)) {
|
|
269
|
+
return [];
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (Array.isArray(playerSize[0])) {
|
|
273
|
+
playerSize = playerSize[0];
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (playerSize.length < 2) {
|
|
277
|
+
return [];
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
return playerSize;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function getBidFloorData(bidRequest) {
|
|
284
|
+
const { params } = bidRequest;
|
|
285
|
+
const currency = params.currency || 'USD';
|
|
286
|
+
|
|
287
|
+
let floorData;
|
|
288
|
+
if (isFn(bidRequest.getFloor)) {
|
|
289
|
+
const bidFloorRequest = {
|
|
290
|
+
currency: currency,
|
|
291
|
+
mediaType: VIDEO,
|
|
292
|
+
size: '*'
|
|
293
|
+
};
|
|
294
|
+
floorData = bidRequest.getFloor(bidFloorRequest);
|
|
295
|
+
} else if (params.bidFloor) {
|
|
296
|
+
floorData = { floor: params.bidFloor, currency: currency };
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
return floorData;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function getRequestSite(bidRequest, bidderRequest) {
|
|
303
|
+
const site = bidderRequest.ortb2.site || {};
|
|
304
|
+
|
|
305
|
+
site.domain = site.domain || config.publisherDomain || window.location.hostname;
|
|
306
|
+
site.page = site.page || config.pageUrl || window.location.href;
|
|
307
|
+
|
|
308
|
+
const referer = bidderRequest.refererInfo && bidderRequest.refererInfo.referer;
|
|
309
|
+
if (!site.ref && referer) {
|
|
310
|
+
site.ref = referer;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const jwplayerPublisherExtChain = 'publisher.ext.jwplayer.';
|
|
314
|
+
|
|
315
|
+
deepSetValue(site, jwplayerPublisherExtChain + 'publisherId', bidRequest.params.publisherId);
|
|
316
|
+
deepSetValue(site, jwplayerPublisherExtChain + 'siteId', bidRequest.params.siteId);
|
|
317
|
+
|
|
318
|
+
return site;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function getRequestDevice(ortb2) {
|
|
322
|
+
const device = Object.assign({
|
|
323
|
+
h: screen.height,
|
|
324
|
+
w: screen.width,
|
|
325
|
+
ua: navigator.userAgent,
|
|
326
|
+
dnt: getDNT() ? 1 : 0,
|
|
327
|
+
js: 1
|
|
328
|
+
}, ortb2.device || {})
|
|
329
|
+
|
|
330
|
+
const language = getLanguage();
|
|
331
|
+
if (!device.language && language) {
|
|
332
|
+
device.language = language;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
return device;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function getLanguage() {
|
|
339
|
+
const navigatorLanguage = navigator.language;
|
|
340
|
+
if (!navigatorLanguage) {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const languageCodeSegments = navigatorLanguage.split('-');
|
|
345
|
+
if (!languageCodeSegments.length) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
return languageCodeSegments[0];
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function getRequestUser(ortb2) {
|
|
353
|
+
const user = ortb2.user || {};
|
|
354
|
+
if (config.getConfig('coppa') === true) {
|
|
355
|
+
user.coppa = true;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
return user;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function hasContentUrl(ortb2) {
|
|
362
|
+
const site = ortb2.site;
|
|
363
|
+
const content = site && site.content;
|
|
364
|
+
return !!(content && content.url);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function getWarnings(bidderRequest) {
|
|
368
|
+
const content = bidderRequest.ortb2.site.content;
|
|
369
|
+
const contentChain = 'ortb2.site.content.';
|
|
370
|
+
const warnings = [];
|
|
371
|
+
if (!content.id) {
|
|
372
|
+
warnings.push(getMissingFieldMessage(contentChain + 'id'));
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (!content.title) {
|
|
376
|
+
warnings.push(getMissingFieldMessage(contentChain + 'title'));
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (!content.ext || !content.ext.description) {
|
|
380
|
+
warnings.push(getMissingFieldMessage(contentChain + 'ext.description'));
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
return warnings;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function getMissingFieldMessage(fieldName) {
|
|
387
|
+
return `Optional field ${fieldName} is not populated; we recommend populating for maximum performance.`
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function logResponseWarnings(serverResponseBody) {
|
|
391
|
+
const warningPayload = deepAccess(serverResponseBody, 'ext.warnings');
|
|
392
|
+
if (!warningPayload) {
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const warningCategories = Object.keys(warningPayload);
|
|
397
|
+
warningCategories.forEach(category => {
|
|
398
|
+
const warnings = warningPayload[category];
|
|
399
|
+
if (!isArray(warnings)) {
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
warnings.forEach(warning => {
|
|
404
|
+
logWarn(`${BIDDER_CODE}: [Bid Response][Warning Code: ${warning.code}] ${warning.message}`);
|
|
405
|
+
});
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
export const spec = getBidAdapter();
|
|
411
|
+
|
|
412
|
+
registerBidder(spec);
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
Module Name: JWPlayer Bid Adapter
|
|
5
|
+
Module Type: Bidder Adapter
|
|
6
|
+
Maintainer: boost-engineering@jwplayer.com
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
# Description
|
|
10
|
+
|
|
11
|
+
Connects to JWPlayer's demand sources.
|
|
12
|
+
|
|
13
|
+
JWPlayer bid adapter supports Video (instream and outstream).
|
|
14
|
+
|
|
15
|
+
# Sample Ad Unit
|
|
16
|
+
|
|
17
|
+
```markdown
|
|
18
|
+
const adUnit = {
|
|
19
|
+
code: 'test-ad-unit',
|
|
20
|
+
mediaTypes: {
|
|
21
|
+
video: {
|
|
22
|
+
pos: 0,
|
|
23
|
+
w: 640,
|
|
24
|
+
h: 480,
|
|
25
|
+
mimes : ['video/x-ms-wmv', 'video/mp4'],
|
|
26
|
+
minduration : 0,
|
|
27
|
+
maxduration: 60,
|
|
28
|
+
protocols : [2,3,7,5,6,8],
|
|
29
|
+
startdelay: 0,
|
|
30
|
+
placement: 1,
|
|
31
|
+
plcmt: 1,
|
|
32
|
+
skip: 1,
|
|
33
|
+
skipafter: 10,
|
|
34
|
+
playbackmethod: [3],
|
|
35
|
+
api: [2],
|
|
36
|
+
linearity: 1
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
bids: [{
|
|
40
|
+
bidder: 'jwplayer',
|
|
41
|
+
params: {
|
|
42
|
+
publisherId: 'test-publisher-id',
|
|
43
|
+
siteId: 'test-site-id',
|
|
44
|
+
placementId: 'test-placement-id'
|
|
45
|
+
}
|
|
46
|
+
}]
|
|
47
|
+
};
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
# Sample ortb2 config
|
|
51
|
+
|
|
52
|
+
```markdown
|
|
53
|
+
pbjs.setConfig({
|
|
54
|
+
ortb2: {
|
|
55
|
+
site: {
|
|
56
|
+
publisher: {
|
|
57
|
+
id: 'test-publisher-id'
|
|
58
|
+
},
|
|
59
|
+
content: {
|
|
60
|
+
id: 'test-media-id',
|
|
61
|
+
url: 'test.mp4',
|
|
62
|
+
title: 'title of my media',
|
|
63
|
+
ext: {
|
|
64
|
+
description: 'description of my media'
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
domain: 'test-domain.com',
|
|
68
|
+
page: 'https://www.test-domain.com/test.html',
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as utils from '../src/utils.js';
|
|
2
|
+
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
3
|
+
import { config } from '../src/config.js';
|
|
4
|
+
import { BANNER } from '../src/mediaTypes.js';
|
|
5
|
+
import { ortbConverter } from '../libraries/ortbConverter/converter.js'
|
|
6
|
+
const converter = ortbConverter({
|
|
7
|
+
context: { netRevenue: true, ttl: 300 },
|
|
8
|
+
imp(buildImp, bidRequest, context) {
|
|
9
|
+
const imp = buildImp(bidRequest, context);
|
|
10
|
+
utils.mergeDeep(imp, {
|
|
11
|
+
tagid: bidRequest.params.site,
|
|
12
|
+
});
|
|
13
|
+
return imp;
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
const BIDDER_CODE = 'optable';
|
|
17
|
+
const DEFAULT_REGION = 'ca'
|
|
18
|
+
const DEFAULT_ORIGIN = 'https://ads.optable.co'
|
|
19
|
+
|
|
20
|
+
export const spec = {
|
|
21
|
+
code: BIDDER_CODE,
|
|
22
|
+
isBidRequestValid: function(bid) { return !!bid.params?.site },
|
|
23
|
+
buildRequests: function(bidRequests, bidderRequest) {
|
|
24
|
+
const region = config.getConfig('optable.region') ?? DEFAULT_REGION
|
|
25
|
+
const origin = config.getConfig('optable.origin') ?? DEFAULT_ORIGIN
|
|
26
|
+
const requestURL = `${origin}/${region}/ortb2/v1/ssp/bid`
|
|
27
|
+
const data = converter.toORTB({ bidRequests, bidderRequest, context: { mediaType: BANNER } });
|
|
28
|
+
|
|
29
|
+
return { method: 'POST', url: requestURL, data }
|
|
30
|
+
},
|
|
31
|
+
interpretResponse: function(response, request) {
|
|
32
|
+
const bids = converter.fromORTB({ response: response.body, request: request.data }).bids
|
|
33
|
+
const auctionConfigs = (response.body.ext?.optable?.fledge?.auctionconfigs ?? []).map((cfg) => {
|
|
34
|
+
const { impid, ...config } = cfg;
|
|
35
|
+
return { bidId: impid, config }
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
return { bids, fledgeAuctionConfigs: auctionConfigs }
|
|
39
|
+
},
|
|
40
|
+
supportedMediaTypes: [BANNER]
|
|
41
|
+
}
|
|
42
|
+
registerBidder(spec);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
Module Name: Optable Bidder Adapter
|
|
5
|
+
Module Type: Bidder Adapter
|
|
6
|
+
Maintainer: prebid@optable.co
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
# Description
|
|
10
|
+
|
|
11
|
+
Module that connects to Optable's demand sources.
|
|
12
|
+
|
|
13
|
+
# Bid Parameters
|
|
14
|
+
## Banner
|
|
15
|
+
|
|
16
|
+
| Name | Scope | Type | Description | Example
|
|
17
|
+
| ---- | ----- | ---- | ----------- | -------
|
|
18
|
+
| `site` | required | String | Optable site ID provided by your Optable representative. | "aaaaaaaa"
|
|
19
|
+
|
|
20
|
+
## Video
|
|
21
|
+
|
|
22
|
+
Not supported at the moment.
|
|
23
|
+
|
|
24
|
+
# Example
|
|
25
|
+
```javascript
|
|
26
|
+
var adUnits = [
|
|
27
|
+
{
|
|
28
|
+
code: 'test-div',
|
|
29
|
+
sizes: [[728, 90]], // a display size
|
|
30
|
+
mediaTypes: {'banner': {}},
|
|
31
|
+
bids: [
|
|
32
|
+
{
|
|
33
|
+
bidder: 'optable',
|
|
34
|
+
params: {
|
|
35
|
+
site: 'aaaaaaaa',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
```
|