prebid.js 5.20.0 → 6.3.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 -10
- package/README.md +4 -2
- package/browsers.json +13 -37
- package/gulpfile.js +1 -8
- package/integrationExamples/gpt/weboramaRtdProvider_example.html +23 -14
- package/karma.conf.maker.js +1 -1
- package/modules/33acrossBidAdapter.js +189 -102
- package/modules/adagioBidAdapter.js +1 -1
- package/modules/addefendBidAdapter.js +1 -0
- package/modules/adheseBidAdapter.js +7 -2
- package/modules/adkernelBidAdapter.js +1 -0
- package/modules/adlivetechBidAdapter.md +61 -0
- package/modules/admanBidAdapter.js +1 -0
- package/modules/admixerBidAdapter.js +3 -2
- package/modules/adnuntiusBidAdapter.js +5 -2
- package/modules/adomikAnalyticsAdapter.js +10 -4
- package/modules/adplusBidAdapter.js +203 -0
- package/modules/adplusBidAdapter.md +39 -0
- package/modules/adxcgBidAdapter.js +311 -359
- package/modules/adxcgBidAdapter.md +22 -21
- package/modules/adyoulikeBidAdapter.js +7 -2
- package/modules/appnexusBidAdapter.js +23 -3
- package/modules/beachfrontBidAdapter.js +14 -17
- package/modules/beopBidAdapter.js +5 -3
- package/modules/codefuelBidAdapter.js +1 -3
- package/modules/codefuelBidAdapter.md +3 -3
- package/modules/colossussspBidAdapter.js +7 -0
- package/modules/craftBidAdapter.js +5 -3
- package/modules/criteoBidAdapter.js +1 -1
- package/modules/cwireBidAdapter.js +3 -0
- package/modules/datablocksBidAdapter.js +3 -3
- package/modules/dchain.js +149 -0
- package/modules/dchain.md +45 -0
- package/modules/deepintentBidAdapter.js +1 -1
- package/modules/dspxBidAdapter.js +1 -1
- package/modules/emx_digitalBidAdapter.js +9 -1
- package/modules/engageyaBidAdapter.js +68 -54
- package/modules/freewheel-sspBidAdapter.js +6 -0
- package/modules/futureads.md +48 -0
- package/modules/glimpseBidAdapter.js +44 -16
- package/modules/goldbachBidAdapter.js +1176 -0
- package/modules/goldbachBidAdapter.md +151 -0
- package/modules/gptPreAuction.js +11 -5
- package/modules/gridBidAdapter.js +1 -1
- package/modules/gumgumBidAdapter.js +7 -3
- package/modules/id5IdSystem.md +6 -6
- package/modules/imRtdProvider.js +31 -0
- package/modules/intersectionRtdProvider.js +114 -0
- package/modules/invibesBidAdapter.js +15 -9
- package/modules/ipromBidAdapter.js +79 -0
- package/modules/ixBidAdapter.js +166 -21
- package/modules/kinessoIdSystem.js +1 -1
- package/modules/limelightDigitalBidAdapter.js +2 -1
- package/modules/lotamePanoramaIdSystem.js +80 -8
- package/modules/luponmediaBidAdapter.js +570 -0
- package/modules/mediasquareBidAdapter.js +1 -9
- package/modules/merkleIdSystem.js +5 -0
- package/modules/missenaBidAdapter.js +89 -0
- package/modules/nativoBidAdapter.js +27 -1
- package/modules/nextMillenniumBidAdapter.js +29 -1
- package/modules/oguryBidAdapter.js +2 -1
- package/modules/openxBidAdapter.js +6 -1
- package/modules/prebidServerBidAdapter/index.js +19 -15
- package/modules/pubmaticBidAdapter.js +5 -3
- package/modules/relaidoBidAdapter.js +86 -65
- package/modules/richaudienceBidAdapter.js +2 -3
- package/modules/rtdModule/index.js +48 -18
- package/modules/rubiconBidAdapter.js +10 -8
- package/modules/saambaaBidAdapter.js +420 -0
- package/modules/saambaaBidAdapter.md +65 -68
- package/modules/seedtagBidAdapter.js +6 -0
- package/modules/sharedIdSystem.js +27 -1
- package/modules/smaatoBidAdapter.js +9 -1
- package/modules/smartxBidAdapter.js +17 -1
- package/modules/sspBCBidAdapter.js +34 -3
- package/modules/tappxBidAdapter.js +3 -1
- package/modules/targetVideoBidAdapter.js +187 -0
- package/modules/targetVideoBidAdapter.md +34 -0
- package/modules/trustxBidAdapter.js +10 -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/vidoomyBidAdapter.js +65 -108
- package/modules/visxBidAdapter.js +20 -3
- package/modules/visxBidAdapter.md +4 -6
- package/modules/weboramaRtdProvider.js +288 -73
- package/modules/weboramaRtdProvider.md +27 -10
- package/modules/yahoosspBidAdapter.js +5 -1
- package/modules/yahoosspBidAdapter.md +1 -1
- package/modules/yieldlabBidAdapter.js +41 -10
- package/modules/yieldlabBidAdapter.md +91 -48
- package/modules/yieldoneBidAdapter.js +115 -11
- package/modules/zetaSspBidAdapter.md +33 -1
- package/modules/zeta_global_sspBidAdapter.js +22 -1
- package/package.json +6 -1
- package/plugins/pbjsGlobals.js +28 -1
- package/src/adapterManager.js +14 -8
- package/src/auction.js +3 -2
- package/src/prebid.js +1 -2
- package/src/targeting.js +24 -3
- package/src/utils.js +41 -7
- package/test/spec/integration/faker/googletag.js +6 -0
- package/test/spec/modules/33acrossBidAdapter_spec.js +300 -78
- package/test/spec/modules/adheseBidAdapter_spec.js +27 -1
- package/test/spec/modules/adnuntiusBidAdapter_spec.js +35 -0
- package/test/spec/modules/adomikAnalyticsAdapter_spec.js +3 -1
- package/test/spec/modules/adplusBidAdapter_spec.js +213 -0
- package/test/spec/modules/adxcgBidAdapter_spec.js +820 -571
- package/test/spec/modules/adyoulikeBidAdapter_spec.js +26 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +63 -1
- package/test/spec/modules/beachfrontBidAdapter_spec.js +65 -1
- package/test/spec/modules/codefuelBidAdapter_spec.js +1 -1
- package/test/spec/modules/colossussspBidAdapter_spec.js +9 -0
- package/test/spec/modules/cwireBidAdapter_spec.js +10 -8
- package/test/spec/modules/datablocksBidAdapter_spec.js +3 -3
- package/test/spec/modules/dchain_spec.js +329 -0
- package/test/spec/modules/emx_digitalBidAdapter_spec.js +10 -0
- package/test/spec/modules/engageyaBidAdapter_spec.js +231 -95
- package/test/spec/modules/eplanningBidAdapter_spec.js +8 -8
- package/test/spec/modules/freewheel-sspBidAdapter_spec.js +19 -0
- package/test/spec/modules/glimpseBidAdapter_spec.js +33 -0
- package/test/spec/modules/goldbachBidAdapter_spec.js +1359 -0
- package/test/spec/modules/gptPreAuction_spec.js +58 -4
- package/test/spec/modules/gumgumBidAdapter_spec.js +6 -0
- package/test/spec/modules/imRtdProvider_spec.js +25 -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/ixBidAdapter_spec.js +285 -2
- package/test/spec/modules/konduitWrapper_spec.js +0 -1
- package/test/spec/modules/limelightDigitalBidAdapter_spec.js +10 -7
- package/test/spec/modules/lotamePanoramaIdSystem_spec.js +227 -0
- package/test/spec/modules/luponmediaBidAdapter_spec.js +412 -0
- package/test/spec/modules/mediasquareBidAdapter_spec.js +4 -4
- package/test/spec/modules/merkleIdSystem_spec.js +18 -0
- package/test/spec/modules/missenaBidAdapter_spec.js +134 -0
- package/test/spec/modules/nativoBidAdapter_spec.js +35 -18
- package/test/spec/modules/nextMillenniumBidAdapter_spec.js +18 -0
- 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 +62 -2
- package/test/spec/modules/pubmaticBidAdapter_spec.js +1 -1
- package/test/spec/modules/realTimeDataModule_spec.js +135 -49
- package/test/spec/modules/relaidoBidAdapter_spec.js +71 -63
- package/test/spec/modules/richaudienceBidAdapter_spec.js +2 -2
- package/test/spec/modules/rubiconBidAdapter_spec.js +17 -0
- package/test/spec/modules/seedtagBidAdapter_spec.js +3 -0
- package/test/spec/modules/sharedIdSystem_spec.js +52 -6
- package/test/spec/modules/smaatoBidAdapter_spec.js +61 -0
- package/test/spec/modules/smartxBidAdapter_spec.js +9 -0
- package/test/spec/modules/sspBCBidAdapter_spec.js +33 -3
- package/test/spec/modules/tappxBidAdapter_spec.js +4 -0
- package/test/spec/modules/targetVideoBidAdapter_spec.js +96 -0
- package/test/spec/modules/trustxBidAdapter_spec.js +42 -0
- package/test/spec/modules/userId_spec.js +51 -0
- package/test/spec/modules/vidoomyBidAdapter_spec.js +32 -13
- package/test/spec/modules/visxBidAdapter_spec.js +121 -5
- package/test/spec/modules/weboramaRtdProvider_spec.js +408 -214
- package/test/spec/modules/yahoosspBidAdapter_spec.js +28 -1
- package/test/spec/modules/yieldlabBidAdapter_spec.js +81 -0
- package/test/spec/modules/yieldoneBidAdapter_spec.js +299 -53
- package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +33 -1
- package/test/spec/unit/core/adapterManager_spec.js +24 -6
- package/test/spec/unit/core/targeting_spec.js +116 -0
- package/test/spec/utils_spec.js +38 -0
- package/wdio.conf.js +1 -1
package/modules/ixBidAdapter.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { deepAccess, parseGPTSingleSizeArray, inIframe, deepClone, logError, logWarn, isFn, contains, isInteger, isArray, deepSetValue, parseQueryStringParameters, isEmpty, mergeDeep, convertTypes } from '../src/utils.js';
|
|
2
2
|
import { BANNER, VIDEO } from '../src/mediaTypes.js';
|
|
3
3
|
import { config } from '../src/config.js';
|
|
4
|
+
import { EVENTS } from '../src/constants.json';
|
|
5
|
+
import { getStorageManager } from '../src/storageManager.js';
|
|
6
|
+
import events from '../src/events.js';
|
|
4
7
|
import find from 'core-js-pure/features/array/find.js';
|
|
5
8
|
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
6
9
|
import { INSTREAM, OUTSTREAM } from '../src/video.js';
|
|
@@ -20,15 +23,23 @@ const VIDEO_TIME_TO_LIVE = 3600; // 1hr
|
|
|
20
23
|
const NET_REVENUE = true;
|
|
21
24
|
const MAX_REQUEST_SIZE = 8000;
|
|
22
25
|
const MAX_REQUEST_LIMIT = 4;
|
|
23
|
-
|
|
24
26
|
const PRICE_TO_DOLLAR_FACTOR = {
|
|
25
27
|
JPY: 1
|
|
26
28
|
};
|
|
27
29
|
const USER_SYNC_URL = 'https://js-sec.indexww.com/um/ixmatch.html';
|
|
28
30
|
const RENDERER_URL = 'https://js-sec.indexww.com/htv/video-player.js';
|
|
29
31
|
const FLOOR_SOURCE = { PBJS: 'p', IX: 'x' };
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
export const ERROR_CODES = {
|
|
33
|
+
BID_SIZE_INVALID_FORMAT: 1,
|
|
34
|
+
BID_SIZE_NOT_INCLUDED: 2,
|
|
35
|
+
PROPERTY_NOT_INCLUDED: 3,
|
|
36
|
+
SITE_ID_INVALID_VALUE: 4,
|
|
37
|
+
BID_FLOOR_INVALID_FORMAT: 5,
|
|
38
|
+
IX_FPD_EXCEEDS_MAX_SIZE: 6,
|
|
39
|
+
EXCEEDS_MAX_SIZE: 7,
|
|
40
|
+
PB_FPD_EXCEEDS_MAX_SIZE: 8,
|
|
41
|
+
VIDEO_DURATION_INVALID: 9
|
|
42
|
+
};
|
|
32
43
|
const FIRST_PARTY_DATA = {
|
|
33
44
|
SITE: [
|
|
34
45
|
'id', 'name', 'domain', 'cat', 'sectioncat', 'pagecat', 'page', 'ref', 'search', 'mobile',
|
|
@@ -36,7 +47,6 @@ const FIRST_PARTY_DATA = {
|
|
|
36
47
|
],
|
|
37
48
|
USER: ['id', 'buyeruid', 'yob', 'gender', 'keywords', 'customdata', 'geo', 'data', 'ext']
|
|
38
49
|
};
|
|
39
|
-
|
|
40
50
|
const SOURCE_RTI_MAPPING = {
|
|
41
51
|
'liveramp.com': 'idl',
|
|
42
52
|
'netid.de': 'NETID',
|
|
@@ -45,7 +55,6 @@ const SOURCE_RTI_MAPPING = {
|
|
|
45
55
|
'uidapi.com': 'UID2',
|
|
46
56
|
'adserver.org': 'TDID'
|
|
47
57
|
};
|
|
48
|
-
|
|
49
58
|
const PROVIDERS = [
|
|
50
59
|
'britepoolid',
|
|
51
60
|
'id5id',
|
|
@@ -62,9 +71,7 @@ const PROVIDERS = [
|
|
|
62
71
|
'TDID',
|
|
63
72
|
'flocId'
|
|
64
73
|
];
|
|
65
|
-
|
|
66
74
|
const REQUIRED_VIDEO_PARAMS = ['mimes', 'minduration', 'maxduration']; // note: protocol/protocols is also reqd
|
|
67
|
-
|
|
68
75
|
const VIDEO_PARAMS_ALLOW_LIST = [
|
|
69
76
|
'mimes', 'minduration', 'maxduration', 'protocols', 'protocol',
|
|
70
77
|
'startdelay', 'placement', 'linearity', 'skip', 'skipmin',
|
|
@@ -73,6 +80,17 @@ const VIDEO_PARAMS_ALLOW_LIST = [
|
|
|
73
80
|
'delivery', 'pos', 'companionad', 'api', 'companiontype', 'ext',
|
|
74
81
|
'playerSize', 'w', 'h'
|
|
75
82
|
];
|
|
83
|
+
const LOCAL_STORAGE_KEY = 'ixdiag';
|
|
84
|
+
let hasRegisteredHandler = false;
|
|
85
|
+
export const storage = getStorageManager(GLOBAL_VENDOR_ID, BIDDER_CODE);
|
|
86
|
+
|
|
87
|
+
// Possible values for bidResponse.seatBid[].bid[].mtype which indicates the type of the creative markup so that it can properly be associated with the right sub-object of the BidRequest.Imp.
|
|
88
|
+
const MEDIA_TYPES = {
|
|
89
|
+
Banner: 1,
|
|
90
|
+
Video: 2,
|
|
91
|
+
Audio: 3,
|
|
92
|
+
Native: 4
|
|
93
|
+
}
|
|
76
94
|
|
|
77
95
|
/**
|
|
78
96
|
* Transform valid bid request config object to banner impression object that will be sent to ad server.
|
|
@@ -125,7 +143,10 @@ function bidToVideoImp(bid) {
|
|
|
125
143
|
}
|
|
126
144
|
|
|
127
145
|
if (imp.video.minduration > imp.video.maxduration) {
|
|
128
|
-
logError(
|
|
146
|
+
logError(
|
|
147
|
+
`IX Bid Adapter: video minduration [${imp.video.minduration}] cannot be greater than video maxduration [${imp.video.maxduration}]`,
|
|
148
|
+
{ bidder: BIDDER_CODE, code: ERROR_CODES.VIDEO_DURATION_INVALID }
|
|
149
|
+
);
|
|
129
150
|
return {};
|
|
130
151
|
}
|
|
131
152
|
|
|
@@ -262,9 +283,14 @@ function parseBid(rawBid, currency, bidRequest) {
|
|
|
262
283
|
bid.currency = currency;
|
|
263
284
|
bid.creativeId = rawBid.hasOwnProperty('crid') ? rawBid.crid : '-';
|
|
264
285
|
|
|
265
|
-
|
|
266
|
-
|
|
286
|
+
if (rawBid.mtype == MEDIA_TYPES.Video) {
|
|
287
|
+
bid.vastXml = rawBid.adm
|
|
288
|
+
} else if (rawBid.ext && rawBid.ext.vasturl) {
|
|
267
289
|
bid.vastUrl = rawBid.ext.vasturl
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// in the event of a video
|
|
293
|
+
if ((rawBid.ext && rawBid.ext.vasturl) || rawBid.mtype == MEDIA_TYPES.Video) {
|
|
268
294
|
bid.width = bidRequest.video.w;
|
|
269
295
|
bid.height = bidRequest.video.h;
|
|
270
296
|
bid.mediaType = VIDEO;
|
|
@@ -498,6 +524,13 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
|
|
|
498
524
|
r.ext.ixdiag[key] = ixdiag[key];
|
|
499
525
|
}
|
|
500
526
|
|
|
527
|
+
// Get cached errors stored in LocalStorage
|
|
528
|
+
const cachedErrors = getCachedErrors();
|
|
529
|
+
|
|
530
|
+
if (!isEmpty(cachedErrors)) {
|
|
531
|
+
r.ext.ixdiag.err = cachedErrors;
|
|
532
|
+
}
|
|
533
|
+
|
|
501
534
|
// if an schain is provided, send it along
|
|
502
535
|
if (validBidRequests[0].schain) {
|
|
503
536
|
r.source = {
|
|
@@ -576,7 +609,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
|
|
|
576
609
|
const baseRequestSize = `${baseUrl}${parseQueryStringParameters({ ...payload, r: JSON.stringify(r) })}`.length;
|
|
577
610
|
|
|
578
611
|
if (baseRequestSize > MAX_REQUEST_SIZE) {
|
|
579
|
-
logError('
|
|
612
|
+
logError('IX Bid Adapter: Base request size has exceeded maximum request size.', { bidder: BIDDER_CODE, code: ERROR_CODES.EXCEEDS_MAX_SIZE });
|
|
580
613
|
return requests;
|
|
581
614
|
}
|
|
582
615
|
|
|
@@ -606,7 +639,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
|
|
|
606
639
|
}
|
|
607
640
|
currentRequestSize += fpdRequestSize;
|
|
608
641
|
} else {
|
|
609
|
-
logError('
|
|
642
|
+
logError('IX Bid Adapter: IX config FPD request size has exceeded maximum request size.', { bidder: BIDDER_CODE, code: ERROR_CODES.IX_FPD_EXCEEDS_MAX_SIZE });
|
|
610
643
|
}
|
|
611
644
|
}
|
|
612
645
|
|
|
@@ -713,7 +746,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
|
|
|
713
746
|
const fpdRequestSize = encodeURIComponent(JSON.stringify({ ...site, ...user })).length;
|
|
714
747
|
currentRequestSize += fpdRequestSize;
|
|
715
748
|
} else {
|
|
716
|
-
logError('
|
|
749
|
+
logError('IX Bid Adapter: FPD request size has exceeded maximum request size.', { bidder: BIDDER_CODE, code: ERROR_CODES.PB_FPD_EXCEEDS_MAX_SIZE });
|
|
717
750
|
}
|
|
718
751
|
}
|
|
719
752
|
|
|
@@ -946,10 +979,99 @@ function createMissingBannerImp(bid, imp, newSize) {
|
|
|
946
979
|
}
|
|
947
980
|
|
|
948
981
|
/**
|
|
982
|
+
* @typedef {Array[message: string, err: Object<bidder: string, code: number>]} ErrorData
|
|
983
|
+
* @property {string} message - The error message.
|
|
984
|
+
* @property {object} err - The error object.
|
|
985
|
+
* @property {string} err.bidder - The bidder of the error.
|
|
986
|
+
* @property {string} err.code - The error code.
|
|
987
|
+
*/
|
|
988
|
+
|
|
989
|
+
/**
|
|
990
|
+
* Error Event handler that receives type and arguments in a data object.
|
|
991
|
+
*
|
|
992
|
+
* @param {ErrorData} data
|
|
993
|
+
*/
|
|
994
|
+
function errorEventHandler(data) {
|
|
995
|
+
if (!storage.localStorageIsEnabled()) {
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
let currentStorage;
|
|
1000
|
+
|
|
1001
|
+
try {
|
|
1002
|
+
currentStorage = JSON.parse(storage.getDataFromLocalStorage(LOCAL_STORAGE_KEY) || '{}');
|
|
1003
|
+
} catch (e) {
|
|
1004
|
+
logWarn('ix can not read ixdiag from localStorage.');
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
const todayDate = new Date();
|
|
1008
|
+
|
|
1009
|
+
Object.keys(currentStorage).map((errorDate) => {
|
|
1010
|
+
const date = new Date(errorDate);
|
|
1011
|
+
|
|
1012
|
+
if (date.setDate(date.getDate() + 7) - todayDate < 0) {
|
|
1013
|
+
delete currentStorage[errorDate];
|
|
1014
|
+
}
|
|
1015
|
+
});
|
|
1016
|
+
|
|
1017
|
+
if (data.type === 'ERROR' && data.arguments && data.arguments[1] && data.arguments[1].bidder === BIDDER_CODE) {
|
|
1018
|
+
const todayString = todayDate.toISOString().slice(0, 10);
|
|
1019
|
+
|
|
1020
|
+
const errorCode = data.arguments[1].code;
|
|
1021
|
+
|
|
1022
|
+
if (errorCode) {
|
|
1023
|
+
currentStorage[todayString] = currentStorage[todayString] || {};
|
|
1024
|
+
|
|
1025
|
+
if (!Number(currentStorage[todayString][errorCode])) {
|
|
1026
|
+
currentStorage[todayString][errorCode] = 0;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
currentStorage[todayString][errorCode]++;
|
|
1030
|
+
};
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
storage.setDataInLocalStorage(LOCAL_STORAGE_KEY, JSON.stringify(currentStorage));
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
/**
|
|
1037
|
+
* Get ixdiag stored in LocalStorage and format to be added to request payload
|
|
1038
|
+
*
|
|
1039
|
+
* @returns {Object} Object with error codes and counts
|
|
1040
|
+
*/
|
|
1041
|
+
function getCachedErrors() {
|
|
1042
|
+
if (!storage.localStorageIsEnabled()) {
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
const errors = {};
|
|
1047
|
+
let currentStorage;
|
|
1048
|
+
|
|
1049
|
+
try {
|
|
1050
|
+
currentStorage = JSON.parse(storage.getDataFromLocalStorage(LOCAL_STORAGE_KEY) || '{}');
|
|
1051
|
+
} catch (e) {
|
|
1052
|
+
logError('ix can not read ixdiag from localStorage.');
|
|
1053
|
+
return null;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
Object.keys(currentStorage).forEach((date) => {
|
|
1057
|
+
Object.keys(currentStorage[date]).forEach((code) => {
|
|
1058
|
+
if (typeof currentStorage[date][code] === 'number') {
|
|
1059
|
+
errors[code] = errors[code]
|
|
1060
|
+
? errors[code] + currentStorage[date][code]
|
|
1061
|
+
: currentStorage[date][code];
|
|
1062
|
+
}
|
|
1063
|
+
});
|
|
1064
|
+
});
|
|
1065
|
+
|
|
1066
|
+
return errors;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
/**
|
|
1070
|
+
*
|
|
949
1071
|
* Initialize Outstream Renderer
|
|
950
1072
|
* @param {Object} bid
|
|
951
1073
|
*/
|
|
952
|
-
function outstreamRenderer
|
|
1074
|
+
function outstreamRenderer(bid) {
|
|
953
1075
|
bid.renderer.push(() => {
|
|
954
1076
|
var config = {
|
|
955
1077
|
width: bid.width,
|
|
@@ -957,7 +1079,13 @@ function outstreamRenderer (bid) {
|
|
|
957
1079
|
timeout: 3000
|
|
958
1080
|
};
|
|
959
1081
|
|
|
960
|
-
|
|
1082
|
+
// IXOutstreamPlayer supports both vastUrl and vastXml, so we can pass either.
|
|
1083
|
+
// Since vastUrl is going to be deprecated from exchange response, vastXml takes priority.
|
|
1084
|
+
if (bid.vastXml) {
|
|
1085
|
+
window.IXOutstreamPlayer(bid.vastXml, bid.adUnitCode, config);
|
|
1086
|
+
} else {
|
|
1087
|
+
window.IXOutstreamPlayer(bid.vastUrl, bid.adUnitCode, config);
|
|
1088
|
+
}
|
|
961
1089
|
});
|
|
962
1090
|
}
|
|
963
1091
|
|
|
@@ -966,7 +1094,7 @@ function outstreamRenderer (bid) {
|
|
|
966
1094
|
* @param {string} id
|
|
967
1095
|
* @returns {Renderer}
|
|
968
1096
|
*/
|
|
969
|
-
function createRenderer
|
|
1097
|
+
function createRenderer(id) {
|
|
970
1098
|
const renderer = Renderer.install({
|
|
971
1099
|
id: id,
|
|
972
1100
|
url: RENDERER_URL,
|
|
@@ -1000,6 +1128,12 @@ export const spec = {
|
|
|
1000
1128
|
* @return {boolean} True if this is a valid bid, and false otherwise.
|
|
1001
1129
|
*/
|
|
1002
1130
|
isBidRequestValid: function (bid) {
|
|
1131
|
+
if (!hasRegisteredHandler) {
|
|
1132
|
+
events.on(EVENTS.AUCTION_DEBUG, errorEventHandler);
|
|
1133
|
+
events.on(EVENTS.AD_RENDER_FAILED, errorEventHandler);
|
|
1134
|
+
hasRegisteredHandler = true;
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1003
1137
|
const paramsVideoRef = deepAccess(bid, 'params.video');
|
|
1004
1138
|
const paramsSize = deepAccess(bid, 'params.size');
|
|
1005
1139
|
const mediaTypeBannerSizes = deepAccess(bid, 'mediaTypes.banner.sizes');
|
|
@@ -1009,6 +1143,7 @@ export const spec = {
|
|
|
1009
1143
|
const hasBidFloorCur = bid.params.hasOwnProperty('bidFloorCur');
|
|
1010
1144
|
|
|
1011
1145
|
if (bid.hasOwnProperty('mediaType') && !(contains(SUPPORTED_AD_TYPES, bid.mediaType))) {
|
|
1146
|
+
logWarn('IX Bid Adapter: media type is not supported.');
|
|
1012
1147
|
return false;
|
|
1013
1148
|
}
|
|
1014
1149
|
|
|
@@ -1020,26 +1155,26 @@ export const spec = {
|
|
|
1020
1155
|
// since there is an ix bidder level size, make sure its valid
|
|
1021
1156
|
const ixSize = getFirstSize(paramsSize);
|
|
1022
1157
|
if (!ixSize) {
|
|
1023
|
-
logError('
|
|
1158
|
+
logError('IX Bid Adapter: size has invalid format.', { bidder: BIDDER_CODE, code: ERROR_CODES.BID_SIZE_INVALID_FORMAT });
|
|
1024
1159
|
return false;
|
|
1025
1160
|
}
|
|
1026
1161
|
// check if the ix bidder level size, is present in ad unit level
|
|
1027
1162
|
if (!includesSize(bid.sizes, ixSize) &&
|
|
1028
1163
|
!(includesSize(mediaTypeVideoPlayerSize, ixSize)) &&
|
|
1029
1164
|
!(includesSize(mediaTypeBannerSizes, ixSize))) {
|
|
1030
|
-
logError('
|
|
1165
|
+
logError('IX Bid Adapter: bid size is not included in ad unit sizes or player size.', { bidder: BIDDER_CODE, code: ERROR_CODES.BID_SIZE_NOT_INCLUDED });
|
|
1031
1166
|
return false;
|
|
1032
1167
|
}
|
|
1033
1168
|
}
|
|
1034
1169
|
|
|
1035
1170
|
if (typeof bid.params.siteId !== 'string' && typeof bid.params.siteId !== 'number') {
|
|
1036
|
-
logError('
|
|
1171
|
+
logError('IX Bid Adapter: siteId must be string or number value.', { bidder: BIDDER_CODE, code: ERROR_CODES.SITE_ID_INVALID_VALUE });
|
|
1037
1172
|
return false;
|
|
1038
1173
|
}
|
|
1039
1174
|
|
|
1040
1175
|
if (hasBidFloor || hasBidFloorCur) {
|
|
1041
1176
|
if (!(hasBidFloor && hasBidFloorCur && isValidBidFloorParams(bid.params.bidFloor, bid.params.bidFloorCur))) {
|
|
1042
|
-
logError('
|
|
1177
|
+
logError('IX Bid Adapter: bidFloor / bidFloorCur parameter has invalid format.', { bidder: BIDDER_CODE, code: ERROR_CODES.BID_FLOOR_INVALID_FORMAT });
|
|
1043
1178
|
return false;
|
|
1044
1179
|
}
|
|
1045
1180
|
}
|
|
@@ -1048,7 +1183,7 @@ export const spec = {
|
|
|
1048
1183
|
const errorList = checkVideoParams(mediaTypeVideoRef, paramsVideoRef);
|
|
1049
1184
|
if (errorList.length) {
|
|
1050
1185
|
errorList.forEach((err) => {
|
|
1051
|
-
logError(err);
|
|
1186
|
+
logError(err, { bidder: BIDDER_CODE, code: ERROR_CODES.PROPERTY_NOT_INCLUDED });
|
|
1052
1187
|
});
|
|
1053
1188
|
return false;
|
|
1054
1189
|
}
|
|
@@ -1169,6 +1304,16 @@ export const spec = {
|
|
|
1169
1304
|
|
|
1170
1305
|
bids.push(bid);
|
|
1171
1306
|
}
|
|
1307
|
+
|
|
1308
|
+
if (deepAccess(requestBid, 'ext.ixdiag.err')) {
|
|
1309
|
+
if (storage.localStorageIsEnabled()) {
|
|
1310
|
+
try {
|
|
1311
|
+
storage.removeDataFromLocalStorage(LOCAL_STORAGE_KEY);
|
|
1312
|
+
} catch (e) {
|
|
1313
|
+
logError('ix can not clear ixdiag from localStorage.');
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1172
1317
|
}
|
|
1173
1318
|
|
|
1174
1319
|
return bids;
|
|
@@ -180,7 +180,7 @@ function kinessoSyncUrl(accountId, consentData) {
|
|
|
180
180
|
const usPrivacyString = uspDataHandler.getConsentData();
|
|
181
181
|
let kinessoSyncUrl = `${ID_SVC}?accountid=${accountId}`;
|
|
182
182
|
if (usPrivacyString) {
|
|
183
|
-
kinessoSyncUrl = `${kinessoSyncUrl}
|
|
183
|
+
kinessoSyncUrl = `${kinessoSyncUrl}&us_privacy=${usPrivacyString}`;
|
|
184
184
|
}
|
|
185
185
|
if (!consentData || typeof consentData.gdprApplies !== 'boolean' || !consentData.gdprApplies) return kinessoSyncUrl;
|
|
186
186
|
|
|
@@ -4,10 +4,20 @@
|
|
|
4
4
|
* @module modules/lotamePanoramaId
|
|
5
5
|
* @requires module:modules/userId
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
timestamp,
|
|
9
|
+
isStr,
|
|
10
|
+
logError,
|
|
11
|
+
isBoolean,
|
|
12
|
+
buildUrl,
|
|
13
|
+
isEmpty,
|
|
14
|
+
isArray,
|
|
15
|
+
isEmptyStr
|
|
16
|
+
} from '../src/utils.js';
|
|
8
17
|
import { ajax } from '../src/ajax.js';
|
|
9
18
|
import { submodule } from '../src/hook.js';
|
|
10
19
|
import { getStorageManager } from '../src/storageManager.js';
|
|
20
|
+
import { uspDataHandler } from '../src/adapterManager.js';
|
|
11
21
|
|
|
12
22
|
const KEY_ID = 'panoramaId';
|
|
13
23
|
const KEY_EXPIRY = `${KEY_ID}_expiry`;
|
|
@@ -115,14 +125,23 @@ function saveLotameCache(
|
|
|
115
125
|
|
|
116
126
|
/**
|
|
117
127
|
* Retrieve all the cached values from cookies and/or local storage
|
|
128
|
+
* @param {Number} clientId
|
|
118
129
|
*/
|
|
119
|
-
function getLotameLocalCache() {
|
|
130
|
+
function getLotameLocalCache(clientId = undefined) {
|
|
120
131
|
let cache = {
|
|
121
132
|
data: getFromStorage(KEY_ID),
|
|
122
133
|
expiryTimestampMs: 0,
|
|
134
|
+
clientExpiryTimestampMs: 0,
|
|
123
135
|
};
|
|
124
136
|
|
|
125
137
|
try {
|
|
138
|
+
if (clientId) {
|
|
139
|
+
const rawClientExpiry = getFromStorage(`${KEY_EXPIRY}_${clientId}`);
|
|
140
|
+
if (isStr(rawClientExpiry)) {
|
|
141
|
+
cache.clientExpiryTimestampMs = parseInt(rawClientExpiry, 10);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
126
145
|
const rawExpiry = getFromStorage(KEY_EXPIRY);
|
|
127
146
|
if (isStr(rawExpiry)) {
|
|
128
147
|
cache.expiryTimestampMs = parseInt(rawExpiry, 10);
|
|
@@ -191,11 +210,25 @@ export const lotamePanoramaIdSubmodule = {
|
|
|
191
210
|
*/
|
|
192
211
|
getId(config, consentData, cacheIdObj) {
|
|
193
212
|
cookieDomain = lotamePanoramaIdSubmodule.findRootDomain();
|
|
194
|
-
|
|
213
|
+
const configParams = (config && config.params) || {};
|
|
214
|
+
const clientId = configParams.clientId;
|
|
215
|
+
const hasCustomClientId = !isEmpty(clientId);
|
|
216
|
+
const localCache = getLotameLocalCache(clientId);
|
|
195
217
|
|
|
196
|
-
|
|
218
|
+
const hasExpiredPanoId = Date.now() > localCache.expiryTimestampMs;
|
|
219
|
+
|
|
220
|
+
if (hasCustomClientId) {
|
|
221
|
+
const hasFreshClientNoConsent = Date.now() < localCache.clientExpiryTimestampMs;
|
|
222
|
+
if (hasFreshClientNoConsent) {
|
|
223
|
+
// There is no consent
|
|
224
|
+
return {
|
|
225
|
+
id: undefined,
|
|
226
|
+
reason: 'NO_CLIENT_CONSENT',
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
}
|
|
197
230
|
|
|
198
|
-
if (!
|
|
231
|
+
if (!hasExpiredPanoId) {
|
|
199
232
|
return {
|
|
200
233
|
id: localCache.data,
|
|
201
234
|
};
|
|
@@ -203,6 +236,18 @@ export const lotamePanoramaIdSubmodule = {
|
|
|
203
236
|
|
|
204
237
|
const storedUserId = getProfileId();
|
|
205
238
|
|
|
239
|
+
// Add CCPA Consent data handling
|
|
240
|
+
const usp = uspDataHandler.getConsentData();
|
|
241
|
+
|
|
242
|
+
let usPrivacy;
|
|
243
|
+
if (typeof usp !== 'undefined' && !isEmpty(usp) && !isEmptyStr(usp)) {
|
|
244
|
+
usPrivacy = usp;
|
|
245
|
+
}
|
|
246
|
+
if (!usPrivacy) {
|
|
247
|
+
// fallback to 1st party cookie
|
|
248
|
+
usPrivacy = getFromStorage('us_privacy');
|
|
249
|
+
}
|
|
250
|
+
|
|
206
251
|
const resolveIdFunction = function (callback) {
|
|
207
252
|
let queryParams = {};
|
|
208
253
|
if (storedUserId) {
|
|
@@ -226,6 +271,17 @@ export const lotamePanoramaIdSubmodule = {
|
|
|
226
271
|
if (consentString) {
|
|
227
272
|
queryParams.gdpr_consent = consentString;
|
|
228
273
|
}
|
|
274
|
+
|
|
275
|
+
// Add usPrivacy to the url
|
|
276
|
+
if (usPrivacy) {
|
|
277
|
+
queryParams.us_privacy = usPrivacy;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Add clientId to the url
|
|
281
|
+
if (hasCustomClientId) {
|
|
282
|
+
queryParams.c = clientId;
|
|
283
|
+
}
|
|
284
|
+
|
|
229
285
|
const url = buildUrl({
|
|
230
286
|
protocol: 'https',
|
|
231
287
|
host: `id.crwdcntrl.net`,
|
|
@@ -239,15 +295,31 @@ export const lotamePanoramaIdSubmodule = {
|
|
|
239
295
|
if (response) {
|
|
240
296
|
try {
|
|
241
297
|
let responseObj = JSON.parse(response);
|
|
242
|
-
const
|
|
298
|
+
const hasNoConsentErrors = !(
|
|
243
299
|
isArray(responseObj.errors) &&
|
|
244
300
|
responseObj.errors.indexOf(MISSING_CORE_CONSENT) !== -1
|
|
245
301
|
);
|
|
246
302
|
|
|
303
|
+
if (hasCustomClientId) {
|
|
304
|
+
if (hasNoConsentErrors) {
|
|
305
|
+
clearLotameCache(`${KEY_EXPIRY}_${clientId}`);
|
|
306
|
+
} else if (isStr(responseObj.no_consent) && responseObj.no_consent === 'CLIENT') {
|
|
307
|
+
saveLotameCache(
|
|
308
|
+
`${KEY_EXPIRY}_${clientId}`,
|
|
309
|
+
responseObj.expiry_ts,
|
|
310
|
+
responseObj.expiry_ts
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
// End Processing
|
|
314
|
+
callback();
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
247
319
|
saveLotameCache(KEY_EXPIRY, responseObj.expiry_ts, responseObj.expiry_ts);
|
|
248
320
|
|
|
249
321
|
if (isStr(responseObj.profile_id)) {
|
|
250
|
-
if (
|
|
322
|
+
if (hasNoConsentErrors) {
|
|
251
323
|
setProfileId(responseObj.profile_id);
|
|
252
324
|
}
|
|
253
325
|
|
|
@@ -262,7 +334,7 @@ export const lotamePanoramaIdSubmodule = {
|
|
|
262
334
|
clearLotameCache(KEY_ID);
|
|
263
335
|
}
|
|
264
336
|
} else {
|
|
265
|
-
if (
|
|
337
|
+
if (hasNoConsentErrors) {
|
|
266
338
|
clearLotameCache(KEY_PROFILE);
|
|
267
339
|
}
|
|
268
340
|
clearLotameCache(KEY_ID);
|