diff --git a/modules/conversantBidAdapter.js b/modules/conversantBidAdapter.js index aa0761161f7..9ad1357fa2a 100644 --- a/modules/conversantBidAdapter.js +++ b/modules/conversantBidAdapter.js @@ -144,6 +144,12 @@ export const spec = { userExt.fpc = pubcid; } + // Add Eids if available + const eids = collectEids(validBidRequests); + if (eids.length > 0) { + userExt.eids = eids; + } + // Only add the user object if it's not empty if (!utils.isEmpty(userExt)) { payload.user = {ext: userExt}; @@ -294,6 +300,45 @@ function copyOptProperty(src, dst, dstName) { } } +/** + * Collect IDs from validBidRequests and store them as an extended id array + * @param bidRequests valid bid requests + */ +function collectEids(bidRequests) { + const request = bidRequests[0]; // bidRequests have the same userId object + const eids = []; + + addEid(eids, request, 'userId.tdid', 'adserver.org'); + addEid(eids, request, 'userId.idl_env', 'liveramp.com'); + addEid(eids, request, 'userId.criteoId', 'criteo.com'); + addEid(eids, request, 'userId.id5id', 'id5-sync.com'); + addEid(eids, request, 'userId.parrableid', 'parrable.com'); + addEid(eids, request, 'userId.digitrustid.data.id', 'digitru.st'); + addEid(eids, request, 'userId.lipb.lipbid', 'liveintent.com'); + + return eids; +} + +/** + * Extract and push a single extended id into eids array + * @param eids Array of extended IDs + * @param idObj Object containing IDs + * @param keyPath Nested properties expressed as a path + * @param source Source for the ID + */ +function addEid(eids, idObj, keyPath, source) { + const id = utils.deepAccess(idObj, keyPath); + if (id) { + eids.push({ + source: source, + uids: [{ + id: id, + atype: 1 + }] + }); + } +} + /** * Look for a stored value from both cookie and local storage and return the first value found. * @param key Key for the search diff --git a/test/spec/modules/conversantBidAdapter_spec.js b/test/spec/modules/conversantBidAdapter_spec.js index 02a915f0c17..37a13312619 100644 --- a/test/spec/modules/conversantBidAdapter_spec.js +++ b/test/spec/modules/conversantBidAdapter_spec.js @@ -374,6 +374,7 @@ describe('Conversant adapter tests', function() { // construct http post payload const payload = spec.buildRequests(requests).data; expect(payload).to.have.deep.nested.property('user.ext.fpc', 12345); + expect(payload).to.not.have.nested.property('user.ext.eids'); }); it('Verify User ID publisher commond id support', function() { @@ -387,6 +388,7 @@ describe('Conversant adapter tests', function() { // construct http post payload const payload = spec.buildRequests(requests).data; expect(payload).to.have.deep.nested.property('user.ext.fpc', 67890); + expect(payload).to.not.have.nested.property('user.ext.eids'); }); it('Verify GDPR bid request', function() { @@ -416,6 +418,24 @@ describe('Conversant adapter tests', function() { expect(payload).to.not.have.deep.nested.property('regs.ext.gdpr'); }); + describe('Extended ID', function() { + it('Verify unifiedid and liveramp', function() { + // clone bidRequests + let requests = utils.deepClone(bidRequests); + + // add pubcid to every entry + requests.forEach((unit) => { + Object.assign(unit, {userId: {pubcid: 112233, tdid: 223344, idl_env: 334455}}); + }); + // construct http post payload + const payload = spec.buildRequests(requests).data; + expect(payload).to.have.deep.nested.property('user.ext.eids', [ + {source: 'adserver.org', uids: [{id: 223344, atype: 1}]}, + {source: 'liveramp.com', uids: [{id: 334455, atype: 1}]} + ]); + }); + }); + describe('direct reading pubcid', function() { const ID_NAME = '_pubcid'; const CUSTOM_ID_NAME = 'myid';