Skip to content

Commit

Permalink
Merge branch 'master' into prebid-3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Fawke committed Nov 11, 2019
2 parents 3d99998 + 12b7eed commit 46e635b
Show file tree
Hide file tree
Showing 9 changed files with 658 additions and 7 deletions.
142 changes: 142 additions & 0 deletions modules/deepintentBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import {registerBidder} from '../src/adapters/bidderFactory';
import {BANNER} from '../src/mediaTypes';
import * as utils from '../src/utils';
const BIDDER_CODE = 'deepintent';
const BIDDER_ENDPOINT = 'https://prebid.deepintent.com/prebid';
const USER_SYNC_URL = 'https://beacon.deepintent.com/usersync.html';

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

// tagId is mandatory param
isBidRequestValid: bid => {
let valid = false;
if (bid && bid.params && bid.params.tagId) {
if (typeof bid.params.tagId === 'string' || bid.params.tagId instanceof String) {
valid = true;
}
}
return valid;
},
interpretResponse: function(bidResponse, request) {
let responses = [];
if (bidResponse && bidResponse.body) {
let bids = bidResponse.body.seatbid && bidResponse.body.seatbid[0] ? bidResponse.body.seatbid[0].bid : [];
responses = bids.map(bid => formatResponse(bid))
}
return responses;
},
buildRequests: function (validBidRequests, bidderRequest) {
const openRtbBidRequest = {
id: utils.generateUUID(),
at: 1,
imp: validBidRequests.map(bid => buildImpression(bid)),
site: buildSite(bidderRequest),
device: buildDevice(),
source: {
fd: 0,
ext: {
type: 2
}
}
};

return {
method: 'POST',
url: BIDDER_ENDPOINT,
data: JSON.stringify(openRtbBidRequest),
options: {
contentType: 'application/json'
}
};
},
/**
* Register User Sync.
*/
getUserSyncs: syncOptions => {
if (syncOptions.iframeEnabled) {
return [{
type: 'iframe',
url: USER_SYNC_URL
}];
}
}

};

function formatResponse(bid) {
return {
requestId: bid && bid.impid ? bid.impid : undefined,
cpm: bid && bid.price ? bid.price : 0.0,
width: bid && bid.w ? bid.w : 0,
height: bid && bid.h ? bid.h : 0,
ad: bid && bid.adm ? bid.adm : '',
creativeId: bid && bid.crid ? bid.crid : undefined,
netRevenue: false,
currency: bid && bid.cur ? bid.cur : 'USD',
ttl: 300,
dealId: bid && bid.dealId ? bid.dealId : undefined
}
}

function buildImpression(bid) {
return {
id: bid.bidId,
tagid: bid.params.tagId || '',
secure: window.location.protocol === 'https' ? 1 : 0,
banner: buildBanner(bid),
ext: bid.params.custom ? bid.params.custom : {}
};
}

function buildBanner(bid) {
if (utils.deepAccess(bid, 'mediaTypes.banner')) {
// Get Sizes from MediaTypes Object, Will always take first size, will be overrided by params for exact w,h
if (utils.deepAccess(bid, 'mediaTypes.banner.sizes') && !bid.params.height && !bid.params.width) {
let sizes = utils.deepAccess(bid, 'mediaTypes.banner.sizes');
if (utils.isArray(sizes) && sizes.length > 0) {
return {
h: sizes[0][1],
w: sizes[0][0]
}
}
} else {
return {
h: bid.params.height,
w: bid.params.width
}
}
}
}

function buildSite(bidderRequest) {
let site = {};
if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer) {
site.page = bidderRequest.refererInfo.referer;
site.domain = getDomain(bidderRequest.refererInfo.referer);
}
return site;
}

function getDomain(referer) {
if (referer) {
let domainA = document.createElement('a');
domainA.href = referer;
return domainA.hostname;
}
}

function buildDevice() {
return {
ua: navigator.userAgent,
js: 1,
dnt: (navigator.doNotTrack == 'yes' || navigator.doNotTrack === '1') ? 1 : 0,
h: screen.height,
w: screen.width,
language: navigator.language
}
}

registerBidder(spec);
53 changes: 53 additions & 0 deletions modules/deepintentBidAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Overview

```
Module Name: Deepintent Bidder Adapter
Module Type: Bidder Adapter
Maintainer: prebid@deepintent.com
```

# Description

Deepintent currently supports the BANNER type ads through prebid js

Module that connects to Deepintent's demand sources.

# Banner Test Request
```
var adUnits = [
{
code: 'di_adUnit1',
mediaTypes: {
banner: {
sizes: [[300, 250]], // a display size, only first one will be picked up since multiple ad sizes are not supported yet
}
}
bids: [
{
bidder: 'deepintent',
params: {
tagId: '1300', // Required parameter
w: 300, // Width and Height here will override sizes in mediatype
h: 250,
custom: { // Custom parameters in form of key value pairs
user_min_age: 18
}
}
}
]
}
];
```

###Recommended User Sync Configuration

```javascript
pbjs.setConfig({
userSync: {
iframeEnabled: true,
enabledBidders: ['deepintent'],
syncDelay: 3000
}});


```
15 changes: 14 additions & 1 deletion modules/pulsepointBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export const spec = {
badv: bidRequests[0].params.badv,
user: user(bidRequests[0], bidderRequest),
regs: regs(bidderRequest),
source: source(bidRequests[0].schain),
};
return {
method: 'POST',
Expand Down Expand Up @@ -116,7 +117,7 @@ function bidResponseAvailable(request, response) {
adId: id,
ttl: idToBidMap[id].exp || DEFAULT_BID_TTL,
netRevenue: DEFAULT_NET_REVENUE,
currency: idToBidMap[id].cur || DEFAULT_CURRENCY
currency: bidResponse.cur || DEFAULT_CURRENCY
};
if (idToImpMap[id]['native']) {
bid['native'] = nativeResponse(idToImpMap[id], idToBidMap[id]);
Expand Down Expand Up @@ -428,6 +429,18 @@ function regs(bidderRequest) {
return null;
}

/**
* Creates source object with supply chain
*/
function source(schain) {
if (schain) {
return {
ext: { schain }
};
}
return null;
}

/**
* Parses the native response from the Bid given.
*/
Expand Down
68 changes: 66 additions & 2 deletions modules/rubiconBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,10 @@ export const spec = {
utils.deepSetValue(data, 'regs.coppa', 1);
}

if (bidRequest.schain && hasValidSupplyChainParams(bidRequest.schain)) {
utils.deepSetValue(data, 'source.ext.schain', bidRequest.schain);
}

return {
method: 'POST',
url: VIDEO_ENDPOINT,
Expand All @@ -277,7 +281,7 @@ export const spec = {
url: FASTLANE_ENDPOINT,
data: spec.getOrderedParams(bidParams).reduce((paramString, key) => {
const propValue = bidParams[key];
return ((utils.isStr(propValue) && propValue !== '') || utils.isNumber(propValue)) ? `${paramString}${key}=${encodeURIComponent(propValue)}&` : paramString;
return ((utils.isStr(propValue) && propValue !== '') || utils.isNumber(propValue)) ? `${paramString}${encodeParam(key, propValue)}&` : paramString;
}, '') + `slots=1&rand=${Math.random()}`,
bidRequest
};
Expand Down Expand Up @@ -308,7 +312,7 @@ export const spec = {
url: FASTLANE_ENDPOINT,
data: spec.getOrderedParams(combinedSlotParams).reduce((paramString, key) => {
const propValue = combinedSlotParams[key];
return ((utils.isStr(propValue) && propValue !== '') || utils.isNumber(propValue)) ? `${paramString}${key}=${encodeURIComponent(propValue)}&` : paramString;
return ((utils.isStr(propValue) && propValue !== '') || utils.isNumber(propValue)) ? `${paramString}${encodeParam(key, propValue)}&` : paramString;
}, '') + `slots=${bidsInGroup.length}&rand=${Math.random()}`,
bidRequest: bidsInGroup
});
Expand All @@ -332,6 +336,8 @@ export const spec = {
'p_pos',
'gdpr',
'gdpr_consent',
'rp_schain',
'rf',
'tpid_tdid',
'tpid_liveintent.com',
'tg_v.LIseg',
Expand Down Expand Up @@ -482,9 +488,38 @@ export const spec = {
data['coppa'] = 1;
}

// if SupplyChain is supplied and contains all required fields
if (bidRequest.schain && hasValidSupplyChainParams(bidRequest.schain)) {
data.rp_schain = spec.serializeSupplyChain(bidRequest.schain);
}

return data;
},

/**
* Serializes schain params according to OpenRTB requirements
* @param {Object} supplyChain
* @returns {String}
*/
serializeSupplyChain: function (supplyChain) {
const supplyChainIsValid = hasValidSupplyChainParams(supplyChain);
if (!supplyChainIsValid) return '';
const { ver, complete, nodes } = supplyChain;
return `${ver},${complete}!${spec.serializeSupplyChainNodes(nodes)}`;
},

/**
* Properly sorts schain object params
* @param {Array} nodes
* @returns {String}
*/
serializeSupplyChainNodes: function (nodes) {
const nodePropOrder = ['asi', 'sid', 'hp', 'rid', 'name', 'domain'];
return nodes.map(node => {
return nodePropOrder.map(prop => encodeURIComponent(node[prop] || '')).join(',');
}).join('!');
},

/**
* @param {*} responseObj
* @param {BidRequest|Object.<string, BidRequest[]>} bidRequest - if request was SRA the bidRequest argument will be a keyed BidRequest array object,
Expand Down Expand Up @@ -982,6 +1017,35 @@ export function hasValidVideoParams(bid) {
return isValid;
}

/**
* Make sure the required params are present
* @param {Object} schain
* @param {Bool}
*/
export function hasValidSupplyChainParams(schain) {
let isValid = false;
const requiredFields = ['asi', 'sid', 'hp'];
if (!schain.nodes) return isValid;
isValid = schain.nodes.reduce((status, node) => {
if (!status) return status;
return requiredFields.every(field => node[field]);
}, true);
if (!isValid) utils.logError('Rubicon: required schain params missing');
return isValid;
}

/**
* Creates a URL key value param, encoding the
* param unless the key is schain
* @param {String} key
* @param {String} param
* @returns {String}
*/
export function encodeParam(key, param) {
if (key === 'rp_schain') return `rp_schain=${param}`;
return `${key}=${encodeURIComponent(param)}`;
}

/**
* split array into multiple arrays of defined size
* @param {Array} array
Expand Down
4 changes: 4 additions & 0 deletions modules/teadsBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ export const spec = {
hb_version: '$prebid.version$'
};

if (validBidRequests[0].schain) {
payload.schain = validBidRequests[0].schain;
}

let gdpr = bidderRequest.gdprConsent;
if (bidderRequest && gdpr) {
let isCmp = (typeof gdpr.gdprApplies === 'boolean')
Expand Down
Loading

0 comments on commit 46e635b

Please sign in to comment.