本文面向在使用 Google 跟踪代码管理器 (GTM) 的网站上维护意见征求管理解决方案的开发者。
本页介绍了 Google 跟踪代码管理器中的意见征求类型,并展示了如何将这些意见征求类型与意见征求管理解决方案集成。
为什么要使用意见征求代码模板?
如果您提供代码模板,您的用户无需编写代码即可集成您的用户意见征求解决方案,从而节省大量的时间和精力。
用户可以使用意见征求模式模板来设置默认的同意情况,并将访问者选择的同意情况传达给 Google 跟踪代码管理器。这样可确保 Google 代码和支持意见征求模式的第三方跟踪代码以最佳方式运作。
作为模板创建者,您可以实现意见征求模式模板以供内部使用,也可以将其发布到社区模板库中以供公开使用。提供意见征求模式模板的意见征求管理平台 (CMP) 提供商有机会列示在我们的意见征求模式文档中,模板库选择器也有可能会显示其模板。
同意情况和用户意见征求类型
Google 代码和第三方跟踪代码会根据同意情况是 granted 还是 denied 来调整其存储行为。对于以下任一用户意见征求类型,这些代码都内置了用户意见检查:
| 用户意见征求类型 | 说明 | 
|---|---|
| ad_storage | 启用与广告相关的存储机制(例如 Cookie)。 | 
| ad_user_data | 针对能否出于线上广告目的向 Google 发送用户数据,设置用户意见征求。 | 
| ad_personalization | 针对能否投放个性化广告,设置用户意见征求。 | 
| analytics_storage | 启用与分析(例如访问时长)相关的存储机制(例如 Cookie)。 | 
| functionality_storage | 启用为网站或应用的功能(例如语言设置)提供支持的存储机制。 | 
| personalization_storage | 启用与个性化(例如视频推荐)相关的存储机制。 | 
| security_storage | 启用与安全(例如,身份验证功能、欺诈防范功能和其他用户保护功能)相关的存储机制。 | 
创建新的意见征求模板
意见征求模式会跟踪访问者选择的同意情况和包含用户意见检查的代码,以确保代码行为会进行相应的调整。在创建新的意见征求模板时,请遵循以下最佳做法:
- 使用跟踪代码管理器意见征求模式 API setDefaultConsentState 和 updateConsentState,而不要使用 - gtag consent。
- 在使用用户意见征求初始化 - 所有网页触发器触发代码后立即设置默认同意情况。 
- CMP 必须尽快提示访问者针对所有适用的用户意见征求类型表示同意或拒绝。 
- 在访问者选择自己的同意情况后,CMP 必须传递最新的同意情况。 
1. 创建新模板
此实现方法会使用模板中的一个字段来保存默认同意情况。实现代码将读取该字段,以在运行时设置默认同意情况。对于更新命令,您的代码将尝试读取意见征求解决方案设置的 Cookie,以存储访问者所选的同意情况。您还需要为
updateConsentState设置回调,以处理访问者尚未选择是否同意或尚未决定更改其意见的情况。
创建意见征求模板:
- 登录您的 Google 跟踪代码管理器账号。
- 在左侧导航栏中,选择模板。
- 在代码模板窗格中,点击新建。
设置默认同意情况:
- 选择字段标签页,然后点击添加字段 > 参数表格。
- 将名称更改为 defaultSettings。
- 展开相应字段。
- 将显示名称更新为 Default settings。
- 点击添加列,选择文本输入,将名称更改为 region,并勾选要求列值必须具有唯一性复选框。
- 展开对应的列,并将显示名称更改为 Region (leave blank to have consent apply to all regions)。括号中的表述是面向您的模板用户的说明。详细了解如何针对不同区域设置同意情况默认值。
- 点击添加列,选择文本输入,将名称更改为 granted。
- 展开对应的列,并将显示名称更改为 Granted Consent Types (comma separated)。
- 点击添加列,选择文本输入,将名称更改为 denied。
- 展开对应的列,并将显示名称更改为 Denied Consent Types (comma separated)。
可选:添加对广告数据隐去功能的支持:
- 点击添加字段,选择复选框,然后将字段名称更改为 ads_data_redaction。
- 将显示名称更新为 Redact Ads Data。
详细了解使用广告数据隐去功能时的 Cookie 行为
可选:添加对通过网址参数传递信息的支持:
- 点击添加字段,选择复选框,然后将字段名称更改为 url_passthrough。
- 将显示名称更新为 Pass through URL parameters。
详细了解如何通过网址参数传递信息
添加实现代码:
- 在模板编辑器中打开代码标签页。
- 修改下方代码示例中的占位符字段。
- 复制代码并用它来替换模板编辑器中的样板代码。
- 保存模板。
// The first two lines are optional, use if you want to enable logging
const log = require('logToConsole');
log('data =', data);
const setDefaultConsentState = require('setDefaultConsentState');
const updateConsentState = require('updateConsentState');
const getCookieValues = require('getCookieValues');
const callInWindow = require('callInWindow');
const gtagSet = require('gtagSet');
const COOKIE_NAME = 'Your_cookie_name';
/*
 *   Splits the input string using comma as a delimiter, returning an array of
 *   strings
 */
const splitInput = (input) => {
  return input.split(',')
      .map(entry => entry.trim())
      .filter(entry => entry.length !== 0);
};
/*
 *   Processes a row of input from the default settings table, returning an object
 *   which can be passed as an argument to setDefaultConsentState
 */
const parseCommandData = (settings) => {
  const regions = splitInput(settings['region']);
  const granted = splitInput(settings['granted']);
  const denied = splitInput(settings['denied']);
  const commandData = {};
  if (regions.length > 0) {
    commandData.region = regions;
  }
  granted.forEach(entry => {
    commandData[entry] = 'granted';
  });
  denied.forEach(entry => {
    commandData[entry] = 'denied';
  });
  return commandData;
};
/*
 *   Called when consent changes. Assumes that consent object contains keys which
 *   directly correspond to Google consent types.
 */
const onUserConsent = (consent) => {
  const consentModeStates = {
    ad_storage: consent['adConsentGranted'] ? 'granted' : 'denied',
    ad_user_data: consent['adUserDataConsentGranted'] ? 'granted' : 'denied',
    ad_personalization: consent['adPersonalizationConsentGranted'] ? 'granted' : 'denied',
    analytics_storage: consent['analyticsConsentGranted'] ? 'granted' : 'denied',
    functionality_storage: consent['functionalityConsentGranted'] ? 'granted' : 'denied',
    personalization_storage: consent['personalizationConsentGranted'] ? 'granted' : 'denied',
    security_storage: consent['securityConsentGranted'] ? 'granted' : 'denied',
  };
  updateConsentState(consentModeStates);
};
/*
 *   Executes the default command, sets the developer ID, and sets up the consent
 *   update callback
 */
const main = (data) => {
  /*
   * Optional settings using gtagSet
   */
  gtagSet('ads_data_redaction', data.ads_data_redaction);
  gtagSet('url_passthrough', data.url_passthrough);
  gtagSet('developer_id.your_developer_id', true);
  // Set default consent state(s)
  data.defaultSettings.forEach(settings => {
    const defaultData = parseCommandData(settings);
  // wait_for_update (ms) allows for time to receive visitor choices from the CMP
    defaultData.wait_for_update = 500;
    setDefaultConsentState(defaultData);
  });
  // Check if cookie is set and has values that correspond to Google consent
  // types. If it does, run onUserConsent().
  const settings = getCookieValues(COOKIE_NAME);
  if (typeof settings !== 'undefined') {
    onUserConsent(settings);
  }
  /**
   *   Add event listener to trigger update when consent changes
   *
   *   References an external method on the window object which accepts a
   *   function as an argument. If you do not have such a method, you will need
   *   to create one before continuing. This method should add the function
   *   that is passed as an argument as a callback for an event emitted when
   *   the user updates their consent. The callback should be called with an
   *   object containing fields that correspond to the five built-in Google
   *   consent types.
   */
  callInWindow('addConsentListenerExample', onUserConsent);
};
main(data);
data.gtmOnSuccess();
接下来,配置权限以访问用户同意情况和 Cookie。
添加管理同意情况所需的权限:
- 选择权限标签页,然后点击访问用户同意情况。
- 点击添加用户意见征求类型。
- 点击相应复选框,然后从下拉菜单中选择 ad_storage。
- 勾选写入。
- 点击添加。
- 针对 ad_user_data、ad_personalization和analytics_storage重复第 2-5 步。如果您需要其他的用户意见征求类型,请以相同的方式进行添加。
- 点击保存。
添加访问 Cookie 所需的权限:
- 选择权限标签页,然后点击读取 Cookie 值。
- 在特定下方,输入您的代码需要读取的每个 Cookie 的名称,以确定用户的意见征求选项(每行一个名称)。
- 点击保存。
2. 创建单元测试
如需了解如何为模板创建测试,请参阅测试。
3. 将模板与意见征求解决方案集成
以下代码示例展示了如何通过添加监听器,将此模板与您的意见征求管理解决方案的代码集成:
// Array of callbacks to be executed when consent changes
const consentListeners = [];
/**
 *   Called from GTM template to set callback to be executed when user consent is provided.
 *   @param {function} Callback to execute on user consent
 */
window.addConsentListenerExample = (callback) => {
  consentListeners.push(callback);
};
/**
 *   Called when user grants/denies consent.
 *   @param {Object} Object containing user consent settings.
 */
const onConsentChange = (consent) => {
  consentListeners.forEach((callback) => {
    callback(consent);
  });
};
更新用户同意情况
在网站访问者表明自己的意见征求选项(通常通过与意见征求横幅互动表明)之后,模板代码应该使用 updateConsentState API 相应地更新同意情况。
以下示例展示了对访问者的 updateConsentState 调用,该调用表明访问者同意所有存储类型。同样,此示例使用的是 granted 的硬编码值,但实际上,这些值应在运行时使用由 CMP 征求的访问者意见确定。
const updateConsentState = require('updateConsentState');
updateConsentState({
  'ad_storage': 'granted',
  'ad_user_data': 'granted',
  'ad_personalization': 'granted',
  'analytics_storage': 'granted',
  'functionality_storage': 'granted',
  'personalization_storage': 'granted',
  'security_storage': 'granted'
});
关于针对特定区域的行为
若要设置适用于特定区域的访问者的默认同意情况,请在模板中指定相应区域(根据 ISO 3166-2)。通过使用区域值,模板用户可以遵守区域性法规,同时又不会丢失这些区域之外的访问者的信息。如果 setDefaultConsentState 命令中没有指定区域,则该值适用于所有其他区域。
例如,对于来自西班牙和阿拉斯加州的访问者,以下代码会将 analytics_storage 的默认同意情况设置为 denied,而对于来自所有其他区域的访问者,则将 analytics_storage 设置为 granted:
const setDefaultConsentState = require('setDefaultConsentState');
setDefaultConsentState({
  'analytics_storage': 'denied',
  'region': ['ES', 'US-AK']
});
setDefaultConsentState({
  'analytics_storage': 'granted'
});
最具体的区域优先
如果同一个网页上出现了两个分别包含区域和子区域值的默认意见征求命令,则更具体的区域对应的命令就会生效。例如,如果您针对区域 US 将 ad_storage 设置为 'granted',并针对区域 US-CA 将 ad_storage 设置为 'denied',则对于来自加利福尼亚州的访问者而言,更具体的 US-CA 设置将会生效。
| 区域 | ad_storage | 行为 | 
|---|---|---|
| 美国 | 'granted' | 适用于加利福尼亚州以外的美国境内用户 | 
| 美国加利福利亚州 | 'denied' | 适用于美国加利福尼亚洲的用户 | 
| 未指定 | 'granted' | 使用 'granted'的默认值。在此示例中,该值适用于不在美国加利福尼亚州且不在美国境内的用户 | 
其他元数据
您可以使用 gtagSet API 来设置以下可选参数:
这些 API 仅在 GTM 模板沙盒环境中可用。
在网址中传递广告点击、客户端 ID 和会话 ID 方面的信息
如果访问者在点击某个广告后访问广告客户的网站,则与该广告相关的信息可能会以查询参数的形式附加到着陆页网址中。为了提高转化计数的准确性,Google 代码通常会将此类信息存储在广告客户网域上的第一方 Cookie 中。
不过,如果 ad_storage 为 denied,Google 代码就不会在本地保存此类信息。若要在这种情况下提高广告点击衡量准确性,广告客户可以选择使用称为“网址传递”的功能,在所有网页中通过网址参数传递广告点击信息。
同样,如果将 analytics_storage 设置为 denied,网址传递功能将可用于在不采用 Cookie 的情况下,在所有网页中发送基于事件和会话的分析数据(包括转化数据)。
若要使用网址传递功能,必须满足以下条件:
- 网页上包含知晓用户意见的 Google 代码。
- 网站已选择使用网址传递功能。
- 在网页上实现了意见征求模式。
- 出站链接所指向的网域与当前网页的网域相同。
- 网址中存在 GCLID/DCLID(仅限 Google Ads 代码和 Floodlight 代码)
您的模板应允许模板用户配置是否要启用此设置。以下模板代码可用于将 url_passthrough 设置为 true:
gtagSet('url_passthrough', true);
隐去广告数据
当 ad_storage 为 denied 时,系统不会出于广告目的设置新的 cookie。此外,系统也不会使用之前在 google.com 和 doubleclick.net 上设置的第三方 Cookie。发送到 Google 的数据仍将包含完整网址,其中包括网址参数中的所有广告点击信息。
若要在 ad_storage 为 denied 时进一步隐去广告数据,请将 ads_data_redaction 设置为 true。
当 ads_data_redaction 为 true 且 ad_storage 为 denied 时,系统会隐去 Google Ads 代码和 Floodlight 代码在网络请求中发送的广告点击标识符。
gtagSet('ads_data_redaction', true);
开发者 ID
如果您是 CMP 供应商且拥有 Google 签发的开发者 ID,请尽早使用以下方法在模板中进行此项设置。
只有当会有多个不相关的公司或实体跨多个网站使用您的实现时,您才需要使用开发者 ID。如果只有一个网站或实体会使用相应实现,请勿申请开发者 ID。
gtagSet('developer_id.<your_developer_id>', true);
提供面向用户的文档
您的用户将使用您的用户意见征求模板来设置用于收集用户意见的代码。请提供面向用户的文档,以说明以下方面的最佳做法:
- 如何在设置表格中设置同意情况默认值。
- 如何通过在表格中添加更多行针对不同区域设置同意情况默认值。
- 使用用户意见征求初始化 - 所有网页触发器触发代码。
后续步骤
如果您想面向所有跟踪代码管理器用户提供自己的模板,请将其上传到社区模板库。