Skip to content

Commit

Permalink
GumGum Adapter for Prebid.js 1.0 (prebid#1966)
Browse files Browse the repository at this point in the history
* 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
mxcoder authored and dluxemburg committed Jul 17, 2018
1 parent b6b7e95 commit 7b82fbf
Show file tree
Hide file tree
Showing 3 changed files with 348 additions and 0 deletions.
170 changes: 170 additions & 0 deletions modules/gumgumBidAdapter.js
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)
40 changes: 40 additions & 0 deletions modules/gumgumBidAdapter.md
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
}
}
]
}
];
```
138 changes: 138 additions & 0 deletions test/spec/modules/gumgumBidAdapter_spec.js
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);
});
})
});

0 comments on commit 7b82fbf

Please sign in to comment.