diff --git a/modules/yieldlabBidAdapter.js b/modules/yieldlabBidAdapter.js index 13910d688e8..23ff94f62a1 100644 --- a/modules/yieldlabBidAdapter.js +++ b/modules/yieldlabBidAdapter.js @@ -1,4 +1,4 @@ -import { _each, deepAccess, isArray, isFn, isPlainObject, timestamp } from '../src/utils.js'; +import { _each, deepAccess, isArray, isEmptyStr, isFn, isPlainObject, timestamp } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { find } from '../src/polyfill.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; @@ -130,6 +130,13 @@ export const spec = { } } } + + const topics = getGoogleTopics(bidderRequest); + if (topics) { + assignIfNotUndefined(query, 'segtax', topics.segtax); + assignIfNotUndefined(query, 'segclass', topics.segclass); + assignIfNotUndefined(query, 'segments', topics.segments); + } } const adslots = adslotIds.join(','); @@ -607,4 +614,22 @@ function assignIfNotUndefined(obj, key, value) { } } +function getGoogleTopics(bid) { + const userData = deepAccess(bid, 'ortb2.user.data') || []; + const validData = userData.filter(dataObj => + dataObj.segment && isArray(dataObj.segment) && dataObj.segment.length > 0 && + dataObj.segment.every(seg => (seg.id && !isEmptyStr(seg.id) && isFinite(seg.id))) + )[0]; + + if (validData) { + return { + segtax: validData.ext?.segtax, + segclass: validData.ext?.segclass, + segments: validData.segment.map(seg => Number(seg.id)).join(','), + }; + } + + return undefined; +} + registerBidder(spec); diff --git a/test/spec/modules/yieldlabBidAdapter_spec.js b/test/spec/modules/yieldlabBidAdapter_spec.js index 751dff4fe33..225186dd326 100644 --- a/test/spec/modules/yieldlabBidAdapter_spec.js +++ b/test/spec/modules/yieldlabBidAdapter_spec.js @@ -585,6 +585,76 @@ describe('yieldlabBidAdapter', () => { expect(request.url).to.not.include('dsaparams'); }); }); + + describe('google topics handling', () => { + afterEach(() => { + config.resetConfig(); + }); + + it('does pass segtax, segclass, segments for google topics data', () => { + const GOOGLE_TOPICS_DATA = { + ortb2: { + user: { + data: [ + { + ext: { + segtax: 600, + segclass: 'v1', + }, + segment: [ + {id: '717'}, {id: '808'}, + ] + } + ] + }, + }, + } + config.setConfig(GOOGLE_TOPICS_DATA); + const request = spec.buildRequests([DEFAULT_REQUEST()], { ...REQPARAMS, ...GOOGLE_TOPICS_DATA }); + expect(request.url).to.include('segtax=600&segclass=v1&segments=717%2C808'); + }); + + it('does not pass topics params for invalid topics data', () => { + const INVALID_TOPICS_DATA = { + ortb2: { + user: { + data: [ + { + segment: [] + }, + { + segment: [{id: ''}] + }, + { + segment: [{id: null}] + }, + { + segment: [{id: 'dummy'}, {id: '123'}] + }, + { + ext: { + segtax: 600, + segclass: 'v1', + }, + segment: [ + { + name: 'dummy' + } + ] + }, + ] + } + } + }; + + config.setConfig(INVALID_TOPICS_DATA); + let request = spec.buildRequests([DEFAULT_REQUEST()], { ...REQPARAMS, ...INVALID_TOPICS_DATA }); + + expect(request.url).to.not.include('segtax'); + expect(request.url).to.not.include('segclass'); + expect(request.url).to.not.include('segments'); + }); + }); }); describe('interpretResponse', () => {