本教程演示如何使用 Google Analytics 跟踪扩展程序的使用情况。您可以在 GitHub 上找到有效的 Google Analytics 4 示例,其中 google-analytics.js
包含所有 Google Analytics 相关代码。
要求
本教程假定您熟悉编写 Chrome 扩展程序。如果您需要了解如何编写扩展程序,请参阅入门教程。
此外,您还必须设置 Google Analytics 4 账号才能跟踪您的扩展程序。请注意,在设置账号时,您可以使用“网站网址”字段中的任何值,因为您的扩展程序不会有自己的网址。
使用 Google Analytics Measurement Protocol
从 Manifest V3 开始,Chrome 扩展程序不得执行远程托管的代码。也就是说,您必须使用 Google Analytics Measurement Protocol 来跟踪扩展程序事件。利用 Measurement Protocol,您可以通过 HTTP 请求直接将事件发送到 Google Analytics 服务器。这种方法的一大优势在于,它允许您从扩展程序中的任何位置(包括 Service Worker)发送分析事件。
设置 API 凭据
第一步是获取 api_secret
和 measurement_id
。请参阅 Measurement Protocol 文档,了解如何为您的 Google Analytics 账号获取这些数据。
生成 client_id
第二步是为特定设备/用户生成唯一标识符,即 client_id
。只要扩展程序安装在用户浏览器中,ID 就应保持不变。它可以是任意字符串,但对客户端而言应该是唯一的。您可以通过调用 self.crypto.randomUUID()
生成一个。将 client_id
存储在 chrome.storage.local
中,以确保其在安装扩展程序期间保持不变。
要使用 chrome.storage.local
,您需要在清单文件中拥有 storage
权限:
manifest.json:
{ … "permissions": ["storage"], … }
然后,您可以使用 chrome.storage.local
存储 client_id
:
async function getOrCreateClientId() { const result = await chrome.storage.local.get('clientId'); let clientId = result.clientId; if (!clientId) { // Generate a unique client ID, the actual value is not relevant clientId = self.crypto.randomUUID(); await chrome.storage.local.set({clientId}); } return clientId; }
发送分析事件
借助 API 凭据和 client_id
,您可以通过 fetch
请求向 Google Analytics 发送事件:
const GA_ENDPOINT = 'https://www.google-analytics.com/mp/collect'; const MEASUREMENT_ID = `G-...`; const API_SECRET = `...`; fetch( `${GA_ENDPOINT}?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`, { method: 'POST', body: JSON.stringify({ client_id: await getOrCreateClientId(), events: [ { name: 'button_clicked', params: { id: 'my-button', }, }, ], }), } );
这样会发送 button_clicked
事件,该事件会显示在您的 Google Analytics 事件报告中。如果您想在 Google Analytics 实时报告中查看事件,则需要提供两个额外的参数:session_id
和 engagement_time_msec
。
使用建议的参数 session_id
和 engagement_time_msec
session_id
和 engagement_time_msec
都是使用 Google Analytics Measurement Protocol 时的推荐参数,因为它们在实时等标准报告中显示用户活动时必不可少。
session_id
描述了用户持续与您的扩展程序互动的时间段。默认情况下,会话会在用户处于不活动状态 30 分钟后结束。会话无持续时间限制。
与常规网站不同,Chrome 扩展程序中没有明确的用户会话概念。因此,您必须在扩展程序中定义用户会话的含义。例如,每次新的用户互动都可能是一次新会话。在这种情况下,您只需为每个事件生成一个新的会话 ID(即使用时间戳)。
以下示例演示了一种方法,该方法会在没有报告任何事件 30 分钟后使新会话超时(您可以自定义此时间,以更好地适应您的扩展程序的用户行为)。该示例使用 chrome.storage.session
来存储浏览器运行时的活动会话。我们将与会话一起存储上次触发事件的时间。我们可以通过以下方法判断当前会话是否已过期:
const SESSION_EXPIRATION_IN_MIN = 30; async function getOrCreateSessionId() { // Store session in memory storage let {sessionData} = await chrome.storage.session.get('sessionData'); // Check if session exists and is still valid const currentTimeInMs = Date.now(); if (sessionData && sessionData.timestamp) { // Calculate how long ago the session was last updated const durationInMin = (currentTimeInMs - sessionData.timestamp) / 60000; // Check if last update lays past the session expiration threshold if (durationInMin > SESSION_EXPIRATION_IN_MIN) { // Delete old session id to start a new session sessionData = null; } else { // Update timestamp to keep session alive sessionData.timestamp = currentTimeInMs; await chrome.storage.session.set({sessionData}); } } if (!sessionData) { // Create and store a new session sessionData = { session_id: currentTimeInMs.toString(), timestamp: currentTimeInMs.toString(), }; await chrome.storage.session.set({sessionData}); } return sessionData.session_id; }
以下示例将 session_id
和 engagement_time_msec
添加到了上一个按钮点击事件请求中。对于 engagement_time_msec
,您可以提供默认值 100 ms
。
const GA_ENDPOINT = "https://www.google-analytics.com/mp/collect"; const MEASUREMENT_ID = `G-...`; const API_SECRET = `...`; const DEFAULT_ENGAGEMENT_TIME_IN_MSEC = 100; fetch( `${GA_ENDPOINT}?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`, { method: "POST", body: JSON.stringify({ client_id: await getOrCreateClientId(), events: [ { name: "button_clicked", params: { session_id: await this.getOrCreateSessionId(), engagement_time_msec: DEFAULT_ENGAGEMENT_TIME_IN_MSEC, id: "my-button", }, }, ], }), } );
该事件在 Google Analytics 实时报告中将按如下方式显示。
跟踪弹出式窗口、侧边栏和扩展程序页面中的网页浏览量
Google Analytics Measurement Protocol 支持用于跟踪网页浏览量的特殊 page_view
事件。使用此方法跟踪访问新标签页、侧边栏或扩展程序页面(新标签页中)的用户。page_view
事件还需要 page_title
和 page_location
参数。以下示例会在文档 load
事件中针对扩展程序弹出式窗口触发网页浏览事件:
popup.js:
window.addEventListener("load", async () => { fetch(`${GA_ENDPOINT}?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`, { method: "POST", body: JSON.stringify({ client_id: await getOrCreateClientId(), events: [ { name: "page_view", params: { session_id: await getOrCreateSessionId(), engagement_time_msec: DEFAULT_ENGAGEMENT_TIME_IN_MSEC, page_title: document.title, page_location: document.location.href }, }, ], }), }); });
popup.js
脚本需要导入到弹出式窗口的 HTML 文件中,并且应在执行任何其他脚本之前运行:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Analytics Demo Popup</title> <script src="./popup.js" type="module"></script> </head> <body> <h1>Analytics Demo</h1> </body> </html>
弹出式视图将像 Google Analytics 实时报告中的任何其他网页浏览一样显示:
在 Service Worker 中跟踪分析事件
使用 Google Analytics Measurement Protocol 可以跟踪扩展程序 Service Worker 中的分析事件。例如,通过监听 Service Worker 中的 unhandledrejection event
,您可以将 Service Worker 中任何未捕获的异常记录到 Google Analytics,这在很大程度上有助于调试用户可能报告的问题。
service-worker.js:
addEventListener("unhandledrejection", async (event) => { `${GA_ENDPOINT}?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`, { method: "POST", body: JSON.stringify({ client_id: getOrCreateClientId(), events: [ { // Note: 'error' is a reserved event name and cannot be used // see https://developers.google.com/analytics/devguides/collection/protocol/ga4/reference?client_type=gtag#reserved_names name: "extension_error", params: { session_id: await this.getOrCreateSessionId(), engagement_time_msec: DEFAULT_ENGAGEMENT_TIME_IN_MSEC, message: error.message, stack: error.stack, }, }, ], }), } });
现在,您可以在 Google Analytics 报告中查看错误事件:
调试
Google Analytics 提供了两项实用功能,用于在扩展程序中调试 Analytics 事件:
- 一个特殊调试端点
https://www.google-analytics.com**/debug**/mp/collect
,将报告事件定义中的所有错误。 - Google Analytics 实时报告:实时显示有事件发生的事件。