-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Create undertone udapter #1850
Create undertone udapter #1850
Changes from 13 commits
02f6569
0102ca1
b4ca9fd
bdbd153
00b84ed
b66f3dc
1077e68
10d4e92
2b4e23f
1eae245
9de1d5a
7d1e224
e79b30d
f9ff6c1
01ccb13
faa122f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/** | ||
* Adapter to send bids to Undertone | ||
*/ | ||
|
||
import * as utils from 'src/utils'; | ||
import { registerBidder } from 'src/adapters/bidderFactory'; | ||
|
||
const BIDDER_CODE = 'undertone'; | ||
const URL = '//hb.undertone.com/hb'; // //ads.undertone.com/hb | ||
|
||
export const spec = { | ||
code: BIDDER_CODE, | ||
isBidRequestValid: function(bid) { | ||
if (bid && bid.params && bid.params.publisherId && bid.params.placementId) { | ||
bid.params.publisherId = parseInt(bid.params.publisherId); | ||
return true; | ||
} | ||
}, | ||
buildRequests: function(validBidRequests) { | ||
const payload = { | ||
'x-ut-hb-params': [] | ||
}; | ||
const timeout = window.PREBID_TIMEOUT || null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you clarify why the timeout value is needed for the bid object passed to your system? Is this a reporting metric or actively used by the system? Prebid data can't be accessed directly through the window object. So we want to understand the need to help figure out some alternatives around supplying this information (if it's really needed). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Our API enable us to pass the timeout value to the server, so we can response with nobid if we are not able to respond within this time frame. This should improve the user experience and reduce load from our server. |
||
const host = utils.getTopWindowLocation().host; | ||
const domain = /[-\w]+\.(?:[-\w]+\.xn--[-\w]+|[-\w]{3,}|[-\w]+\.[-\w]{2})$/i.exec(host); | ||
|
||
const pubid = validBidRequests[0].params.publisherId; | ||
const REQ_URL = `${URL}?pid=${pubid}&domain=${domain}`; | ||
|
||
validBidRequests.map(bidReq => { | ||
const bid = { | ||
bidRequestId: bidReq.bidId, | ||
hbadaptor: 'prebid', | ||
domain: domain, | ||
placementId: bidReq.params.placementId, | ||
publisherId: bidReq.params.publisherId, | ||
sizes: bidReq.sizes, | ||
timeout: timeout, | ||
params: bidReq.params | ||
}; | ||
payload['x-ut-hb-params'].push(bid); | ||
}); | ||
return { | ||
method: 'POST', | ||
url: REQ_URL, | ||
withCredentials: true, | ||
data: JSON.stringify(payload) | ||
}; | ||
}, | ||
interpretResponse: function(serverResponse, request) { | ||
const bids = []; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #1748 changed the first argument of
so adding something like
just below this line, or however you'd prefer to grab the body, and updating corresponding tests if needed should get this back to working properly |
||
|
||
if (serverResponse && Array.isArray(serverResponse) && serverResponse.length > 0) { | ||
serverResponse.forEach((bidRes) => { | ||
if (bidRes.ad && bidRes.cpm > 0) { | ||
const bid = { | ||
requestId: bidRes.bidRequestId, | ||
bidderCode: BIDDER_CODE, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
cpm: bidRes.cpm, | ||
width: bidRes.width, | ||
height: bidRes.height, | ||
creativeId: bidRes.adId, | ||
currency: bidRes.currency, | ||
netRevenue: bidRes.netRevenue, | ||
ttl: bidRes.ttl, | ||
ad: bidRes.ad | ||
}; | ||
bids.push(bid); | ||
} | ||
}); | ||
} | ||
return bids; | ||
} | ||
}; | ||
registerBidder(spec); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Overview | ||
|
||
``` | ||
Module Name: Example Bidder Adapter | ||
Module Type: Bidder Adapter | ||
Maintainer: [email protected] | ||
``` | ||
# Description | ||
|
||
Module that connects to Undertone's demand sources | ||
|
||
# Test Parameters | ||
``` | ||
var adUnits = [ | ||
{ | ||
code: 'test-div', | ||
sizes: [[300, 250]], | ||
bids: [ | ||
{ | ||
bidder: "undertone", | ||
params: { | ||
placementId: '10433394', | ||
publisherId: 12345 | ||
} | ||
} | ||
] | ||
} | ||
]; | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
import { expect } from 'chai'; | ||
import { spec } from 'modules/undertoneBidAdapter'; | ||
|
||
const URL = '//hb.undertone.com/hb'; | ||
const BIDDER_CODE = 'undertone'; | ||
const validBidReq = { | ||
bidder: BIDDER_CODE, | ||
params: { | ||
placementId: '10433394', | ||
publisherId: 12345 | ||
}, | ||
sizes: [[300, 250], [300, 600]], | ||
bidId: '263be71e91dd9d', | ||
requestId: '9ad1fa8d-2297-4660-a018-b39945054746', | ||
auctionId: '1d1a030790a475' | ||
}; | ||
|
||
const invalidBidReq = { | ||
bidder: BIDDER_CODE, | ||
params: { | ||
placementId: '123456789' | ||
}, | ||
sizes: [[300, 250], [300, 600]], | ||
bidId: '263be71e91dd9d', | ||
requestId: '9ad1fa8d-2297-4660-a018-b39945054746' | ||
}; | ||
|
||
const bidReq = [{ | ||
bidder: BIDDER_CODE, | ||
params: { | ||
placementId: '10433394', | ||
publisherId: 12345 | ||
}, | ||
sizes: [[300, 250], [300, 600]], | ||
bidId: '263be71e91dd9d', | ||
requestId: '9ad1fa8d-2297-4660-a018-b39945054746', | ||
auctionId: '1d1a030790a475' | ||
}]; | ||
|
||
const validBidRes = { | ||
ad: '<div>Hello</div>', | ||
publisherId: 12345, | ||
bidRequestId: '263be71e91dd9d', | ||
adId: 15, | ||
cpm: 100, | ||
nCampaignId: 2, | ||
creativeId: '123abc', | ||
currency: 'USD', | ||
netRevenue: true, | ||
width: 300, | ||
height: 250, | ||
ttl: 360 | ||
}; | ||
|
||
const bidResponse = [validBidRes]; | ||
|
||
const bidResArray = [ | ||
validBidRes, | ||
{ | ||
ad: '', | ||
bidRequestId: '263be71e91dd9d', | ||
cpm: 100, | ||
adId: '123abc', | ||
currency: 'USD', | ||
netRevenue: true, | ||
width: 300, | ||
height: 250, | ||
ttl: 360 | ||
}, | ||
{ | ||
ad: '<div>Hello</div>', | ||
bidRequestId: '', | ||
cpm: 0, | ||
adId: '123abc', | ||
currency: 'USD', | ||
netRevenue: true, | ||
width: 300, | ||
height: 250, | ||
ttl: 360 | ||
} | ||
]; | ||
|
||
describe('Undertone Adapter', () => { | ||
describe('request', () => { | ||
it('should validate bid request', () => { | ||
expect(spec.isBidRequestValid(validBidReq)).to.equal(true); | ||
}); | ||
it('should not validate incorrect bid request', () => { | ||
expect(spec.isBidRequestValid(invalidBidReq)).to.equal(undefined); | ||
}); | ||
}); | ||
describe('build request', () => { | ||
it('should send request to correct url via POST', () => { | ||
const request = spec.buildRequests(bidReq); | ||
const domain = null; | ||
const REQ_URL = `${URL}?pid=${bidReq[0].params.publisherId}&domain=${domain}`; | ||
expect(request.url).to.equal(REQ_URL); | ||
expect(request.method).to.equal('POST'); | ||
}); | ||
it('should have all relevant fields', () => { | ||
const request = spec.buildRequests(bidReq); | ||
const bid = JSON.parse(request.data)['x-ut-hb-params'][0]; | ||
expect(bid.bidRequestId).to.equal('263be71e91dd9d'); | ||
expect(bid.sizes.length > 0).to.equal(true); | ||
expect(bid.placementId).to.equal('10433394'); | ||
expect(bid.publisherId).to.equal(12345); | ||
expect(bid.params).to.be.an('object'); | ||
}); | ||
}); | ||
|
||
describe('interpretResponse', () => { | ||
it('should build bid array', () => { | ||
let result = spec.interpretResponse(bidResponse); | ||
expect(result.length).to.equal(1); | ||
}); | ||
|
||
it('should have all relevant fields', () => { | ||
const result = spec.interpretResponse(bidResponse); | ||
const bid = result[0]; | ||
|
||
expect(bid.requestId).to.equal('263be71e91dd9d'); | ||
expect(bid.bidderCode).to.equal(BIDDER_CODE); | ||
expect(bid.cpm).to.equal(100); | ||
expect(bid.width).to.equal(300); | ||
expect(bid.height).to.equal(250); | ||
expect(bid.creativeId).to.equal(15); | ||
expect(bid.currency).to.equal('USD'); | ||
expect(bid.netRevenue).to.equal(true); | ||
expect(bid.ttl).to.equal(360); | ||
}); | ||
|
||
it('should return empty array when response is incorrect', () => { | ||
expect(spec.interpretResponse({}).length).to.equal(0); | ||
expect(spec.interpretResponse([]).length).to.equal(0); | ||
}); | ||
|
||
it('should only use valid bid responses', () => { | ||
expect(spec.interpretResponse(bidResArray).length).to.equal(1); | ||
}); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's
//ads.undertone.com/hb
? Could remove this comment