Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trustpid User ID Module: initial release #7945

Merged
merged 12 commits into from
Jan 26, 2022
1 change: 1 addition & 0 deletions modules/.submodules.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"quantcastIdSystem",
"sharedIdSystem",
"tapadIdSystem",
"trustpidSystem",
"uid2IdSystem",
"unifiedIdSystem",
"verizonMediaIdSystem",
Expand Down
197 changes: 197 additions & 0 deletions modules/trustpidSystem.js
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);
45 changes: 45 additions & 0 deletions modules/trustpidSystem.md
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` |
9 changes: 9 additions & 0 deletions modules/userId/eids.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ const USER_IDS_CONFIG = {

// key-name : {config}

// trustpid
'trustpid': {
source: 'trustpid.com',
atype: 1,
getValue: function (data) {
return data;
},
},

// intentIqId
'intentIqId': {
source: 'intentiq.com',
Expand Down
12 changes: 10 additions & 2 deletions modules/userId/eids.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

```
userIdAsEids = [
{
source: 'trustpid.com',
uids: [{
id: 'some-random-id-value',
atype: 1
}]
},

{
source: 'pubcid.org',
uids: [{
Expand All @@ -28,7 +36,7 @@ userIdAsEids = [
atype: 1
}]
},

{
source: 'neustar.biz',
uids: [{
Expand Down Expand Up @@ -203,7 +211,7 @@ userIdAsEids = [
id: 'some-random-id-value',
atype: 3
}]
},
},
{
source: 'kpuid.com',
uids: [{
Expand Down
19 changes: 17 additions & 2 deletions modules/userId/userId.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## User ID Example Configuration

Example showing `cookie` storage for user id data for each of the submodules

```
pbjs.setConfig({
userSync: {
Expand Down Expand Up @@ -147,10 +148,23 @@ pbjs.setConfig({
```

Example showing `localStorage` for user id data for some submodules

```
pbjs.setConfig({
userSync: {
userIds: [{
userIds: [
{
name: 'trustpid',
params: {
maxDelayTime: 2500
},
bidders: ['adform'],
storage: {
type: 'html5',
name: 'trustpid',
expires: 60
}
}, {
name: "unifiedId",
params: {
partner: "prebid",
Expand Down Expand Up @@ -278,7 +292,7 @@ pbjs.setConfig({
name: "knssoId",
expires: 30
},
}
}
},
{
name: 'imuid',
Expand Down Expand Up @@ -312,6 +326,7 @@ pbjs.setConfig({
```

Example showing how to configure a `value` object to pass directly to bid adapters

```
pbjs.setConfig({
userSync: {
Expand Down
Loading