Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HB-2148 PBS Adapter support bidder specific options #25

Closed
89 changes: 89 additions & 0 deletions modules/appierBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { registerBidder } from 'src/adapters/bidderFactory';
import { BANNER } from 'src/mediaTypes';
import { config } from 'src/config';

export const ADAPTER_VERSION = '1.0.0';
const SUPPORTED_AD_TYPES = [BANNER];

// we have different servers for different regions / farms
export const API_SERVERS_MAP = {
'default': 'ad2.apx.appier.net',
'tw': 'ad2.apx.appier.net',
'jp': 'ad-jp.apx.appier.net'
};

const BIDDER_API_ENDPOINT = '/v1/prebid/bid';

export const spec = {
code: 'appier',
supportedMediaTypes: SUPPORTED_AD_TYPES,

/**
* Determines whether or not the given bid request is valid.
*
* @param {BidRequest} bid The bid params to validate.
* @return boolean True if this is a valid bid, and false otherwise.
*/
isBidRequestValid: function (bid) {
return typeof bid.params.hzid === 'string';
},

/**
* Make a server request from the list of BidRequests.
*
* @param {bidRequests[]} - an array of bids
* @return ServerRequest Info describing the request to the server.
*/
buildRequests: function (bidRequests, bidderRequest) {
if (bidRequests.length === 0) {
return [];
}
const server = this.getApiServer();
const bidderApiUrl = `//${server}${BIDDER_API_ENDPOINT}`
const payload = {
'bids': bidRequests,
'refererInfo': bidderRequest.refererInfo,
'version': ADAPTER_VERSION
};
return [{
method: 'POST',
url: bidderApiUrl,
data: payload,
// keep the bidder request object for later use
bidderRequest: bidderRequest
}];
},

/**
* Unpack the response from the server into a list of bids.
*
* @param {serverResponse} serverResponse A successful response from the server.
* @return {Bid[]} An array of bids which were nested inside the server.
*/
interpretResponse: function (serverResponse, serverRequest) {
if (!Array.isArray(serverResponse.body)) {
return [];
}
// server response body is an array of bid results
const bidResults = serverResponse.body;
// our server directly returns the format needed by prebid.js so no more
// transformation is needed here.
return bidResults;
},

/**
* Get the hostname of the server we want to use.
*/
getApiServer() {
// we may use different servers for different farms (geographical regions)
// if a server is specified explicitly, use it. otherwise, use farm specific server.
let server = config.getConfig('appier.server');
if (!server) {
const farm = config.getConfig('appier.farm');
server = API_SERVERS_MAP[farm] || API_SERVERS_MAP['default'];
}
return server;
}
};

registerBidder(spec);
57 changes: 57 additions & 0 deletions modules/appierBidAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Overview

```
Module Name: Appier Bid Adapter
Module Type: Bidder Adapter
Maintainer: apn-dev@appier.com
```

# Description

Connects to Appier exchange for bids.

NOTE:
- Appier bid adapter only supports Banner at the moment.
- Multi-currency is not supported. Please make sure you have correct DFP currency settings according to your deal with Appier.

# Sample Ad Unit Config
```
var adUnits = [
// Banner adUnit
{
code: 'banner-div',
mediaTypes: {
banner: {
sizes: [[300, 250], [300,600]]
}
},
bids: [{
bidder: 'appier',
params: {
hzid: 'WhM5WIOp'
}
}]
}
];
```

# Additional Config (Optional)
Set the "farm" to use region-specific server
```
// use the bid server in Taiwan (country code: tw)
pbjs.setConfig({
appier: {
'farm': 'tw'
}
});
```

Explicitly override the bid server used for bidding
```
// use the bid server specified and override the default
pbjs.setConfig({
appier: {
'server': '${HOST_NAME_OF_THE_SERVER}'
}
});
```
6 changes: 5 additions & 1 deletion modules/conversantBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export const spec = {
siteId = utils.getBidIdParameter('site_id', bid.params);
requestId = bid.auctionId;

const format = convertSizes(bid.sizes);
let format = convertSizes(bid.sizes);

const imp = {
id: bid.bidId,
Expand All @@ -75,6 +75,10 @@ export const spec = {
copyOptProperty(bid.params, 'tag_id', imp, 'tagid');

if (isVideoRequest(bid)) {
if (bid.mediaTypes.video.playerSize) {
format = convertSizes(bid.mediaTypes.video.playerSize);
}

const video = {
w: format[0].w,
h: format[0].h
Expand Down
5 changes: 3 additions & 2 deletions modules/conversantBidAdapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ var adUnits = [
sizes: [640, 480],
mediaTypes: {
video: {
context: 'instream'
context: 'instream',
playerSize: [640, 480]
}
},
bids: [{
Expand All @@ -38,4 +39,4 @@ var adUnits = [
}
}]
}];
```
```
1 change: 0 additions & 1 deletion modules/oneVideoBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ export const spec = {
method: 'POST',
url: location.protocol + spec.ENDPOINT + bid.params.pubId,
data: getRequestData(bid, consentData),
options: {contentType: 'application/json'},
bidRequest: bid
}
})
Expand Down
4 changes: 3 additions & 1 deletion modules/openxBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,10 @@ function buildOXBannerRequest(bids, bidderRequest) {
}

function buildOXVideoRequest(bid, bidderRequest) {
let url = `//${bid.params.delDomain}/v/1.0/avjp`;
let oxVideoParams = generateVideoParameters(bid, bidderRequest);
let url = oxVideoParams.ph
? `//u.openx.net/v/1.0/avjp`
: `//${bid.params.delDomain}/v/1.0/avjp`;
return {
method: 'GET',
url: url,
Expand Down
5 changes: 4 additions & 1 deletion modules/prebidServerBidAdapter/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export const S2S_VENDORS = {
enabled: true,
endpoint: '//prebid-server.rubiconproject.com/openrtb2/auction',
syncEndpoint: '//prebid-server.rubiconproject.com/cookie_sync',
timeout: 500
timeout: 500,
adapterOptions: {
rubicon: { singleRequest: false }
}
}
}
34 changes: 32 additions & 2 deletions modules/prebidServerBidAdapter/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,39 @@ const DEFAULT_S2S_NETREVENUE = true;

let _s2sConfig;

/**
* @typedef {Object} AdapterOptions
* @summary s2sConfig parameter that adds arguments to resulting OpenRTB payload that goes to Prebid Server
* @example
* // example of multiple bidder configuration
* pbjs.setConfig({
* s2sConfig: {
* adapterOptions: {
* rubicon: {singleRequest: false}
* appnexus: {key: "value"}
* }
* }
* });
*/

/**
* @typedef {Object} S2SDefaultConfig
* @property {boolean} enabled
* @property {number} timeout
* @property {number} maxBids
* @property {string} adapter
* @property {AdapterOptions} adapterOptions
*/

/**
* @type {S2SDefaultConfig}
*/
const s2sDefaultConfig = {
enabled: false,
timeout: 1000,
maxBids: 1,
adapter: 'prebidServer'
adapter: 'prebidServer',
adapterOptions: {}
};

config.setDefaults({
Expand All @@ -43,6 +71,8 @@ config.setDefaults({
* @property {boolean} [cacheMarkup] whether to cache the adm result
* @property {string} [adapter] adapter code to use for S2S
* @property {string} [syncEndpoint] endpoint URL for syncing cookies
* @property {string} [cookieSetUrl] url for cookie set library, if passed then cookieSet is enabled
* @property {AdapterOptions} [adapterOptions] adds arguments to resulting OpenRTB payload to Prebid Server
*/
function setS2sConfig(options) {
if (options.defaultVendor) {
Expand Down Expand Up @@ -415,7 +445,7 @@ const OPEN_RTB_PROTOCOL = {
if (adapter && adapter.getSpec().transformBidParams) {
bid.params = adapter.getSpec().transformBidParams(bid.params, isOpenRtb());
}
acc[bid.bidder] = bid.params;
acc[bid.bidder] = (_s2sConfig.adapterOptions && _s2sConfig.adapterOptions[bid.bidder]) ? Object.assign({}, bid.params, _s2sConfig.adapterOptions[bid.bidder]) : bid.params;
return acc;
}, {});

Expand Down
2 changes: 2 additions & 0 deletions src/AnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const {
BID_REQUESTED,
BID_TIMEOUT,
BID_RESPONSE,
NO_BID,
BID_WON,
BID_ADJUSTMENT,
BIDDER_DONE,
Expand Down Expand Up @@ -100,6 +101,7 @@ export default function AnalyticsAdapter({ url, analyticsType, global, handler }
_handlers = {
[BID_REQUESTED]: args => this.enqueue({ eventType: BID_REQUESTED, args }),
[BID_RESPONSE]: args => this.enqueue({ eventType: BID_RESPONSE, args }),
[NO_BID]: args => this.enqueue({ eventType: NO_BID, args }),
[BID_TIMEOUT]: args => this.enqueue({ eventType: BID_TIMEOUT, args }),
[BID_WON]: args => this.enqueue({ eventType: BID_WON, args }),
[BID_ADJUSTMENT]: args => this.enqueue({ eventType: BID_ADJUSTMENT, args }),
Expand Down
14 changes: 9 additions & 5 deletions src/adaptermanager.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** @module adaptermanger */

import { flatten, getBidderCodes, getDefinedParams, shuffle, timestamp } from './utils';
import { flatten, getBidderCodes, getDefinedParams, shuffle, timestamp, getBidderRequest } from './utils';
import { getLabels, resolveStatus } from './sizeMapping';
import { processNativeAdUnitParams, nativeAdapters } from './native';
import { newBidder } from './adapters/bidderFactory';
Expand Down Expand Up @@ -340,7 +340,7 @@ exports.callBids = (adUnits, bidRequests, addBidResponse, doneCb, requestCallbac
if (s2sBidRequest.ad_units.length) {
let doneCbs = serverBidRequests.map(bidRequest => {
bidRequest.start = timestamp();
return doneCb;
return doneCb.bind(bidRequest);
});

// only log adapters that actually have adUnit bids
Expand All @@ -360,7 +360,12 @@ exports.callBids = (adUnits, bidRequests, addBidResponse, doneCb, requestCallbac
s2sAdapter.callBids(
s2sBidRequest,
serverBidRequests,
addBidResponse,
function(adUnitCode, bid) {
let bidderRequest = getBidderRequest(serverBidRequests, bid.bidderCode, adUnitCode);
if (bidderRequest) {
addBidResponse.call(bidderRequest, adUnitCode, bid)
}
},
() => doneCbs.forEach(done => done()),
s2sAjax
);
Expand All @@ -375,12 +380,11 @@ exports.callBids = (adUnits, bidRequests, addBidResponse, doneCb, requestCallbac
const adapter = _bidderRegistry[bidRequest.bidderCode];
utils.logMessage(`CALLING BIDDER ======= ${bidRequest.bidderCode}`);
events.emit(CONSTANTS.EVENTS.BID_REQUESTED, bidRequest);
bidRequest.doneCbCallCount = 0;
let ajax = ajaxBuilder(requestBidsTimeout, requestCallbacks ? {
request: requestCallbacks.request.bind(null, bidRequest.bidderCode),
done: requestCallbacks.done
} : undefined);
adapter.callBids(bidRequest, addBidResponse, doneCb, ajax);
adapter.callBids(bidRequest, addBidResponse.bind(bidRequest), doneCb.bind(bidRequest), ajax);
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/adapters/bidderFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export function newBidder(spec) {
// After all the responses have come back, call done() and
// register any required usersync pixels.
const responses = [];
function afterAllResponses(bids) {
function afterAllResponses() {
done();
events.emit(CONSTANTS.EVENTS.BIDDER_DONE, bidderRequest);
registerSyncs(responses, bidderRequest.gdprConsent);
Expand Down
Loading