Skip to content

Commit

Permalink
Add instream & outstream video support to Criteo adapter (prebid#4037)
Browse files Browse the repository at this point in the history
* assign adapter version

* Mapped video parameter from prebid.js to cdb

* Mapped video parameter from prebid.js to cdb

* Ensure that context is consistent with placement and that we do not support longform

* updated playersize property name

* fixed size parsing to be able to handle single player size as well as several

* Changed playersize to plural playersizes in CDB contract

* Use displayurl instead of creative as we want to fetch the direct url vast cache instead a vast wrapper
  • Loading branch information
leonardlabat authored and sa1omon committed Nov 28, 2019
1 parent ee7bbf2 commit 90942e8
Show file tree
Hide file tree
Showing 2 changed files with 530 additions and 7 deletions.
106 changes: 100 additions & 6 deletions modules/criteoBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { loadExternalScript } from '../src/adloader';
import { registerBidder } from '../src/adapters/bidderFactory';
import { config } from '../src/config';
import { BANNER, VIDEO } from '../src/mediaTypes';
import { parse } from '../src/url';
import * as utils from '../src/utils';
import find from 'core-js/library/fn/array/find';
import JSEncrypt from 'jsencrypt/bin/jsencrypt';
import sha256 from 'crypto-js/sha256';
import { config } from '../src/config';

const ADAPTER_VERSION = 17;
const ADAPTER_VERSION = 19;
const BIDDER_CODE = 'criteo';
const CDB_ENDPOINT = '//bidder.criteo.com/cdb';
const CRITEO_VENDOR_ID = 91;
Expand All @@ -30,14 +31,27 @@ OmOSj0/qnYTAYCu0cR5LiyWG79KlIgUyMbp92ulGg24gAyGrVn4+v/4c53WlOEUp
/** @type {BidderSpec} */
export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: [ BANNER, VIDEO ],

/**
* @param {object} bid
* @return {boolean}
*/
isBidRequestValid: bid => (
!!(bid && bid.params && (bid.params.zoneId || bid.params.networkId))
),
isBidRequestValid: (bid) => {
// either one of zoneId or networkId should be set
if (!(bid && bid.params && (bid.params.zoneId || bid.params.networkId))) {
return false;
}

// video media types requires some mandatory params
if (hasVideoMediaType(bid)) {
if (!hasValidVideoMediaType(bid)) {
return false;
}
}

return true;
},

/**
* @param {BidRequest[]} bidRequests
Expand Down Expand Up @@ -112,6 +126,9 @@ export const spec = {
}
if (slot.native) {
bid.ad = createNativeAd(bidId, slot.native, bidRequest.params.nativeCallback);
} else if (slot.video) {
bid.vastUrl = slot.displayurl;
bid.mediaType = VIDEO;
} else {
bid.ad = slot.creative;
}
Expand Down Expand Up @@ -225,7 +242,7 @@ function buildCdbRequest(context, bidRequests, bidderRequest) {
impid: bidRequest.adUnitCode,
transactionid: bidRequest.transactionId,
auctionId: bidRequest.auctionId,
sizes: bidRequest.sizes.map(size => size[0] + 'x' + size[1]),
sizes: getBannerSizes(bidRequest),
};
if (bidRequest.params.zoneId) {
slot.zoneid = bidRequest.params.zoneId;
Expand All @@ -236,6 +253,23 @@ function buildCdbRequest(context, bidRequests, bidderRequest) {
if (bidRequest.params.nativeCallback) {
slot.native = true;
}
if (hasVideoMediaType(bidRequest)) {
const video = {
playersizes: getVideoSizes(bidRequest),
mimes: bidRequest.mediaTypes.video.mimes,
protocols: bidRequest.mediaTypes.video.protocols,
maxduration: bidRequest.mediaTypes.video.maxduration,
api: bidRequest.mediaTypes.video.api
}

video.skip = bidRequest.params.video.skip;
video.placement = bidRequest.params.video.placement;
video.minduration = bidRequest.params.video.minduration;
video.playbackmethod = bidRequest.params.video.playbackmethod;
video.startdelay = bidRequest.params.video.startdelay;

slot.video = video;
}
return slot;
}),
};
Expand All @@ -262,6 +296,66 @@ function buildCdbRequest(context, bidRequests, bidderRequest) {
return request;
}

function getVideoSizes(bidRequest) {
return parseSizes(utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize'));
}

function getBannerSizes(bidRequest) {
return parseSizes(utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes') || bidRequest.sizes);
}

function parseSize(size) {
return size[0] + 'x' + size[1];
}

function parseSizes(sizes) {
if (Array.isArray(sizes[0])) { // is there several sizes ? (ie. [[728,90],[200,300]])
return sizes.map(size => parseSize(size));
}

return [parseSize(sizes)]; // or a single one ? (ie. [728,90])
}

function hasVideoMediaType(bidRequest) {
if (utils.deepAccess(bidRequest, 'params.video') === undefined) {
return false;
}
return utils.deepAccess(bidRequest, 'mediaTypes.video') !== undefined;
}

function hasValidVideoMediaType(bidRequest) {
let isValid = true;

var requiredMediaTypesParams = ['mimes', 'playerSize', 'maxduration', 'protocols', 'api'];

requiredMediaTypesParams.forEach(function(param) {
if (utils.deepAccess(bidRequest, 'mediaTypes.video.' + param) === undefined) {
isValid = false;
utils.logError('Criteo Bid Adapter: mediaTypes.video.' + param + ' is required');
}
});

var requiredParams = ['skip', 'placement', 'playbackmethod'];

requiredParams.forEach(function(param) {
if (utils.deepAccess(bidRequest, 'params.video.' + param) === undefined) {
isValid = false;
utils.logError('Criteo Bid Adapter: params.video.' + param + ' is required');
}
});

if (isValid) {
// We do not support long form for now, also we have to check that context & placement are consistent
if (bidRequest.mediaTypes.video.context == 'instream' && bidRequest.params.video.placement === 1) {
return true;
} else if (bidRequest.mediaTypes.video.context == 'outstream' && bidRequest.params.video.placement !== 1) {
return true;
}
}

return false;
}

/**
* @param {string} id
* @param {*} payload
Expand Down
Loading

0 comments on commit 90942e8

Please sign in to comment.