prebid.js 6.7.0 → 6.8.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/integrationExamples/gpt/x-domain/creative.html +53 -26
- package/modules/adagioBidAdapter.js +0 -8
- package/modules/adagioBidAdapter.md +1 -1
- package/modules/appnexusBidAdapter.js +11 -0
- package/modules/brandmetricsRtdProvider.js +168 -0
- package/modules/brandmetricsRtdProvider.md +40 -0
- package/modules/criteoBidAdapter.js +9 -0
- 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/gumgumBidAdapter.js +52 -38
- package/modules/interactiveOffersBidAdapter.js +9 -6
- package/modules/sovrnBidAdapter.js +93 -18
- package/modules/sovrnBidAdapter.md +80 -2
- package/modules/undertoneBidAdapter.js +17 -1
- package/modules/yahoosspBidAdapter.js +2 -0
- package/package.json +1 -1
- package/src/adRendering.js +38 -0
- package/src/auction.js +44 -9
- package/src/prebid.js +3 -19
- package/src/secureCreatives.js +111 -42
- package/src/utils.js +13 -3
- package/test/helpers/syncPromise.js +71 -0
- package/test/spec/auctionmanager_spec.js +148 -16
- package/test/spec/modules/adagioBidAdapter_spec.js +0 -10
- package/test/spec/modules/appnexusBidAdapter_spec.js +27 -0
- package/test/spec/modules/brandmetricsRtdProvider_spec.js +191 -0
- package/test/spec/modules/criteoBidAdapter_spec.js +21 -0
- 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/gumgumBidAdapter_spec.js +46 -0
- package/test/spec/modules/sovrnBidAdapter_spec.js +413 -333
- package/test/spec/modules/undertoneBidAdapter_spec.js +55 -2
- package/test/spec/modules/yahoosspBidAdapter_spec.js +10 -0
- package/test/spec/unit/pbjs_api_spec.js +17 -1
- package/test/spec/unit/secureCreatives_spec.js +85 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
Module Name: DisplayIO Bidder Adapter
|
|
5
|
+
Module Type: Bidder Adapter
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
# Description
|
|
9
|
+
|
|
10
|
+
Module that connects to display.io's demand sources.
|
|
11
|
+
Web mobile (not relevant for web desktop).
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
#Features
|
|
15
|
+
| Feature | | Feature | |
|
|
16
|
+
|---------------|---------------------------------------------------------|-----------------------|-----|
|
|
17
|
+
| Bidder Code | displayio | Prebid member | no |
|
|
18
|
+
| Media Types | Banner, video. <br/>Sizes (display 320x480 / vertical video) | GVL ID | no |
|
|
19
|
+
| GDPR Support | yes | Prebid.js Adapter | yes |
|
|
20
|
+
| USP Support | yes | Prebid Server Adapter | no |
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
#Global configuration
|
|
24
|
+
```javascript
|
|
25
|
+
<head>
|
|
26
|
+
<script src="https://cdn.display.io/webis/webis.min.js"></script>
|
|
27
|
+
</head>
|
|
28
|
+
<script>
|
|
29
|
+
......................................
|
|
30
|
+
var CMP_TIMEOUT = 8000;
|
|
31
|
+
var consentManagement = {
|
|
32
|
+
gdpr: {
|
|
33
|
+
cmpApi: 'iab',
|
|
34
|
+
timeout: CMP_TIMEOUT,
|
|
35
|
+
defaultGdprScope: true
|
|
36
|
+
},
|
|
37
|
+
usp: {
|
|
38
|
+
cmpApi: 'iab',
|
|
39
|
+
timeout: CMP_TIMEOUT
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (typeof __tcfapi !== 'function') {
|
|
44
|
+
delete consentManagement.gdpr;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
pbjs.que.push(function() {
|
|
48
|
+
pbjs.setConfig({consentManagement})
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
......................................
|
|
53
|
+
|
|
54
|
+
function initAdserver(bidResponses) {
|
|
55
|
+
if (pbjs.initAdserverSet) return;
|
|
56
|
+
pbjs.initAdserverSet = true;
|
|
57
|
+
|
|
58
|
+
...........................
|
|
59
|
+
|
|
60
|
+
const displayioBids = getDisplayioBid(bidResponses)
|
|
61
|
+
displayioBids.forEach(b => {
|
|
62
|
+
const {adData, placement} = b[1].bids[0];
|
|
63
|
+
webis.init(adData, b[0], {placement})
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function getDisplayioBid(bidResponses) {
|
|
69
|
+
const codes = adUnits.map(u => u.code);
|
|
70
|
+
const bids = Object.entries(bidResponses);
|
|
71
|
+
bids.filter(([key, value]) => codes.includes(key) && value.bids[0].bidderCode === 'displayio');
|
|
72
|
+
return bids;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
......................................
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
# Bid Parameters
|
|
81
|
+
|
|
82
|
+
| Name | Scope | Type | Description | Example |
|
|
83
|
+
|----------------| ----- | ---- |----------------------------------------|-------------------------------|
|
|
84
|
+
| `siteId` | required | Number | SiteId and PlacementID are your inventory IDs on the display.io platform (please ask your Account Manager for your site and placement IDs). | 7753 |
|
|
85
|
+
| `placementId` | required | Number | SiteId and PlacementID are your inventory IDs on the display.io platform (please ask your Account Manager for your site and placement IDs). | 5375 |
|
|
86
|
+
| `adsSrvDomain` | required | String | | "appsrv.display.io" |
|
|
87
|
+
| `cdnDomain` | required | String | | "cdn.display.io" |
|
|
88
|
+
| `pageCategory` | optional | String | Comma-separated list of IAB content categories that describe the current page or view of the site, list of available values. | "pageCategory1, pageCategory2" |
|
|
89
|
+
| `keywords` | optional | String | Comma-separated list of keywords describing the content. | "keyword1, keyword2, keyword3" |
|
|
90
|
+
| `custom` | optional | Object | User-defined targeting key-value pairs. custom applies to a specific unit. | `{headerTextColor: "red", fixedHeaderSelector: '.site-header'}` |
|
|
91
|
+
| `custom.headerText`| optional | String | Ad container header text. By default, text is "Scroll to continue with content". Limited to 50 characters. | "Our awesome advertisement"|
|
|
92
|
+
| `custom.headerTextColor`| optional | String | Ad container header text color, "white" by default | "#2196f3"|
|
|
93
|
+
| `custom.headerBackgroundColor`| optional | String | Ad container header background color, "black" by default | "#fff" |
|
|
94
|
+
| `custom.adContainerBackgroundColor`| optional | String | Ad container body background color, "transparent" by default | "#000"|
|
|
95
|
+
| `custom.fixedHeaderSelector`| optional | String | In case your webpage has a fixed header – the header Id attribute or header class attribute should be defined as a value for parameter fixedHeaderSelector. | ".site-header"|
|
|
96
|
+
|
|
97
|
+
# adUnit configuration example
|
|
98
|
+
```javascript
|
|
99
|
+
var adUnits = [
|
|
100
|
+
{
|
|
101
|
+
code: 'ad-tag-1',
|
|
102
|
+
mediaTypes: {
|
|
103
|
+
banner: {
|
|
104
|
+
sizes: [[320, 480]]
|
|
105
|
+
},
|
|
106
|
+
video: {
|
|
107
|
+
sizes: [[360, 640]]
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
bids: [
|
|
111
|
+
{
|
|
112
|
+
bidder: 'displayio',
|
|
113
|
+
params: {
|
|
114
|
+
siteId: 1,
|
|
115
|
+
placementId: 1,
|
|
116
|
+
adsSrvDomain: 'appsrv.display.io',
|
|
117
|
+
cdnDomain: 'cdn.display.io',
|
|
118
|
+
pageCategory: 'pageCategory1, pageCategory2', //comma separated
|
|
119
|
+
keywords: 'keyword1, keyword2, keyword3', //comma separated
|
|
120
|
+
custom: {
|
|
121
|
+
headerText: 'Our awesome advertisement',
|
|
122
|
+
headerTextColor: '#2196f3',
|
|
123
|
+
headerBackgroundColor: 'black',
|
|
124
|
+
adContainerBackgroundColor: 'transparent',
|
|
125
|
+
fixedHeaderSelector: '.site-header',
|
|
126
|
+
},
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
]
|
|
130
|
+
},
|
|
131
|
+
// minimal required options
|
|
132
|
+
{
|
|
133
|
+
code: 'ad-tag-2',
|
|
134
|
+
bids: [{
|
|
135
|
+
bidder: 'displayio',
|
|
136
|
+
params: {
|
|
137
|
+
siteId: 1,
|
|
138
|
+
placementId: 1,
|
|
139
|
+
adsSrvDomain: 'appsrv.display.io',
|
|
140
|
+
cdnDomain: 'cdn.display.io',
|
|
141
|
+
}
|
|
142
|
+
}]
|
|
143
|
+
}
|
|
144
|
+
];
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
# Additional Details
|
|
148
|
+
[Mobile web prebid.js integration](https://www.display.io/documentation/mobile-web-prebid-js-integration/)
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
2
|
+
import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
|
|
3
|
+
import { isFn, deepAccess, logMessage } from '../src/utils.js';
|
|
4
|
+
|
|
5
|
+
const BIDDER_CODE = 'e_volution';
|
|
6
|
+
const AD_URL = 'https://service.e-volution.ai/?c=o&m=multi';
|
|
7
|
+
const URL_SYNC = 'https://service.e-volution.ai/?c=o&m=sync';
|
|
8
|
+
const NO_SYNC = true;
|
|
9
|
+
|
|
10
|
+
function isBidResponseValid(bid) {
|
|
11
|
+
if (!bid.requestId || !bid.cpm || !bid.creativeId ||
|
|
12
|
+
!bid.ttl || !bid.currency) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
switch (bid.mediaType) {
|
|
16
|
+
case BANNER:
|
|
17
|
+
return Boolean(bid.width && bid.height && bid.ad);
|
|
18
|
+
case VIDEO:
|
|
19
|
+
return Boolean(bid.vastUrl);
|
|
20
|
+
case NATIVE:
|
|
21
|
+
return Boolean(bid.native && bid.native.title && bid.native.image && bid.native.impressionTrackers);
|
|
22
|
+
default:
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getBidFloor(bid) {
|
|
28
|
+
if (!isFn(bid.getFloor)) {
|
|
29
|
+
return deepAccess(bid, 'params.bidfloor', 0);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const bidFloor = bid.getFloor({
|
|
34
|
+
currency: 'USD',
|
|
35
|
+
mediaType: '*',
|
|
36
|
+
size: '*',
|
|
37
|
+
});
|
|
38
|
+
return bidFloor.floor;
|
|
39
|
+
} catch (_) {
|
|
40
|
+
return 0
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const spec = {
|
|
45
|
+
code: BIDDER_CODE,
|
|
46
|
+
supportedMediaTypes: [BANNER, VIDEO, NATIVE],
|
|
47
|
+
noSync: NO_SYNC,
|
|
48
|
+
|
|
49
|
+
isBidRequestValid: (bid) => {
|
|
50
|
+
return Boolean(bid.bidId && bid.params && !isNaN(parseInt(bid.params.placementId)));
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
buildRequests: (validBidRequests = [], bidderRequest) => {
|
|
54
|
+
let winTop = window;
|
|
55
|
+
let location;
|
|
56
|
+
try {
|
|
57
|
+
location = new URL(bidderRequest.refererInfo.referer)
|
|
58
|
+
winTop = window.top;
|
|
59
|
+
} catch (e) {
|
|
60
|
+
location = winTop.location;
|
|
61
|
+
logMessage(e);
|
|
62
|
+
};
|
|
63
|
+
let placements = [];
|
|
64
|
+
let request = {
|
|
65
|
+
'deviceWidth': winTop.screen.width,
|
|
66
|
+
'deviceHeight': winTop.screen.height,
|
|
67
|
+
'language': (navigator && navigator.language) ? navigator.language.split('-')[0] : '',
|
|
68
|
+
'secure': 1,
|
|
69
|
+
'host': location.host,
|
|
70
|
+
'page': location.pathname,
|
|
71
|
+
'placements': placements
|
|
72
|
+
};
|
|
73
|
+
if (bidderRequest) {
|
|
74
|
+
if (bidderRequest.uspConsent) {
|
|
75
|
+
request.ccpa = bidderRequest.uspConsent;
|
|
76
|
+
}
|
|
77
|
+
if (bidderRequest.gdprConsent) {
|
|
78
|
+
request.gdpr = bidderRequest.gdprConsent
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const len = validBidRequests.length;
|
|
82
|
+
|
|
83
|
+
for (let i = 0; i < len; i++) {
|
|
84
|
+
let bid = validBidRequests[i];
|
|
85
|
+
|
|
86
|
+
const placement = {
|
|
87
|
+
placementId: bid.params.placementId,
|
|
88
|
+
bidId: bid.bidId,
|
|
89
|
+
bidfloor: getBidFloor(bid)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (bid.mediaTypes && bid.mediaTypes[BANNER] && bid.mediaTypes[BANNER].sizes) {
|
|
93
|
+
placement.traffic = BANNER;
|
|
94
|
+
placement.sizes = bid.mediaTypes[BANNER].sizes;
|
|
95
|
+
} else if (bid.mediaTypes && bid.mediaTypes[VIDEO] && bid.mediaTypes[VIDEO].playerSize) {
|
|
96
|
+
placement.traffic = VIDEO;
|
|
97
|
+
placement.wPlayer = bid.mediaTypes[VIDEO].playerSize[0];
|
|
98
|
+
placement.hPlayer = bid.mediaTypes[VIDEO].playerSize[1];
|
|
99
|
+
placement.minduration = bid.mediaTypes[VIDEO].minduration;
|
|
100
|
+
placement.maxduration = bid.mediaTypes[VIDEO].maxduration;
|
|
101
|
+
placement.mimes = bid.mediaTypes[VIDEO].mimes;
|
|
102
|
+
placement.protocols = bid.mediaTypes[VIDEO].protocols;
|
|
103
|
+
placement.startdelay = bid.mediaTypes[VIDEO].startdelay;
|
|
104
|
+
placement.placement = bid.mediaTypes[VIDEO].placement;
|
|
105
|
+
placement.skip = bid.mediaTypes[VIDEO].skip;
|
|
106
|
+
placement.skipafter = bid.mediaTypes[VIDEO].skipafter;
|
|
107
|
+
placement.minbitrate = bid.mediaTypes[VIDEO].minbitrate;
|
|
108
|
+
placement.maxbitrate = bid.mediaTypes[VIDEO].maxbitrate;
|
|
109
|
+
placement.delivery = bid.mediaTypes[VIDEO].delivery;
|
|
110
|
+
placement.playbackmethod = bid.mediaTypes[VIDEO].playbackmethod;
|
|
111
|
+
placement.api = bid.mediaTypes[VIDEO].api;
|
|
112
|
+
placement.linearity = bid.mediaTypes[VIDEO].linearity;
|
|
113
|
+
} else if (bid.mediaTypes && bid.mediaTypes[NATIVE]) {
|
|
114
|
+
placement.traffic = NATIVE;
|
|
115
|
+
placement.native = bid.mediaTypes[NATIVE];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (bid.schain) {
|
|
119
|
+
placements.schain = bid.schain;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
placements.push(placement);
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
method: 'POST',
|
|
126
|
+
url: AD_URL,
|
|
127
|
+
data: request
|
|
128
|
+
};
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
interpretResponse: (serverResponse) => {
|
|
132
|
+
let response = [];
|
|
133
|
+
for (let i = 0; i < serverResponse.body.length; i++) {
|
|
134
|
+
let resItem = serverResponse.body[i];
|
|
135
|
+
if (isBidResponseValid(resItem)) {
|
|
136
|
+
const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : [];
|
|
137
|
+
resItem.meta = { ...resItem.meta, advertiserDomains };
|
|
138
|
+
|
|
139
|
+
response.push(resItem);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return response;
|
|
143
|
+
},
|
|
144
|
+
|
|
145
|
+
getUserSyncs: (syncOptions, serverResponses) => {
|
|
146
|
+
if (NO_SYNC) {
|
|
147
|
+
return false
|
|
148
|
+
} else {
|
|
149
|
+
return [{
|
|
150
|
+
type: 'image',
|
|
151
|
+
url: URL_SYNC
|
|
152
|
+
}];
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
registerBidder(spec);
|
|
@@ -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,9 +309,9 @@ 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();
|
|
@@ -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;
|
|
@@ -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;
|
|
@@ -1,12 +1,38 @@
|
|
|
1
|
-
import { _each, getBidIdParameter, isArray, deepClone, parseUrl, getUniqueIdentifierStr, deepSetValue, logError, deepAccess } from '../src/utils.js';
|
|
1
|
+
import { _each, getBidIdParameter, isArray, deepClone, parseUrl, getUniqueIdentifierStr, deepSetValue, logError, deepAccess, isInteger, logWarn } from '../src/utils.js';
|
|
2
2
|
import { registerBidder } from '../src/adapters/bidderFactory.js'
|
|
3
|
-
import { BANNER } from '../src/mediaTypes.js'
|
|
3
|
+
import { ADPOD, BANNER, VIDEO } from '../src/mediaTypes.js'
|
|
4
4
|
import { createEidsArray } from './userId/eids.js';
|
|
5
5
|
import {config} from '../src/config.js';
|
|
6
6
|
|
|
7
|
+
const ORTB_VIDEO_PARAMS = {
|
|
8
|
+
'mimes': (value) => Array.isArray(value) && value.length > 0 && value.every(v => typeof v === 'string'),
|
|
9
|
+
'minduration': (value) => isInteger(value),
|
|
10
|
+
'maxduration': (value) => isInteger(value),
|
|
11
|
+
'protocols': (value) => Array.isArray(value) && value.every(v => v >= 1 && v <= 10),
|
|
12
|
+
'w': (value) => isInteger(value),
|
|
13
|
+
'h': (value) => isInteger(value),
|
|
14
|
+
'startdelay': (value) => isInteger(value),
|
|
15
|
+
'placement': (value) => Array.isArray(value) && value.every(v => v >= 1 && v <= 5),
|
|
16
|
+
'linearity': (value) => [1, 2].indexOf(value) !== -1,
|
|
17
|
+
'skip': (value) => [0, 1].indexOf(value) !== -1,
|
|
18
|
+
'skipmin': (value) => isInteger(value),
|
|
19
|
+
'skipafter': (value) => isInteger(value),
|
|
20
|
+
'sequence': (value) => isInteger(value),
|
|
21
|
+
'battr': (value) => Array.isArray(value) && value.every(v => v >= 1 && v <= 17),
|
|
22
|
+
'maxextended': (value) => isInteger(value),
|
|
23
|
+
'minbitrate': (value) => isInteger(value),
|
|
24
|
+
'maxbitrate': (value) => isInteger(value),
|
|
25
|
+
'boxingallowed': (value) => [0, 1].indexOf(value) !== -1,
|
|
26
|
+
'playbackmethod': (value) => Array.isArray(value) && value.every(v => v >= 1 && v <= 6),
|
|
27
|
+
'playbackend': (value) => [1, 2, 3].indexOf(value) !== -1,
|
|
28
|
+
'delivery': (value) => [1, 2, 3].indexOf(value) !== -1,
|
|
29
|
+
'pos': (value) => Array.isArray(value) && value.every(v => v >= 0 && v <= 7),
|
|
30
|
+
'api': (value) => Array.isArray(value) && value.every(v => v >= 1 && v <= 6)
|
|
31
|
+
}
|
|
32
|
+
|
|
7
33
|
export const spec = {
|
|
8
34
|
code: 'sovrn',
|
|
9
|
-
supportedMediaTypes: [BANNER],
|
|
35
|
+
supportedMediaTypes: [BANNER, VIDEO],
|
|
10
36
|
gvlid: 13,
|
|
11
37
|
|
|
12
38
|
/**
|
|
@@ -15,7 +41,12 @@ export const spec = {
|
|
|
15
41
|
* @return boolean for whether or not a bid is valid
|
|
16
42
|
*/
|
|
17
43
|
isBidRequestValid: function(bid) {
|
|
18
|
-
return !!(
|
|
44
|
+
return !!(
|
|
45
|
+
bid.params.tagid &&
|
|
46
|
+
!isNaN(parseFloat(bid.params.tagid)) &&
|
|
47
|
+
isFinite(bid.params.tagid) &&
|
|
48
|
+
deepAccess(bid, 'mediaTypes.video.context') !== ADPOD
|
|
49
|
+
)
|
|
19
50
|
},
|
|
20
51
|
|
|
21
52
|
/**
|
|
@@ -50,13 +81,9 @@ export const spec = {
|
|
|
50
81
|
}
|
|
51
82
|
iv = iv || getBidIdParameter('iv', bid.params)
|
|
52
83
|
|
|
53
|
-
let bidSizes = (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) || bid.sizes
|
|
54
|
-
bidSizes = ((isArray(bidSizes) && isArray(bidSizes[0])) ? bidSizes : [bidSizes])
|
|
55
|
-
bidSizes = bidSizes.filter(size => isArray(size))
|
|
56
|
-
const processedSizes = bidSizes.map(size => ({w: parseInt(size[0], 10), h: parseInt(size[1], 10)}))
|
|
57
84
|
const floorInfo = (bid.getFloor && typeof bid.getFloor === 'function') ? bid.getFloor({
|
|
58
85
|
currency: 'USD',
|
|
59
|
-
mediaType: 'banner',
|
|
86
|
+
mediaType: bid.mediaTypes && bid.mediaTypes.banner ? 'banner' : 'video',
|
|
60
87
|
size: '*'
|
|
61
88
|
}) : {}
|
|
62
89
|
floorInfo.floor = floorInfo.floor || getBidIdParameter('bidfloor', bid.params)
|
|
@@ -64,13 +91,24 @@ export const spec = {
|
|
|
64
91
|
const imp = {
|
|
65
92
|
adunitcode: bid.adUnitCode,
|
|
66
93
|
id: bid.bidId,
|
|
67
|
-
|
|
94
|
+
tagid: String(getBidIdParameter('tagid', bid.params)),
|
|
95
|
+
bidfloor: floorInfo.floor
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (deepAccess(bid, 'mediaTypes.banner')) {
|
|
99
|
+
let bidSizes = deepAccess(bid, 'mediaTypes.banner.sizes') || bid.sizes
|
|
100
|
+
bidSizes = (isArray(bidSizes) && isArray(bidSizes[0])) ? bidSizes : [bidSizes]
|
|
101
|
+
bidSizes = bidSizes.filter(size => isArray(size))
|
|
102
|
+
const processedSizes = bidSizes.map(size => ({w: parseInt(size[0], 10), h: parseInt(size[1], 10)}))
|
|
103
|
+
|
|
104
|
+
imp.banner = {
|
|
68
105
|
format: processedSizes,
|
|
69
106
|
w: 1,
|
|
70
107
|
h: 1,
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
if (deepAccess(bid, 'mediaTypes.video')) {
|
|
111
|
+
imp.video = _buildVideoRequestObj(bid);
|
|
74
112
|
}
|
|
75
113
|
|
|
76
114
|
imp.ext = getBidIdParameter('ext', bid.ortb2Imp) || undefined
|
|
@@ -149,7 +187,7 @@ export const spec = {
|
|
|
149
187
|
seatbid[0].bid &&
|
|
150
188
|
seatbid[0].bid.length > 0) {
|
|
151
189
|
seatbid[0].bid.map(sovrnBid => {
|
|
152
|
-
|
|
190
|
+
const bid = {
|
|
153
191
|
requestId: sovrnBid.impid,
|
|
154
192
|
cpm: parseFloat(sovrnBid.price),
|
|
155
193
|
width: parseInt(sovrnBid.w),
|
|
@@ -158,11 +196,18 @@ export const spec = {
|
|
|
158
196
|
dealId: sovrnBid.dealid || null,
|
|
159
197
|
currency: 'USD',
|
|
160
198
|
netRevenue: true,
|
|
161
|
-
mediaType: BANNER,
|
|
162
|
-
ad: decodeURIComponent(`${sovrnBid.adm}<img src="${sovrnBid.nurl}">`),
|
|
163
199
|
ttl: sovrnBid.ext ? (sovrnBid.ext.ttl || 90) : 90,
|
|
164
200
|
meta: { advertiserDomains: sovrnBid && sovrnBid.adomain ? sovrnBid.adomain : [] }
|
|
165
|
-
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (!sovrnBid.nurl) {
|
|
204
|
+
bid.mediaType = VIDEO
|
|
205
|
+
bid.vastXml = decodeURIComponent(sovrnBid.adm)
|
|
206
|
+
} else {
|
|
207
|
+
bid.mediaType = BANNER
|
|
208
|
+
bid.ad = decodeURIComponent(`${sovrnBid.adm}<img src="${sovrnBid.nurl}">`)
|
|
209
|
+
}
|
|
210
|
+
sovrnBidResponses.push(bid);
|
|
166
211
|
});
|
|
167
212
|
}
|
|
168
213
|
return sovrnBidResponses
|
|
@@ -209,4 +254,34 @@ export const spec = {
|
|
|
209
254
|
},
|
|
210
255
|
}
|
|
211
256
|
|
|
212
|
-
|
|
257
|
+
function _buildVideoRequestObj(bid) {
|
|
258
|
+
const videoObj = {}
|
|
259
|
+
const videoAdUnitParams = deepAccess(bid, 'mediaTypes.video', {})
|
|
260
|
+
const videoBidderParams = deepAccess(bid, 'params.video', {})
|
|
261
|
+
const computedParams = {}
|
|
262
|
+
|
|
263
|
+
if (Array.isArray(videoAdUnitParams.playerSize)) {
|
|
264
|
+
const sizes = (Array.isArray(videoAdUnitParams.playerSize[0])) ? videoAdUnitParams.playerSize[0] : videoAdUnitParams.playerSize
|
|
265
|
+
computedParams.w = sizes[0]
|
|
266
|
+
computedParams.h = sizes[1]
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const videoParams = {
|
|
270
|
+
...computedParams,
|
|
271
|
+
...videoAdUnitParams,
|
|
272
|
+
...videoBidderParams
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
Object.keys(ORTB_VIDEO_PARAMS).forEach(paramName => {
|
|
276
|
+
if (videoParams.hasOwnProperty(paramName)) {
|
|
277
|
+
if (ORTB_VIDEO_PARAMS[paramName](videoParams[paramName])) {
|
|
278
|
+
videoObj[paramName] = videoParams[paramName]
|
|
279
|
+
} else {
|
|
280
|
+
logWarn(`The OpenRTB video param ${paramName} has been skipped due to misformating. Please refer to OpenRTB 2.5 spec.`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
})
|
|
284
|
+
return videoObj
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
registerBidder(spec)
|