-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Upgrade Quantcast adapter for Prebid 1.0 (#1753)
* Add v1.0 adapter skeleton * Fix a typo in variable name declaration * Change spec dependencies * Add new describes for test * Move URL detechtion inside buildRequests method * Add necessary cases * Clean test cases * Export Quantcast adapter constants * Implemenent test cases * Fix wrong ports number * Correct test cases * Make string with single quote * Remove unused statements * Revert "Remove unused statements" This reverts commit 459ca31. * Remove unused statements * Change string to single quote * Fix sizes type * Fix the sizes propty name typo in the spec * Remove unused method, key value and comments * Update the spec * Change code using single quote * Update the first argument for interpretResponse method and its spec * Handle undefined Server Response * Add required params from the server response
- Loading branch information
1 parent
c5d1ecf
commit 51ffb4e
Showing
3 changed files
with
347 additions
and
294 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,128 +1,165 @@ | ||
const utils = require('src/utils.js'); | ||
const bidfactory = require('src/bidfactory.js'); | ||
const bidmanager = require('src/bidmanager.js'); | ||
const ajax = require('src/ajax.js'); | ||
const CONSTANTS = require('src/constants.json'); | ||
const adaptermanager = require('src/adaptermanager'); | ||
const QUANTCAST_CALLBACK_URL = 'http://global.qc.rtb.quantserve.com:8080/qchb'; | ||
|
||
var QuantcastAdapter = function QuantcastAdapter() { | ||
const BIDDER_CODE = 'quantcast'; | ||
|
||
const DEFAULT_BID_FLOOR = 0.0000000001; | ||
let bidRequests = {}; | ||
|
||
let returnEmptyBid = function(bidId) { | ||
var bidRequested = utils.getBidRequest(bidId); | ||
if (!utils.isEmpty(bidRequested)) { | ||
let bid = bidfactory.createBid(CONSTANTS.STATUS.NO_BID, bidRequested); | ||
bid.bidderCode = BIDDER_CODE; | ||
bidmanager.addBidResponse(bidRequested.placementCode, bid); | ||
import * as utils from 'src/utils'; | ||
import { registerBidder } from 'src/adapters/bidderFactory'; | ||
|
||
const BIDDER_CODE = 'quantcast'; | ||
const DEFAULT_BID_FLOOR = 0.0000000001; | ||
|
||
export const QUANTCAST_CALLBACK_URL = 'global.qc.rtb.quantserve.com'; | ||
export const QUANTCAST_CALLBACK_URL_TEST = 's2s-canary.quantserve.com'; | ||
export const QUANTCAST_NET_REVENUE = true; | ||
export const QUANTCAST_TEST_PUBLISHER = 'test-publisher'; | ||
export const QUANTCAST_TTL = 4; | ||
|
||
/** | ||
* The documentation for Prebid.js Adapter 1.0 can be found at link below, | ||
* http://prebid.org/dev-docs/bidder-adapter-1.html | ||
*/ | ||
export const spec = { | ||
code: BIDDER_CODE, | ||
|
||
/** | ||
* Verify the `AdUnits.bids` response with `true` for valid request and `false` | ||
* for invalid request. | ||
* | ||
* @param {object} bid | ||
* @return boolean `true` is this is a valid bid, and `false` otherwise | ||
*/ | ||
isBidRequestValid(bid) { | ||
if (!bid) { | ||
return false; | ||
} | ||
}; | ||
|
||
// expose the callback to the global object: | ||
$$PREBID_GLOBAL$$.handleQuantcastCB = function (responseText) { | ||
if (utils.isEmpty(responseText)) { | ||
return; | ||
} | ||
let response = null; | ||
try { | ||
response = JSON.parse(responseText); | ||
} catch (e) { | ||
// Malformed JSON | ||
utils.logError("Malformed JSON received from server - can't do anything here"); | ||
return; | ||
} | ||
|
||
if (response === null || !response.hasOwnProperty('bids') || utils.isEmpty(response.bids)) { | ||
utils.logError("Sub-optimal JSON received from server - can't do anything here"); | ||
return; | ||
if (bid.mediaType === 'video') { | ||
return false; | ||
} | ||
|
||
for (let i = 0; i < response.bids.length; i++) { | ||
let seatbid = response.bids[i]; | ||
let key = seatbid.placementCode; | ||
var request = bidRequests[key]; | ||
if (request === null || request === undefined) { | ||
return returnEmptyBid(seatbid.placementCode); | ||
} | ||
// This line is required since this is the field | ||
// that bidfactory.createBid looks for | ||
request.bidId = request.imp[0].placementCode; | ||
let responseBid = bidfactory.createBid(CONSTANTS.STATUS.GOOD, request); | ||
|
||
responseBid.cpm = seatbid.cpm; | ||
responseBid.ad = seatbid.ad; | ||
responseBid.height = seatbid.height; | ||
responseBid.width = seatbid.width; | ||
responseBid.bidderCode = response.bidderCode; | ||
responseBid.requestId = request.requestId; | ||
responseBid.bidderCode = BIDDER_CODE; | ||
|
||
bidmanager.addBidResponse(request.bidId, responseBid); | ||
return true; | ||
}, | ||
|
||
/** | ||
* Make a server request when the page asks Prebid.js for bids from a list of | ||
* `BidRequests`. | ||
* | ||
* @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be send to Quantcast server | ||
* @return ServerRequest information describing the request to the server. | ||
*/ | ||
buildRequests(bidRequests) { | ||
const bids = bidRequests || []; | ||
|
||
const referrer = utils.getTopWindowUrl(); | ||
const loc = utils.getTopWindowLocation(); | ||
const domain = loc.hostname; | ||
|
||
let publisherTagURL; | ||
let publisherTagURLTest; | ||
|
||
// Switch the callback URL to Quantcast Canary Endpoint for testing purpose | ||
// `//` is not used because we have different port setting at our end | ||
switch (window.location.protocol) { | ||
case 'https:': | ||
publisherTagURL = `https://${QUANTCAST_CALLBACK_URL}:8443/qchb`; | ||
publisherTagURLTest = `https://${QUANTCAST_CALLBACK_URL_TEST}:8443/qchb`; | ||
break; | ||
default: | ||
publisherTagURL = `http://${QUANTCAST_CALLBACK_URL}:8080/qchb`; | ||
publisherTagURLTest = `http://${QUANTCAST_CALLBACK_URL_TEST}:8080/qchb`; | ||
} | ||
}; | ||
|
||
function callBids(params) { | ||
let bids = params.bids || []; | ||
if (bids.length === 0) { | ||
return; | ||
} | ||
|
||
let referrer = utils.getTopWindowUrl(); | ||
let loc = utils.getTopWindowLocation(); | ||
let domain = loc.hostname; | ||
let publisherId = 0; | ||
const bidRequestsList = bids.map(bid => { | ||
const bidSizes = []; | ||
|
||
publisherId = '' + bids[0].params.publisherId; | ||
utils._each(bids, function(bid) { | ||
let key = bid.placementCode; | ||
var bidSizes = []; | ||
utils._each(bid.sizes, function (size) { | ||
bid.sizes.forEach(size => { | ||
bidSizes.push({ | ||
'width': size[0], | ||
'height': size[1] | ||
width: size[0], | ||
height: size[1] | ||
}); | ||
}); | ||
|
||
bidRequests[key] = bidRequests[key] || { | ||
'publisherId': publisherId, | ||
'requestId': bid.bidId, | ||
'bidId': bid.bidId, | ||
'site': { | ||
'page': loc.href, | ||
'referrer': referrer, | ||
'domain': domain, | ||
// Request Data Format can be found at https://wiki.corp.qc/display/adinf/QCX | ||
const requestData = { | ||
publisherId: bid.params.publisherId, | ||
requestId: bid.bidId, | ||
imp: [ | ||
{ | ||
banner: { | ||
battr: bid.params.battr, | ||
sizes: bidSizes | ||
}, | ||
placementCode: bid.placementCode, | ||
bidFloor: bid.params.bidFloor || DEFAULT_BID_FLOOR | ||
} | ||
], | ||
site: { | ||
page: loc.href, | ||
referrer, | ||
domain | ||
}, | ||
'imp': [{ | ||
|
||
'banner': { | ||
'battr': bid.params.battr, | ||
'sizes': bidSizes, | ||
}, | ||
'placementCode': bid.placementCode, | ||
'bidFloor': bid.params.bidFloor || DEFAULT_BID_FLOOR, | ||
}] | ||
bidId: bid.bidId | ||
}; | ||
}); | ||
|
||
utils._each(bidRequests, function (bidRequest) { | ||
ajax.ajax(QUANTCAST_CALLBACK_URL, $$PREBID_GLOBAL$$.handleQuantcastCB, JSON.stringify(bidRequest), { | ||
const data = JSON.stringify(requestData); | ||
|
||
const url = | ||
bid.params.publisherId === QUANTCAST_TEST_PUBLISHER | ||
? publisherTagURLTest | ||
: publisherTagURL; | ||
|
||
return { | ||
data, | ||
method: 'POST', | ||
withCredentials: true | ||
}); | ||
url | ||
}; | ||
}); | ||
} | ||
|
||
// Export the `callBids` function, so that Prebid.js can execute | ||
// this function when the page asks to send out bid requests. | ||
return { | ||
callBids: callBids, | ||
QUANTCAST_CALLBACK_URL: QUANTCAST_CALLBACK_URL | ||
}; | ||
}; | ||
return bidRequestsList; | ||
}, | ||
|
||
/** | ||
* Function get called when the browser has received the response from Quantcast server. | ||
* The function parse the response and create a `bidResponse` object containing one/more bids. | ||
* Returns an empty array if no valid bids | ||
* | ||
* Response Data Format can be found at https://wiki.corp.qc/display/adinf/QCX | ||
* | ||
* @param {*} serverResponse A successful response from Quantcast server. | ||
* @return {Bid[]} An array of bids which were nested inside the server. | ||
* | ||
*/ | ||
interpretResponse(serverResponse) { | ||
if (serverResponse === undefined) { | ||
utils.logError('Server Response is undefined'); | ||
return []; | ||
} | ||
|
||
const response = serverResponse['body']; | ||
|
||
if ( | ||
response === undefined || | ||
!response.hasOwnProperty('bids') || | ||
utils.isEmpty(response.bids) | ||
) { | ||
utils.logError('Sub-optimal JSON received from Quantcast server'); | ||
return []; | ||
} | ||
|
||
adaptermanager.registerBidAdapter(new QuantcastAdapter(), 'quantcast'); | ||
const bidResponsesList = response.bids.map(bid => { | ||
const { ad, cpm, width, height, creativeId, currency } = bid; | ||
|
||
return { | ||
requestId: response.requestId, | ||
cpm, | ||
width, | ||
height, | ||
ad, | ||
ttl: QUANTCAST_TTL, | ||
creativeId, | ||
netRevenue: QUANTCAST_NET_REVENUE, | ||
currency | ||
}; | ||
}); | ||
|
||
return bidResponsesList; | ||
} | ||
}; | ||
|
||
module.exports = QuantcastAdapter; | ||
registerBidder(spec); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Overview | ||
|
||
``` | ||
Module Name: Quantcast Bidder Adapter | ||
Module Type: Bidder Adapter | ||
Maintainer: xli@quantcast.com | ||
``` | ||
|
||
# Description | ||
|
||
Module that connects to Quantcast demand sources to fetch bids. | ||
|
||
# Test Parameters | ||
|
||
```js | ||
const adUnits = [{ | ||
code: 'banner', | ||
sizes: [ | ||
[300, 250] | ||
], | ||
bids: [ | ||
{ | ||
bidder: 'quantcast', | ||
params: { | ||
publisherId: 'test-publisher', // REQUIRED - Publisher ID provided by Quantcast | ||
battr: [1, 2] // OPTIONAL - Array of blocked creative attributes as per OpenRTB Spec List 5.3 | ||
} | ||
} | ||
] | ||
}]; | ||
``` |
Oops, something went wrong.