建立同意聲明模式範本

本文適用於在採用 Google 代碼管理工具 (GTM) 的網站上,維護同意聲明管理解決方案的開發人員。

本頁面將介紹 Google 代碼管理工具中的同意聲明類型,並說明如何與同意聲明管理解決方案整合。

提供代碼範本後,使用者就能以無程式碼的方式整合同意聲明解決方案,大幅節省時間和人力。

使用者可以透過同意聲明模式範本設定預設同意聲明狀態,並將訪客的同意聲明選項傳送至 Google 代碼管理工具。確保支援同意聲明模式的 Google 和第三方代碼正常運作。

範本建立者可以實作同意聲明模式範本供內部使用,也可以在社群範本庫中發布範本,供大眾使用。提供同意聲明模式範本的同意聲明管理平台 (CMP) 供應商,有機會列入同意聲明模式說明文件,範本庫挑選器也會顯示他們的範本。

Google 和第三方代碼會根據同意聲明狀態 (granteddenied) 調整儲存行為。這些代碼可針對下列任一同意聲明類型進行內建同意聲明檢查:

同意聲明類型 說明
ad_storage 啟用與廣告相關的儲存功能 (例如 Cookie)。
ad_user_data 設定同意聲明狀態,指明可否基於線上廣告用途將使用者資料傳送給 Google。
ad_personalization 設定個人化廣告的同意聲明。
analytics_storage 啟用與數據分析 (例如造訪停留時間) 相關的儲存功能 (例如 Cookie)。
functionality_storage 啟用支援網站/應用程式功能 (例如語言設定) 的儲存功能。
personalization_storage 啟用與個人化 (例如推薦影片) 相關的儲存功能。
security_storage 啟用與安全性 (例如驗證、防詐欺和其他使用者保護功能) 相關的儲存功能

同意聲明模式會追蹤訪客的同意選項和代碼同意檢查,確保代碼行為會據此調整。建立新的同意聲明範本時,請遵循下列最佳做法:

  • 請改用代碼管理工具同意聲明模式 API setDefaultConsentStateupdateConsentState,而非 gtag consent

  • 使用「同意聲明初始化 - 所有網頁」觸發條件,在觸發時立即設定預設同意聲明狀態。

  • CMP 必須盡快提示訪客授予或拒絕所有適用同意聲明類型的同意聲明。

  • 訪客完成同意聲明設定後,CMP 必須傳遞更新後的同意聲明狀態。

1. 建立新範本

這個導入方法會在範本中使用一個欄位,儲存預設同意聲明狀態。導入程式碼會讀取該欄位,在執行階段設定預設同意聲明狀態。如果是更新指令,程式碼會嘗試讀取同意聲明解決方案設定的 Cookie,以儲存訪客的同意聲明選項。您也會為 updateConsentState 設定回呼,以便處理訪客尚未選取同意聲明選項,或決定變更同意聲明的情況。

  1. 登入 Google 代碼管理工具帳戶。
  2. 在左側導覽面板中選取「範本」
  3. 在「代碼範本」窗格中,按一下「新增」
  1. 選取「欄位」分頁標籤,然後依序點按「新增欄位」>「參數表格」
  2. 將名稱變更為 defaultSettings
  3. 展開欄位。
  4. 將「顯示名稱」更新為「Default settings」。
  5. 按一下「新增資料欄」,選擇「文字輸入」,將名稱變更為 region,然後勾選「資料欄值必須是唯一值」方塊。
  6. 展開資料欄,然後將顯示名稱變更為「Region (leave blank to have consent apply to all regions)」。括號中的陳述是範本使用者的文件。進一步瞭解如何為不同區域設定同意聲明預設值
  7. 按一下「新增資料欄」,選擇「文字輸入」,然後將名稱變更為 granted
  8. 展開資料欄,並將顯示名稱變更為「Granted Consent Types (comma separated)」。
  9. 按一下「新增資料欄」,選擇「文字輸入」,然後將名稱變更為 denied
  10. 展開資料欄,並將顯示名稱變更為 Denied Consent Types (comma separated)

選用:如要新增廣告資料遮蓋支援功能,請按照下列步驟操作:

  1. 按一下「新增欄位」,選擇「核取方塊」,然後將欄位名稱變更為 ads_data_redaction
  2. 將顯示名稱更新為「Redact Ads Data

進一步瞭解廣告資料遮蓋的 Cookie 行為

選用:如要新增支援傳遞網址參數的功能,請按照下列步驟操作:

  1. 按一下「新增欄位」,選擇「核取方塊」,然後將欄位名稱變更為 url_passthrough
  2. 將顯示名稱更新為「Pass through URL parameters

進一步瞭解如何傳遞網址參數

如要新增導入程式碼,請按照下列步驟操作:

  1. 在範本編輯器中開啟「程式碼」分頁。
  2. 在下方的程式碼範例中,編輯預留位置欄位。
  3. 複製程式碼,然後貼到範本編輯器中,取代樣板程式碼。
  4. 儲存範本。
// 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 JSON = require('JSON');
const COOKIE_NAME = 'Your_cookie_name';
/*
 *   Splits the input string using comma as a delimiter, returning an array of
 *   strings
 */
const splitInput = (input) => {
  if (!input) return [];
  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). Add optional chaining to safely handle cases
  // where defaultSettings might be null or undefined.
  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 cookieValues = getCookieValues(COOKIE_NAME);
  if (cookieValues && cookieValues.length > 0) {
    try {
      const settings = JSON.parse(cookieValues[0]);
      if (settings) {
        onUserConsent(settings);
      }
    } catch (e) {
      // Log an error if the cookie value is not valid JSON.
    }
  }
  /**
   *   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 的權限。

  1. 選取「權限」分頁標籤,然後按一下「存取同意聲明狀態」
  2. 按一下「新增同意聲明類型」
  3. 按一下方塊,然後從下拉式選單中選取 ad_storage
  4. 勾選「寫入」
  5. 按一下 [新增]。
  6. 針對 ad_user_dataad_personalizationanalytics_storage 重複步驟 2 到 5。如需其他同意聲明類型,請以相同方式新增。
  7. 按一下 [儲存]

如要新增存取 Cookie 的權限,請按照下列步驟操作:

  1. 選取「權限」分頁標籤,然後按一下「讀取 Cookie 值」
  2. 在「特定」下方,輸入程式碼需要讀取的每個 Cookie 名稱,一行一個名稱,以判斷使用者的同意聲明選項。
  3. 按一下 [儲存]

2. 建立單元測試

如要瞭解如何為範本建立測試,請參閱「測試」。

以下程式碼範例說明如何新增事件監聽器,將這個範本與同意聲明管理解決方案的程式碼整合:

// 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 設為 'granted',區域 US-CA 設為 'denied',來自加州的訪客就會套用更具體的 US-CA 設定。ad_storagead_storage

區域 ad_storage 行為
美國 'granted' 適用於加州境內的美國使用者
US-CA 'denied' 適用於美國加州使用者
未指定 'granted' 使用 'granted' 的預設值。在本例中,這項限制適用於不在美國或美國加州的使用者,

其他中繼資料

您可以使用 gtagSet API 設定下列選用參數:

這些 API 只能在 GTM 範本沙箱環境中使用。

在網址中傳遞廣告點擊、用戶端 ID 和工作階段 ID 資訊

訪客點按廣告後前往廣告主網站時,系統可能會將廣告相關資訊附加至到達網頁網址,做為查詢參數。為提升轉換追蹤準確度,Google 代碼通常會將這項資訊儲存在廣告主網域的第一方 Cookie 中。

不過,如果 ad_storagedenied,Google 代碼就不會在本機儲存這項資訊。為改善這類情況下的廣告點擊評估品質,廣告主可選擇透過網址參數,使用名為「網址傳遞」的功能,在各個頁面傳遞廣告點擊資訊。

同樣地,如果 analytics_storage 設為「已拒絕」,您可以使用網址傳遞功能,在沒有 Cookie 的情況下,跨網頁傳送事件和工作階段型數據分析 (包括轉換)。

如要使用網址直通功能,必須符合下列條件:

  • 網頁上有同意聲明認知 Google 代碼。
  • 網站已選擇使用網址穿透功能。
  • 網頁已導入同意聲明模式。
  • 出站連結參照的網域與目前網頁的網域相同。
  • 網址中含有 gclid/dclid (僅限 Google Ads 和 Floodlight 代碼)

範本應允許範本使用者設定是否要啟用這項設定。下列範本程式碼用於將 url_passthrough 設為 true:

gtagSet('url_passthrough', true);

遮蓋廣告資料

如果使用者拒絕 ad_storage,系統就不會設定新的廣告 Cookie。此外,系統不會使用先前在 google.com 和 doubleclick.net 上設定的第三方 Cookie。傳送給 Google 的資料仍會包含完整網頁網址,包括網址參數中的任何廣告點擊資訊。

如要在 ad_storage 遭拒時進一步遮蓋廣告資料,請將 ads_data_redaction 設為 true。

如果 ads_data_redaction 為 true 且 ad_storage 遭到拒絕,Google Ads 和 Floodlight 代碼在網路要求中傳送的廣告點擊 ID 將會經過修訂。

gtagSet('ads_data_redaction', true);

開發人員 ID

如果您是 CMP 供應商,且擁有 Google 核發的開發人員 ID,請盡早在範本中透過下列方法設定。

如果實作項目會由不相關的公司或實體用於多個網站,才需要開發人員 ID。如果實作項目只會由一個網站或實體使用,請不要申請開發人員 ID。

gtagSet('developer_id.<your_developer_id>', true);

為使用者提供文件

使用者會使用同意聲明範本設定代碼,收集使用者同意聲明。為使用者提供說明文件,說明下列最佳做法:

  • 如何在「設定」表格中設定同意聲明預設值。
  • 新增其他資料列,為不同區域設定同意聲明預設值。
  • 在「Consent Initialization - All Pages」(同意聲明初始化 - 所有網頁) 觸發條件下觸發代碼。

後續步驟

如要將範本提供給所有代碼管理工具使用者,請將範本上傳至社群範本庫