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

Big-Richmedia Bid Adapter: initial release #8033

Merged
merged 14 commits into from
Feb 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
117 changes: 117 additions & 0 deletions modules/big-richmediaBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import {BANNER, VIDEO} from '../src/mediaTypes.js';
import {config} from '../src/config.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {spec as baseAdapter} from './appnexusBidAdapter.js'; // eslint-disable-line prebid/validate-imports

const BIDDER_CODE = 'big-richmedia';

const metadataByRequestId = {};

export const spec = {
version: '1.4.0',
code: BIDDER_CODE,
gvlid: baseAdapter.GVLID, // use base adapter gvlid
supportedMediaTypes: [ BANNER, VIDEO ],

/**
* Determines whether or not the given bid request is valid.
*
* @param {object} bid The bid to validate.
* @return boolean True if this is a valid bid, and false otherwise.
*/
isBidRequestValid: function (bid) {
if (!baseAdapter.isBidRequestValid) { return true; }
return baseAdapter.isBidRequestValid(bid);
},

/**
* Make a server request from the list of BidRequests.
*
* @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server.
* @return ServerRequest Info describing the request to the server.
*/
buildRequests: function (bidRequests, bidderRequest) {
if (!baseAdapter.buildRequests) { return []; }

const publisherId = config.getConfig('bigRichmedia.publisherId');
if (typeof publisherId !== 'string') { return []; }

bidRequests.forEach(bidRequest => {
if (bidRequest.params.format === 'skin' && bidRequest.mediaTypes.banner) {
bidRequest.mediaTypes.banner.sizes.push([1800, 1000]);
}
metadataByRequestId[bidRequest.bidId] = { placementId: bidRequest.adUnitCode, bidder: bidRequest.bidder };
});
return baseAdapter.buildRequests(bidRequests, bidderRequest);
},

/**
* Unpack the response from the server into a list of bids.
*
* @param {*} serverResponse A successful response from the server.
* @return {Bid[]} An array of bids which were nested inside the server.
*/
interpretResponse: function (serverResponse, params) {
const publisherId = config.getConfig('bigRichmedia.publisherId');
if (typeof publisherId !== 'string') { return []; }

const bids = baseAdapter.interpretResponse(serverResponse, params);
bids.forEach(bid => {
const { placementId, bidder } = metadataByRequestId[bid.requestId] || {};
const { width = 1, height = 1, ad, creativeId = '', cpm, vastXml, vastUrl } = bid;
const bidRequest = params.bidderRequest.bids.find(({ bidId }) => bidId === bid.requestId);
const format = (bidRequest && bidRequest.params && bidRequest.params.format) || 'video-sticky-footer';
const isReplayable = bidRequest && bidRequest.params && bidRequest.params.isReplayable;
const customSelector = bidRequest && bidRequest.params && bidRequest.params.customSelector;
const renderParams = {
adm: ad,
vastXml,
vastUrl,
width,
height,
placementId,
bidId: bid.requestId,
creativeId: `${creativeId}`,
bidder,
cpm,
format,
customSelector,
isReplayable
};
const encoded = window.btoa(JSON.stringify(renderParams));
bid.ad = `<script src="//cdn.hubvisor.io/wrapper/${publisherId}/richmedia-renderer.js" async="true"></script>
<script>var hbvrm = hbvrm || {}; hbvrm.cmd = hbvrm.cmd || []; hbvrm.cmd.push(function() { hbvrm.render('${encoded}'); });</script>`;

if (bid.mediaType !== 'banner') { // in case this is a video
bid.mediaType = 'banner';
delete bid.renderer;
delete bid.vastUrl;
delete bid.vastXml;
bid.width = 1;
bid.height = 1;
}
});
return bids;
},

getUserSyncs: function (syncOptions, responses, gdprConsent) {
if (!baseAdapter.getUserSyncs) { return []; }
return baseAdapter.getUserSyncs(syncOptions, responses, gdprConsent);
},

transformBidParams: function (params, isOpenRtb) {
if (!baseAdapter.transformBidParams) { return params; }
return baseAdapter.transformBidParams(params, isOpenRtb);
},

/**
* Add element selector to javascript tracker to improve native viewability
* @param {Bid} bid
*/
onBidWon: function (bid) {
if (!baseAdapter.onBidWon) { return; }
baseAdapter.onBidWon(bid);
}
}

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

```
Module Name: BI.Garage Rich Media
Module Type: Bidder Adapter
Maintainer: mediaconsortium-develop@bi.garage.co.jp
```

# Description

Module which renders richmedia demand from a Xandr seat

### Global configuration

```javascript
pbjs.setConfig({
debug: false,
// …,
bigRichmedia: {
publisherId: 'A7FN99NZ98F5ZD4G', // Required
},
});
```

# AdUnit Configuration
```javascript
var adUnits = [
// Skin adUnit
{
code: 'banner-div',
mediaTypes: {
banner: {
sizes: [[300, 250], [300,600]]
}
},
bids: [{
bidder: 'big-richmedia',
params: {
placementId: 12345,
format: 'skin' // This will automatically add 1800x1000 size to banner mediaType
}
}]
},
// Video outstream adUnit
{
code: 'video-outstream',
sizes: [[300, 250]],
mediaTypes: {
video: {
playerSize: [[300, 250]],
context: 'outstream',
// Certain ORTB 2.5 video values can be read from the mediatypes object; below are examples of supported params.
// To note - appnexus supports additional values for our system that are not part of the ORTB spec. If you want
// to use these values, they will have to be declared in the bids[].params.video object instead using the appnexus syntax.
// Between the corresponding values of the mediaTypes.video and params.video objects, the properties in params.video will
// take precedence if declared; eg in the example below, the `skippable: true` setting will be used instead of the `skip: 0`.
minduration: 1,
maxduration: 60,
skip: 0, // 1 - true, 0 - false
skipafter: 5,
playbackmethod: [2], // note - we only support options 1-4 at this time
api: [1,2,3] // note - option 6 is not supported at this time
}
},
bids: [
{
bidder: 'big-richmedia',
params: {
placementId: 12345,
video: {
skippable: true,
playback_method: 'auto_play_sound_off'
},
format: 'video-sticky-footer', // or 'video-sticky-top'
isReplayable: true // Default to false - choose if the video should be replayable or not.
customSelector: '#nav-bar' // custom selector for navbar
}
}
]
}
];
```