UNPKG

mk9-prebid

Version:

Header Bidding Management Library

277 lines (249 loc) 7.43 kB
import {registerBidder} from '../src/adapters/bidderFactory.js'; import * as utils from '../src/utils.js'; import {VIDEO} from '../src/mediaTypes.js'; import {config} from '../src/config.js'; const SUPPORTED_AD_TYPES = [VIDEO]; const BIDDER_CODE = 'rise'; const BIDDER_VERSION = '4.0.1'; const TTL = 360; const CURRENCY = 'USD'; const SELLER_ENDPOINT = 'https://hb.yellowblue.io/'; const MODES = { PRODUCTION: 'hb', TEST: 'hb-test' } const SUPPORTED_SYNC_METHODS = { IFRAME: 'iframe', PIXEL: 'pixel' } export const spec = { code: BIDDER_CODE, version: BIDDER_VERSION, supportedMediaTypes: SUPPORTED_AD_TYPES, isBidRequestValid: function(bidRequest) { return !!(bidRequest.params.org); }, buildRequests: function (bidRequests, bidderRequest) { if (bidRequests.length === 0) { return []; } const requests = []; bidRequests.forEach(bid => { requests.push(buildVideoRequest(bid, bidderRequest)); }); return requests; }, interpretResponse: function({body}) { const bidResponses = []; const bidResponse = { requestId: body.requestId, cpm: body.cpm, width: body.width, height: body.height, creativeId: body.requestId, currency: body.currency, netRevenue: body.netRevenue, ttl: body.ttl || TTL, vastXml: body.vastXml, mediaType: VIDEO }; if (body.adomain && body.adomain.length) { bidResponse.meta = {}; bidResponse.meta.advertiserDomains = body.adomain } bidResponses.push(bidResponse); return bidResponses; }, getUserSyncs: function(syncOptions, serverResponses) { const syncs = []; for (const response of serverResponses) { if (syncOptions.iframeEnabled && response.body.userSyncURL) { syncs.push({ type: 'iframe', url: response.body.userSyncURL }); } if (syncOptions.pixelEnabled && utils.isArray(response.body.userSyncPixels)) { const pixels = response.body.userSyncPixels.map(pixel => { return { type: 'image', url: pixel } }) syncs.push(...pixels) } } return syncs; } }; registerBidder(spec); /** * Get floor price * @param bid {bid} * @returns {Number} */ function getFloor(bid) { if (!utils.isFn(bid.getFloor)) { return 0; } let floorResult = bid.getFloor({ currency: CURRENCY, mediaType: VIDEO, size: '*' }); return floorResult.currency === CURRENCY ? floorResult.floor : 0; } /** * Build the video request * @param bid {bid} * @param bidderRequest {bidderRequest} * @returns {Object} */ function buildVideoRequest(bid, bidderRequest) { const sellerParams = generateParameters(bid, bidderRequest); const {params} = bid; return { method: 'GET', url: getEndpoint(params.testMode), data: sellerParams }; } /** * Get the the ad size from the bid * @param bid {bid} * @returns {Array} */ function getSizes(bid) { if (utils.deepAccess(bid, 'mediaTypes.video.sizes')) { return bid.mediaTypes.video.sizes[0]; } else if (Array.isArray(bid.sizes) && bid.sizes.length > 0) { return bid.sizes[0]; } return []; } /** * Get schain string value * @param schainObject {Object} * @returns {string} */ function getSupplyChain(schainObject) { if (utils.isEmpty(schainObject)) { return ''; } let scStr = `${schainObject.ver},${schainObject.complete}`; schainObject.nodes.forEach((node) => { scStr += '!'; scStr += `${getEncodedValIfNotEmpty(node.asi)},`; scStr += `${getEncodedValIfNotEmpty(node.sid)},`; scStr += `${getEncodedValIfNotEmpty(node.hp)},`; scStr += `${getEncodedValIfNotEmpty(node.rid)},`; scStr += `${getEncodedValIfNotEmpty(node.name)},`; scStr += `${getEncodedValIfNotEmpty(node.domain)}`; }); return scStr; } /** * Get encoded node value * @param val {string} * @returns {string} */ function getEncodedValIfNotEmpty(val) { return !utils.isEmpty(val) ? encodeURIComponent(val) : ''; } /** * Get preferred user-sync method based on publisher configuration * @param bidderCode {string} * @returns {string} */ function getAllowedSyncMethod(filterSettings, bidderCode) { const iframeConfigsToCheck = ['all', 'iframe']; const pixelConfigToCheck = 'image'; if (filterSettings && iframeConfigsToCheck.some(config => isSyncMethodAllowed(filterSettings[config], bidderCode))) { return SUPPORTED_SYNC_METHODS.IFRAME; } if (!filterSettings || !filterSettings[pixelConfigToCheck] || isSyncMethodAllowed(filterSettings[pixelConfigToCheck], bidderCode)) { return SUPPORTED_SYNC_METHODS.PIXEL; } } /** * Check if sync rule is supported * @param syncRule {Object} * @param bidderCode {string} * @returns {boolean} */ function isSyncMethodAllowed(syncRule, bidderCode) { if (!syncRule) { return false; } const isInclude = syncRule.filter === 'include'; const bidders = utils.isArray(syncRule.bidders) ? syncRule.bidders : [bidderCode]; return isInclude && utils.contains(bidders, bidderCode); } /** * Get the seller endpoint * @param testMode {boolean} * @returns {string} */ function getEndpoint(testMode) { return testMode ? SELLER_ENDPOINT + MODES.TEST : SELLER_ENDPOINT + MODES.PRODUCTION; } /** * Generate query parameters for the request * @param bid {bid} * @param bidderRequest {bidderRequest} * @returns {Object} */ function generateParameters(bid, bidderRequest) { const timeout = config.getConfig('bidderTimeout'); const { syncEnabled, filterSettings } = config.getConfig('userSync') || {}; const [ width, height ] = getSizes(bid); const { params } = bid; const { bidderCode } = bidderRequest; const domain = window.location.hostname; const requestParams = { auction_start: utils.timestamp(), ad_unit_code: utils.getBidIdParameter('adUnitCode', bid), tmax: timeout, width: width, height: height, publisher_id: params.org, floor_price: Math.max(getFloor(bid), params.floorPrice), ua: navigator.userAgent, bid_id: utils.getBidIdParameter('bidId', bid), bidder_request_id: utils.getBidIdParameter('bidderRequestId', bid), transaction_id: utils.getBidIdParameter('transactionId', bid), session_id: utils.getBidIdParameter('auctionId', bid), publisher_name: domain, site_domain: domain, bidder_version: BIDDER_VERSION }; if (params.placementId) { requestParams.placement_id = params.placementId; } if (syncEnabled) { const allowedSyncMethod = getAllowedSyncMethod(filterSettings, bidderCode); if (allowedSyncMethod) { requestParams.cs_method = allowedSyncMethod; } } if (bidderRequest.uspConsent) { requestParams.us_privacy = bidderRequest.uspConsent; } if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) { requestParams.gdpr = bidderRequest.gdprConsent.gdprApplies; requestParams.gdpr_consent = bidderRequest.gdprConsent.consentString; } if (params.ifa) { requestParams.ifa = params.ifa; } if (bid.schain) { requestParams.schain = getSupplyChain(bid.schain); } if (bidderRequest && bidderRequest.refererInfo) { requestParams.referrer = utils.deepAccess(bidderRequest, 'refererInfo.referer'); requestParams.page_url = config.getConfig('pageUrl') || utils.deepAccess(window, 'location.href'); } return requestParams; }