prebid.js 6.2.0 → 6.6.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/.circleci/config.yml +1 -1
- package/gulpfile.js +87 -82
- package/integrationExamples/gpt/weboramaRtdProvider_example.html +23 -14
- package/karma.conf.maker.js +1 -1
- package/modules/.submodules.json +2 -1
- package/modules/33acrossBidAdapter.js +189 -102
- package/modules/adagioBidAdapter.js +1 -1
- package/modules/addefendBidAdapter.js +1 -0
- package/modules/adkernelBidAdapter.js +148 -62
- package/modules/adlooxAdServerVideo.js +2 -2
- package/modules/adlooxAnalyticsAdapter.js +4 -4
- package/modules/admanBidAdapter.js +11 -4
- package/modules/admixerBidAdapter.js +1 -1
- package/modules/adnuntiusBidAdapter.js +3 -1
- package/modules/adomikAnalyticsAdapter.js +27 -9
- package/modules/adqueryIdSystem.js +103 -0
- package/modules/adqueryIdSystem.md +35 -0
- package/modules/adxcgBidAdapter.js +311 -359
- package/modules/adxcgBidAdapter.md +22 -21
- package/modules/adyoulikeBidAdapter.js +13 -9
- package/modules/aniviewBidAdapter.js +1 -1
- package/modules/appnexusBidAdapter.js +0 -1
- package/modules/beopBidAdapter.js +6 -4
- package/modules/bidViewability.js +3 -3
- package/modules/bidViewabilityIO.js +3 -3
- package/modules/bliinkBidAdapter.js +3 -2
- package/modules/colossussspBidAdapter.js +7 -0
- package/modules/compassBidAdapter.js +208 -0
- package/modules/compassBidAdapter.md +79 -0
- package/modules/consentManagement.js +7 -1
- package/modules/criteoBidAdapter.js +1 -1
- package/modules/criteoIdSystem.js +29 -7
- package/modules/currency.js +2 -2
- package/modules/cwireBidAdapter.js +3 -0
- package/modules/dailyhuntBidAdapter.js +435 -0
- package/modules/dailyhuntBidAdapter.md +4 -0
- package/modules/docereeBidAdapter.js +10 -1
- package/modules/docereeBidAdapter.md +2 -0
- package/modules/dspxBidAdapter.js +1 -1
- package/modules/engageyaBidAdapter.js +1 -1
- package/modules/feedadBidAdapter.js +2 -2
- package/modules/feedadBidAdapter.md +4 -2
- package/modules/futureads.md +48 -0
- package/modules/glimpseBidAdapter.js +82 -47
- package/modules/gptPreAuction.js +55 -7
- package/modules/gridBidAdapter.js +4 -3
- package/modules/gumgumBidAdapter.js +2 -2
- package/modules/idImportLibrary.js +45 -8
- package/modules/idImportLibrary.md +4 -0
- package/modules/improvedigitalBidAdapter.js +42 -4
- package/modules/instreamTracking.js +4 -4
- package/modules/invibesBidAdapter.js +49 -5
- package/modules/invibesBidAdapter.md +2 -1
- package/modules/ixBidAdapter.js +53 -18
- package/modules/kinessoIdSystem.js +1 -1
- package/modules/limelightDigitalBidAdapter.js +2 -1
- package/modules/livewrappedAnalyticsAdapter.js +3 -1
- package/modules/livewrappedBidAdapter.js +8 -2
- package/modules/loglyliftBidAdapter.js +79 -0
- package/modules/loglyliftBidAdapter.md +55 -0
- package/modules/lotamePanoramaIdSystem.js +80 -8
- package/modules/mediasquareBidAdapter.js +1 -9
- package/modules/nextMillenniumBidAdapter.js +39 -7
- package/modules/oguryBidAdapter.js +9 -2
- package/modules/onetagBidAdapter.js +4 -2
- package/modules/optimeraRtdProvider.js +8 -1
- package/modules/ozoneBidAdapter.js +21 -64
- package/modules/prebidServerBidAdapter/index.js +16 -12
- package/modules/proxistoreBidAdapter.js +0 -2
- package/modules/pubgeniusBidAdapter.js +1 -1
- package/modules/pubmaticAnalyticsAdapter.js +16 -0
- package/modules/pubxaiAnalyticsAdapter.js +17 -0
- package/modules/richaudienceBidAdapter.js +4 -4
- package/modules/riseBidAdapter.js +1 -1
- package/modules/rtbhouseBidAdapter.js +14 -4
- package/modules/rtdModule/index.js +49 -18
- package/modules/rubiconBidAdapter.js +31 -19
- package/modules/sharedIdSystem.js +27 -1
- package/modules/showheroes-bsBidAdapter.js +13 -2
- package/modules/tappxBidAdapter.js +8 -5
- package/modules/targetVideoBidAdapter.js +187 -0
- package/modules/targetVideoBidAdapter.md +34 -0
- package/modules/teadsBidAdapter.js +1 -2
- package/modules/telariaBidAdapter.js +2 -2
- package/modules/trustxBidAdapter.js +8 -16
- package/modules/userId/eids.js +7 -1
- package/modules/userId/userId.md +8 -0
- package/modules/vidoomyBidAdapter.js +16 -10
- package/modules/weboramaRtdProvider.js +288 -73
- package/modules/weboramaRtdProvider.md +27 -10
- package/modules/welectBidAdapter.js +106 -0
- package/modules/yahoosspBidAdapter.js +5 -1
- package/modules/yieldmoBidAdapter.js +23 -5
- package/modules/zetaSspBidAdapter.md +33 -1
- package/modules/zeta_global_sspAnalyticsAdapter.js +97 -0
- package/modules/zeta_global_sspAnalyticsAdapter.md +24 -0
- package/modules/zeta_global_sspBidAdapter.js +22 -1
- package/package.json +1 -1
- package/plugins/pbjsGlobals.js +28 -1
- package/src/auction.js +2 -2
- package/src/config.js +27 -3
- package/src/hook.js +5 -1
- package/src/prebid.js +21 -6
- package/src/targeting.js +22 -1
- package/src/utils.js +46 -8
- package/test/helpers/prebidGlobal.js +1 -0
- package/test/spec/config_spec.js +279 -0
- package/test/spec/modules/33acrossBidAdapter_spec.js +300 -78
- package/test/spec/modules/adlooxAnalyticsAdapter_spec.js +6 -6
- package/test/spec/modules/admanBidAdapter_spec.js +2 -2
- package/test/spec/modules/adnuntiusBidAdapter_spec.js +17 -0
- package/test/spec/modules/adomikAnalyticsAdapter_spec.js +9 -1
- package/test/spec/modules/adqueryIdSystem_spec.js +74 -0
- package/test/spec/modules/adxcgBidAdapter_spec.js +820 -571
- package/test/spec/modules/adyoulikeBidAdapter_spec.js +49 -0
- package/test/spec/modules/beopBidAdapter_spec.js +1 -1
- package/test/spec/modules/bidViewabilityIO_spec.js +2 -2
- package/test/spec/modules/bidViewability_spec.js +4 -4
- package/test/spec/modules/bliinkBidAdapter_spec.js +2 -0
- package/test/spec/modules/colossussspBidAdapter_spec.js +9 -0
- package/test/spec/modules/compassBidAdapter_spec.js +398 -0
- package/test/spec/modules/consentManagement_spec.js +20 -0
- package/test/spec/modules/criteoIdSystem_spec.js +6 -3
- package/test/spec/modules/cwireBidAdapter_spec.js +10 -8
- package/test/spec/modules/dailyhuntBidAdapter_spec.js +404 -0
- package/test/spec/modules/docereeBidAdapter_spec.js +9 -1
- package/test/spec/modules/eids_spec.js +15 -0
- package/test/spec/modules/feedadBidAdapter_spec.js +15 -0
- package/test/spec/modules/glimpseBidAdapter_spec.js +0 -18
- package/test/spec/modules/gptPreAuction_spec.js +177 -2
- package/test/spec/modules/idImportLibrary_spec.js +197 -10
- package/test/spec/modules/improvedigitalBidAdapter_spec.js +45 -1
- package/test/spec/modules/invibesBidAdapter_spec.js +119 -0
- package/test/spec/modules/ixBidAdapter_spec.js +112 -62
- package/test/spec/modules/limelightDigitalBidAdapter_spec.js +75 -17
- package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +22 -0
- package/test/spec/modules/livewrappedBidAdapter_spec.js +31 -0
- package/test/spec/modules/loglyliftBidAdapter_spec.js +172 -0
- package/test/spec/modules/lotamePanoramaIdSystem_spec.js +227 -0
- package/test/spec/modules/mediasquareBidAdapter_spec.js +4 -4
- package/test/spec/modules/nextMillenniumBidAdapter_spec.js +26 -1
- package/test/spec/modules/oguryBidAdapter_spec.js +10 -2
- package/test/spec/modules/optimeraRtdProvider_spec.js +14 -1
- package/test/spec/modules/ozoneBidAdapter_spec.js +43 -31
- package/test/spec/modules/prebidServerBidAdapter_spec.js +43 -0
- package/test/spec/modules/pubgeniusBidAdapter_spec.js +3 -3
- package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +13 -1
- package/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +11 -0
- package/test/spec/modules/realTimeDataModule_spec.js +147 -48
- package/test/spec/modules/richaudienceBidAdapter_spec.js +42 -2
- package/test/spec/modules/riseBidAdapter_spec.js +1 -1
- package/test/spec/modules/rtbhouseBidAdapter_spec.js +20 -0
- package/test/spec/modules/rubiconBidAdapter_spec.js +65 -9
- package/test/spec/modules/sharedIdSystem_spec.js +52 -6
- package/test/spec/modules/showheroes-bsBidAdapter_spec.js +2 -0
- package/test/spec/modules/tappxBidAdapter_spec.js +0 -19
- package/test/spec/modules/targetVideoBidAdapter_spec.js +96 -0
- package/test/spec/modules/teadsBidAdapter_spec.js +14 -59
- package/test/spec/modules/userId_spec.js +68 -19
- package/test/spec/modules/weboramaRtdProvider_spec.js +408 -214
- package/test/spec/modules/welectBidAdapter_spec.js +211 -0
- package/test/spec/modules/yahoosspBidAdapter_spec.js +28 -1
- package/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js +427 -0
- package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +33 -1
- package/test/spec/unit/core/targeting_spec.js +72 -0
- package/test/spec/unit/pbjs_api_spec.js +3 -1
- package/test/spec/utils_spec.js +38 -0
- package/test/test_deps.js +3 -0
- package/test/test_index.js +1 -3
|
@@ -40,28 +40,21 @@ export const spec = {
|
|
|
40
40
|
* @returns {ServerRequest}
|
|
41
41
|
*/
|
|
42
42
|
buildRequests: (validBidRequests, bidderRequest) => {
|
|
43
|
-
const demo = config.getConfig('glimpse.demo') || false
|
|
44
|
-
const account = config.getConfig('glimpse.account') || -1
|
|
45
|
-
const demand = config.getConfig('glimpse.demand') || 'glimpse'
|
|
46
|
-
const keywords = config.getConfig('glimpse.keywords') || {}
|
|
47
|
-
|
|
48
43
|
const auth = getVaultJwt()
|
|
49
44
|
const referer = getReferer(bidderRequest)
|
|
50
45
|
const gdprConsent = getGdprConsentChoice(bidderRequest)
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
})
|
|
46
|
+
const bidRequests = validBidRequests.map(processBidRequest)
|
|
47
|
+
const firstPartyData = getFirstPartyData()
|
|
54
48
|
|
|
55
49
|
const data = {
|
|
56
50
|
auth,
|
|
57
51
|
data: {
|
|
58
|
-
bidderCode: spec.code,
|
|
59
|
-
demo,
|
|
60
|
-
account,
|
|
61
|
-
demand,
|
|
62
52
|
referer,
|
|
63
53
|
gdprConsent,
|
|
64
|
-
|
|
54
|
+
bidRequests,
|
|
55
|
+
site: firstPartyData.site,
|
|
56
|
+
user: firstPartyData.user,
|
|
57
|
+
bidderCode: spec.code,
|
|
65
58
|
}
|
|
66
59
|
}
|
|
67
60
|
|
|
@@ -91,35 +84,12 @@ export const spec = {
|
|
|
91
84
|
},
|
|
92
85
|
}
|
|
93
86
|
|
|
94
|
-
function
|
|
95
|
-
|
|
96
|
-
const bidKeywords = bidRequest.params.keywords || {}
|
|
97
|
-
const keywords = {
|
|
98
|
-
...globalKeywords,
|
|
99
|
-
...bidKeywords,
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return {
|
|
103
|
-
unitCode: bidRequest.adUnitCode,
|
|
104
|
-
bidId: bidRequest.bidId,
|
|
105
|
-
placementId: bidRequest.params.placementId,
|
|
106
|
-
keywords,
|
|
107
|
-
sizes,
|
|
108
|
-
}
|
|
87
|
+
function setVaultJwt(auth) {
|
|
88
|
+
storageManager.setDataInLocalStorage(LOCAL_STORAGE_KEY.vault.jwt, auth)
|
|
109
89
|
}
|
|
110
90
|
|
|
111
|
-
function
|
|
112
|
-
|
|
113
|
-
isArray(sizes) &&
|
|
114
|
-
sizes.length === 2 &&
|
|
115
|
-
!isArray(sizes[0]) &&
|
|
116
|
-
!isArray(sizes[1])
|
|
117
|
-
|
|
118
|
-
if (isSingleSize) {
|
|
119
|
-
return [sizes]
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return sizes
|
|
91
|
+
function getVaultJwt() {
|
|
92
|
+
return storageManager.getDataFromLocalStorage(LOCAL_STORAGE_KEY.vault.jwt) || ''
|
|
123
93
|
}
|
|
124
94
|
|
|
125
95
|
function getReferer(bidderRequest) {
|
|
@@ -138,11 +108,17 @@ function getReferer(bidderRequest) {
|
|
|
138
108
|
function getGdprConsentChoice(bidderRequest) {
|
|
139
109
|
const hasGdprConsent =
|
|
140
110
|
hasValue(bidderRequest) &&
|
|
141
|
-
hasValue(bidderRequest.gdprConsent)
|
|
142
|
-
hasStringValue(bidderRequest.gdprConsent.consentString)
|
|
111
|
+
hasValue(bidderRequest.gdprConsent)
|
|
143
112
|
|
|
144
113
|
if (hasGdprConsent) {
|
|
145
|
-
|
|
114
|
+
const gdprConsent = bidderRequest.gdprConsent
|
|
115
|
+
const hasGdprApplies = hasBooleanValue(gdprConsent.gdprApplies)
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
consentString: gdprConsent.consentString || '',
|
|
119
|
+
vendorData: gdprConsent.vendorData || {},
|
|
120
|
+
gdprApplies: hasGdprApplies ? gdprConsent.gdprApplies : true,
|
|
121
|
+
}
|
|
146
122
|
}
|
|
147
123
|
|
|
148
124
|
return {
|
|
@@ -152,12 +128,64 @@ function getGdprConsentChoice(bidderRequest) {
|
|
|
152
128
|
}
|
|
153
129
|
}
|
|
154
130
|
|
|
155
|
-
function
|
|
156
|
-
|
|
131
|
+
function processBidRequest(bidRequest) {
|
|
132
|
+
const demand = bidRequest.params.demand || 'glimpse'
|
|
133
|
+
const sizes = normalizeSizes(bidRequest.sizes)
|
|
134
|
+
const keywords = bidRequest.params.keywords || {}
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
demand,
|
|
138
|
+
sizes,
|
|
139
|
+
keywords,
|
|
140
|
+
bidId: bidRequest.bidId,
|
|
141
|
+
placementId: bidRequest.params.placementId,
|
|
142
|
+
unitCode: bidRequest.adUnitCode,
|
|
143
|
+
}
|
|
157
144
|
}
|
|
158
145
|
|
|
159
|
-
function
|
|
160
|
-
|
|
146
|
+
function normalizeSizes(sizes) {
|
|
147
|
+
const isSingleSize =
|
|
148
|
+
isArray(sizes) &&
|
|
149
|
+
sizes.length === 2 &&
|
|
150
|
+
!isArray(sizes[0]) &&
|
|
151
|
+
!isArray(sizes[1])
|
|
152
|
+
|
|
153
|
+
if (isSingleSize) {
|
|
154
|
+
return [sizes]
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return sizes
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function getFirstPartyData() {
|
|
161
|
+
const siteKeywords = parseGlobalKeywords('site')
|
|
162
|
+
const userKeywords = parseGlobalKeywords('user')
|
|
163
|
+
|
|
164
|
+
const siteAttributes = getConfig('ortb2.site.ext.data', {})
|
|
165
|
+
const userAttributes = getConfig('ortb2.user.ext.data', {})
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
site: {
|
|
169
|
+
keywords: siteKeywords,
|
|
170
|
+
attributes: siteAttributes,
|
|
171
|
+
},
|
|
172
|
+
user: {
|
|
173
|
+
keywords: userKeywords,
|
|
174
|
+
attributes: userAttributes,
|
|
175
|
+
},
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function parseGlobalKeywords(scope) {
|
|
180
|
+
const keywords = getConfig(`ortb2.${scope}.keywords`, '')
|
|
181
|
+
|
|
182
|
+
return keywords
|
|
183
|
+
.split(', ')
|
|
184
|
+
.filter((keyword) => keyword !== '')
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function getConfig(path, defaultValue) {
|
|
188
|
+
return config.getConfig(path) || defaultValue
|
|
161
189
|
}
|
|
162
190
|
|
|
163
191
|
function isValidBidResponse(bidResponse) {
|
|
@@ -177,6 +205,13 @@ function hasValue(value) {
|
|
|
177
205
|
)
|
|
178
206
|
}
|
|
179
207
|
|
|
208
|
+
function hasBooleanValue(value) {
|
|
209
|
+
return (
|
|
210
|
+
hasValue(value) &&
|
|
211
|
+
typeof value === 'boolean'
|
|
212
|
+
)
|
|
213
|
+
}
|
|
214
|
+
|
|
180
215
|
function hasStringValue(value) {
|
|
181
216
|
return (
|
|
182
217
|
hasValue(value) &&
|
package/modules/gptPreAuction.js
CHANGED
|
@@ -48,10 +48,35 @@ const sanitizeSlotPath = (path) => {
|
|
|
48
48
|
return path;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
const defaultPreAuction = (adUnit, adServerAdSlot) => {
|
|
52
|
+
const context = adUnit.ortb2Imp.ext.data;
|
|
53
|
+
|
|
54
|
+
// use pbadslot if supplied
|
|
55
|
+
if (context.pbadslot) {
|
|
56
|
+
return context.pbadslot;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// confirm that GPT is set up
|
|
60
|
+
if (!isGptPubadsDefined()) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// find all GPT slots with this name
|
|
65
|
+
var gptSlots = window.googletag.pubads().getSlots().filter(slot => slot.getAdUnitPath() === adServerAdSlot);
|
|
66
|
+
|
|
67
|
+
if (gptSlots.length === 0) {
|
|
68
|
+
return; // should never happen
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (gptSlots.length === 1) {
|
|
72
|
+
return adServerAdSlot;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// else the adunit code must be div id. append it.
|
|
76
|
+
return `${adServerAdSlot}#${adUnit.code}`;
|
|
77
|
+
}
|
|
78
|
+
|
|
51
79
|
export const appendPbAdSlot = adUnit => {
|
|
52
|
-
adUnit.ortb2Imp = adUnit.ortb2Imp || {};
|
|
53
|
-
adUnit.ortb2Imp.ext = adUnit.ortb2Imp.ext || {};
|
|
54
|
-
adUnit.ortb2Imp.ext.data = adUnit.ortb2Imp.ext.data || {};
|
|
55
80
|
const context = adUnit.ortb2Imp.ext.data;
|
|
56
81
|
const { customPbAdSlot } = _currentConfig;
|
|
57
82
|
|
|
@@ -84,11 +109,32 @@ export const appendPbAdSlot = adUnit => {
|
|
|
84
109
|
|
|
85
110
|
export const makeBidRequestsHook = (fn, adUnits, ...args) => {
|
|
86
111
|
appendGptSlots(adUnits);
|
|
112
|
+
const { useDefaultPreAuction, customPreAuction } = _currentConfig;
|
|
87
113
|
adUnits.forEach(adUnit => {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
114
|
+
// init the ortb2Imp if not done yet
|
|
115
|
+
adUnit.ortb2Imp = adUnit.ortb2Imp || {};
|
|
116
|
+
adUnit.ortb2Imp.ext = adUnit.ortb2Imp.ext || {};
|
|
117
|
+
adUnit.ortb2Imp.ext.data = adUnit.ortb2Imp.ext.data || {};
|
|
118
|
+
const context = adUnit.ortb2Imp.ext;
|
|
119
|
+
|
|
120
|
+
// if neither new confs set do old stuff
|
|
121
|
+
if (!customPreAuction && !useDefaultPreAuction) {
|
|
122
|
+
const usedAdUnitCode = appendPbAdSlot(adUnit);
|
|
123
|
+
// gpid should be set to itself if already set, or to what pbadslot was (as long as it was not adUnit code)
|
|
124
|
+
if (!context.gpid && !usedAdUnitCode) {
|
|
125
|
+
context.gpid = context.data.pbadslot;
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
let adserverSlot = deepAccess(context, 'data.adserver.adslot');
|
|
129
|
+
let result;
|
|
130
|
+
if (customPreAuction) {
|
|
131
|
+
result = customPreAuction(adUnit, adserverSlot);
|
|
132
|
+
} else if (useDefaultPreAuction) {
|
|
133
|
+
result = defaultPreAuction(adUnit, adserverSlot);
|
|
134
|
+
}
|
|
135
|
+
if (result) {
|
|
136
|
+
context.gpid = context.data.pbadslot = result;
|
|
137
|
+
}
|
|
92
138
|
}
|
|
93
139
|
});
|
|
94
140
|
return fn.call(this, adUnits, ...args);
|
|
@@ -100,6 +146,8 @@ const handleSetGptConfig = moduleConfig => {
|
|
|
100
146
|
'customGptSlotMatching', customGptSlotMatching =>
|
|
101
147
|
typeof customGptSlotMatching === 'function' && customGptSlotMatching,
|
|
102
148
|
'customPbAdSlot', customPbAdSlot => typeof customPbAdSlot === 'function' && customPbAdSlot,
|
|
149
|
+
'customPreAuction', customPreAuction => typeof customPreAuction === 'function' && customPreAuction,
|
|
150
|
+
'useDefaultPreAuction', useDefaultPreAuction => useDefaultPreAuction === true,
|
|
103
151
|
]);
|
|
104
152
|
|
|
105
153
|
if (_currentConfig.enabled) {
|
|
@@ -291,10 +291,11 @@ export const spec = {
|
|
|
291
291
|
if (!hasSynced && syncOptions.pixelEnabled) {
|
|
292
292
|
let params = '';
|
|
293
293
|
|
|
294
|
-
if (gdprConsent
|
|
294
|
+
if (gdprConsent) {
|
|
295
295
|
if (typeof gdprConsent.gdprApplies === 'boolean') {
|
|
296
|
-
params += `&gdpr=${Number(gdprConsent.gdprApplies)}
|
|
297
|
-
}
|
|
296
|
+
params += `&gdpr=${Number(gdprConsent.gdprApplies)}`;
|
|
297
|
+
}
|
|
298
|
+
if (typeof gdprConsent.consentString === 'string') {
|
|
298
299
|
params += `&gdpr_consent=${gdprConsent.consentString}`;
|
|
299
300
|
}
|
|
300
301
|
}
|
|
@@ -296,8 +296,8 @@ function buildRequests(validBidRequests, bidderRequest) {
|
|
|
296
296
|
let gpid = '';
|
|
297
297
|
|
|
298
298
|
const date = new Date();
|
|
299
|
-
const lt = date
|
|
300
|
-
const to = date
|
|
299
|
+
const lt = date.getTime();
|
|
300
|
+
const to = date.getTimezoneOffset();
|
|
301
301
|
if (to) {
|
|
302
302
|
lt && (data.lt = lt);
|
|
303
303
|
data.to = to;
|
|
@@ -9,6 +9,7 @@ let conf;
|
|
|
9
9
|
const LOG_PRE_FIX = 'ID-Library: ';
|
|
10
10
|
const CONF_DEFAULT_OBSERVER_DEBOUNCE_MS = 250;
|
|
11
11
|
const CONF_DEFAULT_FULL_BODY_SCAN = false;
|
|
12
|
+
const CONF_DEFAULT_INPUT_SCAN = false;
|
|
12
13
|
const OBSERVER_CONFIG = {
|
|
13
14
|
subtree: true,
|
|
14
15
|
attributes: true,
|
|
@@ -78,7 +79,13 @@ function targetAction(mutations, observer) {
|
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
81
|
|
|
81
|
-
function addInputElementsElementListner(
|
|
82
|
+
function addInputElementsElementListner() {
|
|
83
|
+
if (doesInputElementsHaveEmail()) {
|
|
84
|
+
_logInfo('Email found in input elements ' + email);
|
|
85
|
+
_logInfo('Post data on email found in target without');
|
|
86
|
+
postData();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
82
89
|
_logInfo('Adding input element listeners');
|
|
83
90
|
const inputs = document.querySelectorAll('input[type=text], input[type=email]');
|
|
84
91
|
|
|
@@ -89,6 +96,19 @@ function addInputElementsElementListner(conf) {
|
|
|
89
96
|
}
|
|
90
97
|
}
|
|
91
98
|
|
|
99
|
+
function addFormInputElementsElementListner(id) {
|
|
100
|
+
_logInfo('Adding input element listeners');
|
|
101
|
+
if (doesFormInputElementsHaveEmail(id)) {
|
|
102
|
+
_logInfo('Email found in input elements ' + email);
|
|
103
|
+
postData();
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
_logInfo('Adding input element listeners');
|
|
107
|
+
const input = document.getElementById(id);
|
|
108
|
+
input.addEventListener('change', event => processInputChange(event));
|
|
109
|
+
input.addEventListener('blur', event => processInputChange(event));
|
|
110
|
+
}
|
|
111
|
+
|
|
92
112
|
function removeInputElementsElementListner() {
|
|
93
113
|
_logInfo('Removing input element listeners');
|
|
94
114
|
const inputs = document.querySelectorAll('input[type=text], input[type=email]');
|
|
@@ -149,12 +169,6 @@ function handleTargetElement() {
|
|
|
149
169
|
}
|
|
150
170
|
|
|
151
171
|
function handleBodyElements() {
|
|
152
|
-
if (doesInputElementsHaveEmail()) {
|
|
153
|
-
_logInfo('Email found in input elements ' + email);
|
|
154
|
-
_logInfo('Post data on email found in target without');
|
|
155
|
-
postData();
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
172
|
email = getEmail(document.body.innerHTML);
|
|
159
173
|
if (email !== null) {
|
|
160
174
|
_logInfo('Email found in body ' + email);
|
|
@@ -162,7 +176,7 @@ function handleBodyElements() {
|
|
|
162
176
|
postData();
|
|
163
177
|
return;
|
|
164
178
|
}
|
|
165
|
-
|
|
179
|
+
|
|
166
180
|
if (conf.fullscan === true) {
|
|
167
181
|
const bodyObserver = new MutationObserver(debounce(bodyAction, conf.debounce, false));
|
|
168
182
|
bodyObserver.observe(document.body, OBSERVER_CONFIG);
|
|
@@ -182,6 +196,17 @@ function doesInputElementsHaveEmail() {
|
|
|
182
196
|
return false;
|
|
183
197
|
}
|
|
184
198
|
|
|
199
|
+
function doesFormInputElementsHaveEmail(formElementId) {
|
|
200
|
+
const input = document.getElementById(formElementId);
|
|
201
|
+
if (input) {
|
|
202
|
+
email = getEmail(input.value);
|
|
203
|
+
if (email !== null) {
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
|
|
185
210
|
function syncCallback() {
|
|
186
211
|
return {
|
|
187
212
|
success: function () {
|
|
@@ -213,6 +238,10 @@ function associateIds() {
|
|
|
213
238
|
if (window.MutationObserver || window.WebKitMutationObserver) {
|
|
214
239
|
if (conf.target) {
|
|
215
240
|
handleTargetElement();
|
|
241
|
+
} else if (conf.formElementId) {
|
|
242
|
+
addFormInputElementsElementListner(conf.formElementId);
|
|
243
|
+
} else if (conf.inputscan) {
|
|
244
|
+
addInputElementsElementListner();
|
|
216
245
|
} else {
|
|
217
246
|
handleBodyElements();
|
|
218
247
|
}
|
|
@@ -236,6 +265,14 @@ export function setConfig(config) {
|
|
|
236
265
|
config.fullscan = CONF_DEFAULT_FULL_BODY_SCAN;
|
|
237
266
|
_logInfo('Set default fullscan ' + CONF_DEFAULT_FULL_BODY_SCAN);
|
|
238
267
|
}
|
|
268
|
+
if (typeof config.inputscan !== 'boolean') {
|
|
269
|
+
config.inputscan = CONF_DEFAULT_INPUT_SCAN;
|
|
270
|
+
_logInfo('Set default input scan ' + CONF_DEFAULT_INPUT_SCAN);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (typeof config.formElementId == 'string') {
|
|
274
|
+
_logInfo('Looking for formElementId ' + config.formElementId);
|
|
275
|
+
}
|
|
239
276
|
conf = config;
|
|
240
277
|
associateIds();
|
|
241
278
|
}
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
| `url` | Yes | String | N/A | URL endpoint used to post the hashed email and user IDs. |
|
|
9
9
|
| `debounce` | No | Number | 250 | Time in milliseconds before the email and IDs are fetched. |
|
|
10
10
|
| `fullscan` | No | Boolean | false | Enable/disable a full page body scan to get email. |
|
|
11
|
+
| `formElementId` | No | String | N/A | ID attribute of the input (type=text/email) from which the email can be read. |
|
|
12
|
+
| `inputscan` | No | Boolean | N/A | Enable/disable a input element (type=text/email) scan to get email. |
|
|
11
13
|
|
|
12
14
|
## Example
|
|
13
15
|
|
|
@@ -18,5 +20,7 @@ pbjs.setConfig({
|
|
|
18
20
|
url: 'https://example.com',
|
|
19
21
|
debounce: 250,
|
|
20
22
|
fullscan: false,
|
|
23
|
+
inputscan: false,
|
|
24
|
+
formElementId: "userid"
|
|
21
25
|
},
|
|
22
26
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { deepSetValue, logError, _each, getBidRequest, isNumber, isArray, deepAccess, isFn, isPlainObject, logWarn, getBidIdParameter, getUniqueIdentifierStr, isEmpty, isInteger } from '../src/utils.js';
|
|
1
|
+
import { deepSetValue, logError, _each, getBidRequest, isNumber, isArray, deepAccess, isFn, isPlainObject, logWarn, getBidIdParameter, getUniqueIdentifierStr, isEmpty, isInteger, isStr } from '../src/utils.js';
|
|
2
2
|
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
3
3
|
import { config } from '../src/config.js';
|
|
4
4
|
import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
|
|
@@ -11,7 +11,7 @@ const RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js
|
|
|
11
11
|
const VIDEO_TARGETING = ['skip', 'skipmin', 'skipafter'];
|
|
12
12
|
|
|
13
13
|
export const spec = {
|
|
14
|
-
version: '7.
|
|
14
|
+
version: '7.6.0',
|
|
15
15
|
code: BIDDER_CODE,
|
|
16
16
|
gvlid: 253,
|
|
17
17
|
aliases: ['id'],
|
|
@@ -45,8 +45,24 @@ export const spec = {
|
|
|
45
45
|
libVersion: this.version
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
const gdprConsent = deepAccess(bidderRequest, 'gdprConsent')
|
|
49
|
+
if (gdprConsent) {
|
|
50
|
+
// GDPR Consent String
|
|
51
|
+
if (gdprConsent.consentString) {
|
|
52
|
+
requestParameters.gdpr = gdprConsent.consentString;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Additional Consent String
|
|
56
|
+
const additionalConsent = deepAccess(gdprConsent, 'addtlConsent');
|
|
57
|
+
if (additionalConsent && additionalConsent.indexOf('~') !== -1) {
|
|
58
|
+
// Google Ad Tech Provider IDs
|
|
59
|
+
const atpIds = additionalConsent.substring(additionalConsent.indexOf('~') + 1);
|
|
60
|
+
deepSetValue(
|
|
61
|
+
requestParameters,
|
|
62
|
+
'user.ext.consented_providers_settings.consented_providers',
|
|
63
|
+
atpIds.split('.').map(id => parseInt(id, 10))
|
|
64
|
+
);
|
|
65
|
+
}
|
|
50
66
|
}
|
|
51
67
|
|
|
52
68
|
if (bidderRequest && bidderRequest.uspConsent) {
|
|
@@ -57,6 +73,22 @@ export const spec = {
|
|
|
57
73
|
requestParameters.referrer = bidderRequest.refererInfo.referer;
|
|
58
74
|
}
|
|
59
75
|
|
|
76
|
+
// Adding first party data
|
|
77
|
+
const site = config.getConfig('ortb2.site');
|
|
78
|
+
if (site) {
|
|
79
|
+
const pageCategory = site.pagecat || site.cat;
|
|
80
|
+
if (pageCategory && isArray(pageCategory)) {
|
|
81
|
+
requestParameters.pagecat = pageCategory.filter((category) => {
|
|
82
|
+
return category && isStr(category)
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
const genre = deepAccess(site, 'content.genre');
|
|
86
|
+
if (genre && isStr(genre)) {
|
|
87
|
+
requestParameters.genre = genre;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// End of adding first party data
|
|
91
|
+
|
|
60
92
|
requestParameters.schain = bidRequests[0].schain;
|
|
61
93
|
|
|
62
94
|
if (bidRequests[0].userId) {
|
|
@@ -605,6 +637,12 @@ export function ImproveDigitalAdServerJSClient(endPoint) {
|
|
|
605
637
|
if (requestParameters.schain) {
|
|
606
638
|
impressionBidRequestObject.schain = requestParameters.schain;
|
|
607
639
|
}
|
|
640
|
+
if (requestParameters.pagecat) {
|
|
641
|
+
impressionBidRequestObject.pagecat = requestParameters.pagecat;
|
|
642
|
+
}
|
|
643
|
+
if (requestParameters.genre) {
|
|
644
|
+
impressionBidRequestObject.genre = requestParameters.genre;
|
|
645
|
+
}
|
|
608
646
|
if (requestParameters.user) {
|
|
609
647
|
impressionBidRequestObject.user = requestParameters.user;
|
|
610
648
|
}
|
|
@@ -3,11 +3,11 @@ import { config } from '../src/config.js';
|
|
|
3
3
|
import { auctionManager } from '../src/auctionManager.js';
|
|
4
4
|
import { INSTREAM } from '../src/video.js';
|
|
5
5
|
import * as events from '../src/events.js';
|
|
6
|
-
import
|
|
6
|
+
import CONSTANTS from '../src/constants.json'
|
|
7
7
|
|
|
8
|
-
const {CACHE_ID, UUID} = TARGETING_KEYS;
|
|
9
|
-
const {BID_WON, AUCTION_END} = EVENTS;
|
|
10
|
-
const {RENDERED} = BID_STATUS;
|
|
8
|
+
const {CACHE_ID, UUID} = CONSTANTS.TARGETING_KEYS;
|
|
9
|
+
const {BID_WON, AUCTION_END} = CONSTANTS.EVENTS;
|
|
10
|
+
const {RENDERED} = CONSTANTS.BID_STATUS;
|
|
11
11
|
|
|
12
12
|
const INSTREAM_TRACKING_DEFAULT_CONFIG = {
|
|
13
13
|
enabled: false,
|
|
@@ -4,7 +4,8 @@ import {getStorageManager} from '../src/storageManager.js';
|
|
|
4
4
|
|
|
5
5
|
const CONSTANTS = {
|
|
6
6
|
BIDDER_CODE: 'invibes',
|
|
7
|
-
BID_ENDPOINT: '
|
|
7
|
+
BID_ENDPOINT: '.videostep.com/Bid/VideoAdContent',
|
|
8
|
+
BID_SUBDOMAIN: 'https://bid',
|
|
8
9
|
SYNC_ENDPOINT: 'https://k.r66net.com/GetUserSync',
|
|
9
10
|
TIME_TO_LIVE: 300,
|
|
10
11
|
DEFAULT_CURRENCY: 'EUR',
|
|
@@ -78,14 +79,14 @@ function buildRequest(bidRequests, bidderRequest) {
|
|
|
78
79
|
bidderRequest = bidderRequest || {};
|
|
79
80
|
const _placementIds = [];
|
|
80
81
|
const _adUnitCodes = [];
|
|
81
|
-
let
|
|
82
|
+
let _customEndpoint, _userId, _domainId;
|
|
82
83
|
let _ivAuctionStart = bidderRequest.auctionStart || Date.now();
|
|
83
84
|
|
|
84
85
|
bidRequests.forEach(function (bidRequest) {
|
|
85
86
|
bidRequest.startTime = new Date().getTime();
|
|
86
87
|
_placementIds.push(bidRequest.params.placementId);
|
|
87
88
|
_adUnitCodes.push(bidRequest.adUnitCode);
|
|
88
|
-
|
|
89
|
+
_domainId = _domainId || bidRequest.params.domainId;
|
|
89
90
|
_customEndpoint = _customEndpoint || bidRequest.params.customEndpoint;
|
|
90
91
|
_customUserSync = _customUserSync || bidRequest.params.customUserSync;
|
|
91
92
|
_userId = _userId || bidRequest.userId;
|
|
@@ -102,7 +103,6 @@ function buildRequest(bidRequests, bidderRequest) {
|
|
|
102
103
|
let bidParamsJson = {
|
|
103
104
|
placementIds: _placementIds,
|
|
104
105
|
adUnitCodes: _adUnitCodes,
|
|
105
|
-
loginId: _loginId,
|
|
106
106
|
auctionStartTime: _ivAuctionStart,
|
|
107
107
|
bidVersion: CONSTANTS.PREBID_VERSION
|
|
108
108
|
};
|
|
@@ -146,9 +146,11 @@ function buildRequest(bidRequests, bidderRequest) {
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
+
let endpoint = createEndpoint(_customEndpoint, _domainId, _placementIds);
|
|
150
|
+
|
|
149
151
|
return {
|
|
150
152
|
method: CONSTANTS.METHOD,
|
|
151
|
-
url:
|
|
153
|
+
url: endpoint,
|
|
152
154
|
data: data,
|
|
153
155
|
options: {withCredentials: true},
|
|
154
156
|
// for POST: { contentType: 'application/json', withCredentials: true }
|
|
@@ -280,6 +282,48 @@ function createBid(bidRequest, requestPlacement, multipositionEnabled, usedPlace
|
|
|
280
282
|
};
|
|
281
283
|
}
|
|
282
284
|
|
|
285
|
+
function createEndpoint(customEndpoint, domainId, placementIds) {
|
|
286
|
+
if (customEndpoint != null) {
|
|
287
|
+
return customEndpoint;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (domainId != null) {
|
|
291
|
+
return extractEndpointFromId(domainId - 1000);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (placementIds.length > 0) {
|
|
295
|
+
for (var i = 0; i < placementIds.length; i++) {
|
|
296
|
+
const id = extractFromPlacement(placementIds[i]);
|
|
297
|
+
if (id != null) {
|
|
298
|
+
return extractEndpointFromId(id);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return extractEndpointFromId(1);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function extractEndpointFromId(domainId) {
|
|
307
|
+
if (domainId < 2) {
|
|
308
|
+
return CONSTANTS.BID_SUBDOMAIN + CONSTANTS.BID_ENDPOINT;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return CONSTANTS.BID_SUBDOMAIN + domainId + CONSTANTS.BID_ENDPOINT;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function extractFromPlacement(placementId) {
|
|
315
|
+
if (placementId == null) { return null; }
|
|
316
|
+
|
|
317
|
+
var pattern = /_ivbs([0-9]+)/g;
|
|
318
|
+
|
|
319
|
+
var match = pattern.exec(placementId);
|
|
320
|
+
if (match != null && match[1] != null) {
|
|
321
|
+
return parseInt(match[1]);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
|
|
283
327
|
function addMeta(bidModelMeta) {
|
|
284
328
|
var meta = {};
|
|
285
329
|
if (bidModelMeta != null) {
|