Skip to content

Commit

Permalink
Videonow Bid Adapter: Initial Bid Adapter Release (#8669)
Browse files Browse the repository at this point in the history
* Videonow bid adapter: add videonow bid adapter

* Update videonowBidAdapter.md

Co-authored-by: Patrick McCann <pmccann@cafemedia.com>
  • Loading branch information
regulyarniy and patmmccann authored Jul 27, 2022
1 parent d22f149 commit fbcecc9
Show file tree
Hide file tree
Showing 3 changed files with 239 additions and 0 deletions.
122 changes: 122 additions & 0 deletions modules/videonowBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER} from '../src/mediaTypes.js';
import {_each, getBidIdParameter, getValue, logError, logInfo} from '../src/utils.js';

const BIDDER_CODE = 'videonow';
const RTB_URL = 'https://adx.videonow.ru/yhb'
const DEFAULT_CURRENCY = 'RUB'
const DEFAULT_CODE_TYPE = 'combo'
const TTL_SECONDS = 60 * 5

export const spec = {

code: BIDDER_CODE,
url: RTB_URL,
supportedMediaTypes: [ BANNER ],

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

if (!bidRequest.params.pId) {
logError('failed validation: pId not declared');
return false
}

return true
},

/**
* Make a server request from the list of BidRequests.
*
* @param {validBidRequests[]} validBidRequests - an array of bids
* @param bidderRequest
* @return ServerRequest Info describing the request to the server.
*/
buildRequests: function (validBidRequests, bidderRequest) {
logInfo('validBidRequests', validBidRequests);

const bidRequests = [];

_each(validBidRequests, (bid) => {
const bidId = getBidIdParameter('bidId', bid)
const placementId = getValue(bid.params, 'pId')
const currency = getValue(bid.params, 'currency') || DEFAULT_CURRENCY
const url = getValue(bid.params, 'url') || RTB_URL
const codeType = getValue(bid.params, 'codeType') || DEFAULT_CODE_TYPE
const sizes = getValue(bid, 'sizes')

bidRequests.push({
method: 'POST',
url,
data: {
places: [
{
id: bidId,
placementId,
codeType,
sizes
}
],
settings: {
currency,
}
},
})
})

return bidRequests;
},

/**
* Unpack the response from the server into a list of bids.
*
* @param {ServerResponse} serverResponse A successful response from the server.
* @param {BidRequest} bidRequest The bid params
* @return {Bid[]} An array of bids which were nested inside the server.
*/
interpretResponse: function (serverResponse, bidRequest) {
logInfo('serverResponse', serverResponse.body);

const responsesBody = serverResponse ? serverResponse.body : {};
const bidResponses = [];
try {
if (!responsesBody?.bids?.length) {
return [];
}

_each(responsesBody.bids, (bid) => {
if (bid?.displayCode) {
const bidResponse = {
requestId: bid.id,
cpm: bid.cpm,
currency: bid.currency,
width: bid.size.width,
height: bid.size.height,
ad: bid.displayCode,
ttl: TTL_SECONDS,
creativeId: bid.id,
netRevenue: true,
meta: {
advertiserDomains: bid.adDomain ? [bid.adDomain] : []
}
};
bidResponses.push(bidResponse)
}
})
} catch (error) {
logError(error);
}

return bidResponses
},
}

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

**Module Name**: Videonow Bidder Adapter
**Module Type**: Bidder Adapter
**Maintainer**: nregularniy@videonow.ru

# Description

Videonow Bidder Adapter for Prebid.js. About: https://videonow.ru/


Use `videonow` as bidder:

# Params
- `pId` required, profile ID
- `currency` optional, currency, default is 'RUB'
- `url` optional, for debug, bidder url
- `codeType` optional, for debug, yhb codeType

## AdUnits configuration example
```
var adUnits = [{
code: 'your-slot', //use exactly the same code as your slot div id.
mediaTypes: {
banner: {
sizes: [[640, 480]]
}
},
bids: [{
bidder: 'videonow',
params: {
pId: '1234',
currency: 'RUB',
}
}]
}];
```
80 changes: 80 additions & 0 deletions test/spec/modules/videonowBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import {expect} from 'chai';
import {spec} from 'modules/videonowBidAdapter';

describe('videonowBidAdapter', function () {
it('minimal params', function () {
expect(spec.isBidRequestValid({
bidder: 'videonow',
params: {
pId: 'advDesktopBillboard'
}})).to.equal(true)
})

it('minimal params no placementId', function () {
expect(spec.isBidRequestValid({
bidder: 'videonow',
params: {
currency: `GBP`
}})).to.equal(false)
})

it('generated_params common case', function () {
const bidRequestData = [{
bidId: 'bid1234',
bidder: 'videonow',
params: {
pId: 'advDesktopBillboard',
currency: `GBP`
},
sizes: [[240, 400]]
}];

const request = spec.buildRequests(bidRequestData);
const req_data = request[0].data;

expect(req_data.places[0].id).to.equal(`bid1234`)
expect(req_data.places[0].placementId).to.equal(`advDesktopBillboard`)
expect(req_data.settings.currency).to.equal(`GBP`)
expect(req_data.places[0].sizes[0][0]).to.equal(240);
expect(req_data.places[0].sizes[0][1]).to.equal(400);
});

it('response_params common case', function () {
const bidRequestData = {
data: {
bidId: 'bid1234'
}
};

const serverResponse = {
body: {
bids: [
{
'displayCode': '<html><body>test html</body></html>',
'id': '123456',
'cpm': 375,
'currency': 'RUB',
'placementId': 'profileName',
'codeType': 'js',
'size': {
'width': 640,
'height': 480
}
}
]
}
};

const bids = spec.interpretResponse(serverResponse, bidRequestData);
expect(bids).to.have.lengthOf(1);
const bid = bids[0];
expect(bid.requestId).to.equal('123456')
expect(bid.cpm).to.equal(375);
expect(bid.currency).to.equal('RUB');
expect(bid.width).to.equal(640);
expect(bid.height).to.equal(480);
expect(bid.ad).to.equal('<html><body>test html</body></html>');
expect(bid.creativeId).to.equal(`123456`)
expect(bid.netRevenue).to.equal(true);
});
})

0 comments on commit fbcecc9

Please sign in to comment.