Skip to content

Commit

Permalink
MobfoxBidAdapter compliant to prebid1.0 (#1757)
Browse files Browse the repository at this point in the history
* Upgrade MobfoxAdapter to be compliant with Prebid 1.0 - missing cpm

* MfBidAdapter changes for preBid1.0

* Upgrade MobfoxAdapter to be compliant with Prebid 1.0 - final version

* removed accidentally added files

* Update MobfoxBidAdapter after review

* Update MobfoxBidAdapter after review - Final

* Add markdown file containing key information about Mobfox adapter

* Fix error field - under request in serverResponse
  • Loading branch information
hadarpeer authored and dbemiller committed Nov 8, 2017
1 parent c0a1f45 commit 9376885
Show file tree
Hide file tree
Showing 3 changed files with 222 additions and 262 deletions.
183 changes: 67 additions & 116 deletions modules/mobfoxBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,25 @@
const bidfactory = require('src/bidfactory.js');
const bidmanager = require('src/bidmanager.js');
const ajax = require('src/ajax.js');
const CONSTANTS = require('src/constants.json');
import {registerBidder} from 'src/adapters/bidderFactory';

const utils = require('src/utils.js');
const adaptermanager = require('src/adaptermanager');

function MobfoxAdapter() {
const BIDDER_CODE = 'mobfox';
const BID_REQUEST_BASE_URL = 'https://my.mobfox.com/request.php';

// request
function buildQueryStringFromParams(params) {
for (let key in params) {
if (params.hasOwnProperty(key)) {
if (params[key] === undefined) {
delete params[key];
} else {
params[key] = encodeURIComponent(params[key]);
}
}
const BIDDER_CODE = 'mobfox';
const BID_REQUEST_BASE_URL = 'https://my.mobfox.com/request.php';
const CPM_HEADER = 'X-Pricing-CPM';

export const spec = {
code: BIDDER_CODE,
aliases: ['mf'], // short code
isBidRequestValid: function (bid) {
return bid.params.s !== null && bid.params.s !== undefined && bid.requestId !== null && bid.requestId !== undefined;
},
buildRequests: function (validBidRequests) {
if (validBidRequests.length > 1) {
throw ('invalid number of valid bid requests, expected 1 element')
}

return utils._map(Object.keys(params), key => `${key}=${params[key]}`)
.join('&');
}

function buildBidRequest(bid) {
let bidParams = bid.params;
let bidParams = validBidRequests[0].params;
let bid = validBidRequests[0];

let requestParams = {
let params = {
// -------------------- Mandatory Parameters ------------------
rt: bidParams.rt || 'api-fetchip',
r_type: bidParams.r_type || 'banner',
Expand Down Expand Up @@ -80,103 +71,63 @@ function MobfoxAdapter() {
n_rating_req: bidParams.n_rating_req || undefined
};

return requestParams;
}
let payloadString = buildPayloadString(params);

function sendBidRequest(bid) {
let requestParams = buildBidRequest(bid);
let queryString = buildQueryStringFromParams(requestParams);

ajax.ajax(`${BID_REQUEST_BASE_URL}?${queryString}`, {
success(resp, xhr) {
if (xhr.getResponseHeader('Content-Type') == 'application/json') {
try {
resp = JSON.parse(resp)
} catch (e) {
resp = {error: resp}
}
}
onBidResponse({
data: resp,
xhr: xhr
}, bid);
},
error(err) {
if (xhr.getResponseHeader('Content-Type') == 'application/json') {
try {
err = JSON.parse(err);
} catch (e) {
}
;
}
onBidResponseError(bid, [err]);
return {
method: 'GET',
url: BID_REQUEST_BASE_URL,
data: payloadString,
requestId: bid.bidId
};
},
interpretResponse: function (serverResponse, bidRequest) {
const bidResponses = [];
let serverResponseBody = serverResponse.body;

if (!serverResponseBody || serverResponseBody.error) {
let errorMessage = `in response for ${BIDDER_CODE} adapter`;
if (serverResponseBody && serverResponseBody.error) {
errorMessage += `: ${serverResponseBody.error}`;
}
});
}

// response
function onBidResponseError(bid, err) {
utils.logError('Bid Response Error', bid, ...err);
let bidResponse = bidfactory.createBid(CONSTANTS.STATUS.NO_BID, bid);
bidResponse.bidderCode = BIDDER_CODE;
bidmanager.addBidResponse(bid.placementCode, bidResponse);
}

function onBidResponse(bidderResponse, bid) {
// transform the response to a valid prebid response
try {
let bidResponse = transformResponse(bidderResponse, bid);
bidmanager.addBidResponse(bid.placementCode, bidResponse);
} catch (e) {
onBidResponseError(bid, [e]);
}
}

function transformResponse(bidderResponse, bid) {
let responseBody = bidderResponse.data;

// Validate Request
let err = responseBody.error;
if (err) {
throw err;
utils.logError(errorMessage);
return bidResponses;
}

let htmlString = responseBody.request && responseBody.request.htmlString;
if (!htmlString) {
throw [`htmlString is missing`, responseBody];
}

let cpm;
const cpmHeader = bidderResponse.xhr.getResponseHeader('X-Pricing-CPM');
try {
cpm = Number(cpmHeader);
let serverResponseHeaders = serverResponse.headers;
let bidRequestData = bidRequest.data.split('&');
const bidResponse = {
requestId: bidRequest.requestId,
cpm: serverResponseHeaders.get(CPM_HEADER),
width: bidRequestData[5].split('=')[1],
height: bidRequestData[6].split('=')[1],
creativeId: bidRequestData[3].split('=')[1],
currency: 'USD',
netRevenue: true,
ttl: 360,
referrer: serverResponseBody.request.clickurl,
ad: serverResponseBody.request.htmlString
};
bidResponses.push(bidResponse);
} catch (e) {
throw ['Invalid CPM value:', cpmHeader];
throw 'could not build bid response: ' + e;
}

// Validations passed - Got bid
let bidResponse = bidfactory.createBid(CONSTANTS.STATUS.GOOD, bid);
bidResponse.bidderCode = BIDDER_CODE;

bidResponse.ad = htmlString;
bidResponse.cpm = cpm;

bidResponse.width = bid.sizes[0][0];
bidResponse.height = bid.sizes[0][1];

return bidResponse;
return bidResponses;
}

// prebid api
function callBids(params) {
let bids = params.bids || [];
bids.forEach(sendBidRequest);
};

function buildPayloadString(params) {
for (let key in params) {
if (params.hasOwnProperty(key)) {
if (params[key] === undefined) {
delete params[key];
} else {
params[key] = encodeURIComponent(params[key]);
}
}
}

return {
callBids: callBids
};
return utils._map(Object.keys(params), key => `${key}=${params[key]}`)
.join('&')
}

adaptermanager.registerBidAdapter(new MobfoxAdapter(), 'mobfox');
module.exports = MobfoxAdapter;
registerBidder(spec);
29 changes: 29 additions & 0 deletions modules/mobfoxBidAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Overview

```
Module Name: Mobfox Bidder Adapter
Module Type: Bidder Adapter
Maintainer: solutions-team@matomy.com
```

# Description

Module that connects to Mobfox's demand sources

# Test Parameters
```
var adUnits = [{
code: 'div-gpt-ad-1460505748561-0',
sizes: [[320, 480], [300, 250], [300,600]],
// Replace this object to test a new Adapter!
bids: [{
bidder: 'mobfox',
params: {
s: "267d72ac3f77a3f447b32cf7ebf20673", // required - The hash of your inventory to identify which app is making the request,
imp_instl: 1 // optional - set to 1 if using interstitial otherwise delete or set to 0
}
}]
}];
```
Loading

0 comments on commit 9376885

Please sign in to comment.