Skip to content

Commit

Permalink
LiveIntent UserId module: Expose shared id
Browse files Browse the repository at this point in the history
  • Loading branch information
peixunzhang committed Feb 22, 2024
1 parent adbcf71 commit 1b94935
Show file tree
Hide file tree
Showing 8 changed files with 235 additions and 102 deletions.
18 changes: 18 additions & 0 deletions libraries/pubcidEids/pubcidEids.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export const PUBCID_EIDS = {
'pubcid': {
source: 'pubcid.org',
atype: 1,
getValue: function(data) {
if (data.id) {
return data.id;
} else {
return data;
}
},
getUidExt: function(data) {
if (data.ext) {
return data.ext;
}
}
}
};
96 changes: 60 additions & 36 deletions modules/liveIntentIdSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import { triggerPixel, logError } from '../src/utils.js';
import { ajaxBuilder } from '../src/ajax.js';
import { submodule } from '../src/hook.js';
import { LiveConnect } from 'live-connect-js'; // eslint-disable-line prebid/validate-imports
import { gdprDataHandler, uspDataHandler, gppDataHandler } from '../src/adapterManager.js';
import {getStorageManager} from '../src/storageManager.js';
import {MODULE_TYPE_UID} from '../src/activities/modules.js';
import {UID2_EIDS} from '../libraries/uid2Eids/uid2Eids.js';
import { gdprDataHandler, uspDataHandler, gppDataHandler, coppaDataHandler } from '../src/adapterManager.js';
import { getStorageManager } from '../src/storageManager.js';
import { MODULE_TYPE_UID } from '../src/activities/modules.js';
import { UID2_EIDS } from '../libraries/uid2Eids/uid2Eids.js';
import { PUBCID_EIDS } from '../libraries/pubcidEids/pubcidEids.js';
import { getRefererInfo } from '../src/refererDetection.js';

/**
Expand All @@ -20,12 +21,12 @@ import { getRefererInfo } from '../src/refererDetection.js';
* @typedef {import('../modules/userId/index.js').IdResponse} IdResponse
*/

const DEFAULT_AJAX_TIMEOUT = 5000
const EVENTS_TOPIC = 'pre_lips'
const DEFAULT_AJAX_TIMEOUT = 5000;
const EVENTS_TOPIC = 'pre_lips';
const MODULE_NAME = 'liveIntentId';
const LI_PROVIDER_DOMAIN = 'liveintent.com';
export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME});
const defaultRequestedAttributes = {'nonId': true}
const defaultRequestedAttributes = {'nonId': true};
const calls = {
ajaxGet: (url, onSuccess, onError, timeout) => {
ajaxBuilder(timeout)(
Expand All @@ -52,10 +53,10 @@ let liveConnect = null;
*/
export function reset() {
if (window && window.liQ_instances) {
window.liQ_instances.forEach(i => i.eventBus.off(EVENTS_TOPIC, setEventFiredFlag))
window.liQ_instances.forEach(i => i.eventBus.off(EVENTS_TOPIC, setEventFiredFlag));
window.liQ_instances = [];
}
liveIntentIdSubmodule.setModuleMode(null)
liveIntentIdSubmodule.setModuleMode(null);
eventFired = false;
liveConnect = null;
}
Expand All @@ -69,7 +70,7 @@ export function setEventFiredFlag() {

function parseLiveIntentCollectorConfig(collectConfig) {
const config = {};
collectConfig = collectConfig || {}
collectConfig = collectConfig || {};
collectConfig.appId && (config.appId = collectConfig.appId);
collectConfig.fpiStorageStrategy && (config.storageStrategy = collectConfig.fpiStorageStrategy);
collectConfig.fpiExpirationDays && (config.expirationDays = collectConfig.fpiExpirationDays);
Expand All @@ -85,30 +86,39 @@ function parseLiveIntentCollectorConfig(collectConfig) {
* @returns {Array}
*/
function parseRequestedAttributes(overrides) {
function renameAttribute(attribute) {
if (attribute === 'sharedId') {
return 'idCookie';
} else {
return attribute;
};
}
function createParameterArray(config) {
return Object.entries(config).flatMap(([k, v]) => (typeof v === 'boolean' && v) ? [k] : []);
return Object.entries(config).flatMap(([k, v]) => (typeof v === 'boolean' && v) ? [renameAttribute(k)] : []);
}
if (typeof overrides === 'object') {
return createParameterArray({...defaultRequestedAttributes, ...overrides})
return createParameterArray({...defaultRequestedAttributes, ...overrides});
} else {
return createParameterArray(defaultRequestedAttributes);
}
}

function initializeLiveConnect(configParams) {
configParams = configParams || {};
if (liveConnect) {
return liveConnect;
}

configParams = configParams || {};
const sharedIdConfig = configParams.sharedId || {};

const publisherId = configParams.publisherId || 'any';
const identityResolutionConfig = {
publisherId: publisherId,
requestedAttributes: parseRequestedAttributes(configParams.requestedAttributesOverrides)
};
if (configParams.url) {
identityResolutionConfig.url = configParams.url
}
identityResolutionConfig.url = configParams.url;
};

identityResolutionConfig.ajaxTimeout = configParams.ajaxTimeout || DEFAULT_AJAX_TIMEOUT;

Expand All @@ -118,19 +128,24 @@ function initializeLiveConnect(configParams) {
liveConnectConfig.distributorId = configParams.distributorId;
identityResolutionConfig.source = configParams.distributorId;
} else {
identityResolutionConfig.source = configParams.partner || 'prebid'
identityResolutionConfig.source = configParams.partner || 'prebid';
}

liveConnectConfig.wrapperName = 'prebid';
liveConnectConfig.trackerVersion = '$prebid.version$';
liveConnectConfig.identityResolutionConfig = identityResolutionConfig;
liveConnectConfig.identifiersToResolve = configParams.identifiersToResolve || [];
liveConnectConfig.fireEventDelay = configParams.fireEventDelay;

liveConnectConfig.idCookie = {};
liveConnectConfig.idCookie.name = sharedIdConfig.name;
liveConnectConfig.idCookie.strategy = sharedIdConfig.strategy == 'html5' ? 'localStorage' : sharedIdConfig.strategy;

const usPrivacyString = uspDataHandler.getConsentData();
if (usPrivacyString) {
liveConnectConfig.usPrivacyString = usPrivacyString;
}
const gdprConsent = gdprDataHandler.getConsentData()
const gdprConsent = gdprDataHandler.getConsentData();
if (gdprConsent) {
liveConnectConfig.gdprApplies = gdprConsent.gdprApplies;
liveConnectConfig.gdprConsent = gdprConsent.consentString;
Expand All @@ -144,21 +159,21 @@ function initializeLiveConnect(configParams) {
// The third param is the ajax and pixel object, the ajax and pixel use PBJS
liveConnect = liveIntentIdSubmodule.getInitializer()(liveConnectConfig, storage, calls);
if (configParams.emailHash) {
liveConnect.push({ hash: configParams.emailHash })
liveConnect.push({ hash: configParams.emailHash });
}
return liveConnect;
}

function tryFireEvent() {
if (!eventFired && liveConnect) {
const eventDelay = liveConnect.config.fireEventDelay || 500
const eventDelay = liveConnect.config.fireEventDelay || 500;
setTimeout(() => {
const instances = window.liQ_instances
instances.forEach(i => i.eventBus.once(EVENTS_TOPIC, setEventFiredFlag))
const instances = window.liQ_instances;
instances.forEach(i => i.eventBus.once(EVENTS_TOPIC, setEventFiredFlag));
if (!eventFired && liveConnect) {
liveConnect.fire();
}
}, eventDelay)
}, eventDelay);
}
}

Expand All @@ -172,10 +187,10 @@ export const liveIntentIdSubmodule = {
name: MODULE_NAME,

setModuleMode(mode) {
this.moduleMode = mode
this.moduleMode = mode;
},
getInitializer() {
return (liveConnectConfig, storage, calls) => LiveConnect(liveConnectConfig, storage, calls, this.moduleMode)
return (liveConnectConfig, storage, calls) => LiveConnect(liveConnectConfig, storage, calls, this.moduleMode);
},

/**
Expand All @@ -193,46 +208,54 @@ export const liveIntentIdSubmodule = {
const result = {};

// old versions stored lipbid in unifiedId. Ensure that we can still read the data.
const lipbid = value.nonId || value.unifiedId
const lipbid = value.nonId || value.unifiedId;
if (lipbid) {
value.lipbid = lipbid
delete value.unifiedId
result.lipb = value
const lipb = { ...value, lipbid };
delete lipb.unifiedId;
result.lipb = lipb;
}

// Lift usage of uid2 by exposing uid2 if we were asked to resolve it.
// As adapters are applied in lexicographical order, we will always
// be overwritten by the 'proper' uid2 module if it is present.
if (value.uid2) {
result.uid2 = { 'id': value.uid2, ext: { provider: LI_PROVIDER_DOMAIN } }
result.uid2 = { 'id': value.uid2, ext: { provider: LI_PROVIDER_DOMAIN } };
}

if (value.bidswitch) {
result.bidswitch = { 'id': value.bidswitch, ext: { provider: LI_PROVIDER_DOMAIN } }
result.bidswitch = { 'id': value.bidswitch, ext: { provider: LI_PROVIDER_DOMAIN } };
}

if (value.medianet) {
result.medianet = { 'id': value.medianet, ext: { provider: LI_PROVIDER_DOMAIN } }
result.medianet = { 'id': value.medianet, ext: { provider: LI_PROVIDER_DOMAIN } };
}

if (value.magnite) {
result.magnite = { 'id': value.magnite, ext: { provider: LI_PROVIDER_DOMAIN } }
result.magnite = { 'id': value.magnite, ext: { provider: LI_PROVIDER_DOMAIN } };
}

if (value.index) {
result.index = { 'id': value.index, ext: { provider: LI_PROVIDER_DOMAIN } }
result.index = { 'id': value.index, ext: { provider: LI_PROVIDER_DOMAIN } };
}

if (value.openx) {
result.openx = { 'id': value.openx, ext: { provider: LI_PROVIDER_DOMAIN } }
result.openx = { 'id': value.openx, ext: { provider: LI_PROVIDER_DOMAIN } };
}

if (value.pubmatic) {
result.pubmatic = { 'id': value.pubmatic, ext: { provider: LI_PROVIDER_DOMAIN } }
result.pubmatic = { 'id': value.pubmatic, ext: { provider: LI_PROVIDER_DOMAIN } };
}

if (value.sovrn) {
result.sovrn = { 'id': value.sovrn, ext: { provider: LI_PROVIDER_DOMAIN } }
result.sovrn = { 'id': value.sovrn, ext: { provider: LI_PROVIDER_DOMAIN } };
}

if (value.idCookie) {
if (!coppaDataHandler.getCoppa()) {
result.lipb = { ...result.lipb, pubcid: value.idCookie };
result.pubcid = { 'id': value.idCookie, ext: { provider: LI_PROVIDER_DOMAIN } };
}
delete result.lipb.idCookie;
}

if (value.thetradedesk) {
Expand Down Expand Up @@ -279,6 +302,7 @@ export const liveIntentIdSubmodule = {
},
eids: {
...UID2_EIDS,
...PUBCID_EIDS,
'lipb': {
getValue: function(data) {
return data.lipbid;
Expand Down
6 changes: 2 additions & 4 deletions modules/sharedIdSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {getStorageManager} from '../src/storageManager.js';
import {VENDORLESS_GVLID} from '../src/consentHandler.js';
import {MODULE_TYPE_UID} from '../src/activities/modules.js';
import {domainOverrideToRootDomain} from '../libraries/domainOverrideToRootDomain/index.js';
import {PUBCID_EIDS} from '../libraries/pubcidEids/pubcidEids.js';

/**
* @typedef {import('../modules/userId/index.js').Submodule} Submodule
Expand Down Expand Up @@ -183,10 +184,7 @@ export const sharedIdSystemSubmodule = {

domainOverride: domainOverrideToRootDomain(storage, 'sharedId'),
eids: {
'pubcid': {
source: 'pubcid.org',
atype: 1
},
...PUBCID_EIDS
}
};

Expand Down
17 changes: 14 additions & 3 deletions modules/userId/eids.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ userIdAsEids = [
segments: ['s1', 's2']
}
},
{
source: 'bidswitch.net',
uids: [{
Expand All @@ -117,7 +117,7 @@ userIdAsEids = [
}
}]
},
{
source: 'liveintent.indexexchange.com',
uids: [{
Expand Down Expand Up @@ -160,7 +160,7 @@ userIdAsEids = [
provider: 'liveintent.com'
}
}]
},
},
{
source: 'media.net',
Expand Down Expand Up @@ -195,6 +195,17 @@ userIdAsEids = [
}]
},
{
source: 'pubcid.org',
uids: [{
id: 'some-random-id-value',
atype: 1,
ext: {
provider: 'liveintent.com'
}
}]
},
{
source: 'merkleinc.com',
uids: [{
Expand Down
30 changes: 15 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@
"fun-hooks": "^0.9.9",
"gulp-wrap": "^0.15.0",
"just-clone": "^1.0.2",
"live-connect-js": "^6.3.4"
"live-connect-js": "^6.6.0"
},
"optionalDependencies": {
"fsevents": "^2.3.2"
Expand Down
Loading

0 comments on commit 1b94935

Please sign in to comment.