UNPKG

mk9-prebid

Version:

Header Bidding Management Library

339 lines (311 loc) 8.26 kB
import { logError, replaceAuctionPrice, parseUrl } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { config } from '../src/config.js'; import { NATIVE } from '../src/mediaTypes.js'; export const ENDPOINT = 'https://app.readpeak.com/header/prebid'; const NATIVE_DEFAULTS = { TITLE_LEN: 70, DESCR_LEN: 120, SPONSORED_BY_LEN: 50, IMG_MIN: 150, ICON_MIN: 50, CTA_LEN: 50 }; const BIDDER_CODE = 'readpeak'; export const spec = { code: BIDDER_CODE, supportedMediaTypes: [NATIVE], isBidRequestValid: bid => !!(bid && bid.params && bid.params.publisherId && bid.nativeParams), buildRequests: (bidRequests, bidderRequest) => { const currencyObj = config.getConfig('currency'); const currency = (currencyObj && currencyObj.adServerCurrency) || 'USD'; const request = { id: bidRequests[0].bidderRequestId, imp: bidRequests .map(slot => impression(slot)) .filter(imp => imp.native != null), site: site(bidRequests, bidderRequest), app: app(bidRequests), device: device(), cur: [currency], source: { fd: 1, tid: bidRequests[0].transactionId, ext: { prebid: '$prebid.version$' } } }; if (bidderRequest.gdprConsent) { request.user = { ext: { consent: bidderRequest.gdprConsent.consentString || '' }, }; request.regs = { ext: { gdpr: bidderRequest.gdprConsent.gdprApplies !== undefined ? bidderRequest.gdprConsent.gdprApplies : true } }; } return { method: 'POST', url: ENDPOINT, data: JSON.stringify(request) }; }, interpretResponse: (response, request) => bidResponseAvailable(request, response) }; function bidResponseAvailable(bidRequest, bidResponse) { const idToImpMap = {}; const idToBidMap = {}; if (!bidResponse['body']) { return []; } bidResponse = bidResponse.body; parse(bidRequest.data).imp.forEach(imp => { idToImpMap[imp.id] = imp; }); if (bidResponse) { bidResponse.seatbid.forEach(seatBid => seatBid.bid.forEach(bid => { idToBidMap[bid.impid] = bid; }) ); } const bids = []; Object.keys(idToImpMap).forEach(id => { if (idToBidMap[id]) { const bid = { requestId: id, cpm: idToBidMap[id].price, creativeId: idToBidMap[id].crid, ttl: 300, netRevenue: true, mediaType: NATIVE, currency: bidResponse.cur, native: nativeResponse(idToImpMap[id], idToBidMap[id]) }; if (idToBidMap[id].adomain) { bid.meta = { advertiserDomains: idToBidMap[id].adomain } } bids.push(bid); } }); return bids; } function impression(slot) { let bidFloorFromModule if (typeof slot.getFloor === 'function') { const floorInfo = slot.getFloor({ currency: 'USD', mediaType: 'native', size: '\*' }); bidFloorFromModule = floorInfo.currency === 'USD' ? floorInfo.floor : undefined; } return { id: slot.bidId, native: nativeImpression(slot), bidfloor: bidFloorFromModule || slot.params.bidfloor || 0, bidfloorcur: (bidFloorFromModule && 'USD') || slot.params.bidfloorcur || 'USD', tagId: slot.params.tagId || '0' }; } function nativeImpression(slot) { if (slot.nativeParams) { const assets = []; addAsset( assets, titleAsset(1, slot.nativeParams.title, NATIVE_DEFAULTS.TITLE_LEN) ); addAsset( assets, imageAsset( 2, slot.nativeParams.image, 3, slot.nativeParams.wmin || NATIVE_DEFAULTS.IMG_MIN, slot.nativeParams.hmin || NATIVE_DEFAULTS.IMG_MIN ) ); addAsset( assets, dataAsset( 3, slot.nativeParams.sponsoredBy, 1, NATIVE_DEFAULTS.SPONSORED_BY_LEN ) ); addAsset( assets, dataAsset(4, slot.nativeParams.body, 2, NATIVE_DEFAULTS.DESCR_LEN) ); addAsset( assets, dataAsset(5, slot.nativeParams.cta, 12, NATIVE_DEFAULTS.CTA_LEN) ); return { request: JSON.stringify({ assets }), ver: '1.1' }; } return null; } function addAsset(assets, asset) { if (asset) { assets.push(asset); } } function titleAsset(id, params, defaultLen) { if (params) { return { id, required: params.required ? 1 : 0, title: { len: params.len || defaultLen } }; } return null; } function imageAsset(id, params, type, defaultMinWidth, defaultMinHeight) { return params ? { id, required: params.required ? 1 : 0, img: { type, wmin: params.wmin || defaultMinWidth, hmin: params.hmin || defaultMinHeight } } : null; } function dataAsset(id, params, type, defaultLen) { return params ? { id, required: params.required ? 1 : 0, data: { type, len: params.len || defaultLen } } : null; } function site(bidRequests, bidderRequest) { const url = config.getConfig('pageUrl') || (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer); const pubId = bidRequests && bidRequests.length > 0 ? bidRequests[0].params.publisherId : '0'; const siteId = bidRequests && bidRequests.length > 0 ? bidRequests[0].params.siteId : '0'; const appParams = bidRequests[0].params.app; if (!appParams) { return { publisher: { id: pubId.toString(), domain: config.getConfig('publisherDomain') }, id: siteId ? siteId.toString() : pubId.toString(), page: url, domain: (url && parseUrl(url).hostname) || config.getConfig('publisherDomain') }; } return undefined; } function app(bidderRequest) { const pubId = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.publisherId : '0'; const appParams = bidderRequest[0].params.app; if (appParams) { return { publisher: { id: pubId.toString() }, bundle: appParams.bundle, storeurl: appParams.storeUrl, domain: appParams.domain }; } return undefined; } function isMobile() { return /(ios|ipod|ipad|iphone|android)/i.test(global.navigator.userAgent); } function isConnectedTV() { return /(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i.test( global.navigator.userAgent ); } function device() { return { ua: navigator.userAgent, language: navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage, devicetype: isMobile() ? 1 : isConnectedTV() ? 3 : 2 }; } function parse(rawResponse) { try { if (rawResponse) { if (typeof rawResponse === 'object') { return rawResponse; } else { return JSON.parse(rawResponse); } } } catch (ex) { logError('readpeakBidAdapter.safeParse', 'ERROR', ex); } return null; } function nativeResponse(imp, bid) { if (imp && imp['native']) { const nativeAd = parse(bid.adm); const keys = {}; if (nativeAd && nativeAd.assets) { nativeAd.assets.forEach(asset => { keys.title = asset.title ? asset.title.text : keys.title; keys.body = asset.data && asset.id === 4 ? asset.data.value : keys.body; keys.sponsoredBy = asset.data && asset.id === 3 ? asset.data.value : keys.sponsoredBy; keys.image = asset.img && asset.id === 2 ? { url: asset.img.url, width: asset.img.w || 750, height: asset.img.h || 500 } : keys.image; keys.cta = asset.data && asset.id === 5 ? asset.data.value : keys.cta; }); if (nativeAd.link) { keys.clickUrl = encodeURIComponent(nativeAd.link.url); } const trackers = nativeAd.imptrackers || []; trackers.unshift(replaceAuctionPrice(bid.burl, bid.price)); keys.impressionTrackers = trackers; return keys; } } return null; } registerBidder(spec);