prebid.js 5.18.0 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc.js +1 -10
- package/README.md +3 -1
- package/browsers.json +1 -8
- package/gulpfile.js +1 -0
- package/integrationExamples/gpt/akamaidap_segments_example.html +132 -0
- package/modules/.submodules.json +1 -0
- package/modules/adfBidAdapter.js +21 -16
- package/modules/adheseBidAdapter.js +7 -2
- package/modules/adkernelBidAdapter.js +1 -0
- package/modules/adlivetechBidAdapter.md +61 -0
- package/modules/adomikAnalyticsAdapter.js +10 -4
- package/modules/adtelligentBidAdapter.js +2 -1
- package/modules/airgridRtdProvider.js +1 -1
- package/modules/akamaiDapRtdProvider.js +474 -0
- package/modules/akamaiDapRtdProvider.md +47 -0
- package/modules/appnexusBidAdapter.js +9 -3
- package/modules/atsAnalyticsAdapter.js +67 -46
- package/modules/atsAnalyticsAdapter.md +1 -0
- package/modules/betweenBidAdapter.js +20 -3
- package/modules/browsiRtdProvider.js +106 -18
- package/modules/cleanioRtdProvider.js +192 -0
- package/modules/cleanioRtdProvider.md +59 -0
- package/modules/codefuelBidAdapter.js +181 -0
- package/modules/codefuelBidAdapter.md +111 -0
- package/modules/connectIdSystem.js +104 -0
- package/modules/connectIdSystem.md +33 -0
- package/modules/datablocksBidAdapter.js +3 -3
- package/modules/deepintentBidAdapter.js +107 -10
- package/modules/deepintentBidAdapter.md +36 -1
- package/modules/deltaprojectsBidAdapter.js +252 -0
- package/modules/deltaprojectsBidAdapter.md +32 -0
- package/modules/engageyaBidAdapter.js +171 -0
- package/modules/glimpseBidAdapter.js +31 -16
- package/modules/gptPreAuction.js +11 -5
- package/modules/gridBidAdapter.js +1 -0
- package/modules/gumgumBidAdapter.js +8 -0
- package/modules/id5IdSystem.md +6 -6
- package/modules/imRtdProvider.js +31 -0
- package/modules/inskinBidAdapter.js +7 -3
- package/modules/ixBidAdapter.js +174 -22
- package/modules/jixieBidAdapter.js +8 -2
- package/modules/justpremiumBidAdapter.js +6 -1
- package/modules/limelightDigitalBidAdapter.js +22 -2
- package/modules/livewrappedAnalyticsAdapter.js +49 -1
- package/modules/merkleIdSystem.js +5 -0
- package/modules/multibid/index.js +3 -3
- package/modules/nativoBidAdapter.js +32 -2
- package/modules/nextMillenniumBidAdapter.js +12 -3
- package/modules/oguryBidAdapter.js +16 -2
- package/modules/openxBidAdapter.js +40 -23
- package/modules/operaadsBidAdapter.js +21 -1
- package/modules/otmBidAdapter.js +146 -0
- package/modules/otmBidAdapter.md +27 -26
- package/modules/outbrainBidAdapter.js +5 -0
- package/modules/playwireBidAdapter.md +61 -0
- package/modules/prebidServerBidAdapter/index.js +3 -3
- package/modules/publinkIdSystem.js +11 -6
- package/modules/pubmaticBidAdapter.js +2 -0
- package/modules/rtdModule/index.js +2 -2
- package/modules/saambaaBidAdapter.js +420 -0
- package/modules/saambaaBidAdapter.md +65 -68
- package/modules/seedtagBidAdapter.js +6 -0
- package/modules/smaatoBidAdapter.js +6 -1
- package/modules/sonobiBidAdapter.js +7 -0
- package/modules/sortableBidAdapter.js +1 -0
- package/modules/sspBCBidAdapter.js +34 -3
- package/modules/teadsBidAdapter.js +3 -0
- package/modules/tripleliftBidAdapter.js +22 -5
- package/modules/trustxBidAdapter.js +18 -7
- package/modules/undertoneBidAdapter.js +9 -5
- package/modules/undertoneBidAdapter.md +5 -1
- package/modules/userId/eids.js +18 -0
- package/modules/userId/eids.md +7 -0
- package/modules/userId/userId.md +12 -0
- package/modules/ventesBidAdapter.js +370 -0
- package/modules/ventesBidAdapter.md +94 -0
- package/modules/videobyteBidAdapter.js +13 -6
- package/modules/videobyteBidAdapter.md +49 -0
- package/modules/vidoomyBidAdapter.js +51 -100
- package/modules/visxBidAdapter.js +1 -1
- package/modules/yahoosspBidAdapter.js +6 -6
- package/modules/yieldlabBidAdapter.js +41 -10
- package/modules/yieldlabBidAdapter.md +91 -48
- package/modules/yieldmoSyntheticInventoryModule.js +46 -0
- package/modules/yieldmoSyntheticInventoryModule.md +68 -0
- package/package.json +6 -1
- package/src/adapterManager.js +19 -8
- package/src/adapters/bidderFactory.js +4 -3
- package/src/auction.js +11 -11
- package/src/constants.json +1 -0
- package/src/secureCreatives.js +6 -7
- package/src/targeting.js +11 -9
- package/test/spec/modules/adfBidAdapter_spec.js +83 -29
- package/test/spec/modules/adheseBidAdapter_spec.js +27 -1
- package/test/spec/modules/adomikAnalyticsAdapter_spec.js +3 -1
- package/test/spec/modules/adtelligentBidAdapter_spec.js +1 -0
- package/test/spec/modules/akamaiDapRtdProvider_spec.js +246 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +16 -1
- package/test/spec/modules/atsAnalyticsAdapter_spec.js +42 -9
- package/test/spec/modules/betweenBidAdapter_spec.js +41 -0
- package/test/spec/modules/browsiRtdProvider_spec.js +62 -7
- package/test/spec/modules/cleanioRtdProvider_spec.js +188 -0
- package/test/spec/modules/codefuelBidAdapter_spec.js +316 -0
- package/test/spec/modules/connectIdSystem_spec.js +189 -0
- package/test/spec/modules/datablocksBidAdapter_spec.js +3 -3
- package/test/spec/modules/deepintentBidAdapter_spec.js +153 -3
- package/test/spec/modules/deltaprojectsBidAdapter_spec.js +399 -0
- package/test/spec/modules/engageyaBidAdapter_spec.js +422 -0
- package/test/spec/modules/eplanningBidAdapter_spec.js +8 -8
- package/test/spec/modules/glimpseBidAdapter_spec.js +33 -0
- package/test/spec/modules/gptPreAuction_spec.js +58 -4
- package/test/spec/modules/gumgumBidAdapter_spec.js +5 -1
- package/test/spec/modules/imRtdProvider_spec.js +25 -0
- package/test/spec/modules/ixBidAdapter_spec.js +298 -5
- package/test/spec/modules/jixieBidAdapter_spec.js +13 -11
- package/test/spec/modules/justpremiumBidAdapter_spec.js +9 -2
- package/test/spec/modules/konduitWrapper_spec.js +0 -1
- package/test/spec/modules/limelightDigitalBidAdapter_spec.js +155 -1
- package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +52 -7
- package/test/spec/modules/merkleIdSystem_spec.js +18 -0
- package/test/spec/modules/multibid_spec.js +31 -31
- package/test/spec/modules/nativoBidAdapter_spec.js +35 -18
- package/test/spec/modules/nextMillenniumBidAdapter_spec.js +13 -1
- package/test/spec/modules/oguryBidAdapter_spec.js +66 -23
- package/test/spec/modules/openxBidAdapter_spec.js +90 -13
- package/test/spec/modules/operaadsBidAdapter_spec.js +38 -6
- package/test/spec/modules/otmBidAdapter_spec.js +67 -0
- package/test/spec/modules/outbrainBidAdapter_spec.js +18 -0
- package/test/spec/modules/prebidServerBidAdapter_spec.js +19 -2
- package/test/spec/modules/publinkIdSystem_spec.js +6 -6
- package/test/spec/modules/seedtagBidAdapter_spec.js +3 -0
- package/test/spec/modules/smaatoBidAdapter_spec.js +30 -0
- package/test/spec/modules/sonobiBidAdapter_spec.js +34 -1
- package/test/spec/modules/sortableBidAdapter_spec.js +11 -0
- package/test/spec/modules/sspBCBidAdapter_spec.js +33 -3
- package/test/spec/modules/teadsBidAdapter_spec.js +132 -0
- package/test/spec/modules/tripleliftBidAdapter_spec.js +128 -0
- package/test/spec/modules/trustxBidAdapter_spec.js +45 -3
- package/test/spec/modules/undertoneBidAdapter_spec.js +52 -0
- package/test/spec/modules/ventesBidAdapter_spec.js +845 -0
- package/test/spec/modules/videobyteBidAdapter_spec.js +2 -2
- package/test/spec/modules/vidoomyBidAdapter_spec.js +32 -13
- package/test/spec/modules/visxBidAdapter_spec.js +1 -1
- package/test/spec/modules/yieldlabBidAdapter_spec.js +81 -0
- package/test/spec/modules/yieldmoSyntheticInventoryModule_spec.js +89 -0
- package/test/spec/unit/core/adapterManager_spec.js +56 -6
- package/test/spec/unit/core/bidderFactory_spec.js +61 -1
- package/test/spec/unit/pbjs_api_spec.js +37 -2
- package/test/spec/unit/secureCreatives_spec.js +54 -25
- package/wdio.conf.js +1 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
Module Name: clean.io Rtd provider
|
|
5
|
+
Module Type: Rtd Provider
|
|
6
|
+
Maintainer: nick@clean.io
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
The clean.io Realtime module provides effective anti-malvertising solution for publishers, including, but not limited to,
|
|
10
|
+
blocking unwanted 0- and 1-click redirects, deceptive ads or those with malicious landing pages, and various types of affiliate fraud.
|
|
11
|
+
|
|
12
|
+
Using this module requires prior agreement with [clean.io](https://clean.io) to obtain the necessary distribution key.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# Integration
|
|
16
|
+
|
|
17
|
+
clean.io Realtime module can be built just like any other prebid module:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
gulp build --modules=cleanioRtdProvider,...
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# Configuration
|
|
25
|
+
|
|
26
|
+
When built into prebid.js, this module can be configured through the following `pbjs.setConfig` call:
|
|
27
|
+
|
|
28
|
+
```javascript
|
|
29
|
+
pbjs.setConfig({
|
|
30
|
+
realTimeData: {
|
|
31
|
+
dataProviders: [{
|
|
32
|
+
name: 'clean.io',
|
|
33
|
+
params: {
|
|
34
|
+
cdnUrl: 'https://abc1234567890.cloudfront.net/script.js', ///< Contact clean.io to get your own CDN URL
|
|
35
|
+
protectionMode: 'full', ///< Supported modes are 'full', 'bids' and 'bids-nowait', see below.
|
|
36
|
+
}
|
|
37
|
+
}]
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
## Configuration parameters
|
|
44
|
+
|
|
45
|
+
{: .table .table-bordered .table-striped }
|
|
46
|
+
| Name | Type | Scope | Description |
|
|
47
|
+
| :------------ | :------------ | :------------ |:------------ |
|
|
48
|
+
| ``cdnUrl`` | ``string`` | Required | CDN URL of the script, which is to be used for protection. |
|
|
49
|
+
| ``protectionMode`` | ``'full' \| 'bids' \| 'bids-nowait'`` | Required | Integration mode. Please refer to the "Integration modes" section for details. |
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## Integration modes
|
|
53
|
+
|
|
54
|
+
{: .table .table-bordered .table-striped }
|
|
55
|
+
| Integration Mode | Parameter Value | Description |
|
|
56
|
+
| :------------ | :------------ | :------------ |
|
|
57
|
+
| Full page protection | ``'full'`` | Preferred mode. The module will add the protector agent script directly to the page, and it will protect all placements. This mode will make the most out of various behavioral detection mechanisms, and will also prevent typical malicious behaviors. Please note that in this mode, depending on Prebid library naming, Chrome may mistakenly tag non-ad-related content as ads: https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/ad_tagging.md. |
|
|
58
|
+
| Bids-only protection | ``'bids'`` | The module will protect specific bid responses, more specifically, the HTML representing ad payload, by wrapping it into the agent script. Please note that in this mode, ads delivered directly, outside of Prebid integration, will not be protected, since the module can only access the ads coming through Prebid. |
|
|
59
|
+
| Bids-only protection with no delay on bid rendering | ``'bids-nowait'`` | Same as above, but in this mode, the script will also *not* wrap those bid responses, which arrived prior to successful preloading of agent script. |
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { deepAccess, isArray } from '../src/utils.js';
|
|
2
|
+
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
3
|
+
import { BANNER } from '../src/mediaTypes.js';
|
|
4
|
+
const BIDDER_CODE = 'codefuel';
|
|
5
|
+
const CURRENCY = 'USD';
|
|
6
|
+
|
|
7
|
+
export const spec = {
|
|
8
|
+
code: BIDDER_CODE,
|
|
9
|
+
supportedMediaTypes: [ BANNER ],
|
|
10
|
+
aliases: ['ex'], // short code
|
|
11
|
+
/**
|
|
12
|
+
* Determines whether or not the given bid request is valid.
|
|
13
|
+
*
|
|
14
|
+
* @param {BidRequest} bid The bid params to validate.
|
|
15
|
+
* @return boolean True if this is a valid bid, and false otherwise.
|
|
16
|
+
*/
|
|
17
|
+
isBidRequestValid: function(bid) {
|
|
18
|
+
if (bid.nativeParams) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return !!(bid.params.placementId || (bid.params.member && bid.params.invCode));
|
|
22
|
+
},
|
|
23
|
+
/**
|
|
24
|
+
* Make a server request from the list of BidRequests.
|
|
25
|
+
*
|
|
26
|
+
* @param {validBidRequests[]} - an array of bids
|
|
27
|
+
* @return ServerRequest Info describing the request to the server.
|
|
28
|
+
*/
|
|
29
|
+
buildRequests: function(validBidRequests, bidderRequest) {
|
|
30
|
+
const page = bidderRequest.refererInfo.referer;
|
|
31
|
+
const domain = getDomainFromURL(page)
|
|
32
|
+
const ua = navigator.userAgent;
|
|
33
|
+
const devicetype = getDeviceType()
|
|
34
|
+
const publisher = setOnAny(validBidRequests, 'params.publisher');
|
|
35
|
+
const cur = CURRENCY;
|
|
36
|
+
const endpointUrl = 'https://ai-p-codefuel-ds-rtb-us-east-1-k8s.seccint.com/prebid'
|
|
37
|
+
const timeout = bidderRequest.timeout;
|
|
38
|
+
|
|
39
|
+
validBidRequests.forEach(bid => bid.netRevenue = 'net');
|
|
40
|
+
|
|
41
|
+
const imps = validBidRequests.map((bid, idx) => {
|
|
42
|
+
const imp = {
|
|
43
|
+
id: idx + 1 + ''
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (bid.params.tagid) {
|
|
47
|
+
imp.tagid = bid.params.tagid
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (bid.sizes) {
|
|
51
|
+
imp.banner = {
|
|
52
|
+
format: transformSizes(bid.sizes)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return imp;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const request = {
|
|
60
|
+
id: bidderRequest.auctionId,
|
|
61
|
+
site: { page, domain, publisher },
|
|
62
|
+
device: { ua, devicetype },
|
|
63
|
+
source: { fd: 1 },
|
|
64
|
+
cur: [cur],
|
|
65
|
+
tmax: timeout,
|
|
66
|
+
imp: imps,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
url: endpointUrl,
|
|
72
|
+
data: request,
|
|
73
|
+
bids: validBidRequests,
|
|
74
|
+
options: {
|
|
75
|
+
withCredentials: false
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
},
|
|
79
|
+
/**
|
|
80
|
+
* Unpack the response from the server into a list of bids.
|
|
81
|
+
*
|
|
82
|
+
* @param {ServerResponse} serverResponse A successful response from the server.
|
|
83
|
+
* @return {Bid[]} An array of bids which were nested inside the server.
|
|
84
|
+
*/
|
|
85
|
+
interpretResponse: (serverResponse, { bids }) => {
|
|
86
|
+
if (!serverResponse.body) {
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
89
|
+
const { seatbid, cur } = serverResponse.body;
|
|
90
|
+
|
|
91
|
+
const bidResponses = flatten(seatbid.map(seat => seat.bid)).reduce((result, bid) => {
|
|
92
|
+
result[bid.impid - 1] = bid;
|
|
93
|
+
return result;
|
|
94
|
+
}, []);
|
|
95
|
+
|
|
96
|
+
return bids.map((bid, id) => {
|
|
97
|
+
const bidResponse = bidResponses[id];
|
|
98
|
+
if (bidResponse) {
|
|
99
|
+
const bidObject = {
|
|
100
|
+
requestId: bid.bidId,
|
|
101
|
+
cpm: bidResponse.price,
|
|
102
|
+
creativeId: bidResponse.crid,
|
|
103
|
+
ttl: 360,
|
|
104
|
+
netRevenue: true,
|
|
105
|
+
currency: cur,
|
|
106
|
+
mediaType: BANNER,
|
|
107
|
+
ad: bidResponse.adm,
|
|
108
|
+
width: bidResponse.w,
|
|
109
|
+
height: bidResponse.h,
|
|
110
|
+
meta: { advertiserDomains: bid.adomain ? bid.adomain : [] }
|
|
111
|
+
};
|
|
112
|
+
return bidObject;
|
|
113
|
+
}
|
|
114
|
+
}).filter(Boolean);
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Register the user sync pixels which should be dropped after the auction.
|
|
119
|
+
*
|
|
120
|
+
* @param {SyncOptions} syncOptions Which user syncs are allowed?
|
|
121
|
+
* @param {ServerResponse[]} serverResponses List of server's responses.
|
|
122
|
+
* @return {UserSync[]} The user syncs which should be dropped.
|
|
123
|
+
*/
|
|
124
|
+
getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) {
|
|
125
|
+
return [];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
}
|
|
129
|
+
registerBidder(spec);
|
|
130
|
+
|
|
131
|
+
function getDomainFromURL(url) {
|
|
132
|
+
let anchor = document.createElement('a');
|
|
133
|
+
anchor.href = url;
|
|
134
|
+
return anchor.hostname;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function getDeviceType() {
|
|
138
|
+
if ((/ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i.test(navigator.userAgent.toLowerCase()))) {
|
|
139
|
+
return 5; // 'tablet'
|
|
140
|
+
}
|
|
141
|
+
if ((/iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i.test(navigator.userAgent.toLowerCase()))) {
|
|
142
|
+
return 4; // 'mobile'
|
|
143
|
+
}
|
|
144
|
+
return 2; // 'desktop'
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function setOnAny(collection, key) {
|
|
148
|
+
for (let i = 0, result; i < collection.length; i++) {
|
|
149
|
+
result = deepAccess(collection[i], key);
|
|
150
|
+
if (result) {
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function flatten(arr) {
|
|
157
|
+
return [].concat(...arr);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/* Turn bid request sizes into ut-compatible format */
|
|
161
|
+
function transformSizes(requestSizes) {
|
|
162
|
+
if (!isArray(requestSizes)) {
|
|
163
|
+
return [];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (requestSizes.length === 2 && !isArray(requestSizes[0])) {
|
|
167
|
+
return [{
|
|
168
|
+
w: parseInt(requestSizes[0], 10),
|
|
169
|
+
h: parseInt(requestSizes[1], 10)
|
|
170
|
+
}];
|
|
171
|
+
} else if (isArray(requestSizes[0])) {
|
|
172
|
+
return requestSizes.map(item =>
|
|
173
|
+
({
|
|
174
|
+
w: parseInt(item[0], 10),
|
|
175
|
+
h: parseInt(item[1], 10)
|
|
176
|
+
})
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return [];
|
|
181
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
Module Name: Codefuel Adapter
|
|
5
|
+
Module Type: Bidder Adapter
|
|
6
|
+
Maintainer: hayimm@codefuel.com
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
# Description
|
|
10
|
+
|
|
11
|
+
Module that connects to Codefuel bidder to fetch bids.
|
|
12
|
+
Display format is supported but not native format. Using OpenRTB standard.
|
|
13
|
+
|
|
14
|
+
# Configuration
|
|
15
|
+
|
|
16
|
+
## Bidder and usersync URLs
|
|
17
|
+
|
|
18
|
+
The Codefuel adapter does not work without setting the correct bidder.
|
|
19
|
+
You will receive the URLs when contacting us.
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
pbjs.setConfig({
|
|
23
|
+
codefuel: {
|
|
24
|
+
bidderUrl: 'https://ai-p-codefuel-ds-rtb-us-east-1-k8s.seccint.com/prebid',
|
|
25
|
+
usersyncUrl: 'https://usersync-url.com'
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# Test Native Parameters
|
|
32
|
+
```
|
|
33
|
+
var adUnits = [
|
|
34
|
+
code: '/19968336/prebid_native_example_1',
|
|
35
|
+
mediaTypes: {
|
|
36
|
+
native: {
|
|
37
|
+
image: {
|
|
38
|
+
required: false,
|
|
39
|
+
sizes: [100, 50]
|
|
40
|
+
},
|
|
41
|
+
title: {
|
|
42
|
+
required: false,
|
|
43
|
+
len: 140
|
|
44
|
+
},
|
|
45
|
+
sponsoredBy: {
|
|
46
|
+
required: false
|
|
47
|
+
},
|
|
48
|
+
clickUrl: {
|
|
49
|
+
required: false
|
|
50
|
+
},
|
|
51
|
+
body: {
|
|
52
|
+
required: false
|
|
53
|
+
},
|
|
54
|
+
icon: {
|
|
55
|
+
required: false,
|
|
56
|
+
sizes: [50, 50]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
bids: [{
|
|
61
|
+
bidder: 'codefuel',
|
|
62
|
+
params: {
|
|
63
|
+
publisher: {
|
|
64
|
+
id: '2706', // required
|
|
65
|
+
name: 'Publishers Name',
|
|
66
|
+
domain: 'publisher.com'
|
|
67
|
+
},
|
|
68
|
+
tagid: 'tag-id',
|
|
69
|
+
bcat: ['IAB1-1'],
|
|
70
|
+
badv: ['example.com']
|
|
71
|
+
}
|
|
72
|
+
}]
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
pbjs.setConfig({
|
|
76
|
+
codefuel: {
|
|
77
|
+
bidderUrl: 'https://ai-p-codefuel-ds-rtb-us-east-1-k8s.seccint.com/prebid'
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
# Test Display Parameters
|
|
83
|
+
```
|
|
84
|
+
var adUnits = [
|
|
85
|
+
code: '/19968336/prebid_display_example_1',
|
|
86
|
+
mediaTypes: {
|
|
87
|
+
banner: {
|
|
88
|
+
sizes: [[300, 250]]
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
bids: [{
|
|
92
|
+
bidder: 'codefuel',
|
|
93
|
+
params: {
|
|
94
|
+
publisher: {
|
|
95
|
+
id: '2706', // required
|
|
96
|
+
name: 'Publishers Name',
|
|
97
|
+
domain: 'publisher.com'
|
|
98
|
+
},
|
|
99
|
+
tagid: 'tag-id',
|
|
100
|
+
bcat: ['IAB1-1'],
|
|
101
|
+
badv: ['example.com']
|
|
102
|
+
},
|
|
103
|
+
}]
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
pbjs.setConfig({
|
|
107
|
+
codefuel: {
|
|
108
|
+
bidderUrl: 'https://ai-p-codefuel-ds-rtb-us-east-1-k8s.seccint.com/prebid'
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
```
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This module adds support for Yahoo ConnectID to the user ID module system.
|
|
3
|
+
* The {@link module:modules/userId} module is required
|
|
4
|
+
* @module modules/connectIdSystem
|
|
5
|
+
* @requires module:modules/userId
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {ajax} from '../src/ajax.js';
|
|
9
|
+
import {submodule} from '../src/hook.js';
|
|
10
|
+
import {logError, formatQS} from '../src/utils.js';
|
|
11
|
+
import includes from 'core-js-pure/features/array/includes.js';
|
|
12
|
+
|
|
13
|
+
const MODULE_NAME = 'connectId';
|
|
14
|
+
const VENDOR_ID = 25;
|
|
15
|
+
const PLACEHOLDER = '__PIXEL_ID__';
|
|
16
|
+
const UPS_ENDPOINT = `https://ups.analytics.yahoo.com/ups/${PLACEHOLDER}/fed`;
|
|
17
|
+
|
|
18
|
+
function isEUConsentRequired(consentData) {
|
|
19
|
+
return !!(consentData && consentData.gdpr && consentData.gdpr.gdprApplies);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** @type {Submodule} */
|
|
23
|
+
export const connectIdSubmodule = {
|
|
24
|
+
/**
|
|
25
|
+
* used to link submodule with config
|
|
26
|
+
* @type {string}
|
|
27
|
+
*/
|
|
28
|
+
name: MODULE_NAME,
|
|
29
|
+
/**
|
|
30
|
+
* @type {Number}
|
|
31
|
+
*/
|
|
32
|
+
gvlid: VENDOR_ID,
|
|
33
|
+
/**
|
|
34
|
+
* decode the stored id value for passing to bid requests
|
|
35
|
+
* @function
|
|
36
|
+
* @returns {{connectId: string} | undefined}
|
|
37
|
+
*/
|
|
38
|
+
decode(value) {
|
|
39
|
+
return (typeof value === 'object' && value.connectid)
|
|
40
|
+
? {connectId: value.connectid} : undefined;
|
|
41
|
+
},
|
|
42
|
+
/**
|
|
43
|
+
* Gets the Yahoo ConnectID
|
|
44
|
+
* @function
|
|
45
|
+
* @param {SubmoduleConfig} [config]
|
|
46
|
+
* @param {ConsentData} [consentData]
|
|
47
|
+
* @returns {IdResponse|undefined}
|
|
48
|
+
*/
|
|
49
|
+
getId(config, consentData) {
|
|
50
|
+
const params = config.params || {};
|
|
51
|
+
if (!params || typeof params.he !== 'string' ||
|
|
52
|
+
(typeof params.pixelId === 'undefined' && typeof params.endpoint === 'undefined')) {
|
|
53
|
+
logError('The connectId submodule requires the \'he\' and \'pixelId\' parameters to be defined.');
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const data = {
|
|
58
|
+
'1p': includes([1, '1', true], params['1p']) ? '1' : '0',
|
|
59
|
+
he: params.he,
|
|
60
|
+
gdpr: isEUConsentRequired(consentData) ? '1' : '0',
|
|
61
|
+
gdpr_consent: isEUConsentRequired(consentData) ? consentData.gdpr.consentString : '',
|
|
62
|
+
us_privacy: consentData && consentData.uspConsent ? consentData.uspConsent : ''
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
if (params.pixelId) {
|
|
66
|
+
data.pixelId = params.pixelId
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const resp = function (callback) {
|
|
70
|
+
const callbacks = {
|
|
71
|
+
success: response => {
|
|
72
|
+
let responseObj;
|
|
73
|
+
if (response) {
|
|
74
|
+
try {
|
|
75
|
+
responseObj = JSON.parse(response);
|
|
76
|
+
} catch (error) {
|
|
77
|
+
logError(error);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
callback(responseObj);
|
|
81
|
+
},
|
|
82
|
+
error: error => {
|
|
83
|
+
logError(`${MODULE_NAME}: ID fetch encountered an error`, error);
|
|
84
|
+
callback();
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const endpoint = UPS_ENDPOINT.replace(PLACEHOLDER, params.pixelId);
|
|
88
|
+
let url = `${params.endpoint || endpoint}?${formatQS(data)}`;
|
|
89
|
+
connectIdSubmodule.getAjaxFn()(url, callbacks, null, {method: 'GET', withCredentials: true});
|
|
90
|
+
};
|
|
91
|
+
return {callback: resp};
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Return the function used to perform XHR calls.
|
|
96
|
+
* Utilised for each of testing.
|
|
97
|
+
* @returns {Function}
|
|
98
|
+
*/
|
|
99
|
+
getAjaxFn() {
|
|
100
|
+
return ajax;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
submodule('userId', connectIdSubmodule);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
## Yahoo ConnectID User ID Submodule
|
|
2
|
+
|
|
3
|
+
Yahoo ConnectID user ID Module.
|
|
4
|
+
|
|
5
|
+
### Prebid Params
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
pbjs.setConfig({
|
|
9
|
+
userSync: {
|
|
10
|
+
userIds: [{
|
|
11
|
+
name: 'connectId',
|
|
12
|
+
storage: {
|
|
13
|
+
name: 'connectId',
|
|
14
|
+
type: 'html5',
|
|
15
|
+
expires: 15
|
|
16
|
+
},
|
|
17
|
+
params: {
|
|
18
|
+
pixelId: 58776,
|
|
19
|
+
he: '0bef996248d63cea1529cb86de31e9547a712d9f380146e98bbd39beec70355a'
|
|
20
|
+
}
|
|
21
|
+
}]
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
## Parameter Descriptions for the `usersync` Configuration Section
|
|
26
|
+
The below parameters apply only to the Yahoo ConnectID user ID Module.
|
|
27
|
+
|
|
28
|
+
| Param under usersync.userIds[] | Scope | Type | Description | Example |
|
|
29
|
+
| --- | --- | --- | --- | --- |
|
|
30
|
+
| name | Required | String | ID value for the Yahoo ConnectID module - `"connectId"` | `"connectId"` |
|
|
31
|
+
| params | Required | Object | Data for Yahoo ConnectID initialization. | |
|
|
32
|
+
| params.pixelId | Required | Number | The Yahoo supplied publisher specific pixel Id | `8976` |
|
|
33
|
+
| params.he | Required | String | The SHA-256 hashed user email address | `"529cb86de31e9547a712d9f380146e98bbd39beec"` |
|
|
@@ -94,7 +94,7 @@ export const spec = {
|
|
|
94
94
|
code: 'datablocks',
|
|
95
95
|
|
|
96
96
|
// DATABLOCKS SCOPED OBJECT
|
|
97
|
-
db_obj: {metrics_host: 'prebid.
|
|
97
|
+
db_obj: {metrics_host: 'prebid.dblks.net', metrics: [], metrics_timer: null, metrics_queue_time: 1000, vis_optout: false, source_id: 0},
|
|
98
98
|
|
|
99
99
|
// STORE THE DATABLOCKS BUYERID IN STORAGE
|
|
100
100
|
store_dbid: function(dbid) {
|
|
@@ -388,12 +388,12 @@ export const spec = {
|
|
|
388
388
|
};
|
|
389
389
|
|
|
390
390
|
let sourceId = validRequests[0].params.source_id || 0;
|
|
391
|
-
let host = validRequests[0].params.host || 'prebid.
|
|
391
|
+
let host = validRequests[0].params.host || 'prebid.dblks.net';
|
|
392
392
|
|
|
393
393
|
// RETURN WITH THE REQUEST AND PAYLOAD
|
|
394
394
|
return {
|
|
395
395
|
method: 'POST',
|
|
396
|
-
url: `https://${
|
|
396
|
+
url: `https://${host}/openrtb/?sid=${sourceId}`,
|
|
397
397
|
data: {
|
|
398
398
|
id: bidderRequest.auctionId,
|
|
399
399
|
imp: imps,
|
|
@@ -1,13 +1,38 @@
|
|
|
1
|
-
import { generateUUID, deepSetValue, deepAccess, isArray } from '../src/utils.js';
|
|
1
|
+
import { generateUUID, deepSetValue, deepAccess, isArray, isInteger, logError, logWarn } from '../src/utils.js';
|
|
2
2
|
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
3
|
-
import {BANNER} from '../src/mediaTypes.js';
|
|
3
|
+
import {BANNER, VIDEO} from '../src/mediaTypes.js';
|
|
4
4
|
const BIDDER_CODE = 'deepintent';
|
|
5
5
|
const BIDDER_ENDPOINT = 'https://prebid.deepintent.com/prebid';
|
|
6
6
|
const USER_SYNC_URL = 'https://cdn.deepintent.com/syncpixel.html';
|
|
7
7
|
const DI_M_V = '1.0.0';
|
|
8
|
+
export const ORTB_VIDEO_PARAMS = {
|
|
9
|
+
'mimes': (value) => Array.isArray(value) && value.length > 0 && value.every(v => typeof v === 'string'),
|
|
10
|
+
'minduration': (value) => isInteger(value),
|
|
11
|
+
'maxduration': (value) => isInteger(value),
|
|
12
|
+
'protocols': (value) => Array.isArray(value) && value.every(v => v >= 1 && v <= 10),
|
|
13
|
+
'w': (value) => isInteger(value),
|
|
14
|
+
'h': (value) => isInteger(value),
|
|
15
|
+
'startdelay': (value) => isInteger(value),
|
|
16
|
+
'placement': (value) => Array.isArray(value) && value.every(v => v >= 1 && v <= 5),
|
|
17
|
+
'linearity': (value) => [1, 2].indexOf(value) !== -1,
|
|
18
|
+
'skip': (value) => [0, 1].indexOf(value) !== -1,
|
|
19
|
+
'skipmin': (value) => isInteger(value),
|
|
20
|
+
'skipafter': (value) => isInteger(value),
|
|
21
|
+
'sequence': (value) => isInteger(value),
|
|
22
|
+
'battr': (value) => Array.isArray(value) && value.every(v => v >= 1 && v <= 17),
|
|
23
|
+
'maxextended': (value) => isInteger(value),
|
|
24
|
+
'minbitrate': (value) => isInteger(value),
|
|
25
|
+
'maxbitrate': (value) => isInteger(value),
|
|
26
|
+
'boxingallowed': (value) => [0, 1].indexOf(value) !== -1,
|
|
27
|
+
'playbackmethod': (value) => Array.isArray(value) && value.every(v => v >= 1 && v <= 6),
|
|
28
|
+
'playbackend': (value) => [1, 2, 3].indexOf(value) !== -1,
|
|
29
|
+
'delivery': (value) => [1, 2, 3].indexOf(value) !== -1,
|
|
30
|
+
'pos': (value) => [0, 1, 2, 3, 4, 5, 6, 7].indexOf(value) !== -1,
|
|
31
|
+
'api': (value) => Array.isArray(value) && value.every(v => v >= 1 && v <= 6)
|
|
32
|
+
};
|
|
8
33
|
export const spec = {
|
|
9
34
|
code: BIDDER_CODE,
|
|
10
|
-
supportedMediaTypes: [BANNER],
|
|
35
|
+
supportedMediaTypes: [BANNER, VIDEO],
|
|
11
36
|
aliases: [],
|
|
12
37
|
|
|
13
38
|
// tagId is mandatory param
|
|
@@ -15,16 +40,38 @@ export const spec = {
|
|
|
15
40
|
let valid = false;
|
|
16
41
|
if (bid && bid.params && bid.params.tagId) {
|
|
17
42
|
if (typeof bid.params.tagId === 'string' || bid.params.tagId instanceof String) {
|
|
18
|
-
|
|
43
|
+
if (bid.hasOwnProperty('mediaTypes') && bid.mediaTypes.hasOwnProperty(VIDEO)) {
|
|
44
|
+
if (bid.mediaTypes[VIDEO].hasOwnProperty('context')) {
|
|
45
|
+
valid = true;
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
valid = true;
|
|
49
|
+
}
|
|
19
50
|
}
|
|
20
51
|
}
|
|
21
52
|
return valid;
|
|
22
53
|
},
|
|
23
|
-
interpretResponse: function(bidResponse,
|
|
54
|
+
interpretResponse: function(bidResponse, bidRequest) {
|
|
24
55
|
let responses = [];
|
|
25
56
|
if (bidResponse && bidResponse.body) {
|
|
26
|
-
|
|
27
|
-
|
|
57
|
+
try {
|
|
58
|
+
let bids = bidResponse.body.seatbid && bidResponse.body.seatbid[0] ? bidResponse.body.seatbid[0].bid : [];
|
|
59
|
+
if (bids) {
|
|
60
|
+
bids.forEach(bidObj => {
|
|
61
|
+
let newBid = formatResponse(bidObj);
|
|
62
|
+
let mediaType = _checkMediaType(bidObj);
|
|
63
|
+
if (mediaType === BANNER) {
|
|
64
|
+
newBid.mediaType = BANNER;
|
|
65
|
+
} else if (mediaType === VIDEO) {
|
|
66
|
+
newBid.mediaType = VIDEO;
|
|
67
|
+
newBid.vastXml = bidObj.adm;
|
|
68
|
+
}
|
|
69
|
+
responses.push(newBid);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
} catch (err) {
|
|
73
|
+
logError(err);
|
|
74
|
+
}
|
|
28
75
|
}
|
|
29
76
|
return responses;
|
|
30
77
|
},
|
|
@@ -73,6 +120,17 @@ export const spec = {
|
|
|
73
120
|
}
|
|
74
121
|
|
|
75
122
|
};
|
|
123
|
+
function _checkMediaType(bid) {
|
|
124
|
+
let videoRegex = new RegExp(/VAST\s+version/);
|
|
125
|
+
let mediaType;
|
|
126
|
+
if (bid.adm && bid.adm.indexOf('deepintent_wrapper') >= 0) {
|
|
127
|
+
mediaType = BANNER;
|
|
128
|
+
} else if (videoRegex.test(bid.adm)) {
|
|
129
|
+
mediaType = VIDEO;
|
|
130
|
+
}
|
|
131
|
+
return mediaType;
|
|
132
|
+
}
|
|
133
|
+
|
|
76
134
|
function clean(obj) {
|
|
77
135
|
for (let propName in obj) {
|
|
78
136
|
if (obj[propName] === null || obj[propName] === undefined) {
|
|
@@ -100,16 +158,55 @@ function formatResponse(bid) {
|
|
|
100
158
|
}
|
|
101
159
|
|
|
102
160
|
function buildImpression(bid) {
|
|
103
|
-
|
|
161
|
+
let impression = {};
|
|
162
|
+
impression = {
|
|
104
163
|
id: bid.bidId,
|
|
105
164
|
tagid: bid.params.tagId || '',
|
|
106
|
-
secure: window.location.protocol === 'https' ? 1 : 0,
|
|
107
|
-
banner: buildBanner(bid),
|
|
165
|
+
secure: window.location.protocol === 'https:' ? 1 : 0,
|
|
108
166
|
displaymanager: 'di_prebid',
|
|
109
167
|
displaymanagerver: DI_M_V,
|
|
110
168
|
ext: buildCustomParams(bid)
|
|
111
169
|
};
|
|
170
|
+
if (deepAccess(bid, 'mediaTypes.banner')) {
|
|
171
|
+
impression['banner'] = buildBanner(bid);
|
|
172
|
+
}
|
|
173
|
+
if (deepAccess(bid, 'mediaTypes.video')) {
|
|
174
|
+
impression['video'] = _buildVideo(bid);
|
|
175
|
+
}
|
|
176
|
+
return impression;
|
|
112
177
|
}
|
|
178
|
+
|
|
179
|
+
function _buildVideo(bid) {
|
|
180
|
+
const videoObj = {};
|
|
181
|
+
const videoAdUnitParams = deepAccess(bid, 'mediaTypes.video', {});
|
|
182
|
+
const videoBidderParams = deepAccess(bid, 'params.video', {});
|
|
183
|
+
const computedParams = {};
|
|
184
|
+
|
|
185
|
+
if (Array.isArray(videoAdUnitParams.playerSize)) {
|
|
186
|
+
const tempSize = (Array.isArray(videoAdUnitParams.playerSize[0])) ? videoAdUnitParams.playerSize[0] : videoAdUnitParams.playerSize;
|
|
187
|
+
computedParams.w = tempSize[0];
|
|
188
|
+
computedParams.h = tempSize[1];
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const videoParams = {
|
|
192
|
+
...computedParams,
|
|
193
|
+
...videoAdUnitParams,
|
|
194
|
+
...videoBidderParams
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
Object.keys(ORTB_VIDEO_PARAMS).forEach(paramName => {
|
|
198
|
+
if (videoParams.hasOwnProperty(paramName)) {
|
|
199
|
+
if (ORTB_VIDEO_PARAMS[paramName](videoParams[paramName])) {
|
|
200
|
+
videoObj[paramName] = videoParams[paramName];
|
|
201
|
+
} else {
|
|
202
|
+
logWarn(`The OpenRTB video param ${paramName} has been skipped due to misformating. Please refer to OpenRTB 2.5 spec.`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
return videoObj;
|
|
208
|
+
};
|
|
209
|
+
|
|
113
210
|
function buildCustomParams(bid) {
|
|
114
211
|
if (bid.params && bid.params.custom) {
|
|
115
212
|
return {
|