Skip to content

Commit

Permalink
Merge pull request #9 from Parrable/parrableIdSystem/PBID-11
Browse files Browse the repository at this point in the history
PBID-11: Integrate new compound cookie
  • Loading branch information
icflournoy authored May 12, 2020
2 parents 8f717da + af77318 commit 5d972c0
Show file tree
Hide file tree
Showing 8 changed files with 236 additions and 164 deletions.
5 changes: 0 additions & 5 deletions integrationExamples/gpt/audigentSegments_example.html
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,6 @@
params: {
// change to Parrable Partner Client ID(s) you received from the Parrable Partners you are using
partner: '30182847-e426-4ff9-b2b5-9ca1324ea09b'
},
storage: {
type: "cookie",
name: "_parrable_eid", // create a cookie with this name
expires: 365 // cookie can last for a year
}
}, {
name: "pubCommonId",
Expand Down
5 changes: 0 additions & 5 deletions integrationExamples/gpt/userId_example.html
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,6 @@
params: {
// change to Parrable Partner Client ID(s) you received from the Parrable Partners you are using
partner: '30182847-e426-4ff9-b2b5-9ca1324ea09b'
},
storage: {
type: "cookie",
name: "_parrable_eid", // create a cookie with this name
expires: 365 // cookie can last for a year
}
}, {
name: "pubCommonId",
Expand Down
125 changes: 114 additions & 11 deletions modules/parrableIdSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,50 @@ import { ajax } from '../src/ajax.js';
import { submodule } from '../src/hook.js';
import { getRefererInfo } from '../src/refererDetection.js';
import { uspDataHandler } from '../src/adapterManager.js';
import { getStorageManager } from '../src/storageManager.js';

const PARRABLE_URL = 'https://h.parrable.com/prebid';
const PARRABLE_COOKIE_NAME = '_parrable_id';
const LEGACY_ID_COOKIE_NAME = '_parrable_eid';
const LEGACY_OPTOUT_COOKIE_NAME = '_parrable_optout';
const ONE_YEAR_MS = 364 * 24 * 60 * 60 * 1000;

const storage = getStorageManager();
const expiredCookieDate = new Date(0).toString();

function getExpirationDate() {
const oneYearFromNow = new Date(utils.timestamp() + ONE_YEAR_MS);
return oneYearFromNow.toGMTString();
}

function deserializeParrableId(parrableIdStr) {
const parrableId = {};
const values = parrableIdStr.split(',');

values.forEach(function(value) {
const pair = value.split(':');
// unpack a value of 1 as true
parrableId[pair[0]] = +pair[1] === 1 ? true : pair[1];
});

return parrableId;
}

function serializeParrableId(parrableId) {
let components = [];

if (parrableId.eid) {
components.push('eid:' + parrableId.eid);
}
if (parrableId.ibaOptout) {
components.push('ibaOptout:1');
}
if (parrableId.ccpaOptout) {
components.push('ccpaOptout:1');
}

return components.join(',');
}

function isValidConfig(configParams) {
if (!configParams) {
Expand All @@ -22,17 +64,62 @@ function isValidConfig(configParams) {
utils.logError('User ID - parrableId submodule requires partner list');
return false;
}
if (configParams.storage) {
utils.logWarn('User ID - parrableId submodule does not require a storage config');
}
return true;
}

function fetchId(configParams, currentStoredId) {
function readCookie() {
const parrableIdStr = storage.getCookie(PARRABLE_COOKIE_NAME);
if (parrableIdStr) {
return deserializeParrableId(decodeURIComponent(parrableIdStr));
}
return undefined;
}

function writeCookie(parrableId) {
const parrableIdStr = encodeURIComponent(serializeParrableId(parrableId));
storage.setCookie(PARRABLE_COOKIE_NAME, parrableIdStr, getExpirationDate(), 'lax');
}

function readLegacyCookies() {
let legacyParrableId = {};
let legacyEid = storage.getCookie(LEGACY_ID_COOKIE_NAME);
if (legacyEid) {
legacyParrableId.eid = legacyEid;
}
let legacyOptout = storage.getCookie(LEGACY_OPTOUT_COOKIE_NAME);
if (legacyOptout === 'true') {
legacyParrableId.ibaOptout = true;
}
return legacyParrableId;
}

function migrateLegacyCookies(parrableId) {
writeCookie(parrableId);
if (parrableId.eid) {
storage.setCookie(LEGACY_ID_COOKIE_NAME, '', expiredCookieDate);
}
if (parrableId.ibaOptout) {
storage.setCookie(LEGACY_OPTOUT_COOKIE_NAME, '', expiredCookieDate);
}
}

function fetchId(configParams) {
if (!isValidConfig(configParams)) return;

let parrableId = readCookie();
if (!parrableId) {
parrableId = readLegacyCookies();
migrateLegacyCookies(parrableId);
}

const refererInfo = getRefererInfo();
const uspString = uspDataHandler.getConsentData();

const data = {
eid: currentStoredId || null,
eid: (parrableId && parrableId.eid) || null,
trackers: configParams.partner.split(','),
url: refererInfo.referer
};
Expand All @@ -53,21 +140,34 @@ function fetchId(configParams, currentStoredId) {

const callback = function (cb) {
const onSuccess = (response) => {
let eid;
let parrableId = {};
if (response) {
try {
let responseObj = JSON.parse(response);
eid = responseObj ? responseObj.eid : undefined;
if (responseObj) {
if (responseObj.ccpaOptout !== true) {
parrableId.eid = responseObj.eid;
} else {
parrableId.ccpaOptout = true;
}
if (responseObj.ibaOptout === true) {
parrableId.ibaOptout = true;
}
writeCookie(responseObj);
}
} catch (error) {
utils.logError(error);
}
}
cb(eid);
cb(parrableId);
};
ajax(PARRABLE_URL, onSuccess, searchParams, options);
};

return { callback };
return {
callback,
id: parrableId
};
};

/** @type {Submodule} */
Expand All @@ -80,22 +180,25 @@ export const parrableIdSubmodule = {
/**
* decode the stored id value for passing to bid requests
* @function
* @param {Object|string} value
* @param {ParrableId} parrableId
* @return {(Object|undefined}
*/
decode(value) {
return (value && typeof value === 'string') ? { 'parrableid': value } : undefined;
decode(parrableId) {
if (parrableId && utils.isPlainObject(parrableId)) {
return { 'parrableid': parrableId.eid };
}
return undefined;
},

/**
* performs action to obtain id and return a value in the callback's response argument
* @function
* @param {SubmoduleParams} [configParams]
* @param {ConsentData} [consentData]
* @returns {function(callback:function)}
* @returns {function(callback:function), id:ParrableId}
*/
getId(configParams, gdprConsentData, currentStoredId) {
return fetchId(configParams, currentStoredId);
return fetchId(configParams);
}
};

Expand Down
4 changes: 0 additions & 4 deletions modules/userId/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -426,10 +426,6 @@ function initSubmodules(submodules, consentData) {
refreshNeeded = storedDate && (Date.now() - storedDate.getTime() > submodule.config.storage.refreshInSeconds * 1000);
}

if (CONSTANTS.SUBMODULES_THAT_ALWAYS_REFRESH_ID[submodule.config.name] === true) {
refreshNeeded = true;
}

if (!storedId || refreshNeeded) {
// No previously saved id. Request one from submodule.
response = submodule.submodule.getId(submodule.config.params, consentData, storedId);
Expand Down
5 changes: 0 additions & 5 deletions modules/userId/userId.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,6 @@ pbjs.setConfig({
params: {
// Replace partner with comma-separated (if more than one) Parrable Partner Client ID(s) for Parrable-aware bid adapters in use
partner: "30182847-e426-4ff9-b2b5-9ca1324ea09b"
},
storage: {
type: 'cookie',
name: '_parrable_eid',
expires: 365
}
}, {
name: 'identityLink',
Expand Down
3 changes: 0 additions & 3 deletions src/constants.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,5 @@
"BID_TARGETING_SET": "targetingSet",
"RENDERED": "rendered",
"BID_REJECTED": "bidRejected"
},
"SUBMODULES_THAT_ALWAYS_REFRESH_ID": {
"parrableId": true
}
}
Loading

0 comments on commit 5d972c0

Please sign in to comment.