diff --git a/libraries/appnexusKeywords/anKeywords.js b/libraries/appnexusKeywords/anKeywords.js index e4c770a0b18..2d6845c8658 100644 --- a/libraries/appnexusKeywords/anKeywords.js +++ b/libraries/appnexusKeywords/anKeywords.js @@ -1,5 +1,16 @@ -import {_each, getValueString, isArray, isStr, mergeDeep, isNumber} from '../../src/utils.js'; +import {_each, deepAccess, getValueString, isArray, isStr, mergeDeep, isNumber} from '../../src/utils.js'; import {getAllOrtbKeywords} from '../keywords/keywords.js'; +import {CLIENT_SECTIONS} from '../../src/fpd/oneClient.js'; + +const ORTB_SEGTAX_KEY_MAP = { + 526: '1plusx', + 527: '1plusx', + 541: 'captify_segments', + 540: 'perid' +}; +const ORTB_SEG_PATHS = ['user.data'].concat( + CLIENT_SECTIONS.map((prefix) => `${prefix}.content.data`) +); /** * Converts an object of arrays (either strings or numbers) into an array of objects containing key and value properties @@ -85,7 +96,7 @@ function convertKeywordsToANMap(kwarray) { * @param ortb2 * @return {{}} appnexus-style keyword map using all keywords contained in ortb2 */ -export function getANMapFromOrtb(ortb2) { +export function getANMapFromOrtbKeywords(ortb2) { return convertKeywordsToANMap(getAllOrtbKeywords(ortb2)); } @@ -100,7 +111,30 @@ export function getANKewyordParamFromMaps(...anKeywordMaps) { export function getANKeywordParam(ortb2, ...anKeywordsMaps) { return getANKewyordParamFromMaps( - getANMapFromOrtb(ortb2), + getANMapFromOrtbKeywords(ortb2), + getANMapFromOrtbSegments(ortb2), ...anKeywordsMaps ) } + +export function getANMapFromOrtbSegments(ortb2) { + let ortbSegData = {}; + ORTB_SEG_PATHS.forEach(path => { + let ortbSegsArrObj = deepAccess(ortb2, path) || []; + ortbSegsArrObj.forEach(segObj => { + // only read segment data from known sources + const segtax = ORTB_SEGTAX_KEY_MAP[deepAccess(segObj, 'ext.segtax')]; + if (segtax) { + segObj.segment.forEach(seg => { + // if source was in multiple locations of ortb or had multiple segments in same area, stack them together into an array + if (ortbSegData[segtax]) { + ortbSegData[segtax].push(seg.id); + } else { + ortbSegData[segtax] = [seg.id] + } + }); + } + }); + }); + return ortbSegData; +} diff --git a/test/spec/modules/appnexusBidAdapter_spec.js b/test/spec/modules/appnexusBidAdapter_spec.js index 7d351e03453..1eeee4fb9b9 100644 --- a/test/spec/modules/appnexusBidAdapter_spec.js +++ b/test/spec/modules/appnexusBidAdapter_spec.js @@ -784,6 +784,69 @@ describe('AppNexusAdapter', function () { config.getConfig.restore(); }); + it('adds ortb2 segments to auction request as keywords', function() { + let bidRequest = Object.assign({}, bidRequests[0]); + const bidderRequest = { + ortb2: { + site: { + keywords: 'drill', + content: { + data: [{ + name: 'siteseg1', + ext: { + segtax: 540 + }, + segment: [{ + id: 's123', + }, { + id: 's234' + }] + }, { + name: 'sitseg2', + ext: { + segtax: 1 + }, + segment: [{ + id: 'unknown' + }] + }, { + name: 'siteseg3', + ext: { + segtax: 526 + }, + segment: [{ + id: 'dog' + }] + }] + } + }, + user: { + data: [{ + name: 'userseg1', + ext: { + segtax: 526 + }, + segment: [{ + id: 'cat' + }] + }] + } + } + }; + const request = spec.buildRequests([bidRequest], bidderRequest); + const payload = JSON.parse(request.data); + + expectKeywords(payload.keywords, [{ + 'key': 'drill' + }, { + 'key': '1plusx', + 'value': ['cat', 'dog'] + }, { + 'key': 'perid', + 'value': ['s123', 's234'] + }]); + }); + if (FEATURES.NATIVE) { it('should attach native params to the request', function () { let bidRequest = Object.assign({},