Skip to content

Commit

Permalink
displayio bid adapter, tests, doc (#7906)
Browse files Browse the repository at this point in the history
Co-authored-by: Anna Philippova <annyphilippova@gmail.com>
  • Loading branch information
philan15 and philan15 authored Jan 18, 2022
1 parent d86b409 commit 5b47f53
Show file tree
Hide file tree
Showing 3 changed files with 544 additions and 0 deletions.
157 changes: 157 additions & 0 deletions modules/displayioBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';

const BIDDER_VERSION = '1.0.0';
const BIDDER_CODE = 'displayio';
const GVLID = 999;
const BID_TTL = 300;
const SUPPORTED_AD_TYPES = [BANNER, VIDEO];
const DEFAULT_CURRENCY = 'USD';

export const spec = {
code: BIDDER_CODE,
gvlid: GVLID,
supportedMediaTypes: SUPPORTED_AD_TYPES,
isBidRequestValid: function(bid) {
return !!(bid.params && bid.params.placementId && bid.params.siteId &&
bid.params.adsSrvDomain && bid.params.cdnDomain);
},
buildRequests: function (bidRequests, bidderRequest) {
return bidRequests.map(bid => {
let url = '//' + bid.params.adsSrvDomain + '/srv?method=getPlacement&app=' +
bid.params.siteId + '&placement=' + bid.params.placementId;
const data = this._getPayload(bid, bidderRequest);
return {
method: 'POST',
headers: {'Content-Type': 'application/json;charset=utf-8'},
url,
data
};
});
},
interpretResponse: function (serverResponse, serverRequest) {
const ads = serverResponse.body.data.ads;
const bidResponses = [];
const { data } = serverRequest.data;
if (ads.length) {
const adData = ads[0].ad.data;
const bidResponse = {
requestId: data.id,
cpm: adData.ecpm,
width: adData.w,
height: adData.h,
netRevenue: true,
ttl: BID_TTL,
creativeId: adData.adId || 0,
currency: DEFAULT_CURRENCY,
referrer: data.data.ref,
mediaType: ads[0].ad.subtype,
ad: adData.markup,
placement: data.placement,
adData: adData
};
if (bidResponse.vastUrl === 'videoVast') {
bidResponse.vastUrl = adData.videos[0].url
}
bidResponses.push(bidResponse);
}
return bidResponses;
},
_getPayload: function (bid, bidderRequest) {
const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
const userSession = 'us_web_xxxxxxxxxxxx'.replace(/[x]/g, c => {
let r = Math.random() * 16 | 0;
let v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
const { params } = bid;
const { siteId, placementId } = params;
const { refererInfo, uspConsent, gdprConsent } = bidderRequest;
const mediation = {consent: '-1', gdpr: '-1'};
if (gdprConsent) {
if (gdprConsent.consentString !== undefined) {
mediation.consent = gdprConsent.consentString;
}
if (gdprConsent.gdprApplies !== undefined) {
mediation.gdpr = gdprConsent.gdprApplies ? '1' : '0';
}
}
const payload = {
userSession,
data: {
id: bid.bidId,
action: 'getPlacement',
app: siteId,
placement: placementId,
data: {
pagecat: params.pageCategory ? params.pageCategory.split(',').map(k => k.trim()) : [],
keywords: params.keywords ? params.keywords.split(',').map(k => k.trim()) : [],
lang_content: document.documentElement.lang,
lang: window.navigator.language,
domain: window.location.hostname,
page: window.location.href,
ref: refererInfo.referer,
userids: _getUserIDs(),
geo: '',
},
complianceData: {
child: '-1',
us_privacy: uspConsent,
dnt: window.navigator.doNotTrack,
iabConsent: {},
mediation: {
consent: mediation.consent,
gdpr: mediation.gdpr,
}
},
integration: 'JS',
omidpn: 'Displayio',
mediationPlatform: 0,
prebidVersion: BIDDER_VERSION,
device: {
w: window.screen.width,
h: window.screen.height,
connection_type: connection ? connection.effectiveType : '',
}
}
}
if (navigator.permissions) {
navigator.permissions.query({ name: 'geolocation' })
.then((result) => {
if (result.state === 'granted') {
payload.data.data.geo = _getGeoData();
}
});
}
return payload
}
};

function _getUserIDs () {
let ids = {};
try {
ids = window.owpbjs.getUserIdsAsEids();
} catch (e) {}
return ids;
}

async function _getGeoData () {
let geoData = null;
const getCurrentPosition = () => {
return new Promise((resolve, reject) =>
navigator.geolocation.getCurrentPosition(resolve, reject)
);
}
try {
const position = await getCurrentPosition();
let {latitude, longitude, accuracy} = position.coords;
geoData = {
'lat': latitude,
'lng': longitude,
'precision': accuracy
};
} catch (e) {}
return geoData
}

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

```
Module Name: DisplayIO Bidder Adapter
Module Type: Bidder Adapter
```

# Description

Module that connects to display.io's demand sources.
Web mobile (not relevant for web desktop).


#Features
| Feature | | Feature | |
|---------------|---------------------------------------------------------|-----------------------|-----|
| Bidder Code | displayio | Prebid member | no |
| Media Types | Banner, video. <br/>Sizes (display 320x480 / vertical video) | GVL ID | no |
| GDPR Support | yes | Prebid.js Adapter | yes |
| USP Support | yes | Prebid Server Adapter | no |


#Global configuration
```javascript
<head>
<script src="https://cdn.display.io/webis/webis.min.js"></script>
</head>
<script>
......................................
var CMP_TIMEOUT = 8000;
var consentManagement = {
gdpr: {
cmpApi: 'iab',
timeout: CMP_TIMEOUT,
defaultGdprScope: true
},
usp: {
cmpApi: 'iab',
timeout: CMP_TIMEOUT
}
}

if (typeof __tcfapi !== 'function') {
delete consentManagement.gdpr;
}

pbjs.que.push(function() {
pbjs.setConfig({consentManagement})
});


......................................

function initAdserver(bidResponses) {
if (pbjs.initAdserverSet) return;
pbjs.initAdserverSet = true;

...........................

const displayioBids = getDisplayioBid(bidResponses)
displayioBids.forEach(b => {
const {adData, placement} = b[1].bids[0];
webis.init(adData, b[0], {placement})
})

}

function getDisplayioBid(bidResponses) {
const codes = adUnits.map(u => u.code);
const bids = Object.entries(bidResponses);
bids.filter(([key, value]) => codes.includes(key) && value.bids[0].bidderCode === 'displayio');
return bids;
}

......................................

```


# Bid Parameters

| Name | Scope | Type | Description | Example |
|----------------| ----- | ---- |----------------------------------------|-------------------------------|
| `siteId` | required | Number | SiteId and PlacementID are your inventory IDs on the display.io platform (please ask your Account Manager for your site and placement IDs). | 7753 |
| `placementId` | required | Number | SiteId and PlacementID are your inventory IDs on the display.io platform (please ask your Account Manager for your site and placement IDs). | 5375 |
| `adsSrvDomain` | required | String | | "appsrv.display.io" |
| `cdnDomain` | required | String | | "cdn.display.io" |
| `pageCategory` | optional | String | Comma-separated list of IAB content categories that describe the current page or view of the site, list of available values. | "pageCategory1, pageCategory2" |
| `keywords` | optional | String | Comma-separated list of keywords describing the content. | "keyword1, keyword2, keyword3" |
| `custom` | optional | Object | User-defined targeting key-value pairs. custom applies to a specific unit. | `{headerTextColor: "red", fixedHeaderSelector: '.site-header'}` |
| `custom.headerText`| optional | String | Ad container header text. By default, text is "Scroll to continue with content". Limited to 50 characters. | "Our awesome advertisement"|
| `custom.headerTextColor`| optional | String | Ad container header text color, "white" by default | "#2196f3"|
| `custom.headerBackgroundColor`| optional | String | Ad container header background color, "black" by default | "#fff" |
| `custom.adContainerBackgroundColor`| optional | String | Ad container body background color, "transparent" by default | "#000"|
| `custom.fixedHeaderSelector`| optional | String | In case your webpage has a fixed header – the header Id attribute or header class attribute should be defined as a value for parameter fixedHeaderSelector. | ".site-header"|

# adUnit configuration example
```javascript
var adUnits = [
{
code: 'ad-tag-1',
mediaTypes: {
banner: {
sizes: [[320, 480]]
},
video: {
sizes: [[360, 640]]
},
},
bids: [
{
bidder: 'displayio',
params: {
siteId: 1,
placementId: 1,
adsSrvDomain: 'appsrv.display.io',
cdnDomain: 'cdn.display.io',
pageCategory: 'pageCategory1, pageCategory2', //comma separated
keywords: 'keyword1, keyword2, keyword3', //comma separated
custom: {
headerText: 'Our awesome advertisement',
headerTextColor: '#2196f3',
headerBackgroundColor: 'black',
adContainerBackgroundColor: 'transparent',
fixedHeaderSelector: '.site-header',
},
}
}
]
},
// minimal required options
{
code: 'ad-tag-2',
bids: [{
bidder: 'displayio',
params: {
siteId: 1,
placementId: 1,
adsSrvDomain: 'appsrv.display.io',
cdnDomain: 'cdn.display.io',
}
}]
}
];
```

# Additional Details
[Mobile web prebid.js integration](https://www.display.io/documentation/mobile-web-prebid-js-integration/)
Loading

0 comments on commit 5b47f53

Please sign in to comment.