Skip to content
This repository was archived by the owner on May 11, 2026. It is now read-only.
Open
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
166 changes: 111 additions & 55 deletions measurement.js
Original file line number Diff line number Diff line change
@@ -1,73 +1,129 @@
// ==UserScript==
// @name LI Measurement Script
// @name LI Prebid Identity Initialization and Measurement Script
// @namespace http://liveintent.com
// @version 2024-03-12-1
// @description LiveIntent PCID Initialization and GAM Measurement Script
// @author You
// @version 1.6
// @description Performs an a/b test for the LiveIntent prebid identity module and reports on the relative performance of each group.
// @author phillip@liveintent.com <Phillip Markert>
// @homepage https://github.com/LiveIntent/lipid
// @run-at document-start
// @grant none
// ==/UserScript==

(function() {
// start liveintent module init and measurement v1.5
const LI_PUBLISHER_ID = "INSERT PUBLISHER_ID HERE";
const LI_DISTRIBUTOR_ID = undefined;
const LOGGED_IN_USERS_EMAIL_OR_EMAIL_HASH = "";
const LI_REPORTING_KEY = "li-module-enabled";
const pbjs = (window.pbjs = window.pbjs || { que: [] });
const googletag = (window.googletag = window.googletag || { cmd: [] });
const LI_MODULE_ENABLED = Math.random() < 0.95;
let bidsEnriched;

function setTargeting(enriched, wonAll) {
googletag.cmd.push(function () {
let targeting = LI_MODULE_ENABLED ? "t1" : "t0";
if(enriched!==undefined) targeting += enriched ? "-e1" : "-e0";
if(wonAll!==undefined) targeting += wonAll ? "-wa" : "-ws";
googletag.pubads().setTargeting(LI_REPORTING_KEY, targeting);
});
}

setTargeting();

pbjs.que.push(function () {
if (LI_MODULE_ENABLED) {
(function () {
// start liveintent module init and measurement script v1.6
const pbjs = (window.pbjs = window.pbjs || { cmd: [] });
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be worth making it more explicit that pbjs should be replaced with whatever the global var name is in case it is a custom one?

For example by adding something like

// Replace with a different global name if needed
const prebidGlobalVarName = 'pbjs'
const pbjs = (window[prebidGlobalVarName] = window[prebidGlobalVarName] || { cmd: [] });


pbjs.cmd.push(() => {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the script relies on Prebid configuration being present before this function is executed. For example, if

pbjs.que.push(function() {
    pbjs.setConfig({...})
}

is executed after line 16 is executed to set the actual Prebid configuration, it will overwrite whatever config has been computed by this script. Do I see it correctly?

const userSync = pbjs.getConfig().userSync;
// Is the module already configured
const liModuleConfigured = userSync.userIds?.some(
(m) => m.name === "liveIntentId"
);

/*
Configuration Phase: Determines group (control vs. treated) and configures appropriately
There are three options for how to determine the group:
Option A: via window.liModule.enabled or window.liModuleEnabled (if set)
Option B: random selection based upon window.liModule.testPercentage (if set)
Option C: automatically if liveIntent module is configured in prebid userSync
*/

// update window.liModule w/deep merge of defaults and capture as a constant to prevent updates
const liModule = (window.liModule = Object.assign(
{
enabled:
window.liModuleEnabled ?? window.liModule.testPercentage
? // normalize testPercentage to a number between 0 and 1
Math.random() <
(window.liModule.testPercentage < 1
? window.liModule.testPercentage
: window.liModule.testPercentage / 100)
: liModuleConfigured,
params: Object.assign(
{
requestedAttributesOverrides: {
uid2: true,
bidswitch: true,
medianet: true,
magnite: true,
pubmatic: true,
index: true,
openx: true,
},
},
window.liModule.params
Comment on lines +42 to +54
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the intention to allow to provide params for configuring the module via a global variable? If so, what is the reason to have the hardcoded config here? Is it a fallback? What happens if it is not the list of IDs the customer wants? Would it make sense to require providing a config explicitly instead?

),
reportingKey: "li-module-enabled",
auctionsEnriched: {},
},
window.liModule
));
// Legacy support
window.liModuleEnabled = liModule.enabled;

if (liModule.enabled && !liModuleConfigured) {
liModule.deferInit
? setTimeout(configureLiveIntentModule, 0)
: configureLiveIntentModule();
}

function configureLiveIntentModule() {
pbjs.mergeConfig({
userSync: {
auctionDelay: 300,
userIds: [
{
Object.assign({
name: "liveIntentId",
params: {
publisherId: LI_PUBLISHER_ID,
distributorId: LI_DISTRIBUTOR_ID,
emailHash: LOGGED_IN_USERS_EMAIL_OR_EMAIL_HASH,
requestedAttributesOverrides: {
uid2: true,
bidswitch: true,
medianet: true,
magnite: true,
pubmatic: true,
index: true,
openx: true,
},
},
},
params: liModule.params,
storage: userSync.auctionDelay
? undefined
: {
expires: 1,
name: "pbjs_li_nonid",
type: "cookie",
},
}),
],
},
});
}


// Reporting Phase: Reports the group and performance of the module
const googletag = (window.googletag = window.googletag || { cmd: [] });

function setTargeting(enriched, wonAll) {
googletag.cmd.push(function () {
// t1 = module enabled, t0 = module disabled
let targeting = liModule.enabled ? "t1" : "t0";
// e1 = enriched, e0 = not enriched
if (enriched !== undefined) targeting += enriched ? "-e1" : "-e0";
// wa = Prebid won all ad-slots, ws = Prebid won some ad-slots
if (wonAll !== undefined) targeting += wonAll ? "-wa" : "-ws";
googletag.pubads().setTargeting(liModule.reportingKey, targeting);
});
}

setTargeting();

pbjs.onEvent("auctionInit", function (args) {
bidsEnriched = args.adUnits && args.adUnits.some((au) => au.bids &&
au.bids.some((b) => b.userIdAsEids && b.userIdAsEids.some((eid) => eid.source
=== "liveintent.com" || (eid.uids && eid.uids.some((uid) => uid.ext &&
uid.ext.provider === "liveintent.com")))));
setTargeting(bidsEnriched);
liModule.auctionsEnriched[args.auctionId ?? 0] = args.adUnits?.some(
(adUnit) =>
adUnit.bids?.some((bid) =>
bid.userIdAsEids?.some(
(eid) =>
eid.source === "liveintent.com" ||
eid.uids?.some((uid) => uid.ext?.provider === "liveintent.com")
)
)
);
setTargeting(liModule.auctionsEnriched[args.auctionId]);
});

pbjs.onEvent("bidWon", function (args) {
setTargeting(bidsEnriched, pbjs.getAllPrebidWinningBids().length === 0);

pbjs.onEvent("adRenderSucceeded", function (args) {
setTargeting(
liModule.auctionsEnriched[args.bid.auctionId ?? 0],
pbjs.getAllPrebidWinningBids().length === 0
);
});
});
// end liveintent module init and measurement
// end liveintent module init and measurement script
})();