Skip to content

Commit

Permalink
add imuidIdSystem
Browse files Browse the repository at this point in the history
  • Loading branch information
eknis committed Jul 30, 2021
1 parent 568a90d commit 8dd2c8a
Show file tree
Hide file tree
Showing 7 changed files with 239 additions and 1 deletion.
6 changes: 6 additions & 0 deletions integrationExamples/gpt/userId_example.html
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,13 @@
// To get new token, register https://developer.chrome.com/origintrials/#/trials/active for Federated Learning of Cohorts
token: "A3dHTSoNUMjjERBLlrvJSelNnwWUCwVQhZ5tNQ+sll7y+LkPPVZXtB77u2y7CweRIxiYaGwGXNlW1/dFp8VMEgIAAAB+eyJvcmlnaW4iOiJodHRwczovL3NoYXJlZGlkLm9yZzo0NDMiLCJmZWF0dXJlIjoiSW50ZXJlc3RDb2hvcnRBUEkiLCJleHBpcnkiOjE2MjYyMjA3OTksImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9"
}
},
{
"name": "imuid",
"params": {
"cid": 5126 // Set your Intimate Merger Customer ID here for production
}
}
],
"syncDelay": 5000,
"auctionDelay": 1000
Expand Down
3 changes: 2 additions & 1 deletion modules/.submodules.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"dmdIdSystem",
"akamaiDAPId",
"flocIdSystem",
"amxIdSystem"
"amxIdSystem",
"imuIdSystem"
],
"adpod": [
"freeWheelAdserverVideo",
Expand Down
143 changes: 143 additions & 0 deletions modules/imuIdSystem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/**
* The {@link module:modules/userId} module is required
* @module modules/imuIdSystem
*
* @requires module:modules/userId
*/

import * as utils from '../src/utils.js'
import { ajax } from '../src/ajax.js'
import { submodule } from '../src/hook.js';
import { getStorageManager } from '../src/storageManager.js';

export const storage = getStorageManager();

const storageKey = '__im_uid';
const cookieKey = '_im_vid';
const storageMaxAge = 1800000; // 30 minites (30 * 60 * 1000)
const cookiesMaxAge = 97200000000; // 37 months ((365 * 3 + 30) * 24 * 60 * 60 * 1000)

function setImDataInLocalStorage(value) {
storage.setDataInLocalStorage(storageKey, value);
storage.setDataInLocalStorage(`${storageKey}_mt`, new Date(utils.timestamp()).toUTCString());
}

function removeImDataFromLocalStorage() {
storage.removeDataFromLocalStorage(storageKey);
storage.removeDataFromLocalStorage(`${storageKey}_mt`);
}

function setImDataInCookie(value) {
storage.setCookie(
cookieKey,
value,
new Date(utils.timestamp() + cookiesMaxAge).toUTCString(),
'none'
);
}

function getLocalData() {
const mt = storage.getDataFromLocalStorage(`${storageKey}_mt`);
let expired = true;
if (Date.parse(mt) && Date.now() - (new Date(mt)).getTime() < storageMaxAge) {
expired = false;
}
return {
id: storage.getDataFromLocalStorage(storageKey),
vid: storage.getCookie(cookieKey),
expired: expired
};
}

function syncSuccessProcess(jsonResponse) {
if (!jsonResponse) {
return;
}
if (jsonResponse.uid) {
setImDataInLocalStorage(jsonResponse.uid);
if (jsonResponse.vid) {
setImDataInCookie(jsonResponse.vid);
}
} else {
removeImDataFromLocalStorage(storageKey);
}
}

function callImuidSync(syncUrl) {
return function (callback) {
const callbacks = {
success: response => {
let responseObj;
if (response) {
try {
responseObj = JSON.parse(response);
syncSuccessProcess(responseObj);
} catch (error) {
utils.logError('User ID - imuid submodule: ' + error);
}
}
if (callback) {
callback(responseObj.uid);
}
},
error: error => {
utils.logError('User ID - imuid submodule was unable to get data from api: ' + error);
if (callback) {
callback();
}
}
};
ajax(syncUrl, callbacks, undefined, {method: 'GET', withCredentials: true});
};
}

/** @type {Submodule} */
export const imuIdSubmodule = {
/**
* used to link submodule with config
* @type {string}
*/
name: 'imuid',
/**
* decode the stored id value for passing to bid requests
* @function
* @returns {{imuid: string} | undefined}
*/
decode(id) {
if (id && typeof id === 'string') {
return {imuid: id};
}
return undefined;
},
/**
* @function
* @param {SubmoduleConfig} [config]
* @returns {{id: string} | undefined}}}
*/
getId(config) {
const configParams = (config && config.params) || {};
if (!configParams || typeof configParams.cid !== 'number') {
utils.logError('User ID - imuid submodule requires a valid cid to be defined');
return undefined;
}
const localData = getLocalData();
let syncUrl = `https://audiencedata.im-apps.net/imuid/get?cid=${configParams.cid}`;
if (configParams.url) {
syncUrl = `${configParams.url}?cid=${configParams.cid}`;
}
if (localData.vid) {
syncUrl += `&vid=${localData.vid}`;
setImDataInCookie(localData.vid);
}

if (!localData.id) {
return {callback: callImuidSync(syncUrl)}
}
if (localData.expired) {
callImuidSync(syncUrl)();
}
return {id: localData.id};
}
};

submodule('userId', imuIdSubmodule);
35 changes: 35 additions & 0 deletions modules/imuIdSystem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Intimate Merger User ID Submodule

IM-UID is a universal identifier provided by Intimate Merger.
The integration of [IM-UID](https://intimatemerger.com/r/uid) into Prebid.js consists of this module.

## Building Prebid with IM-UID Support

First, make sure to add the Intimate Merger submodule to your Prebid.js package with:

```
gulp build --modules=imuIdSystem, userId
```

The following configuration parameters are available:

```javascript
pbjs.setConfig({
userSync: {
userIds: [{
name: 'imuid',
params: {
cid 5126 // Set your Intimate Merger Customer ID here for production
}
}
}]
}
});
```

| Param under userSync.userIds[] | Scope | Type | Description | Example |
| --- | --- | --- | --- | --- |
| name | Required | String | The name of this module. | `"imuid"` |
| params | Required | Object | Details of module params. | |
| params.cid | Required | String | This is the Customer ID value obtained via Intimate Merger. | `5126` |
| params.url | Optional | String | Use this to change the default endpoint URL. | `"https://example.com/some/api"` |
4 changes: 4 additions & 0 deletions modules/userId/eids.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@ const USER_IDS_CONFIG = {
amxId: {
source: 'amxrtb.com',
atype: 1,
},
'imuid': {
source: 'intimatemerger.com',
atype: 1
}
};

Expand Down
6 changes: 6 additions & 0 deletions modules/userId/userId.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,12 @@ pbjs.setConfig({
name: "_dpes_id",
expires: 90
}
},
{
name: 'imuid',
params: {
cid: 5126 // Set your Intimate Merger Customer ID here for production
}
}],
syncDelay: 5000
}
Expand Down
43 changes: 43 additions & 0 deletions test/spec/modules/imuIdSystem_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { imuIdSubmodule, storage } from 'modules/imuIdSystem.js';

describe('imuId module', function () {
let getLocalStorageStub;

beforeEach(function (done) {
getLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage');
done();
});

afterEach(function () {
getLocalStorageStub.restore();
});

const storageTestCasesForEmpty = [
undefined,
null,
''
]

const configParamTestCase = {
params: {
cid: 5126
}
}

it('getId() should return the uid when it exists in local storages', function () {
getLocalStorageStub.withArgs('__im_uid').returns('testUid');
const id = imuIdSubmodule.getId(configParamTestCase);
expect(id).to.be.deep.equal({id: 'testUid'});
});

storageTestCasesForEmpty.forEach(testCase => it('getId() should return the callback when it not exists in local storages', function () {
getLocalStorageStub.withArgs('__im_uid').returns(testCase);
const id = imuIdSubmodule.getId(configParamTestCase);
expect(id).have.all.keys('callback');
}))

it('decode() should return the uid when it exists in local storages', function () {
const id = imuIdSubmodule.decode('testDecode');
expect(id).to.be.deep.equal({imuid: 'testDecode'});
});
});

0 comments on commit 8dd2c8a

Please sign in to comment.