Skip to content

Commit

Permalink
Adding a method pbjs.getUserIds to share userIds in Prebid to externa…
Browse files Browse the repository at this point in the history
…l 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
  • Loading branch information
pm-harshad-mane authored and Isaac Dettman committed Jul 11, 2019
1 parent b26e6ad commit 2be5cc7
Showing 1 changed file with 46 additions and 14 deletions.
60 changes: 46 additions & 14 deletions modules/userId/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,19 +199,32 @@ 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 => {
carry[key] = i.idObj[key];
});
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 => {
Expand All @@ -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());
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 2be5cc7

Please sign in to comment.