prebid.js 6.1.0 → 6.2.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/README.md +1 -1
- package/browsers.json +13 -29
- package/karma.conf.maker.js +1 -1
- package/modules/admixerBidAdapter.js +2 -1
- package/modules/adnuntiusBidAdapter.js +2 -1
- package/modules/adplusBidAdapter.js +203 -0
- package/modules/adplusBidAdapter.md +39 -0
- package/modules/adyoulikeBidAdapter.js +7 -2
- package/modules/appnexusBidAdapter.js +19 -2
- package/modules/beachfrontBidAdapter.js +14 -17
- package/modules/craftBidAdapter.js +5 -3
- package/modules/dchain.js +149 -0
- package/modules/dchain.md +45 -0
- package/modules/emx_digitalBidAdapter.js +9 -1
- package/modules/freewheel-sspBidAdapter.js +6 -0
- package/modules/goldbachBidAdapter.js +1176 -0
- package/modules/goldbachBidAdapter.md +151 -0
- package/modules/gumgumBidAdapter.js +5 -1
- package/modules/intersectionRtdProvider.js +114 -0
- package/modules/invibesBidAdapter.js +15 -9
- package/modules/ipromBidAdapter.js +79 -0
- package/modules/limelightDigitalBidAdapter.js +2 -1
- package/modules/luponmediaBidAdapter.js +570 -0
- package/modules/missenaBidAdapter.js +89 -0
- package/modules/pubmaticBidAdapter.js +3 -3
- package/modules/relaidoBidAdapter.js +86 -65
- package/modules/richaudienceBidAdapter.js +1 -1
- package/modules/smaatoBidAdapter.js +4 -1
- package/modules/smartxBidAdapter.js +17 -1
- package/modules/tappxBidAdapter.js +3 -1
- package/modules/undertoneBidAdapter.js +8 -1
- package/modules/userId/index.js +27 -2
- package/modules/ventes.md +71 -0
- package/modules/ventesBidAdapter.js +104 -64
- package/modules/ventesBidAdapter.md +0 -1
- package/modules/visxBidAdapter.js +19 -2
- package/modules/visxBidAdapter.md +4 -6
- package/modules/yahoosspBidAdapter.md +1 -1
- package/modules/yieldoneBidAdapter.js +115 -11
- package/package.json +1 -1
- package/src/auction.js +3 -2
- package/src/targeting.js +2 -2
- package/src/utils.js +7 -0
- package/test/spec/integration/faker/googletag.js +6 -0
- package/test/spec/modules/adnuntiusBidAdapter_spec.js +18 -0
- package/test/spec/modules/adplusBidAdapter_spec.js +213 -0
- package/test/spec/modules/adyoulikeBidAdapter_spec.js +26 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +49 -1
- package/test/spec/modules/beachfrontBidAdapter_spec.js +65 -1
- package/test/spec/modules/dchain_spec.js +329 -0
- package/test/spec/modules/emx_digitalBidAdapter_spec.js +10 -0
- package/test/spec/modules/freewheel-sspBidAdapter_spec.js +19 -0
- package/test/spec/modules/goldbachBidAdapter_spec.js +1359 -0
- package/test/spec/modules/gumgumBidAdapter_spec.js +6 -0
- package/test/spec/modules/intersectionRtdProvider_spec.js +141 -0
- package/test/spec/modules/invibesBidAdapter_spec.js +29 -4
- package/test/spec/modules/ipromBidAdapter_spec.js +195 -0
- package/test/spec/modules/limelightDigitalBidAdapter_spec.js +10 -7
- package/test/spec/modules/luponmediaBidAdapter_spec.js +412 -0
- package/test/spec/modules/missenaBidAdapter_spec.js +134 -0
- package/test/spec/modules/pubmaticBidAdapter_spec.js +1 -1
- package/test/spec/modules/relaidoBidAdapter_spec.js +71 -63
- package/test/spec/modules/smaatoBidAdapter_spec.js +31 -0
- package/test/spec/modules/smartxBidAdapter_spec.js +9 -0
- package/test/spec/modules/tappxBidAdapter_spec.js +4 -0
- package/test/spec/modules/userId_spec.js +51 -0
- package/test/spec/modules/visxBidAdapter_spec.js +120 -4
- package/test/spec/modules/yieldoneBidAdapter_spec.js +299 -53
- package/test/spec/unit/core/targeting_spec.js +44 -0
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
import {isArray, logMessage, deepAccess, logWarn, parseSizesInput, deepSetValue, generateUUID, isEmpty, logError, _each, isFn} 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 { ajax } from '../src/ajax.js';
|
|
6
|
+
|
|
7
|
+
const BIDDER_CODE = 'luponmedia';
|
|
8
|
+
const ENDPOINT_URL = 'https://rtb.adxpremium.services/openrtb2/auction';
|
|
9
|
+
|
|
10
|
+
const DIGITRUST_PROP_NAMES = {
|
|
11
|
+
PREBID_SERVER: {
|
|
12
|
+
id: 'id',
|
|
13
|
+
keyv: 'keyv'
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
var sizeMap = {
|
|
18
|
+
1: '468x60',
|
|
19
|
+
2: '728x90',
|
|
20
|
+
5: '120x90',
|
|
21
|
+
7: '125x125',
|
|
22
|
+
8: '120x600',
|
|
23
|
+
9: '160x600',
|
|
24
|
+
10: '300x600',
|
|
25
|
+
13: '200x200',
|
|
26
|
+
14: '250x250',
|
|
27
|
+
15: '300x250',
|
|
28
|
+
16: '336x280',
|
|
29
|
+
17: '240x400',
|
|
30
|
+
19: '300x100',
|
|
31
|
+
31: '980x120',
|
|
32
|
+
32: '250x360',
|
|
33
|
+
33: '180x500',
|
|
34
|
+
35: '980x150',
|
|
35
|
+
37: '468x400',
|
|
36
|
+
38: '930x180',
|
|
37
|
+
39: '750x100',
|
|
38
|
+
40: '750x200',
|
|
39
|
+
41: '750x300',
|
|
40
|
+
42: '2x4',
|
|
41
|
+
43: '320x50',
|
|
42
|
+
44: '300x50',
|
|
43
|
+
48: '300x300',
|
|
44
|
+
53: '1024x768',
|
|
45
|
+
54: '300x1050',
|
|
46
|
+
55: '970x90',
|
|
47
|
+
57: '970x250',
|
|
48
|
+
58: '1000x90',
|
|
49
|
+
59: '320x80',
|
|
50
|
+
60: '320x150',
|
|
51
|
+
61: '1000x1000',
|
|
52
|
+
64: '580x500',
|
|
53
|
+
65: '640x480',
|
|
54
|
+
66: '930x600',
|
|
55
|
+
67: '320x480',
|
|
56
|
+
68: '1800x1000',
|
|
57
|
+
72: '320x320',
|
|
58
|
+
73: '320x160',
|
|
59
|
+
78: '980x240',
|
|
60
|
+
79: '980x300',
|
|
61
|
+
80: '980x400',
|
|
62
|
+
83: '480x300',
|
|
63
|
+
85: '300x120',
|
|
64
|
+
90: '548x150',
|
|
65
|
+
94: '970x310',
|
|
66
|
+
95: '970x100',
|
|
67
|
+
96: '970x210',
|
|
68
|
+
101: '480x320',
|
|
69
|
+
102: '768x1024',
|
|
70
|
+
103: '480x280',
|
|
71
|
+
105: '250x800',
|
|
72
|
+
108: '320x240',
|
|
73
|
+
113: '1000x300',
|
|
74
|
+
117: '320x100',
|
|
75
|
+
125: '800x250',
|
|
76
|
+
126: '200x600',
|
|
77
|
+
144: '980x600',
|
|
78
|
+
145: '980x150',
|
|
79
|
+
152: '1000x250',
|
|
80
|
+
156: '640x320',
|
|
81
|
+
159: '320x250',
|
|
82
|
+
179: '250x600',
|
|
83
|
+
195: '600x300',
|
|
84
|
+
198: '640x360',
|
|
85
|
+
199: '640x200',
|
|
86
|
+
213: '1030x590',
|
|
87
|
+
214: '980x360',
|
|
88
|
+
221: '1x1',
|
|
89
|
+
229: '320x180',
|
|
90
|
+
230: '2000x1400',
|
|
91
|
+
232: '580x400',
|
|
92
|
+
234: '6x6',
|
|
93
|
+
251: '2x2',
|
|
94
|
+
256: '480x820',
|
|
95
|
+
257: '400x600',
|
|
96
|
+
258: '500x200',
|
|
97
|
+
259: '998x200',
|
|
98
|
+
264: '970x1000',
|
|
99
|
+
265: '1920x1080',
|
|
100
|
+
274: '1800x200',
|
|
101
|
+
278: '320x500',
|
|
102
|
+
282: '320x400',
|
|
103
|
+
288: '640x380',
|
|
104
|
+
548: '500x1000',
|
|
105
|
+
550: '980x480',
|
|
106
|
+
552: '300x200',
|
|
107
|
+
558: '640x640'
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
_each(sizeMap, (item, key) => sizeMap[item] = key);
|
|
111
|
+
|
|
112
|
+
export const spec = {
|
|
113
|
+
code: BIDDER_CODE,
|
|
114
|
+
supportedMediaTypes: [BANNER],
|
|
115
|
+
isBidRequestValid: function (bid) {
|
|
116
|
+
return !!(bid.params && bid.params.siteId && bid.params.keyId); // TODO: check for siteId and keyId
|
|
117
|
+
},
|
|
118
|
+
buildRequests: function (bidRequests, bidderRequest) {
|
|
119
|
+
const bRequest = {
|
|
120
|
+
method: 'POST',
|
|
121
|
+
url: ENDPOINT_URL,
|
|
122
|
+
data: null,
|
|
123
|
+
options: {},
|
|
124
|
+
bidderRequest
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
let currentImps = [];
|
|
128
|
+
|
|
129
|
+
for (let i = 0, len = bidRequests.length; i < len; i++) {
|
|
130
|
+
let newReq = newOrtbBidRequest(bidRequests[i], bidderRequest, currentImps);
|
|
131
|
+
currentImps = newReq.imp;
|
|
132
|
+
bRequest.data = JSON.stringify(newReq);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return bRequest;
|
|
136
|
+
},
|
|
137
|
+
interpretResponse: (response, request) => {
|
|
138
|
+
const bidResponses = [];
|
|
139
|
+
var respCur = 'USD';
|
|
140
|
+
let parsedRequest = JSON.parse(request.data);
|
|
141
|
+
let parsedReferrer = parsedRequest.site && parsedRequest.site.ref ? parsedRequest.site.ref : '';
|
|
142
|
+
try {
|
|
143
|
+
if (response.body && response.body.seatbid && isArray(response.body.seatbid)) {
|
|
144
|
+
// Supporting multiple bid responses for same adSize
|
|
145
|
+
respCur = response.body.cur || respCur;
|
|
146
|
+
response.body.seatbid.forEach(seatbidder => {
|
|
147
|
+
seatbidder.bid &&
|
|
148
|
+
isArray(seatbidder.bid) &&
|
|
149
|
+
seatbidder.bid.forEach(bid => {
|
|
150
|
+
let newBid = {
|
|
151
|
+
requestId: bid.impid,
|
|
152
|
+
cpm: (parseFloat(bid.price) || 0).toFixed(2),
|
|
153
|
+
width: bid.w,
|
|
154
|
+
height: bid.h,
|
|
155
|
+
creativeId: bid.crid || bid.id,
|
|
156
|
+
dealId: bid.dealid,
|
|
157
|
+
currency: respCur,
|
|
158
|
+
netRevenue: false,
|
|
159
|
+
ttl: 300,
|
|
160
|
+
referrer: parsedReferrer,
|
|
161
|
+
ad: bid.adm
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
bidResponses.push(newBid);
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
} catch (error) {
|
|
169
|
+
logError(error);
|
|
170
|
+
}
|
|
171
|
+
return bidResponses;
|
|
172
|
+
},
|
|
173
|
+
getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent) {
|
|
174
|
+
let allUserSyncs = [];
|
|
175
|
+
if (!hasSynced && (syncOptions.iframeEnabled || syncOptions.pixelEnabled)) {
|
|
176
|
+
responses.forEach(csResp => {
|
|
177
|
+
if (csResp.body && csResp.body.ext && csResp.body.ext.usersyncs) {
|
|
178
|
+
try {
|
|
179
|
+
let response = csResp.body.ext.usersyncs
|
|
180
|
+
let bidders = response.bidder_status;
|
|
181
|
+
for (let synci in bidders) {
|
|
182
|
+
let thisSync = bidders[synci];
|
|
183
|
+
if (thisSync.no_cookie) {
|
|
184
|
+
let url = thisSync.usersync.url;
|
|
185
|
+
let type = thisSync.usersync.type;
|
|
186
|
+
|
|
187
|
+
if (!url) {
|
|
188
|
+
logError(`No sync url for bidder luponmedia.`);
|
|
189
|
+
} else if ((type === 'image' || type === 'redirect') && syncOptions.pixelEnabled) {
|
|
190
|
+
logMessage(`Invoking image pixel user sync for luponmedia`);
|
|
191
|
+
allUserSyncs.push({type: 'image', url: url});
|
|
192
|
+
} else if (type == 'iframe' && syncOptions.iframeEnabled) {
|
|
193
|
+
logMessage(`Invoking iframe user sync for luponmedia`);
|
|
194
|
+
allUserSyncs.push({type: 'iframe', url: url});
|
|
195
|
+
} else {
|
|
196
|
+
logError(`User sync type "${type}" not supported for luponmedia`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
} catch (e) {
|
|
201
|
+
logError(e);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
} else {
|
|
206
|
+
logWarn('Luponmedia: Please enable iframe/pixel based user sync.');
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
hasSynced = true;
|
|
210
|
+
return allUserSyncs;
|
|
211
|
+
},
|
|
212
|
+
onBidWon: bid => {
|
|
213
|
+
const bidString = JSON.stringify(bid);
|
|
214
|
+
spec.sendWinningsToServer(bidString);
|
|
215
|
+
},
|
|
216
|
+
sendWinningsToServer: data => {
|
|
217
|
+
let mutation = `mutation {createWin(input: {win: {eventData: "${window.btoa(data)}"}}) {win {createTime } } }`;
|
|
218
|
+
let dataToSend = JSON.stringify({ query: mutation });
|
|
219
|
+
|
|
220
|
+
ajax('https://analytics.adxpremium.services/graphql', null, dataToSend, {
|
|
221
|
+
contentType: 'application/json',
|
|
222
|
+
method: 'POST'
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
export function hasValidSupplyChainParams(schain) {
|
|
228
|
+
let isValid = false;
|
|
229
|
+
const requiredFields = ['asi', 'sid', 'hp'];
|
|
230
|
+
if (!schain.nodes) return isValid;
|
|
231
|
+
isValid = schain.nodes.reduce((status, node) => {
|
|
232
|
+
if (!status) return status;
|
|
233
|
+
return requiredFields.every(field => node[field]);
|
|
234
|
+
}, true);
|
|
235
|
+
if (!isValid) logError('LuponMedia: required schain params missing');
|
|
236
|
+
return isValid;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
var hasSynced = false;
|
|
240
|
+
|
|
241
|
+
export function resetUserSync() {
|
|
242
|
+
hasSynced = false;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export function masSizeOrdering(sizes) {
|
|
246
|
+
const MAS_SIZE_PRIORITY = [15, 2, 9];
|
|
247
|
+
|
|
248
|
+
return sizes.sort((first, second) => {
|
|
249
|
+
// sort by MAS_SIZE_PRIORITY priority order
|
|
250
|
+
const firstPriority = MAS_SIZE_PRIORITY.indexOf(first);
|
|
251
|
+
const secondPriority = MAS_SIZE_PRIORITY.indexOf(second);
|
|
252
|
+
|
|
253
|
+
if (firstPriority > -1 || secondPriority > -1) {
|
|
254
|
+
if (firstPriority === -1) {
|
|
255
|
+
return 1;
|
|
256
|
+
}
|
|
257
|
+
if (secondPriority === -1) {
|
|
258
|
+
return -1;
|
|
259
|
+
}
|
|
260
|
+
return firstPriority - secondPriority;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// and finally ascending order
|
|
264
|
+
return first - second;
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function newOrtbBidRequest(bidRequest, bidderRequest, currentImps) {
|
|
269
|
+
bidRequest.startTime = new Date().getTime();
|
|
270
|
+
|
|
271
|
+
const bannerParams = deepAccess(bidRequest, 'mediaTypes.banner');
|
|
272
|
+
|
|
273
|
+
let bannerSizes = [];
|
|
274
|
+
|
|
275
|
+
if (bannerParams && bannerParams.sizes) {
|
|
276
|
+
const sizes = parseSizesInput(bannerParams.sizes);
|
|
277
|
+
|
|
278
|
+
// get banner sizes in form [{ w: <int>, h: <int> }, ...]
|
|
279
|
+
const format = sizes.map(size => {
|
|
280
|
+
const [ width, height ] = size.split('x');
|
|
281
|
+
const w = parseInt(width, 10);
|
|
282
|
+
const h = parseInt(height, 10);
|
|
283
|
+
return { w, h };
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
bannerSizes = format;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const data = {
|
|
290
|
+
id: bidRequest.transactionId,
|
|
291
|
+
test: config.getConfig('debug') ? 1 : 0,
|
|
292
|
+
source: {
|
|
293
|
+
tid: bidRequest.transactionId
|
|
294
|
+
},
|
|
295
|
+
tmax: config.getConfig('timeout') || 1500,
|
|
296
|
+
imp: currentImps.concat([{
|
|
297
|
+
id: bidRequest.bidId,
|
|
298
|
+
secure: 1,
|
|
299
|
+
ext: {
|
|
300
|
+
[bidRequest.bidder]: bidRequest.params
|
|
301
|
+
},
|
|
302
|
+
banner: {
|
|
303
|
+
format: bannerSizes
|
|
304
|
+
}
|
|
305
|
+
}]),
|
|
306
|
+
ext: {
|
|
307
|
+
prebid: {
|
|
308
|
+
targeting: {
|
|
309
|
+
includewinners: true,
|
|
310
|
+
// includebidderkeys always false for openrtb
|
|
311
|
+
includebidderkeys: false
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
user: {
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
let bidFloor;
|
|
320
|
+
if (isFn(bidRequest.getFloor) && !config.getConfig('disableFloors')) {
|
|
321
|
+
let floorInfo;
|
|
322
|
+
try {
|
|
323
|
+
floorInfo = bidRequest.getFloor({
|
|
324
|
+
currency: 'USD',
|
|
325
|
+
mediaType: 'video',
|
|
326
|
+
size: parseSizes(bidRequest, 'video')
|
|
327
|
+
});
|
|
328
|
+
} catch (e) {
|
|
329
|
+
logError('LuponMedia: getFloor threw an error: ', e);
|
|
330
|
+
}
|
|
331
|
+
bidFloor = typeof floorInfo === 'object' && floorInfo.currency === 'USD' && !isNaN(parseInt(floorInfo.floor)) ? parseFloat(floorInfo.floor) : undefined;
|
|
332
|
+
} else {
|
|
333
|
+
bidFloor = parseFloat(deepAccess(bidRequest, 'params.floor'));
|
|
334
|
+
}
|
|
335
|
+
if (!isNaN(bidFloor)) {
|
|
336
|
+
data.imp[0].bidfloor = bidFloor;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
appendSiteAppDevice(data, bidRequest, bidderRequest);
|
|
340
|
+
|
|
341
|
+
const digiTrust = _getDigiTrustQueryParams(bidRequest, 'PREBID_SERVER');
|
|
342
|
+
if (digiTrust) {
|
|
343
|
+
deepSetValue(data, 'user.ext.digitrust', digiTrust);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (bidderRequest.gdprConsent) {
|
|
347
|
+
// note - gdprApplies & consentString may be undefined in certain use-cases for consentManagement module
|
|
348
|
+
let gdprApplies;
|
|
349
|
+
if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') {
|
|
350
|
+
gdprApplies = bidderRequest.gdprConsent.gdprApplies ? 1 : 0;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
deepSetValue(data, 'regs.ext.gdpr', gdprApplies);
|
|
354
|
+
deepSetValue(data, 'user.ext.consent', bidderRequest.gdprConsent.consentString);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (bidderRequest.uspConsent) {
|
|
358
|
+
deepSetValue(data, 'regs.ext.us_privacy', bidderRequest.uspConsent);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Set user uuid
|
|
362
|
+
deepSetValue(data, 'user.id', generateUUID());
|
|
363
|
+
|
|
364
|
+
// set crumbs
|
|
365
|
+
if (bidRequest.crumbs && bidRequest.crumbs.pubcid) {
|
|
366
|
+
deepSetValue(data, 'user.buyeruid', bidRequest.crumbs.pubcid);
|
|
367
|
+
} else {
|
|
368
|
+
deepSetValue(data, 'user.buyeruid', generateUUID());
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
if (bidRequest.userId && typeof bidRequest.userId === 'object' &&
|
|
372
|
+
(bidRequest.userId.tdid || bidRequest.userId.pubcid || bidRequest.userId.lipb || bidRequest.userId.idl_env)) {
|
|
373
|
+
deepSetValue(data, 'user.ext.eids', []);
|
|
374
|
+
|
|
375
|
+
if (bidRequest.userId.tdid) {
|
|
376
|
+
data.user.ext.eids.push({
|
|
377
|
+
source: 'adserver.org',
|
|
378
|
+
uids: [{
|
|
379
|
+
id: bidRequest.userId.tdid,
|
|
380
|
+
ext: {
|
|
381
|
+
rtiPartner: 'TDID'
|
|
382
|
+
}
|
|
383
|
+
}]
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (bidRequest.userId.pubcid) {
|
|
388
|
+
data.user.ext.eids.push({
|
|
389
|
+
source: 'pubcommon',
|
|
390
|
+
uids: [{
|
|
391
|
+
id: bidRequest.userId.pubcid,
|
|
392
|
+
}]
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// support liveintent ID
|
|
397
|
+
if (bidRequest.userId.lipb && bidRequest.userId.lipb.lipbid) {
|
|
398
|
+
data.user.ext.eids.push({
|
|
399
|
+
source: 'liveintent.com',
|
|
400
|
+
uids: [{
|
|
401
|
+
id: bidRequest.userId.lipb.lipbid
|
|
402
|
+
}]
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
data.user.ext.tpid = {
|
|
406
|
+
source: 'liveintent.com',
|
|
407
|
+
uid: bidRequest.userId.lipb.lipbid
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
if (Array.isArray(bidRequest.userId.lipb.segments) && bidRequest.userId.lipb.segments.length) {
|
|
411
|
+
deepSetValue(data, 'rp.target.LIseg', bidRequest.userId.lipb.segments);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// support identityLink (aka LiveRamp)
|
|
416
|
+
if (bidRequest.userId.idl_env) {
|
|
417
|
+
data.user.ext.eids.push({
|
|
418
|
+
source: 'liveramp.com',
|
|
419
|
+
uids: [{
|
|
420
|
+
id: bidRequest.userId.idl_env
|
|
421
|
+
}]
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if (config.getConfig('coppa') === true) {
|
|
427
|
+
deepSetValue(data, 'regs.coppa', 1);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
if (bidRequest.schain && hasValidSupplyChainParams(bidRequest.schain)) {
|
|
431
|
+
deepSetValue(data, 'source.ext.schain', bidRequest.schain);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
const siteData = Object.assign({}, bidRequest.params.inventory, config.getConfig('fpd.context'));
|
|
435
|
+
const userData = Object.assign({}, bidRequest.params.visitor, config.getConfig('fpd.user'));
|
|
436
|
+
|
|
437
|
+
if (!isEmpty(siteData) || !isEmpty(userData)) {
|
|
438
|
+
const bidderData = {
|
|
439
|
+
bidders: [ bidderRequest.bidderCode ],
|
|
440
|
+
config: {
|
|
441
|
+
fpd: {}
|
|
442
|
+
}
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
if (!isEmpty(siteData)) {
|
|
446
|
+
bidderData.config.fpd.site = siteData;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
if (!isEmpty(userData)) {
|
|
450
|
+
bidderData.config.fpd.user = userData;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
deepSetValue(data, 'ext.prebid.bidderconfig.0', bidderData);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
const pbAdSlot = deepAccess(bidRequest, 'fpd.context.pbAdSlot');
|
|
457
|
+
if (typeof pbAdSlot === 'string' && pbAdSlot) {
|
|
458
|
+
deepSetValue(data.imp[0].ext, 'context.data.adslot', pbAdSlot);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
return data;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
function _getDigiTrustQueryParams(bidRequest = {}, endpointName) {
|
|
465
|
+
if (!endpointName || !DIGITRUST_PROP_NAMES[endpointName]) {
|
|
466
|
+
return null;
|
|
467
|
+
}
|
|
468
|
+
const propNames = DIGITRUST_PROP_NAMES[endpointName];
|
|
469
|
+
|
|
470
|
+
function getDigiTrustId() {
|
|
471
|
+
const bidRequestDigitrust = deepAccess(bidRequest, 'userId.digitrustid.data');
|
|
472
|
+
if (bidRequestDigitrust) {
|
|
473
|
+
return bidRequestDigitrust;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
let digiTrustUser = (window.DigiTrust && (config.getConfig('digiTrustId') || window.DigiTrust.getUser({member: 'T9QSFKPDN9'})));
|
|
477
|
+
return (digiTrustUser && digiTrustUser.success && digiTrustUser.identity) || null;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
let digiTrustId = getDigiTrustId();
|
|
481
|
+
// Verify there is an ID and this user has not opted out
|
|
482
|
+
if (!digiTrustId || (digiTrustId.privacy && digiTrustId.privacy.optout)) {
|
|
483
|
+
return null;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
const digiTrustQueryParams = {
|
|
487
|
+
[propNames.id]: digiTrustId.id,
|
|
488
|
+
[propNames.keyv]: digiTrustId.keyv
|
|
489
|
+
};
|
|
490
|
+
if (propNames.pref) {
|
|
491
|
+
digiTrustQueryParams[propNames.pref] = 0;
|
|
492
|
+
}
|
|
493
|
+
return digiTrustQueryParams;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
function _getPageUrl(bidRequest, bidderRequest) {
|
|
497
|
+
let pageUrl = config.getConfig('pageUrl');
|
|
498
|
+
if (bidRequest.params.referrer) {
|
|
499
|
+
pageUrl = bidRequest.params.referrer;
|
|
500
|
+
} else if (!pageUrl) {
|
|
501
|
+
pageUrl = bidderRequest.refererInfo.referer;
|
|
502
|
+
}
|
|
503
|
+
return bidRequest.params.secure ? pageUrl.replace(/^http:/i, 'https:') : pageUrl;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
function appendSiteAppDevice(data, bidRequest, bidderRequest) {
|
|
507
|
+
if (!data) return;
|
|
508
|
+
|
|
509
|
+
// ORTB specifies app OR site
|
|
510
|
+
if (typeof config.getConfig('app') === 'object') {
|
|
511
|
+
data.app = config.getConfig('app');
|
|
512
|
+
} else {
|
|
513
|
+
data.site = {
|
|
514
|
+
page: _getPageUrl(bidRequest, bidderRequest)
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
if (typeof config.getConfig('device') === 'object') {
|
|
518
|
+
data.device = config.getConfig('device');
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* @param sizes
|
|
524
|
+
* @returns {*}
|
|
525
|
+
*/
|
|
526
|
+
function mapSizes(sizes) {
|
|
527
|
+
return parseSizesInput(sizes)
|
|
528
|
+
// map sizes while excluding non-matches
|
|
529
|
+
.reduce((result, size) => {
|
|
530
|
+
let mappedSize = parseInt(sizeMap[size], 10);
|
|
531
|
+
if (mappedSize) {
|
|
532
|
+
result.push(mappedSize);
|
|
533
|
+
}
|
|
534
|
+
return result;
|
|
535
|
+
}, []);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
function parseSizes(bid, mediaType) {
|
|
539
|
+
let params = bid.params;
|
|
540
|
+
if (mediaType === 'video') {
|
|
541
|
+
let size = [];
|
|
542
|
+
if (params.video && params.video.playerWidth && params.video.playerHeight) {
|
|
543
|
+
size = [
|
|
544
|
+
params.video.playerWidth,
|
|
545
|
+
params.video.playerHeight
|
|
546
|
+
];
|
|
547
|
+
} else if (Array.isArray(deepAccess(bid, 'mediaTypes.video.playerSize')) && bid.mediaTypes.video.playerSize.length === 1) {
|
|
548
|
+
size = bid.mediaTypes.video.playerSize[0];
|
|
549
|
+
} else if (Array.isArray(bid.sizes) && bid.sizes.length > 0 && Array.isArray(bid.sizes[0]) && bid.sizes[0].length > 1) {
|
|
550
|
+
size = bid.sizes[0];
|
|
551
|
+
}
|
|
552
|
+
return size;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
// Deprecated: temp legacy support
|
|
556
|
+
let sizes = [];
|
|
557
|
+
if (Array.isArray(params.sizes)) {
|
|
558
|
+
sizes = params.sizes;
|
|
559
|
+
} else if (typeof deepAccess(bid, 'mediaTypes.banner.sizes') !== 'undefined') {
|
|
560
|
+
sizes = mapSizes(bid.mediaTypes.banner.sizes);
|
|
561
|
+
} else if (Array.isArray(bid.sizes) && bid.sizes.length > 0) {
|
|
562
|
+
sizes = mapSizes(bid.sizes)
|
|
563
|
+
} else {
|
|
564
|
+
logWarn('LuponMedia: no sizes are setup or found');
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
return masSizeOrdering(sizes);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
registerBidder(spec);
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { formatQS, logInfo } from '../src/utils.js';
|
|
2
|
+
import { BANNER } from '../src/mediaTypes.js';
|
|
3
|
+
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
4
|
+
|
|
5
|
+
const BIDDER_CODE = 'missena';
|
|
6
|
+
const ENDPOINT_URL = 'https://bid.missena.io/';
|
|
7
|
+
|
|
8
|
+
export const spec = {
|
|
9
|
+
aliases: [BIDDER_CODE],
|
|
10
|
+
code: BIDDER_CODE,
|
|
11
|
+
gvlid: 687,
|
|
12
|
+
supportedMediaTypes: [BANNER],
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Determines whether or not the given bid request is valid.
|
|
16
|
+
*
|
|
17
|
+
* @param {BidRequest} bid The bid params to validate.
|
|
18
|
+
* @return boolean True if this is a valid bid, and false otherwise.
|
|
19
|
+
*/
|
|
20
|
+
isBidRequestValid: function (bid) {
|
|
21
|
+
return typeof bid == 'object' && !!bid.params.apiKey;
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Make a server request from the list of BidRequests.
|
|
26
|
+
*
|
|
27
|
+
* @param {validBidRequests[]} - an array of bids
|
|
28
|
+
* @return ServerRequest Info describing the request to the server.
|
|
29
|
+
*/
|
|
30
|
+
buildRequests: function (validBidRequests, bidderRequest) {
|
|
31
|
+
return validBidRequests.map((bidRequest) => {
|
|
32
|
+
const payload = {
|
|
33
|
+
request_id: bidRequest.bidId,
|
|
34
|
+
timeout: bidderRequest.timeout,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
if (bidderRequest && bidderRequest.refererInfo) {
|
|
38
|
+
payload.referer = bidderRequest.refererInfo.referer;
|
|
39
|
+
payload.referer_canonical = bidderRequest.refererInfo.canonicalUrl;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (bidderRequest && bidderRequest.gdprConsent) {
|
|
43
|
+
payload.consent_string = bidderRequest.gdprConsent.consentString;
|
|
44
|
+
payload.consent_required = bidderRequest.gdprConsent.gdprApplies;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
method: 'POST',
|
|
49
|
+
url: ENDPOINT_URL + '?' + formatQS({ t: bidRequest.params.apiKey }),
|
|
50
|
+
data: JSON.stringify(payload),
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Unpack the response from the server into a list of bids.
|
|
57
|
+
*
|
|
58
|
+
* @param {ServerResponse} serverResponse A successful response from the server.
|
|
59
|
+
* @return {Bid[]} An array of bids which were nested inside the server.
|
|
60
|
+
*/
|
|
61
|
+
interpretResponse: function (serverResponse, bidRequest) {
|
|
62
|
+
const bidResponses = [];
|
|
63
|
+
const response = serverResponse.body;
|
|
64
|
+
|
|
65
|
+
if (response && !response.timeout && !!response.ad) {
|
|
66
|
+
bidResponses.push(response);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return bidResponses;
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Register bidder specific code, which will execute if bidder timed out after an auction
|
|
74
|
+
* @param {data} Containing timeout specific data
|
|
75
|
+
*/
|
|
76
|
+
onTimeout: function onTimeout(timeoutData) {
|
|
77
|
+
logInfo('Missena - Timeout from adapter', timeoutData);
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Register bidder specific code, which@ will execute if a bid from this bidder won the auction
|
|
82
|
+
* @param {Bid} The bid that won the auction
|
|
83
|
+
*/
|
|
84
|
+
onBidWon: function (bid) {
|
|
85
|
+
logInfo('Missena - Bid won', bid);
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
registerBidder(spec);
|
|
@@ -867,10 +867,10 @@ function _handleEids(payload, validBidRequests) {
|
|
|
867
867
|
|
|
868
868
|
function _checkMediaType(bid, newBid) {
|
|
869
869
|
// Create a regex here to check the strings
|
|
870
|
-
if (bid.ext && bid.ext['
|
|
871
|
-
newBid.mediaType = MEDIATYPE[bid.ext.
|
|
870
|
+
if (bid.ext && bid.ext['bidtype'] != undefined) {
|
|
871
|
+
newBid.mediaType = MEDIATYPE[bid.ext.bidtype];
|
|
872
872
|
} else {
|
|
873
|
-
logInfo(LOG_WARN_PREFIX + 'bid.ext.
|
|
873
|
+
logInfo(LOG_WARN_PREFIX + 'bid.ext.bidtype does not exist, checking alternatively for mediaType')
|
|
874
874
|
var adm = bid.adm;
|
|
875
875
|
var admStr = '';
|
|
876
876
|
var videoRegex = new RegExp(/VAST\s+version/);
|