diff --git a/modules/openxBidAdapter.js b/modules/openxBidAdapter.js
index ba3bc98b766..cd5bcef36ad 100644
--- a/modules/openxBidAdapter.js
+++ b/modules/openxBidAdapter.js
@@ -8,7 +8,7 @@ import {parse} from 'src/url';
const SUPPORTED_AD_TYPES = [BANNER, VIDEO];
const BIDDER_CODE = 'openx';
const BIDDER_CONFIG = 'hb_pb';
-const BIDDER_VERSION = '2.1.2';
+const BIDDER_VERSION = '2.1.3';
let shouldSendBoPixel = true;
@@ -20,8 +20,8 @@ export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: SUPPORTED_AD_TYPES,
isBidRequestValid: function (bidRequest) {
- if (bidRequest.mediaTypes && bidRequest.mediaTypes.banner) {
- return !!((bidRequest.params.unit || bidRequest.params.placementId) && bidRequest.params.delDomain);
+ if (utils.deepAccess(bidRequest, 'mediaTypes.banner') && bidRequest.params.delDomain) {
+ return !!bidRequest.params.unit || utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes.length') > 0;
}
return !!(bidRequest.params.unit && bidRequest.params.delDomain);
@@ -223,16 +223,20 @@ function buildOXBannerRequest(bids, bidderRequest) {
let hasCustomParam = false;
let queryParams = buildCommonQueryParamsFromBids(bids, bidderRequest);
let auids = utils._map(bids, bid => bid.params.unit);
- let pids = utils._map(bids, bid => bid.params.placementId);
queryParams.aus = utils._map(bids, bid => utils.parseSizesInput(bid.sizes).join(',')).join('|');
queryParams.bc = bids[0].params.bc || `${BIDDER_CONFIG}_${BIDDER_VERSION}`;
- queryParams.divs = utils._map(bids, bid => bid.adUnitCode).join(',');
+ queryParams.divIds = utils._map(bids, bid => encodeURIComponent(bid.adUnitCode)).join(',');
if (auids.some(auid => auid)) {
queryParams.auid = auids.join(',');
}
- if (pids.some(pid => pid)) {
- queryParams.pids = pids.join(',');
+
+ if (bids.some(bid => bid.params.doNotTrack)) {
+ queryParams.ns = 1;
+ }
+
+ if (bids.some(bid => bid.params.coppa)) {
+ queryParams.tfcd = 1;
}
bids.forEach(function (bid) {
diff --git a/modules/openxBidAdapter.md b/modules/openxBidAdapter.md
index a7a39a8412e..243b2e53104 100644
--- a/modules/openxBidAdapter.md
+++ b/modules/openxBidAdapter.md
@@ -10,46 +10,88 @@ Maintainer: team-openx@openx.com
Module that connects to OpenX's demand sources
-# Test Parameters
-```
- var adUnits = [
- {
- code: 'test-div',
- sizes: [[728, 90]], // a display size
- mediaTypes: {'banner': {}},
- bids: [
- {
- bidder: 'openx',
- params: {
- placementId: '/123/abcdefg'
- unit: '539439964',
- delDomain: 'se-demo-d.openx.net'
- }
- }
- ]
- },
- {
- code: 'video1',
- sizes: [[640,480]],
- mediaTypes: {'video': {}},
- bids: [
- {
- bidder: 'openx',
- params: {
- unit: '539131525',
- delDomain: 'zdo.com',
- video: {
- url: 'abc.com'
- }
- }
- }
- ]
+# Bid Parameters
+## Banner
+
+| Name | Scope | Type | Description | Example
+| ---- | ----- | ---- | ----------- | -------
+| `delDomain` | required | String | OpenX delivery domain provided by your OpenX representative. | "PUBLISHER-d.openx.net"
+| `unit` | required | String | OpenX ad unit ID provided by your OpenX representative. | "1611023122"
+| `customParams` | optional | Object | User-defined targeting key-value pairs. customParams applies to a specific unit. | `{key1: "v1", key2: ["v2","v3"]}`
+| `customFloor` | optional | Number | Minimum price in USD. customFloor applies to a specific unit. For example, use the following value to set a $1.50 floor: 1.50
**WARNING:**
Misuse of this parameter can impact revenue | 1.50
+| `doNotTrack` | optional | Boolean | Prevents advertiser from using data for this user.
**WARNING:**
Request-level setting. May impact revenue. | true
+| `coppa` | optional | Boolean | Enables Child's Online Privacy Protection Act (COPPA) regulations. | true
+
+## Video
+
+| Name | Scope | Type | Description | Example
+| ---- | ----- | ---- | ----------- | -------
+| `unit` | required | String | OpenX ad unit ID provided by your OpenX representative. | "1611023122"
+| `delDomain` | required | String | OpenX delivery domain provided by your OpenX representative. | "PUBLISHER-d.openx.net"
+| `openrtb` | optional | OpenRTB Impression | An OpenRtb Impression with Video subtype properties | `{ imp: [{ video: {mimes: ['video/x-ms-wmv, video/mp4']} }] }`
+
+
+# Example
+```javascript
+var adUnits = [
+ {
+ code: 'test-div',
+ sizes: [[728, 90]], // a display size
+ mediaTypes: {'banner': {}},
+ bids: [
+ {
+ bidder: 'openx',
+ params: {
+ unit: '539439964',
+ delDomain: 'se-demo-d.openx.net',
+ customParams: {
+ key1: 'v1',
+ key2: ['v2', 'v3']
+ },
+ }
+ }
+ ]
+ },
+ {
+ code: 'video1',
+ mediaTypes: {
+ video: {
+ playerSize: [640, 480],
+ context: 'instream'
+ }
+ },
+ bids: [{
+ bidder: 'openx',
+ params: {
+ unit: '1611023124',
+ delDomain: 'PUBLISHER-d.openx.net',
+ openrtb: {
+ imp: [{
+ video: {
+ mimes: ['video/x-ms-wmv, video/mp4']
+ }
+ }]
}
- ];
+ }
+ }]
+ }
+];
```
+# Configuration
+Add the following code to enable user syncing. By default, Prebid.js version 0.34.0+ turns off user syncing through iframes.
+OpenX strongly recommends enabling user syncing through iframes. This functionality improves DSP user match rates and increases the
+OpenX bid rate and bid price. Be sure to call `pbjs.setConfig()` only once.
+
+```javascript
+pbjs.setConfig({
+ userSync: {
+ iframeEnabled: true
+ }
+});
+```
-# Links
+# Additional Details
[Banner Ads](https://docs.openx.com/Content/developers/containers/prebid-adapter.html)
[Video Ads](https://docs.openx.com/Content/developers/containers/prebid-video-adapter.html)
diff --git a/test/spec/modules/openxBidAdapter_spec.js b/test/spec/modules/openxBidAdapter_spec.js
index 7f9cac405c3..c0588f2eff0 100644
--- a/test/spec/modules/openxBidAdapter_spec.js
+++ b/test/spec/modules/openxBidAdapter_spec.js
@@ -153,7 +153,7 @@ describe('OpenxAdapter', () => {
bannerBid.params = {delDomain: 'test-delivery-domain'}
});
- it('should return false when there is no ad unit id and no placement id', () => {
+ it('should return false when there is no ad unit id and size', () => {
expect(spec.isBidRequestValid(bannerBid)).to.equal(false);
});
@@ -162,10 +162,19 @@ describe('OpenxAdapter', () => {
expect(spec.isBidRequestValid(bannerBid)).to.equal(true);
});
- it('should return true if there is an placement id ', () => {
- bannerBid.params.placementId = '/12345678/aaaa/bbbb';
+ it('should return true if there is no adunit id and sizes are defined', () => {
+ bannerBid.mediaTypes.banner.sizes = [720, 90];
expect(spec.isBidRequestValid(bannerBid)).to.equal(true);
});
+
+ it('should return false if no sizes are defined ', () => {
+ expect(spec.isBidRequestValid(bannerBid)).to.equal(false);
+ });
+
+ it('should return false if sizes empty ', () => {
+ bannerBid.mediaTypes.banner.sizes = [];
+ expect(spec.isBidRequestValid(bannerBid)).to.equal(false);
+ });
});
});
@@ -245,7 +254,7 @@ describe('OpenxAdapter', () => {
'unit': '11',
'delDomain': 'test-del-domain'
},
- 'adUnitCode': 'adunit-code',
+ 'adUnitCode': '/adunit-code/test-path',
mediaTypes: {
banner: {
sizes: [[300, 250], [300, 600]]
@@ -285,11 +294,11 @@ describe('OpenxAdapter', () => {
it('should send the adunit codes', () => {
const request = spec.buildRequests(bidRequestsWithMediaTypes);
- expect(request[0].data.divs).to.equal(`${bidRequestsWithMediaTypes[0].adUnitCode},${bidRequestsWithMediaTypes[1].adUnitCode}`);
+ expect(request[0].data.divIds).to.equal(`${encodeURIComponent(bidRequestsWithMediaTypes[0].adUnitCode)},${encodeURIComponent(bidRequestsWithMediaTypes[1].adUnitCode)}`);
});
it('should send ad unit ids when any are defined', () => {
- const bidRequestsWithPlacementIds = [{
+ const bidRequestsWithUnitIds = [{
'bidder': 'openx',
'params': {
'delDomain': 'test-del-domain'
@@ -319,12 +328,12 @@ describe('OpenxAdapter', () => {
'bidderRequestId': 'test-bid-request-2',
'auctionId': 'test-auction-2'
}];
- const request = spec.buildRequests(bidRequestsWithPlacementIds);
- expect(request[0].data.auid).to.equal(`,${bidRequestsWithPlacementIds[1].params.unit}`);
+ const request = spec.buildRequests(bidRequestsWithUnitIds);
+ expect(request[0].data.auid).to.equal(`,${bidRequestsWithUnitIds[1].params.unit}`);
});
it('should not send any ad unit ids when none are defined', () => {
- const bidRequestsWithoutPlacementIds = [{
+ const bidRequestsWithoutUnitIds = [{
'bidder': 'openx',
'params': {
'delDomain': 'test-del-domain'
@@ -353,83 +362,10 @@ describe('OpenxAdapter', () => {
'bidderRequestId': 'test-bid-request-2',
'auctionId': 'test-auction-2'
}];
- const request = spec.buildRequests(bidRequestsWithoutPlacementIds);
+ const request = spec.buildRequests(bidRequestsWithoutUnitIds);
expect(request[0].data).to.not.have.any.keys('auid');
});
- it('should send placement ids when any are defined', () => {
- const bidRequestsWithPlacementIds = [{
- 'bidder': 'openx',
- 'params': {
- 'unit': '11',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- 'bidId': 'test-bid-id-1',
- 'bidderRequestId': 'test-bid-request-1',
- 'auctionId': 'test-auction-1'
- }, {
- 'bidder': 'openx',
- 'params': {
- 'unit': '22',
- 'delDomain': 'test-del-domain',
- placementId: 'test-placement-id-2'
- },
- 'adUnitCode': 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[728, 90]]
- }
- },
- 'bidId': 'test-bid-id-2',
- 'bidderRequestId': 'test-bid-request-2',
- 'auctionId': 'test-auction-2'
- }];
- const request = spec.buildRequests(bidRequestsWithPlacementIds);
- expect(request[0].data.pids).to.equal(`,${bidRequestsWithPlacementIds[1].params.placementId}`);
- });
-
- it('should not send any placement ids when none are defined', () => {
- const bidRequestsWithoutPlacementIds = [{
- 'bidder': 'openx',
- 'params': {
- 'unit': '11',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- 'bidId': 'test-bid-id-1',
- 'bidderRequestId': 'test-bid-request-1',
- 'auctionId': 'test-auction-1'
- }, {
- 'bidder': 'openx',
- 'params': {
- 'unit': '22',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[728, 90]]
- }
- },
- 'bidId': 'test-bid-id-2',
- 'bidderRequestId': 'test-bid-request-2',
- 'auctionId': 'test-auction-2'
- }];
- const request = spec.buildRequests(bidRequestsWithoutPlacementIds);
- expect(request[0].data).to.not.have.any.keys('pids');
- });
-
describe('when there is a legacy request with no media type', function () {
const deprecatedBidRequestsFormatWithNoMediaType = [{
'bidder': 'openx',
@@ -695,6 +631,156 @@ describe('OpenxAdapter', () => {
});
});
});
+
+ it('should not send a coppa query param when there are no coppa param settings in the bid requests', () => {
+ const bidRequestsWithoutCoppa = [{
+ bidder: 'openx',
+ params: {
+ unit: '11',
+ delDomain: 'test-del-domain',
+ coppa: false
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300, 600]]
+ }
+ },
+ bidId: 'test-bid-id-1',
+ bidderRequestId: 'test-bid-request-1',
+ auctionId: 'test-auction-1'
+ }, {
+ bidder: 'openx',
+ params: {
+ unit: '22',
+ delDomain: 'test-del-domain'
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ banner: {
+ sizes: [[728, 90]]
+ }
+ },
+ bidId: 'test-bid-id-2',
+ bidderRequestId: 'test-bid-request-2',
+ auctionId: 'test-auction-2'
+ }];
+ const request = spec.buildRequests(bidRequestsWithoutCoppa);
+ expect(request[0].data).to.not.have.any.keys('tfcd');
+ });
+
+ it('should send a coppa flag there is when there is coppa param settings in the bid requests', () => {
+ const bidRequestsWithCoppa = [{
+ bidder: 'openx',
+ params: {
+ unit: '11',
+ delDomain: 'test-del-domain',
+ coppa: false
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300, 600]]
+ }
+ },
+ bidId: 'test-bid-id-1',
+ bidderRequestId: 'test-bid-request-1',
+ auctionId: 'test-auction-1'
+ }, {
+ bidder: 'openx',
+ params: {
+ unit: '22',
+ delDomain: 'test-del-domain',
+ coppa: true
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ banner: {
+ sizes: [[728, 90]]
+ }
+ },
+ bidId: 'test-bid-id-2',
+ bidderRequestId: 'test-bid-request-2',
+ auctionId: 'test-auction-2'
+ }];
+ const request = spec.buildRequests(bidRequestsWithCoppa);
+ expect(request[0].data.tfcd).to.equal(1);
+ });
+
+ it('should not send a "no segmentation" flag there no DoNotTrack setting that is set to true', () => {
+ const bidRequestsWithoutDnt = [{
+ bidder: 'openx',
+ params: {
+ unit: '11',
+ delDomain: 'test-del-domain',
+ doNotTrack: false
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300, 600]]
+ }
+ },
+ bidId: 'test-bid-id-1',
+ bidderRequestId: 'test-bid-request-1',
+ auctionId: 'test-auction-1'
+ }, {
+ bidder: 'openx',
+ params: {
+ unit: '22',
+ delDomain: 'test-del-domain'
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ banner: {
+ sizes: [[728, 90]]
+ }
+ },
+ bidId: 'test-bid-id-2',
+ bidderRequestId: 'test-bid-request-2',
+ auctionId: 'test-auction-2'
+ }];
+ const request = spec.buildRequests(bidRequestsWithoutDnt);
+ expect(request[0].data).to.not.have.any.keys('ns');
+ });
+
+ it('should send a "no segmentation" flag there is any DoNotTrack setting that is set to true', () => {
+ const bidRequestsWithDnt = [{
+ bidder: 'openx',
+ params: {
+ unit: '11',
+ delDomain: 'test-del-domain',
+ doNotTrack: false
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300, 600]]
+ }
+ },
+ bidId: 'test-bid-id-1',
+ bidderRequestId: 'test-bid-request-1',
+ auctionId: 'test-auction-1'
+ }, {
+ bidder: 'openx',
+ params: {
+ unit: '22',
+ delDomain: 'test-del-domain',
+ doNotTrack: true
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ banner: {
+ sizes: [[728, 90]]
+ }
+ },
+ bidId: 'test-bid-id-2',
+ bidderRequestId: 'test-bid-request-2',
+ auctionId: 'test-auction-2'
+ }];
+ const request = spec.buildRequests(bidRequestsWithDnt);
+ expect(request[0].data.ns).to.equal(1);
+ });
});
describe('buildRequests for video', () => {