forked from prebid/Prebid.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GumGum Adapter for Prebid.js 1.0 (prebid#1966)
* GumGum Adapter for Prebid.js 1.0 * removed getUserSyncs. Give cpm a non-zero value when bidRequest is for test unit so DFP chooses it. * parsing slot ID as integer from params * ADSS-78 removed bidderCode from response. Correctly parsing bidRequest.sizes to account for 1-dimensional array.
- Loading branch information
1 parent
b6b7e95
commit 7b82fbf
Showing
3 changed files
with
348 additions
and
0 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 |
---|---|---|
@@ -0,0 +1,170 @@ | ||
import * as utils from 'src/utils' | ||
|
||
import { config } from 'src/config' | ||
import { registerBidder } from 'src/adapters/bidderFactory' | ||
|
||
const BIDDER_CODE = 'gumgum' | ||
const ALIAS_BIDDER_CODE = ['gg'] | ||
const BID_ENDPOINT = `https://g2.gumgum.com/hbid/imp` | ||
const DT_CREDENTIALS = { member: 'YcXr87z2lpbB' } | ||
const TIME_TO_LIVE = 60 | ||
let browserParams = {}; | ||
|
||
// TODO: potential 0 values for browserParams sent to ad server | ||
function _getBrowserParams() { | ||
let topWindow | ||
let topScreen | ||
if (browserParams.vw) { | ||
// we've already initialized browserParams, just return it. | ||
return browserParams | ||
} | ||
|
||
try { | ||
topWindow = global.top; | ||
topScreen = topWindow.screen; | ||
} catch (error) { | ||
utils.logError(error); | ||
return browserParams | ||
} | ||
|
||
browserParams = { | ||
vw: topWindow.innerWidth, | ||
vh: topWindow.innerHeight, | ||
sw: topScreen.width, | ||
sh: topScreen.height, | ||
pu: utils.getTopWindowUrl(), | ||
ce: utils.cookiesAreEnabled(), | ||
dpr: topWindow.devicePixelRatio || 1 | ||
} | ||
return browserParams | ||
} | ||
|
||
function getWrapperCode(wrapper, data) { | ||
return wrapper.replace('AD_JSON', window.btoa(JSON.stringify(data))) | ||
} | ||
|
||
// TODO: use getConfig() | ||
function _getDigiTrustQueryParams() { | ||
function getDigiTrustId () { | ||
var digiTrustUser = (window.DigiTrust && window.DigiTrust.getUser) ? window.DigiTrust.getUser(DT_CREDENTIALS) : {}; | ||
return (digiTrustUser && digiTrustUser.success && digiTrustUser.identity) || ''; | ||
}; | ||
|
||
let digiTrustId = getDigiTrustId(); | ||
// Verify there is an ID and this user has not opted out | ||
if (!digiTrustId || (digiTrustId.privacy && digiTrustId.privacy.optout)) { | ||
return {}; | ||
} | ||
return { | ||
'dt': digiTrustId.id | ||
}; | ||
} | ||
|
||
/** | ||
* 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. | ||
*/ | ||
function isBidRequestValid (bid) { | ||
const { | ||
params, | ||
adUnitCode | ||
} = bid; | ||
|
||
switch (true) { | ||
case !!(params.inScreen): break; | ||
case !!(params.inSlot): break; | ||
default: | ||
utils.logWarn(`[GumGum] No product selected for the placement ${adUnitCode}, please check your implementation.`); | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* Make a server request from the list of BidRequests. | ||
* | ||
* @param {validBidRequests[]} - an array of bids | ||
* @return ServerRequest Info describing the request to the server. | ||
*/ | ||
function buildRequests (validBidRequests) { | ||
const bids = []; | ||
utils._each(validBidRequests, bidRequest => { | ||
const timeout = config.getConfig('bidderTimeout'); | ||
const { | ||
bidId, | ||
params = {}, | ||
transactionId | ||
} = bidRequest; | ||
const data = {} | ||
|
||
if (params.inScreen) { | ||
data.t = params.inScreen; | ||
data.pi = 2; | ||
} | ||
if (params.inSlot) { | ||
data.si = parseInt(params.inSlot, 10); | ||
data.pi = 3; | ||
} | ||
|
||
bids.push({ | ||
id: bidId, | ||
tmax: timeout, | ||
tId: transactionId, | ||
pi: data.pi, | ||
sizes: bidRequest.sizes, | ||
url: BID_ENDPOINT, | ||
method: 'GET', | ||
data: Object.assign(data, _getBrowserParams(), _getDigiTrustQueryParams()) | ||
}) | ||
}); | ||
return bids; | ||
} | ||
|
||
/** | ||
* Unpack the response from the server into a list of bids. | ||
* | ||
* @param {*} serverResponse A successful response from the server. | ||
* @return {Bid[]} An array of bids which were nested inside the server. | ||
*/ | ||
function interpretResponse (serverResponse, bidRequest) { | ||
const bidResponses = [] | ||
const serverResponseBody = serverResponse.body | ||
const { | ||
ad: { | ||
price: cpm, | ||
id: creativeId, | ||
markup | ||
}, | ||
cw: wrapper | ||
} = serverResponseBody | ||
let isTestUnit = (bidRequest.data && bidRequest.data.pi === 3 && bidRequest.data.si === 9) | ||
let [width, height] = utils.parseSizesInput(bidRequest.sizes)[0].split('x') | ||
|
||
if (creativeId) { | ||
bidResponses.push({ | ||
// dealId: DEAL_ID, | ||
// referrer: REFERER, | ||
ad: wrapper ? getWrapperCode(wrapper, Object.assign({}, serverResponseBody, { bidRequest })) : markup, | ||
cpm: isTestUnit ? 0.1 : cpm, | ||
creativeId, | ||
currency: 'USD', | ||
height, | ||
netRevenue: true, | ||
requestId: bidRequest.id, | ||
ttl: TIME_TO_LIVE, | ||
width | ||
}) | ||
} | ||
return bidResponses | ||
} | ||
|
||
export const spec = { | ||
code: BIDDER_CODE, | ||
aliases: ALIAS_BIDDER_CODE, | ||
isBidRequestValid, | ||
buildRequests, | ||
interpretResponse | ||
} | ||
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,40 @@ | ||
# Overview | ||
|
||
``` | ||
Module Name: GumGum Bidder Adapter | ||
Module Type: Bidder Adapter | ||
Maintainer: engineering@gumgum.com | ||
``` | ||
|
||
# Description | ||
|
||
GumGum adapter for Prebid.js 1.0 | ||
|
||
# Test Parameters | ||
``` | ||
var adUnits = [ | ||
{ | ||
code: 'test-div', | ||
sizes: [[300, 250]], | ||
bids: [ | ||
{ | ||
bidder: 'gumgum', | ||
params: { | ||
inSlot: '9' // GumGum Slot ID given to the client | ||
} | ||
} | ||
] | ||
},{ | ||
code: 'test-div', | ||
sizes: [[300, 50]], | ||
bids: [ | ||
{ | ||
bidder: 'gumgum', | ||
params: { | ||
inScreen: 'ggumtest' // GumGum Zone ID given to the client | ||
} | ||
} | ||
] | ||
} | ||
]; | ||
``` |
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,138 @@ | ||
import { expect } from 'chai'; | ||
import { newBidder } from 'src/adapters/bidderFactory'; | ||
import { spec } from 'modules/gumgumBidAdapter'; | ||
|
||
const ENDPOINT = 'https://g2.gumgum.com/hbid/imp'; | ||
|
||
describe('gumgumAdapter', () => { | ||
const adapter = newBidder(spec); | ||
|
||
describe('inherited functions', () => { | ||
it('exists and is a function', () => { | ||
expect(adapter.callBids).to.exist.and.to.be.a('function'); | ||
}); | ||
}); | ||
|
||
describe('isBidRequestValid', () => { | ||
let bid = { | ||
'bidder': 'gumgum', | ||
'params': { | ||
'inScreen': '10433394' | ||
}, | ||
'adUnitCode': 'adunit-code', | ||
'sizes': [[300, 250], [300, 600]], | ||
'bidId': '30b31c1838de1e', | ||
'bidderRequestId': '22edbae2733bf6', | ||
'auctionId': '1d1a030790a475', | ||
}; | ||
|
||
it('should return true when required params found', () => { | ||
expect(spec.isBidRequestValid(bid)).to.equal(true); | ||
}); | ||
|
||
it('should return true when required params found', () => { | ||
let bid = Object.assign({}, bid); | ||
delete bid.params; | ||
bid.params = { | ||
'inSlot': '789' | ||
}; | ||
|
||
expect(spec.isBidRequestValid(bid)).to.equal(true); | ||
}); | ||
|
||
it('should return false when required params are not passed', () => { | ||
let bid = Object.assign({}, bid); | ||
delete bid.params; | ||
bid.params = { | ||
'placementId': 0 | ||
}; | ||
expect(spec.isBidRequestValid(bid)).to.equal(false); | ||
}); | ||
}); | ||
|
||
describe('buildRequests', () => { | ||
let bidRequests = [ | ||
{ | ||
'bidder': 'gumgum', | ||
'params': { | ||
'inSlot': '9' | ||
}, | ||
'adUnitCode': 'adunit-code', | ||
'sizes': [[300, 250], [300, 600]], | ||
'bidId': '30b31c1838de1e' | ||
} | ||
]; | ||
|
||
it('sends bid request to ENDPOINT via GET', () => { | ||
const requests = spec.buildRequests(bidRequests); | ||
const request = requests[0]; | ||
expect(request.url).to.equal(ENDPOINT); | ||
expect(request.method).to.equal('GET'); | ||
expect(request.id).to.equal('30b31c1838de1e'); | ||
}); | ||
}) | ||
|
||
describe('interpretResponse', () => { | ||
let serverResponse = { | ||
'ad': { | ||
'id': 29593, | ||
'width': 300, | ||
'height': 250, | ||
'ipd': 2000, | ||
'markup': '<html><h3>I am an ad</h3></html>', | ||
'ii': true, | ||
'du': null, | ||
'price': 0, | ||
'zi': 0, | ||
'impurl': 'http://g2.gumgum.com/ad/view', | ||
'clsurl': 'http://g2.gumgum.com/ad/close' | ||
}, | ||
'pag': { | ||
't': 'ggumtest', | ||
'pvid': 'aa8bbb65-427f-4689-8cee-e3eed0b89eec', | ||
'css': 'html { overflow-y: auto }', | ||
'js': 'console.log("environment", env);' | ||
}, | ||
'thms': 10000 | ||
} | ||
let bidRequest = { | ||
id: 12345, | ||
sizes: [[300, 250]], | ||
url: ENDPOINT, | ||
method: 'GET', | ||
pi: 3 | ||
} | ||
|
||
it('should get correct bid response', () => { | ||
let expectedResponse = { | ||
'ad': '<html><h3>I am an ad</h3></html>', | ||
'cpm': 0, | ||
'creativeId': 29593, | ||
'currency': 'USD', | ||
'height': '250', | ||
'netRevenue': true, | ||
'requestId': 12345, | ||
'width': '300', | ||
// dealId: DEAL_ID, | ||
// referrer: REFERER, | ||
ttl: 60 | ||
}; | ||
expect(spec.interpretResponse({ body: serverResponse }, bidRequest)).to.deep.equal([expectedResponse]); | ||
}); | ||
|
||
it('handles nobid responses', () => { | ||
let response = { | ||
'ad': {}, | ||
'pag': { | ||
't': 'ggumtest', | ||
'pvid': 'aa8bbb65-427f-4689-8cee-e3eed0b89eec', | ||
'css': 'html { overflow-y: auto }', | ||
'js': 'console.log("environment", env);' | ||
}, | ||
'thms': 10000 | ||
} | ||
let result = spec.interpretResponse({ body: response }, bidRequest); | ||
expect(result.length).to.equal(0); | ||
}); | ||
}) | ||
}); |