prebid.js 6.5.0 → 6.9.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/.eslintrc.js +8 -1
- package/integrationExamples/gpt/amp/creative.html +11 -33
- package/integrationExamples/gpt/weboramaRtdProvider_example.html +154 -115
- package/integrationExamples/gpt/x-domain/creative.html +63 -29
- package/modules/.submodules.json +2 -1
- package/modules/adagioBidAdapter.js +0 -8
- package/modules/adagioBidAdapter.md +1 -1
- package/modules/adbookpspBidAdapter.js +27 -10
- package/modules/adhashBidAdapter.js +3 -3
- package/modules/adkernelBidAdapter.js +2 -1
- package/modules/admanBidAdapter.js +10 -4
- package/modules/adomikAnalyticsAdapter.js +23 -11
- package/modules/adqueryIdSystem.js +103 -0
- package/modules/adqueryIdSystem.md +35 -0
- package/modules/appnexusBidAdapter.js +14 -2
- package/modules/asealBidAdapter.js +58 -0
- package/modules/asealBidAdapter.md +52 -0
- package/modules/bliinkBidAdapter.js +2 -1
- package/modules/brandmetricsRtdProvider.js +168 -0
- package/modules/brandmetricsRtdProvider.md +40 -0
- package/modules/colossussspBidAdapter.js +12 -8
- package/modules/colossussspBidAdapter.md +15 -1
- package/modules/compassBidAdapter.js +10 -3
- package/modules/consumableBidAdapter.md +1 -1
- package/modules/conversantBidAdapter.js +7 -0
- package/modules/criteoBidAdapter.js +10 -1
- package/modules/criteoIdSystem.js +29 -7
- package/modules/currency.js +26 -1
- package/modules/displayioBidAdapter.js +157 -0
- package/modules/displayioBidAdapter.md +148 -0
- package/modules/e_volutionBidAdapter.js +158 -0
- package/modules/glimpseBidAdapter.js +66 -44
- package/modules/gnetBidAdapter.js +3 -3
- package/modules/gnetBidAdapter.md +4 -4
- package/modules/gumgumBidAdapter.js +56 -42
- package/modules/idImportLibrary.js +45 -8
- package/modules/idImportLibrary.md +4 -0
- package/modules/improvedigitalBidAdapter.js +29 -2
- package/modules/interactiveOffersBidAdapter.js +9 -6
- package/modules/jwplayerRtdProvider.js +71 -6
- package/modules/jwplayerRtdProvider.md +27 -11
- package/modules/kargoBidAdapter.js +2 -2
- package/modules/lunamediahbBidAdapter.js +32 -4
- package/modules/nextMillenniumBidAdapter.js +3 -1
- package/modules/oguryBidAdapter.js +14 -14
- package/modules/onetagBidAdapter.js +4 -2
- package/modules/pilotxBidAdapter.js +147 -0
- package/modules/pilotxBidAdapter.md +50 -0
- package/modules/priceFloors.js +2 -1
- package/modules/proxistoreBidAdapter.js +0 -2
- package/modules/pubmaticAnalyticsAdapter.js +16 -0
- package/modules/richaudienceBidAdapter.js +10 -4
- package/modules/riseBidAdapter.js +18 -7
- package/modules/rtbhouseBidAdapter.js +14 -4
- package/modules/rtdModule/index.js +14 -15
- package/modules/rubiconAnalyticsAdapter.js +8 -2
- package/modules/seedingAllianceBidAdapter.js +3 -3
- package/modules/sharethroughBidAdapter.js +12 -17
- package/modules/showheroes-bsBidAdapter.js +13 -2
- package/modules/sortableAnalyticsAdapter.js +5 -4
- package/modules/sovrnBidAdapter.js +93 -18
- package/modules/sovrnBidAdapter.md +80 -2
- package/modules/synacormediaBidAdapter.js +31 -10
- package/modules/tappxBidAdapter.js +8 -5
- package/modules/teadsBidAdapter.js +1 -2
- package/modules/undertoneBidAdapter.js +17 -1
- package/modules/userId/eids.js +7 -1
- package/modules/userId/userId.md +8 -0
- package/modules/viewability.js +177 -0
- package/modules/viewability.md +87 -0
- package/modules/weboramaRtdProvider.js +264 -34
- package/modules/weboramaRtdProvider.md +110 -40
- package/modules/welectBidAdapter.js +106 -0
- package/modules/yahoosspBidAdapter.js +2 -0
- package/package.json +2 -1
- package/src/adRendering.js +38 -0
- package/src/adloader.js +2 -1
- package/src/auction.js +103 -73
- package/src/bidderSettings.js +69 -0
- package/src/hook.js +5 -1
- package/src/prebid.js +19 -21
- package/src/secureCreatives.js +131 -47
- package/src/targeting.js +3 -2
- package/src/utils.js +13 -10
- package/test/helpers/syncPromise.js +71 -0
- package/test/spec/auctionmanager_spec.js +179 -15
- package/test/spec/modules/adagioBidAdapter_spec.js +0 -10
- package/test/spec/modules/adbookpspBidAdapter_spec.js +17 -3
- package/test/spec/modules/adhashBidAdapter_spec.js +2 -2
- package/test/spec/modules/admanBidAdapter_spec.js +2 -2
- package/test/spec/modules/adomikAnalyticsAdapter_spec.js +3 -1
- package/test/spec/modules/adqueryIdSystem_spec.js +74 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +27 -0
- package/test/spec/modules/asealBidAdapter_spec.js +144 -0
- package/test/spec/modules/bliinkBidAdapter_spec.js +2 -0
- package/test/spec/modules/brandmetricsRtdProvider_spec.js +191 -0
- package/test/spec/modules/colossussspBidAdapter_spec.js +5 -2
- package/test/spec/modules/compassBidAdapter_spec.js +1 -0
- package/test/spec/modules/conversantBidAdapter_spec.js +54 -2
- package/test/spec/modules/criteoBidAdapter_spec.js +21 -0
- package/test/spec/modules/criteoIdSystem_spec.js +6 -3
- package/test/spec/modules/currency_spec.js +21 -6
- package/test/spec/modules/displayioBidAdapter_spec.js +239 -0
- package/test/spec/modules/e_volutionBidAdapter_spec.js +242 -0
- package/test/spec/modules/eids_spec.js +15 -0
- package/test/spec/modules/glimpseBidAdapter_spec.js +0 -18
- package/test/spec/modules/gnetBidAdapter_spec.js +6 -6
- package/test/spec/modules/gumgumBidAdapter_spec.js +46 -0
- package/test/spec/modules/idImportLibrary_spec.js +197 -10
- package/test/spec/modules/improvedigitalBidAdapter_spec.js +61 -0
- package/test/spec/modules/jwplayerRtdProvider_spec.js +195 -2
- package/test/spec/modules/kargoBidAdapter_spec.js +1 -1
- package/test/spec/modules/loglyliftBidAdapter_spec.js +1 -1
- package/test/spec/modules/lunamediahbBidAdapter_spec.js +27 -1
- package/test/spec/modules/nextMillenniumBidAdapter_spec.js +1 -1
- package/test/spec/modules/oguryBidAdapter_spec.js +69 -3
- package/test/spec/modules/pilotxBidAdapter_spec.js +244 -0
- package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +13 -1
- package/test/spec/modules/realTimeDataModule_spec.js +67 -5
- package/test/spec/modules/richaudienceBidAdapter_spec.js +40 -0
- package/test/spec/modules/riseBidAdapter_spec.js +31 -5
- package/test/spec/modules/rtbhouseBidAdapter_spec.js +20 -0
- package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +61 -1
- package/test/spec/modules/sharethroughBidAdapter_spec.js +91 -6
- package/test/spec/modules/showheroes-bsBidAdapter_spec.js +2 -0
- package/test/spec/modules/sortableAnalyticsAdapter_spec.js +2 -3
- package/test/spec/modules/sovrnBidAdapter_spec.js +413 -333
- package/test/spec/modules/synacormediaBidAdapter_spec.js +70 -0
- package/test/spec/modules/tappxBidAdapter_spec.js +0 -19
- package/test/spec/modules/teadsBidAdapter_spec.js +14 -59
- package/test/spec/modules/undertoneBidAdapter_spec.js +55 -2
- package/test/spec/modules/userId_spec.js +68 -19
- package/test/spec/modules/viewability_spec.js +280 -0
- package/test/spec/modules/weboramaRtdProvider_spec.js +536 -20
- package/test/spec/modules/welectBidAdapter_spec.js +211 -0
- package/test/spec/modules/yahoosspBidAdapter_spec.js +10 -0
- package/test/spec/unit/core/bidderSettings_spec.js +123 -0
- package/test/spec/unit/pbjs_api_spec.js +21 -8
- package/test/spec/unit/secureCreatives_spec.js +143 -24
|
@@ -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) {
|
|
@@ -158,12 +128,64 @@ function getGdprConsentChoice(bidderRequest) {
|
|
|
158
128
|
}
|
|
159
129
|
}
|
|
160
130
|
|
|
161
|
-
function
|
|
162
|
-
|
|
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
|
+
}
|
|
163
144
|
}
|
|
164
145
|
|
|
165
|
-
function
|
|
166
|
-
|
|
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
|
|
167
189
|
}
|
|
168
190
|
|
|
169
191
|
function isValidBidResponse(bidResponse) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { _each, parseSizesInput, isEmpty } from '../src/utils.js';
|
|
2
1
|
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
2
|
+
import { _each, isEmpty, parseSizesInput } from '../src/utils.js';
|
|
3
3
|
import { BANNER } from '../src/mediaTypes.js';
|
|
4
4
|
|
|
5
5
|
const BIDDER_CODE = 'gnet';
|
|
6
|
-
const ENDPOINT = 'https://
|
|
6
|
+
const ENDPOINT = 'https://service.gnetrtb.com/api/adrequest';
|
|
7
7
|
|
|
8
8
|
export const spec = {
|
|
9
9
|
code: BIDDER_CODE,
|
|
@@ -16,7 +16,7 @@ export const spec = {
|
|
|
16
16
|
* @return boolean True if this is a valid bid, and false otherwise.
|
|
17
17
|
*/
|
|
18
18
|
isBidRequestValid: function (bid) {
|
|
19
|
-
return !!(bid.params.websiteId);
|
|
19
|
+
return !!(bid.params.websiteId && bid.params.adunitId);
|
|
20
20
|
},
|
|
21
21
|
|
|
22
22
|
/**
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# Overview
|
|
2
2
|
|
|
3
3
|
```
|
|
4
|
-
Module Name: Gnet Bidder Adapter
|
|
4
|
+
Module Name: Gnet RTB Bidder Adapter
|
|
5
5
|
Module Type: Bidder Adapter
|
|
6
|
-
Maintainer:
|
|
6
|
+
Maintainer: bruno.bonanho@grumft.com
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
# Description
|
|
10
10
|
|
|
11
|
-
Connect to Gnet
|
|
11
|
+
Connect to Gnet RTB exchange for bids.
|
|
12
12
|
|
|
13
13
|
# Test Parameters
|
|
14
14
|
```
|
|
@@ -24,7 +24,7 @@ Connect to Gnet Project exchange for bids.
|
|
|
24
24
|
{
|
|
25
25
|
bidder: 'gnet',
|
|
26
26
|
params: {
|
|
27
|
-
websiteId: '
|
|
27
|
+
websiteId: '1', adunitId: '1'
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
]
|
|
@@ -17,32 +17,48 @@ const TIME_TO_LIVE = 60
|
|
|
17
17
|
const DELAY_REQUEST_TIME = 1800000; // setting to 30 mins
|
|
18
18
|
|
|
19
19
|
let invalidRequestIds = {};
|
|
20
|
-
let browserParams = {};
|
|
21
20
|
let pageViewId = null;
|
|
22
21
|
|
|
23
22
|
// TODO: potential 0 values for browserParams sent to ad server
|
|
24
23
|
function _getBrowserParams(topWindowUrl) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
let
|
|
28
|
-
let
|
|
29
|
-
let
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
const paramRegex = paramName => new RegExp(`[?#&](${paramName}=(.*?))($|&)`, 'i');
|
|
25
|
+
|
|
26
|
+
let browserParams = {};
|
|
27
|
+
let topWindow;
|
|
28
|
+
let topScreen;
|
|
29
|
+
let topUrl;
|
|
30
|
+
let ggad;
|
|
31
|
+
let ggdeal;
|
|
32
|
+
let ns;
|
|
33
|
+
|
|
34
|
+
function getNetworkSpeed () {
|
|
35
|
+
const connection = window.navigator && (window.navigator.connection || window.navigator.mozConnection || window.navigator.webkitConnection);
|
|
36
|
+
const Mbps = connection && (connection.downlink || connection.bandwidth);
|
|
37
|
+
return Mbps ? Math.round(Mbps * 1024) : null;
|
|
34
38
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
|
|
40
|
+
function getOgURL () {
|
|
41
|
+
let ogURL = '';
|
|
42
|
+
const ogURLSelector = "meta[property='og:url']";
|
|
43
|
+
const head = document && document.getElementsByTagName('head')[0];
|
|
44
|
+
const ogURLElement = head.querySelector(ogURLSelector);
|
|
45
|
+
ogURL = ogURLElement ? ogURLElement.content : null;
|
|
46
|
+
return ogURL;
|
|
42
47
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
|
|
49
|
+
function stripGGParams (url) {
|
|
50
|
+
const params = [
|
|
51
|
+
'ggad',
|
|
52
|
+
'ggdeal'
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
return params.reduce((result, param) => {
|
|
56
|
+
const matches = url.match(paramRegex(param));
|
|
57
|
+
if (!matches) return result;
|
|
58
|
+
matches[1] && (result = result.replace(matches[1], ''));
|
|
59
|
+
matches[3] && (result = result.replace(matches[3], ''));
|
|
60
|
+
return result;
|
|
61
|
+
}, url);
|
|
46
62
|
}
|
|
47
63
|
|
|
48
64
|
try {
|
|
@@ -51,7 +67,7 @@ function _getBrowserParams(topWindowUrl) {
|
|
|
51
67
|
topUrl = topWindowUrl || '';
|
|
52
68
|
} catch (error) {
|
|
53
69
|
logError(error);
|
|
54
|
-
return browserParams
|
|
70
|
+
return browserParams;
|
|
55
71
|
}
|
|
56
72
|
|
|
57
73
|
browserParams = {
|
|
@@ -59,23 +75,25 @@ function _getBrowserParams(topWindowUrl) {
|
|
|
59
75
|
vh: topWindow.innerHeight,
|
|
60
76
|
sw: topScreen.width,
|
|
61
77
|
sh: topScreen.height,
|
|
62
|
-
pu: topUrl,
|
|
78
|
+
pu: stripGGParams(topUrl),
|
|
63
79
|
ce: storage.cookiesAreEnabled(),
|
|
64
80
|
dpr: topWindow.devicePixelRatio || 1,
|
|
65
81
|
jcsi: JSON.stringify(JCSI),
|
|
66
82
|
ogu: getOgURL()
|
|
67
|
-
}
|
|
83
|
+
};
|
|
68
84
|
|
|
69
|
-
ns = getNetworkSpeed()
|
|
85
|
+
ns = getNetworkSpeed();
|
|
70
86
|
if (ns) {
|
|
71
|
-
browserParams.ns = ns
|
|
87
|
+
browserParams.ns = ns;
|
|
72
88
|
}
|
|
73
89
|
|
|
74
|
-
ggad = (topUrl.match(
|
|
75
|
-
if (ggad)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
90
|
+
ggad = (topUrl.match(paramRegex('ggad')) || [0, 0, 0])[2];
|
|
91
|
+
if (ggad) browserParams[isNaN(ggad) ? 'eAdBuyId' : 'adBuyId'] = ggad;
|
|
92
|
+
|
|
93
|
+
ggdeal = (topUrl.match(paramRegex('ggdeal')) || [0, 0, 0])[2];
|
|
94
|
+
if (ggdeal) browserParams.ggdeal = ggdeal;
|
|
95
|
+
|
|
96
|
+
return browserParams;
|
|
79
97
|
}
|
|
80
98
|
|
|
81
99
|
function getWrapperCode(wrapper, data) {
|
|
@@ -291,17 +309,17 @@ function buildRequests(validBidRequests, bidderRequest) {
|
|
|
291
309
|
} = bidRequest;
|
|
292
310
|
const { currency, floor } = _getFloor(mediaTypes, params.bidfloor, bidRequest);
|
|
293
311
|
const eids = getEids(userId);
|
|
312
|
+
const gpid = deepAccess(ortb2Imp, 'ext.data.pbadslot') || deepAccess(ortb2Imp, 'ext.data.adserver.adslot');
|
|
294
313
|
let sizes = [1, 1];
|
|
295
314
|
let data = {};
|
|
296
|
-
let gpid = '';
|
|
297
315
|
|
|
298
316
|
const date = new Date();
|
|
299
317
|
const lt = date.getTime();
|
|
300
318
|
const to = date.getTimezoneOffset();
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
319
|
+
|
|
320
|
+
// ADTS-174 Removed unnecessary checks to fix failing test
|
|
321
|
+
data.lt = lt;
|
|
322
|
+
data.to = to;
|
|
305
323
|
|
|
306
324
|
// ADTS-169 add adUnitCode to requests
|
|
307
325
|
if (adUnitCode) data.aun = adUnitCode
|
|
@@ -309,12 +327,8 @@ function buildRequests(validBidRequests, bidderRequest) {
|
|
|
309
327
|
// ADTS-134 Retrieve ID envelopes
|
|
310
328
|
for (const eid in eids) data[eid] = eids[eid];
|
|
311
329
|
|
|
312
|
-
// ADJS-1024 & ADSS-1297
|
|
313
|
-
|
|
314
|
-
gpid = deepAccess(ortb2Imp, 'ext.data.pbadslot')
|
|
315
|
-
} else if (deepAccess(ortb2Imp, 'ext.data.adserver.name')) {
|
|
316
|
-
gpid = ortb2Imp.ext.data.adserver.adslot
|
|
317
|
-
}
|
|
330
|
+
// ADJS-1024 & ADSS-1297 & ADTS-175
|
|
331
|
+
gpid && (data.gpid = gpid);
|
|
318
332
|
|
|
319
333
|
if (mediaTypes.banner) {
|
|
320
334
|
sizes = mediaTypes.banner.sizes;
|
|
@@ -384,7 +398,7 @@ function buildRequests(validBidRequests, bidderRequest) {
|
|
|
384
398
|
sizes,
|
|
385
399
|
url: BID_ENDPOINT,
|
|
386
400
|
method: 'GET',
|
|
387
|
-
data: Object.assign(data, _getBrowserParams(topWindowUrl), _getDigiTrustQueryParams(userId)
|
|
401
|
+
data: Object.assign(data, _getBrowserParams(topWindowUrl), _getDigiTrustQueryParams(userId))
|
|
388
402
|
})
|
|
389
403
|
});
|
|
390
404
|
return bids;
|
|
@@ -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'],
|
|
@@ -73,7 +73,24 @@ export const spec = {
|
|
|
73
73
|
requestParameters.referrer = bidderRequest.refererInfo.referer;
|
|
74
74
|
}
|
|
75
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
|
+
|
|
76
92
|
requestParameters.schain = bidRequests[0].schain;
|
|
93
|
+
requestParameters.coppa = config.getConfig('coppa') === true;
|
|
77
94
|
|
|
78
95
|
if (bidRequests[0].userId) {
|
|
79
96
|
const eids = createEidsArray(bidRequests[0].userId);
|
|
@@ -621,6 +638,12 @@ export function ImproveDigitalAdServerJSClient(endPoint) {
|
|
|
621
638
|
if (requestParameters.schain) {
|
|
622
639
|
impressionBidRequestObject.schain = requestParameters.schain;
|
|
623
640
|
}
|
|
641
|
+
if (requestParameters.pagecat) {
|
|
642
|
+
impressionBidRequestObject.pagecat = requestParameters.pagecat;
|
|
643
|
+
}
|
|
644
|
+
if (requestParameters.genre) {
|
|
645
|
+
impressionBidRequestObject.genre = requestParameters.genre;
|
|
646
|
+
}
|
|
624
647
|
if (requestParameters.user) {
|
|
625
648
|
impressionBidRequestObject.user = requestParameters.user;
|
|
626
649
|
}
|
|
@@ -630,6 +653,10 @@ export function ImproveDigitalAdServerJSClient(endPoint) {
|
|
|
630
653
|
}
|
|
631
654
|
}
|
|
632
655
|
|
|
656
|
+
if (requestParameters.coppa) {
|
|
657
|
+
impressionBidRequestObject.coppa = 1;
|
|
658
|
+
}
|
|
659
|
+
|
|
633
660
|
return impressionBidRequestObject;
|
|
634
661
|
};
|
|
635
662
|
|
|
@@ -83,7 +83,8 @@ function parseRequestPrebidjsToOpenRTB(prebidRequest) {
|
|
|
83
83
|
let openRTBRequest = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequest']));
|
|
84
84
|
openRTBRequest.id = prebidRequest.auctionId;
|
|
85
85
|
openRTBRequest.ext = {
|
|
86
|
-
|
|
86
|
+
refererInfo: prebidRequest.refererInfo,
|
|
87
|
+
auctionId: prebidRequest.auctionId
|
|
87
88
|
};
|
|
88
89
|
|
|
89
90
|
openRTBRequest.site = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestSite']));
|
|
@@ -111,15 +112,17 @@ function parseRequestPrebidjsToOpenRTB(prebidRequest) {
|
|
|
111
112
|
openRTBRequest.user = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestUser']));
|
|
112
113
|
|
|
113
114
|
openRTBRequest.imp = [];
|
|
114
|
-
prebidRequest.bids.forEach(function(bid
|
|
115
|
-
impId++;
|
|
115
|
+
prebidRequest.bids.forEach(function(bid) {
|
|
116
116
|
if (!ret.partnerId) {
|
|
117
117
|
ret.partnerId = bid.params.partnerId;
|
|
118
118
|
}
|
|
119
119
|
let imp = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestImp']));
|
|
120
|
-
imp.id =
|
|
120
|
+
imp.id = bid.bidId;
|
|
121
121
|
imp.secure = secure;
|
|
122
|
-
imp.tagid = bid.
|
|
122
|
+
imp.tagid = bid.adUnitCode;
|
|
123
|
+
imp.ext = {
|
|
124
|
+
rawdata: bid
|
|
125
|
+
};
|
|
123
126
|
|
|
124
127
|
openRTBRequest.site.publisher.id = openRTBRequest.site.publisher.id || 0;
|
|
125
128
|
openRTBRequest.tmax = openRTBRequest.tmax || bid.params.tmax || 0;
|
|
@@ -152,7 +155,7 @@ function parseResponseOpenRTBToPrebidjs(openRTBResponse) {
|
|
|
152
155
|
if (seatbid.bid && seatbid.bid.forEach) {
|
|
153
156
|
seatbid.bid.forEach(function(bid) {
|
|
154
157
|
let prebid = JSON.parse(JSON.stringify(DEFAULT['PrebidBid']));
|
|
155
|
-
prebid.requestId = bid.
|
|
158
|
+
prebid.requestId = bid.impid;
|
|
156
159
|
prebid.ad = bid.adm;
|
|
157
160
|
prebid.creativeId = bid.crid;
|
|
158
161
|
prebid.cpm = bid.price;
|
|
@@ -155,8 +155,10 @@ export function enrichAdUnits(adUnits) {
|
|
|
155
155
|
if (!vat) {
|
|
156
156
|
return;
|
|
157
157
|
}
|
|
158
|
+
const contentId = getContentId(vat.mediaID);
|
|
159
|
+
const contentData = getContentData(vat.segments);
|
|
158
160
|
const targeting = formatTargetingResponse(vat);
|
|
159
|
-
|
|
161
|
+
enrichBids(adUnit.bids, targeting, contentId, contentData);
|
|
160
162
|
};
|
|
161
163
|
loadVat(jwTargeting, onVatResponse);
|
|
162
164
|
});
|
|
@@ -235,6 +237,9 @@ export function getVatFromPlayer(playerID, mediaID) {
|
|
|
235
237
|
};
|
|
236
238
|
}
|
|
237
239
|
|
|
240
|
+
/*
|
|
241
|
+
deprecated
|
|
242
|
+
*/
|
|
238
243
|
export function formatTargetingResponse(vat) {
|
|
239
244
|
const { segments, mediaID } = vat;
|
|
240
245
|
const targeting = {};
|
|
@@ -243,23 +248,83 @@ export function formatTargetingResponse(vat) {
|
|
|
243
248
|
}
|
|
244
249
|
|
|
245
250
|
if (mediaID) {
|
|
246
|
-
const id = 'jw_' + mediaID;
|
|
247
251
|
targeting.content = {
|
|
248
|
-
id
|
|
252
|
+
id: getContentId(mediaID)
|
|
249
253
|
}
|
|
250
254
|
}
|
|
251
255
|
return targeting;
|
|
252
256
|
}
|
|
253
257
|
|
|
254
|
-
function
|
|
255
|
-
if (!
|
|
258
|
+
export function getContentId(mediaID) {
|
|
259
|
+
if (!mediaID) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return 'jw_' + mediaID;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export function getContentData(segments) {
|
|
267
|
+
if (!segments || !segments.length) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const formattedSegments = segments.reduce((convertedSegments, rawSegment) => {
|
|
272
|
+
convertedSegments.push({
|
|
273
|
+
id: rawSegment,
|
|
274
|
+
value: rawSegment
|
|
275
|
+
});
|
|
276
|
+
return convertedSegments;
|
|
277
|
+
}, []);
|
|
278
|
+
|
|
279
|
+
return {
|
|
280
|
+
name: 'jwplayer',
|
|
281
|
+
ext: {
|
|
282
|
+
segtax: 502
|
|
283
|
+
},
|
|
284
|
+
segment: formattedSegments
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export function addOrtbSiteContent(bid, contentId, contentData) {
|
|
289
|
+
if (!contentId && !contentData) {
|
|
256
290
|
return;
|
|
257
291
|
}
|
|
258
292
|
|
|
259
|
-
|
|
293
|
+
let ortb2 = bid.ortb2 || {};
|
|
294
|
+
let site = ortb2.site = ortb2.site || {};
|
|
295
|
+
let content = site.content = site.content || {};
|
|
296
|
+
|
|
297
|
+
if (contentId) {
|
|
298
|
+
content.id = contentId;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (contentData) {
|
|
302
|
+
const data = content.data = content.data || [];
|
|
303
|
+
data.push(contentData);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
bid.ortb2 = ortb2;
|
|
260
307
|
}
|
|
261
308
|
|
|
309
|
+
function enrichBids(bids, targeting, contentId, contentData) {
|
|
310
|
+
if (!bids) {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
bids.forEach(bid => {
|
|
315
|
+
addTargetingToBid(bid, targeting);
|
|
316
|
+
addOrtbSiteContent(bid, contentId, contentData);
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/*
|
|
321
|
+
deprecated
|
|
322
|
+
*/
|
|
262
323
|
export function addTargetingToBid(bid, targeting) {
|
|
324
|
+
if (!targeting) {
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
|
|
263
328
|
const rtd = bid.rtd || {};
|
|
264
329
|
const jwRtd = {};
|
|
265
330
|
jwRtd[SUBMODULE_NAME] = Object.assign({}, rtd[SUBMODULE_NAME], { targeting });
|