Supported vendor integrations
This article describes the supported CMPs in Tealium iQ Consent Integrations and how to easily gather the relevant vendor-specific information to complete your Consent Integrations setup.
How it works
Tealium iQ Consent Integrations supports integration with various consent management platforms (CMPs). You can access relevant vendor-specific information from the user interface of the supported consent management platforms (CMP) or the web page. To keep this documentation reliable and user-friendly, this section only covers the steps to retrieve vendor specific information from the webpage. For steps to retrieve your Vendor ID and Purposes in the user interface of each partner CMP, see the respective CMP documentation.
To retrieve the relevant information from the web page follow these steps:
- Visit your website, where the CMP is implemented.
- Accept all tracking.
- Open the Developer Tools JavaScript console.
- Paste the CMP-specific code from the code snippets below into the console.
- Enter the displayed Vendor ID, Purpose Keys and Purpose Names into your Consent Integration.
Repaste the code to see the latest interpretation after you update your consent decision.
Integration-specific instructions and code snippets
Cookiebot
Test this snippet on cookiebot.com or on your website by following the instructions in the How it works section to check compatibility and get the information needed for integration.
;(function cookiebotIntegration (window) {
window.tealiumCmpIntegration = window.tealiumCmpIntegration || {}
window.tealiumCmpIntegration.cmpName = 'Cookiebot'
window.tealiumCmpIntegration.cmpIntegrationVersion = 'v1.0.0'
window.tealiumCmpIntegration.cmpFetchCurrentConsentDecision = cmpFetchCurrentConsentDecision
window.tealiumCmpIntegration.cmpFetchCurrentLookupKey = cmpFetchCurrentLookupKey
window.tealiumCmpIntegration.cmpCheckIfOptInModel = cmpCheckIfOptInModel
window.tealiumCmpIntegration.cmpCheckForWellFormedDecision = cmpCheckForWellFormedDecision
window.tealiumCmpIntegration.cmpCheckForExplicitConsentDecision = cmpCheckForExplicitConsentDecision
window.tealiumCmpIntegration.cmpCheckForTiqConsent = cmpCheckForTiqConsent
window.tealiumCmpIntegration.cmpConvertResponseToGroupList = cmpConvertResponseToGroupList
// Should return a boolean, true if the CMP is running the 'Opt-in' model (GDPR style)
function cmpCheckIfOptInModel () {
if (!window.Cookiebot || !window.Cookiebot.regulations || typeof window.Cookiebot.regulations.gdprApplies !== 'boolean') return false
return Cookiebot.regulations.gdprApplies
}
// Should return some CMP-specific raw object (must be an object) that contains the needed information about the decision.
// This output is used as the cmpRawOutput argument in functions below.
function cmpFetchCurrentConsentDecision () {
if (!window.Cookiebot || typeof window.Cookiebot.hasResponse !== 'boolean') return false
return cmpRawOutput = window.Cookiebot.consent;
}
// Should return a string that helps Tealium iQ confirm that it's got the right CMP configuration (and not one from some other page / customer of the CMP)
function cmpFetchCurrentLookupKey() {
if (!window.Cookiebot || typeof window.Cookiebot.serial !== 'string') return false
return Cookiebot.serial
}
// Should return a boolean - true if the raw decision meets our expectations for the CMP
function cmpCheckForWellFormedDecision (cmpRawOutput) {
return typeof cmpRawOutput === 'object' && typeof cmpRawOutput.stamp ==='string'
}
// Should return a boolean - true if the consent decision was explicitly made by the user
function cmpCheckForExplicitConsentDecision (cmpRawOutput) {
// The only way we can tell if the decision is explicit in this example is to check if an opt-out cookie is set
return cmpRawOutput.method === 'explicit'? true : false;
}
// Should return an array of consented vendors/purposes - these should match the Purposes in Tealium iQ exactly
function cmpConvertResponseToGroupList(cmpRawOutput) {
var consentDecision = []
// very simple check for a non-empty opt-out cookie to determine if tags that sell data are allowed
if (cmpRawOutput.necessary) {
consentDecision.push('necessary') // we don't see a cookie, so we have to assume selling/sharing data is fine
}
if (cmpRawOutput.preferences) {
consentDecision.push('preferences') // we don't see a cookie, so we have to assume selling/sharing data is fine
}
if (cmpRawOutput.marketing) {
consentDecision.push('marketing') // we don't see a cookie, so we have to assume selling/sharing data is fine
}
if (cmpRawOutput.statistics) {
consentDecision.push('statistics') // we don't see a cookie, so we have to assume selling/sharing data is fine
}
return consentDecision
}
// You shouldn't need to change this function, or anything below it
function cmpCheckForTiqConsent (cmpRawOutput, tiqGroupName) {
// treat things we don't understand as an opt-out
if (cmpCheckForWellFormedDecision(cmpRawOutput) !== true) return false
tiqGroupName = tiqGroupName || 'tiq-group-name-missing'
var allowedGroups = cmpConvertResponseToGroupList(cmpRawOutput)
return allowedGroups.indexOf(tiqGroupName) !== -1
}
})(window)
/*
// Debugging / development output - uncomment this block, then paste/repaste this entire template on your test pages
var outputString = `${tealiumCmpIntegration.cmpCheckIfOptInModel() ? 'Opt-in' : 'Opt-out'} Model
Checks:
- id: ${tealiumCmpIntegration.cmpFetchCurrentLookupKey()}
- well-formed: ${tealiumCmpIntegration.cmpCheckForWellFormedDecision(tealiumCmpIntegration.cmpFetchCurrentConsentDecision())}
- explicit: ${tealiumCmpIntegration.cmpCheckForExplicitConsentDecision(tealiumCmpIntegration.cmpFetchCurrentConsentDecision())}
- group list: ${JSON.stringify(tealiumCmpIntegration.cmpConvertResponseToGroupList(tealiumCmpIntegration.cmpFetchCurrentConsentDecision()))}
`
console.log(outputString);
*/
Didomi
Test this snippet on didomi.io or on your website by following the instructions above to check compatibility and get the information needed for integration.
The Didomi integration uses Vendors as Purposes.
Didomi doesn’t return implicitly consented purposes or vendors, this is a known bug. As a workaround until this bug is fixed, this integration unconditionally adds an always_consented
purpose key to the outbound consent decision to allow implicit triggering.
;(function didomiIntegration (window) {
// CMP specific functionality and labels
window.tealiumCmpIntegration = window.tealiumCmpIntegration || {}
window.tealiumCmpIntegration.cmpName = 'Didomi'
window.tealiumCmpIntegration.cmpIntegrationVersion = 'didomi-1.0.1'
window.tealiumCmpIntegration.cmpFetchCurrentConsentDecision = cmpFetchCurrentConsentDecision
window.tealiumCmpIntegration.cmpFetchCurrentLookupKey = cmpFetchCurrentLookupKey
window.tealiumCmpIntegration.cmpCheckIfOptInModel = cmpCheckIfOptInModel
window.tealiumCmpIntegration.cmpCheckForWellFormedDecision = cmpCheckForWellFormedDecision
window.tealiumCmpIntegration.cmpCheckForExplicitConsentDecision = cmpCheckForExplicitConsentDecision
window.tealiumCmpIntegration.cmpCheckForTiqConsent = cmpCheckForTiqConsent
window.tealiumCmpIntegration.cmpConvertResponseToGroupList = cmpConvertResponseToGroupList
window.tealiumCmpIntegration.cmpConvertResponseToLookupObject = cmpConvertResponseToLookupObject
function cmpCheckIfOptInModel () {
if (!window.Didomi || typeof window.Didomi.getConfig !== 'function') return false
return window.Didomi.getConfig().notice.type === 'optin'
}
function cmpFetchCurrentConsentDecision () {
if (!window.Didomi || typeof window.Didomi.getUserStatus !== 'function') return false
if (typeof window.Didomi.getConfig !== 'function') return false
var cmpRawOutput = {}
cmpRawOutput.userStatus = window.Didomi.getUserStatus()
cmpRawOutput.vendorInfo = window.Didomi.getVendors()
cmpRawOutput.shouldConsentBeCollected = window.Didomi.shouldConsentBeCollected()
return cmpRawOutput
}
function cmpFetchCurrentLookupKey () {
if (!window.Didomi || typeof window.Didomi.getConfig !== 'function') return ''
var id = window.Didomi.getConfig().app.deploymentId
return id || ''
}
function cmpCheckForWellFormedDecision (cmpRawOutput) {
// treat things we don't understand as an opt-out
if (typeof cmpRawOutput !== 'object') return false
if (typeof cmpRawOutput.userStatus !== 'object') return false
// do more checks than strictly necessary to confirm expectations
if (typeof cmpRawOutput.userStatus.purposes !== 'object') return false
if (typeof cmpRawOutput.userStatus.vendors !== 'object') return false
if (typeof cmpRawOutput.userStatus.purposes.global !== 'object') return false
if (typeof cmpRawOutput.userStatus.vendors.global !== 'object') return false
if (toString.call(cmpRawOutput.userStatus.purposes.global.enabled) !== '[object Array]') return false
if (toString.call(cmpRawOutput.userStatus.vendors.global.enabled) !== '[object Array]') return false
if (typeof cmpRawOutput.vendorInfo !== 'object') return false
if (typeof cmpRawOutput.shouldConsentBeCollected !== 'boolean') return false
return true
}
function cmpCheckForExplicitConsentDecision (cmpRawOutput) {
// treat things we don't understand as an opt-out
if (cmpCheckForWellFormedDecision(cmpRawOutput) !== true) return false
return cmpRawOutput.shouldConsentBeCollected === false // false after an explicit decision is made
}
function cmpConvertResponseToGroupList (cmpRawOutput) {
// Didomi handles checking each vendor's required purposes
if (cmpCheckForWellFormedDecision(cmpRawOutput) !== true) return []
// enforce strings, even for IAB vendor ids
const decision = cmpRawOutput.userStatus.vendors.global.enabled.map(function (vendorId) {
return String(vendorId)
})
decision.push('always_consented')
return decision
}
function cmpConvertResponseToLookupObject (cmpRawOutput) {
var allowedVendors = cmpConvertResponseToGroupList(cmpRawOutput)
var allVendors = cmpRawOutput.vendorInfo
var lookupObject = {}
// WORKAROUND to allow implicit triggering until the Didomi bug is fixed
lookupObject.always_consented = 'Always consented (to allow strictly needed triggering)'
allVendors.forEach(function (vendorObject) {
if (allowedVendors.indexOf(String(vendorObject.id)) === -1) return
lookupObject[vendorObject.id] = vendorObject.name || 'iab-vendor-' + vendorObject.id
})
return lookupObject
}
function cmpCheckForTiqConsent (cmpRawOutput, tiqGroupName) {
// treat things we don't understand as an opt-out
if (cmpCheckForWellFormedDecision(cmpRawOutput) !== true) return false
tiqGroupName = tiqGroupName || 'tiq-group-name-missing'
var allowedGroups = cmpConvertResponseToGroupList(cmpRawOutput)
return allowedGroups.indexOf(tiqGroupName) !== -1
}
})(window)
// Debugging / development output - repaste the integration on your test pages each time you make a change to your consent state
var outputString = `CMP Found: ${window.tealiumCmpIntegration.cmpName} (${window.tealiumCmpIntegration.cmpCheckIfOptInModel() ? 'Opt-in' : 'Opt-out'} Model)
Checks:
- id: ${window.tealiumCmpIntegration.cmpFetchCurrentLookupKey()}
- well-formed: ${window.tealiumCmpIntegration.cmpCheckForWellFormedDecision(window.tealiumCmpIntegration.cmpFetchCurrentConsentDecision())}
- explicit: ${window.tealiumCmpIntegration.cmpCheckForExplicitConsentDecision(window.tealiumCmpIntegration.cmpFetchCurrentConsentDecision())}
- group list: ${JSON.stringify(window.tealiumCmpIntegration.cmpConvertResponseToGroupList(window.tealiumCmpIntegration.cmpFetchCurrentConsentDecision()))}
- name lookup: ${JSON.stringify(tealiumCmpIntegration.cmpConvertResponseToLookupObject(tealiumCmpIntegration.cmpFetchCurrentConsentDecision()), null, 6)}
`
console.log(outputString)
Digital Control Room
Test this snippet on digitalcontrolroom.com or on your website by following the instructions in the How it works section to check compatibility and get the information needed for integration.
;(function digitalControlRoom(window) {
window.tealiumCmpIntegration = window.tealiumCmpIntegration || {};
window.tealiumCmpIntegration.cmpName = 'Digital Control Room';
window.tealiumCmpIntegration.cmpIntegrationVersion = 'v1.0.0';
window.tealiumCmpIntegration.cmpCheckIfOptInModel = cmpCheckIfOptInModel;
window.tealiumCmpIntegration.cmpFetchCurrentConsentDecision = cmpFetchCurrentConsentDecision;
window.tealiumCmpIntegration.cmpFetchCurrentLookupKey = cmpFetchCurrentLookupKey;
window.tealiumCmpIntegration.cmpCheckForWellFormedDecision = cmpCheckForWellFormedDecision;
window.tealiumCmpIntegration.cmpCheckForExplicitConsentDecision = cmpCheckForExplicitConsentDecision;
window.tealiumCmpIntegration.cmpCheckForTiqConsent = cmpCheckForTiqConsent;
window.tealiumCmpIntegration.cmpConvertResponseToGroupList = cmpConvertResponseToGroupList;
function cmpCheckIfOptInModel() {
return (
window._cookiereports &&
window._cookiereports.panels &&
window._cookiereports.panels[0].consent &&
window._cookiereports.panels[0].consentExplicit
);
}
// This output is used as the cmpRawOutput argument in functions below.
function cmpFetchCurrentConsentDecision() {
if (!window._cookiereports) {
return {};
}
var levels = window._cookiereports.loadConsent();
levels[1] = true;
var output = { "levels": levels };
output.panels = window._cookiereports.panels;
return output;
}
// Should return a string that helps Tealium iQ confirm that it's got the right CMP configuration (and not one from some other page / customer of the CMP)
function cmpFetchCurrentLookupKey() {
if (window._cookiereports && window._cookiereports.panels && window._cookiereports.panels.length > 0)
return window._cookiereports.panels[0].storagekey;
return "";
}
function cmpCheckForWellFormedDecision(cmpRawOutput) {
if (typeof cmpRawOutput.levels !== "object" || cmpRawOutput.levels === null || typeof cmpRawOutput.panels !== "object" || cmpRawOutput.panels === null) {
return false;
}
return true;
}
// Should return a boolean - true if the consent decision was explicitly made by the user
function cmpCheckForExplicitConsentDecision(cmpRawOutput) {
if (cmpRawOutput && cmpRawOutput.panels)
return cmpRawOutput.panels[0].consentDecisionIsExplicit();
return false;
}
function cmpConvertResponseToGroupList(cmpRawOutput) {
if (!cmpCheckForWellFormedDecision(cmpRawOutput)) {
return ["1"];
}
var levels = cmpRawOutput.levels;
var consentDecision = [];
for (var key in levels) {
if (levels.hasOwnProperty(key)) {
if (levels[key] === true) {
consentDecision.push(key);
}
}
}
return consentDecision;
}
// You shouldn't need to change this function, or anything below it
function cmpCheckForTiqConsent(cmpRawOutput, tiqGroupName) {
// treat things we don't understand as an opt-out
if (cmpCheckForWellFormedDecision(cmpRawOutput) !== true) return false;
tiqGroupName = tiqGroupName || "tiq-group-name-missing";
var allowedGroups = cmpConvertResponseToGroupList(cmpRawOutput);
return allowedGroups.indexOf(tiqGroupName) !== -1;
}
})(window);
// Debugging / development output - uncomment this block, then paste/repaste this entire template on your test pages
/*
var outputString = `${tealiumCmpIntegration.cmpCheckIfOptInModel() ? "Opt-in" : "Opt-out"} Model
Checks:
- id: ${tealiumCmpIntegration.cmpFetchCurrentLookupKey()}
- well-formed: ${tealiumCmpIntegration.cmpCheckForWellFormedDecision(tealiumCmpIntegration.cmpFetchCurrentConsentDecision())}
- explicit: ${tealiumCmpIntegration.cmpCheckForExplicitConsentDecision(tealiumCmpIntegration.cmpFetchCurrentConsentDecision())}
- group list: ${JSON.stringify(tealiumCmpIntegration.cmpConvertResponseToGroupList(tealiumCmpIntegration.cmpFetchCurrentConsentDecision()))}
`;
console.log(outputString);
*/
OneTrust
Test this snippet on https://onetrust.com or on your website by following the instructions above to check compatibility and get the information needed for integration.
OneTrust provides a test mode to preview settings, activated by adding -test
to your Vendor ID. To simplify integration, OneTrust Consent Integrations remove the -test
suffix from Vendor IDs. For seamless integration, enter your Vendor ID without -test
in the Tealium iQ Consent Integrations UI when setting up your integration, even if you use the -test
suffix on your pages. Mismatched Vendor IDs between the Tealium iQ UI and your active integrations prevent Tealium iQ Tag Management from setting cookies or triggering tags on the page.
;(function oneTrust(window) {
// allows simple adjustment of the name/id behavior
var useNamesInsteadOfKeys = false;
// allow the safety check of the expected Vendor ID to be circumvented to simplify setup at the cost of increased risk
var disableVendorIdValidation = false;
// CMP specific functionality and labels
window.tealiumCmpIntegration = window.tealiumCmpIntegration || {};
window.tealiumCmpIntegration.cmpName = "OneTrust";
window.tealiumCmpIntegration.cmpIntegrationVersion = "onetrust-2.0.2";
window.tealiumCmpIntegration.cmpFetchCurrentConsentDecision = cmpFetchCurrentConsentDecision;
window.tealiumCmpIntegration.cmpFetchCurrentLookupKey = cmpFetchCurrentLookupKey;
window.tealiumCmpIntegration.cmpCheckIfOptInModel = cmpCheckIfOptInModel;
window.tealiumCmpIntegration.cmpCheckForWellFormedDecision = cmpCheckForWellFormedDecision;
window.tealiumCmpIntegration.cmpCheckForExplicitConsentDecision = cmpCheckForExplicitConsentDecision;
window.tealiumCmpIntegration.cmpCheckForTiqConsent = cmpCheckForTiqConsent;
window.tealiumCmpIntegration.cmpConvertResponseToGroupList = cmpConvertResponseToGroupList;
window.tealiumCmpIntegration.cmpConvertResponseToLookupObject = cmpConvertResponseToLookupObject;
function cmpCheckIfOptInModel() {
var decision = cmpFetchCurrentConsentDecision();
if (decision && decision.ConsentModel && decision.ConsentModel.Name === "opt-out") {
return false;
}
return true;
}
function cmpFetchCurrentConsentDecision() {
if (!window.OneTrust || typeof window.OneTrust.GetDomainData !== "function") return false;
var cmpRawOutput = window.OneTrust.GetDomainData();
cmpRawOutput.dataLayer = window.dataLayer;
return cmpRawOutput;
}
function cmpFetchCurrentLookupKey() {
// newer versions of OneTrust, starting at the end of 2022 no longer have cctId defined
// but this HTML attribute is the way OneTrust can tell
var scrapeOneTrustVendorId = function () {
var allScripts = document.getElementsByTagName("script");
var re = /\/otSDKStub\.js(\?.*)*$/;
for (var i = 0; i < allScripts.length; i++) {
var isOneTrustScript = re.test(allScripts[i].src); // can be null
if (isOneTrustScript) {
var fullVendorId = allScripts[i].getAttribute("data-domain-script"); // parse it from the script
return fullVendorId.split("-test")[0];
}
}
return "error-not-found";
}
if (disableVendorIdValidation) {
// just return whatever Vendor ID is expected be active
return (window.tealiumCmpIntegration && window.tealiumCmpIntegration.map && Object.keys(window.tealiumCmpIntegration.map)[0]) || "(Vendor ID check disabled)";
}
return scrapeOneTrustVendorId();
}
function cmpCheckForWellFormedDecision(cmpRawOutput) {
// treat things we don't understand as an opt-out
if (typeof cmpRawOutput !== "object") return false;
if (toString.call(cmpRawOutput.Groups) !== "[object Array]") return false;
if (toString.call(cmpRawOutput.dataLayer) !== "[object Array]") return false;
return true;
}
function cmpCheckForExplicitConsentDecision(cmpRawOutput) {
// treat things we don't understand as implicit
if (cmpCheckForWellFormedDecision(cmpRawOutput) !== true) return false;
return window.OneTrust && typeof window.OneTrust.IsAlertBoxClosed === "function" && window.OneTrust.IsAlertBoxClosed();
}
function cmpConvertResponseToLookupObject(cmpRawOutput) {
// convert from array of objects to object for easier lookups
var decisionString = "";
var foundOneTrustEntry = false;
if (cmpCheckForWellFormedDecision(cmpRawOutput) !== true) return {};
for (var i = cmpRawOutput.dataLayer.length - 1; i >= 0; i--) {
if (["OneTrustGroupsUpdated", "OneTrustLoaded"].indexOf(cmpRawOutput.dataLayer[i].event) !== -1) {
decisionString = cmpRawOutput.dataLayer[i].OnetrustActiveGroups;
foundOneTrustEntry = true;
break;
}
}
var permittedPurposeIds = decisionString.split(",").filter(function (group) {
return group !== "";
});
// CUSTOM - fallback for SPA cases when more than 1000 events are pushed into the dataLayer and the decision isn't available anymore (Google truncates the array)
if (decisionString === "" && cmpRawOutput.dataLayer.length === 1000 && foundOneTrustEntry === false) {
permittedPurposeIds = window.tealiumConsentRegister && window.tealiumConsentRegister.getCurrentDecision();
}
var permittedPurposesWithNames = {};
cmpRawOutput.Groups.forEach(function (groupInfo) {
if (permittedPurposeIds.indexOf(groupInfo.OptanonGroupId) !== -1) {
permittedPurposesWithNames[groupInfo.OptanonGroupId] = groupInfo.GroupName || "ERROR-MISSING";
}
})
return permittedPurposesWithNames; // keys are IDs, values are names
}
function cmpConvertResponseToGroupList(cmpRawOutput) {
var permittedPurposesWithNames = cmpConvertResponseToLookupObject(cmpRawOutput);
var keysOrValues = useNamesInsteadOfKeys ? "values" : "keys";
return Object[keysOrValues](permittedPurposesWithNames); // keys are IDs, values are names
}
function cmpCheckForTiqConsent(cmpRawOutput, tiqGroupName) {
// treat things we don't understand as an opt-out
if (cmpCheckForWellFormedDecision(cmpRawOutput) !== true) return false;
tiqGroupName = tiqGroupName || "tiq-group-name-missing";
var allowedGroups = cmpConvertResponseToGroupList(cmpRawOutput);
return allowedGroups.indexOf(tiqGroupName) !== -1;
}
})(window);
/*
// Debugging / development output - repaste the integration on your test pages each time you make a change to your consent state
var outputString = `CMP Found: ${window.tealiumCmpIntegration.cmpName} (${window.tealiumCmpIntegration.cmpCheckIfOptInModel() ? "Opt-in" : 'Opt-out'} Model)
Checks:
- id: ${window.tealiumCmpIntegration.cmpFetchCurrentLookupKey()}
- well-formed: ${window.tealiumCmpIntegration.cmpCheckForWellFormedDecision(window.tealiumCmpIntegration.cmpFetchCurrentConsentDecision())}
- explicit: ${window.tealiumCmpIntegration.cmpCheckForExplicitConsentDecision(window.tealiumCmpIntegration.cmpFetchCurrentConsentDecision())}
- group list: ${JSON.stringify(window.tealiumCmpIntegration.cmpConvertResponseToGroupList(window.tealiumCmpIntegration.cmpFetchCurrentConsentDecision()))}
- name lookup: ${JSON.stringify(window.tealiumCmpIntegration.cmpConvertResponseToLookupObject(window.tealiumCmpIntegration.cmpFetchCurrentConsentDecision()), null, 6)}
`
console.log(outputString)
*/
Opt-out Cookie + GPC
This integration intends to provide support for very simple opt-out models such as CCPA/CPRA. It interprets the Vendor ID field as the cookie name of an opt-out cookie, and is case sensitive. A user is considered to have opted out if this cookie is found with any value, or if the Global Privacy Control (GPC) opt-out signal is found.
The Purpose Keys used in the integration and included in the default Purpose Group are:
no-selling
- For tags to allow regardless of the user’s opt-out signal. These tags don’t sell/share data or are considered strictly necessary by your legal team, etc.yes-selling
- For tags to block for opt-out users because applicable regulations or policies prohibit tracking after a user has opted out.
TrustArc
Test this snippet on trustarc.com or on your website by following the instructions in the How it works section to check compatibility and get the information needed for integration.
;(function trustarc (window) {
// CMP specific functionality and labels
window.tealiumCmpIntegration = window.tealiumCmpIntegration || {}
window.tealiumCmpIntegration.cmpName = 'TrustArc'
window.tealiumCmpIntegration.cmpIntegrationVersion = 'trustarc-1.0.3'
window.tealiumCmpIntegration.cmpFetchCurrentConsentDecision = cmpFetchCurrentConsentDecision
window.tealiumCmpIntegration.cmpFetchCurrentLookupKey = cmpFetchCurrentLookupKey
window.tealiumCmpIntegration.cmpCheckIfOptInModel = cmpCheckIfOptInModel
window.tealiumCmpIntegration.cmpCheckForWellFormedDecision = cmpCheckForWellFormedDecision
window.tealiumCmpIntegration.cmpCheckForExplicitConsentDecision = cmpCheckForExplicitConsentDecision
window.tealiumCmpIntegration.cmpCheckForTiqConsent = cmpCheckForTiqConsent
window.tealiumCmpIntegration.cmpConvertResponseToGroupList = cmpConvertResponseToGroupList
window.tealiumCmpIntegration.cmpConvertResponseToLookupObject = cmpConvertResponseToLookupObject
function cmpCheckIfOptInModel () {
var modeCookieValue = (truste && truste.util && typeof truste.util.readCookie === 'function' && truste.util.readCookie('notice_behavior')) || 'expressed|eu' // default to strict EU rules if no cookie
return modeCookieValue.indexOf('expressed') === 0
}
function cmpFetchCurrentConsentDecision () {
if (!window.truste || !window.truste.util || typeof window.truste.util.readCookie !== 'function') return false
""
var cookieValue = window.truste.util.readCookie(truste.eu.COOKIE_GDPR_PREF_NAME) || '0,'
// if we're in the opt-out model and it's an implicit decision, we should allow all tags to fire
var map = (window.tealiumCmpIntegration && window.tealiumCmpIntegration.map && Object.keys(window.tealiumCmpIntegration.map)[0] && window.tealiumCmpIntegration.map[Object.keys(window.tealiumCmpIntegration.map)[0]]) || {}
if (cmpCheckIfOptInModel() === false && cmpCheckForExplicitConsentDecision() === false) {
cookieValue = Object.keys(map).join(',') // all purpose keys that have been added in the UI are returned as consented
}
return {
cookie: cookieValue
}
}
function cmpFetchCurrentLookupKey () {
// just return whatever Vendor ID is expected be active to short-circuit the ID-based double check for now
return (window.tealiumCmpIntegration && window.tealiumCmpIntegration.map && Object.keys(window.tealiumCmpIntegration.map)[0]) || '(Vendor ID check disabled)'
}
function cmpCheckForWellFormedDecision (cmpRawOutput) {
// treat things we don't understand as an opt-out
if (typeof cmpRawOutput !== 'object') return false
if (typeof cmpRawOutput.cookie !== 'string') return false
return true
}
function cmpCheckForExplicitConsentDecision (cmpRawOutput) {
if (!window.truste || !window.truste.util || typeof window.truste.util.readCookie !== 'function') return false
return typeof window.truste.util.readCookie(truste.eu.COOKIE_GDPR_PREF_NAME) === 'string'
}
function cmpConvertResponseToLookupObject (cmpRawOutput) {
if (!cmpCheckForWellFormedDecision(cmpRawOutput)) return []
const cookieConsentValues = cmpRawOutput.cookie.split(':')[0].split(',')
const extraSplit = []
cookieConsentValues.forEach((el) => {
if (!el) return
extraSplit.push.apply(extraSplit, el.split('|'))
})
const trustArcMap = {
0: 'Required',
1: 'Functional',
2: 'Personalization/Advertising'
}
const output = {}
extraSplit.forEach((key) => {
if (key !== '') {
output[key] = trustArcMap[key] || 'Category name unknown'
}
})
return output
}
function cmpConvertResponseToGroupList (cmpRawOutput) {
var permittedPurposesWithNames = cmpConvertResponseToLookupObject(cmpRawOutput)
var keysOrValues = 'keys'
return Object[keysOrValues](permittedPurposesWithNames) // keys are IDs, values are names
}
function cmpCheckForTiqConsent (cmpRawOutput, tiqGroupName) {
// treat things we don't understand as an opt-out
if (cmpCheckForWellFormedDecision(cmpRawOutput) !== true) return false
tiqGroupName = tiqGroupName || 'tiq-group-name-missing'
var allowedGroups = cmpConvertResponseToGroupList(cmpRawOutput)
return allowedGroups.indexOf(tiqGroupName) !== -1
}
})(window)
// Debugging / development output - uncomment this code and paste the integration into the console on your test pages each time you make a change to your consent state to test without publishing
var outputString = `CMP Found: ${window.tealiumCmpIntegration.cmpName} (${window.tealiumCmpIntegration.cmpCheckIfOptInModel() ? 'Opt-in' : 'Opt-out'} Model)
Checks:
- id: ${tealiumCmpIntegration.cmpFetchCurrentLookupKey()}
- well-formed: ${tealiumCmpIntegration.cmpCheckForWellFormedDecision(tealiumCmpIntegration.cmpFetchCurrentConsentDecision())}
- explicit: ${tealiumCmpIntegration.cmpCheckForExplicitConsentDecision(tealiumCmpIntegration.cmpFetchCurrentConsentDecision())}
- group list: ${JSON.stringify(tealiumCmpIntegration.cmpConvertResponseToGroupList(tealiumCmpIntegration.cmpFetchCurrentConsentDecision()))}
- name lookup: ${JSON.stringify(tealiumCmpIntegration.cmpConvertResponseToLookupObject(tealiumCmpIntegration.cmpFetchCurrentConsentDecision()), null, 6)}
${tealiumCmpIntegration.cmpCheckIfOptInModel() === false && tealiumCmpIntegration.cmpCheckForExplicitConsentDecision() === false ? '(All purposes are consented in opt-out mode with an implicit decision, but the full purpose list can\'t be shown in this debug output for technical reasons.)' : ''}
`
console.log(outputString)
Usercentrics
Test this snippet on your website by following the instructions in the How it works section to check compatibility and get the information needed for integration. The Usercentrics integration uses Vendors as Purposes.
;(function usercentricsBrowserSdkV2 (window) {
// CMP specific functionality and labels
window.tealiumCmpIntegration = window.tealiumCmpIntegration || {}
window.tealiumCmpIntegration.cmpName = 'Usercentrics Browser SDK'
window.tealiumCmpIntegration.cmpIntegrationVersion = 'usercentrics-1.0.3'
function cmpFetchCurrentConsentDecision () {
if (!window.UC_UI || typeof window.UC_UI.getServicesBaseInfo !== 'function') return false
var cmpRawOutput = window.UC_UI.getServicesBaseInfo()
return cmpRawOutput
}
function cmpFetchCurrentLookupKey () {
return (window.UC_UI && typeof window.UC_UI.getSettingsCore === 'function' && window.UC_UI.getSettingsCore().id) || ''
}
// only support opt-In model for Usercentrics for now, can be added if needed
function cmpCheckIfOptInModel () {
return window.UC_UI && typeof window.UC_UI.isConsentRequired === 'function' && window.UC_UI.isConsentRequired() === true
}
function cmpCheckForWellFormedDecision (cmpRawOutput) {
// treat things we don't understand as an opt-out
if (toString.call(cmpRawOutput) !== '[object Array]') return false
// use the first entry as a proxy for all
if (cmpRawOutput && cmpRawOutput[0] && typeof cmpRawOutput[0].name === 'string') {
return true
}
return false
}
function cmpCheckForExplicitConsentDecision (cmpRawOutput) {
// treat things we don't understand as an opt-out
if (toString.call(cmpRawOutput) !== '[object Array]') return false
// use the first entry as a proxy for all
var consentHistory = (cmpRawOutput && cmpRawOutput[0] && cmpRawOutput[0].consent && cmpRawOutput[0].consent.history) || []
var lastHistoryEntryType = (consentHistory && consentHistory.length && consentHistory[consentHistory.length - 1].type) || ''
if (lastHistoryEntryType === 'explicit') {
return true
}
return false
}
function cmpCheckForTiqConsent (cmpRawOutput, tiqGroupName) {
var foundOptIn = false
// treat things we don't understand as an opt-out
if (toString.call(cmpRawOutput) !== '[object Array]') return false
// use the mapping if found, with a fallback (Usercentrics default value) if not specified in the mapping
tiqGroupName = tiqGroupName || 'tiq-group-name-missing'
// check vendors if there's an object, look for at least one
cmpRawOutput.forEach(function (tagInfo) {
if ((tagInfo.consent && tagInfo.consent.status === true) && tagInfo.name === tiqGroupName) {
foundOptIn = true
}
})
return foundOptIn
}
function cmpConvertResponseToGroupList (cmpRawOutput) {
var vendorArray = []
cmpRawOutput && cmpRawOutput.forEach(function (tagConsent) {
if (tagConsent.consent && tagConsent.consent.status === true) {
vendorArray.push(tagConsent.name)
}
})
return vendorArray
}
window.tealiumCmpIntegration.cmpFetchCurrentConsentDecision = cmpFetchCurrentConsentDecision
window.tealiumCmpIntegration.cmpFetchCurrentLookupKey = cmpFetchCurrentLookupKey
window.tealiumCmpIntegration.cmpCheckIfOptInModel = cmpCheckIfOptInModel
window.tealiumCmpIntegration.cmpCheckForWellFormedDecision = cmpCheckForWellFormedDecision
window.tealiumCmpIntegration.cmpCheckForExplicitConsentDecision = cmpCheckForExplicitConsentDecision
window.tealiumCmpIntegration.cmpCheckForTiqConsent = cmpCheckForTiqConsent
window.tealiumCmpIntegration.cmpConvertResponseToGroupList = cmpConvertResponseToGroupList
})(window)
var outputString = `${tealiumCmpIntegration.cmpName} - ${tealiumCmpIntegration.cmpCheckIfOptInModel() ? 'Opt-in' : 'Opt-out'} Model
Checks:
- vendor id: ${tealiumCmpIntegration.cmpFetchCurrentLookupKey()}
- well-formed decision: ${tealiumCmpIntegration.cmpCheckForWellFormedDecision(tealiumCmpIntegration.cmpFetchCurrentConsentDecision())}
- explicit decision: ${tealiumCmpIntegration.cmpCheckForExplicitConsentDecision(tealiumCmpIntegration.cmpFetchCurrentConsentDecision())}
- consented purposes: ${JSON.stringify(tealiumCmpIntegration.cmpConvertResponseToGroupList(tealiumCmpIntegration.cmpFetchCurrentConsentDecision()).sort(),null, 8)}
`
console.log(outputString)
Custom Integration template
See custom integration for more information about the custom integration template and how to use it.
Was this page helpful?
Thank you for your feedback!
This page was last updated: October 9, 2024