Skip to content
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

Update sharethrough bid adapter #1740

Merged
merged 4 commits into from
Nov 3, 2017
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 67 additions & 124 deletions modules/sharethroughBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,128 +1,71 @@
var utils = require('src/utils.js');
var bidmanager = require('src/bidmanager.js');
var bidfactory = require('src/bidfactory.js');
var ajax = require('src/ajax.js').ajax;
var adaptermanager = require('src/adaptermanager');

const STR_BIDDER_CODE = 'sharethrough';
const STR_VERSION = '1.2.0';

var SharethroughAdapter = function SharethroughAdapter() {
const str = {};
str.STR_BTLR_HOST = document.location.protocol + '//btlr.sharethrough.com';
str.STR_BEACON_HOST = document.location.protocol + '//b.sharethrough.com/butler?';
str.placementCodeSet = {};
str.ajax = ajax;

function _callBids(params) {
const bids = params.bids;

// cycle through bids
for (let i = 0; i < bids.length; i += 1) {
const bidRequest = bids[i];
str.placementCodeSet[bidRequest.placementCode] = bidRequest;
const scriptUrl = _buildSharethroughCall(bidRequest);
str.ajax(scriptUrl, _createCallback(bidRequest), undefined, {withCredentials: true});
}
import { registerBidder } from 'src/adapters/bidderFactory';

const BIDDER_CODE = 'sharethrough';
const VERSION = '2.0.0';
const STR_ENDPOINT = document.location.protocol + '//btlr.sharethrough.com/header-bid/v1';

export const sharethroughAdapterSpec = {
code: BIDDER_CODE,
isBidRequestValid: bid => !!bid.params.pkey && bid.bidder === BIDDER_CODE,
buildRequests: (bidRequests) => {
return bidRequests.map(bid => {
return {
method: 'GET',
url: STR_ENDPOINT,
data: {
bidId: bid.bidId,
placement_key: bid.params.pkey,
hbVersion: '$prebid.version$',
strVersion: VERSION,
hbSource: 'prebid'
}
};
})
},
interpretResponse: (resp, req) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#1748 changed the first argument of interpretResponse to:

{
  body: responseBody,
  headers: {
    get: function(header) { /* returns a header from the HTTP response */ }
  }
}

so adding something like

resp = resp.body;

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 (!Object.keys(resp).length) return [];

const creative = resp.creatives[0];

return [{
requestId: req.data.bidId,
bidderCode: BIDDER_CODE,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bidderCode will be set automatically by bidderFactory now, this line can be dropped

width: 0,
height: 0,
cpm: creative.cpm,
creativeId: creative.creative.creative_key,
deal_id: creative.creative.deal_id,
currency: 'USD',
netRevenue: true,
ttl: 360,
ad: generateAd(resp, req)
}];
}

function _createCallback(bidRequest) {
return (bidResponse) => {
_strcallback(bidRequest, bidResponse);
};
}

function _buildSharethroughCall(bid) {
const pkey = utils.getBidIdParameter('pkey', bid.params);

let host = str.STR_BTLR_HOST;

let url = host + '/header-bid/v1?';
url = utils.tryAppendQueryString(url, 'bidId', bid.bidId);
url = utils.tryAppendQueryString(url, 'placement_key', pkey);
url = appendEnvFields(url);

return url;
}

function _strcallback(bidObj, bidResponse) {
try {
bidResponse = JSON.parse(bidResponse);
} catch (e) {
_handleInvalidBid(bidObj);
return;
}

if (bidResponse.creatives && bidResponse.creatives.length > 0) {
_handleBid(bidObj, bidResponse);
} else {
_handleInvalidBid(bidObj);
}
}

function _handleBid(bidObj, bidResponse) {
try {
const bidId = bidResponse.bidId;
const bid = bidfactory.createBid(1, bidObj);
bid.bidderCode = STR_BIDDER_CODE;
bid.cpm = bidResponse.creatives[0].cpm;
const size = bidObj.sizes[0];
bid.width = size[0];
bid.height = size[1];
bid.adserverRequestId = bidResponse.adserverRequestId;
str.placementCodeSet[bidObj.placementCode].adserverRequestId = bidResponse.adserverRequestId;

bid.pkey = utils.getBidIdParameter('pkey', bidObj.params);

const windowLocation = `str_response_${bidId}`;
const bidJsonString = JSON.stringify(bidResponse);
bid.ad = `<div data-str-native-key="${bid.pkey}" data-stx-response-name='${windowLocation}'>
</div>
<script>var ${windowLocation} = ${bidJsonString}</script>
<script src="//native.sharethrough.com/assets/sfp-set-targeting.js"></script>`
}

function generateAd(resp, req) {
const strRespId = `str_response_${req.data.bidId}`;

return `
<div data-str-native-key="${req.data.placement_key}" data-stx-response-name="${strRespId}">
</div>
<script>var ${strRespId} = "${btoa(JSON.stringify(resp))}"</script>
<script src="//native.sharethrough.com/assets/sfp-set-targeting.js"></script>
<script>
(function() {
if (!(window.STR && window.STR.Tag) && !(window.top.STR && window.top.STR.Tag)) {
let sfpScriptTag = `
<script>
(function() {
const sfp_js = document.createElement('script');
sfp_js.src = "//native.sharethrough.com/assets/sfp.js";
sfp_js.type = 'text/javascript';
sfp_js.charset = 'utf-8';
try {
window.top.document.getElementsByTagName('body')[0].appendChild(sfp_js);
} catch (e) {
console.log(e);
}
})()
</script>`
bid.ad += sfpScriptTag;
const sfp_js = document.createElement('script');
sfp_js.src = "//native.sharethrough.com/assets/sfp.js";
sfp_js.type = 'text/javascript';
sfp_js.charset = 'utf-8';
try {
window.top.document.getElementsByTagName('body')[0].appendChild(sfp_js);
} catch (e) {
console.log(e);
}
}
bidmanager.addBidResponse(bidObj.placementCode, bid);
} catch (e) {
_handleInvalidBid(bidObj);
}
}

function _handleInvalidBid(bidObj) {
const bid = bidfactory.createBid(2, bidObj);
bid.bidderCode = STR_BIDDER_CODE;
bidmanager.addBidResponse(bidObj.placementCode, bid);
}

function appendEnvFields(url) {
url = utils.tryAppendQueryString(url, 'hbVersion', '$prebid.version$');
url = utils.tryAppendQueryString(url, 'strVersion', STR_VERSION);
url = utils.tryAppendQueryString(url, 'hbSource', 'prebid');

return url;
}

return {
callBids: _callBids,
str: str,
};
};

adaptermanager.registerBidAdapter(new SharethroughAdapter(), 'sharethrough');
})()
</script>`;
}

module.exports = SharethroughAdapter;
registerBidder(sharethroughAdapterSpec);
40 changes: 40 additions & 0 deletions modules/sharethroughBidAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Overview

```
Module Name: Sharethrough Bidder Adapter
Module Type: Bidder Adapter
Maintainer: jchau@sharethrough.com && cpan@sharethrough.com
```

# Description

Module that connects to Sharethrough's demand sources

# Test Parameters
```
var adUnits = [
{
code: 'test-div',
sizes: [[1, 1]], // a display size
bids: [
{
bidder: "sharethrough",
params: {
pkey: 'LuB3vxGGFrBZJa6tifXW4xgK'
}
}
]
},{
code: 'test-div',
sizes: [[1, 1]], // a mobile size
bids: [
{
bidder: "sharethrough",
params: {
pkey: 'LuB3vxGGFrBZJa6tifXW4xgK'
}
}
]
}
];
```
Loading