
Google アナリティクスのアクセスデータを取得して、Google スプレッドシートに毎週自動で出力するGASを作る
先日、Google サーチコンソールにGoogle サイトで作成した独自ドメインのホームページの登録についてご紹介しました。
その記事の中でもご説明していますが、Google サーチコンソールは、ホームページに悪世するまでの行動を、Google アナリティクスはホームページに訪れてからの行動を確認し、ホームページの改善策を考えます。今回は、Google アナリティクスから改善のために必要最低限の情報を取得することを目的としたGASについてご紹介します。なお、Google アナリティクスへの登録は済みであることを前提に進めてまいります。
ところで、改善のために必要最低限の情報とは何かを明確にしておく必要があります。私自身、それほどWeb解析に詳しいわけではないのですが、一応以下の4つがあればよいかと思っています。
アクティブユーザー数
実際にサイトを訪れた「人数」 のこと。特定の期間内に、あなたのWebサ
イトやアプリで何らかの操作(スクロール、クリックなど)を行ったユニ
ークなユーザーの数を示します。増加傾向にあることが重要です。目安と
して、週次レポートであれば、週比で減少していないかをチェックしまし
ょう。
セッション数
サイトへの「訪問回数」 のこと。ユーザーがサイトにアクセスしてから離
脱するまでの一連の行動をひとまとまりとして数えます。1人のユーザーが
1日に3回サイトを訪れた場合、アクティブユーザー数は「1」ですが、セ
ッション数は「3」になります。アクティブユーザー数よりも多くなりま
す。ユーザー一人当たりのセッション数が多すぎる場合は、ユーザーが目
的の情報にたどり着くまでに何度も訪問している(迷っている)可能性が
あります。
ページビュー数
サイト内の「ページが見られた合計回数」 のこと。1回のセッション内で
ユーザーが3つの記事を読んだ場合、セッション数は「1」ですが、ページ
ビュー数は「3」になります。セッション数よりも多くなります。ページビ
ュー数 / セッション数で、「1回の訪問で平均何ページ見られているか」
(PV/セッション)を確認し、この数値が高いほど、サイト内の記事間の回
遊がうまくいっていると言えます。
エンゲージメント率
ユーザーがサイトで「価値ある行動をしてくれた割合」 のこと。「10秒以
上 サイトに滞在したセッション」、「コンバージョン(目標達成)イベント
が発生したセッション」、「2ページ以上 のページビューがあったセッショ
ン」などを価値ある行動としています。「エンゲージメントがあったセッシ
ョン」を全セッションで割った割合です。サイトの目的によって異なりま
すが、一般的に30%〜60%を目安とすることが多いです。この数値が高い
ほど、サイトの内容が訪問者にとって有用であることを意味します。
それでは早速作成手順をご紹介します。Google スプレッドシートにバインドする形式で作成します。上記の4つの情報の解説をシートに記載しておくとよいと思います。
Google アナリティクス(GA4)週次レポート自動作成
1. 準備:必要な情報とファイルの準備
GA4 プロパティの数値
GA4 管理画面の「プロパティ詳細」で確認できる、プロパティID(9桁程度の数字)が必要です。

出力先のスプレッドシート
新規作成したスプレッドシートの URLの一部です。例: .../d/この部分/edit...
GAS スクリプトコード
本手順書の下部に記載されているコードをご用意ください。
2. 環境構築:APIの有効化とコードの貼り付け
その1: 出力先スプレッドシートの作成と GASの起動
レポートを出力したい場所に新しい Google スプレッドシートを作成します。
スプレッドシートのメニューから「拡張機能」>「Apps Script」を選択し、スクリプトエディタを起動します。
その2: Google Analytics Data API の有効化(最重要)
GAS がGA4 のデータにアクセスできるように許可を与えます。
スクリプトエディタの左側メニューにある「サービス」(🧭のようなアイコン)をクリックします。
画面下部の「サービスを追加」をクリックします。
サービスの一覧から「Google Analytics Data API」を探して選択し、「追加」ボタンをクリックします。
その3: コードの貼り付けと定数の設定
エディタに最初からある`コード.gs` ファイルの内容をすべて削除します。
以下のGAS スクリプトコード の内容をすべて貼り付けます。
// ====================================================================
// ユーザー設定項目 (ご自身の情報に修正してください)
// ====================================================================
// ⚠️ 以下の '123456789' の部分を、ご自身のGA4プロパティの数値IDに修正してください。
// 形式は 'properties/数値ID' です。
const PROPERTY_ID = 'properties/123456789';
// ⚠️ 以下の 'asdfghjkl' の部分を、ご自身のスプレッドシートIDに修正してください。
const SPREADSHEET_ID = 'asdfghjkl';
// ====================================================================
// メイン処理:毎週この関数を自動実行するようトリガーを設定します
// ====================================================================
function exportWeeklyReports() {
try {
const dateRange = getLastWeekDateRange();
Logger.log(`レポート期間: ${dateRange.startDate} から ${dateRange.endDate}`);
const ss = SpreadsheetApp.openById(SPREADSHEET_ID);
// レポート 1: 全体アクセス状況
const overallData = runOverallAccessReport(dateRange);
exportDataToSheet(ss, '全体アクセスレポート', overallData);
// レポート 2: 人気記事(Top 30)
const popularData = runPopularArticlesReport(dateRange);
exportDataToSheet(ss, '人気記事レポート', popularData);
Logger.log('週次レポートのエクスポートが完了しました。');
} catch (e) {
Logger.log(`エラーが発生しました: ${e.toString()}`);
}
}
// ====================================================================
// レポート取得関数
// ====================================================================
function runOverallAccessReport(dateRange) {
const request = {
dateRanges: [{ startDate: dateRange.startDate, endDate: dateRange.endDate }],
dimensions: [{ name: 'date' }],
metrics: [
{ name: 'activeUsers' },
{ name: 'sessions' },
{ name: 'screenPageViews' }
],
orderBys: [{ dimension: { dimensionName: 'date' } }]
};
const headers = ['日付', 'アクティブユーザー数', 'セッション数', 'ページビュー数'];
return fetchGA4Data(request, headers);
}
function runPopularArticlesReport(dateRange) {
const request = {
dateRanges: [{ startDate: dateRange.startDate, endDate: dateRange.endDate }],
dimensions: [{ name: 'pageTitle' }],
metrics: [
{ name: 'screenPageViews' },
{ name: 'sessions' },
{ name: 'engagementRate' }
],
orderBys: [{
metric: { metricName: 'screenPageViews' },
desc: true
}],
limit: 30, // 上位30件に制限
};
const headers = ['ページタイトル', 'ページビュー数', 'セッション数', 'エンゲージメント率'];
return fetchGA4Data(request, headers);
}
// ====================================================================
// 共通ユーティリティ関数
// ====================================================================
function fetchGA4Data(request, headerRow) {
const report = AnalyticsData.Properties.runReport(request, PROPERTY_ID);
const data = [];
if (report.rows) {
report.rows.forEach(row => {
const rowData = [];
row.dimensionValues.forEach(dim => {
rowData.push(dim.value);
});
row.metricValues.forEach(metric => {
const value = isNaN(metric.value) ? metric.value : parseFloat(metric.value);
rowData.push(value);
});
data.push(rowData);
});
}
data.unshift(headerRow);
return data;
}
function getLastWeekDateRange() {
const today = new Date();
const dayOfWeek = today.getDay();
const daysToPrevMonday = (dayOfWeek === 0 ? 6 : dayOfWeek - 1) + 7;
const startDate = new Date(today);
startDate.setDate(today.getDate() - daysToPrevMonday);
const endDate = new Date(startDate);
endDate.setDate(startDate.getDate() + 6);
const start = Utilities.formatDate(startDate, Session.getScriptTimeZone(), 'yyyy-MM-dd');
const end = Utilities.formatDate(endDate, Session.getScriptTimeZone(), 'yyyy-MM-dd');
return { startDate: start, endDate: end };
}
function exportDataToSheet(ss, sheetName, data) {
let sheet = ss.getSheetByName(sheetName);
if (!sheet) {
sheet = ss.insertSheet(sheetName);
}
// 既存コンテンツをクリア(書式もクリアされるはずだが、念のため明示的な書式設定を追加)
sheet.clearContents();
if (data.length > 1) {
sheet.getRange(1, 1, data.length, data[0].length).setValues(data);
// 修正: 「全体アクセスレポート」の数値列に標準の数値形式を適用
if (sheetName === '全体アクセスレポート') {
// 2列目から最終列まで(アクティブユーザー数、セッション数、ページビュー数)
const numCols = data[0].length - 1;
sheet.getRange(2, 2, data.length - 1, numCols).setNumberFormat('0'); // 標準の整数形式
}
// 「人気記事レポート」の時のみ、最終列(エンゲージメント率)にパーセント表示を適用
if (sheetName === '人気記事レポート') {
const lastCol = data[0].length;
sheet.getRange(2, lastCol, data.length - 1, 1).setNumberFormat('0.00%');
}
Logger.log(`Successfully wrote ${data.length - 1} rows to sheet: ${sheetName}`);
} else {
if (data.length > 0) {
sheet.getRange(1, 1, data.length, data[0].length).setValues(data);
}
sheet.getRange(2, 1).setValue('データが見つかりませんでした。');
Logger.log(`No data found for sheet: ${sheetName}`);
}
}
コードの先頭にある PROPERTY_ID と SPREADSHEET_ID の定数を、その1で確認したご自身の情報に必ず書き換えてください。
修正例: PROPERTY_ID は 'properties/123456789' (GA4の9桁の数値IDに修正)、SPREADSHEET_ID はご自身のIDです。
上部のフロッピーディスクのアイコン(💾)をクリックし、ファイルを保存します。
3.実行:権限承認と自動実行トリガーの設定
その1: 初回実行と権限の承認
エディタ上部の関数のドロップダウンが exportWeeklyReports になっていることを確認します。
右隣の「実行」(▶️アイコン)をクリックします。
【権限の承認】 ダイアログが表示されたら、以下の手順で許可を与えます。
「権限を確認」をクリックし、ご自身のGoogleアカウントを選択します。
「Googleが確認していないアプリ」と表示されても、「詳細」>「(プロジェクト名)に移動」をクリックして実行を許可します。
実行が完了すると、スプレッドシートに「全体アクセスレポート」と「人気記事レポート」の2つのシートが作成され、データが書き込まれます。

その2: 毎週の自動実行トリガーの設定
このスクリプトを毎週自動で実行するように設定します。
スクリプトエディタの左側メニューにある「トリガー」(時計のようなアイコン)をクリックします。
右下の「トリガーを追加」をクリックします。
設定画面で、以下の通り設定し、「保存」します。
実行する関数を選択: exportWeeklyReports
イベントのソースを選択: 時間主導型
時間ベースのトリガーのタイプを選択: 週ベースのタイマー
曜日を選択: 月曜日
時刻を選択: 午前 1 時〜2 時 (サーバーの負荷が低い深夜帯推奨)
以上です。Web解析の勉強を一時期していましたが、どうしても片手間になってしまい、詳しく理解できていないままです。しかし、何となくでも傾向さえ把握できていればなんとかなるものだと気づきました。Google アナリティクスのサイトでは色んな情報が入手できますが、私には情報が多すぎて、迷ってしまいます。4つの情報さえ定期的に確認できていれば、必要最低限の手は打てると感じています。私のように、大まかな傾向の把握でよろしければどうぞご利用ください。