prebid.js 6.0.0 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc.js +1 -7
- package/gulpfile.js +1 -0
- package/modules/adheseBidAdapter.js +7 -2
- package/modules/adkernelBidAdapter.js +1 -0
- package/modules/adlivetechBidAdapter.md +61 -0
- package/modules/adomikAnalyticsAdapter.js +10 -4
- package/modules/appnexusBidAdapter.js +4 -0
- package/modules/codefuelBidAdapter.js +1 -3
- package/modules/codefuelBidAdapter.md +3 -3
- package/modules/datablocksBidAdapter.js +3 -3
- package/modules/deepintentBidAdapter.js +1 -1
- package/modules/engageyaBidAdapter.js +68 -54
- package/modules/glimpseBidAdapter.js +31 -16
- package/modules/gptPreAuction.js +11 -5
- package/modules/gridBidAdapter.js +1 -1
- package/modules/id5IdSystem.md +6 -6
- package/modules/imRtdProvider.js +31 -0
- package/modules/ixBidAdapter.js +166 -21
- package/modules/merkleIdSystem.js +5 -0
- package/modules/nativoBidAdapter.js +27 -1
- package/modules/oguryBidAdapter.js +2 -1
- package/modules/openxBidAdapter.js +6 -1
- package/modules/prebidServerBidAdapter/index.js +3 -3
- package/modules/pubmaticBidAdapter.js +2 -0
- package/modules/saambaaBidAdapter.js +420 -0
- package/modules/saambaaBidAdapter.md +65 -68
- package/modules/seedtagBidAdapter.js +6 -0
- package/modules/smaatoBidAdapter.js +6 -1
- package/modules/sspBCBidAdapter.js +34 -3
- package/modules/trustxBidAdapter.js +10 -1
- package/modules/vidoomyBidAdapter.js +51 -100
- package/modules/visxBidAdapter.js +1 -1
- package/modules/yieldlabBidAdapter.js +41 -10
- package/modules/yieldlabBidAdapter.md +91 -48
- package/package.json +6 -1
- package/src/adapterManager.js +14 -8
- package/test/spec/modules/adheseBidAdapter_spec.js +27 -1
- package/test/spec/modules/adomikAnalyticsAdapter_spec.js +3 -1
- package/test/spec/modules/appnexusBidAdapter_spec.js +14 -0
- package/test/spec/modules/codefuelBidAdapter_spec.js +1 -1
- package/test/spec/modules/datablocksBidAdapter_spec.js +3 -3
- package/test/spec/modules/engageyaBidAdapter_spec.js +231 -95
- package/test/spec/modules/eplanningBidAdapter_spec.js +8 -8
- package/test/spec/modules/glimpseBidAdapter_spec.js +33 -0
- package/test/spec/modules/gptPreAuction_spec.js +58 -4
- package/test/spec/modules/imRtdProvider_spec.js +25 -0
- package/test/spec/modules/ixBidAdapter_spec.js +285 -2
- package/test/spec/modules/konduitWrapper_spec.js +0 -1
- package/test/spec/modules/merkleIdSystem_spec.js +18 -0
- package/test/spec/modules/nativoBidAdapter_spec.js +35 -18
- package/test/spec/modules/oguryBidAdapter_spec.js +13 -11
- package/test/spec/modules/openxBidAdapter_spec.js +5 -0
- package/test/spec/modules/prebidServerBidAdapter_spec.js +19 -2
- package/test/spec/modules/seedtagBidAdapter_spec.js +3 -0
- package/test/spec/modules/smaatoBidAdapter_spec.js +30 -0
- package/test/spec/modules/sspBCBidAdapter_spec.js +33 -3
- package/test/spec/modules/trustxBidAdapter_spec.js +42 -0
- package/test/spec/modules/vidoomyBidAdapter_spec.js +32 -13
- package/test/spec/modules/visxBidAdapter_spec.js +1 -1
- package/test/spec/modules/yieldlabBidAdapter_spec.js +81 -0
- package/test/spec/unit/core/adapterManager_spec.js +24 -6
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
import { deepAccess, isFn, generateUUID, parseUrl, isEmpty, parseSizesInput } from '../src/utils.js';
|
|
2
|
+
import { config } from '../src/config.js';
|
|
3
|
+
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
4
|
+
import { VIDEO, BANNER } from '../src/mediaTypes.js';
|
|
5
|
+
import find from 'core-js-pure/features/array/find.js';
|
|
6
|
+
import includes from 'core-js-pure/features/array/includes.js';
|
|
7
|
+
|
|
8
|
+
const ADAPTER_VERSION = '1.0';
|
|
9
|
+
const BIDDER_CODE = 'saambaa';
|
|
10
|
+
|
|
11
|
+
export const VIDEO_ENDPOINT = 'https://nep.advangelists.com/xp/get?pubid=';
|
|
12
|
+
export const BANNER_ENDPOINT = 'https://nep.advangelists.com/xp/get?pubid=';
|
|
13
|
+
export const OUTSTREAM_SRC = 'https://player-cdn.beachfrontmedia.com/playerapi/loader/outstream.js';
|
|
14
|
+
export const VIDEO_TARGETING = ['mimes', 'playbackmethod', 'maxduration', 'skip', 'playerSize', 'context'];
|
|
15
|
+
export const DEFAULT_MIMES = ['video/mp4', 'application/javascript'];
|
|
16
|
+
|
|
17
|
+
let pubid = '';
|
|
18
|
+
|
|
19
|
+
export const spec = {
|
|
20
|
+
code: BIDDER_CODE,
|
|
21
|
+
supportedMediaTypes: [BANNER, VIDEO],
|
|
22
|
+
|
|
23
|
+
isBidRequestValid(bidRequest) {
|
|
24
|
+
if (typeof bidRequest != 'undefined') {
|
|
25
|
+
if (bidRequest.bidder !== BIDDER_CODE && typeof bidRequest.params === 'undefined') { return false; }
|
|
26
|
+
if (bidRequest === '' || bidRequest.params.placement === '' || bidRequest.params.pubid === '') { return false; }
|
|
27
|
+
return true;
|
|
28
|
+
} else { return false; }
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
buildRequests(bids, bidderRequest) {
|
|
32
|
+
let requests = [];
|
|
33
|
+
let videoBids = bids.filter(bid => isVideoBidValid(bid));
|
|
34
|
+
let bannerBids = bids.filter(bid => isBannerBidValid(bid));
|
|
35
|
+
videoBids.forEach(bid => {
|
|
36
|
+
pubid = getVideoBidParam(bid, 'pubid');
|
|
37
|
+
requests.push({
|
|
38
|
+
method: 'POST',
|
|
39
|
+
url: VIDEO_ENDPOINT + pubid,
|
|
40
|
+
data: createVideoRequestData(bid, bidderRequest),
|
|
41
|
+
bidRequest: bid
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
bannerBids.forEach(bid => {
|
|
46
|
+
pubid = getBannerBidParam(bid, 'pubid');
|
|
47
|
+
|
|
48
|
+
requests.push({
|
|
49
|
+
method: 'POST',
|
|
50
|
+
url: BANNER_ENDPOINT + pubid,
|
|
51
|
+
data: createBannerRequestData(bid, bidderRequest),
|
|
52
|
+
bidRequest: bid
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
return requests;
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
interpretResponse(serverResponse, {bidRequest}) {
|
|
59
|
+
let response = serverResponse.body;
|
|
60
|
+
if (response !== null && isEmpty(response) == false) {
|
|
61
|
+
if (isVideoBid(bidRequest)) {
|
|
62
|
+
let bidResponse = {
|
|
63
|
+
requestId: response.id,
|
|
64
|
+
bidderCode: BIDDER_CODE,
|
|
65
|
+
cpm: response.seatbid[0].bid[0].price,
|
|
66
|
+
width: response.seatbid[0].bid[0].w,
|
|
67
|
+
height: response.seatbid[0].bid[0].h,
|
|
68
|
+
ttl: response.seatbid[0].bid[0].ttl || 60,
|
|
69
|
+
creativeId: response.seatbid[0].bid[0].crid,
|
|
70
|
+
currency: response.cur,
|
|
71
|
+
meta: { 'advertiserDomains': response.seatbid[0].bid[0].adomain },
|
|
72
|
+
mediaType: VIDEO,
|
|
73
|
+
netRevenue: true
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (response.seatbid[0].bid[0].adm) {
|
|
77
|
+
bidResponse.vastXml = response.seatbid[0].bid[0].adm;
|
|
78
|
+
bidResponse.adResponse = {
|
|
79
|
+
content: response.seatbid[0].bid[0].adm
|
|
80
|
+
};
|
|
81
|
+
} else {
|
|
82
|
+
bidResponse.vastUrl = response.seatbid[0].bid[0].nurl;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return bidResponse;
|
|
86
|
+
} else {
|
|
87
|
+
return {
|
|
88
|
+
requestId: response.id,
|
|
89
|
+
bidderCode: BIDDER_CODE,
|
|
90
|
+
cpm: response.seatbid[0].bid[0].price,
|
|
91
|
+
width: response.seatbid[0].bid[0].w,
|
|
92
|
+
height: response.seatbid[0].bid[0].h,
|
|
93
|
+
ad: response.seatbid[0].bid[0].adm,
|
|
94
|
+
ttl: response.seatbid[0].bid[0].ttl || 60,
|
|
95
|
+
creativeId: response.seatbid[0].bid[0].crid,
|
|
96
|
+
currency: response.cur,
|
|
97
|
+
meta: { 'advertiserDomains': response.seatbid[0].bid[0].adomain },
|
|
98
|
+
mediaType: BANNER,
|
|
99
|
+
netRevenue: true
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
function isBannerBid(bid) {
|
|
107
|
+
return deepAccess(bid, 'mediaTypes.banner') || !isVideoBid(bid);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function isVideoBid(bid) {
|
|
111
|
+
return deepAccess(bid, 'mediaTypes.video');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function getBannerBidFloor(bid) {
|
|
115
|
+
let floorInfo = isFn(bid.getFloor) ? bid.getFloor({ currency: 'USD', mediaType: 'banner', size: '*' }) : {};
|
|
116
|
+
return floorInfo.floor || getBannerBidParam(bid, 'bidfloor');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function getVideoBidFloor(bid) {
|
|
120
|
+
let floorInfo = isFn(bid.getFloor) ? bid.getFloor({ currency: 'USD', mediaType: 'video', size: '*' }) : {};
|
|
121
|
+
return floorInfo.floor || getVideoBidParam(bid, 'bidfloor');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function isVideoBidValid(bid) {
|
|
125
|
+
return isVideoBid(bid) && getVideoBidParam(bid, 'pubid') && getVideoBidParam(bid, 'placement');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function isBannerBidValid(bid) {
|
|
129
|
+
return isBannerBid(bid) && getBannerBidParam(bid, 'pubid') && getBannerBidParam(bid, 'placement');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function getVideoBidParam(bid, key) {
|
|
133
|
+
return deepAccess(bid, 'params.video.' + key) || deepAccess(bid, 'params.' + key);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function getBannerBidParam(bid, key) {
|
|
137
|
+
return deepAccess(bid, 'params.banner.' + key) || deepAccess(bid, 'params.' + key);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function isMobile() {
|
|
141
|
+
return (/(ios|ipod|ipad|iphone|android)/i).test(navigator.userAgent);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function isConnectedTV() {
|
|
145
|
+
return (/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(navigator.userAgent);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function getDoNotTrack() {
|
|
149
|
+
return navigator.doNotTrack === '1' || window.doNotTrack === '1' || navigator.msDoNoTrack === '1' || navigator.doNotTrack === 'yes';
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function findAndFillParam(o, key, value) {
|
|
153
|
+
try {
|
|
154
|
+
if (typeof value === 'function') {
|
|
155
|
+
o[key] = value();
|
|
156
|
+
} else {
|
|
157
|
+
o[key] = value;
|
|
158
|
+
}
|
|
159
|
+
} catch (ex) {}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function getOsVersion() {
|
|
163
|
+
let clientStrings = [
|
|
164
|
+
{ s: 'Android', r: /Android/ },
|
|
165
|
+
{ s: 'iOS', r: /(iPhone|iPad|iPod)/ },
|
|
166
|
+
{ s: 'Mac OS X', r: /Mac OS X/ },
|
|
167
|
+
{ s: 'Mac OS', r: /(MacPPC|MacIntel|Mac_PowerPC|Macintosh)/ },
|
|
168
|
+
{ s: 'Linux', r: /(Linux|X11)/ },
|
|
169
|
+
{ s: 'Windows 10', r: /(Windows 10.0|Windows NT 10.0)/ },
|
|
170
|
+
{ s: 'Windows 8.1', r: /(Windows 8.1|Windows NT 6.3)/ },
|
|
171
|
+
{ s: 'Windows 8', r: /(Windows 8|Windows NT 6.2)/ },
|
|
172
|
+
{ s: 'Windows 7', r: /(Windows 7|Windows NT 6.1)/ },
|
|
173
|
+
{ s: 'Windows Vista', r: /Windows NT 6.0/ },
|
|
174
|
+
{ s: 'Windows Server 2003', r: /Windows NT 5.2/ },
|
|
175
|
+
{ s: 'Windows XP', r: /(Windows NT 5.1|Windows XP)/ },
|
|
176
|
+
{ s: 'UNIX', r: /UNIX/ },
|
|
177
|
+
{ s: 'Search Bot', r: /(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/ }
|
|
178
|
+
];
|
|
179
|
+
let cs = find(clientStrings, cs => cs.r.test(navigator.userAgent));
|
|
180
|
+
return cs ? cs.s : 'unknown';
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function getFirstSize(sizes) {
|
|
184
|
+
return (sizes && sizes.length) ? sizes[0] : { w: undefined, h: undefined };
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function parseSizes(sizes) {
|
|
188
|
+
return parseSizesInput(sizes).map(size => {
|
|
189
|
+
let [ width, height ] = size.split('x');
|
|
190
|
+
return {
|
|
191
|
+
w: parseInt(width, 10) || undefined,
|
|
192
|
+
h: parseInt(height, 10) || undefined
|
|
193
|
+
};
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function getVideoSizes(bid) {
|
|
198
|
+
return parseSizes(deepAccess(bid, 'mediaTypes.video.playerSize') || bid.sizes);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function getBannerSizes(bid) {
|
|
202
|
+
return parseSizes(deepAccess(bid, 'mediaTypes.banner.sizes') || bid.sizes);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function getTopWindowReferrer() {
|
|
206
|
+
try {
|
|
207
|
+
return window.top.document.referrer;
|
|
208
|
+
} catch (e) {
|
|
209
|
+
return '';
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function getVideoTargetingParams(bid) {
|
|
214
|
+
const result = {};
|
|
215
|
+
const excludeProps = ['playerSize', 'context', 'w', 'h'];
|
|
216
|
+
Object.keys(Object(bid.mediaTypes.video))
|
|
217
|
+
.filter(key => !includes(excludeProps, key))
|
|
218
|
+
.forEach(key => {
|
|
219
|
+
result[ key ] = bid.mediaTypes.video[ key ];
|
|
220
|
+
});
|
|
221
|
+
Object.keys(Object(bid.params.video))
|
|
222
|
+
.filter(key => includes(VIDEO_TARGETING, key))
|
|
223
|
+
.forEach(key => {
|
|
224
|
+
result[ key ] = bid.params.video[ key ];
|
|
225
|
+
});
|
|
226
|
+
return result;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function createVideoRequestData(bid, bidderRequest) {
|
|
230
|
+
let topLocation = getTopWindowLocation(bidderRequest);
|
|
231
|
+
let topReferrer = getTopWindowReferrer();
|
|
232
|
+
|
|
233
|
+
// if size is explicitly given via adapter params
|
|
234
|
+
let paramSize = getVideoBidParam(bid, 'size');
|
|
235
|
+
let sizes = [];
|
|
236
|
+
let coppa = config.getConfig('coppa');
|
|
237
|
+
|
|
238
|
+
if (typeof paramSize !== 'undefined' && paramSize != '') {
|
|
239
|
+
sizes = parseSizes(paramSize);
|
|
240
|
+
} else {
|
|
241
|
+
sizes = getVideoSizes(bid);
|
|
242
|
+
}
|
|
243
|
+
const firstSize = getFirstSize(sizes);
|
|
244
|
+
let floor = (getVideoBidFloor(bid) == null || typeof getVideoBidFloor(bid) == 'undefined') ? 0.5 : getVideoBidFloor(bid);
|
|
245
|
+
let video = getVideoTargetingParams(bid);
|
|
246
|
+
const o = {
|
|
247
|
+
'device': {
|
|
248
|
+
'langauge': (global.navigator.language).split('-')[0],
|
|
249
|
+
'dnt': (global.navigator.doNotTrack === 1 ? 1 : 0),
|
|
250
|
+
'devicetype': isMobile() ? 4 : isConnectedTV() ? 3 : 2,
|
|
251
|
+
'js': 1,
|
|
252
|
+
'os': getOsVersion()
|
|
253
|
+
},
|
|
254
|
+
'at': 2,
|
|
255
|
+
'site': {},
|
|
256
|
+
'tmax': 3000,
|
|
257
|
+
'cur': ['USD'],
|
|
258
|
+
'id': bid.bidId,
|
|
259
|
+
'imp': [],
|
|
260
|
+
'regs': {
|
|
261
|
+
'ext': {
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
'user': {
|
|
265
|
+
'ext': {
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
o.site['page'] = topLocation.href;
|
|
271
|
+
o.site['domain'] = topLocation.hostname;
|
|
272
|
+
o.site['search'] = topLocation.search;
|
|
273
|
+
o.site['domain'] = topLocation.hostname;
|
|
274
|
+
o.site['ref'] = topReferrer;
|
|
275
|
+
o.site['mobile'] = isMobile() ? 1 : 0;
|
|
276
|
+
const secure = topLocation.protocol.indexOf('https') === 0 ? 1 : 0;
|
|
277
|
+
|
|
278
|
+
o.device['dnt'] = getDoNotTrack() ? 1 : 0;
|
|
279
|
+
|
|
280
|
+
findAndFillParam(o.site, 'name', function() {
|
|
281
|
+
return global.top.document.title;
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
findAndFillParam(o.device, 'h', function() {
|
|
285
|
+
return global.screen.height;
|
|
286
|
+
});
|
|
287
|
+
findAndFillParam(o.device, 'w', function() {
|
|
288
|
+
return global.screen.width;
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
let placement = getVideoBidParam(bid, 'placement');
|
|
292
|
+
|
|
293
|
+
for (let j = 0; j < sizes.length; j++) {
|
|
294
|
+
o.imp.push({
|
|
295
|
+
'id': '' + j,
|
|
296
|
+
'displaymanager': '' + BIDDER_CODE,
|
|
297
|
+
'displaymanagerver': '' + ADAPTER_VERSION,
|
|
298
|
+
'tagId': placement,
|
|
299
|
+
'bidfloor': floor,
|
|
300
|
+
'bidfloorcur': 'USD',
|
|
301
|
+
'secure': secure,
|
|
302
|
+
'video': Object.assign({
|
|
303
|
+
'id': generateUUID(),
|
|
304
|
+
'pos': 0,
|
|
305
|
+
'w': firstSize.w,
|
|
306
|
+
'h': firstSize.h,
|
|
307
|
+
'mimes': DEFAULT_MIMES
|
|
308
|
+
}, video)
|
|
309
|
+
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
if (coppa) {
|
|
313
|
+
o.regs.ext = {'coppa': 1};
|
|
314
|
+
}
|
|
315
|
+
if (bidderRequest && bidderRequest.gdprConsent) {
|
|
316
|
+
let { gdprApplies, consentString } = bidderRequest.gdprConsent;
|
|
317
|
+
o.regs.ext = {'gdpr': gdprApplies ? 1 : 0};
|
|
318
|
+
o.user.ext = {'consent': consentString};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return o;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function getTopWindowLocation(bidderRequest) {
|
|
325
|
+
let url = bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer;
|
|
326
|
+
return parseUrl(config.getConfig('pageUrl') || url, { decodeSearchAsString: true });
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function createBannerRequestData(bid, bidderRequest) {
|
|
330
|
+
let topLocation = getTopWindowLocation(bidderRequest);
|
|
331
|
+
let topReferrer = getTopWindowReferrer();
|
|
332
|
+
|
|
333
|
+
// if size is explicitly given via adapter params
|
|
334
|
+
|
|
335
|
+
let paramSize = getBannerBidParam(bid, 'size');
|
|
336
|
+
let sizes = [];
|
|
337
|
+
let coppa = config.getConfig('coppa');
|
|
338
|
+
if (typeof paramSize !== 'undefined' && paramSize != '') {
|
|
339
|
+
sizes = parseSizes(paramSize);
|
|
340
|
+
} else {
|
|
341
|
+
sizes = getBannerSizes(bid);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
let floor = (getBannerBidFloor(bid) == null || typeof getBannerBidFloor(bid) == 'undefined') ? 0.1 : getBannerBidFloor(bid);
|
|
345
|
+
const o = {
|
|
346
|
+
'device': {
|
|
347
|
+
'langauge': (global.navigator.language).split('-')[0],
|
|
348
|
+
'dnt': (global.navigator.doNotTrack === 1 ? 1 : 0),
|
|
349
|
+
'devicetype': isMobile() ? 4 : isConnectedTV() ? 3 : 2,
|
|
350
|
+
'js': 1
|
|
351
|
+
},
|
|
352
|
+
'at': 2,
|
|
353
|
+
'site': {},
|
|
354
|
+
'tmax': 3000,
|
|
355
|
+
'cur': ['USD'],
|
|
356
|
+
'id': bid.bidId,
|
|
357
|
+
'imp': [],
|
|
358
|
+
'regs': {
|
|
359
|
+
'ext': {
|
|
360
|
+
}
|
|
361
|
+
},
|
|
362
|
+
'user': {
|
|
363
|
+
'ext': {
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
o.site['page'] = topLocation.href;
|
|
369
|
+
o.site['domain'] = topLocation.hostname;
|
|
370
|
+
o.site['search'] = topLocation.search;
|
|
371
|
+
o.site['domain'] = topLocation.hostname;
|
|
372
|
+
o.site['ref'] = topReferrer;
|
|
373
|
+
o.site['mobile'] = isMobile() ? 1 : 0;
|
|
374
|
+
const secure = topLocation.protocol.indexOf('https') === 0 ? 1 : 0;
|
|
375
|
+
|
|
376
|
+
o.device['dnt'] = getDoNotTrack() ? 1 : 0;
|
|
377
|
+
|
|
378
|
+
findAndFillParam(o.site, 'name', function() {
|
|
379
|
+
return global.top.document.title;
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
findAndFillParam(o.device, 'h', function() {
|
|
383
|
+
return global.screen.height;
|
|
384
|
+
});
|
|
385
|
+
findAndFillParam(o.device, 'w', function() {
|
|
386
|
+
return global.screen.width;
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
let placement = getBannerBidParam(bid, 'placement');
|
|
390
|
+
for (let j = 0; j < sizes.length; j++) {
|
|
391
|
+
let size = sizes[j];
|
|
392
|
+
|
|
393
|
+
o.imp.push({
|
|
394
|
+
'id': '' + j,
|
|
395
|
+
'displaymanager': '' + BIDDER_CODE,
|
|
396
|
+
'displaymanagerver': '' + ADAPTER_VERSION,
|
|
397
|
+
'tagId': placement,
|
|
398
|
+
'bidfloor': floor,
|
|
399
|
+
'bidfloorcur': 'USD',
|
|
400
|
+
'secure': secure,
|
|
401
|
+
'banner': {
|
|
402
|
+
'id': generateUUID(),
|
|
403
|
+
'pos': 0,
|
|
404
|
+
'w': size['w'],
|
|
405
|
+
'h': size['h']
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
if (coppa) {
|
|
410
|
+
o.regs.ext = {'coppa': 1};
|
|
411
|
+
}
|
|
412
|
+
if (bidderRequest && bidderRequest.gdprConsent) {
|
|
413
|
+
let { gdprApplies, consentString } = bidderRequest.gdprConsent;
|
|
414
|
+
o.regs.ext = {'gdpr': gdprApplies ? 1 : 0};
|
|
415
|
+
o.user.ext = {'consent': consentString};
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
return o;
|
|
419
|
+
}
|
|
420
|
+
registerBidder(spec);
|
|
@@ -1,69 +1,66 @@
|
|
|
1
|
-
# Overview
|
|
2
|
-
|
|
3
|
-
```
|
|
4
|
-
Module Name: Saambaa Bidder Adapter
|
|
5
|
-
Module Type: Bidder Adapter
|
|
6
|
-
Maintainer: matt.voigt@saambaa.com
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
# Description
|
|
10
|
-
|
|
11
|
-
Connects to Saambaa exchange for bids.
|
|
12
|
-
|
|
13
|
-
Saambaa bid adapter supports Banner and Video ads currently.
|
|
14
|
-
|
|
15
|
-
For more informatio
|
|
16
|
-
|
|
17
|
-
# Sample Display Ad Unit: For Publishers
|
|
18
|
-
```javascript
|
|
19
|
-
|
|
20
|
-
var displayAdUnit = [
|
|
21
|
-
{
|
|
22
|
-
code: 'display',
|
|
23
|
-
mediaTypes: {
|
|
24
|
-
banner: {
|
|
25
|
-
sizes: [[300, 250],[320, 50]]
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
bids: [{
|
|
29
|
-
bidder: 'saambaa',
|
|
30
|
-
params: {
|
|
31
|
-
pubid: '121ab139faf7ac67428a23f1d0a9a71b',
|
|
32
|
-
placement: 1234,
|
|
33
|
-
size: '320x50'
|
|
34
|
-
}
|
|
35
|
-
}]
|
|
36
|
-
}];
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
# Sample Video Ad Unit: For Publishers
|
|
40
|
-
```javascript
|
|
41
|
-
|
|
42
|
-
var videoAdUnit = {
|
|
43
|
-
code: 'video',
|
|
44
|
-
sizes: [320,480],
|
|
45
|
-
mediaTypes: {
|
|
46
|
-
video: {
|
|
47
|
-
playerSize : [[320, 480]],
|
|
48
|
-
context: 'instream'
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
]
|
|
68
|
-
};
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
Module Name: Saambaa Bidder Adapter
|
|
5
|
+
Module Type: Bidder Adapter
|
|
6
|
+
Maintainer: matt.voigt@saambaa.com
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
# Description
|
|
10
|
+
|
|
11
|
+
Connects to Saambaa exchange for bids.
|
|
12
|
+
|
|
13
|
+
Saambaa bid adapter supports Banner and Video ads currently.
|
|
14
|
+
|
|
15
|
+
For more informatio
|
|
16
|
+
|
|
17
|
+
# Sample Display Ad Unit: For Publishers
|
|
18
|
+
```javascript
|
|
19
|
+
|
|
20
|
+
var displayAdUnit = [
|
|
21
|
+
{
|
|
22
|
+
code: 'display',
|
|
23
|
+
mediaTypes: {
|
|
24
|
+
banner: {
|
|
25
|
+
sizes: [[300, 250],[320, 50]]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
bids: [{
|
|
29
|
+
bidder: 'saambaa',
|
|
30
|
+
params: {
|
|
31
|
+
pubid: '121ab139faf7ac67428a23f1d0a9a71b',
|
|
32
|
+
placement: 1234,
|
|
33
|
+
size: '320x50'
|
|
34
|
+
}
|
|
35
|
+
}]
|
|
36
|
+
}];
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
# Sample Video Ad Unit: For Publishers
|
|
40
|
+
```javascript
|
|
41
|
+
|
|
42
|
+
var videoAdUnit = {
|
|
43
|
+
code: 'video',
|
|
44
|
+
sizes: [320,480],
|
|
45
|
+
mediaTypes: {
|
|
46
|
+
video: {
|
|
47
|
+
playerSize : [[320, 480]],
|
|
48
|
+
context: 'instream',
|
|
49
|
+
skip: 1,
|
|
50
|
+
mimes : ['video/mp4', 'application/javascript'],
|
|
51
|
+
playbackmethod : [2,6],
|
|
52
|
+
maxduration: 30
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
bids: [
|
|
56
|
+
{
|
|
57
|
+
bidder: 'saambaa',
|
|
58
|
+
params: {
|
|
59
|
+
pubid: '121ab139faf7ac67428a23f1d0a9a71b',
|
|
60
|
+
placement: 1234,
|
|
61
|
+
size: "320x480"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
};
|
|
69
66
|
```
|
|
@@ -13,6 +13,11 @@ const ALLOWED_PLACEMENTS = {
|
|
|
13
13
|
banner: true,
|
|
14
14
|
video: true
|
|
15
15
|
}
|
|
16
|
+
|
|
17
|
+
// Global Vendor List Id
|
|
18
|
+
// https://iabeurope.eu/vendor-list-tcf-v2-0/
|
|
19
|
+
const GVLID = 157;
|
|
20
|
+
|
|
16
21
|
const mediaTypesMap = {
|
|
17
22
|
[BANNER]: 'display',
|
|
18
23
|
[VIDEO]: 'video'
|
|
@@ -158,6 +163,7 @@ export function getTimeoutUrl (data) {
|
|
|
158
163
|
|
|
159
164
|
export const spec = {
|
|
160
165
|
code: BIDDER_CODE,
|
|
166
|
+
gvlid: GVLID,
|
|
161
167
|
aliases: [SEEDTAG_ALIAS],
|
|
162
168
|
supportedMediaTypes: [BANNER, VIDEO],
|
|
163
169
|
/**
|
|
@@ -5,7 +5,7 @@ import {ADPOD, BANNER, VIDEO} from '../src/mediaTypes.js';
|
|
|
5
5
|
|
|
6
6
|
const BIDDER_CODE = 'smaato';
|
|
7
7
|
const SMAATO_ENDPOINT = 'https://prebid.ad.smaato.net/oapi/prebid';
|
|
8
|
-
const SMAATO_CLIENT = 'prebid_js_$prebid.version$_1.
|
|
8
|
+
const SMAATO_CLIENT = 'prebid_js_$prebid.version$_1.5'
|
|
9
9
|
const CURRENCY = 'USD';
|
|
10
10
|
|
|
11
11
|
const buildOpenRtbBidRequest = (bidRequest, bidderRequest) => {
|
|
@@ -37,6 +37,11 @@ const buildOpenRtbBidRequest = (bidRequest, bidderRequest) => {
|
|
|
37
37
|
user: {
|
|
38
38
|
ext: {}
|
|
39
39
|
},
|
|
40
|
+
source: {
|
|
41
|
+
ext: {
|
|
42
|
+
schain: bidRequest.schain
|
|
43
|
+
}
|
|
44
|
+
},
|
|
40
45
|
ext: {
|
|
41
46
|
client: SMAATO_CLIENT
|
|
42
47
|
}
|
|
@@ -9,11 +9,13 @@ const BIDDER_URL = 'https://ssp.wp.pl/bidder/';
|
|
|
9
9
|
const SYNC_URL = 'https://ssp.wp.pl/bidder/usersync';
|
|
10
10
|
const NOTIFY_URL = 'https://ssp.wp.pl/bidder/notify';
|
|
11
11
|
const TMAX = 450;
|
|
12
|
-
const BIDDER_VERSION = '5.
|
|
12
|
+
const BIDDER_VERSION = '5.3';
|
|
13
13
|
const W = window;
|
|
14
14
|
const { navigator } = W;
|
|
15
15
|
const oneCodeDetection = {};
|
|
16
|
+
const adUnitsCalled = {};
|
|
16
17
|
const adSizesCalled = {};
|
|
18
|
+
const pageView = {};
|
|
17
19
|
var consentApiVersion;
|
|
18
20
|
|
|
19
21
|
/**
|
|
@@ -70,6 +72,7 @@ const cookieSupport = () => {
|
|
|
70
72
|
};
|
|
71
73
|
|
|
72
74
|
const applyClientHints = ortbRequest => {
|
|
75
|
+
const { location } = document;
|
|
73
76
|
const { connection = {}, deviceMemory, userAgentData = {} } = navigator;
|
|
74
77
|
const viewport = W.visualViewport || false;
|
|
75
78
|
const segments = [];
|
|
@@ -85,6 +88,16 @@ const applyClientHints = ortbRequest => {
|
|
|
85
88
|
'CH-isMobile': userAgentData.mobile,
|
|
86
89
|
};
|
|
87
90
|
|
|
91
|
+
/**
|
|
92
|
+
Check / generate page view id
|
|
93
|
+
Should be generated dureing first call to applyClientHints(),
|
|
94
|
+
and re-generated if pathname has changed
|
|
95
|
+
*/
|
|
96
|
+
if (!pageView.id || location.pathname !== pageView.path) {
|
|
97
|
+
pageView.path = location.pathname;
|
|
98
|
+
pageView.id = Math.floor(1E20 * Math.random());
|
|
99
|
+
}
|
|
100
|
+
|
|
88
101
|
Object.keys(hints).forEach(key => {
|
|
89
102
|
const hint = hints[key];
|
|
90
103
|
|
|
@@ -100,6 +113,14 @@ const applyClientHints = ortbRequest => {
|
|
|
100
113
|
id: '12',
|
|
101
114
|
name: 'NetInfo',
|
|
102
115
|
segment: segments,
|
|
116
|
+
}, {
|
|
117
|
+
id: '7',
|
|
118
|
+
name: 'pvid',
|
|
119
|
+
segment: [
|
|
120
|
+
{
|
|
121
|
+
value: `${pageView.id}`
|
|
122
|
+
}
|
|
123
|
+
]
|
|
103
124
|
}];
|
|
104
125
|
|
|
105
126
|
ortbRequest.user = Object.assign(ortbRequest.user, { data });
|
|
@@ -129,6 +150,7 @@ const setOnAny = (collection, key) => collection.reduce((prev, next) => prev ||
|
|
|
129
150
|
*/
|
|
130
151
|
const sendNotification = payload => {
|
|
131
152
|
ajax(NOTIFY_URL, null, JSON.stringify(payload), {
|
|
153
|
+
contentType: 'application/json',
|
|
132
154
|
withCredentials: false,
|
|
133
155
|
method: 'POST',
|
|
134
156
|
crossOrigin: true
|
|
@@ -267,8 +289,14 @@ const mapImpression = slot => {
|
|
|
267
289
|
send this info as ext.pbsize
|
|
268
290
|
*/
|
|
269
291
|
const slotSize = slot.sizes.length ? slot.sizes.reduce((prev, next) => prev[0] * prev[1] <= next[0] * next[1] ? next : prev).join('x') : '1x1';
|
|
270
|
-
|
|
271
|
-
|
|
292
|
+
|
|
293
|
+
if (!adUnitsCalled[adUnitCode]) {
|
|
294
|
+
// this is a new adunit - assign & save pbsize
|
|
295
|
+
adSizesCalled[slotSize] = adSizesCalled[slotSize] ? adSizesCalled[slotSize] += 1 : 1;
|
|
296
|
+
adUnitsCalled[adUnitCode] = `${slotSize}_${adSizesCalled[slotSize]}`
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
ext.data = Object.assign({ pbsize: adUnitsCalled[adUnitCode] }, ext.data);
|
|
272
300
|
|
|
273
301
|
const imp = {
|
|
274
302
|
id: id && siteId ? id : 'bidid-' + bidId,
|
|
@@ -325,6 +353,9 @@ const parseNative = nativeData => {
|
|
|
325
353
|
case 0:
|
|
326
354
|
result.title = asset.title.text;
|
|
327
355
|
break;
|
|
356
|
+
case 1:
|
|
357
|
+
result.cta = asset.data.value;
|
|
358
|
+
break;
|
|
328
359
|
case 2:
|
|
329
360
|
result.icon = {
|
|
330
361
|
url: asset.img.url,
|