GA4のデータを自動的にスプレッドシートに連携するスクリプト
業務効率化公開日:2023年11月13日 更新日:2024年8月29日
マーケティングに従事する方の殆どは、毎日のように数値の変化をレポートで確認していると思います。(確認してほしい)
しかし様々なツールや広告媒体を使っていると、そのデータの整理・処理に膨大な時間を使うことは少なくありません。
今回は多くの企業で導入されているデジタルマーケティングツールの一つ、Google Analytics4(以下GA4)のデータを、プラグインなしで定期的にスプレッドシートに連携する方法を、非エンジニアの方にも分かりやすく紹介します。
目次
GA4のデータを連携する下準備
Apps Scriptの設定
まず、GA4のデータをエクスポートしたいスプレッドシートを作成します。
作成後、スプレッドシートのメニュー「拡張機能」からApps Scriptを選択します。
そうすると「無題のプロジェクト」というページに遷移するので、左メニューの「サービス」にある「+」ボタンをクリックします。
次に、Google Analytics4と接続するためのサービスを追加します。
少しスクロールすると「Google Analytics Data API」というものが出てくるので、こちらを選択し「追加」ボタンを押します。
連携する情報の取得
次に基本的な設定として、以下の3つを用意します。
- GA4のプロパティID
- スプレッドシートのID
- スプレッドシートのシート名
まずGA4のプロパティIDは、GA4の管理 > プロパティ > プロパティの詳細から確認することができます。
次にスプレッドシートのIDは、スプレッドシートのURLの以下の部分です。
最後にシート名は、スプレッドシートの画面下部にある自由に設定できるシート名のことを指しています。
デフォルトでは「シート1」となっていますが、今回は「raw」という名前に変更しました。
Apps Scriptに記述するコード
基本的な設定
まずはじめに、下準備で取得した情報を記述します。
function runGaReport() {
// Setting
const propertyId = '*********';
const wb = SpreadsheetApp.openById('*********');
const ws = wb.getSheetByName('*********'');
const propertyIdには、GA4のプロパティIDを、
const wbには、スプレッドシートのIDを、
const wsには、スプレッドシートのシート名を入力します。
また今回はrunGaReport()という関数名にしています。関数については、こちらのレッスンで紹介しています。
指標とディメンションの設定
次に、取得したい指標とディメンションを設定します。
Data APIへのリクエストはJSON形式で行われます。
JSONについて説明していると脱線してしまうので、指標やディメンションをJSON形式で簡単に設定できる関数を用意しました。
とりあえず何も考えずに以下のコードを追加してください。
// Create Metric & Dimension
function createMetric(name) {
const metric = AnalyticsData.newMetric();
metric.name = name;
return metric;
}
function createDimension(name) {
const dimension = AnalyticsData.newDimension();
dimension.name = name;
return dimension;
}
このコードの下に、取得したい指標やディメンションを設定していきます。
[]内に、クオーテーションで指標やディメンション名を囲い、カンマ区切りで指定します。
// Setup Metric & Dimension
const metrics = ['sessions', 'activeUsers', 'engagedSessions'].map(createMetric);
const dimensions = ['date', 'sessionSource'].map(createDimension);
GA4のUI上の指標・ディメンションとの対応は、公式ページの「APIのディメンションと指標」で一覧を確認できます。
今回はセッション数、アクティブユーザー数、エンゲージのあったセッション数を、日付・セッションのソース別に取得します。
データ期間の設定
次に、データの取得期間を設定します。
// Setup Data Range
const dateRange = AnalyticsData.newDateRange();
dateRange.startDate = '2023-01-01';
dateRange.endDate = 'yesterday';
startDateで集計開始日を、endDateで集計終了日を指定します。
日付を直接指定したい場合はYYYY-MM-DD形式(例:2023-01-01)で記入します。
またこの例では「yesterday」と指定していますが、「today」や「NdaysAgo」という指定をすることもできます。
フィルターの設定
最後にフィルターの設定をします。
複数フィルター設定することもできますが、JSONを理解していないとやや難しいので、また別の記事で紹介したいと思います。
フィルターのコードは以下です。
// Setup Filter
const filterExpression = AnalyticsData.newFilterExpression();
filterExpression.filter = AnalyticsData.newFilter();
filterExpression.filter.fieldName = 'sessionMedium';
filterExpression.filter.stringFilter = AnalyticsData.newStringFilter();
filterExpression.filter.stringFilter.value = 'cpc';
filterExpression.filter.stringFilter.matchType = 'EXACT';
const dimensionFilter = AnalyticsData.newFilterExpression();
dimensionFilter.andGroup = AnalyticsData.newFilterExpressionList();
dimensionFilter.andGroup.expressions = [filterExpression];
注目すべきポイントは以下の3点です。
- filterExpression.filter.fieldName
- filterExpression.filter.stringFilter.value
- filterExpression.filter.stringFilter.matchType
fieldNameでは、フィルターしたい指標・ディメンションを設定します。
今回はsessionMedium(セッションのメディア)でフィルターをかけます。
そしてstringFilter.valueには、どんなフィルターをかけたいかを設定します。
今回は広告経由のセッションなどを取得したいので「cpc」と設定します。
最後に、stringFilter.matchTypeでフィルターの一致条件を指定します。
使用できるマッチタイプは、こちらのページで確認ができます。
注意点は、含まない・一致しないなどの設定は、また別のやり方で指定をしなければなりません。
複雑なマッチタイプの指定方法は以下の記事で紹介しているので、ぜひ参考にしてみてください。
エラーが発生したら
残りのコードは、これまで設定してきた情報を元に、Data APIにリクエストを出し、指定したスプレッドシート・シート名にデータを出力するだけなので詳細な解説はしません。
コードの全文は非常に長いので、この記事の最後で紹介します。
もしエラーが発生した場合、以下の点を確認してみましょう。
- 設定したプロパティIDやシートID、シート名は間違っていないか
- 指標やディメンションの設定方法に間違いはないか
- その他、誤字脱字などないか
それでもエラーが解決されない場合は、お気軽にお問い合わせください。
データ取得を実行・自動化する
データ取得を実行する
では実際にコードを動かしてみます。
Apps Scriptの上部メニューの「実行」ボタンを押します。
そうすると、以下のようなポップアップが表示されます。
これは、Apps Scriptにスプレッドシートや外部ツールへのアクセス権限を付与するためのものです。
「権限を確認」ボタンを押して次に進みます。
そうすると、アカウントの情報や、どんな外部ツールにアクセスするのかが表示されるので、問題なければ「許可」ボタンを押します。
これで実行がされるはずです。
定期的にレポートを取得する
このコードを定期実行するためにはApps Scriptの「トリガー」という機能を使います。
左メニューの「トリガー」を選択し、「トリガーを追加」ボタンを押します。
すると、このような設定画面が出てきます。
毎日実行する場合は、「イベントのソース」を「時間主導型」に設定し、「日付ベースのタイマー」を設定します。
時刻では実行したい時間を選択しましょう。
毎日確認するのであれば、その確認する時間の前の時刻を指定しましょう。
この状態で、保存ボタンを押せば、毎日指定した時刻にレポートが出力されるようになります。
コードの全文
最後に、今回紹介したコードの全文です。
細かく説明をしたプロパティIDやシートID、指標やディメンションなどは、コード上部にあるので、必要に応じて変更して使ってください。
function runGaReport() {
// Setting
const propertyId = '*********';
const wb = SpreadsheetApp.openById('*********');
const ws = wb.getSheetByName('*********'');
// Create Metric & Dimension
function createMetric(name) {
const metric = AnalyticsData.newMetric();
metric.name = name;
return metric;
}
function createDimension(name) {
const dimension = AnalyticsData.newDimension();
dimension.name = name;
return dimension;
}
// Setup Metric & Dimension
const metrics = ['sessions', 'activeUsers', 'engagedSessions'].map(createMetric);
const dimensions = ['date', 'sessionSource'].map(createDimension);
// Setup Data Range
const dateRange = AnalyticsData.newDateRange();
dateRange.startDate = '2023-01-01';
dateRange.endDate = 'yesterday';
// Setup Filter
const filterExpression = AnalyticsData.newFilterExpression();
filterExpression.filter = AnalyticsData.newFilter();
filterExpression.filter.fieldName = 'sessionMedium';
filterExpression.filter.stringFilter = AnalyticsData.newStringFilter();
filterExpression.filter.stringFilter.value = 'organic';
filterExpression.filter.stringFilter.matchType = 'EXACT';
const dimensionFilter = AnalyticsData.newFilterExpression();
dimensionFilter.andGroup = AnalyticsData.newFilterExpressionList();
dimensionFilter.andGroup.expressions = [filterExpression];
// Run Report
const request = AnalyticsData.newRunReportRequest();
request.dimensions = dimensions;
request.metrics = metrics;
request.dateRanges = [dateRange];
request.dimensionFilter = dimensionFilter;
try {
const report = AnalyticsData.Properties.runReport(request, `properties/${propertyId}`);
if (!report.rows) {
console.log('No rows returned.');
return;
}
//ws clear
ws.clear();
// Process headers
const dimensionHeaders = report.dimensionHeaders.map(header => header.name);
const metricHeaders = report.metricHeaders.map(header => header.name);
const headers = [...dimensionHeaders, ...metricHeaders];
ws.appendRow(headers);
// Process and append rows
const rows = report.rows.map(row => {
const dimensionValues = row.dimensionValues.map(value => {
if (/^\d{8}$/.test(value.value)) {
return `${value.value.substring(0, 4)}/${value.value.substring(4, 6)}/${value.value.substring(6, 8)}`;
}
return value.value;
});
const metricValues = row.metricValues.map(value => value.value);
return [...dimensionValues, ...metricValues]; // プロパティIDを含めない
});
ws.getRange(2, 1, rows.length, headers.length).setValues(rows);
console.log('Report Updated!');
} catch (e) {
console.log('Failed with error: %s', e.error);
}
}