GA4自動集計&分析
第2回:GASでGA4データを自動記録!コピペで動くスクリプトと権限の承認

第2回:GASでGA4データを自動記録!コピペで動くスクリプトと権限の承認

第1回の記事では、GASでGA4のデータを取得するための準備として、GCPプロジェクトの作成と連携設定を行いました。

第2回となる今回は、いよいよGASエディタにスクリプト(コード)を記述し、実際にGA4のデータをスプレッドシートに「記録(出力)」する手順を解説します。

「プログラミング」といっても、難しいことはありません。
コピー&ペーストで動くコードですので、IDを書き換えるだけで、すぐにご自分のサイトの分析データベースが完成します。

スクリプトを記述する前の準備

コードを貼る前に、スプレッドシート側でデータを出力するシートを用意します。
今回は3種類のデータを記録するため、3つのシートを作成してください。

スプレッドシート側の設定手順

GASが「どのGA4のデータを見に行くか」を指定するために、「プロパティID」が必要です。

ステップ1:GA4の「プロパティID」を確認する

1. GA4の管理画面(左下の歯車マーク)を開きます。

2. 「プロパティ設定」の列にある「プロパティの詳細」をクリックします。

3. 画面右上に表示される「プロパティID」をコピーしておきます。

重要「G-XXXXXXXXXX」から始まる「測定ID」とは異なります。必ず「数字のみ」のIDを使用してください。

ステップ2:3つのシートを作成し、見出しを入力する

スプレッドシートの下部にある「+」ボタンでシートを追加し、以下のシート名と列見出し(1行目)を設定してください。

シート名列見出し用途
日次サマリーA1:日付
B1:PV数
C1:ユーザー数
D1:セッション数
E1:新規ユーザー数
F1:リピーター数
G1:平均エンゲージメント時間(秒)
全体の推移を記録
流入元データA1:日付
B1:参照元/メディア
C1:セッション数
D1:エンゲージメントのあったセッション数
E1:平均セッション継続時間
Google検索やSNSなどアクセスの参照元を記録
記事ランキングA1:日付
B1:記事タイトル
C1:URL
D1:PV数
E1:アクティブユーザー数
F1:ユーザーあたりPV数
G1:平均エンゲージメント時間(秒)
アクセスの多い記事トップ10を記録

【コピペOK】3つのデータを一括記録するスクリプト

準備ができたら、GASエディタでの作業に移ります。
先程作成したGA4データを記録するスプレッドシートのメニュー「拡張機能」>「Apps Script」からエディタを開いてください。

コードの貼り付けと設定変更

ステップ1:サンプルスクリプトをコピーする

以下のスクリプトをすべてコピーしてください。
このスクリプトによりシートへ自動でデータを振り分けて記録します。

function fetchGA4Data() {

  // ▼▼▼ 設定項目(GA4のプロパティID)
  const PROPERTY_ID = 'ここをプロパティIDに書き換える';
  // ▲▲▲ 設定項目

  // 出力先のシート名を定義(シート名を変える場合はここを修正)
  const SHEET_NAMES = {
    SUMMARY: '日次サマリー',
    SOURCE: '流入元データ',
    RANKING: '記事ランキング'
  };

  const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();

  // 日付設定(昨日)
  const yesterday = new Date();
  yesterday.setDate(yesterday.getDate() - 1);
  const formattedDate = Utilities.formatDate(yesterday, 'Asia/Tokyo', 'yyyy-MM-dd');
  const dateRange = [{ startDate: formattedDate, endDate: formattedDate }];


  // ===== 共通処理 =====

  // シート取得(存在しなければエラー)
  function getSheet(name) {
    const sheet = spreadsheet.getSheetByName(name);
    if (!sheet) throw new Error(`シート「${name}」が存在しません`);
    return sheet;
  }

  // GA4 API 実行
  function runGa4Report(request) {
    return AnalyticsData.Properties.runReport(
      request,
      `properties/${PROPERTY_ID}`
    );
  }

  // データが無い場合に指定列数0埋めで1行追加
  function appendEmptyRow(sheet, date, colCount) {
    const empty = Array(colCount - 1).fill(0);
    sheet.appendRow([date, ...empty]);
  }

  // ===== 1. 日次サマリー =====
  try {
    const sheet = getSheet(SHEET_NAMES.SUMMARY);

    const request = {
      property: `properties/${PROPERTY_ID}`,
      dateRanges: dateRange,
      metrics: [
        { name: 'screenPageViews' },        // PV数
        { name: 'activeUsers' },            // アクティブユーザー数
        { name: 'sessions' },               // セッション数
        { name: 'newUsers' },               // 新規ユーザー数
        { name: 'userEngagementDuration' }  // 総エンゲージメント時間(秒)
      ],
      dimensions: [{ name: 'date' }]        // 日付毎
    };

    const response = runGa4Report(request);

    if (response.rows && response.rows.length > 0) {
      const row = response.rows[0];
      const pv = Number(row.metricValues[0].value);
      const activeUsers = Number(row.metricValues[1].value);
      const sessions = Number(row.metricValues[2].value);
      const newUsers = Number(row.metricValues[3].value);
      const totalEngTime = Number(row.metricValues[4].value);

      // リピーター数 = アクティブユーザー - 新規ユーザー(マイナスにならないよう調整)
      const returningUsers = Math.max(0, activeUsers - newUsers);
      // 平均エンゲージメント時間 = 総時間 / 人数
      const avgEngTime = activeUsers > 0 ? Number((totalEngTime / activeUsers).toFixed(1)) : 0;

      sheet.appendRow([
        formattedDate,
        pv,
        activeUsers,
        sessions,
        newUsers,
        returningUsers,
        avgEngTime
      ]);
    } else {
      appendEmptyRow(sheet, formattedDate, 7);
    }

    Logger.log('日次サマリー取得完了');
  } catch (e) {
    Logger.log('日次サマリー取得エラー: ' + e);
  }

  // ===== 2. 流入元データ =====
  try {
    const sheet = getSheet(SHEET_NAMES.SOURCE);

    const request = {
      property: `properties/${PROPERTY_ID}`,
      dateRanges: dateRange,
      metrics: [
        { name: 'sessions' },               // セッション
        { name: 'engagedSessions' },        // エンゲージのあったセッション
        { name: 'userEngagementDuration' }  // 総エンゲージメント時間
      ],
      dimensions: [{ name: 'sessionSourceMedium' }],                  // 参照元/メディア
      orderBys: [{ desc: true, metric: { metricName: 'sessions' } }], // セッション数が多い順
      limit: 10 // 上位10件
    };

    const response = runGa4Report(request);

    if (response.rows && response.rows.length > 0) {
      const rows = response.rows.map(row => {
        const sessions = Number(row.metricValues[0].value);
        const engagedSessions = Number(row.metricValues[1].value);
        const totalEngTime = Number(row.metricValues[2].value);

        // セッションあたりの平均時間
        const avgSessionEngTime =
          sessions > 0 ? Number((totalEngTime / sessions).toFixed(1)) : 0;

        return [
          formattedDate,
          row.dimensionValues[0].value,
          sessions,
          engagedSessions,
          avgSessionEngTime
        ];
      });

      sheet
        .getRange(sheet.getLastRow() + 1, 1, rows.length, rows[0].length)
        .setValues(rows);
    }

    Logger.log('流入元データ取得完了');
  } catch (e) {
    Logger.log('流入元データ取得エラー: ' + e);
  }

  // ===== 3. 記事ランキング =====
  try {
    const sheet = getSheet(SHEET_NAMES.RANKING);

    const request = {
      property: `properties/${PROPERTY_ID}`,
      dateRanges: dateRange,
      metrics: [
        { name: 'screenPageViews' },        // PV数
        { name: 'activeUsers' },            // アクティブユーザー数
        { name: 'userEngagementDuration' }  // 総エンゲージメント時間
      ],
      dimensions: [{ name: 'pageTitle' }, { name: 'pagePath' }],              // 記事タイトルとURL
      orderBys: [{ desc: true, metric: { metricName: 'screenPageViews' } }],  // PVが多い順
      limit: 10 // 上位10件
    };

    const response = runGa4Report(request);

    if (response.rows && response.rows.length > 0) {
      const rows = response.rows.map(row => {
        const pv = Number(row.metricValues[0].value);
        const users = Number(row.metricValues[1].value);
        const totalEngTime = Number(row.metricValues[2].value);

        // ユーザーあたりのPV数
        const viewsPerUser = users > 0 ? Number((pv / users).toFixed(2)) : 0;
        // ユーザーあたりの平均滞在時間
        const avgEngTime = users > 0 ? Number((totalEngTime / users).toFixed(1)) : 0;

        return [
          formattedDate,
          row.dimensionValues[0].value,
          row.dimensionValues[1].value,
          pv,
          users,
          viewsPerUser,
          avgEngTime
        ];
      });

      sheet
        .getRange(sheet.getLastRow() + 1, 1, rows.length, rows[0].length)
        .setValues(rows);
    }

    Logger.log('記事ランキング取得完了');
  } catch (e) {
    Logger.log('記事ランキング取得エラー: ' + e);
  }

  Logger.log('全データ処理完了');
}

ステップ2:設定項目を書き換える

  1. GASエディタに元々書かれている function myFunction() { ... } を削除します。
  2. 上記のサンプルスクリプトをすべて貼り付けます。
  3. スクリプトの4行目にある設定項目(▼▼▼~▲▲▲の間)を書き換えます。
    • PROPERTY_ID: 『スプレッドシート側の設定手順』のステップ1で確認したご自身のプロパティIDを入力します。

初回実行と権限の承認

設定が完了したら、スクリプトを実行してみましょう。
初回のみ、GASにアクセス権限を与えるための「承認作業」が必要です。

承認プロセスの手順

承認前のため警告画面が出ることがありますが、手順通りに進めれば問題ありません。

ステップ1:実行ボタンを押す

  1. GASエディタの上部にある「関数を選択」が「fetchGA4Data」になっていることを確認します。
  2. 実行」ボタンをクリックします。

ステップ2:権限を確認する

  1. 「承認が必要です」というダイアログが表示されます。
  2. 権限を確認」をクリックします。
  3. データにアクセスするご自身のGoogleアカウントを選択します。

ステップ3:警告画面(安全ではないページ)を進む

  1. このアプリは Google で確認されていません」という警告画面が表示されることがあります。
  2. その場合、画面左下の「詳細」をクリックします。
  3. 下に開いたメニューから「(あなたのプロジェクト名)に移動(安全ではないページ)」というリンクをクリックします。

ステップ4:許可を与える

  1. 「(プロジェクト名)が Google アカウントへのアクセスを求めています」という画面が表示されます。
  2. 内容を確認し、右下の「続行」(または「許可」)をクリックします。

これで承認は完了です。自動的にスクリプトの実行が始まります。

実行結果の確認

スクリプトが最後まで動くと、エディタ下部の「実行ログ」に「実行開始」~「実行完了」のメッセージが表示されます。

データ記録の確認手順

ステップ1:3つのシートを確認する

スプレッドシートに戻り、それぞれのシートを見てみましょう。

GASでGA4データを自動取得_スプレッドシートを確認する
  • 日次サマリー:昨日のPV数やユーザー数などが1行入っているか?
  • 流入元データ:昨日の流入元(google / organicなど)やセッション数が並んでいるか?
  • 記事ランキング:昨日読まれた記事のタイトルが並んでいるか?

これらが記録されていれば成功です。

ステップ2:再度実行する

確認のため、GASエディタに戻ってもう一度「実行」ボタンを押してみてください。
今度は承認画面は出ず、すぐに完了します。

スプレッドシートを見ると、データがさらに追記されているはずです。これが「データを記録(蓄積)していく」動きです。
(※本番運用では1日1回動くように設定するため、重複の心配はいりません。今実行した重複分は削除してください。)

まとめ

今回は、GASでスクリプトを作成し、「権限の承認」をして、GA4データをスプレッドシートに記録することに成功しました。

  1. 分析に必要な「サマリー」「流入元」「記事ランキング」を一括取得するコードを設定した
  2. 警告画面(承認)の手順を正しく進めた
  3. シートにデータが振り分けられ、記録されることを確認した

これで、「ボタンを押せば詳細な分析データが記録できる」状態になりました。
しかし、毎日ボタンを押しにくるのは面倒です。

次回(最終回)は、このスクリプトを「毎日朝8時に自動で実行する」ためのトリガー設定の方法と、今回取得した3つのデータを活用した具体的な分析・改善アクションについて解説します。

もし、「エラーが出て進めない」「自社用にカスタマイズしたい」といったご相談があれば、お気軽にお問い合わせください。

GA4自動集計&分析 の記事一覧

この記事は役に立ちましたか?

参考になりましたら、下のボタンで教えてください。

コメント

この記事へのトラックバックはありません。

PAGE TOP
ログイン