同意の統合 - サポートされているベンダーの構成
この記事では、Tealium iQ Consent IntegrationsでサポートされているCMP(同意管理プラットフォーム)と、Consent Integrationsのセットアップを完了するために必要な関連するベンダー固有の情報を簡単に取得する方法について説明します。
動作原理
Tealium iQ Consent Integrationsは、さまざまな同意管理プラットフォーム(CMP)との統合をサポートしています。サポートされている同意管理プラットフォーム(CMP)またはウェブページのユーザーインターフェースから、関連するベンダー固有の情報にアクセスできます。このドキュメントを信頼性があり使いやすいものにするため、このセクションではウェブページからベンダー固有の情報を取得する手順のみをカバーしています。各パートナーCMPのユーザーインターフェースでベンダーIDと目的を取得する手順については、各CMPのドキュメントを参照してください。
ウェブページから関連する情報を取得するには、次の手順に従ってください。
- CMPが実装されているウェブサイトを訪れます。
- すべてのトラッキングを許可します。
- 開発者ツールのJavaScriptコンソールを開きます。
- 下記のコードスニペットからCMP固有のコードをコンソールに貼り付けます。
- 表示されたベンダーID、目的キー、目的名をConsent Integrationに入力します。
同意の決定を更新した後に最新の解釈を表示するには、コードを再貼り付けしてください。
統合固有の手順とコードスニペット
Didomi
このスニペットをdidomi.ioでテストするか、上記の手順に従ってウェブサイトでテストして、統合に必要な情報の互換性と取得方法を確認します。
Didomiの統合では、ベンダーを目的として使用します。
Didomiは、暗黙の同意が必要な目的やベンダーを返さないため、これは既知のバグです。このバグが修正されるまでの回避策として、この統合では常にalways_consented目的キーを出力同意決定に追加して、暗黙のトリガリングを許可します。
;(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)
OneTrust
このスニペットをhttps://onetrust.comでテストするか、上記の手順に従ってウェブサイトでテストして、統合に必要な情報の互換性と取得方法を確認します。
OneTrustは、構成をプレビューするためのテストモードを提供しており、ベンダーIDに-testを追加することで有効化できます。統合を簡素化するため、OneTrust Consent Integrationsでは、ベンダーIDから-testサフィックスを削除します。シームレスな統合のために、ページで-testサフィックスを使用している場合でも、Tealium iQ Consent Integrations UIに-testを含まないベンダーIDを入力してください。Tealium iQ UIとアクティブな統合のベンダーIDが一致しない場合、Tealium iQ Tag Managementはクッキーを構成したり、ページ上でタグをトリガーしたりすることができません。
;(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.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 () {
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)' // just return whatever's mapped to short-circuit the check as a test
}
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 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 cmpConvertResponseToLookupObject (cmpRawOutput) {
// convert from array of objects to object for easier lookups
var decisionString = ''
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
break
}
}
var permittedPurposeIds = decisionString.split(',').filter(function (group) {
return group !== ''
})
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)
Usercentrics
このスニペットをウェブサイトでテストするには、動作原理セクションの手順に従ってください。互換性を確認し、統合に必要な情報を取得します。Usercentricsの統合では、ベンダーを目的として使用します。
;(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)
オプトアウトCookie + GPC
この統合は、CCPA/CPRAなどの非常にシンプルなオプトアウトモデルをサポートするためのものです。ベンダーIDフィールドをオプトアウトCookieの名前(大文字と小文字を区別する)と解釈します。ユーザーは、このCookieが任意の値で見つかる場合、またはGlobal Privacy Control (GPC)のオプトアウトシグナルが見つかる場合、オプトアウトしたと見なされます。
統合で使用される目的キーとデフォルトの目的グループに含まれるものは次のとおりです。
no-selling- ユーザーのオプトアウトシグナルに関係なく許可するタグ。これらのタグはデータを販売/共有せず、法務チームなどによって厳密に必要とされるものです。yes-selling- オプトアウトしたユーザーに対してブロックするタグ。該当する規制やポリシーにより、ユーザーがオプトアウトした後のトラッキングが禁止されています。
カスタム統合テンプレート
カスタム統合テンプレートの詳細と使用方法については、カスタム統合を参照してください。
最終更新日 :: 2024年March月25日