UNPKG

mk9-prebid

Version:

Header Bidding Management Library

281 lines (250 loc) 8.24 kB
'use strict'; import * as utils from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; function RhythmOneBidAdapter() { this.code = 'rhythmone'; this.supportedMediaTypes = [VIDEO, BANNER]; let SUPPORTED_VIDEO_PROTOCOLS = [2, 3, 5, 6]; let SUPPORTED_VIDEO_MIMES = ['video/mp4']; let SUPPORTED_VIDEO_PLAYBACK_METHODS = [1, 2, 3, 4]; let SUPPORTED_VIDEO_DELIVERY = [1]; let SUPPORTED_VIDEO_API = [1, 2, 5]; let slotsToBids = {}; let that = this; let version = '2.1'; this.isBidRequestValid = function (bid) { return !!(bid.params && bid.params.placementId); }; this.getUserSyncs = function (syncOptions, responses, gdprConsent) { return []; }; function frameImp(BRs, bidderRequest) { var impList = []; var isSecure = 0; if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.stack.length) { // clever trick to get the protocol var el = document.createElement('a'); el.href = bidderRequest.refererInfo.stack[0]; isSecure = (el.protocol == 'https:') ? 1 : 0; } for (var i = 0; i < BRs.length; i++) { slotsToBids[BRs[i].adUnitCode] = BRs[i]; var impObj = {}; impObj.id = BRs[i].adUnitCode; impObj.bidfloor = 0; impObj.secure = isSecure; if (utils.deepAccess(BRs[i], 'mediaTypes.banner') || utils.deepAccess(BRs[i], 'mediaType') === 'banner') { let banner = frameBanner(BRs[i]); if (banner) { impObj.banner = banner; } } if (utils.deepAccess(BRs[i], 'mediaTypes.video') || utils.deepAccess(BRs[i], 'mediaType') === 'video') { impObj.video = frameVideo(BRs[i]); } if (!(impObj.banner || impObj.video)) { continue; } impObj.ext = frameExt(BRs[i]); impList.push(impObj); } return impList; } function frameSite(bidderRequest) { var site = { domain: '', page: '', ref: '' } if (bidderRequest && bidderRequest.refererInfo) { var ri = bidderRequest.refererInfo; site.ref = ri.referer; if (ri.stack.length) { site.page = ri.stack[ri.stack.length - 1]; // clever trick to get the domain var el = document.createElement('a'); el.href = ri.stack[0]; site.domain = el.hostname; } } return site; } function frameDevice() { return { ua: navigator.userAgent, ip: '', // Empty Ip string is required, server gets the ip from HTTP header dnt: utils.getDNT() ? 1 : 0, } } function getValidSizeSet(dimensionList) { let w = parseInt(dimensionList[0]); let h = parseInt(dimensionList[1]); // clever check for NaN if (! (w !== w || h !== h)) { // eslint-disable-line return [w, h]; } return false; } function frameBanner(adUnit) { // adUnit.sizes is scheduled to be deprecated, continue its support but prefer adUnit.mediaTypes.banner var sizeList = adUnit.sizes; if (adUnit.mediaTypes && adUnit.mediaTypes.banner) { sizeList = adUnit.mediaTypes.banner.sizes; } var sizeStringList = utils.parseSizesInput(sizeList); var format = []; sizeStringList.forEach(function(size) { if (size) { var dimensionList = getValidSizeSet(size.split('x')); if (dimensionList) { format.push({ 'w': dimensionList[0], 'h': dimensionList[1], }); } } }); if (format.length) { return { 'format': format }; } return false; } function frameVideo(bid) { var size = []; if (utils.deepAccess(bid, 'mediaTypes.video.playerSize')) { var dimensionSet = bid.mediaTypes.video.playerSize; if (utils.isArray(bid.mediaTypes.video.playerSize[0])) { dimensionSet = bid.mediaTypes.video.playerSize[0]; } var validSize = getValidSizeSet(dimensionSet) if (validSize) { size = validSize; } } return { mimes: utils.deepAccess(bid, 'mediaTypes.video.mimes') || SUPPORTED_VIDEO_MIMES, protocols: utils.deepAccess(bid, 'mediaTypes.video.protocols') || SUPPORTED_VIDEO_PROTOCOLS, w: size[0], h: size[1], startdelay: utils.deepAccess(bid, 'mediaTypes.video.startdelay') || 0, skip: utils.deepAccess(bid, 'mediaTypes.video.skip') || 0, playbackmethod: utils.deepAccess(bid, 'mediaTypes.video.playbackmethod') || SUPPORTED_VIDEO_PLAYBACK_METHODS, delivery: utils.deepAccess(bid, 'mediaTypes.video.delivery') || SUPPORTED_VIDEO_DELIVERY, api: utils.deepAccess(bid, 'mediaTypes.video.api') || SUPPORTED_VIDEO_API, } } function frameExt(bid) { return { bidder: { placementId: bid.params['placementId'], zone: (bid.params && bid.params['zone']) ? bid.params['zone'] : '1r', path: (bid.params && bid.params['path']) ? bid.params['path'] : 'mvo' } } } function frameBid(BRs, bidderRequest) { let bid = { id: BRs[0].bidderRequestId, imp: frameImp(BRs, bidderRequest), site: frameSite(bidderRequest), device: frameDevice(), user: { ext: { consent: utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies') ? bidderRequest.gdprConsent.consentString : '' } }, at: 1, tmax: 1000, regs: { ext: { gdpr: utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies') ? Boolean(bidderRequest.gdprConsent.gdprApplies & 1) : false } } }; if (BRs[0].schain) { bid.source = { 'ext': { 'schain': BRs[0].schain } } } return bid; } function getFirstParam(key, validBidRequests) { for (let i = 0; i < validBidRequests.length; i++) { if (validBidRequests[i].params && validBidRequests[i].params[key]) { return validBidRequests[i].params[key]; } } } this.buildRequests = function (BRs, bidderRequest) { let fallbackPlacementId = getFirstParam('placementId', BRs); if (fallbackPlacementId === undefined || BRs.length < 1) { return []; } var rmpUrl = getFirstParam('endpoint', BRs) || 'https://tag.1rx.io/rmp/{placementId}/0/{path}?z={zone}'; var defaultZone = getFirstParam('zone', BRs) || '1r'; var defaultPath = getFirstParam('path', BRs) || 'mvo'; rmpUrl = rmpUrl.replace(/\{placementId\}/i, fallbackPlacementId); rmpUrl = rmpUrl.replace(/\{zone\}/i, defaultZone); rmpUrl = rmpUrl.replace(/\{path\}/i, defaultPath); var fat = /(^v|(\.0)+$)/gi; var prebidVersion = '$prebid.version$'; rmpUrl += '&hbv=' + prebidVersion.replace(fat, '') + ',' + version.replace(fat, ''); var bidRequest = frameBid(BRs, bidderRequest); if (!bidRequest.imp.length) { return {}; } return { method: 'POST', url: rmpUrl, data: JSON.stringify(bidRequest) }; }; this.interpretResponse = function (serverResponse) { let responses = serverResponse.body || []; let bids = []; let i = 0; if (responses.seatbid) { let temp = []; for (i = 0; i < responses.seatbid.length; i++) { for (let j = 0; j < responses.seatbid[i].bid.length; j++) { temp.push(responses.seatbid[i].bid[j]); } } responses = temp; } for (i = 0; i < responses.length; i++) { let bid = responses[i]; let bidRequest = slotsToBids[bid.impid]; let bidResponse = { requestId: bidRequest.bidId, bidderCode: that.code, cpm: parseFloat(bid.price), width: bid.w, height: bid.h, meta: { advertiserDomains: bid.adomain }, creativeId: bid.crid, currency: 'USD', netRevenue: true, ttl: 350 }; if (bidRequest.mediaTypes && bidRequest.mediaTypes.video) { bidResponse.vastUrl = bid.nurl; bidResponse.mediaType = 'video'; bidResponse.ttl = 600; } else { bidResponse.ad = bid.adm; } bids.push(bidResponse); } return bids; }; } export const spec = new RhythmOneBidAdapter(); registerBidder(spec);