Google アナリティクスを使用する

このチュートリアルでは、Google アナリティクスを使用して拡張機能の使用状況をトラッキングする方法について説明します。GitHub で動作する Google アナリティクスのサンプルを確認できます。ここで、google-analytics.js には Google アナリティクス関連のコードがすべて含まれています。

要件

このチュートリアルは、Chrome 拡張機能の作成に精通していることを前提としています。拡張機能の作成方法については、スタートガイドのチュートリアルをご覧ください。

拡張機能をトラッキングするには、Google アナリティクス アカウントも設定する必要があります。アカウントの設定時に、ウェブサイトの URL フィールドに任意の値を入力できます。拡張機能には独自の URL がないためです。

Google アナリティクス Measurement Protocol を使用する

Manifest V3 以降、Chrome 拡張機能はリモートでホストされるコードを実行できません。つまり、拡張機能イベントのトラッキングには Google アナリティクス Measurement Protocol を使用する必要があります。Measurement Protocol を使用すると、HTTP リクエストで Google アナリティクス サーバーに直接イベントを送信できます。この方法の利点は、Service Worker を含め、拡張機能のあらゆる場所から分析イベントを送信できることです。

API 認証情報を設定する

Google アナリティクスにイベントを送信するには、api_secretmeasurement_id が必要です。Measurement Protocol の一般的な仕様については、Measurement Protocol のドキュメントをご覧ください。

ステップ 1: ウェブデータ ストリームを作成する

Chrome 拡張機能はウェブ環境としてトラッキングされるため、Google アナリティクスのプロパティでウェブデータ ストリームを設定する必要があります。

  1. Google アナリティクスの管理ページに移動します。
  2. [プロパティ] 列で [データの収集と修正] をクリックし、[データ ストリーム] を選択します。
  3. [ストリームを追加]、[ウェブ] の順にクリックします。
  4. [ウェブサイトの URL] フィールドにプレースホルダ URL(https://extension や拡張機能の Chrome ウェブストア URL など)を入力します。
  5. [ストリーム名](例: My Chrome Extension)を入力します。
  6. [ストリームを作成] をクリックします。

作成が完了すると、[ストリームの詳細] ページの上部に測定 IDG-XXXXXXXXXX のような形式)が表示されます。

ステップ 2: Measurement Protocol API Secret を生成する

Measurement Protocol に必要な api_secret を生成するには、作成したウェブデータ ストリームの設定に移動します。

  1. [管理] > [データの収集と修正] > [データ ストリーム] に移動し、ウェブ データ ストリームを選択します。
  2. [イベント] セクションで、[Measurement Protocol API シークレット] をクリックします。

  3. プロンプトが表示されたら、Measurement Protocol の利用規約を確認し、同意します。

  4. [作成] をクリックします。

  5. シークレットのニックネーム(Chrome Extension Secret など)を入力し、[作成] をクリックしてシークレットを生成します。

  6. 生成されたシークレット値をコピーします。

client_id を生成する

2 つ目の手順は、特定のデバイス/ユーザーの固有識別子 client_id を生成することです。拡張機能がユーザーのブラウザにインストールされている限り、ID は同じままです。任意の文字列にできますが、クライアントごとに一意である必要があります。拡張機能がインストールされている間は同じ状態を維持できるように、client_idchrome.storage.local に保存します。

chrome.storage.local を使用するには、マニフェスト ファイルで storage 権限が必要です。

manifest.json:

{
  
  "permissions": ["storage"],
  
}

その後、chrome.storage.local を使用して client_id を保存できます。

function getRandomId() {
  const digits = '123456789'.split('');
  let result = '';

  for (let i = 0; i < 10; i++) {
    result += digits[Math.floor(Math.random() * 9)];
  }

  return result;
}

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. We use
    // the <number>.<number> format since this is typical for GA client IDs.
    const unixTimestampSeconds = Math.floor(new Date().getTime() / 1000);
    clientId = `${getRandomId()}.${unixTimestampSeconds}`;
    await chrome.storage.local.set({clientId});
  }
  return clientId;
}

分析イベントを送信する

API 認証情報と client_id を使用して、fetch リクエストで Google アナリティクスにイベントを送信できます。

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 アナリティクスのイベント レポートに表示されます。Google アナリティクスのリアルタイム レポートでイベントを確認するには、session_idengagement_time_msec の 2 つの追加パラメータを指定する必要があります。

推奨パラメータ session_idengagement_time_msec を使用する

session_idengagement_time_msec は、ユーザー アクティビティを「リアルタイム」などの標準レポートに表示させるために必要となるため、Google アナリティクス 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_idengagement_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 getOrCreateSessionId(),
            engagement_time_msec: DEFAULT_ENGAGEMENT_TIME_IN_MSEC,
            id: "my-button",
          },
        },
      ],
    }),
  }
);

このイベントは、Google アナリティクスのリアルタイム レポートに次のように表示されます。

Google アナリティクスのリアルタイム イベント。

ポップアップ、サイドパネル、拡張機能のページでのページビューをトラッキングする

Google アナリティクス 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 アナリティクスのリアルタイム レポートで他のページビューと同様に表示されます。

Google アナリティクスのリアルタイム ダッシュボードに表示されるページビュー イベント。

サービス ワーカーで分析イベントをトラッキングする

Google アナリティクスの Measurement Protocol を使用すると、拡張機能のサービス ワーカーでアナリティクス イベントをトラッキングできます。たとえば、Service Worker で unhandledrejection event をリッスンすることで、Service Worker でキャッチされなかった例外を Google アナリティクスに記録できます。これは、ユーザーが報告する可能性のある問題のデバッグに大いに役立ちます。

service-worker.js:

addEventListener("unhandledrejection", async (event) => {
  fetch(`${GA_ENDPOINT}?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`,
  {
    method: "POST",
    body: JSON.stringify({
      client_id: await 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 getOrCreateSessionId(),
            engagement_time_msec: DEFAULT_ENGAGEMENT_TIME_IN_MSEC,
            message: event.reason.message,
            stack: event.reason.stack,
          },
        },
      ],
    }),
  });
});

Google アナリティクス レポートにエラー イベントが表示されるようになりました。

Google アナリティクスのイベント ダッシュボードに表示されるエラー イベント。

デバッグ

Google アナリティクスには、拡張機能へのアナリティクス イベントのデバッグに役立つ 2 つの機能があります。

  1. イベント定義のエラーを報告する特別なデバッグ エンドポイント https://www.google-analytics.com**/debug**/mp/collect
  2. イベントが届くと表示される Google アナリティクスのリアルタイム レポート