|
| 1 | +import find from 'core-js/library/fn/array/find'; |
| 2 | +import * as utils from 'src/utils'; |
| 3 | +import { registerBidder } from 'src/adapters/bidderFactory'; |
| 4 | + |
| 5 | +const BIDDER_CODE = 'adagio'; |
| 6 | +const VERSION = '1.0.0'; |
| 7 | +const ENDPOINT = 'https://mp.4dex.io/prebid'; |
| 8 | +const SUPPORTED_MEDIA_TYPES = ['banner']; |
| 9 | + |
| 10 | +/** |
| 11 | + * Based on https://github.com/ua-parser/uap-cpp/blob/master/UaParser.cpp#L331, with the following updates: |
| 12 | + * - replaced `mobile` by `mobi` in the table regexp, so Opera Mobile on phones is not detected as a tablet. |
| 13 | + */ |
| 14 | +function _getDeviceType() { |
| 15 | + let ua = navigator.userAgent; |
| 16 | + |
| 17 | + // Tablets must be checked before phones. |
| 18 | + if ((/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i).test(ua)) { |
| 19 | + return 5; // "tablet" |
| 20 | + } |
| 21 | + if ((/Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/).test(ua)) { |
| 22 | + return 4; // "phone" |
| 23 | + } |
| 24 | + // Consider that all other devices are personal computers |
| 25 | + return 2; |
| 26 | +}; |
| 27 | + |
| 28 | +function _getDevice() { |
| 29 | + const language = navigator.language ? 'language' : 'userLanguage'; |
| 30 | + return { |
| 31 | + userAgent: navigator.userAgent, |
| 32 | + language: navigator[language], |
| 33 | + deviceType: _getDeviceType(), |
| 34 | + dnt: utils.getDNT() ? 1 : 0, |
| 35 | + geo: {}, |
| 36 | + js: 1 |
| 37 | + }; |
| 38 | +}; |
| 39 | + |
| 40 | +function _getSite() { |
| 41 | + const topLocation = utils.getTopWindowLocation(); |
| 42 | + return { |
| 43 | + domain: topLocation.hostname, |
| 44 | + page: topLocation.href, |
| 45 | + referrer: utils.getTopWindowReferrer() |
| 46 | + }; |
| 47 | +}; |
| 48 | + |
| 49 | +function _getPageviewId() { |
| 50 | + return (!window.top.ADAGIO || !window.top.ADAGIO.pageviewId) ? '_' : window.top.ADAGIO.pageviewId; |
| 51 | +}; |
| 52 | + |
| 53 | +function _getFeatures(bidRequest) { |
| 54 | + if (!window.top._ADAGIO || !window.top._ADAGIO.features) { |
| 55 | + return {}; |
| 56 | + } |
| 57 | + |
| 58 | + const rawFeatures = window.top._ADAGIO.features.getFeatures( |
| 59 | + document.getElementById(bidRequest.adUnitCode), |
| 60 | + function(features) { |
| 61 | + return { |
| 62 | + site_id: bidRequest.params.siteId, |
| 63 | + placement: bidRequest.params.placementId, |
| 64 | + pagetype: bidRequest.params.pagetypeId, |
| 65 | + categories: bidRequest.params.categories |
| 66 | + }; |
| 67 | + } |
| 68 | + ); |
| 69 | + return rawFeatures; |
| 70 | +} |
| 71 | + |
| 72 | +function _getGdprConsent(bidderRequest) { |
| 73 | + const consent = {}; |
| 74 | + if (utils.deepAccess(bidderRequest, 'gdprConsent')) { |
| 75 | + if (bidderRequest.gdprConsent.consentString !== undefined) { |
| 76 | + consent.consentString = bidderRequest.gdprConsent.consentString; |
| 77 | + } |
| 78 | + if (bidderRequest.gdprConsent.gdprApplies !== undefined) { |
| 79 | + consent.consentRequired = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; |
| 80 | + } |
| 81 | + if (bidderRequest.gdprConsent.allowAuctionWithoutConsent !== undefined) { |
| 82 | + consent.allowAuctionWithoutConsent = bidderRequest.gdprConsent.allowAuctionWithoutConsent ? 1 : 0; |
| 83 | + } |
| 84 | + } |
| 85 | + return consent; |
| 86 | +} |
| 87 | + |
| 88 | +export const spec = { |
| 89 | + code: BIDDER_CODE, |
| 90 | + |
| 91 | + supportedMediaType: SUPPORTED_MEDIA_TYPES, |
| 92 | + |
| 93 | + isBidRequestValid: function(bid) { |
| 94 | + return !!(bid.params.siteId && bid.params.placementId); |
| 95 | + }, |
| 96 | + |
| 97 | + buildRequests: function(validBidRequests, bidderRequest) { |
| 98 | + const secure = (location.protocol === 'https:') ? 1 : 0; |
| 99 | + const device = _getDevice(); |
| 100 | + const site = _getSite(); |
| 101 | + const pageviewId = _getPageviewId(); |
| 102 | + const gdprConsent = _getGdprConsent(bidderRequest); |
| 103 | + const adUnits = utils._map(validBidRequests, (bidRequest) => { |
| 104 | + bidRequest.params.features = _getFeatures(bidRequest); |
| 105 | + const categories = bidRequest.params.categories; |
| 106 | + if (typeof categories !== 'undefined' && !Array.isArray(categories)) { |
| 107 | + bidRequest.params.categories = [categories]; |
| 108 | + } |
| 109 | + return bidRequest; |
| 110 | + }); |
| 111 | + |
| 112 | + // Regroug ad units by siteId |
| 113 | + const groupedAdUnits = adUnits.reduce((groupedAdUnits, adUnit) => { |
| 114 | + (groupedAdUnits[adUnit.params.siteId] = groupedAdUnits[adUnit.params.siteId] || []).push(adUnit); |
| 115 | + return groupedAdUnits; |
| 116 | + }, {}); |
| 117 | + |
| 118 | + // Build one request per siteId |
| 119 | + const requests = utils._map(Object.keys(groupedAdUnits), (siteId) => { |
| 120 | + return { |
| 121 | + method: 'POST', |
| 122 | + url: ENDPOINT, |
| 123 | + data: { |
| 124 | + id: utils.generateUUID(), |
| 125 | + secure: secure, |
| 126 | + device: device, |
| 127 | + site: site, |
| 128 | + siteId: siteId, |
| 129 | + pageviewId: pageviewId, |
| 130 | + adUnits: groupedAdUnits[siteId], |
| 131 | + gdpr: gdprConsent, |
| 132 | + adapterVersion: VERSION |
| 133 | + }, |
| 134 | + options: { |
| 135 | + contentType: 'application/json' |
| 136 | + } |
| 137 | + } |
| 138 | + }); |
| 139 | + |
| 140 | + return requests; |
| 141 | + }, |
| 142 | + |
| 143 | + interpretResponse: function(serverResponse, bidRequest) { |
| 144 | + let bidResponses = []; |
| 145 | + try { |
| 146 | + const response = serverResponse.body; |
| 147 | + if (response) { |
| 148 | + response.bids.forEach(bidObj => { |
| 149 | + const bidReq = (find(bidRequest.data.adUnits, bid => bid.bidId === bidObj.requestId)); |
| 150 | + if (bidReq) { |
| 151 | + bidObj.placementId = bidReq.params.placementId; |
| 152 | + bidObj.pagetypeId = bidReq.params.pagetypeId; |
| 153 | + bidObj.categories = (bidReq.params.features && bidReq.params.features.categories) ? bidReq.params.features.categories : []; |
| 154 | + } |
| 155 | + bidResponses.push(bidObj); |
| 156 | + }); |
| 157 | + } |
| 158 | + } catch (err) { |
| 159 | + utils.logError(err); |
| 160 | + } |
| 161 | + return bidResponses; |
| 162 | + }, |
| 163 | + |
| 164 | + getUserSyncs: function(syncOptions, serverResponses) { |
| 165 | + if (!serverResponses.length || serverResponses[0].body === '' || !serverResponses[0].body.userSyncs) { |
| 166 | + return false; |
| 167 | + } |
| 168 | + const syncs = serverResponses[0].body.userSyncs.map((sync) => { |
| 169 | + return { |
| 170 | + type: sync.t === 'p' ? 'image' : 'iframe', |
| 171 | + url: sync.u |
| 172 | + } |
| 173 | + }) |
| 174 | + return syncs; |
| 175 | + } |
| 176 | +} |
| 177 | + |
| 178 | +registerBidder(spec); |
0 commit comments