在「伺服器端代碼簡介」一文中,您已瞭解代碼管理工具中的伺服器端代碼。您已瞭解用戶端的定義和用途:用戶端會接收使用者裝置的事件資料,並將資料轉換成其他容器可用的格式。本文將說明如何在伺服器端代碼中處理這類資料。
在伺服器容器中,代碼會接收來自用戶端的事件資料,並進行轉換,再傳回收集和分析。標記可將資料傳送至任何位置只要目的地接受 HTTP 要求,也可接受來自伺服器容器的資料。
伺服器容器有三個內建標記,無須自訂設定即可使用:
- Google Analytics 4
- HTTP 要求
如果您想將資料傳送至 Google Analytics 以外的位置,或是需要比 HTTP 要求代碼提供的更多功能,就必須使用其他代碼。您可以在社群範本庫中找到其他代碼,也可以自行編寫。本教學課程將教您為伺服器容器編寫自己的標記。
目標
- 瞭解要在瀏覽器中讀取事件資料、傳送 HTTP 要求及設定 Cookie 時,應使用哪些 API。
- 瞭解設計代碼設定選項的最佳做法。
- 瞭解使用者指定資料與自動收集的資料之間的差異,以及這種區別的重要性。
- 瞭解代碼在伺服器容器中的角色。瞭解代碼的使用方式和注意事項。
- 瞭解何時應考慮將代碼範本提交至社群範本庫。
必要條件
Baz Analytics 代碼
在本教學課程中,您將建立代碼,將評估資料傳送至名為 Baz Analytics 的服務。
Baz Analytics 是簡單的假設分析服務,可透過 HTTP GET 要求擷取 https://example.com/baz_analytics
的資料。其參數如下:
參數 | 範例 | 說明 |
---|---|---|
id | BA-1234 | Baz Analytics 帳戶的 ID。 |
en | click | 這是指活動名稱。 |
l | https://www.google.com/search?q=sgtm
|
事件發生的網頁網址。 |
u | 2384294892 | 執行動作的使用者 ID。用來將多個動作連回單一使用者。 |
代碼設定
首先,請建立標記範本。前往容器的「範本」部分,然後點選「代碼範本」部分中的「新增」。為代碼新增名稱和說明。
接著,請前往範本編輯器的「欄位」部分,為代碼新增不同的設定選項。下一個顯而易見的問題是 您需要哪些選項?您可以選擇以下三種方式建構代碼:
- 總設定:為每個參數新增設定欄位。使用者必須明確設定所有屬性。
- 無設定:沒有任何代碼設定選項。所有資料都會直接從事件擷取。
- 部分設定:僅提供部分參數的欄位。
為每個參數提供欄位非常靈活,可讓使用者完全控管代碼設定。但在實際操作中,這通常會導致大量重複的工作。特別是像 Baz Analytics l
參數 (包含網頁網址) 這類參數,都具有明確性和通用性。每次設定代碼時,輸入相同且不變的資料,是電腦最適合處理的任務。
或許答案是使用只擷取事件資料的代碼。這是使用者可設定的最簡單標記,因為使用者無需實際執行任何操作。另一方面,這也是最受限制且最不穩定的選項。使用者無法在需要時變更代碼的行為。
舉例來說,他們可能會在網站和 Google Analytics 中呼叫 purchase
事件,但 Baz Analytics 會呼叫 buy
。或者,也許代碼對傳入事件資料結構的假設,實際上與現實不符。無論是哪一種情況,使用者都會卡住。
就像許多事情一樣,答案介於兩個極端之間。有些資料適合一律從事件中擷取。其他資料應由使用者設定。如何判斷哪個是哪個?為了回答這個問題 我們需要進一步檢視進入容器的資料
資料來源為何?
從 Google Analytics 4 代碼傳入伺服器容器的資料大致可分為兩類:使用者指定資料和自動收集的資料。
使用者指定的資料是使用者放入 gtag.js event
指令中的所有內容。例如以下指令:
gtag('event', 'search', {
search_term: 'beets',
});
這會在伺服器容器中產生下列參數:
{
event_name: 'search',
search_term: 'beets',
}
這很簡單,但從標記的角度來看,這很難處理。由於這項資料是由使用者輸入,因此可以是任何內容。或許使用者只會傳送上述建議事件和參數,但系統並未要求這麼做。除了 event_name
參數的位置 (但不是值!) 之外,我們無法保證使用者資料的格式或結構。
幸好,容器接收的資料不是只有使用者輸入的資料。同時,也會獲得瀏覽器中的 Google Analytics 4 代碼自動收集許多資料。其中包括:
ip_override
language
page_location
page_referrer
page_title
screen_resolution
user_agent
此外,如果伺服器要求來自網路瀏覽器,則可能也會透過 getCookieValue
API 提供瀏覽器 Cookie 資料。
這些資料共同組成我們在前文中提到的自動收集資料。一般來說,這類資料是通用且語意明確的資料。如果瀏覽器收到來自 GA4 代碼的要求,系統一律會提供這項資料,而且格式一律相同。如要進一步瞭解這些參數,請參閱事件參考資料。
在決定使用者應設定哪些資料,以及代碼應指定哪些資料時,這項分類資訊可提供實用的工具。自動收集的資料可安全地直接從事件讀取。其他所有設定都應由使用者設定。
請再參考 Baz Analytics 代碼的參數。
- 評估 ID,
id
:由於系統不會自動收集,因此這是使用者設定代碼時應輸入的值。 - 事件名稱
en
:如上所述,事件名稱一律可以從event_name
參數直接取得。不過,由於其值是由使用者定義,因此建議您提供覆寫名稱的功能 (如有需要)。 - Page URL
l
:這個值可以從page_location
參數取得,Google Analytics GA4 瀏覽器代碼會自動收集每個事件的資料。因此,您不應要求使用者手動輸入值。 - 使用者 ID,
u
:在 Baz Analytics 伺服器代碼中,u
參數既不是使用者指定,也不是由網頁上的代碼自動收集。而是儲存在瀏覽器 Cookie 中,方便在使用者多次造訪網站時識別使用者。如您在以下實作中所見,Baz Analytics 伺服器代碼會使用setCookie
API 設定 Cookie。換句話說,您只能透過 Baz Analytics 標記得知 Cookie 的儲存位置和方式。和l
一樣,系統應該自動收集u
參數。
設定代碼設定後,應該會如下所示:
導入廣告代碼
代碼設定完成後,您就可以在沙箱機制的 JavaScript 中實作代碼行為。
代碼需要執行四項操作:
- 從代碼設定取得事件名稱。
- 從事件的
page_location
屬性取得網頁網址。 - 計算使用者 ID。代碼會在名為
_bauid
的 Cookie 中尋找使用者 ID。如果沒有該 Cookie,標記會計算新值,並儲存起來供日後的請求使用。 - 建立網址並向 Baz Analytics 收集伺服器發出要求。
您也可以花點時間想想,如何在整個容器中融入代碼。不同的容器元件扮演不同的角色,因此代碼無法或不應執行某些操作。您的代碼:
- 請勿透過檢查事件判斷是否應執行。這就是觸發事件的用途。
- 不應使用
runContainer
API 執行容器。這是用戶端的工作。 - 除了 Cookie 之外,請勿嘗試直接與要求或回應互動。這也是客戶的工作。
如果您撰寫的標記範本會執行上述任何操作,使用者可能會對標記的行為感到困惑。舉例來說,如果標記會向傳入要求傳送回應,就會阻止用戶端執行相同動作。這會違背使用者對容器行為的預期。
關於以上所有事項,以下是在沙箱 JS 中加註的標記實作。
const encodeUriComponent = require('encodeUriComponent');
const generateRandom = require('generateRandom');
const getCookieValues = require('getCookieValues');
const getEventData = require('getEventData');
const logToConsole = require('logToConsole');
const makeString = require('makeString');
const sendHttpGet = require('sendHttpGet');
const setCookie = require('setCookie');
const USER_ID_COOKIE = '_bauid';
const MAX_USER_ID = 1000000000;
// The event name is taken from either the tag's configuration or from the
// event. Configuration data comes into the sandboxed code as a predefined
// variable called 'data'.
const eventName = data.eventName || getEventData('event_name');
// page_location is automatically collected by the Google Analytics 4 tag.
// Therefore, it's safe to take it directly from event data rather than require
// the user to specify it. Use the getEventData API to retrieve a single data
// point from the event. There's also a getAllEventData API that returns the
// entire event.
const pageLocation = getEventData('page_location');
const userId = getUserId();
const url = 'https://www.example.com/baz_analytics?' +
'id=' + encodeUriComponent(data.measurementId) +
'en=' + encodeUriComponent(eventName) +
(pageLocation ? 'l=' + encodeUriComponent(pageLocation) : '') +
'u=' + userId;
// The sendHttpGet API takes a URL and returns a promise that resolves with the
// result once the request completes. You must call data.gtmOnSuccess() or
// data.gtmOnFailure() so that the container knows when the tag has finished
// executing.
sendHttpGet(url).then((result) => {
if (result.statusCode >= 200 && result.statusCode < 300) {
data.gtmOnSuccess();
} else {
data.gtmOnFailure();
}
});
// The user ID is taken from a cookie, if present. If it's not present, a new ID
// is randomly generated and stored for later use.
//
// Generally speaking, tags should not interact directly with the request or
// response. This prevents different tags from conflicting with each other.
// Cookies, however, are an exception. Tags are the only container entities that
// know which cookies they need to read or write. Therefore, it's okay for tags
// to interact with them directly.
function getUserId() {
const userId = getCookieValues(USER_ID_COOKIE)[0] || generateRandom(0, MAX_USER_ID);
// The setCookie API adds a value to the 'cookie' header on the response.
setCookie(USER_ID_COOKIE, makeString(userId), {
'max-age': 3600 * 24 * 365 * 2,
domain: 'auto',
path: '/',
httpOnly: true,
secure: true,
});
return userId;
}
這樣就完成代碼導入作業。您必須先正確設定 API 權限,才能使用代碼。前往範本編輯器的「Permissions」(權限) 分頁,並指定下列權限:
- 讀取 Cookie 值:
_bauid
- 讀取事件資料:
event_name
和page_location
- 傳送 HTTP 要求:
https://www.example.com/*
- 設定 Cookie:
_bauid
您也應為標記撰寫測試。如要進一步瞭解範本測試,請參閱範本開發人員指南中的「測試」一節。
最後,請務必至少使用「Run Code」按鈕一次,嘗試執行代碼。這樣可以避免許多簡單錯誤發生在伺服器中。
將標記提交至社群範本庫
由於您已完成建立、測試及部署新代碼的所有工作,因此沒有理由繼續使用該代碼。如果您認為新代碼對其他人有用,不妨考慮將其提交至社群範本庫。
結論
在本教學課程中,您已瞭解為伺服器容器編寫標記的基本概念。並瞭解:
- 要使用哪些 API 讀取事件資料、傳送 HTTP 要求,以及在瀏覽器中設定 Cookie。
- 為代碼設計設定選項的最佳做法。
- 使用者指定資料和自動收集資料的差異,以及為何這項區別相當重要。
- 標記在容器中的角色,以及標記應做和不應做的事。
- 將代碼範本提交至社群範本庫的時間和方式。