diff --git a/modules/beopBidAdapter.js b/modules/beopBidAdapter.js index f8a53a293de5..8376df1f0f0e 100644 --- a/modules/beopBidAdapter.js +++ b/modules/beopBidAdapter.js @@ -1,153 +1,225 @@ -import { deepAccess, isArray, logWarn, triggerPixel, buildUrl, logInfo, getValue, getBidIdParameter } from '../src/utils.js'; -import { getRefererInfo } from '../src/refererDetection.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { config } from '../src/config.js'; -const BIDDER_CODE = 'beop'; -const ENDPOINT_URL = 'https://hb.beop.io/bid'; +import { + deepAccess, + isArray, + logWarn, + triggerPixel, + buildUrl, + logInfo, + getValue, + getBidIdParameter, +} from "../src/utils.js"; +import { getRefererInfo } from "../src/refererDetection.js"; +import { registerBidder } from "../src/adapters/bidderFactory.js"; +import { config } from "../src/config.js"; +const BIDDER_CODE = "beop"; +const ENDPOINT_URL = "https://hb.beop.io/bid"; const TCF_VENDOR_ID = 666; -const validIdRegExp = /^[0-9a-fA-F]{24}$/ +const validIdRegExp = /^[0-9a-fA-F]{24}$/; export const spec = { code: BIDDER_CODE, gvlid: TCF_VENDOR_ID, - aliases: ['bp'], + aliases: ["bp"], /** - * Test if the bid request is valid. - * - * @param {bid} : The Bid params - * @return boolean true if the bid request is valid (aka contains a valid accountId or networkId and is open for BANNER), false otherwise. - */ - isBidRequestValid: function(bid) { + * Test if the bid request is valid. + * + * @param {bid} : The Bid params + * @return boolean true if the bid request is valid (aka contains a valid accountId or networkId and is open for BANNER), false otherwise. + */ + isBidRequestValid: function (bid) { const id = bid.params.accountId || bid.params.networkId; - if (id === null || typeof id === 'undefined') { - return false + if (id === null || typeof id === "undefined") { + return false; } if (!validIdRegExp.test(id)) { - return false + return false; } - return bid.mediaTypes.banner !== null && typeof bid.mediaTypes.banner !== 'undefined'; + return ( + bid.mediaTypes.banner !== null && + typeof bid.mediaTypes.banner !== "undefined" + ); }, /** - * Create a BeOp server request from a list of BidRequest - * - * @param {validBidRequests[], ...} : The array of validated bidRequests - * @param {... , bidderRequest} : Common params for each bidRequests - * @return ServerRequest Info describing the request to the BeOp's server - */ - buildRequests: function(validBidRequests, bidderRequest) { + * Create a BeOp server request from a list of BidRequest + * + * @param {validBidRequests[], ...} : The array of validated bidRequests + * @param {... , bidderRequest} : Common params for each bidRequests + * @return ServerRequest Info describing the request to the BeOp's server + */ + buildRequests: function (validBidRequests, bidderRequest) { const slots = validBidRequests.map(beOpRequestSlotsMaker); const pageUrl = getPageUrl(bidderRequest.refererInfo, window); const gdpr = bidderRequest.gdprConsent; const firstSlot = slots[0]; + const kwdsFromRequest = bidderRequest.ortb2?.site?.keywords; + const keywords = []; + if (kwdsFromRequest) { + if (isArray(kwdsFromRequest)) { + keywords = kwdsFromRequest; + } else { + keywords.push(kwdsFromRequest); + } + } + const payloadObject = { at: new Date().toString(), nid: firstSlot.nid, nptnid: firstSlot.nptnid, pid: firstSlot.pid, url: pageUrl, - lang: (window.navigator.language || window.navigator.languages[0]), - kwds: bidderRequest.ortb2?.site?.keywords || [], + lang: window.navigator.language || window.navigator.languages[0], + kwds: keywords, dbg: false, slts: slots, - is_amp: deepAccess(bidderRequest, 'referrerInfo.isAmp'), - tc_string: (gdpr && gdpr.gdprApplies) ? gdpr.consentString : null, + is_amp: deepAccess(bidderRequest, "referrerInfo.isAmp"), + tc_string: gdpr && gdpr.gdprApplies ? gdpr.consentString : null, }; const payloadString = JSON.stringify(payloadObject); + let trackingParams = buildTrackingParams( + timeoutData, + "request", + timeoutData.timeout + ); + + logWarn(BIDDER_CODE + ": timed out request"); + triggerPixel( + buildUrl({ + protocol: "https", + hostname: "t.beop.io", + pathname: "/bid", + search: trackingParams, + }) + ); return { - method: 'POST', + method: "POST", url: ENDPOINT_URL, - data: payloadString - } + data: payloadString, + }; }, - interpretResponse: function(serverResponse, request) { - if (serverResponse && serverResponse.body && isArray(serverResponse.body.bids) && serverResponse.body.bids.length > 0) { + interpretResponse: function (serverResponse, request) { + if ( + serverResponse && + serverResponse.body && + isArray(serverResponse.body.bids) && + serverResponse.body.bids.length > 0 + ) { return serverResponse.body.bids; } return []; }, - onTimeout: function(timeoutData) { - if (timeoutData === null || typeof timeoutData === 'undefined' || Object.keys(timeoutData).length === 0) { + onTimeout: function (timeoutData) { + if ( + timeoutData === null || + typeof timeoutData === "undefined" || + Object.keys(timeoutData).length === 0 + ) { return; } - let trackingParams = buildTrackingParams(timeoutData, 'timeout', timeoutData.timeout); + let trackingParams = buildTrackingParams( + timeoutData, + "timeout", + timeoutData.timeout + ); - logWarn(BIDDER_CODE + ': timed out request'); - triggerPixel(buildUrl({ - protocol: 'https', - hostname: 't.beop.io', - pathname: '/bid', - search: trackingParams - })); + logWarn(BIDDER_CODE + ": timed out request"); + triggerPixel( + buildUrl({ + protocol: "https", + hostname: "t.beop.io", + pathname: "/bid", + search: trackingParams, + }) + ); }, - onBidWon: function(bid) { - if (bid === null || typeof bid === 'undefined' || Object.keys(bid).length === 0) { + onBidWon: function (bid) { + if ( + bid === null || + typeof bid === "undefined" || + Object.keys(bid).length === 0 + ) { return; } - let trackingParams = buildTrackingParams(bid, 'won', bid.cpm); + let trackingParams = buildTrackingParams(bid, "won", bid.cpm); - logInfo(BIDDER_CODE + ': won request'); - triggerPixel(buildUrl({ - protocol: 'https', - hostname: 't.beop.io', - pathname: '/bid', - search: trackingParams - })); + logInfo(BIDDER_CODE + ": won request"); + triggerPixel( + buildUrl({ + protocol: "https", + hostname: "t.beop.io", + pathname: "/bid", + search: trackingParams, + }) + ); }, - onSetTargeting: function(bid) {} -} + onSetTargeting: function (bid) {}, +}; function buildTrackingParams(data, info, value) { let params = Array.isArray(data.params) ? data.params[0] : data.params; const pageUrl = getPageUrl(null, window); return { - pid: params.accountId === undefined ? data.ad.match(/account: \“([a-f\d]{24})\“/)[1] : params.accountId, + pid: + params.accountId === undefined + ? data.ad.match(/account: \“([a-f\d]{24})\“/)[1] + : params.accountId, nid: params.networkId, nptnid: params.networkPartnerId, bid: data.bidId || data.requestId, sl_n: data.adUnitCode, aid: data.auctionId, - se_ca: 'bid', + se_ca: "bid", se_ac: info, se_va: value, - url: pageUrl + url: pageUrl, }; } function beOpRequestSlotsMaker(bid) { - const bannerSizes = deepAccess(bid, 'mediaTypes.banner.sizes'); - const publisherCurrency = config.getConfig('currency.adServerCurrency') || getValue(bid.params, 'currency') || 'EUR'; + const bannerSizes = deepAccess(bid, "mediaTypes.banner.sizes"); + const publisherCurrency = + config.getConfig("currency.adServerCurrency") || + getValue(bid.params, "currency") || + "EUR"; let floor; - if (typeof bid.getFloor === 'function') { - const floorInfo = bid.getFloor({currency: publisherCurrency, mediaType: 'banner', size: [1, 1]}); - if (typeof floorInfo === 'object' && floorInfo.currency === publisherCurrency && !isNaN(parseFloat(floorInfo.floor))) { + if (typeof bid.getFloor === "function") { + const floorInfo = bid.getFloor({ + currency: publisherCurrency, + mediaType: "banner", + size: [1, 1], + }); + if ( + typeof floorInfo === "object" && + floorInfo.currency === publisherCurrency && + !isNaN(parseFloat(floorInfo.floor)) + ) { floor = parseFloat(floorInfo.floor); } } return { sizes: isArray(bannerSizes) ? bannerSizes : bid.sizes, flr: floor, - pid: getValue(bid.params, 'accountId'), - nid: getValue(bid.params, 'networkId'), - nptnid: getValue(bid.params, 'networkPartnerId'), - bid: getBidIdParameter('bidId', bid), - brid: getBidIdParameter('bidderRequestId', bid), - name: getBidIdParameter('adUnitCode', bid), - aid: getBidIdParameter('auctionId', bid), - tid: getBidIdParameter('transactionId', bid), - brc: getBidIdParameter('bidRequestsCount', bid), - bdrc: getBidIdParameter('bidderRequestCount', bid), - bwc: getBidIdParameter('bidderWinsCount', bid), - } + pid: getValue(bid.params, "accountId"), + nid: getValue(bid.params, "networkId"), + nptnid: getValue(bid.params, "networkPartnerId"), + bid: getBidIdParameter("bidId", bid), + brid: getBidIdParameter("bidderRequestId", bid), + name: getBidIdParameter("adUnitCode", bid), + aid: getBidIdParameter("auctionId", bid), + tid: getBidIdParameter("transactionId", bid), + brc: getBidIdParameter("bidRequestsCount", bid), + bdrc: getBidIdParameter("bidderRequestCount", bid), + bwc: getBidIdParameter("bidderWinsCount", bid), + }; } -const protocolRelativeRegExp = /^\/\// +const protocolRelativeRegExp = /^\/\//; function isProtocolRelativeUrl(url) { return url && url.match(protocolRelativeRegExp) != null; } -const withProtocolRegExp = /[a-z]{1,}:\/\// +const withProtocolRegExp = /[a-z]{1,}:\/\//; function isNoProtocolUrl(url) { return url && url.match(withProtocolRegExp) == null; } @@ -168,7 +240,7 @@ function ensureProtocolInUrl(url, defaultProtocol) { */ function safeDeepAccess(obj, path) { try { - return deepAccess(obj, path) + return deepAccess(obj, path); } catch (_e) { return null; } @@ -176,10 +248,15 @@ function safeDeepAccess(obj, path) { function getPageUrl(refererInfo, window) { refererInfo = refererInfo || getRefererInfo(); - let pageUrl = refererInfo.canonicalUrl || safeDeepAccess(window, 'top.location.href') || deepAccess(window, 'location.href'); + let pageUrl = + refererInfo.canonicalUrl || + safeDeepAccess(window, "top.location.href") || + deepAccess(window, "location.href"); // Ensure the protocol is present (looks like sometimes the extracted pageUrl misses it) if (pageUrl != null) { - const defaultProtocol = safeDeepAccess(window, 'top.location.protocol') || deepAccess(window, 'location.protocol'); + const defaultProtocol = + safeDeepAccess(window, "top.location.protocol") || + deepAccess(window, "location.protocol"); pageUrl = ensureProtocolInUrl(pageUrl, defaultProtocol); } return pageUrl;