prebid.js 7.23.0 → 7.24.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/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/admaticBidAdapter.js +1 -0
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adtrgtmeBidAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/adyoulikeBidAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/audiencerunBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bluebillywigBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/carodaBidAdapter.js +1 -1
- package/dist/chtnwBidAdapter.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectIdSystem.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/glimpseBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gridNMBidAdapter.js +1 -1
- package/dist/growthCodeIdSystem.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/impactifyBidAdapter.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/jixieBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/kueezRtbBidAdapter.js +1 -0
- 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/mediakeysBidAdapter.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/mgidRtdProvider.js +1 -0
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +122 -119
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/pbsExtensions.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/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/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/underdogmediaBidAdapter.js +1 -1
- package/dist/undertoneBidAdapter.js +1 -1
- package/dist/userId.js +1 -1
- package/dist/vidazooBidAdapter.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/visxBidAdapter.js +1 -1
- package/dist/vuukleBidAdapter.js +1 -1
- package/dist/widespaceBidAdapter.js +1 -1
- package/dist/winrBidAdapter.js +1 -1
- package/dist/yahoosspBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/integrationExamples/gpt/mgidRtdProvider_example.html +143 -0
- package/modules/.submodules.json +1 -0
- package/modules/admaticBidAdapter.js +147 -0
- package/modules/admaticBidAdapter.md +48 -0
- package/modules/amxBidAdapter.js +1 -0
- package/modules/connectIdSystem.js +36 -23
- package/modules/connectIdSystem.md +3 -2
- package/modules/growthCodeIdSystem.js +9 -5
- package/modules/gumgumBidAdapter.js +4 -0
- package/modules/ixBidAdapter.js +30 -7
- package/modules/kueezRtbBidAdapter.js +278 -0
- package/modules/kueezRtbBidAdapter.md +35 -0
- package/modules/magniteAnalyticsAdapter.js +6 -1
- package/modules/mgidRtdProvider.js +190 -0
- package/modules/mgidRtdProvider.md +51 -0
- package/modules/permutiveRtdProvider.js +2 -1
- package/modules/permutiveRtdProvider.md +36 -1
- package/modules/pubmaticBidAdapter.js +21 -29
- package/modules/tripleliftBidAdapter.js +1 -1
- package/modules/userId/eids.js +3 -10
- package/package.json +8 -8
- package/src/adRendering.js +1 -1
- package/src/adloader.js +1 -0
- package/src/auction.js +1 -1
- package/src/prebid.js +83 -79
- package/test/spec/auctionmanager_spec.js +9 -0
- package/test/spec/modules/admaticBidAdapter_spec.js +46 -0
- package/test/spec/modules/connectIdSystem_spec.js +175 -5
- package/test/spec/modules/eids_spec.js +10 -7
- package/test/spec/modules/ftrackIdSystem_spec.js +34 -22
- package/test/spec/modules/gumgumBidAdapter_spec.js +15 -0
- package/test/spec/modules/ixBidAdapter_spec.js +203 -0
- package/test/spec/modules/kueezRtbBidAdapter_spec.js +396 -0
- package/test/spec/modules/magniteAnalyticsAdapter_spec.js +26 -0
- package/test/spec/modules/mgidRtdProvider_spec.js +366 -0
- package/test/spec/modules/permutiveRtdProvider_spec.js +64 -5
- package/test/spec/modules/tripleliftBidAdapter_spec.js +14 -0
- package/test/spec/unit/pbjs_api_spec.js +17 -1
package/modules/ixBidAdapter.js
CHANGED
|
@@ -38,7 +38,6 @@ const BANNER_TIME_TO_LIVE = 300;
|
|
|
38
38
|
const VIDEO_TIME_TO_LIVE = 3600; // 1hr
|
|
39
39
|
const NATIVE_TIME_TO_LIVE = 3600; // Since native can have video, use ttl same as video
|
|
40
40
|
const NET_REVENUE = true;
|
|
41
|
-
const MAX_REQUEST_SIZE = 8000;
|
|
42
41
|
const MAX_REQUEST_LIMIT = 4;
|
|
43
42
|
const OUTSTREAM_MINIMUM_PLAYER_SIZE = [144, 144];
|
|
44
43
|
const PRICE_TO_DOLLAR_FACTOR = {
|
|
@@ -159,7 +158,7 @@ const MEDIA_TYPES = {
|
|
|
159
158
|
* @return {object} A impression object that will be sent to ad server.
|
|
160
159
|
*/
|
|
161
160
|
function bidToBannerImp(bid) {
|
|
162
|
-
const imp = bidToImp(bid);
|
|
161
|
+
const imp = bidToImp(bid, BANNER);
|
|
163
162
|
imp.banner = {};
|
|
164
163
|
const impSize = deepAccess(bid, 'params.size');
|
|
165
164
|
if (impSize) {
|
|
@@ -181,7 +180,7 @@ function bidToBannerImp(bid) {
|
|
|
181
180
|
* @return {object} A impression object that will be sent to ad server.
|
|
182
181
|
*/
|
|
183
182
|
function bidToVideoImp(bid) {
|
|
184
|
-
const imp = bidToImp(bid);
|
|
183
|
+
const imp = bidToImp(bid, VIDEO);
|
|
185
184
|
const videoAdUnitRef = deepAccess(bid, 'mediaTypes.video');
|
|
186
185
|
const videoParamRef = deepAccess(bid, 'params.video');
|
|
187
186
|
const videoParamErrors = checkVideoParams(videoAdUnitRef, videoParamRef);
|
|
@@ -249,7 +248,7 @@ function bidToVideoImp(bid) {
|
|
|
249
248
|
* @return {object} A impression object that will be sent to ad server.
|
|
250
249
|
*/
|
|
251
250
|
function bidToNativeImp(bid) {
|
|
252
|
-
const imp = bidToImp(bid);
|
|
251
|
+
const imp = bidToImp(bid, NATIVE);
|
|
253
252
|
|
|
254
253
|
const request = bid.nativeOrtbRequest
|
|
255
254
|
request.eventtrackers = [{
|
|
@@ -276,13 +275,28 @@ function bidToNativeImp(bid) {
|
|
|
276
275
|
* @param {object} bid PBJS bid object
|
|
277
276
|
* @returns {object} IX impression object
|
|
278
277
|
*/
|
|
279
|
-
function bidToImp(bid) {
|
|
278
|
+
function bidToImp(bid, mediaType) {
|
|
280
279
|
const imp = {};
|
|
281
280
|
|
|
282
281
|
imp.id = bid.bidId;
|
|
283
282
|
|
|
284
283
|
imp.ext = {};
|
|
285
|
-
|
|
284
|
+
|
|
285
|
+
if (deepAccess(bid, `params.${mediaType}.siteId`) && !isNaN(Number(bid.params[mediaType].siteId))) {
|
|
286
|
+
switch (mediaType) {
|
|
287
|
+
case BANNER:
|
|
288
|
+
imp.ext.siteID = bid.params.banner.siteId.toString();
|
|
289
|
+
break;
|
|
290
|
+
case VIDEO:
|
|
291
|
+
imp.ext.siteID = bid.params.video.siteId.toString();
|
|
292
|
+
break;
|
|
293
|
+
case NATIVE:
|
|
294
|
+
imp.ext.siteID = bid.params.native.siteId.toString();
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
} else {
|
|
298
|
+
imp.ext.siteID = bid.params.siteId.toString();
|
|
299
|
+
}
|
|
286
300
|
|
|
287
301
|
// populate imp level sid
|
|
288
302
|
if (bid.params.hasOwnProperty('id') && (typeof bid.params.id === 'string' || typeof bid.params.id === 'number')) {
|
|
@@ -586,6 +600,12 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
|
|
|
586
600
|
let userEids = eidInfo.toSend;
|
|
587
601
|
const pageUrl = deepAccess(bidderRequest, 'refererInfo.page');
|
|
588
602
|
|
|
603
|
+
let MAX_REQUEST_SIZE = 8000;
|
|
604
|
+
// Modify request size limit if its FT is enabeld.
|
|
605
|
+
if (FEATURE_TOGGLES.isFeatureEnabled('pbjs_use_32kb_size_limit')) {
|
|
606
|
+
MAX_REQUEST_SIZE = 32000
|
|
607
|
+
}
|
|
608
|
+
|
|
589
609
|
// RTI ids will be included in the bid request if the function getIdentityInfo() is loaded
|
|
590
610
|
// and if the data for the partner exist
|
|
591
611
|
if (window.headertag && typeof window.headertag.getIdentityInfo === 'function') {
|
|
@@ -642,6 +662,9 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
|
|
|
642
662
|
r.ext.ixdiag.err = cachedErrors;
|
|
643
663
|
}
|
|
644
664
|
|
|
665
|
+
// Add number of available imps to ixDiag.
|
|
666
|
+
r.ext.ixdiag.imps = Object.keys(impressions).length;
|
|
667
|
+
|
|
645
668
|
// set source.tid to auctionId for outgoing request to Exchange.
|
|
646
669
|
r.source = {
|
|
647
670
|
tid: validBidRequests[0].auctionId,
|
|
@@ -1418,7 +1441,7 @@ export const spec = {
|
|
|
1418
1441
|
|
|
1419
1442
|
// Step 1: Create impresssions from IX params
|
|
1420
1443
|
validBidRequests.forEach((validBidRequest) => {
|
|
1421
|
-
const adUnitMediaTypes = Object.keys(deepAccess(validBidRequest, 'mediaTypes', {}))
|
|
1444
|
+
const adUnitMediaTypes = Object.keys(deepAccess(validBidRequest, 'mediaTypes', {}));
|
|
1422
1445
|
|
|
1423
1446
|
for (const type in adUnitMediaTypes) {
|
|
1424
1447
|
switch (adUnitMediaTypes[type]) {
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { _each, deepAccess, parseSizesInput, parseUrl, uniques, isFn } from '../src/utils.js';
|
|
2
|
+
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
3
|
+
import { BANNER } from '../src/mediaTypes.js';
|
|
4
|
+
import { getStorageManager } from '../src/storageManager.js';
|
|
5
|
+
|
|
6
|
+
const GVLID = 1165;
|
|
7
|
+
const DEFAULT_SUB_DOMAIN = 'exchange';
|
|
8
|
+
const BIDDER_CODE = 'kueezrtb';
|
|
9
|
+
const BIDDER_VERSION = '1.0.0';
|
|
10
|
+
const CURRENCY = 'USD';
|
|
11
|
+
const TTL_SECONDS = 60 * 5;
|
|
12
|
+
const UNIQUE_DEAL_ID_EXPIRY = 1000 * 60 * 15;
|
|
13
|
+
export const SUPPORTED_ID_SYSTEMS = {
|
|
14
|
+
'britepoolid': 1,
|
|
15
|
+
'criteoId': 1,
|
|
16
|
+
'id5id': 1,
|
|
17
|
+
'idl_env': 1,
|
|
18
|
+
'lipb': 1,
|
|
19
|
+
'netId': 1,
|
|
20
|
+
'parrableId': 1,
|
|
21
|
+
'pubcid': 1,
|
|
22
|
+
'tdid': 1,
|
|
23
|
+
'pubProvidedId': 1
|
|
24
|
+
};
|
|
25
|
+
const storage = getStorageManager({ gvlid: GVLID, bidderCode: BIDDER_CODE });
|
|
26
|
+
|
|
27
|
+
function getTopWindowQueryParams() {
|
|
28
|
+
try {
|
|
29
|
+
const parsedUrl = parseUrl(window.top.document.URL, { decodeSearchAsString: true });
|
|
30
|
+
return parsedUrl.search;
|
|
31
|
+
} catch (e) {
|
|
32
|
+
return '';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) {
|
|
37
|
+
return `https://${subDomain}.kueezrtb.com`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function extractCID(params) {
|
|
41
|
+
return params.cId || params.CID || params.cID || params.CId || params.cid || params.ciD || params.Cid || params.CiD;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function extractPID(params) {
|
|
45
|
+
return params.pId || params.PID || params.pID || params.PId || params.pid || params.piD || params.Pid || params.PiD;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function extractSubDomain(params) {
|
|
49
|
+
return params.subDomain || params.SubDomain || params.Subdomain || params.subdomain || params.SUBDOMAIN || params.subDOMAIN;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function isBidRequestValid(bid) {
|
|
53
|
+
const params = bid.params || {};
|
|
54
|
+
return !!(extractCID(params) && extractPID(params));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function buildRequest(bid, topWindowUrl, sizes, bidderRequest) {
|
|
58
|
+
const { params, bidId, userId, adUnitCode, schain } = bid;
|
|
59
|
+
let { bidFloor, ext } = params;
|
|
60
|
+
const hashUrl = hashCode(topWindowUrl);
|
|
61
|
+
const uniqueDealId = getUniqueDealId(hashUrl);
|
|
62
|
+
const cId = extractCID(params);
|
|
63
|
+
const pId = extractPID(params);
|
|
64
|
+
const subDomain = extractSubDomain(params);
|
|
65
|
+
|
|
66
|
+
if (isFn(bid.getFloor)) {
|
|
67
|
+
const floorInfo = bid.getFloor({
|
|
68
|
+
currency: 'USD',
|
|
69
|
+
mediaType: '*',
|
|
70
|
+
size: '*'
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
if (floorInfo.currency === 'USD') {
|
|
74
|
+
bidFloor = floorInfo.floor;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
let data = {
|
|
79
|
+
url: encodeURIComponent(topWindowUrl),
|
|
80
|
+
uqs: getTopWindowQueryParams(),
|
|
81
|
+
cb: Date.now(),
|
|
82
|
+
bidFloor: bidFloor,
|
|
83
|
+
bidId: bidId,
|
|
84
|
+
referrer: bidderRequest.refererInfo.ref,
|
|
85
|
+
adUnitCode: adUnitCode,
|
|
86
|
+
publisherId: pId,
|
|
87
|
+
sizes: sizes,
|
|
88
|
+
uniqueDealId: uniqueDealId,
|
|
89
|
+
bidderVersion: BIDDER_VERSION,
|
|
90
|
+
prebidVersion: '$prebid.version$',
|
|
91
|
+
res: `${screen.width}x${screen.height}`,
|
|
92
|
+
schain: schain
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
appendUserIdsToRequestPayload(data, userId);
|
|
96
|
+
|
|
97
|
+
if (bidderRequest.gdprConsent) {
|
|
98
|
+
if (bidderRequest.gdprConsent.consentString) {
|
|
99
|
+
data.gdprConsent = bidderRequest.gdprConsent.consentString;
|
|
100
|
+
}
|
|
101
|
+
if (bidderRequest.gdprConsent.gdprApplies !== undefined) {
|
|
102
|
+
data.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (bidderRequest.uspConsent) {
|
|
106
|
+
data.usPrivacy = bidderRequest.uspConsent;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const dto = {
|
|
110
|
+
method: 'POST',
|
|
111
|
+
url: `${createDomain(subDomain)}/prebid/multi/${cId}`,
|
|
112
|
+
data: data
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
_each(ext, (value, key) => {
|
|
116
|
+
dto.data['ext.' + key] = value;
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
return dto;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function appendUserIdsToRequestPayload(payloadRef, userIds) {
|
|
123
|
+
let key;
|
|
124
|
+
_each(userIds, (userId, idSystemProviderName) => {
|
|
125
|
+
if (SUPPORTED_ID_SYSTEMS[idSystemProviderName]) {
|
|
126
|
+
key = `uid.${idSystemProviderName}`;
|
|
127
|
+
|
|
128
|
+
switch (idSystemProviderName) {
|
|
129
|
+
case 'digitrustid':
|
|
130
|
+
payloadRef[key] = deepAccess(userId, 'data.id');
|
|
131
|
+
break;
|
|
132
|
+
case 'lipb':
|
|
133
|
+
payloadRef[key] = userId.lipbid;
|
|
134
|
+
break;
|
|
135
|
+
case 'parrableId':
|
|
136
|
+
payloadRef[key] = userId.eid;
|
|
137
|
+
break;
|
|
138
|
+
case 'id5id':
|
|
139
|
+
payloadRef[key] = userId.uid;
|
|
140
|
+
break;
|
|
141
|
+
default:
|
|
142
|
+
payloadRef[key] = userId;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function buildRequests(validBidRequests, bidderRequest) {
|
|
149
|
+
const topWindowUrl = bidderRequest.refererInfo.page || bidderRequest.refererInfo.topmostLocation;
|
|
150
|
+
const requests = [];
|
|
151
|
+
validBidRequests.forEach(validBidRequest => {
|
|
152
|
+
const sizes = parseSizesInput(validBidRequest.sizes);
|
|
153
|
+
const request = buildRequest(validBidRequest, topWindowUrl, sizes, bidderRequest);
|
|
154
|
+
requests.push(request);
|
|
155
|
+
});
|
|
156
|
+
return requests;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function interpretResponse(serverResponse, request) {
|
|
160
|
+
if (!serverResponse || !serverResponse.body) {
|
|
161
|
+
return [];
|
|
162
|
+
}
|
|
163
|
+
const { bidId } = request.data;
|
|
164
|
+
const { results } = serverResponse.body;
|
|
165
|
+
|
|
166
|
+
let output = [];
|
|
167
|
+
|
|
168
|
+
try {
|
|
169
|
+
results.forEach(result => {
|
|
170
|
+
const { creativeId, ad, price, exp, width, height, currency, advertiserDomains } = result;
|
|
171
|
+
if (!ad || !price) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
output.push({
|
|
175
|
+
requestId: bidId,
|
|
176
|
+
cpm: price,
|
|
177
|
+
width: width,
|
|
178
|
+
height: height,
|
|
179
|
+
creativeId: creativeId,
|
|
180
|
+
currency: currency || CURRENCY,
|
|
181
|
+
netRevenue: true,
|
|
182
|
+
ttl: exp || TTL_SECONDS,
|
|
183
|
+
ad: ad,
|
|
184
|
+
meta: {
|
|
185
|
+
advertiserDomains: advertiserDomains || []
|
|
186
|
+
}
|
|
187
|
+
})
|
|
188
|
+
});
|
|
189
|
+
return output;
|
|
190
|
+
} catch (e) {
|
|
191
|
+
return [];
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function getUserSyncs(syncOptions, responses, gdprConsent = {}, uspConsent = '') {
|
|
196
|
+
let syncs = [];
|
|
197
|
+
const { iframeEnabled, pixelEnabled } = syncOptions;
|
|
198
|
+
const { gdprApplies, consentString = '' } = gdprConsent;
|
|
199
|
+
|
|
200
|
+
const cidArr = responses.filter(resp => deepAccess(resp, 'body.cid')).map(resp => resp.body.cid).filter(uniques);
|
|
201
|
+
const params = `?cid=${encodeURIComponent(cidArr.join(','))}&gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${encodeURIComponent(consentString || '')}&us_privacy=${encodeURIComponent(uspConsent || '')}`
|
|
202
|
+
if (iframeEnabled) {
|
|
203
|
+
syncs.push({
|
|
204
|
+
type: 'iframe',
|
|
205
|
+
url: `https://sync.kueezrtb.com/api/sync/iframe/${params}`
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
if (pixelEnabled) {
|
|
209
|
+
syncs.push({
|
|
210
|
+
type: 'image',
|
|
211
|
+
url: `https://sync.kueezrtb.com/api/sync/image/${params}`
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
return syncs;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export function hashCode(s, prefix = '_') {
|
|
218
|
+
const l = s.length;
|
|
219
|
+
let h = 0
|
|
220
|
+
let i = 0;
|
|
221
|
+
if (l > 0) {
|
|
222
|
+
while (i < l) { h = (h << 5) - h + s.charCodeAt(i++) | 0; }
|
|
223
|
+
}
|
|
224
|
+
return prefix + h;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export function getUniqueDealId(key, expiry = UNIQUE_DEAL_ID_EXPIRY) {
|
|
228
|
+
const storageKey = `u_${key}`;
|
|
229
|
+
const now = Date.now();
|
|
230
|
+
const data = getStorageItem(storageKey);
|
|
231
|
+
let uniqueId;
|
|
232
|
+
|
|
233
|
+
if (!data || !data.value || now - data.created > expiry) {
|
|
234
|
+
uniqueId = `${key}_${now.toString()}`;
|
|
235
|
+
setStorageItem(storageKey, uniqueId);
|
|
236
|
+
} else {
|
|
237
|
+
uniqueId = data.value;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return uniqueId;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export function getStorageItem(key) {
|
|
244
|
+
try {
|
|
245
|
+
return tryParseJSON(storage.getDataFromLocalStorage(key));
|
|
246
|
+
} catch (e) { }
|
|
247
|
+
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export function setStorageItem(key, value, timestamp) {
|
|
252
|
+
try {
|
|
253
|
+
const created = timestamp || Date.now();
|
|
254
|
+
const data = JSON.stringify({ value, created });
|
|
255
|
+
storage.setDataInLocalStorage(key, data);
|
|
256
|
+
} catch (e) { }
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export function tryParseJSON(value) {
|
|
260
|
+
try {
|
|
261
|
+
return JSON.parse(value);
|
|
262
|
+
} catch (e) {
|
|
263
|
+
return value;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export const spec = {
|
|
268
|
+
code: BIDDER_CODE,
|
|
269
|
+
version: BIDDER_VERSION,
|
|
270
|
+
gvlid: GVLID,
|
|
271
|
+
supportedMediaTypes: [BANNER],
|
|
272
|
+
isBidRequestValid,
|
|
273
|
+
buildRequests,
|
|
274
|
+
interpretResponse,
|
|
275
|
+
getUserSyncs
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
registerBidder(spec);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
**Module Name:** Kueez RTB Bidder Adapter
|
|
4
|
+
|
|
5
|
+
**Module Type:** Bidder Adapter
|
|
6
|
+
|
|
7
|
+
**Maintainer:** rtb@kueez.com
|
|
8
|
+
|
|
9
|
+
# Description
|
|
10
|
+
|
|
11
|
+
Module that connects to Kueez's demand sources.
|
|
12
|
+
|
|
13
|
+
# Test Parameters
|
|
14
|
+
```js
|
|
15
|
+
var adUnits = [
|
|
16
|
+
{
|
|
17
|
+
code: 'test-ad',
|
|
18
|
+
sizes: [[300, 250]],
|
|
19
|
+
bids: [
|
|
20
|
+
{
|
|
21
|
+
bidder: 'kueezrtb',
|
|
22
|
+
params: {
|
|
23
|
+
cId: '562524b21b1c1f08117fc7f9',
|
|
24
|
+
pId: '59ac17c192832d0011283fe3',
|
|
25
|
+
bidFloor: 0.0001,
|
|
26
|
+
ext: {
|
|
27
|
+
param1: 'loremipsum',
|
|
28
|
+
param2: 'dolorsitamet'
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
];
|
|
35
|
+
```
|
|
@@ -254,9 +254,14 @@ export const parseBidResponse = (bid, previousBidResponse) => {
|
|
|
254
254
|
const validAdomains = Array.isArray(adomains) && adomains.filter(domain => typeof domain === 'string');
|
|
255
255
|
return validAdomains && validAdomains.length > 0 ? validAdomains.slice(0, 10) : undefined
|
|
256
256
|
},
|
|
257
|
+
'networkId', () => {
|
|
258
|
+
const networkId = deepAccess(bid, 'meta.networkId');
|
|
259
|
+
// if not a valid after this, set to undefined so it gets filtered out
|
|
260
|
+
return (networkId && networkId.toString()) || undefined;
|
|
261
|
+
},
|
|
257
262
|
'conversionError', conversionError => conversionError === true || undefined, // only pass if exactly true
|
|
258
263
|
'ogCurrency',
|
|
259
|
-
'ogPrice'
|
|
264
|
+
'ogPrice',
|
|
260
265
|
]);
|
|
261
266
|
}
|
|
262
267
|
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { submodule } from '../src/hook.js';
|
|
2
|
+
import {ajax} from '../src/ajax.js';
|
|
3
|
+
import {deepAccess, logError, logInfo, mergeDeep} from '../src/utils.js';
|
|
4
|
+
import {getStorageManager} from '../src/storageManager.js';
|
|
5
|
+
import {getRefererInfo} from '../src/refererDetection.js';
|
|
6
|
+
|
|
7
|
+
const MODULE_NAME = 'realTimeData';
|
|
8
|
+
const SUBMODULE_NAME = 'mgid';
|
|
9
|
+
const MGID_RTD_API_URL = 'https://servicer.mgid.com/sda';
|
|
10
|
+
const MGUID_LOCAL_STORAGE_KEY = 'mguid';
|
|
11
|
+
const ORTB2_NAME = 'www.mgid.com'
|
|
12
|
+
|
|
13
|
+
const GVLID = 358;
|
|
14
|
+
/** @type {?Object} */
|
|
15
|
+
export const storage = getStorageManager({
|
|
16
|
+
gvlid: GVLID,
|
|
17
|
+
moduleName: SUBMODULE_NAME
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
function init(moduleConfig) {
|
|
21
|
+
if (!moduleConfig?.params?.clientSiteId) {
|
|
22
|
+
logError('Mgid clientSiteId is not set!');
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function getBidRequestData(reqBidsConfigObj, onDone, moduleConfig, userConsent) {
|
|
29
|
+
let mguid;
|
|
30
|
+
try {
|
|
31
|
+
mguid = storage.getDataFromLocalStorage(MGUID_LOCAL_STORAGE_KEY);
|
|
32
|
+
} catch (e) {
|
|
33
|
+
logInfo(`Can't get mguid from localstorage`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const params = [
|
|
37
|
+
{
|
|
38
|
+
name: 'gdprApplies',
|
|
39
|
+
data: typeof userConsent?.gdpr?.gdprApplies !== 'undefined' ? userConsent?.gdpr?.gdprApplies + '' : undefined,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'consentData',
|
|
43
|
+
data: userConsent?.gdpr?.consentString,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'uspString',
|
|
47
|
+
data: userConsent?.usp,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'cxurl',
|
|
51
|
+
data: encodeURIComponent(getContextUrl()),
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'muid',
|
|
55
|
+
data: mguid,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: 'clientSiteId',
|
|
59
|
+
data: moduleConfig?.params?.clientSiteId,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: 'cxlang',
|
|
63
|
+
data: deepAccess(reqBidsConfigObj.ortb2Fragments.global, 'site.content.language'),
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
const url = MGID_RTD_API_URL + '?' + params.filter((p) => p.data).map((p) => p.name + '=' + p.data).join('&');
|
|
68
|
+
|
|
69
|
+
let isDone = false;
|
|
70
|
+
|
|
71
|
+
ajax(url, {
|
|
72
|
+
success: (response, req) => {
|
|
73
|
+
if (req.status === 200) {
|
|
74
|
+
try {
|
|
75
|
+
const data = JSON.parse(response);
|
|
76
|
+
const ortb2 = reqBidsConfigObj?.ortb2Fragments?.global || {};
|
|
77
|
+
|
|
78
|
+
mergeDeep(ortb2, getDataForMerge(data));
|
|
79
|
+
|
|
80
|
+
if (data?.muid) {
|
|
81
|
+
try {
|
|
82
|
+
mguid = storage.setDataInLocalStorage(MGUID_LOCAL_STORAGE_KEY, data.muid);
|
|
83
|
+
} catch (e) {
|
|
84
|
+
logInfo(`Can't set mguid to localstorage`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
onDone();
|
|
89
|
+
isDone = true;
|
|
90
|
+
} catch (e) {
|
|
91
|
+
onDone();
|
|
92
|
+
isDone = true;
|
|
93
|
+
|
|
94
|
+
logError('Unable to parse Mgid RTD data', e);
|
|
95
|
+
}
|
|
96
|
+
} else {
|
|
97
|
+
onDone();
|
|
98
|
+
isDone = true;
|
|
99
|
+
|
|
100
|
+
logError('Mgid RTD wrong response status');
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
error: () => {
|
|
104
|
+
onDone();
|
|
105
|
+
isDone = true;
|
|
106
|
+
|
|
107
|
+
logError('Unable to get Mgid RTD data');
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
null, {
|
|
111
|
+
method: 'GET',
|
|
112
|
+
withCredentials: false,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
setTimeout(function () {
|
|
116
|
+
if (!isDone) {
|
|
117
|
+
onDone();
|
|
118
|
+
logInfo('Mgid RTD timeout');
|
|
119
|
+
isDone = true;
|
|
120
|
+
}
|
|
121
|
+
}, moduleConfig.params.timeout || 1000);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function getContextUrl() {
|
|
125
|
+
const refererInfo = getRefererInfo();
|
|
126
|
+
|
|
127
|
+
let resultUrl = refererInfo.canonicalUrl || refererInfo.topmostLocation;
|
|
128
|
+
|
|
129
|
+
const metaElements = document.getElementsByTagName('meta');
|
|
130
|
+
for (let i = 0; i < metaElements.length; i++) {
|
|
131
|
+
if (metaElements[i].getAttribute('property') === 'og:url') {
|
|
132
|
+
resultUrl = metaElements[i].content;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return resultUrl;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function getDataForMerge(responseData) {
|
|
140
|
+
let siteData = {
|
|
141
|
+
name: ORTB2_NAME
|
|
142
|
+
};
|
|
143
|
+
let userData = {
|
|
144
|
+
name: ORTB2_NAME
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
if (responseData.siteSegments) {
|
|
148
|
+
siteData.segment = responseData.siteSegments.map((segmentId) => ({ id: segmentId }));
|
|
149
|
+
}
|
|
150
|
+
if (responseData.siteSegtax) {
|
|
151
|
+
siteData.ext = {
|
|
152
|
+
segtax: responseData.siteSegtax
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (responseData.userSegments) {
|
|
157
|
+
userData.segment = responseData.userSegments.map((segmentId) => ({ id: segmentId }));
|
|
158
|
+
}
|
|
159
|
+
if (responseData.userSegtax) {
|
|
160
|
+
userData.ext = {
|
|
161
|
+
segtax: responseData.userSegtax
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
let result = {};
|
|
166
|
+
if (siteData.segment || siteData.ext) {
|
|
167
|
+
result.site = {
|
|
168
|
+
content: {
|
|
169
|
+
data: [siteData],
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (userData.segment || userData.ext) {
|
|
175
|
+
result.user = {
|
|
176
|
+
data: [userData],
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** @type {RtdSubmodule} */
|
|
184
|
+
export const mgidSubmodule = {
|
|
185
|
+
name: SUBMODULE_NAME,
|
|
186
|
+
init: init,
|
|
187
|
+
getBidRequestData: getBidRequestData,
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
submodule(MODULE_NAME, mgidSubmodule);
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
Module Name: Mgid RTD Provider
|
|
5
|
+
Module Type: RTD Provider
|
|
6
|
+
Maintainer: prebid@mgid.com
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
# Description
|
|
10
|
+
|
|
11
|
+
Mgid RTD module allows you to enrich bid data with contextual and audience signals, based on IAB taxonomies.
|
|
12
|
+
|
|
13
|
+
## Configuration
|
|
14
|
+
|
|
15
|
+
This module is configured as part of the `realTimeData.dataProviders` object.
|
|
16
|
+
|
|
17
|
+
{: .table .table-bordered .table-striped }
|
|
18
|
+
| Name | Scope | Description | Example | Type |
|
|
19
|
+
|------------|----------|----------------------------------------|---------------|----------|
|
|
20
|
+
| `name ` | required | Real time data module name | `'mgid'` | `string` |
|
|
21
|
+
| `params` | required | | | `Object` |
|
|
22
|
+
| `params.clientSiteId` | required | The client site id provided by Mgid. | `'123456'` | `string` |
|
|
23
|
+
| `params.timeout` | optional | Maximum amount of milliseconds allowed for module to finish working | `1000` | `number` |
|
|
24
|
+
|
|
25
|
+
#### Example
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
pbjs.setConfig({
|
|
29
|
+
realTimeData: {
|
|
30
|
+
dataProviders: [{
|
|
31
|
+
name: 'mgid',
|
|
32
|
+
params: {
|
|
33
|
+
clientSiteId: '123456'
|
|
34
|
+
}
|
|
35
|
+
}]
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Integration
|
|
41
|
+
To install the module, follow these instructions:
|
|
42
|
+
|
|
43
|
+
#### Step 1: Prepare the base Prebid file
|
|
44
|
+
|
|
45
|
+
- Option 1: Use Prebid [Download](/download.html) page to build the prebid package. Ensure that you do check *Mgid Realtime Module* module
|
|
46
|
+
|
|
47
|
+
- Option 2: From the command line, run `gulp build --modules=mgidRtdProvider,...`
|
|
48
|
+
|
|
49
|
+
#### Step 2: Set configuration
|
|
50
|
+
|
|
51
|
+
Enable Mgid Real Time Module using `pbjs.setConfig`. Example is provided in Configuration section.
|
|
@@ -238,7 +238,8 @@ function getDefaultBidderFn (bidder) {
|
|
|
238
238
|
deepSetValue(bid, 'params.visitor.p_standard', data.ac)
|
|
239
239
|
}
|
|
240
240
|
if (data.rubicon && data.rubicon.length) {
|
|
241
|
-
|
|
241
|
+
const rubiconCohorts = deepAccess(bid, 'params.video') ? data.rubicon.map(String) : data.rubicon
|
|
242
|
+
deepSetValue(bid, 'params.visitor.permutive', rubiconCohorts)
|
|
242
243
|
}
|
|
243
244
|
|
|
244
245
|
return bid
|