prebid.js 7.47.0 → 7.48.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/dist/33acrossBidAdapter.js +1 -1
- package/dist/33acrossIdSystem.js +1 -1
- package/dist/ablidaBidAdapter.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/admaticBidAdapter.js +1 -1
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adrinoBidAdapter.js +1 -1
- package/dist/adtrgtmeBidAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/adyoulikeBidAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/carodaBidAdapter.js +1 -1
- package/dist/chtnwBidAdapter.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectIdSystem.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantAnalyticsAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/cwireBidAdapter.js +1 -1
- package/dist/dependencies.json +4 -0
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/feedadBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/freewheel-sspBidAdapter.js +1 -1
- package/dist/glimpseBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/greenbidsAnalyticsAdapter.js +1 -1
- package/dist/greenbidsRtdProvider.js +1 -0
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/impactifyBidAdapter.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/inmarBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/iqmBidAdapter.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/kargoBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/kueezRtbBidAdapter.js +1 -1
- package/dist/kulturemediaBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/lifestreetBidAdapter.js +1 -1
- package/dist/liveyieldAnalyticsAdapter.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/magniteAnalyticsAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/minutemediaplusBidAdapter.js +1 -1
- package/dist/nexx360BidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +137 -135
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/optidigitalBidAdapter.js +1 -1
- package/dist/orbitsoftBidAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/radsBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/relevantdigitalBidAdapter.js +1 -0
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseBidAdapter.js +1 -1
- package/dist/rtbhouseBidAdapter.js +1 -1
- package/dist/rubiconAnalyticsAdapter.js +1 -1
- package/dist/rubiconBidAdapter.js +1 -1
- package/dist/seedingAllianceBidAdapter.js +1 -1
- package/dist/seedtagBidAdapter.js +1 -1
- package/dist/sharethroughAnalyticsAdapter.js +1 -1
- package/dist/sharethroughBidAdapter.js +1 -1
- package/dist/shinezBidAdapter.js +1 -1
- package/dist/smaatoBidAdapter.js +1 -1
- package/dist/smartadserverBidAdapter.js +1 -1
- package/dist/smartxBidAdapter.js +1 -1
- package/dist/smilewantedBidAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnAnalyticsAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/stvBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/synacormediaBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/trionBidAdapter.js +1 -1
- package/dist/tripleliftBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.js +1 -1
- package/dist/uid2IdSystem.js +1 -1
- package/dist/underdogmediaBidAdapter.js +1 -1
- package/dist/undertoneBidAdapter.js +1 -1
- package/dist/userId.js +1 -1
- package/dist/vdoaiBidAdapter.js +1 -1
- package/dist/vidazooBidAdapter.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/visxBidAdapter.js +1 -1
- package/dist/vuukleBidAdapter.js +1 -1
- package/dist/widespaceBidAdapter.js +1 -1
- package/dist/winrBidAdapter.js +1 -1
- package/dist/wipesBidAdapter.js +1 -1
- package/dist/yahoosspBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/dist/yieldoneBidAdapter.js +1 -1
- package/modules/ablidaBidAdapter.js +4 -5
- package/modules/admaticBidAdapter.js +32 -5
- package/modules/adrinoBidAdapter.js +11 -4
- package/modules/axonixBidAdapter.js +6 -6
- package/modules/connectIdSystem.js +5 -2
- package/modules/criteoBidAdapter.js +3 -5
- package/modules/dspxBidAdapter.js +2 -3
- package/modules/freewheel-sspBidAdapter.js +32 -7
- package/modules/greenbidsRtdProvider.js +110 -0
- package/modules/greenbidsRtdProvider.md +65 -0
- package/modules/impactifyBidAdapter.js +0 -1
- package/modules/iqmBidAdapter.js +1 -2
- package/modules/orbitsoftBidAdapter.js +1 -2
- package/modules/radsBidAdapter.js +3 -4
- package/modules/relevantdigitalBidAdapter.js +198 -0
- package/modules/relevantdigitalBidAdapter.md +117 -0
- package/modules/rtbhouseBidAdapter.js +6 -9
- package/modules/sovrnBidAdapter.js +4 -0
- package/modules/stvBidAdapter.js +4 -5
- package/modules/tripleliftBidAdapter.js +14 -3
- package/modules/ttdBidAdapter.js +73 -71
- package/modules/underdogmediaBidAdapter.js +9 -12
- package/modules/userId/index.js +1 -1
- package/modules/vdoaiBidAdapter.js +2 -3
- package/modules/wipesBidAdapter.js +2 -3
- package/modules/yieldoneBidAdapter.js +3 -4
- package/package.json +1 -1
- package/test/spec/modules/adlooxAdServerVideo_spec.js +18 -35
- package/test/spec/modules/admaticBidAdapter_spec.js +164 -11
- package/test/spec/modules/adrinoBidAdapter_spec.js +50 -2
- package/test/spec/modules/connectIdSystem_spec.js +4 -4
- package/test/spec/modules/criteoBidAdapter_spec.js +56 -0
- package/test/spec/modules/freewheel-sspBidAdapter_spec.js +31 -2
- package/test/spec/modules/greenbidsRtdProvider_spec.js +210 -0
- package/test/spec/modules/relevantdigitalBidAdapter_spec.js +295 -0
- package/test/spec/modules/rtbhouseBidAdapter_spec.js +22 -0
- package/test/spec/modules/sovrnBidAdapter_spec.js +65 -0
- package/test/spec/modules/tripleliftBidAdapter_spec.js +53 -8
- package/test/spec/modules/ttdBidAdapter_spec.js +20 -0
- package/test/spec/ortbConverter/userId_spec.js +12 -0
- package/test/spec/modules/realvuAnalyticsAdapter_spec.js +0 -189
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { logError } from '../src/utils.js';
|
|
2
|
+
import { ajax } from '../src/ajax.js';
|
|
3
|
+
import { submodule } from '../src/hook.js';
|
|
4
|
+
|
|
5
|
+
const MODULE_NAME = 'greenbidsRtdProvider';
|
|
6
|
+
const MODULE_VERSION = '1.0.0';
|
|
7
|
+
const ENDPOINT = 'https://europe-west1-greenbids-357713.cloudfunctions.net/partner-selection';
|
|
8
|
+
|
|
9
|
+
const auctionInfo = {};
|
|
10
|
+
const rtdOptions = {};
|
|
11
|
+
|
|
12
|
+
function init(moduleConfig) {
|
|
13
|
+
let params = moduleConfig?.params;
|
|
14
|
+
if (!params?.pbuid) {
|
|
15
|
+
logError('Greenbids pbuid is not set!');
|
|
16
|
+
return false;
|
|
17
|
+
} else {
|
|
18
|
+
rtdOptions.pbuid = params?.pbuid;
|
|
19
|
+
rtdOptions.targetTPR = params?.targetTPR || 0.99;
|
|
20
|
+
rtdOptions.timeout = params?.timeout || 200;
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function onAuctionInitEvent(auctionDetails) {
|
|
26
|
+
auctionInfo.auctionId = auctionDetails.auctionId;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function getBidRequestData(reqBidsConfigObj, callback, config, userConsent) {
|
|
30
|
+
let promise = createPromise(reqBidsConfigObj);
|
|
31
|
+
promise.then(callback);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function createPromise(reqBidsConfigObj) {
|
|
35
|
+
return new Promise((resolve) => {
|
|
36
|
+
const timeoutId = setTimeout(() => {
|
|
37
|
+
resolve(reqBidsConfigObj);
|
|
38
|
+
}, rtdOptions.timeout);
|
|
39
|
+
ajax(
|
|
40
|
+
ENDPOINT,
|
|
41
|
+
{
|
|
42
|
+
success: (response) => {
|
|
43
|
+
processSuccessResponse(response, timeoutId, reqBidsConfigObj);
|
|
44
|
+
resolve(reqBidsConfigObj);
|
|
45
|
+
},
|
|
46
|
+
error: () => {
|
|
47
|
+
clearTimeout(timeoutId);
|
|
48
|
+
resolve(reqBidsConfigObj);
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
createPayload(reqBidsConfigObj),
|
|
52
|
+
{ contentType: 'application/json' }
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function processSuccessResponse(response, timeoutId, reqBidsConfigObj) {
|
|
58
|
+
clearTimeout(timeoutId);
|
|
59
|
+
const responseAdUnits = JSON.parse(response);
|
|
60
|
+
|
|
61
|
+
updateAdUnitsBasedOnResponse(reqBidsConfigObj.adUnits, responseAdUnits);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function updateAdUnitsBasedOnResponse(adUnits, responseAdUnits) {
|
|
65
|
+
adUnits.forEach((adUnit) => {
|
|
66
|
+
const matchingAdUnit = findMatchingAdUnit(responseAdUnits, adUnit.code);
|
|
67
|
+
if (matchingAdUnit) {
|
|
68
|
+
removeFalseBidders(adUnit, matchingAdUnit);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function findMatchingAdUnit(responseAdUnits, adUnitCode) {
|
|
74
|
+
return responseAdUnits.find((responseAdUnit) => responseAdUnit.code === adUnitCode);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function removeFalseBidders(adUnit, matchingAdUnit) {
|
|
78
|
+
const falseBidders = getFalseBidders(matchingAdUnit.bidders);
|
|
79
|
+
adUnit.bids = adUnit.bids.filter((bidRequest) => !falseBidders.includes(bidRequest.bidder));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function getFalseBidders(bidders) {
|
|
83
|
+
return Object.entries(bidders)
|
|
84
|
+
.filter(([bidder, shouldKeep]) => !shouldKeep)
|
|
85
|
+
.map(([bidder]) => bidder);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function createPayload(reqBidsConfigObj) {
|
|
89
|
+
return JSON.stringify({
|
|
90
|
+
auctionId: auctionInfo.auctionId,
|
|
91
|
+
version: MODULE_VERSION,
|
|
92
|
+
referrer: window.location.href,
|
|
93
|
+
prebid: '$prebid.version$',
|
|
94
|
+
rtdOptions: rtdOptions,
|
|
95
|
+
adUnits: reqBidsConfigObj.adUnits,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const greenbidsSubmodule = {
|
|
100
|
+
name: MODULE_NAME,
|
|
101
|
+
init: init,
|
|
102
|
+
onAuctionInitEvent: onAuctionInitEvent,
|
|
103
|
+
getBidRequestData: getBidRequestData,
|
|
104
|
+
updateAdUnitsBasedOnResponse: updateAdUnitsBasedOnResponse,
|
|
105
|
+
findMatchingAdUnit: findMatchingAdUnit,
|
|
106
|
+
removeFalseBidders: removeFalseBidders,
|
|
107
|
+
getFalseBidders: getFalseBidders,
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
submodule('realTimeData', greenbidsSubmodule);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
Module Name: Greenbids RTD Provider
|
|
5
|
+
Module Type: RTD Provider
|
|
6
|
+
Maintainer: jb@greenbids.ai
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
# Description
|
|
10
|
+
|
|
11
|
+
The Greenbids RTD adapter allows to dynamically filter calls to SSP to reduce outgoing call to the programmatics chain, reducing ad serving carbon impact
|
|
12
|
+
|
|
13
|
+
## Configuration
|
|
14
|
+
|
|
15
|
+
This module is configured as part of the `realTimeData.dataProviders` object.
|
|
16
|
+
|
|
17
|
+
{: .table .table-bordered .table-striped }
|
|
18
|
+
| Name | Scope | Description | Example | Type |
|
|
19
|
+
|------------|----------|----------------------------------------|---------------|----------|
|
|
20
|
+
| `name ` | required | Real time data module name | `'greenbidsRtdProvider'` | `string` |
|
|
21
|
+
| `waitForIt ` | required (mandatory true value) | Tells prebid auction to wait for the result of this module | `'true'` | `boolean` |
|
|
22
|
+
| `params` | required | | | `Object` |
|
|
23
|
+
| `params.pbuid` | required | The client site id provided by Greenbids. | `'TEST_FROM_GREENBIDS'` | `string` |
|
|
24
|
+
| `params.targetTPR` | optional (default 0.95) | Target True positive rate for the throttling model | `0.99` | `[0-1]` |
|
|
25
|
+
| `params.timeout` | optional (default 200) | Maximum amount of milliseconds allowed for module to finish working (has to be <= to the realTimeData.auctionDelay property) | `200` | `number` |
|
|
26
|
+
|
|
27
|
+
#### Example
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
const greenbidsDataProvider = {
|
|
31
|
+
name: 'greenbidsRtdProvider',
|
|
32
|
+
waitForIt: true,
|
|
33
|
+
params: {
|
|
34
|
+
pbuid: 'TEST_FROM_GREENBIDS',
|
|
35
|
+
timeout: 200
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
pbjs.setConfig({
|
|
40
|
+
realTimeData: {
|
|
41
|
+
auctionDelay: 200,
|
|
42
|
+
dataProviders: [greenbidsDataProvider]
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Integration
|
|
48
|
+
To install the module, follow these instructions:
|
|
49
|
+
|
|
50
|
+
#### Step 1: Contact Greenbids to get a pbuid and account
|
|
51
|
+
|
|
52
|
+
#### Step 2: Integrate the Greenbids Analytics Adapter
|
|
53
|
+
|
|
54
|
+
Greenbids RTD module works hand in hand with Greenbids Analytics module
|
|
55
|
+
See prebid Analytics modules -> Greenbids Analytics module
|
|
56
|
+
|
|
57
|
+
#### Step 3: Prepare the base Prebid file
|
|
58
|
+
|
|
59
|
+
- Option 1: Use Prebid [Download](/download.html) page to build the prebid package. Ensure that you do check *Greenbids RTD Provider* module
|
|
60
|
+
|
|
61
|
+
- Option 2: From the command line, run `gulp build --modules=greenbidsRtdProvider,...`
|
|
62
|
+
|
|
63
|
+
#### Step 4: Set configuration
|
|
64
|
+
|
|
65
|
+
Enable Greenbids Real Time Module using `pbjs.setConfig`. Example is provided in Configuration section.
|
|
@@ -91,7 +91,6 @@ const createOpenRtbRequest = (validBidRequests, bidderRequest) => {
|
|
|
91
91
|
|
|
92
92
|
if (bidderRequest.uspConsent) {
|
|
93
93
|
deepSetValue(request, 'regs.ext.us_privacy', bidderRequest.uspConsent);
|
|
94
|
-
this.syncStore.uspConsent = bidderRequest.uspConsent;
|
|
95
94
|
}
|
|
96
95
|
|
|
97
96
|
if (GETCONFIG('coppa') == true) deepSetValue(request, 'regs.coppa', 1);
|
package/modules/iqmBidAdapter.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {_each, deepAccess, getBidIdParameter, isArray} from '../src/utils.js';
|
|
2
2
|
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
3
|
-
import {config} from '../src/config.js';
|
|
4
3
|
import {BANNER, VIDEO} from '../src/mediaTypes.js';
|
|
5
4
|
import {INSTREAM} from '../src/video.js';
|
|
6
5
|
|
|
@@ -155,7 +154,7 @@ export const spec = {
|
|
|
155
154
|
auctionId: bidRequest.data.auctionId,
|
|
156
155
|
mediaType: bidRequest.data.imp.mediatype,
|
|
157
156
|
|
|
158
|
-
ttl: bid.ttl ||
|
|
157
|
+
ttl: bid.ttl || 60
|
|
159
158
|
};
|
|
160
159
|
|
|
161
160
|
if (bidRequest.data.imp.mediatype === VIDEO) {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as utils from '../src/utils.js';
|
|
2
2
|
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
3
|
-
import {config} from '../src/config.js';
|
|
4
3
|
|
|
5
4
|
const BIDDER_CODE = 'orbitsoft';
|
|
6
5
|
let styleParamsMap = {
|
|
@@ -122,7 +121,7 @@ export const spec = {
|
|
|
122
121
|
const HEIGHT = serverBody.height;
|
|
123
122
|
const CREATIVE = serverBody.content_url;
|
|
124
123
|
const CALLBACK_UID = serverBody.callback_uid;
|
|
125
|
-
const TIME_TO_LIVE =
|
|
124
|
+
const TIME_TO_LIVE = 60;
|
|
126
125
|
const REFERER = utils.getWindowTop();
|
|
127
126
|
let bidRequest = request.bidRequest;
|
|
128
127
|
if (CPM > 0 && WIDTH > 0 && HEIGHT > 0) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {config} from '../src/config.js';
|
|
1
|
+
import {deepAccess} from '../src/utils.js';
|
|
3
2
|
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
4
|
-
import {
|
|
3
|
+
import {BANNER, VIDEO} from '../src/mediaTypes.js';
|
|
5
4
|
|
|
6
5
|
const BIDDER_CODE = 'rads';
|
|
7
6
|
const ENDPOINT_URL = 'https://rads.recognified.net/md.request.php';
|
|
@@ -86,7 +85,7 @@ export const spec = {
|
|
|
86
85
|
dealId: dealId,
|
|
87
86
|
currency: currency,
|
|
88
87
|
netRevenue: netRevenue,
|
|
89
|
-
ttl:
|
|
88
|
+
ttl: 60,
|
|
90
89
|
meta: {
|
|
91
90
|
advertiserDomains: response.adomain || []
|
|
92
91
|
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
2
|
+
import {ortbConverter} from '../libraries/ortbConverter/converter.js'
|
|
3
|
+
import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js';
|
|
4
|
+
import {config} from '../src/config.js';
|
|
5
|
+
import {pbsExtensions} from '../libraries/pbsExtensions/pbsExtensions.js'
|
|
6
|
+
import {deepSetValue, isEmpty, deepClone, shuffle, triggerPixel, deepAccess} from '../src/utils.js';
|
|
7
|
+
|
|
8
|
+
const BIDDER_CODE = 'relevantdigital';
|
|
9
|
+
|
|
10
|
+
/** Global settings per bidder-code for this adapter (which might be > 1 if using aliasing) */
|
|
11
|
+
let configByBidder = {};
|
|
12
|
+
|
|
13
|
+
/** Used by the tests */
|
|
14
|
+
export const resetBidderConfigs = () => {
|
|
15
|
+
configByBidder = {};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/** Settings ber bidder-code. checkParams === true means that it can optionally be set in bid-params */
|
|
19
|
+
const FIELDS = [
|
|
20
|
+
{ name: 'pbsHost', checkParams: true, required: true },
|
|
21
|
+
{ name: 'accountId', checkParams: true, required: true },
|
|
22
|
+
{ name: 'pbsBufferMs', checkParams: false, required: false, default: 250 },
|
|
23
|
+
{ name: 'useSourceBidderCode', checkParams: false, required: false, default: false },
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
const SYNC_HTML = 'https://cdn.relevant-digital.com/resources/load-cookie.html';
|
|
27
|
+
const MAX_SYNC_COUNT = 10; // Max server-side bidder to sync at once via the iframe
|
|
28
|
+
|
|
29
|
+
/** Get settings for a bidder-code via config and, if needed, bid parameters */
|
|
30
|
+
const getBidderConfig = (bids) => {
|
|
31
|
+
const { bidder } = bids[0];
|
|
32
|
+
const cfg = configByBidder[bidder] || {
|
|
33
|
+
...Object.fromEntries(FIELDS.filter((f) => 'default' in f).map((f) => [f.name, f.default])),
|
|
34
|
+
syncedBidders: {}, // To keep track of S2S-bidders we already (started to) synced
|
|
35
|
+
};
|
|
36
|
+
if (cfg.complete) {
|
|
37
|
+
return cfg; // Most common case, we already have the settings we need (and we won't re-read them)
|
|
38
|
+
}
|
|
39
|
+
configByBidder[bidder] = cfg;
|
|
40
|
+
const bidderConfiguration = config.getConfig(bidder) || {};
|
|
41
|
+
|
|
42
|
+
// Read settings set by setConfig({ [bidder]: { ... }}) and if not available - from bid params
|
|
43
|
+
FIELDS.forEach(({ name, checkParams }) => {
|
|
44
|
+
cfg[name] = bidderConfiguration[name] || cfg[name];
|
|
45
|
+
if (!cfg[name] && checkParams) {
|
|
46
|
+
bids.forEach((bid) => {
|
|
47
|
+
cfg[name] = cfg[name] || bid.params?.[name];
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
cfg.complete = FIELDS.every((field) => !field.required || cfg[field.name]);
|
|
52
|
+
if (cfg.complete) {
|
|
53
|
+
cfg.pbsHost = cfg.pbsHost.trim().replace('http://', 'https://');
|
|
54
|
+
if (cfg.pbsHost.indexOf('https://') < 0) {
|
|
55
|
+
cfg.pbsHost = `https://${cfg.pbsHost}`;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return cfg;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const converter = ortbConverter({
|
|
62
|
+
context: {
|
|
63
|
+
netRevenue: true,
|
|
64
|
+
ttl: 300
|
|
65
|
+
},
|
|
66
|
+
processors: pbsExtensions,
|
|
67
|
+
imp(buildImp, bidRequest, context) {
|
|
68
|
+
// Set stored request id from placementId
|
|
69
|
+
const imp = buildImp(bidRequest, context);
|
|
70
|
+
const { placementId } = bidRequest.params;
|
|
71
|
+
deepSetValue(imp, 'ext.prebid.storedrequest.id', placementId);
|
|
72
|
+
delete imp.ext.prebid.bidder;
|
|
73
|
+
return imp;
|
|
74
|
+
},
|
|
75
|
+
overrides: {
|
|
76
|
+
bidResponse: {
|
|
77
|
+
bidderCode(orig, bidResponse, bid, { bidRequest }) {
|
|
78
|
+
const { bidder, params = {} } = bidRequest || {};
|
|
79
|
+
let useSourceBidderCode = configByBidder[bidder]?.useSourceBidderCode;
|
|
80
|
+
if ('useSourceBidderCode' in params) {
|
|
81
|
+
useSourceBidderCode = params.useSourceBidderCode;
|
|
82
|
+
}
|
|
83
|
+
// Only use the orignal function when useSourceBidderCode is true, else our own bidder code will be used
|
|
84
|
+
if (useSourceBidderCode) {
|
|
85
|
+
orig.apply(this, [...arguments].slice(1));
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
export const spec = {
|
|
93
|
+
code: BIDDER_CODE,
|
|
94
|
+
gvlid: 1100,
|
|
95
|
+
supportedMediaTypes: [BANNER, VIDEO, NATIVE],
|
|
96
|
+
|
|
97
|
+
/** We need both params.placementId + a complete configuration (pbsHost + accountId) to continue **/
|
|
98
|
+
isBidRequestValid: (bid) => bid.params?.placementId && getBidderConfig([bid]).complete,
|
|
99
|
+
|
|
100
|
+
/** Trigger impression-pixel */
|
|
101
|
+
onBidWon: ({pbsWurl}) => pbsWurl && triggerPixel(pbsWurl),
|
|
102
|
+
|
|
103
|
+
/** Build BidRequest for PBS */
|
|
104
|
+
buildRequests(bidRequests, bidderRequest) {
|
|
105
|
+
const { bidder } = bidRequests[0];
|
|
106
|
+
const cfg = getBidderConfig(bidRequests);
|
|
107
|
+
const data = converter.toORTB({bidRequests, bidderRequest});
|
|
108
|
+
|
|
109
|
+
/** Set tmax, in general this will be timeout - pbsBufferMs */
|
|
110
|
+
const pbjsTimeout = bidderRequest.timeout || 1000;
|
|
111
|
+
data.tmax = Math.min(Math.max(pbjsTimeout - cfg.pbsBufferMs, cfg.pbsBufferMs), pbjsTimeout);
|
|
112
|
+
|
|
113
|
+
delete data.ext?.prebid?.aliases; // We don't need/want to send aliases to PBS
|
|
114
|
+
deepSetValue(data, 'ext.relevant', {
|
|
115
|
+
...data.ext?.relevant,
|
|
116
|
+
adapter: true, // For internal analytics
|
|
117
|
+
});
|
|
118
|
+
deepSetValue(data, 'ext.prebid.storedrequest.id', cfg.accountId);
|
|
119
|
+
data.ext.prebid.passthrough = {
|
|
120
|
+
...data.ext.prebid.passthrough,
|
|
121
|
+
relevant: { bidder }, // to find config for the right bidder-code in interpretResponse / getUserSyncs
|
|
122
|
+
};
|
|
123
|
+
return [{
|
|
124
|
+
method: 'POST',
|
|
125
|
+
url: `${cfg.pbsHost}/openrtb2/auction`,
|
|
126
|
+
data
|
|
127
|
+
}];
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
/** Read BidResponse from PBS and make necessary adjustments to not make it appear to come from unknown bidders */
|
|
131
|
+
interpretResponse(response, request) {
|
|
132
|
+
const resp = deepClone(response.body);
|
|
133
|
+
const { bidder } = request.data.ext.prebid.passthrough.relevant;
|
|
134
|
+
|
|
135
|
+
// Modify response times / errors for actual PBS bidders into a single value
|
|
136
|
+
const MODIFIERS = {
|
|
137
|
+
responsetimemillis: (values) => Math.max(...values),
|
|
138
|
+
errors: (values) => [].concat(...values),
|
|
139
|
+
};
|
|
140
|
+
Object.entries(MODIFIERS).forEach(([field, combineFn]) => {
|
|
141
|
+
const obj = resp.ext?.[field];
|
|
142
|
+
if (!isEmpty(obj)) {
|
|
143
|
+
resp.ext[field] = {[bidder]: combineFn(Object.values(obj))};
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
const bids = converter.fromORTB({response: resp, request: request.data}).bids;
|
|
148
|
+
return bids;
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
/** Do syncing, but avoid running the sync > 1 time for S2S bidders */
|
|
152
|
+
getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent) {
|
|
153
|
+
if (!syncOptions.iframeEnabled && !syncOptions.pixelEnabled) {
|
|
154
|
+
return [];
|
|
155
|
+
}
|
|
156
|
+
const syncs = [];
|
|
157
|
+
serverResponses.forEach(({ body }) => {
|
|
158
|
+
const { pbsHost, syncedBidders } = configByBidder[body.ext.prebid.passthrough.relevant.bidder] || {};
|
|
159
|
+
if (!pbsHost) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const { gdprApplies, consentString } = gdprConsent || {};
|
|
163
|
+
let bidders = Object.keys(body.ext?.responsetimemillis || {});
|
|
164
|
+
bidders = bidders.reduce((acc, curr) => {
|
|
165
|
+
if (!syncedBidders[curr]) {
|
|
166
|
+
acc.push(curr);
|
|
167
|
+
syncedBidders[curr] = true;
|
|
168
|
+
}
|
|
169
|
+
return acc;
|
|
170
|
+
}, []);
|
|
171
|
+
bidders = shuffle(bidders).slice(0, MAX_SYNC_COUNT); // Shuffle to not always leave out the same bidders
|
|
172
|
+
if (!bidders.length) {
|
|
173
|
+
return; // All bidders already synced
|
|
174
|
+
}
|
|
175
|
+
if (syncOptions.iframeEnabled) {
|
|
176
|
+
const params = {
|
|
177
|
+
endpoint: `${pbsHost}/cookie_sync`,
|
|
178
|
+
max_sync_count: bidders.length,
|
|
179
|
+
gdpr: gdprApplies ? 1 : 0,
|
|
180
|
+
gdpr_consent: consentString,
|
|
181
|
+
us_privacy: uspConsent,
|
|
182
|
+
bidders: bidders.join(','),
|
|
183
|
+
};
|
|
184
|
+
const qs = Object.entries(params)
|
|
185
|
+
.filter(([k, v]) => ![null, undefined, ''].includes(v))
|
|
186
|
+
.map(([k, v]) => `${k}=${encodeURIComponent(v.toString())}`)
|
|
187
|
+
.join('&');
|
|
188
|
+
syncs.push({ type: 'iframe', url: `${SYNC_HTML}?${qs}` });
|
|
189
|
+
} else { // Else, try to pixel-sync (for future-compatibility)
|
|
190
|
+
const pixels = deepAccess(body, `ext.relevant.sync`, []).filter(({ type }) => type === 'redirect');
|
|
191
|
+
syncs.push(...pixels.map(({ url }) => ({ type: 'image', url })));
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
return syncs;
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
registerBidder(spec);
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
Module Name: Relevant Digital Bid Adapter
|
|
5
|
+
Module Type: Bidder Adapter
|
|
6
|
+
Maintainer: support@relevant-digital.com
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
# Description
|
|
10
|
+
|
|
11
|
+
This adapter is used for integration with providers using the **[Relevant Yield](https://www.relevant-digital.com/relevantyield)** platform. The provider will supply the necessary **pbsHost** and **accountId** settings along with the **placementId** bid parameters per ad unit.
|
|
12
|
+
|
|
13
|
+
# Example setup using pbjs.setConfig()
|
|
14
|
+
This is the recommended method to set the global configuration parameters.
|
|
15
|
+
```javascript
|
|
16
|
+
pbjs.setConfig({
|
|
17
|
+
relevantdigital: {
|
|
18
|
+
pbsHost: 'pbs-example.relevant-digital.com',
|
|
19
|
+
accountId: '6204e5fa70e3ad10821b84ff',
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
var adUnits = [
|
|
24
|
+
{
|
|
25
|
+
code: 'test-div',
|
|
26
|
+
mediaTypes: { banner: { sizes: [[300, 250], [320, 320]] }},
|
|
27
|
+
bids: [
|
|
28
|
+
{
|
|
29
|
+
bidder: 'relevantdigital',
|
|
30
|
+
params: {
|
|
31
|
+
placementId: '6204e83a077c5825441b8508_620f9e8e4fe67c1f87cd30ed',
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
}
|
|
36
|
+
];
|
|
37
|
+
```
|
|
38
|
+
# Example setup using only bid params
|
|
39
|
+
This method to set the global configuration parameters (like **pbsHost**) in **params** could simplify integration of a provider for some publishers. Setting different global config-parameters on different bids is not supported in general*, as the first settings found will be used and any subsequent global settings will be ignored.
|
|
40
|
+
|
|
41
|
+
* _The exception is `useSourceBidderCode` which can be overriden individually per ad unit._
|
|
42
|
+
```javascript
|
|
43
|
+
var adUnits = [
|
|
44
|
+
{
|
|
45
|
+
code: 'test-div',
|
|
46
|
+
mediaTypes: { banner: { sizes: [[300, 250], [320, 320]] }},
|
|
47
|
+
bids: [
|
|
48
|
+
{
|
|
49
|
+
bidder: 'relevantdigital',
|
|
50
|
+
params: {
|
|
51
|
+
placementId: '6204e83a077c5825441b8508_620f9e8e4fe67c1f87cd30ed',
|
|
52
|
+
pbsHost: 'pbs-example.relevant-digital.com',
|
|
53
|
+
accountId: '6204e5fa70e3ad10821b84ff',
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
}
|
|
58
|
+
];
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
# Example setup with multiple providers
|
|
62
|
+
**Notice:** Placements below are _not_ live test placements
|
|
63
|
+
```javascript
|
|
64
|
+
|
|
65
|
+
pbjs.aliasBidder('relevantdigital', 'providerA');
|
|
66
|
+
pbjs.aliasBidder('relevantdigital', 'providerB');
|
|
67
|
+
|
|
68
|
+
pbjs.setConfig({
|
|
69
|
+
providerA: {
|
|
70
|
+
pbsHost: 'pbs-example-a.relevant-digital.com',
|
|
71
|
+
accountId: '620533ae7f5bbe1691bbb815',
|
|
72
|
+
},
|
|
73
|
+
providerB: {
|
|
74
|
+
pbsHost: 'pbs-example-b.relevant-digital.com',
|
|
75
|
+
accountId: '990533ae7f5bbe1691bbb815',
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
var adUnits = [
|
|
80
|
+
{
|
|
81
|
+
code: 'test-div',
|
|
82
|
+
mediaTypes: { banner: { sizes: [[300, 250], [320, 320]] }},
|
|
83
|
+
bids: [
|
|
84
|
+
{
|
|
85
|
+
bidder: 'providerA',
|
|
86
|
+
params: {
|
|
87
|
+
placementId: '610525862d7517bfd4bbb81e_620523b7d1dbed6b0fbbb817',
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
bidder: 'providerB',
|
|
92
|
+
params: {
|
|
93
|
+
placementId: '990525862d7517bfd4bbb81e_770523b7d1dbed6b0fbbb817',
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
}
|
|
98
|
+
];
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
# Bid Parameters
|
|
102
|
+
|
|
103
|
+
| Name | Scope | Description | Example | Type |
|
|
104
|
+
|---------------|----------|---------------------------------------------------------|----------------------------|--------------|
|
|
105
|
+
| `placementId` | required | The placement id. | `'6204e83a077c5825441b8508_620f9e8e4fe67c1f87cd30ed'` | `String` |
|
|
106
|
+
| `pbsHost` | required if not set in config | Host name of the server. | `'pbs-example.relevant-digital.com'` | `String` |
|
|
107
|
+
| `accountId` | required if not set in config | The account id. | `'6204e5fa70e3ad10821b84ff'` | `String` |
|
|
108
|
+
| `useSourceBidderCode` | optional | Set to `true` in order to use the bidder code of the actual server-side bidder in bid responses. You **MUST** also use `allowAlternateBidderCodes: true` in `bidderSettings` if you enabled this - as otherwise the bids will be rejected.| `true` | `Boolean` |
|
|
109
|
+
|
|
110
|
+
# Config Parameters
|
|
111
|
+
|
|
112
|
+
| Name | Scope | Description | Example | Type |
|
|
113
|
+
|---------------|----------|---------------------------------------------------------|----------------------------|--------------|
|
|
114
|
+
| `pbsHost` | required if not set in bid parameters | Host name of the server. | `'pbs-example.relevant-digital.com'` | `String` |
|
|
115
|
+
| `accountId` | required if not set in bid parameters | The account id. | `'6204e5fa70e3ad10821b84ff'` | `String` |
|
|
116
|
+
| `pbsBufferMs` | optional | How much less in *milliseconds* the server's internal timeout should be compared to the normal Prebid timeout. Default is *250*. To be increased in cases of frequent timeouts. | `250` | `Integer` |
|
|
117
|
+
| `useSourceBidderCode` | optional | Set to `true` in order to use the bidder code of the actual server-side bidder in bid responses. You **MUST** also use `allowAlternateBidderCodes: true` in `bidderSettings` if you enabled this - as otherwise the bids will be rejected.| `true` | `Boolean` |
|
|
@@ -85,15 +85,12 @@ export const spec = {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
const ortb2Params = bidderRequest?.ortb2 || {};
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
if (ortb2Params.device) {
|
|
95
|
-
mergeDeep(request, { device: ortb2Params.device });
|
|
96
|
-
}
|
|
88
|
+
['site', 'user', 'device', 'bcat', 'badv'].forEach(entry => {
|
|
89
|
+
const ortb2Param = ortb2Params[entry];
|
|
90
|
+
if (ortb2Param) {
|
|
91
|
+
mergeDeep(request, { [entry]: ortb2Param });
|
|
92
|
+
}
|
|
93
|
+
});
|
|
97
94
|
|
|
98
95
|
let computedEndpointUrl = ENDPOINT_URL;
|
|
99
96
|
|
|
@@ -173,6 +173,10 @@ export const spec = {
|
|
|
173
173
|
if (bidderRequest.uspConsent) {
|
|
174
174
|
deepSetValue(sovrnBidReq, 'regs.ext.us_privacy', bidderRequest.uspConsent);
|
|
175
175
|
}
|
|
176
|
+
if (bidderRequest.gppConsent) {
|
|
177
|
+
deepSetValue(sovrnBidReq, 'regs.gpp', bidderRequest.gppConsent.gppString);
|
|
178
|
+
deepSetValue(sovrnBidReq, 'regs.gpp_sid', bidderRequest.gppConsent.applicableSections);
|
|
179
|
+
}
|
|
176
180
|
|
|
177
181
|
if (eids) {
|
|
178
182
|
deepSetValue(sovrnBidReq, 'user.ext.eids', eids)
|
package/modules/stvBidAdapter.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { BANNER, VIDEO } from '../src/mediaTypes.js';
|
|
1
|
+
import {deepAccess} from '../src/utils.js';
|
|
2
|
+
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
3
|
+
import {BANNER, VIDEO} from '../src/mediaTypes.js';
|
|
5
4
|
import {includes} from '../src/polyfill.js';
|
|
6
5
|
|
|
7
6
|
const BIDDER_CODE = 'stv';
|
|
@@ -128,7 +127,7 @@ export const spec = {
|
|
|
128
127
|
dealId: dealId,
|
|
129
128
|
currency: currency,
|
|
130
129
|
netRevenue: netRevenue,
|
|
131
|
-
ttl:
|
|
130
|
+
ttl: 60,
|
|
132
131
|
meta: {
|
|
133
132
|
advertiserDomains: response.adomain || []
|
|
134
133
|
}
|
|
@@ -9,7 +9,7 @@ const BIDDER_CODE = 'triplelift';
|
|
|
9
9
|
const STR_ENDPOINT = 'https://tlx.3lift.com/header/auction?';
|
|
10
10
|
const BANNER_TIME_TO_LIVE = 300;
|
|
11
11
|
const VIDEO_TIME_TO_LIVE = 3600;
|
|
12
|
-
let gdprApplies =
|
|
12
|
+
let gdprApplies = null;
|
|
13
13
|
let consentString = null;
|
|
14
14
|
export const storage = getStorageManager({bidderCode: BIDDER_CODE});
|
|
15
15
|
|
|
@@ -40,8 +40,12 @@ export const tripleliftAdapterSpec = {
|
|
|
40
40
|
if (bidderRequest && bidderRequest.gdprConsent) {
|
|
41
41
|
if (typeof bidderRequest.gdprConsent.gdprApplies !== 'undefined') {
|
|
42
42
|
gdprApplies = bidderRequest.gdprConsent.gdprApplies;
|
|
43
|
-
|
|
43
|
+
} else {
|
|
44
|
+
gdprApplies = true;
|
|
44
45
|
}
|
|
46
|
+
|
|
47
|
+
tlCall = tryAppendQueryString(tlCall, 'gdpr', gdprApplies.toString());
|
|
48
|
+
|
|
45
49
|
if (typeof bidderRequest.gdprConsent.consentString !== 'undefined') {
|
|
46
50
|
consentString = bidderRequest.gdprConsent.consentString;
|
|
47
51
|
tlCall = tryAppendQueryString(tlCall, 'cmp_cs', consentString);
|
|
@@ -87,7 +91,7 @@ export const tripleliftAdapterSpec = {
|
|
|
87
91
|
syncEndpoint = tryAppendQueryString(syncEndpoint, 'src', 'prebid');
|
|
88
92
|
}
|
|
89
93
|
|
|
90
|
-
if (consentString !== null) {
|
|
94
|
+
if (consentString !== null || gdprApplies) {
|
|
91
95
|
syncEndpoint = tryAppendQueryString(syncEndpoint, 'gdpr', gdprApplies);
|
|
92
96
|
syncEndpoint = tryAppendQueryString(syncEndpoint, 'cmp_cs', consentString);
|
|
93
97
|
}
|
|
@@ -130,8 +134,15 @@ function _buildPostBody(bidRequests, bidderRequest) {
|
|
|
130
134
|
}
|
|
131
135
|
|
|
132
136
|
if (!isEmpty(bidRequest.ortb2Imp)) {
|
|
137
|
+
// legacy method for extracting ortb2Imp.ext
|
|
133
138
|
imp.fpd = _getAdUnitFpd(bidRequest.ortb2Imp);
|
|
139
|
+
|
|
140
|
+
// preferred method for extracting ortb2Imp.ext
|
|
141
|
+
if (!isEmpty(bidRequest.ortb2Imp.ext)) {
|
|
142
|
+
imp.ext = { ...bidRequest.ortb2Imp.ext };
|
|
143
|
+
}
|
|
134
144
|
}
|
|
145
|
+
|
|
135
146
|
return imp;
|
|
136
147
|
});
|
|
137
148
|
|