From 94f954907155c93d609fe6264f3e16d182f856f1 Mon Sep 17 00:00:00 2001 From: Chris Huie Date: Tue, 11 Oct 2022 05:07:02 -0600 Subject: [PATCH] Eplanning Bid Adapter: add support for video (#9044) * add video * move up imptypes logic * fix linting * update curly braces * fix spaces linting * fix line --- modules/eplanningBidAdapter.js | 50 ++- test/spec/modules/eplanningBidAdapter_spec.js | 286 +++++++++++++++++- 2 files changed, 333 insertions(+), 3 deletions(-) diff --git a/modules/eplanningBidAdapter.js b/modules/eplanningBidAdapter.js index 0d37b72f4ad..b60c3571d47 100644 --- a/modules/eplanningBidAdapter.js +++ b/modules/eplanningBidAdapter.js @@ -2,6 +2,7 @@ import {getWindowSelf, isEmpty, parseSizesInput, isGptPubadsDefined, isSlotMatch import {getGlobal} from '../src/prebidGlobal.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {getStorageManager} from '../src/storageManager.js'; +import {BANNER, VIDEO} from '../src/mediaTypes.js'; const BIDDER_CODE = 'eplanning'; export const storage = getStorageManager({bidderCode: BIDDER_CODE}); @@ -19,9 +20,14 @@ const STORAGE_VIEW_PREFIX = 'pbvi_'; const mobileUserAgent = isMobileUserAgent(); const PRIORITY_ORDER_FOR_MOBILE_SIZES_ASC = ['1x1', '300x50', '320x50', '300x250']; const PRIORITY_ORDER_FOR_DESKTOP_SIZES_ASC = ['1x1', '970x90', '970x250', '160x600', '300x600', '728x90', '300x250']; +const VAST_INSTREAM = 1; +const VAST_OUTSTREAM = 2; +const VAST_VERSION_DEFAULT = 3; +const DEFAULT_SIZE_VAST = '640x480'; export const spec = { code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO], isBidRequestValid: function(bid) { return Boolean(bid.params.ci) || Boolean(bid.params.t); @@ -86,6 +92,10 @@ export const spec = { params['e_' + id] = (typeof userIds[id] === 'object') ? encodeURIComponent(JSON.stringify(userIds[id])) : encodeURIComponent(userIds[id]); } } + if (spaces.impType) { + params.vctx = spaces.impType & VAST_INSTREAM ? VAST_INSTREAM : VAST_OUTSTREAM; + params.vv = VAST_VERSION_DEFAULT; + } } return { @@ -108,7 +118,6 @@ export const spec = { cpm: ad.pr, width: ad.w, height: ad.h, - ad: ad.adm, ttl: TTL, creativeId: ad.crid, netRevenue: NET_REVENUE, @@ -119,6 +128,13 @@ export const spec = { advertiserDomains: ad.adom }; } + if (isVastResponse(ad)) { + bidResponse.vastXml = ad.adm; + bidResponse.mediaTypes = VIDEO; + } else { + bidResponse.ad = ad.adm; + } + bidResponses.push(bidResponse); }); } @@ -236,17 +252,42 @@ function getSpacesStruct(bids) { return e; } +function getFirstSizeVast(sizes) { + if (sizes == undefined || !Array.isArray(sizes)) { + return undefined; + } + + let size = Array.isArray(sizes[0]) ? sizes[0] : sizes; + + return (Array.isArray(size) && size.length == 2) ? size : undefined; +} + function cleanName(name) { return name.replace(/_|\.|-|\//g, '').replace(/\)\(|\(|\)|:/g, '_').replace(/^_+|_+$/g, ''); } function getSpaces(bidRequests, ml) { + let impType = bidRequests.reduce((previousBits, bid) => (bid.mediaTypes && bid.mediaTypes[VIDEO]) ? (bid.mediaTypes[VIDEO].context == 'outstream' ? (previousBits | 2) : (previousBits | 1)) : previousBits, 0); + // Only one type of auction is supported at a time + if (impType) { + bidRequests = bidRequests.filter((bid) => bid.mediaTypes && bid.mediaTypes[VIDEO] && (impType & VAST_INSTREAM ? (!bid.mediaTypes[VIDEO].context || bid.mediaTypes[VIDEO].context == 'instream') : (bid.mediaTypes[VIDEO].context == 'outstream'))); + } + let spacesStruct = getSpacesStruct(bidRequests); - let es = {str: '', vs: '', map: {}}; + let es = {str: '', vs: '', map: {}, impType: impType}; es.str = Object.keys(spacesStruct).map(size => spacesStruct[size].map((bid, i) => { es.vs += getVs(bid); let name; + + if (impType) { + let firstSize = getFirstSizeVast(bid.mediaTypes[VIDEO].playerSize); + let sizeVast = firstSize ? firstSize.join('x') : DEFAULT_SIZE_VAST; + name = 'video_' + sizeVast + '_' + i; + es.map[name] = bid.bidId; + return name + ':' + sizeVast + ';1'; + } + if (ml) { name = cleanName(bid.adUnitCode); } else { @@ -462,4 +503,9 @@ function registerAuction(storageID) { return true; } + +function isVastResponse(bid) { + return bid.adm.match(/^(