Skip to content

Commit

Permalink
add stroeerCoreBidAdapter (#5830)
Browse files Browse the repository at this point in the history
* add stroeerCoreBidAdapter

* test correction

* refactroring

* add gvl id to spec

Co-authored-by: Jakub Dlouhý <[email protected]>
Co-authored-by: karel koule <[email protected]>
Co-authored-by: Lukáš Havrlant <[email protected]>
  • Loading branch information
4 people authored Oct 12, 2020
1 parent b6bfbef commit e39a812
Show file tree
Hide file tree
Showing 3 changed files with 759 additions and 0 deletions.
196 changes: 196 additions & 0 deletions modules/stroeerCoreBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER} from '../src/mediaTypes.js';
import * as utils from '../src/utils.js';

const GVL_ID = 136;
const BIDDER_CODE = 'stroeerCore';
const DEFAULT_HOST = 'hb.adscale.de';
const DEFAULT_PATH = '/dsh';
const DEFAULT_PORT = '';
const FIVE_MINUTES_IN_SECONDS = 300;
const USER_SYNC_IFRAME_URL = 'https://js.adscale.de/pbsync.html';

const isSecureWindow = () => utils.getWindowSelf().location.protocol === 'https:';
const isMainPageAccessible = () => getMostAccessibleTopWindow() === utils.getWindowTop();

function getTopWindowReferrer() {
try {
return utils.getWindowTop().document.referrer;
} catch (e) {
return utils.getWindowSelf().referrer;
}
}

function getMostAccessibleTopWindow() {
let res = utils.getWindowSelf();

try {
while (utils.getWindowTop().top !== res && res.parent.location.href.length) {
res = res.parent;
}
} catch (ignore) {
}

return res;
}

function elementInView(elementId) {
const resolveElement = (elId) => {
const win = utils.getWindowSelf();

return win.document.getElementById(elId);
};

const visibleInWindow = (el, win) => {
const rect = el.getBoundingClientRect();
const inView = (rect.top + rect.height >= 0) && (rect.top <= win.innerHeight);

if (win !== win.parent) {
return inView && visibleInWindow(win.frameElement, win.parent);
}

return inView;
};

try {
return visibleInWindow(resolveElement(elementId), utils.getWindowSelf());
} catch (e) {
// old browser, element not found, cross-origin etc.
}
return undefined;
}

function buildUrl({host: hostname = DEFAULT_HOST, port = DEFAULT_PORT, securePort, path: pathname = DEFAULT_PATH}) {
if (securePort) {
port = securePort;
}

return utils.buildUrl({protocol: 'https', hostname, port, pathname});
}

function getGdprParams(gdprConsent) {
if (gdprConsent) {
const consentString = encodeURIComponent(gdprConsent.consentString || '')
const isGdpr = gdprConsent.gdprApplies ? 1 : 0;

return `?gdpr=${isGdpr}&gdpr_consent=${consentString}`
} else {
return '';
}
}

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

isBidRequestValid: (function () {
const validators = [];

const createValidator = (checkFn, errorMsgFn) => {
return (bidRequest) => {
if (checkFn(bidRequest)) {
return true;
} else {
utils.logError(`invalid bid: ${errorMsgFn(bidRequest)}`, 'ERROR');
return false;
}
}
};

function isBanner(bidReq) {
return (!bidReq.mediaTypes && !bidReq.mediaType) ||
(bidReq.mediaTypes && bidReq.mediaTypes.banner) ||
bidReq.mediaType === BANNER;
}

validators.push(createValidator((bidReq) => isBanner(bidReq),
bidReq => `bid request ${bidReq.bidId} is not a banner`));
validators.push(createValidator((bidReq) => typeof bidReq.params === 'object',
bidReq => `bid request ${bidReq.bidId} does not have custom params`));
validators.push(createValidator((bidReq) => utils.isStr(bidReq.params.sid),
bidReq => `bid request ${bidReq.bidId} does not have a sid string field`));

return function (bidRequest) {
return validators.every(f => f(bidRequest));
}
}()),

buildRequests: function (validBidRequests = [], bidderRequest) {
const anyBid = bidderRequest.bids[0];

const payload = {
id: bidderRequest.auctionId,
bids: [],
ref: getTopWindowReferrer(),
ssl: isSecureWindow(),
mpa: isMainPageAccessible(),
timeout: bidderRequest.timeout - (Date.now() - bidderRequest.auctionStart)
};

const userIds = anyBid.userId;

if (!utils.isEmpty(userIds)) {
payload.user = {
euids: userIds
};
}

const gdprConsent = bidderRequest.gdprConsent;

if (gdprConsent && gdprConsent.consentString != null && gdprConsent.gdprApplies != null) {
payload.gdpr = {
consent: bidderRequest.gdprConsent.consentString, applies: bidderRequest.gdprConsent.gdprApplies
};
}

function bidSizes(bid) {
return utils.deepAccess(bid, 'mediaTypes.banner.sizes') || bid.sizes /* for prebid < 3 */ || [];
}

validBidRequests.forEach(bid => {
payload.bids.push({
bid: bid.bidId, sid: bid.params.sid, siz: bidSizes(bid), viz: elementInView(bid.adUnitCode)
});
});

return {
method: 'POST', url: buildUrl(anyBid.params), data: payload
}
},

interpretResponse: function (serverResponse) {
const bids = [];

if (serverResponse.body && typeof serverResponse.body === 'object') {
serverResponse.body.bids.forEach(bidResponse => {
bids.push({
requestId: bidResponse.bidId,
cpm: bidResponse.cpm || 0,
width: bidResponse.width || 0,
height: bidResponse.height || 0,
ad: bidResponse.ad,
ttl: FIVE_MINUTES_IN_SECONDS,
currency: 'EUR',
netRevenue: true,
creativeId: '',
});
});
}

return bids;
},

getUserSyncs: function (syncOptions, serverResponses, gdprConsent) {
if (serverResponses.length > 0 && syncOptions.iframeEnabled) {
return [{
type: 'iframe',
url: USER_SYNC_IFRAME_URL + getGdprParams(gdprConsent)
}];
}

return [];
}
};

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

```
Module Name: Stroeer Bidder Adapter
Module Type: Bidder Adapter
Maintainer: [email protected]
```


## Ad unit configuration for publishers

```javascript
const adUnits = [{
code: 'div-gpt-ad-1460505748561-0',
mediaTypes: {
banner: {
sizes: [[300, 250]],
}
},
bids: [{
bidder: 'stroeerCore',
params: {
sid: "06b782cc-091b-4f53-9cd2-0291679aa1ac"
}
}]
}];
```
### Config Notes

* Slot id (`sid`) is required. The adapter will ignore bid requests from prebid if `sid` is not provided. This must be in the decoded form. For example, "1234" as opposed to "MTM0ODA=".
* The server ignores dimensions that are not supported by the slot or by the platform (such as 987x123).
Loading

0 comments on commit e39a812

Please sign in to comment.