-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Trustpid User ID Module: initial release (#7945)
* feature: Add trustpid user id module * refactor: Update trustpidSystem module, comments and md file * refactor: Update trustpidSystem file to handle domain setting regardless of message events * refactor: Update trustpidSystem module and dependent tests and docs * refactor: Update trustpid undefined checks and returns * tests: Update trustpid tests * docs: Update trustpid docs typo * refactor: Update trustpid module with storage and logging utils. Adjust tests. Co-authored-by: Tomasz Januszek <tomasz@teavaro.com>
- Loading branch information
Showing
7 changed files
with
511 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
/** | ||
* This module adds TrustPid provided by Vodafone Sales and Services Limited to the User ID module | ||
* The {@link module:modules/userId} module is required | ||
* @module modules/trustpidSystem | ||
* @requires module:modules/userId | ||
*/ | ||
import { logInfo, logError } from '../src/utils.js'; | ||
import { submodule } from '../src/hook.js'; | ||
import { getStorageManager } from '../src/storageManager.js'; | ||
|
||
const MODULE_NAME = 'trustpid'; | ||
const LOG_PREFIX = 'Trustpid module' | ||
let mnoAcronym = ''; | ||
let mnoDomain = ''; | ||
|
||
export const storage = getStorageManager(null, MODULE_NAME); | ||
|
||
/** | ||
* Handle an event for an iframe. | ||
* Takes the body.url parameter from event and returns the string domain. | ||
* i.e.: "fc.vodafone.de" | ||
* @param event | ||
*/ | ||
function messageHandler(event) { | ||
let msg; | ||
try { | ||
if (event && event.data && typeof event.data === 'string' && event.data) { | ||
msg = JSON.parse(event.data); | ||
if (msg.msgType === 'MNOSELECTOR' && msg.body && msg.body.url) { | ||
let URL = msg.body.url.split('//'); | ||
let domainURL = URL[1].split('/'); | ||
mnoDomain = domainURL[0]; | ||
logInfo(`${LOG_PREFIX}: Message handler set domain to ${mnoDomain}`); | ||
getDomainAcronym(mnoDomain); | ||
} | ||
} | ||
} catch (e) { | ||
logError(e); | ||
} | ||
} | ||
|
||
/** | ||
* Properly sets the trustpid acronym depending on the domain value. | ||
* @param domain | ||
*/ | ||
function getDomainAcronym(domain) { | ||
let acronym = ''; | ||
const prefix = '-'; | ||
switch (domain) { | ||
case 'tmi.mno.link': | ||
acronym = 'ndye'; | ||
break; | ||
case 'tmi.vodafone.de': | ||
acronym = 'pqnx'; | ||
break; | ||
case 'tmi.telekom.de': | ||
acronym = 'avgw'; | ||
break; | ||
case 'tmi.tmid.es': | ||
acronym = 'kjws'; | ||
break; | ||
case 'uat.mno.link': | ||
acronym = 'xxxx'; | ||
break; | ||
case 'es.tmiservice.orange.com': | ||
acronym = 'aplw'; | ||
break; | ||
default: | ||
return 'none'; | ||
} | ||
return mnoAcronym = prefix + acronym; | ||
} | ||
|
||
// Set a listener to handle the iframe response message. | ||
window.addEventListener('message', messageHandler, false); | ||
|
||
/** | ||
* Get the "umid" from html5 local storage to make it available to the UserId module. | ||
* @param config | ||
* @returns {{trustpid: (*|string), acr: (string)}} | ||
*/ | ||
function getTrustpidFromStorage() { | ||
// Get the domain either from localStorage or global | ||
let domain = JSON.parse(storage.getDataFromLocalStorage('fcIdConnectDomain')) || mnoDomain; | ||
logInfo(`${LOG_PREFIX}: Local storage domain: ${domain}`); | ||
|
||
if (!domain) { | ||
logInfo(`${LOG_PREFIX}: Local storage domain not found, returning null`); | ||
return { | ||
trustpid: null, | ||
acr: null, | ||
}; | ||
} | ||
|
||
// Get the acronym from global | ||
let acronym = mnoAcronym; | ||
// if acronym is empty, but "domain" is available, get the acronym from domain | ||
if (!acronym) { | ||
getDomainAcronym(domain); | ||
acronym = mnoAcronym; | ||
} | ||
|
||
logInfo(`${LOG_PREFIX}: Domain acronym found: ${acronym}`); | ||
|
||
// Domain is correct in both local storage and idGraph, but no acronym is existing for the domain | ||
if (domain && !acronym) { | ||
return { | ||
trustpid: null, | ||
acr: null | ||
} | ||
} | ||
|
||
let fcIdConnectObject; | ||
let fcIdConnectData = JSON.parse(storage.getDataFromLocalStorage('fcIdConnectData')); | ||
logInfo(`${LOG_PREFIX}: Local storage fcIdConnectData: ${JSON.stringify(fcIdConnectData)}`); | ||
|
||
if (fcIdConnectData && | ||
fcIdConnectData.connectId && | ||
Array.isArray(fcIdConnectData.connectId.idGraph) && | ||
fcIdConnectData.connectId.idGraph.length > 0) { | ||
fcIdConnectObject = fcIdConnectData.connectId.idGraph.find(item => { | ||
return item.domain === domain; | ||
}); | ||
} | ||
logInfo(`${LOG_PREFIX}: Local storage fcIdConnectObject for domain: ${JSON.stringify(fcIdConnectObject)}`); | ||
|
||
return { | ||
trustpid: (fcIdConnectObject && fcIdConnectObject.umid) | ||
? fcIdConnectObject.umid | ||
: null, | ||
acr: acronym, | ||
}; | ||
} | ||
|
||
/** @type {Submodule} */ | ||
export const trustpidSubmodule = { | ||
/** | ||
* Used to link submodule with config | ||
* @type {string} | ||
*/ | ||
name: MODULE_NAME, | ||
/** | ||
* Decodes the stored id value for passing to bid requests. | ||
* @function | ||
* @returns {{trustpid: string} | null} | ||
*/ | ||
decode(bidId) { | ||
logInfo(`${LOG_PREFIX}: Decoded ID value ${JSON.stringify(bidId)}`); | ||
return bidId.trustpid ? bidId : null; | ||
}, | ||
/** | ||
* Get the id from helper function and initiate a new user sync. | ||
* @param config | ||
* @returns {{callback: result}|{id: {trustpid: string}}} | ||
*/ | ||
getId: function(config) { | ||
const data = getTrustpidFromStorage(); | ||
if (data.trustpid) { | ||
logInfo(`${LOG_PREFIX}: Local storage ID value ${JSON.stringify(data)}`); | ||
return {id: {trustpid: data.trustpid + data.acr}}; | ||
} else { | ||
if (!config) { | ||
config = {}; | ||
} | ||
if (!config.params) { | ||
config.params = {}; | ||
} | ||
if (typeof config.params.maxDelayTime === 'undefined' || config.params.maxDelayTime === null) { | ||
config.params.maxDelayTime = 1000; | ||
} | ||
// Current delay and delay step in milliseconds | ||
let currentDelay = 0; | ||
const delayStep = 50; | ||
const result = (callback) => { | ||
const data = getTrustpidFromStorage(); | ||
if (!data.trustpid) { | ||
if (currentDelay > config.params.maxDelayTime) { | ||
logInfo(`${LOG_PREFIX}: No trustpid value set after ${config.params.maxDelayTime} max allowed delay time`); | ||
callback(null); | ||
} else { | ||
currentDelay += delayStep; | ||
setTimeout(() => { | ||
result(callback); | ||
}, delayStep); | ||
} | ||
} else { | ||
const dataToReturn = { trustpid: data.trustpid + data.acr }; | ||
logInfo(`${LOG_PREFIX}: Returning ID value data of ${JSON.stringify(dataToReturn)}`); | ||
callback(dataToReturn); | ||
} | ||
}; | ||
return { callback: result }; | ||
} | ||
}, | ||
}; | ||
|
||
submodule('userId', trustpidSubmodule); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
## trustpid User Id Submodule | ||
|
||
trustpid User Id Module. | ||
|
||
First, make sure to add the trustpid submodule to your Prebid.js package with: | ||
|
||
``` | ||
gulp build --modules=userId,adfBidAdapter,trustpidSystem | ||
``` | ||
|
||
The following configuration parameters are available: | ||
|
||
``` | ||
pbjs.setConfig({ | ||
userSync: { | ||
userIds: [ | ||
{ | ||
name: 'trustpid', | ||
params: { | ||
maxDelayTime: 1000, | ||
}, | ||
bidders: ["adf"], | ||
storage: { | ||
type: "html5", | ||
name: "trustpid", | ||
expires: 1, //days | ||
}, | ||
} | ||
], | ||
} | ||
}); | ||
``` | ||
|
||
## Parameter Descriptions | ||
|
||
| Param under userSync.userIds[] | Scope | Type | Description | Example | | ||
| --- | --- | --- | --- | --- | | ||
| name | Required | String | The name of the module | `"trustpid"` | ||
| params | Required | Object | Object with configuration parameters for trustpid User Id submodule | - | | ||
| params.maxDelayTime | Required | Integer | Max amount of time (in seconds) before looking into storage for data | 2500 | | ||
| bidders | Required | Array of Strings | An array of bidder codes to which this user ID may be sent. Currently required and supporting AdformOpenRTB | `["adf"]` | | ||
| storage | Required | Object | Local storage configuration object | - | | ||
| storage.type | Required | String | Type of the storage that would be used to store user ID. Must be `"html5"` to utilise HTML5 local storage. | `"html5"` | | ||
| storage.name | Required | String | The name of the key in local storage where the user ID will be stored. | `"trustpid"` | | ||
| storage.expires | Required | Integer | How long (in days) the user ID information will be stored. For safety reasons, this information is required.| `1` | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.