Skip to content

Commit

Permalink
Lifestreet adapter 3.0 (#4927)
Browse files Browse the repository at this point in the history
* Added adapter without tests

* Added readme

* Added tests and CCPA support

* Cleaned code, fixed tests

* reverted examples

* Added more tests + CR fixes

* Fixed example in lifestreet readme, reverted integration  example page

* restored permission for page example
  • Loading branch information
probably-kira authored Mar 11, 2020
1 parent 1b62b0b commit 6113cd9
Show file tree
Hide file tree
Showing 3 changed files with 407 additions and 7 deletions.
139 changes: 139 additions & 0 deletions modules/lifestreetBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import * as utils from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';

const BIDDER_CODE = 'lifestreet';
const ADAPTER_VERSION = '$prebid.version$';

const urlTemplate = template`https://ads.lfstmedia.com/gate/${'adapter'}/${'slot'}?adkey=${'adkey'}&ad_size=${'ad_size'}&__location=${'location'}&__referrer=${'referrer'}&__wn=${'wn'}&__sf=${'sf'}&__fif=${'fif'}&__if=${'if'}&__stamp=${'stamp'}&__pp=1&__hb=1&_prebid_json=1&__gz=1&deferred_format=vast_2_0,vast_3_0&__hbver=${'hbver'}`;

/**
* A helper function for template to generate string from boolean
*/
function boolToString(value) {
return value ? '1' : '0';
}

/**
* A helper function to form URL from the template
*/
function template(strings, ...keys) {
return function(...values) {
let dict = values[values.length - 1] || {};
let result = [strings[0]];
keys.forEach(function(key, i) {
let value = utils.isInteger(key) ? values[key] : dict[key];
result.push(value, strings[i + 1]);
});
return result.join('');
};
}

/**
* Creates a bid requests for a given bid.
*
* @param {BidRequest} bid The bid params to use for formatting a request
*/
function formatBidRequest(bid, bidderRequest = {}) {
const {params} = bid;
const {referer} = (bidderRequest.refererInfo || {});
let url = urlTemplate({
adapter: 'prebid',
slot: params.slot,
adkey: params.adkey,
ad_size: params.ad_size,
location: referer,
referrer: referer,
wn: boolToString(/fb_http/i.test(window.name)),
sf: boolToString(window['sfAPI'] || window['$sf']),
fif: boolToString(window['inDapIF'] === true),
if: boolToString(window !== window.top),
stamp: new Date().getTime(),
hbver: ADAPTER_VERSION
});

if (bidderRequest.gdprConsent) {
if (bidderRequest.gdprConsent.gdprApplies !== undefined) {
const gdpr = '&__gdpr=' + (bidderRequest.gdprConsent.gdprApplies ? '1' : '0');
url += gdpr;
}
if (bidderRequest.gdprConsent.consentString !== undefined) {
url += `&__consent=${bidderRequest.gdprConsent.consentString}`;
}
}

// ccpa support
if (bidderRequest.uspConsent) {
url += `&__us_privacy=${bidderRequest.uspConsent}`
}

return {
method: 'GET',
url: url,
bidId: bid.bidId
};
}

function isResponseValid(response) {
return !/^\s*\{\s*"advertisementAvailable"\s*:\s*false/i.test(response.content) &&
response.content.indexOf('<VAST version="2.0"></VAST>') === -1 && (typeof response.cpm !== 'undefined') &&
response.status === 1;
}

export const spec = {
code: BIDDER_CODE,
aliases: ['lsm'],
supportedMediaTypes: [BANNER, VIDEO],

isBidRequestValid: (bid = {}) => {
const {params = {}} = bid;
return !!(params.slot && params.adkey && params.ad_size);
},

buildRequests: (validBidRequests, bidderRequest) => {
return validBidRequests.map(bid => {
return formatBidRequest(bid, bidderRequest)
});
},

interpretResponse: (serverResponse, bidRequest) => {
const bidResponses = [];
let response = serverResponse.body;

if (!isResponseValid(response)) {
return bidResponses;
}

const bidResponse = {
requestId: bidRequest.bidId,
cpm: response.cpm,
width: response.width,
height: response.height,
creativeId: response.creativeId,
currency: response.currency ? response.currency : 'USD',
netRevenue: response.netRevenue ? response.netRevenue : true,
ttl: response.ttl ? response.ttl : 86400
};

if (response.hasOwnProperty('dealId')) {
bidResponse.dealId = response.dealId;
}
if (response.content_type.indexOf('vast') > -1) {
if (typeof response.vastUrl !== 'undefined') {
bidResponse.vastUrl = response.vastUrl;
} else {
bidResponse.vastXml = response.content;
}

bidResponse.mediaType = VIDEO;
} else {
bidResponse.ad = response.content;
bidResponse.mediaType = BANNER;
}

bidResponses.push(bidResponse);
return bidResponses;
}
};

registerBidder(spec);
43 changes: 36 additions & 7 deletions modules/lifestreetBidAdapter.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,41 @@
# Overview

```
Module Name: Lifestreet Bid Adapter

Module Type: Lifestreet Adapter

Maintainer: [email protected]
```

# Description

Module that connects to Lifestreet's demand sources

Values, listed in `ALL_BANNER_SIZES` and `ALL_VIDEO_SIZES` are all the values which our server supports.
For `ad_size`, please use one of that values in following format: `ad_size: WIDTHxHEIGHT`

# Test Parameters
```javascript
var adUnits = [
// Banner adUnit
const ALL_BANNER_SIZES = [
[120, 600], [160, 600], [300, 250], [300, 600], [320, 480],
[320, 50], [468, 60], [510, 510], [600, 300],
[720, 300], [728, 90], [760, 740], [768, 1024]
];

const ALL_VIDEO_SIZES = [
[640, 480], [650, 520], [970, 580]
]
```

# Test Parameters (Banner)
```
const adUnits = [
{
code: 'test-ad',
sizes: [[160, 600]],
mediaTypes: {
banner: {
sizes: [[160, 600]],
}
},
bids: [
{
bidder: 'lifestreet',
Expand All @@ -28,10 +47,20 @@ Module that connects to Lifestreet's demand sources
}
]
},
// Video instream adUnit
];
```

# Test Parameters (Video)
```
const adUnits = [
{
code: 'test-video-ad',
sizes: [[640, 480]],
mediaTypes: {
video: {
playerSize: [[640, 480]],
context: 'instream'
}
},
bids: [
{
bidder: 'lifestreet',
Expand Down
Loading

0 comments on commit 6113cd9

Please sign in to comment.