この記事の目的
GA4 から Google Apps Script (以下、GAS) で Google Analytics Data API を利用してデータを取得し、スプレッドシートに結果を保存します。
なお、この記事を書いている、2023年10月30日現在、Google Analytics Data API のバージョンは、「v1beta」となっていますので、このバージョンに対応した内容の記事となっております。
GASは、Googleのサービスを自動化するためのJavaScriptベースのスクリプト言語です。標準の JavaScript と GAS にはいくつかの違いがあります。以下はその主な違いです。
組み込みAPI: GASには、Googleのサービス(例: Google スプレッドシート、Gmail、Googleドキュメント、Googleカレンダーなど)と直接連携するための組み込みAPIが用意されています。これにより、ユーザーはこれらのサービスを効果的に操作・自動化するスクリプトを容易に書くことができます。
実行環境: GASはブラウザやローカルの環境では実行されず、Googleのクラウド上で実行されます。このため、サーバーサイドの処理を行うことができます。
認証とアクセス制御: GASには組み込みの認証機能があり、Googleのサービスへのアクセス権限を簡単に取得・管理することができます。また、Apps ScriptはOAuth2を内部で取り扱っているため、手間なくセキュアなアクセスが可能です。
バージョン: JavaScriptには多数のバージョンやフレームワークが存在しますが、GASは特定のバージョンのJavaScriptをベースにしており、最新のJavaScript機能の全てがサポートされているわけではありません。
IDE: GASは、Googleが提供するオンラインの統合開発環境 (IDE)、Apps Scriptエディタで編集・実行することができます。このエディタはクラウドベースで、直接ブラウザ上でコードの編集やデバッグが行えます。
トリガーと自動実行: GASにはトリガー機能が組み込まれており、特定の時間やイベントに応じてスクリプトを自動的に実行することができます。(設定方法は後述。)
制限とクォータ: GASには利用制限やクォータが設けられており、1日のメール送信数や同時実行回数など、特定の操作に対する上限が存在します。
GASはJavaScriptベースであるものの、その機能や制限、使用方法には独自の特性が多数含まれています。
GA4にて、管理 > プロパティ設定 > 右上の ID をコピー
新規にスプレッドシートを作成します。
GAS エディタを起動します。
拡張機能 > Apps Script
GAS で Google Analytics Data API を利用できるようにします。
サービスの+ > Google Analytics Data API を選択 > 追加
GA4 から取得したデータをスプレッドシートに書き込むのは、どのようなデータを取得する場合も同じなので、メソッド化して呼び出せるようにしておきます。
「メソッド化」という言葉は、プログラミングの中でよく使われる概念で、特定の処理をまとめて、名前を付けて再利用できるようにすることを意味します。
「メソッド化」について、簡単に解説します。
関数とメソッドの違い
関数:一連の処理をまとめて名前をつけたもので、その名前を使っていつでもその処理を呼び出せるようにしたもの。
メソッド:オブジェクト指向プログラミングの文脈で使われる「関数」のようなもの。特定のクラスやオブジェクトに紐づく関数を指します。
メソッド化のメリット
再利用性:同じ処理を何度も書かなくて済む。
保守性:メソッドの中身を変更すれば、それを呼び出しているすべての場所での挙動が変わるので、修正が簡単。
可読性:メソッドには意味のある名前を付けることができるので、コードが読みやすくなる。
コード.gs を CommonMethods.gs にリネームし(名前は自由に決められます)、下記のGitHubのコードをコピー&ペーストします。
https://github.com/nakata1967/GAS/blob/main/CommonMethods.gs
この時、「GA4のプロパティID」は、上記で確認した GA4 ID に書き換えます。
const GA4_PROPERTY_ID = "プロパティIDを入れてください";
後は、必要なデータを取得して、このメソッドに渡せば、スプレッドシートに結果が保存されます。
GAS はファイル順にコードがグローバル定義されていることになるので、共通メソッドのファイルはファイルリストの中で一番上に来るようにしておきます。
「グローバル定義」とは、プログラムのどこからでもアクセスできるように変数や関数を定義することを指します。具体的には、特定の関数やクラスの中だけでなく、全体で使えるようにするための定義方法です。
例えば、GASでは、スクリプトファイルの順序が実行順序に影響します。そのため、共通で使うメソッドや変数を持つファイルは、他のファイルからもアクセスできるように、ファイルリストの一番上に配置することが推奨されています。これにより、他のファイルがその共通メソッドや変数を使用する際に、エラーが発生することを防ぐことができます。
簡単に言えば、「グローバル定義」とは、全体で使いたいものを最初に定義しておくことで、どこからでも使えるようにする方法のことを指します。GASでのファイルの配置のように、この順序や位置が重要になる場合があります。
このコードには、GAのデータをシートに書き込むための共通の関数が含まれています。
// GA4のプロパティIDの設定
const GA4_PROPERTY_ID = "プロパティIDを入れてください";
上記の部分は、GA4のプロパティIDを定義する部分です。このIDは、GA4からデータを取得する際に必要となります。
/**
* 指定されたシートにGAの結果を書き込む関数
*/
function writeReportToSheet(sheet, report) {
// ...
}
writeReportToSheet
関数は、取得したGAのデータを指定されたシートに書き込むためのものです。具体的には、まずシートの既存のデータをクリアし、次に取得したレポートのヘッダーとデータ部分をシートに書き込む処理が行われます。
データを取得する,、ごく一般的なコードは、下記のGitHubのコードのようになります。
https://github.com/nakata1967/GAS/blob/main/StoreData.gs
このファイルでは、GA4からデータを取得し、それをスプレッドシートに書き込む主要な処理が行われています。
/**
* GA4からデータを取得し、特定のシートに書き込む関数
*/
function fetchAndStoreGA4Data() {
// ...
}
fetchAndStoreGA4Data
関数は、GA4からデータを取得し、それをスプレッドシートに書き込む主要な処理を行います。この関数内では、まず書き込むシートの取得、次に取得するデータの指標やディメンションの設定、そしてデータの取得期間を設定します。この設定を元にAPIリクエストを作成し、GA4からデータを取得。取得したデータは、先述の writeReportToSheet
関数を使用してシートに書き込まれます。
必要なデータのディメンション名、指標名を name に入れます。
ディメンション名、指標名は、
https://developers.google.com/analytics/devguides/reporting/data/v1/api-schema
で探します。
複数指定したい場合は、リクエストパラメータに設定する際に配列内に追加します。
今回ご紹介しているコードの例では、4つのディメンションを指定しています。うち、後半の2つはカスタム ディメンションを指定しています。
const dimensions = [
{ name: "pagePath" },
{ name: "eventName" },
{ name: "customEvent:select_key" },
{ name: "customEvent:select_value" }
];
カスタム ディメンション
Data API では、イベント スコープとユーザー スコープのカスタム ディメンションに関するレポートを作成できます。カスタム ディメンションについて詳しくは、イベント スコープのカスタム ディメンションとカスタム指標のレポートとカスタム ユーザー プロパティをご覧ください。API レポート リクエストでは、カスタム ディメンションはディメンションのパラメータ名とスコープで指定します。 たとえば、Data API リクエストに「customEvent:achievement_id」を追加して、パラメータ名「achievement_id」のイベント スコープのカスタム ディメンションのレポートを作成します。 プロパティでこのイベント スコープのカスタム ディメンションが登録されていない場合、この API リクエストは失敗します。
出所:https://developers.google.com/analytics/devguides/reporting/data/v1/api-schema?hl=jp
フィルタに関するAPIの公式ドキュメントはこちらですが、筆者が読んだ限り、欲しい情報が載っていません。
https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/FilterExpression
フィルタ付のコードの例は、下記のGitHubのコードのようになります。
https://github.com/nakata1967/GAS/blob/main/StoreDataAddFilter.gs
andGroup、orGroup により、それぞれ And 条件、 Or 条件を指定できます。
上記のコードの例では、下記にあるように、andGroupを使用しています。
// 除外ページを設定
const dimensionFilter1 = AnalyticsData.newFilterExpression();
const notExpression = AnalyticsData.newFilterExpression();
const notPagePathFilter = AnalyticsData.newFilter();
notPagePathFilter.fieldName = "pagePath";
const notPagePathStringFilter = AnalyticsData.newStringFilter();
notPagePathStringFilter.matchType = "FULL_REGEXP";
notPagePathStringFilter.value = "^(\\/shop/aaa|\\/shop/bbb).*";
notPagePathFilter.stringFilter = notPagePathStringFilter;
notExpression.filter = notPagePathFilter;
dimensionFilter1.notExpression = notExpression;
// 端末種類でフィルタ
const dimensionFilter2 = AnalyticsData.newFilterExpression();
const deviceFilter = AnalyticsData.newFilter();
deviceFilter.fieldName = "deviceCategory";
const deviceStringFilter = AnalyticsData.newStringFilter();
deviceStringFilter.matchType = "EXACT";
deviceStringFilter.value = "Mobile";
deviceFilter.stringFilter = deviceStringFilter;
dimensionFilter2.filter = deviceFilter;
// 複数フィルタを And で指定
const dimensionFilters = AnalyticsData.newFilterExpressionList();
dimensionFilters.expressions = [dimensionFilter1, dimensionFilter2];
const dimensionFilter = AnalyticsData.newFilterExpression();
dimensionFilter.andGroup = dimensionFilters;
上記のコード内の下記の1行について解説します。
notPagePathStringFilter.value = "^(\\/shop/aaa|\\/shop/bbb).*";
このコード行の中の notPagePathStringFilter.value = "^(\\/shop/aaa|\\/shop/bbb).*";
は、正規表現を使用して特定の文字列を持つページパスをフィルタリングする条件を定義しています。
具体的には、この正規表現は以下の意味を持ちます:
^
: 文字列の先頭を意味します。
(\\/shop/aaa|\\/shop/bbb)
: この部分は、文字列が /shop/aaa
または shop/bbb
で始まることを示しています。
.*
: この部分は、任意の文字(.
)が0回以上(*
)続くことを示しています。
したがって、この正規表現全体は、URLのパス部分が /shop/aaa
または /shop/bbb
で始まるページをフィルタリングするためのものです。
例えば、以下のURLはこのフィルタにマッチします:
/shop/bbb/skirt
/shop/bbb/tops
このフィルタは、特定のページを除外するためのものとして機能します。
【FAQ】(\\/shop/aaa|\\/shop/bbb)
: この部分は、文字列が /shop/aaa
または /shop/bbb
で始まることを示しています。 上記で「\\/
」の部分はどんな意味ですか?
このコードの \\/
の部分は、文字列リテラル内でスラッシュ /
を表現するためのエスケープです。通常、正規表現内でスラッシュ /
は特別な意味を持たないため、エスケープする必要はありません。しかし、JavaScriptでは、正規表現リテラルはスラッシュ /
で囲まれるため、文字列としての正規表現内でスラッシュを使用する場合にはエスケープが必要となります。
JavaScriptの文字列リテラル内で特殊な意味を持つ文字をそのままの意味で使用する場合、バックスラッシュ \
を使用してエスケープする必要があります。しかし、文字列内でバックスラッシュ自体を表現するには、それ自体もエスケープする必要があります。そのため、文字列リテラル内でスラッシュ /
を表現するには、\\/
と2つのバックスラッシュを使用します。
このエスケープは、正規表現のリテラルとしてではなく、文字列としての正規表現を表現するために必要です。したがって、\\/
は文字列内での /
を意味します。
GA4のデータを取得するGASを最初に実行する時は、承認が必要になります。
毎日朝8時-9時の間に実行、といったかたちで、定期実行を設定することができます。
GA4の前日分の集計は、朝8時の段階では、まだ終わっていない可能性があります。
朝の時間帯にレポートを更新したい場合は、今回取り上げたコードの様に、集計期間の終了日を、前日ではなく、2日前にしておくことをおすすめします。
左メニューのトリガー > トリガーを追加 をクリック。
時間主導型、日付ベースのタイマーをセットすると、毎日同じ時間に実行します。
設定が出来ている状態です。
実行されると、前回実行された時刻が、秒まで記録されます。
また、何らかの理由でエラーが発生している場合は、右端の「エラー率」の列が0%よりも大きな値になります。
今回の記事はここまでとなります。最後まで読んで頂き、ありがとうございました。
GA4のデータ取得のためのGASについてのご質問は、弊社の無料・匿名、GA4専門コミュニティまでお願いいたします。
こちらからアクセスできます。