Skip to content

Commit 041a130

Browse files
committedFeb 3, 2025
Merge branch 'master' of github.com:media-net/Prebid.js into vplcmtt
2 parents 108d2d3 + 5864b98 commit 041a130

25 files changed

+1633
-551
lines changed
 

‎integrationExamples/gpt/x-domain/creative.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
<script>
88
pbRender({
9-
adId: '%%PATTERN:hb_adid%%',
10-
pubUrl: '%%PATTERN:url%%',
11-
clickUrl: '%%CLICK_URL_UNESC%%'
9+
adId: "%%PATTERN:hb_adid%%",
10+
pubUrl: "%%PATTERN:url%%",
11+
clickUrl: "%%CLICK_URL_UNESC%%"
1212
});
1313
</script>

‎libraries/ortbConverter/README.md

+62-50
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Prebid.js - ORTB conversion library
22

3-
This library provides methods to convert Prebid.js bid request objects to ORTB requests,
4-
and ORTB responses to Prebid.js bid response objects.
3+
This library provides methods to convert Prebid.js bid request objects to ORTB requests,
4+
and ORTB responses to Prebid.js bid response objects.
55

66
## Usage
77

@@ -37,13 +37,25 @@ registerBidder({
3737
})
3838
```
3939

40-
Without any customization, the library will generate complete ORTB requests, but ignores your [bid params](#params).
40+
Without any customization, the library will generate complete ORTB requests, but ignores your [bid params](#params).
4141
If your endpoint sets `response.seatbid[].bid[].mtype` (part of the ORTB 2.6 spec), it will also parse the response into complete bidResponse objects. See [setting response mediaTypes](#response-mediaTypes) if that is not the case.
4242

4343
### Module-specific conversions
4444

4545
Prebid.js features that require a module also require it for their corresponding ORTB conversion logic. For example, `imp.bidfloor` is only populated if the `priceFloors` module is active; `request.cur` needs the `currency` module, and so on. Notably, this means that to get those fields populated from your unit tests, you must import those modules first; see [this suite](https://github.com/prebid/Prebid.js/blob/master/test/spec/modules/openxOrtbBidAdapter_spec.js) for an example.
4646

47+
#### priceFloors extensions
48+
49+
In addition to `imp.bidfloor` and `imp.bidfloorcur`, the `priceFloors` module also populates media type and `format` objects, if their floors differ:
50+
51+
| Path | `getFloor` invocation |
52+
|-----------------------------------------------------|----------------------------------------------------------------|
53+
| `imp.bidfloor` & `.bidfloorcur` | `.getFloor()` |
54+
| `imp.banner.ext.bidfloor` & `.bidfloorcur` | `.getFloor({mediaType: 'banner', size: '*'})` |
55+
| `imp.banner.format[].ext.bidfloor` & `.bidfloorcur` | `.getFloor({mediaType: 'banner', size: [format.w, format.h]})` |
56+
| `imp.native.ext.bidfloor` & `.bidfloorcur` | `.getFloor({mediaType: 'native', size: '*'})` |
57+
| `imp.video.ext.bidfloor` & `.bidfloorcur` | `.getFloor({mediaType: 'video', size: '*'})` |
58+
4759
## Customization
4860

4961
### Modifying return values directly
@@ -57,35 +69,35 @@ deepSetValue(data.imp[0], 'ext.myCustomParam', bidRequests[0].params.myCustomPar
5769

5870
However, there are two restrictions (to avoid them, use the [other customization options](#fine-customization)):
5971

60-
- you may not change the `imp[].id` returned by `toORTB`; they ared used internally to match responses to their requests.
61-
```javascript
62-
const data = converter.toORTB({bidRequests, bidderRequest});
63-
data.imp[0].id = 'custom-imp-id' // do not do this - it will cause an error later in `fromORTB`
64-
```
65-
See also [overriding `imp.id`](#imp-id).
66-
- the `request` argument passed to `fromORTB` must be the same object returned by `toORTB`.
72+
- you may not change the `imp[].id` returned by `toORTB`; they ared used internally to match responses to their requests.
6773
```javascript
68-
let data = converter.toORTB({bidRequests, bidderRequest});
69-
70-
data = mergeDeep( // the original object is lost
71-
{ext: {myCustomParam: bidRequests[0].params.myCustomParam}}, // `fromORTB` will later throw an error
72-
data
73-
);
74-
75-
// do this instead:
76-
mergeDeep(
77-
data,
78-
{ext: {myCustomParam: bidRequests[0].params.myCustomParam}},
79-
data
80-
)
74+
const data = converter.toORTB({bidRequests, bidderRequest});
75+
data.imp[0].id = 'custom-imp-id' // do not do this - it will cause an error later in `fromORTB`
8176
```
77+
See also [overriding `imp.id`](#imp-id).
78+
- the `request` argument passed to `fromORTB` must be the same object returned by `toORTB`.
79+
```javascript
80+
let data = converter.toORTB({bidRequests, bidderRequest});
81+
82+
data = mergeDeep( // the original object is lost
83+
{ext: {myCustomParam: bidRequests[0].params.myCustomParam}}, // `fromORTB` will later throw an error
84+
data
85+
);
86+
87+
// do this instead:
88+
mergeDeep(
89+
data,
90+
{ext: {myCustomParam: bidRequests[0].params.myCustomParam}},
91+
data
92+
)
93+
```
8294

8395
### <a id="fine-customization" /> Fine grained customization - imp, request, bidResponse, response
8496

8597
When invoked, `toORTB({bidRequests, bidderRequest})` first loops through each request in `bidRequests`, converting them into ORTB `imp` objects.
8698
It then packages them into a single ORTB request, adding other parameters that are not imp-specific (such as for example `request.tmax`).
8799

88-
Likewise, `fromORTB({request, response})` first loops through each `response.seatbid[].bid[]`, converting them into Prebid bidResponses; it then packages them into
100+
Likewise, `fromORTB({request, response})` first loops through each `response.seatbid[].bid[]`, converting them into Prebid bidResponses; it then packages them into
89101
a single return value.
90102

91103
You can customize each of these steps using the `ortbConverter` arguments `imp`, `request`, `bidResponse` and `response`:
@@ -98,8 +110,8 @@ The arguments are:
98110
- `buildImp`: a function taking `(bidRequest, context)` and returning an ORTB `imp` object;
99111
- `bidRequest`: the bid request object to convert;
100112
- `context`: a [context object](#context) that contains at least:
101-
- `bidderRequest`: the `bidderRequest` argument passed to `toORTB`.
102-
113+
- `bidderRequest`: the `bidderRequest` argument passed to `toORTB`.
114+
103115
#### <a id="params" /> Example: attaching custom bid params
104116

105117
```javascript
@@ -194,7 +206,7 @@ const converter = ortbConverter({
194206
})
195207
```
196208

197-
If you know that a particular ORTB request/response pair deals with exclusively one mediaType, you may also pass it directly in the [context parameter](#context).
209+
If you know that a particular ORTB request/response pair deals with exclusively one mediaType, you may also pass it directly in the [context parameter](#context).
198210
Note that - compared to the above - this has additional effects, because `context.mediaType` is also considered during `imp` generation - see [special context properties](#special-context).
199211

200212
```javascript
@@ -223,7 +235,7 @@ const converter = ortbConverter({
223235

224236
### <a id="response" /> Customizing the response: `response(buildResponse, bidResponses, ortbResponse, context)`
225237

226-
Invoked once, after all `seatbid[].bid[]` objects have been converted to corresponding bid responses. The value returned
238+
Invoked once, after all `seatbid[].bid[]` objects have been converted to corresponding bid responses. The value returned
227239
by this function is also the value returned by `fromORTB`.
228240
The arguments are:
229241

@@ -249,7 +261,7 @@ const converter = ortbConverter({
249261
### Even finer grained customization - processor overrides
250262

251263
Each of the four conversion steps described above - imp, request, bidResponse and response - is further broken down into
252-
smaller units of work (called _processors_). For example, when the currency module is included, it adds a _request processor_
264+
smaller units of work (called _processors_). For example, when the currency module is included, it adds a _request processor_
253265
that sets `request.cur`; the priceFloors module adds an _imp processor_ that sets `imp.bidfloor` and `imp.bidfloorcur`, and so on.
254266

255267
Each processor can be overridden or disabled through the `overrides` argument:
@@ -310,21 +322,21 @@ const converter = ortbConverter({
310322
Processor overrides are similar to the override options described above, except that they take the object to process as argument:
311323

312324
- `imp` processor overrides take `(orig, imp, bidRequest, context)`, where:
313-
- `orig` is the processor function being overridden, which itself takes `(imp, bidRequest, context)`;
314-
- `imp` is the (partial) imp object to modify;
315-
- `bidRequest` and `context` are the same arguments passed to [imp](#imp).
325+
- `orig` is the processor function being overridden, which itself takes `(imp, bidRequest, context)`;
326+
- `imp` is the (partial) imp object to modify;
327+
- `bidRequest` and `context` are the same arguments passed to [imp](#imp).
316328
- `request` processor overrides take `(orig, ortbRequest, bidderRequest, context)`, where:
317-
- `orig` is the processor function being overridden, and takes `(ortbRequest, bidderRequest, context)`;
318-
- `ortbRequest` is the partial request to modify;
319-
- `bidderRequest` and `context` are the same arguments passed to [request](#reuqest).
320-
- `bidResponse` processor overrides take `(orig, bidResponse, bid, context)`, where:
321-
- `orig` is the processor function being overridden, and takes `(bidResponse, bid, context)`;
322-
- `bidResponse` is the partial bid response to modify;
323-
- `bid` and `context` are the same arguments passed to [bidResponse](#bidResponse)
329+
- `orig` is the processor function being overridden, and takes `(ortbRequest, bidderRequest, context)`;
330+
- `ortbRequest` is the partial request to modify;
331+
- `bidderRequest` and `context` are the same arguments passed to [request](#reuqest).
332+
- `bidResponse` processor overrides take `(orig, bidResponse, bid, context)`, where:
333+
- `orig` is the processor function being overridden, and takes `(bidResponse, bid, context)`;
334+
- `bidResponse` is the partial bid response to modify;
335+
- `bid` and `context` are the same arguments passed to [bidResponse](#bidResponse)
324336
- `response` processor overrides take `(orig, response, ortbResponse, context)`, where:
325-
- `orig` is the processor function being overriden, and takes `(response, ortbResponse, context)`;
326-
- `response` is the partial response to modify;
327-
- `ortbRespones` and `context` are the same arguments passed to [response](#response).
337+
- `orig` is the processor function being overriden, and takes `(response, ortbResponse, context)`;
338+
- `response` is the partial response to modify;
339+
- `ortbRespones` and `context` are the same arguments passed to [response](#response).
328340

329341
### <a id="context" /> The `context` argument
330342

@@ -354,19 +366,19 @@ const converter = ortbConverter({
354366

355367
For ease of use, the conversion logic gives special meaning to some context properties:
356368

357-
- `currency`: a currency string (e.g. `'EUR'`). If specified, overrides the currency to use for computing price floors and `request.cur`. If omitted, both default to `getConfig('currency.adServerCurrency')`.
358-
- `mediaType`: a bid mediaType (`'banner'`, `'video'`, or `'native'`). If specified:
369+
- `currency`: a currency string (e.g. `'EUR'`). If specified, overrides the currency to use for computing price floors and `request.cur`. If omitted, both default to `getConfig('currency.adServerCurrency')`.
370+
- `mediaType`: a bid mediaType (`'banner'`, `'video'`, or `'native'`). If specified:
359371
- disables `imp` generation for other media types (i.e., if `context.mediaType === 'banner'`, only `imp.banner` will be populated; `imp.video` and `imp.native` will not, even if the bid request specifies them);
360372
- is passed as the `mediaType` option to `bidRequest.getFloor` when computing price floors;
361373
- sets `bidResponse.mediaType`.
362-
- `nativeRequest`: a plain object that serves as the base value for `imp.native.request` (and is relevant only for native bid requests).
363-
If not specified, the only property that is guaranteed to be populated is `assets`, since Prebid does not require anything else to define a native adUnit. You can use `context.nativeRequest` to provide other properties; for example, you may want to signal support for native impression trackers by setting it to `{eventtrackers: [{event: 1, methods: [1, 2]}]}` (see also the [ORTB Native spec](https://www.iab.com/wp-content/uploads/2018/03/OpenRTB-Native-Ads-Specification-Final-1.2.pdf)).
364-
- `netRevenue`: the value to set as `bidResponse.netRevenue`. This is a required property of bid responses that does not have a clear ORTB counterpart.
365-
- `ttl`: the default value to use for `bidResponse.ttl` (if the ORTB response does not provide one in `seatbid[].bid[].exp`).
366-
374+
- `nativeRequest`: a plain object that serves as the base value for `imp.native.request` (and is relevant only for native bid requests).
375+
If not specified, the only property that is guaranteed to be populated is `assets`, since Prebid does not require anything else to define a native adUnit. You can use `context.nativeRequest` to provide other properties; for example, you may want to signal support for native impression trackers by setting it to `{eventtrackers: [{event: 1, methods: [1, 2]}]}` (see also the [ORTB Native spec](https://www.iab.com/wp-content/uploads/2018/03/OpenRTB-Native-Ads-Specification-Final-1.2.pdf)).
376+
- `netRevenue`: the value to set as `bidResponse.netRevenue`. This is a required property of bid responses that does not have a clear ORTB counterpart.
377+
- `ttl`: the default value to use for `bidResponse.ttl` (if the ORTB response does not provide one in `seatbid[].bid[].exp`).
378+
367379
## Prebid Server extensions
368380

369-
If your endpoint is a Prebid Server instance, you may take advantage of the `pbsExtension` companion library, which adds a number of processors that can populate and parse PBS-specific extensions (typically prefixed `ext.prebid`); these include bidder params (with `transformBidParams`), bidder aliases, targeting keys, and others.
381+
If your endpoint is a Prebid Server instance, you may take advantage of the `pbsExtension` companion library, which adds a number of processors that can populate and parse PBS-specific extensions (typically prefixed `ext.prebid`); these include bidder params (with `transformBidParams`), bidder aliases, targeting keys, and others.
370382

371383
```javascript
372384
import {pbsExtensions} from '../../libraries/pbsExtensions/pbsExtensions.js'

‎modules/adnuntiusBidAdapter.js

+11-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { registerBidder } from '../src/adapters/bidderFactory.js';
2-
import {BANNER, VIDEO} from '../src/mediaTypes.js';
2+
import {BANNER, VIDEO, NATIVE} from '../src/mediaTypes.js';
33
import {isStr, isEmpty, deepAccess, getUnixTimestampFromNow, convertObjectToArray, getWindowTop} from '../src/utils.js';
44
import { config } from '../src/config.js';
55
import { getStorageManager } from '../src/storageManager.js';
@@ -12,7 +12,7 @@ const BIDDER_CODE_DEAL_ALIASES = [1, 2, 3, 4, 5].map(num => {
1212
const ENDPOINT_URL = 'https://ads.adnuntius.delivery/i';
1313
const ENDPOINT_URL_EUROPE = 'https://europe.delivery.adnuntius.com/i';
1414
const GVLID = 855;
15-
const SUPPORTED_MEDIA_TYPES = [BANNER, VIDEO];
15+
const SUPPORTED_MEDIA_TYPES = [BANNER, VIDEO, NATIVE];
1616
const MAXIMUM_DEALS_LIMIT = 5;
1717
const VALID_BID_TYPES = ['netBid', 'grossBid'];
1818
const METADATA_KEY = 'adn.metaData';
@@ -319,6 +319,9 @@ export const spec = {
319319
const adUnit = {...bidTargeting, auId: bid.params.auId, targetId: targetId};
320320
if (mediaType === VIDEO) {
321321
adUnit.adType = 'VAST';
322+
} else if (mediaType === NATIVE) {
323+
adUnit.adType = 'NATIVE';
324+
adUnit.nativeRequest = mediaTypeData.ortb;
322325
}
323326
const maxDeals = Math.max(0, Math.min(bid.params.maxDeals || 0, MAXIMUM_DEALS_LIMIT));
324327
if (maxDeals > 0) {
@@ -391,10 +394,13 @@ export const spec = {
391394
const isDeal = dealCount > 0;
392395
const renderSource = isDeal ? ad : adUnit;
393396
if (renderSource.vastXml) {
394-
adResponse.vastXml = renderSource.vastXml
395-
adResponse.mediaType = VIDEO
397+
adResponse.vastXml = renderSource.vastXml;
398+
adResponse.mediaType = VIDEO;
399+
} else if (renderSource.nativeJson) {
400+
adResponse.mediaType = NATIVE;
401+
adResponse.native = renderSource.nativeJson;
396402
} else {
397-
adResponse.ad = renderSource.html
403+
adResponse.ad = renderSource.html;
398404
}
399405
return adResponse;
400406
}

‎modules/airgridRtdProvider.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {MODULE_TYPE_RTD} from '../src/activities/modules.js';
1717

1818
const MODULE_NAME = 'realTimeData';
1919
const SUBMODULE_NAME = 'airgrid';
20-
const AG_TCF_ID = 782;
20+
const MIQ_TCF_ID = 101;
2121
export const AG_AUDIENCE_IDS_KEY = 'edkt_matched_audience_ids';
2222

2323
export const storage = getStorageManager({
@@ -76,7 +76,7 @@ export function setAudiencesAsBidderOrtb2(bidConfig, rtdConfig, audiences) {
7676

7777
const agUserData = [
7878
{
79-
id: String(AG_TCF_ID),
79+
id: String(MIQ_TCF_ID),
8080
ext: {
8181
segtax: 540,
8282
},
@@ -129,7 +129,7 @@ export const airgridSubmodule = {
129129
name: SUBMODULE_NAME,
130130
init: init,
131131
getBidRequestData: passAudiencesToBidders,
132-
gvlid: AG_TCF_ID
132+
gvlid: MIQ_TCF_ID
133133
};
134134

135135
submodule(MODULE_NAME, airgridSubmodule);

‎modules/appnexusBidAdapter.js

+16-11
Original file line numberDiff line numberDiff line change
@@ -354,18 +354,23 @@ export const spec = {
354354

355355
if (bidRequests[0].userId) {
356356
let eids = [];
357-
bidRequests[0].userIdAsEids.forEach(eid => {
358-
if (!eid || !eid.uids || eid.uids.length < 1) { return; }
359-
eid.uids.forEach(uid => {
360-
let tmp = {'source': eid.source, 'id': uid.id};
361-
if (eid.source == 'adserver.org') {
362-
tmp.rti_partner = 'TDID';
363-
} else if (eid.source == 'uidapi.com') {
364-
tmp.rti_partner = 'UID2';
365-
}
366-
eids.push(tmp);
357+
const processEids = (uids) => {
358+
uids.forEach(eid => {
359+
if (!eid || !eid.uids || eid.uids.length < 1) { return; }
360+
eid.uids.forEach(uid => {
361+
let tmp = {'source': eid.source, 'id': uid.id};
362+
if (eid.source == 'adserver.org') {
363+
tmp.rti_partner = 'TDID';
364+
} else if (eid.source == 'uidapi.com') {
365+
tmp.rti_partner = 'UID2';
366+
}
367+
eids.push(tmp);
368+
});
367369
});
368-
});
370+
}
371+
if (bidRequests[0].userIdAsEids) {
372+
processEids(bidRequests[0].userIdAsEids);
373+
}
369374
if (eids.length) {
370375
payload.eids = eids;
371376
}

‎modules/conceptxBidAdapter.js

+3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ export const spec = {
5757
return bidResponses
5858
}
5959
const firstSeat = firstBid.ads[0]
60+
if (!firstSeat) {
61+
return bidResponses
62+
}
6063
const bidResponse = {
6164
requestId: firstSeat.requestId,
6265
cpm: firstSeat.cpm,

‎modules/magniteAnalyticsAdapter.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,8 @@ export const parseBidResponse = (bid, previousBidResponse) => {
264264
return pick(bid, [
265265
'bidPriceUSD', () => responsePrice,
266266
'dealId', dealId => dealId || undefined,
267-
'mediaType',
267+
'mediaType', () => bid?.meta?.mediaType ?? bid.mediaType,
268+
'ogMediaType', () => bid?.meta?.mediaType && bid.mediaType !== bid?.meta?.mediaType ? bid.mediaType : undefined,
268269
'dimensions', () => {
269270
const width = bid.width || bid.playerWidth;
270271
const height = bid.height || bid.playerHeight;

0 commit comments

Comments
 (0)
Failed to load comments.