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

Telaria: Added SupplyChain Object support and an onTimeout Callback #4137

Merged
merged 32 commits into from
Sep 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
5dcf4b5
Added telaria bid adapter
tremorvideo Aug 1, 2018
0a19ea2
more documentation
tremorvideo Aug 1, 2018
e1d19e4
Added more test cases. And improved some code in the adapter
tremorvideo Aug 1, 2018
0863824
Removed the check for optional params, they are handled in the server…
tremorvideo Aug 1, 2018
cb0973a
added some spaces to fix CircleCI tests
tremorvideo Aug 1, 2018
836779c
added some spaces to fix CircleCI tests
tremorvideo Aug 1, 2018
850c4f4
fixed code indentation in /spec/AnalyticsAdapter_spec.js which causin…
tremorvideo Aug 1, 2018
ad01373
Reverted the changes
tremorvideo Aug 1, 2018
df23a42
merged with prebid master.
tremorvideo Aug 1, 2018
de868c1
merged with prebid master.
tremorvideo Aug 1, 2018
dd996a9
creative Id is required when we build a response but our server doesn…
tremorvideo Aug 1, 2018
7ef41b9
- removed an un used method
tremorvideo Aug 3, 2018
d7b95e6
Merge https://github.com/prebid/Prebid.js
tremorvideo Aug 3, 2018
58cc7ce
Merge branch 'master' of https://github.com/prebid/Prebid.js
Dec 12, 2018
81ec17a
merging to master
Dec 12, 2018
cebc764
updated telaria bid adapter to use player size provided by the bid.me…
Dec 13, 2018
7d617a7
- removed the requirement for having player size
Dec 14, 2018
012a77b
added a param to the ad call url to let us know that the request is c…
Dec 18, 2018
178c072
to lower casing the bidder code.
Dec 19, 2018
fb10552
Merge branch 'master' of https://github.com/prebid/Prebid.js
Apr 1, 2019
7c6f20c
Merge branch 'master' of https://github.com/prebid/Prebid.js
Apr 1, 2019
32831bf
Sending the gdpr & gdpr consent string only if they're defined
Apr 2, 2019
a9607be
Merge branch 'master' of https://github.com/prebid/Prebid.js
May 6, 2019
3b3e433
Merge branch 'master' of https://github.com/prebid/Prebid.js
May 21, 2019
95f6d98
- Updated the test ad unit to use 'telaria' as the bidder code.
May 21, 2019
5385ca0
using the bidder code constant
May 23, 2019
787a6ff
Merge branch 'master' of https://github.com/prebid/Prebid.js
Aug 28, 2019
6f2cb7d
- Implemented the 'onTimeout' callback to fire a pixel when there's a…
Aug 29, 2019
b64b614
some mods to the schain tag generation
Aug 29, 2019
fa420db
- added tests for schain param checking.
Aug 30, 2019
4d8f45d
- fixed a malformed url for timeouts
Aug 30, 2019
834945d
- Removed a trailing ',' while generating a schain param.
Aug 30, 2019
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
126 changes: 101 additions & 25 deletions modules/telariaBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import {VIDEO} from '../src/mediaTypes';
import {STATUS} from '../src/constants';

const BIDDER_CODE = 'telaria';
const ENDPOINT = '.ads.tremorhub.com/ad/tag';
const DOMAIN = 'tremorhub.com';
const TAG_ENDPOINT = `ads.${DOMAIN}/ad/tag`;
const EVENTS_ENDPOINT = `events.${DOMAIN}/diag`;

export const spec = {
code: BIDDER_CODE,
Expand Down Expand Up @@ -82,7 +84,7 @@ export const spec = {
errorMessage += `: ${bidResult.error}`;
}
utils.logError(errorMessage);
} else if (bidResult.seatbid && bidResult.seatbid.length > 0) {
} else if (!utils.isEmpty(bidResult.seatbid)) {
bidResult.seatbid[0].bid.forEach(tag => {
bids.push(createBid(STATUS.GOOD, bidderRequest, tag, width, height, BIDDER_CODE));
});
Expand All @@ -100,11 +102,89 @@ export const spec = {
getUserSyncs: function (syncOptions, serverResponses) {
const syncs = [];
if (syncOptions.pixelEnabled && serverResponses.length) {
try {
serverResponses[0].body.ext.telaria.userSync.forEach(url => syncs.push({type: 'image', url: url}));
} catch (e) {}
(utils.deepAccess(serverResponses, '0.body.ext.telaria.userSync') || []).forEach(url => syncs.push({type: 'image', url: url}));
}
return syncs;
},

/**
* See http://prebid.org/dev-docs/bidder-adaptor.html#registering-on-timeout for detailed semantic.
* @param timeoutData bidRequest
*/
onTimeout: function (timeoutData) {
let url = getTimeoutUrl(timeoutData);
if (url) {
utils.triggerPixel(url);
}
}
};

function getScheme() {
return ((document.location.protocol === 'https:') ? 'https' : 'http') + '://';
}

function getSrcPageUrl(params) {
return (params && params['srcPageUrl']) || encodeURIComponent(document.location.href);
}

function getEncodedValIfNotEmpty(val) {
return !utils.isEmpty(val) ? encodeURIComponent(val) : '';
}

/**
* Converts the schain object to a url param value. Please refer to
* https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/supplychainobject.md
* (schain for non ORTB section) for more information
* @param schainObject
* @returns {string}
*/
function getSupplyChainAsUrlParam(schainObject) {
if (utils.isEmpty(schainObject)) {
return '';
}

let scStr = `&schain=${schainObject.ver},${schainObject.complete}`;

schainObject.nodes.forEach((node) => {
scStr += '!';
scStr += `${getEncodedValIfNotEmpty(node.asi)},`;
scStr += `${getEncodedValIfNotEmpty(node.sid)},`;
scStr += `${getEncodedValIfNotEmpty(node.hp)},`;
scStr += `${getEncodedValIfNotEmpty(node.rid)},`;
scStr += `${getEncodedValIfNotEmpty(node.name)},`;
scStr += `${getEncodedValIfNotEmpty(node.domain)}`;
});

return scStr;
}

function getUrlParams(params) {
let urlSuffix = '';

if (!utils.isEmpty(params)) {
for (let key in params) {
if (key !== 'schain' && params.hasOwnProperty(key) && !utils.isEmpty(params[key])) {
urlSuffix += `&${key}=${params[key]}`;
}
}
urlSuffix += getSupplyChainAsUrlParam(params['schain']);
}

return urlSuffix;
}

export const getTimeoutUrl = function(timeoutData) {
let params = utils.deepAccess(timeoutData, '0.params.0');

if (!utils.isEmpty(params)) {
let url = `${getScheme()}${EVENTS_ENDPOINT}`;

url += `?srcPageUrl=${getSrcPageUrl(params)}`;
url += `${getUrlParams(params)}`;

url += '&hb=1&evt=TO';

return url;
}
};

Expand All @@ -116,9 +196,9 @@ export const spec = {
* @returns {string}
*/
function generateUrl(bid, bidderRequest) {
let playerSize = (bid.mediaTypes && bid.mediaTypes.video && bid.mediaTypes.video.playerSize);
let playerSize = utils.deepAccess(bid, 'mediaTypes.video.playerSize');
if (!playerSize) {
utils.logWarn('Although player size isn\'t required it is highly recommended');
utils.logWarn(`Although player size isn't required it is highly recommended`);
}

let width, height;
Expand All @@ -132,45 +212,41 @@ function generateUrl(bid, bidderRequest) {
}
}

if (bid.params.supplyCode && bid.params.adCode) {
let scheme = ((document.location.protocol === 'https:') ? 'https' : 'http') + '://';
let url = scheme + bid.params.supplyCode + ENDPOINT + '?adCode=' + bid.params.adCode;
let supplyCode = utils.deepAccess(bid, 'params.supplyCode');
let adCode = utils.deepAccess(bid, 'params.adCode');

if (supplyCode && adCode) {
let url = `${getScheme()}${supplyCode}.${TAG_ENDPOINT}?adCode=${adCode}`;

if (width) {
url += ('&playerWidth=' + width);
url += (`&playerWidth=${width}`);
}
if (height) {
url += ('&playerHeight=' + height);
url += (`&playerHeight=${height}`);
}

for (let key in bid.params) {
if (bid.params.hasOwnProperty(key) && bid.params[key]) {
url += ('&' + key + '=' + bid.params[key]);
}
}
url += `${getUrlParams(bid.params)}`;

if (!bid.params['srcPageUrl']) {
url += ('&srcPageUrl=' + encodeURIComponent(document.location.href));
}
url += `&srcPageUrl=${getSrcPageUrl(bid.params)}`;

url += ('&transactionId=' + bid.transactionId + '&hb=1');
url += (`&transactionId=${bid.transactionId}`);

if (bidderRequest) {
if (bidderRequest.gdprConsent) {
if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') {
url += ('&gdpr=' + (bidderRequest.gdprConsent.gdprApplies ? 1 : 0));
url += (`&gdpr=${(bidderRequest.gdprConsent.gdprApplies ? 1 : 0)}`);
}
if (bidderRequest.gdprConsent.consentString) {
url += ('&gdpr_consent=' + bidderRequest.gdprConsent.consentString);
url += (`&gdpr_consent=${bidderRequest.gdprConsent.consentString}`);
}
}

if (bidderRequest.refererInfo && bidderRequest.refererInfo.referer) {
url += ('&referrer=' + encodeURIComponent(bidderRequest.refererInfo.referer));
url += (`&referrer=${encodeURIComponent(bidderRequest.refererInfo.referer)}`);
}
}

return (url + '&fmt=json');
return (url + '&hb=1&fmt=json');
}
}

Expand Down
69 changes: 66 additions & 3 deletions test/spec/modules/telariaBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {expect} from 'chai';
import {expect, should} from 'chai';
import {newBidder} from 'src/adapters/bidderFactory';
import {spec} from 'modules/telariaBidAdapter';
import {spec, getTimeoutUrl} from 'modules/telariaBidAdapter';

const ENDPOINT = '.ads.tremorhub.com/ad/tag';
const AD_CODE = 'ssp-!demo!-lufip';
Expand All @@ -16,14 +16,44 @@ const REQUEST = {
},
'mediaType': 'video',
'bids': [{
'bidder': 'tremor',
'bidder': 'telaria',
'params': {
'videoId': 'MyCoolVideo',
'inclSync': true
}
}]
};

const REQUEST_WITH_SCHAIN = [{
'bidder': 'telaria',
'params': {
'videoId': 'MyCoolVideo',
'inclSync': true,
'schain': {
'ver': '1.0',
'complete': 1,
'nodes': [
{
'asi': 'exchange1.com',
'sid': '1234',
'hp': 1,
'rid': 'bid-request-1',
'name': 'publisher',
'domain': 'publisher.com'
},
{
'asi': 'exchange2.com',
'sid': 'abcd',
'hp': 1,
'rid': 'bid-request-2',
'name': 'intermediary',
'domain': 'intermediary.com'
}
]
}
}
}];

const BIDDER_REQUEST = {
'refererInfo': {
'referer': 'www.test.com'
Expand Down Expand Up @@ -102,6 +132,8 @@ describe('TelariaAdapter', () => {
}
}];

const schainStub = REQUEST_WITH_SCHAIN;

it('exists and is a function', () => {
expect(spec.buildRequests).to.exist.and.to.be.a('function');
});
Expand Down Expand Up @@ -147,6 +179,14 @@ describe('TelariaAdapter', () => {

expect(tempRequest.length).to.equal(0);
});

it('converts the schain object into a tag param', () => {
let tempBid = schainStub;
tempBid[0].params.adCode = 'ssp-!demo!-lufip';
tempBid[0].params.supplyCode = 'ssp-demo-rm6rh';
let builtRequests = spec.buildRequests(tempBid, BIDDER_REQUEST);
expect(builtRequests.length).to.equal(1);
});
});

describe('interpretResponse', () => {
Expand Down Expand Up @@ -215,4 +255,27 @@ describe('TelariaAdapter', () => {
expect(urls.length).to.equal(2);
});
});

describe('onTimeout', () => {
const timeoutData = [{
adUnitCode: 'video1',
auctionId: 'd8d239f4-303a-4798-8c8c-dd3151ced4e7',
bidId: '2c749c0101ea92',
bidder: 'telaria',
params: [{
adCode: 'ssp-!demo!-lufip',
supplyCode: 'ssp-demo-rm6rh',
mediaId: 'MyCoolVideo'
}]
}];

it('should return a pixel url', () => {
let url = getTimeoutUrl(timeoutData);
assert(url);
});

it('should fire a pixel', () => {
expect(spec.onTimeout(timeoutData)).to.be.undefined;
});
});
});