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

Vertamedia Adapter for 1.0 #1789

Merged
merged 21 commits into from
Nov 8, 2017
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
220 changes: 113 additions & 107 deletions modules/vertamediaBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,119 +1,125 @@
import Adapter from 'src/adapter';
import bidfactory from 'src/bidfactory';
import bidmanager from 'src/bidmanager';
import * as utils from 'src/utils';
import { ajax } from 'src/ajax';
import { STATUS } from 'src/constants';
import adaptermanager from 'src/adaptermanager';

const ENDPOINT = '//rtb.vertamedia.com/hb/';

function VertamediaAdapter() {
const baseAdapter = new Adapter('vertamedia');
let bidRequest;

baseAdapter.callBids = function (bidRequests) {
if (!bidRequests || !bidRequests.bids || bidRequests.bids.length === 0) {
return;
}

var RTBDataParams = prepareAndSaveRTBRequestParams(bidRequests.bids[0]);

if (!RTBDataParams) {
return;
}

ajax(ENDPOINT, handleResponse, RTBDataParams, {
contentType: 'text/plain',
withCredentials: true,
method: 'GET'
import {registerBidder} from 'src/adapters/bidderFactory';
import {VIDEO} from 'src/mediaTypes';

const URL = '//rtb.vertamedia.com/hb/';
const BIDDER_CODE = 'vertamedia';

export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: [VIDEO],
isBidRequestValid: function (bid) {
return Boolean(bid && bid.params && bid.params.aid);
},

/**
* Make a server request from the list of BidRequests
* @param bidRequests
* @param bidderRequest
*/
buildRequests: function (bidRequests, bidderRequest) {
return bidRequests.map((bid) => {
return {
data: prepareRTBRequestParams(bid),
contentType: 'text/plain',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contentType is text/plain by default and withCrendentials is also set to true.
Both can be removed from here.

withCredentials: true,
bidderRequest,
method: 'GET',
url: URL
}
});
};

function prepareAndSaveRTBRequestParams(bid) {
if (!bid || !bid.params || !bid.params.aid || !bid.placementCode) {
return;
},

/**
* Unpack the response from the server into a list of bids
* @param serverResponse
* @param bidderRequest
* @return {Bid[]} An array of bids which were nested inside the server
*/
interpretResponse: function (serverResponse, {bidderRequest}) {
serverResponse = serverResponse.body;
const isInvalidValidResp = !serverResponse || !serverResponse.bids || !serverResponse.bids.length;
let bids = [];

if (isInvalidValidResp) {
let extMessage = serverResponse && serverResponse.ext && serverResponse.ext.message ? `: ${serverResponse.ext.message}` : '';
let errorMessage = `in response for ${bidderRequest.bidderCode} adapter ${extMessage}`;

utils.logError(errorMessage);

return bids;
}

bidRequest = bid;

let size = getSize(bid.sizes);

bidRequest.width = size.width;
bidRequest.height = size.height;

return {
aid: bid.params.aid,
w: size.width,
h: size.height,
domain: document.location.hostname
};
}

function getSize(requestSizes) {
const parsed = {};
const size = utils.parseSizesInput(requestSizes)[0];

if (typeof size !== 'string') {
return parsed;
}

let parsedSize = size.toUpperCase().split('X');

return {
width: parseInt(parsedSize[0], 10) || undefined,
height: parseInt(parsedSize[1], 10) || undefined
};
}

/* Notify Prebid of bid responses so bids can get in the auction */
function handleResponse(response) {
var parsed;

try {
parsed = JSON.parse(response);
} catch (error) {
utils.logError(error);
}

if (!parsed || parsed.error || !parsed.bids || !parsed.bids.length) {
bidmanager.addBidResponse(bidRequest.placementCode, createBid(STATUS.NO_BID));
serverResponse.bids.forEach(serverBid => {
if (serverBid.cpm !== 0) {
const bid = createBid(serverBid, bidderRequest);
bids.push(bid);
}
});

return;
}
return bids;
},
};

/**
* Prepare all parameters for request
* @param bid {object}
* @returns {object}
*/
function prepareRTBRequestParams(bid) {
let size = getSize(bid.sizes);

return {
domain: utils.getTopWindowLocation().hostname,
callbackId: bid.bidId,
aid: bid.params.aid,
h: size.height,
w: size.width
};
}

bidmanager.addBidResponse(bidRequest.placementCode, createBid(STATUS.GOOD, parsed.bids[0]));
/**
* Prepare size for request
* @param requestSizes {array}
* @returns {object} bid The bid to validate
*/
function getSize(requestSizes) {
const size = utils.parseSizesInput(requestSizes)[0];
const parsed = {};

if (typeof size !== 'string') {
return parsed;
}

function createBid(status, tag) {
var bid = bidfactory.createBid(status, tag);
let parsedSize = size.toUpperCase().split('X');

bid.code = baseAdapter.getBidderCode();
bid.bidderCode = bidRequest.bidder;

if (!tag || status !== STATUS.GOOD) {
return bid;
}

bid.mediaType = 'video';
bid.cpm = tag.cpm;
bid.creative_id = tag.cmpId;
bid.width = bidRequest.width;
bid.height = bidRequest.height;
bid.descriptionUrl = tag.url;
bid.vastUrl = tag.url;

return bid;
}

return Object.assign(this, {
callBids: baseAdapter.callBids,
setBidderCode: baseAdapter.setBidderCode
});
return {
height: parseInt(parsedSize[1], 10) || undefined,
width: parseInt(parsedSize[0], 10) || undefined
};
}

adaptermanager.registerBidAdapter(new VertamediaAdapter(), 'vertamedia', {
supportedMediaTypes: ['video']
});
/**
* Configure new bid by response
* @param bidRequest {object}
* @param bidResponse {object}
* @returns {object}
*/
function createBid(bidResponse, bidRequest) {
return {
bidderCode: bidRequest.bidderCode,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bidderCode will be set by bidderFactory. Can be removed from here.
Also no need to add descriptionUrl

requestId: bidResponse.requestId,
descriptionUrl: bidResponse.url,
creativeId: bidResponse.cmpId,
vastUrl: bidResponse.vastUrl,
height: bidResponse.height,
currency: bidResponse.cur,
width: bidResponse.width,
cpm: bidResponse.cpm,
mediaType: 'video',
netRevenue: true,
ttl: 3600
};
}

module.exports = VertamediaAdapter;
registerBidder(spec);
26 changes: 26 additions & 0 deletions modules/vertamediaBidAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Overview

**Module Name**: VertaMedia Bidder Adapter
**Module Type**: Bidder Adapter
**Maintainer**: [email protected]

# Description

Get access to multiple demand partners across VertaMedia AdExchange and maximize your yield with VertaMedia header bidding adapter.

VertaMedia header bidding adapter connects with VertaMedia demand sources in order to fetch bids.
This adapter provides a solution for accessing Video demand


# Test Parameters
```
var adUnits = [{
code: 'div-test-div',
sizes: [[640, 480]], // ad size
bids: [{
bidder: 'vertamedia', // adapter name
params: {
aid: 332842
}
}]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}] missing at the end.

```
Loading