From 5be582f2e35650e0bf4dbe212bde9e936edfe75c Mon Sep 17 00:00:00 2001 From: Denis Logachov Date: Mon, 22 Aug 2022 20:44:12 +0300 Subject: [PATCH] Adkernel Bid Adapter: add impression-level FPD support (#8880) --- modules/adkernelBidAdapter.js | 40 ++++++++++++++------ test/spec/modules/adkernelBidAdapter_spec.js | 13 ++++++- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/modules/adkernelBidAdapter.js b/modules/adkernelBidAdapter.js index 78f00784462..ff7d3be6ebf 100644 --- a/modules/adkernelBidAdapter.js +++ b/modules/adkernelBidAdapter.js @@ -14,11 +14,12 @@ import { isPlainObject, isStr, mergeDeep, - parseGPTSingleSizeArrayToRtbSize + parseGPTSingleSizeArrayToRtbSize, + getDefinedParams } from '../src/utils.js'; import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {find, includes} from '../src/polyfill.js'; +import {find} from '../src/polyfill.js'; import {config} from '../src/config.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; @@ -28,10 +29,11 @@ import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; * * Please contact prebid@adkernel.com and we'll add your adapter as an alias. */ - -const VIDEO_TARGETING = Object.freeze(['mimes', 'minduration', 'maxduration', 'protocols', - 'startdelay', 'linearity', 'boxingallowed', 'playbackmethod', 'delivery', - 'pos', 'api', 'ext']); +const VIDEO_PARAMS = ['pos', 'context', 'placement', 'api', 'mimes', 'protocols', 'playbackmethod', 'minduration', 'maxduration', + 'startdelay', 'linearity', 'skip', 'skipmin', 'skipafter', 'minbitrate', 'maxbitrate', 'delivery', 'playbackend', 'boxingallowed']; +const VIDEO_FPD = ['battr', 'pos']; +const NATIVE_FPD = ['battr', 'api']; +const BANNER_FPD = ['btype', 'battr', 'pos', 'api']; const VERSION = '1.6'; const SYNC_IFRAME = 1; const SYNC_IMAGE = 2; @@ -275,18 +277,18 @@ function buildImp(bidRequest, secure) { format: sizes.map(wh => parseGPTSingleSizeArrayToRtbSize(wh)), topframe: 0 }; + populateImpFpd(imp.banner, bidRequest, BANNER_FPD); mediaType = BANNER; } else if (deepAccess(bidRequest, 'mediaTypes.video')) { let video = deepAccess(bidRequest, 'mediaTypes.video'); - imp.video = {}; + imp.video = getDefinedParams(video, VIDEO_PARAMS); + populateImpFpd(imp.video, bidRequest, VIDEO_FPD); if (video.playerSize) { sizes = video.playerSize[0]; imp.video = Object.assign(imp.video, parseGPTSingleSizeArrayToRtbSize(sizes) || {}); - } - if (bidRequest.params.video) { - Object.keys(bidRequest.params.video) - .filter(key => includes(VIDEO_TARGETING, key)) - .forEach(key => imp.video[key] = bidRequest.params.video[key]); + } else if (video.w && video.h) { + imp.video.w = video.w; + imp.video.h = video.h; } mediaType = VIDEO; } else if (deepAccess(bidRequest, 'mediaTypes.native')) { @@ -295,6 +297,7 @@ function buildImp(bidRequest, secure) { ver: '1.1', request: JSON.stringify(nativeRequest) }; + populateImpFpd(imp.native, bidRequest, NATIVE_FPD); mediaType = NATIVE; } else { throw new Error('Unsupported bid received'); @@ -338,6 +341,19 @@ function buildNativeRequest(nativeReq) { return request; } +/** + * Populate impression-level FPD from bid request + * @param target {Object} + * @param bidRequest {BidRequest} + * @param props {String[]} + */ +function populateImpFpd(target, bidRequest, props) { + if (bidRequest.ortb2Imp === undefined) { + return; + } + Object.assign(target, getDefinedParams(bidRequest.ortb2Imp, props)); +} + /** * Builds image asset request */ diff --git a/test/spec/modules/adkernelBidAdapter_spec.js b/test/spec/modules/adkernelBidAdapter_spec.js index 4b0eebdf519..45498d2734a 100644 --- a/test/spec/modules/adkernelBidAdapter_spec.js +++ b/test/spec/modules/adkernelBidAdapter_spec.js @@ -17,6 +17,9 @@ describe('Adkernel adapter', function () { banner: { sizes: [[300, 250], [300, 200]] } + }, + ortb2Imp: { + battr: [6, 7, 9] } }, bid2_zone2 = { bidder: 'adkernel', @@ -95,12 +98,12 @@ describe('Adkernel adapter', function () { params: { zoneId: 1, host: 'rtb.adkernel.com', - video: {api: [1, 2]} }, mediaTypes: { video: { context: 'instream', - playerSize: [[640, 480]] + playerSize: [[640, 480]], + api: [1, 2] } }, adUnitCode: 'ad-unit-1' @@ -293,6 +296,7 @@ describe('Adkernel adapter', function () { describe('banner request building', function () { let bidRequest, bidRequests, _; + before(function () { [_, bidRequests] = buildRequest([bid1_zone1]); bidRequest = bidRequests[0]; @@ -337,6 +341,11 @@ describe('Adkernel adapter', function () { expect(bidRequest.device).to.have.property('dnt', 1); }); + it('should copy FPD to imp.banner', function() { + expect(bidRequest.imp[0].banner).to.have.property('battr'); + expect(bidRequest.imp[0].banner.battr).to.be.eql([6, 7, 9]); + }); + it('shouldn\'t contain gdpr nor ccpa information for default request', function () { let [_, bidRequests] = buildRequest([bid1_zone1]); expect(bidRequests[0]).to.not.have.property('regs');