From 2be5cc7ccbc89c940c1e2e253a989e4a351167e2 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Thu, 11 Jul 2019 12:03:04 -0700 Subject: [PATCH] Adding a method pbjs.getUserIds to share userIds in Prebid to external codes (#3889) * Adding a mthod pbjs.getUserIds to share userIds in Prebid to external codes - Need an API to share the UserIds retrieved by Prebid with external codes - Use casse: UserIds can be passed to Wrappers like A9/EB - Added pbjs.getUserIds method - Moved the cide that initalizes all sub-modules and calls passbacks into a separate function - Moved code to combine submodule ids in an object into a separate function * implemented code suggestion chnages * fixed eslint issue --- modules/userId/index.js | 60 +++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/modules/userId/index.js b/modules/userId/index.js index e83258a4e02..16421e39e20 100644 --- a/modules/userId/index.js +++ b/modules/userId/index.js @@ -199,12 +199,12 @@ function processSubmoduleCallbacks(submodules) { } /** - * @param {AdUnit[]} adUnits + * This function will create a combined object for all subModule Ids * @param {SubmoduleContainer[]} submodules */ -function addIdDataToAdUnitBids(adUnits, submodules) { - if ([adUnits, submodules].some(i => !Array.isArray(i) || !i.length)) { - return; +function getCombinedSubmoduleIds(submodules) { + if (!Array.isArray(submodules) || !submodules.length) { + return {}; } const combinedSubmoduleIds = submodules.filter(i => utils.isPlainObject(i.idObj) && Object.keys(i.idObj).length).reduce((carry, i) => { Object.keys(i.idObj).forEach(key => { @@ -212,6 +212,19 @@ function addIdDataToAdUnitBids(adUnits, submodules) { }); return carry; }, {}); + + return combinedSubmoduleIds; +} + +/** + * @param {AdUnit[]} adUnits + * @param {SubmoduleContainer[]} submodules + */ +function addIdDataToAdUnitBids(adUnits, submodules) { + if ([adUnits].some(i => !Array.isArray(i) || !i.length)) { + return; + } + const combinedSubmoduleIds = getCombinedSubmoduleIds(submodules); if (Object.keys(combinedSubmoduleIds).length) { adUnits.forEach(adUnit => { adUnit.bids.forEach(bid => { @@ -223,15 +236,9 @@ function addIdDataToAdUnitBids(adUnits, submodules) { } /** - * Hook is executed before adapters, but after consentManagement. Consent data is requied because - * this module requires GDPR consent with Purpose #1 to save data locally. - * The two main actions handled by the hook are: - * 1. check gdpr consentData and handle submodule initialization. - * 2. append user id data (loaded from cookied/html or from the getId method) to bids to be accessed in adapters. - * @param {Object} reqBidsConfigObj required; This is the same param that's used in pbjs.requestBids. - * @param {function} fn required; The next function in the chain, used by hook.js + * This is a common function that will initalize subModules if not already done and it will also execute subModule callbacks */ -export function requestBidsHook(fn, reqBidsConfigObj) { +function initializeSubmodulesAndExecuteCallbacks() { // initialize submodules only when undefined if (typeof initializedSubmodules === 'undefined') { initializedSubmodules = initSubmodules(submodules, gdprDataHandler.getConsentData()); @@ -256,14 +263,36 @@ export function requestBidsHook(fn, reqBidsConfigObj) { } } } +} +/** + * Hook is executed before adapters, but after consentManagement. Consent data is requied because + * this module requires GDPR consent with Purpose #1 to save data locally. + * The two main actions handled by the hook are: + * 1. check gdpr consentData and handle submodule initialization. + * 2. append user id data (loaded from cookied/html or from the getId method) to bids to be accessed in adapters. + * @param {Object} reqBidsConfigObj required; This is the same param that's used in pbjs.requestBids. + * @param {function} fn required; The next function in the chain, used by hook.js + */ +export function requestBidsHook(fn, reqBidsConfigObj) { + // initialize submodules only when undefined + initializeSubmodulesAndExecuteCallbacks(); // pass available user id data to bid adapters addIdDataToAdUnitBids(reqBidsConfigObj.adUnits || getGlobal().adUnits, initializedSubmodules); - // calling fn allows prebid to continue processing return fn.call(this, reqBidsConfigObj); } +/** + * This function will be exposed in global-name-space so that userIds stored by Prebid UserId module can be used by external codes as well. + * Simple use case will be passing these UserIds to A9 wrapper solution + */ +function getUserIds() { + // initialize submodules only when undefined + initializeSubmodulesAndExecuteCallbacks(); + return getCombinedSubmoduleIds(initializedSubmodules); +}; + /** * @param {SubmoduleContainer[]} submodules * @param {ConsentData} consentData @@ -425,7 +454,10 @@ export function init(config) { syncDelay = utils.isNumber(userSync.syncDelay) ? userSync.syncDelay : DEFAULT_SYNC_DELAY; updateSubmodules(); } - }) + }); + + // exposing getUserIds function in global-name-space so that userIds stored in Prebid can be used by external codes. + (getGlobal()).getUserIds = getUserIds; } // init config update listener to start the application