Skip to content

Commit

Permalink
33Across: Adapter performance enhancements (#2899)
Browse files Browse the repository at this point in the history
* Adding 33across adapter

* Updated per code review from Prebid. See #1805 (review)

* Added support for test bid and crid.

* Removed ability to set test url via params

* Incorporated changes requested in #1855 to fix usage of deprecated method

* Reverted hack to karma conf maker to make unit tests pass with --file option

* Enabling POST withCredentials to send userSync cookies

* Sync based on unique site id

* Store siteID's in module level object instead of config

* Eliminate preflight. Remove test setup in docs

* Added alias for contact mailing list
  • Loading branch information
curlyblueeagle authored and jsnellbaker committed Jul 26, 2018
1 parent 0b6aee7 commit 5bf8e5a
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 131 deletions.
57 changes: 28 additions & 29 deletions modules/33acrossBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { userSync } from 'src/userSync'
import { uniques } from 'src/utils';
const { registerBidder } = require('../src/adapters/bidderFactory');
const { config } = require('../src/config');

const BIDDER_CODE = '33across';
const END_POINT = 'https://ssc.33across.com/api/v1/hb';
const SYNC_ENDPOINT = 'https://de.tynt.com/deb/v2?m=xch&rt=html';

const adapterState = {};

// All this assumes that only one bid is ever returned by ttx
function _createBidResponse(response) {
return {
Expand Down Expand Up @@ -42,19 +43,21 @@ function _createServerRequest(bidRequest) {
}
}
ttxRequest.site = { id: params.siteId };

// Go ahead send the bidId in request to 33exchange so it's kept track of in the bid response and
// therefore in ad targetting process
ttxRequest.id = bidRequest.bidId;

// Finally, set the openRTB 'test' param if this is to be a test bid
if (params.test === 1) {
ttxRequest.test = 1;
}

/*
* Now construt the full server request
* Now construct the full server request
*/
const options = {
contentType: 'application/json',
contentType: 'text/plain',
withCredentials: true
};
// Allow the ability to configure the HB endpoint for testing purposes.
Expand All @@ -70,6 +73,17 @@ function _createServerRequest(bidRequest) {
}
}

// Sync object will always be of type iframe for TTX
function _createSync(siteId) {
const ttxSettings = config.getConfig('ttxSettings');
const syncUrl = (ttxSettings && ttxSettings.syncUrl) || SYNC_ENDPOINT;

return {
type: 'iframe',
url: `${syncUrl}&id=${siteId}`
}
}

function _getFormatSize(sizeArr) {
return {
w: sizeArr[0],
Expand All @@ -78,24 +92,6 @@ function _getFormatSize(sizeArr) {
}
}

// Register one sync per bid since each ad unit may potenitally be linked to a uniqe guid
// Sync type will always be 'iframe' for 33Across
function _registerUserSyncs(requestData) {
let ttxRequest;
try {
ttxRequest = JSON.parse(requestData);
} catch (err) {
// No point in trying to register sync since the requisite data cannot be parsed.
return;
}
const ttxSettings = config.getConfig('ttxSettings');

let syncUrl = (ttxSettings && ttxSettings.syncUrl) || SYNC_ENDPOINT;

syncUrl = `${syncUrl}&id=${ttxRequest.site.id}`;
userSync.registerSync('iframe', BIDDER_CODE, syncUrl);
}

function isBidRequestValid(bid) {
if (bid.bidder !== BIDDER_CODE || typeof bid.params === 'undefined') {
return false;
Expand All @@ -108,18 +104,15 @@ function isBidRequestValid(bid) {
return true;
}

// NOTE: At this point, 33exchange only accepts request for a single impression
// NOTE: At this point, TTX only accepts request for a single impression
function buildRequests(bidRequests) {
adapterState.uniqueSiteIds = bidRequests.map(req => req.params.siteId).filter(uniques);

return bidRequests.map(_createServerRequest);
}

// NOTE: At this point, the response from 33exchange will only ever contain one bid i.e. the highest bid
function interpretResponse(serverResponse, bidRequest) {
// Register user sync first
if (bidRequest && bidRequest.data) {
_registerUserSyncs(bidRequest.data);
}

const bidResponses = [];

// If there are bids, look at the first bid of the first seatbid (see NOTE above for assumption about ttx)
Expand All @@ -130,11 +123,17 @@ function interpretResponse(serverResponse, bidRequest) {
return bidResponses;
}

// Register one sync per unique guid
function getUserSyncs(syncOptions) {
return (syncOptions.iframeEnabled) ? adapterState.uniqueSiteIds.map(_createSync) : ([]);
}

const spec = {
code: BIDDER_CODE,
isBidRequestValid,
buildRequests,
interpretResponse
interpretResponse,
getUserSyncs
}

registerBidder(spec);
Expand Down
69 changes: 3 additions & 66 deletions modules/33acrossBidAdapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
```
Module Name: 33Across Bid Adapter
Module Type: Bidder Adapter
Maintainer: aparna.hegde@33across.com
Maintainer: headerbidding@33across.com
```

# Description
Expand All @@ -24,72 +24,9 @@ var adUnits = [
bids: [{
bidder: '33across',
params: {
siteId: 'pub1234',
productId: 'infeed'
siteId: 'examplePub1234',
productId: 'siab'
}
}]
}
```

# Ad Unit and Setup: For Testing
In order to receive bids please map localhost to (any) test domain.

```
<--! Prebid Config section >
<script>
var PREBID_TIMEOUT = 3000;
var adUnits = [
{
code: '33across-hb-ad-123456-1',
sizes: [
[300, 250],
[728, 90]
],
bids: [{
bidder: '33across',
params: {
site: {
id: 'aRlI5W_9yr5jkxacwqm_6r',
page: "http://thinkbabynames.com/baby-mcbabyface",
ext: {
ttx: {
ssp_configs: [
{
"name": "index",
"enabled": false
},
{
"name": "rubicon",
"enabled": true
},
{
"name": "33xchange",
"enabled": false
}
]
}
}
},
productId: 'infeed'
}
}]
}
];
var pbjs = pbjs || {};
pbjs.que = pbjs.que || [];
// Adjust bid CPM to ensure it wins the auction (USED ONLY FOR TESTING). Need to do this since test bids have too low a CPM
pbjs.bidderSettings = {
'33across': {
bidCpmAdjustment : function(bidCpm, bid){
// adjust the bid in real time before the auction takes place, only do so for valid bids ignore no bids
if (bid.w !== 0 && bid.h !== 0 && bidCpm !== 0) {
return bidCpm + 0.50;
}
}
}
};
</script>
<!-- End Prebid Config section>
```
99 changes: 63 additions & 36 deletions test/spec/modules/33acrossBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ describe('33acrossBidAdapter:', function () {
'url': END_POINT,
'data': JSON.stringify(ttxRequest),
'options': {
'contentType': 'application/json',
'contentType': 'text/plain',
'withCredentials': true
}
}
Expand Down Expand Up @@ -193,7 +193,7 @@ describe('33acrossBidAdapter:', function () {
url: 'https://foo.com/hb/',
data: JSON.stringify(ttxRequest),
options: {
contentType: 'application/json',
contentType: 'text/plain',
withCredentials: true
}
};
Expand Down Expand Up @@ -243,7 +243,7 @@ describe('33acrossBidAdapter:', function () {
url: 'https://foo.com/hb/',
data: JSON.stringify(ttxRequest),
options: {
contentType: 'application/json',
contentType: 'text/plain',
withCredentials: true
}
};
Expand Down Expand Up @@ -293,7 +293,7 @@ describe('33acrossBidAdapter:', function () {
url: '//staging-ssc.33across.com/api/v1/hb',
data: JSON.stringify(this.ttxRequest),
options: {
contentType: 'application/json',
contentType: 'text/plain',
withCredentials: false
}
};
Expand Down Expand Up @@ -404,43 +404,70 @@ describe('33acrossBidAdapter:', function () {
expect(interpretResponse({ body: serverResponse }, this.serverRequest)).to.deep.equal([ bidResponse ]);
});
});
});

context('and register user sync', function() {
it('via the production endpoint', function() {
const spy = this.sandbox.spy(userSync, 'registerSync');
const serverResponse = {
cur: 'USD',
ext: {},
id: 'b1',
seatbid: []
describe('getUserSyncs', function() {
beforeEach(function() {
this.syncs = [
{
type: 'iframe',
url: 'https://de.tynt.com/deb/v2?m=xch&rt=html&id=id1'
},
{
type: 'iframe',
url: 'https://de.tynt.com/deb/v2?m=xch&rt=html&id=id2'
},
];
this.bidRequests = [
{
bidId: 'b1',
bidder: '33across',
bidderRequestId: 'b1a',
params: {
siteId: 'id1',
productId: 'foo'
},
adUnitCode: 'div-id',
auctionId: 'r1',
sizes: [
[ 300, 250 ]
],
transactionId: 't1'
},
{
bidId: 'b2',
bidder: '33across',
bidderRequestId: 'b2a',
params: {
siteId: 'id2',
productId: 'foo'
},
adUnitCode: 'div-id',
auctionId: 'r1',
sizes: [
[ 300, 250 ]
],
transactionId: 't2'
}
interpretResponse({ body: serverResponse }, this.serverRequest);
const syncUrl = `${SYNC_ENDPOINT}&id=${this.ttxRequest.site.id}`;
];
});

const registerSyncCalled = spy.calledWith('iframe', '33across', syncUrl);
expect(registerSyncCalled).to.be.true;
context('when iframe is not enabled', function() {
it('returns empty sync array', function() {
const syncOptions = {};
buildRequests(this.bidRequests);
expect(getUserSyncs(syncOptions)).to.deep.equal([]);
});
});

it('via the test endpoint', function() {
const spy = this.sandbox.spy(userSync, 'registerSync');

this.sandbox.stub(config, 'getConfig').callsFake(() => {
return {
'syncUrl': 'https://foo.com/deb/v2?m=xch'
}
});

const serverResponse = {
cur: 'USD',
ext: {},
id: 'b1',
seatbid: []
}
interpretResponse({ body: serverResponse }, this.serverRequest);
const syncUrl = `https://foo.com/deb/v2?m=xch&id=${this.ttxRequest.site.id}`;

const registerSyncCalled = spy.calledWith('iframe', '33across', syncUrl);
expect(registerSyncCalled).to.be.true;
context('when iframe is enabled', function() {
it('returns sync array equal to number of unique siteIDs', function() {
const syncOptions = {
iframeEnabled: true
};
buildRequests(this.bidRequests);
const syncs = getUserSyncs(syncOptions);
expect(syncs).to.deep.equal(this.syncs);
});
});
});
Expand Down

0 comments on commit 5bf8e5a

Please sign in to comment.