GA4 の Analytics Data API を使ってみた

ウェブ分析をしてる人だと、そろそろ Google Analytics について UA から GA4 に変える必要があると思っている人もたくさんいると思います。

切り替える必要があるのですが、懸念の一つに Google Spreadsheet への書き出しをどうするかという点がありました。今までは、Google 純正の拡張機能で UA の数値を取り込んでいました。

現時点(2023/5/2)では、Google からは https://developers.google.com/analytics/solutions/google-analytics-spreadsheet-add-on?hl=ja の代替になるようなアドオンは作られていません。一方で、https://developers.google.com/apps-script/advanced/analyticsdata?hl=ja にAPI だけは提供されています。さらに、GAS で GA4 のデータを取得するサンプルプログラムも提供されています。そちらをサンプルをベースに GA4 で UA のアドオンになるような機能を作りました。

※ 普段 GAS も JS も触っていないので、文法的には怪しい箇所が多数あります。自己責任でご参照ください。

実行方法

以下の内容を記入します。2行目の SHEET_ID に出力するスプレッドシートの ID に変更してください。

function main() {
  const SHEET_ID = "hoge"; // 出力するスプレッドシートの ID を入力してください。
  const REPORT_CONFIG_SHEET = "ReportConfig";  // 出力したい内容を記載したシート名
  const spreadsheet = SpreadsheetApp.openById(SHEET_ID);
  const configs = getConfig(spreadsheet, REPORT_CONFIG_SHEET); 
  for (let i =0; i < configs.length; i++){
    getData(spreadsheet, configs[i]);
  }
}

function getConfig(spreadsheet, reportConfigSheet) {
  try {
    const sheet = spreadsheet.getSheetByName(reportConfigSheet);
    const lastRow = sheet.getLastRow();
    let rowNum = 2;
    let params = [];
    while (rowNum <= lastRow) {
      const range = sheet.getRange(Utilities.formatString("A%s:F%s", rowNum, rowNum));
      let values = range.getValues();
      const startDateType =  Object.prototype.toString.call(values[0][2]);
      const endDateType =  Object.prototype.toString.call(values[0][3]);
      if (startDateType == "[object Date]") {
        values[0][2] = Utilities.formatDate(values[0][2], 'JST', 'yyyy-MM-dd');
      }
      if (endDateType == "[object Date]") {
        values[0][3] = Utilities.formatDate(values[0][3], 'JST', 'yyyy-MM-dd');
      }
      params.push({
        "propertyId": values[0][0],
        "sheetName": values[0][1],
        "startDate": values[0][2],
        "endDate": values[0][3],
        "metric": values[0][4],
        "dimension": values[0][5],
      });
      rowNum ++;
    }
    return params;
  } catch(e) {
    console.log('Failed reading parameters with error: %s', e.error);
  }
}

function getData(spreadsheet, config) {
  try {
    const metric = AnalyticsData.newMetric();
    metric.name = config.metric;

    const dimension = AnalyticsData.newDimension();
    dimension.name = config.dimension;

    const dateRange = AnalyticsData.newDateRange();
    dateRange.startDate = config.startDate;
    dateRange.endDate = config.endDate;

    const request = AnalyticsData.newRunReportRequest();
    request.dimensions = [dimension];
    request.metrics = [metric];
    request.dateRanges = dateRange;

    const report = AnalyticsData.Properties.runReport(request,
        'properties/' + config.propertyId);
    if (!report.rows) {
      console.log('No rows returned.');
      return;
    }

    const sheets = spreadsheet.getSheets();
    var existFlg = 0;
    for (let i = 0; i < sheets.length; i++) {
      if (config.sheetName == sheets[i].getName()) {
        existFlg = 1;
      } 
    }
    if (existFlg == 0) {
      spreadsheet.insertSheet(config.sheetName);
    }

    const sheet = spreadsheet.getSheetByName(config.sheetName);
    sheet.clear();

    // Append the headers.
    const dimensionHeaders = report.dimensionHeaders.map(
        (dimensionHeader) => {
          return dimensionHeader.name;
        });
    const metricHeaders = report.metricHeaders.map(
        (metricHeader) => {
          return metricHeader.name;
        });
    const headers = [...dimensionHeaders, ...metricHeaders];

    sheet.appendRow(headers);

    // Append the results.
    const rows = report.rows.map((row) => {
      const dimensionValues = row.dimensionValues.map(
          (dimensionValue) => {
            return dimensionValue.value;
          });
      const metricValues = row.metricValues.map(
          (metricValues) => {
            return metricValues.value;
          });
      return [...dimensionValues, ...metricValues];
    });

    sheet.getRange(2, 1, report.rows.length, headers.length)
        .setValues(rows);

    console.log('Report spreadsheet created: %s',
        spreadsheet.getUrl());
  } catch (e) {
    // TODO (Developer) - Handle exception
    console.log('Failed with error: %s', e.error);
  }
}

前提として、

  • API の使用許可をとります。

  • Sheet を作成して、ReportConfig という名前のシートを作成します。

シートには以下の項目の順番にセットします。

ReportConfig シート例
  • PropertyID: GA4 の値を取得する property ID

  • SheetName: 出力先のシート名

  • StartDate: データを取得する開始日

  • EndData: データを取得する終了日

  • Metric: 取得したい指標

  • Dimension: 取得したい次元

あとは実行するだけです。


今後の課題

今回、サンプルのプログラムをそのまま再現することに重点を置きました。いくつか課題も残っていて、

  • Dimension を複数入力する

  • Metric も複数入力する

  • ソートもかけられるようにする

  • フィルタもかけられるようにする。

あたりが必要です。特に Dimension と フィルタがないと思った通りのデータが出ないので、急いで作らないといけないなと思ってます。コンバージョンのデータとか結構めんどくさそう。

資料

Google の アナリティクスデータ API の解説資料

API Dimensions & Metrics > Dimensions 

Dimension に指定できる指標一覧。日本語翻訳されてるページにデフォルトで飛ばされるので注意

API Dimensions & Metrics > Metrics

同じURL内の指標一覧

この記事が気に入ったらサポートをしてみませんか?