Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion allowedModules.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ module.exports = {
...sharedWhiteList,
'criteo-direct-rsa-validate',
'jsencrypt',
'crypto-js'
'crypto-js',
'live-connect'
],
'src': [
...sharedWhiteList,
Expand Down
69 changes: 69 additions & 0 deletions integrationExamples/gpt/liveIntentId_example.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<!--
This page resolves an identifier via LiveIntent Id. It can be considered a "hello world" example for using
Prebid with the LiveIntent Id Module.
The page also has an example of integration with USP privacy policy. The consent string is attached to the
LiveIntent's pixel requests.
-->

<html>
<head>
<script async src="../../build/dev/prebid.js"></script>
<script>
var adUnits = [{
code: 'div-gpt-ad-1460505748561-0',
mediaTypes: {
banner: {
sizes: [[300, 250], [300, 600]],
}
},
// Replace this object to test a new Adapter!
bids: [{
bidder: 'appnexus',
params: {
placementId: 13144370
}
}],
}];

var pbjs = pbjs || {};
pbjs.que = pbjs.que || [];

</script>

<script>
pbjs.que.push(function() {
pbjs.setConfig({
userSync: {
userIds: [{
name: 'liveIntentId',
params: {
publisherId: '9896876',
identifiersToResolve: ['my-own-cookie']
}
}]
},
consentManagement: {
usp: {
cmpApi: 'static',
consentData: {
getUSPData: {
uspString: '1YYY'
}
}
}
}
});
pbjs.addAdUnits(adUnits);
pbjs.requestBids({
bidsBackHandler: function(bidResponses) {
console.log(bidResponses)
}
});
});
</script>
</head>

<body>
<h2>Prebid.js LiveIntent Id Test</h2>
</body>
</html>
132 changes: 78 additions & 54 deletions modules/liveIntentIdSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,72 @@
* @module modules/liveIntentIdSystem
* @requires module:modules/userId
*/
import * as utils from '../src/utils'
import {ajax} from '../src/ajax';
import {submodule} from '../src/hook';
import * as utils from '../src/utils';
import { submodule } from '../src/hook';
import { LiveConnect } from 'live-connect-js/cjs/live-connect';
import { uspDataHandler } from '../src/adapterManager';

const MODULE_NAME = 'liveIntentId';
const LIVE_CONNECT_DUID_KEY = '_li_duid';
const DOMAIN_USER_ID_QUERY_PARAM_KEY = 'duid';
const DEFAULT_LIVEINTENT_IDENTITY_URL = 'https://idx.liadm.com';
const DEFAULT_PREBID_SOURCE = 'prebid';

let eventFired = false;
let liveConnect = null;

/**
* This function is used in tests
*/
export function reset() {
eventFired = false;
liveConnect = null;
}

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

const publisherId = configParams && configParams.publisherId;
if (!publisherId && typeof publisherId !== 'string') {
utils.logError(`${MODULE_NAME} - publisherId must be defined, not a '${publisherId}'`);
return;
}

const identityResolutionConfig = {
source: 'prebid',
publisherId: publisherId
};
if (configParams.url) {
identityResolutionConfig.url = configParams.url
}
if (configParams.partner) {
identityResolutionConfig.source = configParams.partner
}
if (configParams.storage && configParams.storage.expires) {
identityResolutionConfig.expirationDays = configParams.storage.expires;
}

const liveConnectConfig = {
identifiersToResolve: configParams.identifiersToResolve || [],
wrapperName: 'prebid',
identityResolutionConfig: identityResolutionConfig
};
const usPrivacyString = uspDataHandler.getConsentData();
if (usPrivacyString) {
liveConnectConfig.usPrivacyString = usPrivacyString;
}
if (configParams.appId) {
liveConnectConfig.appId = configParams.appId;
}

liveConnect = LiveConnect(liveConnectConfig);
return liveConnect;
}

function tryFireEvent() {
if (!eventFired && liveConnect) {
liveConnect.fire();
eventFired = true;
}
}

/** @type {Submodule} */
export const liveIntentIdSubmodule = {
Expand All @@ -28,14 +85,21 @@ export const liveIntentIdSubmodule = {
* `publisherId` params.
* @function
* @param {{unifiedId:string}} value
* @param {SubmoduleParams|undefined} [configParams]
* @returns {{lipb:Object}}
*/
decode(value) {
decode(value, configParams) {
function composeIdObject(value) {
const base = {'lipbid': value['unifiedId']};
const base = { 'lipbid': value['unifiedId'] };
delete value.unifiedId;
return {'lipb': {...base, ...value}};
return { 'lipb': { ...base, ...value } };
}

if (configParams) {
initializeLiveConnect(configParams);
tryFireEvent();
}

return (value && typeof value['unifiedId'] === 'string') ? composeIdObject(value) : undefined;
},

Expand All @@ -46,52 +110,12 @@ export const liveIntentIdSubmodule = {
* @returns {IdResponse|undefined}
*/
getId(configParams) {
const publisherId = configParams && configParams.publisherId;
if (!publisherId && typeof publisherId !== 'string') {
utils.logError(`${MODULE_NAME} - publisherId must be defined, not a '${publisherId}'`);
const liveConnect = initializeLiveConnect(configParams);
if (!liveConnect) {
return;
}
let baseUrl = DEFAULT_LIVEINTENT_IDENTITY_URL;
let source = DEFAULT_PREBID_SOURCE;
if (configParams.url) {
baseUrl = configParams.url
}
if (configParams.partner) {
source = configParams.partner
}

const additionalIdentifierNames = configParams.identifiersToResolve || [];

const additionalIdentifiers = additionalIdentifierNames.concat([LIVE_CONNECT_DUID_KEY]).reduce((obj, identifier) => {
const value = utils.getCookie(identifier) || utils.getDataFromLocalStorage(identifier);
const key = identifier.replace(LIVE_CONNECT_DUID_KEY, DOMAIN_USER_ID_QUERY_PARAM_KEY);
if (value) {
if (typeof value === 'object') {
obj[key] = JSON.stringify(value);
} else {
obj[key] = value;
}
}
return obj
}, {});

const queryString = utils.parseQueryStringParameters(additionalIdentifiers)
const url = `${baseUrl}/idex/${source}/${publisherId}?${queryString}`;

const result = function (callback) {
ajax(url, response => {
let responseObj = {};
if (response) {
try {
responseObj = JSON.parse(response);
} catch (error) {
utils.logError(error);
}
}
callback(responseObj);
}, undefined, { method: 'GET', withCredentials: true });
};
return {callback: result};
tryFireEvent();
return { callback: liveConnect.resolve };
}
};

Expand Down
6 changes: 4 additions & 2 deletions modules/userId/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
* @summary decode a stored value for passing to bid requests
* @name Submodule#decode
* @param {Object|string} value
* @param {SubmoduleParams|undefined} configParams
* @return {(Object|undefined)}
*/

Expand Down Expand Up @@ -73,6 +74,7 @@
* @property {(string|undefined)} pid - placement id url param value
* @property {(string|undefined)} publisherId - the unique identifier of the publisher in question
* @property {(array|undefined)} identifiersToResolve - the identifiers from either ls|cookie to be attached to the getId query
* @property {(string|undefined)} appId - the unique identifier of the application in question
*/

/**
Expand Down Expand Up @@ -411,7 +413,7 @@ function initSubmodules(submodules, consentData) {

if (storedId) {
// cache decoded value (this is copied to every adUnit bid)
submodule.idObj = submodule.submodule.decode(storedId);
submodule.idObj = submodule.submodule.decode(storedId, submodule.config);
}
} else if (submodule.config.value) {
// cache decoded value (this is copied to every adUnit bid)
Expand All @@ -420,7 +422,7 @@ function initSubmodules(submodules, consentData) {
const response = submodule.submodule.getId(submodule.config.params, consentData, undefined);
if (utils.isPlainObject(response)) {
if (typeof response.callback === 'function') { submodule.callback = response.callback; }
if (response.id) { submodule.idObj = submodule.submodule.decode(response.id); }
if (response.id) { submodule.idObj = submodule.submodule.decode(response.id, submodule.config); }
}
}
carry.push(submodule);
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
"express": "^4.15.4",
"fun-hooks": "^0.9.5",
"jsencrypt": "^3.0.0-rc.1",
"just-clone": "^1.0.2"
"just-clone": "^1.0.2",
"live-connect-js": "^1.0.11"
}
}
Loading