📊

GA4のデータをSpreadSheetに出力する

2022/11/26に公開約4,200字

はじめに

GA(4)は便利だけど、データをいろいろな条件でフィルターしようとすると結構早い段階で限界が来るのでローデータで吐いてSpreadSheetで条件かけてフィルタしたり集計したりしたくなった(特にアプリの解析)。

概要

GA4のAPI叩いてデータを出力してやる。

どうやる

前提:GA4をGCPのPJと紐づけておき、IAMで適切な権限を与えておく

  1. SpreadSheetを新規で作成
  2. 作成したSpreadSheetで「拡張機能」からApps Scriptを選択し、Editorを起動する
  3. 「プロジェクトの設定」からGCPプロジェクトのプロジェクト番号を設定しておく。(これをやっておかないとAPIをたたいた時に権限がなくて怒られる)
  4. 必要なパラメータを控える「ここ」にアクセスして右側のカラムに表示されるPropertyの値をコピーする。
  5. エディタからファイルの追加、スクリプトを選択しファイルの編集を行う。
function getEventData() {
  // アクティブなスプレッドシートからrunReportの出力結果を格納するシートを読み込み
  // 前もってeventというシートを作っておく
  let mySheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("event");
  mySheet.clear();

  // 3の手順で控えた文字列を設定する
  let properties = 'properites/xxxxxxxxx'
  // runReportのURLを定義
  let apiURL = 'https://analyticsdata.googleapis.com/v1beta/' + properties + ':runReport';

  // POSTする際に必要となるディメンションやメトリクスを以下を参考に設定する。
  // https://developers.google.com/analytics/devguides/reporting/data/v1/api-schema?hl=en
  // カスタムイベントは定義名の前に'customeEvent:'を付与、カスタムユーザパラメータは'customUser:'を付与する必要がある。
  let setDimension = [
    {
      "name": "eventName"
    },
    {
      "name": "appVersion"
    },
    {
      "name": "platform"
    },
    {
      "name": "firstSessionDate"
    }
    ];

  let setMetrics = [
    {
      "name": "totalUsers"
    },
    {
      "name": "eventCount"
    }];

  // フィルターの設定は以下を参照。
  // https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport
  // AndとかOrとかありますが、イベントの名前でフィルタする場合は以下の***をフィルタしたいイベントに置き換えます
  let dimensionFilter = {
    "andGroup": {
      "expressions": [
        {"orGroup":{"expressions": [{
          "filter": {
            "fieldName": "eventName",
            "stringFilter": {
              "value": "***"
            }
          }
        }]}},
        {"orGroup":{"expressions": [{
          "filter": {
            "fieldName": "platform",
            "stringFilter": {
              "value": "Android"
            }
          }
        },
        {
          "filter": {
            "fieldName": "platform",
            "stringFilter": {
              "value": "iOS"
            }
          }
        }]}}
      ]}};
  const dimensionsCount = setDimension.length;
  const metricsCount = setMetrics.length;

  // 集計対象にする期間を設定する
  const startDate = '2022-11-01;
  const endDate = '2022-11-30';
  const setDateRange = {
    'startDate': startDate,
    'endDate': endDate;
  console.log('FirstOpen: ' + 'from ' + setDateRange.startDate + ', to ' + setDateRange.endDate);


  // APIリクエスト時にセットするペイロード値を定義
  const payload = {
    'dimensions' : setDimension,
    'metrics': setMetrics,
    'dateRanges': setDateRange,
    'dimensionFilter': dimensionFilter
  };

  // オプションパラメータを設定する。APIの認証のため、headersの情報も必須
  const options = {
    'payload' : JSON.stringify(payload),
    'myamethod' : 'POST',
    'muteHttpExceptions' : true,
    'headers' : {"Authorization" : "Bearer " + ScriptApp.getOAuthToken()},
    'contentType' : 'application/json'
  };

  // レスポンスのJSONデータを変換する
  const response = UrlFetchApp.fetch(apiURL,options);
  const json = JSON.parse(response);

  for(let i=0 ; i<dimensionsCount; i++){
    mySheet.getRange(1, 1 + i).setValue(setDimension[i].name);
  }
  for(let i=0; i<metricsCount; i++){
    mySheet.getRange(1, i + dimensionsCount + 1).setValue(setMetrics[i].name);
  }
  for(let i=0;i<json["rows"].length;i++){
    for(let j=0; j<dimensionsCount; j++){
      mySheet.getRange(i + 2, j + 1).setValue(json["rows"][i]["dimensionValues"][j]["value"]);
    }
    for(let j=0; j<metricsCount; j++){
      mySheet.getRange(i + 2, j + dimensionsCount + 1).setValue(json["rows"][i]["metricValues"][j]["value"]);
    }
  }
  SpreadsheetApp.flush();
}

どうなる?

こうなります。

それで?

このローデータをアプリのバージョンごとに絞ったり、最初の接続日で絞ったり、プラットフォームで絞ったりして集計すると、グラフ化したり定点観測したりするのに便利。

ほかには?

GA4のAPIには1万行の制限があり、それを超えるデータは出力されないので気を付けないとなんか数字低いなぁと思ったら出てないだけ、みたいなことが起きちゃいます。
後は出力する行によって集計される粒度が変わってくるので、その辺は意識しておかないといけないです。
UAからGA4に移行すると、データが保持される期間も最大14か月になってしまうこともあるのでデータを残しておくのにも便利かなと思います。

さいごに

自分が最低限わかるくらいの雑なまとめなので気が向けば補記します。

Discussion

ログインするとコメントできます