Peti-dev
API & Hardware Dev Notes
記事一覧に戻る
GA4 API

GA4 Data API: batchRunReports で複数レポートを1回のリクエストで一括取得する

GA4 Data API の batchRunReports メソッドを徹底解読。1回のリクエストで異なる集計軸や期間のレポートを最大5件までまとめて取得する実装と注意点を解説します。

GA4Google AnalyticsbatchRunReportsNode.jsAPITypeScript
動作検証・実行環境
Node.jsv22.x
TypeScriptv5.x
@google-analytics/datav4.11.0
Google AnalyticsData API v1beta
認証方式サービスアカウント (JSON)

概要・目的

GA4 Data API(v1beta)には、単一のレポートを取得する runReport のほかに、複数のレポートをまとめて取得できる batchRunReports メソッドが用意されています。

ダッシュボードや社内ツールなどで「日別の推移データ」と「流入元の内訳データ」を同時に表示したい場合、runReport を2回呼ぶよりも batchRunReports で一度に取得する方が、ネットワーク往復のレイテンシを削減し、APIの実行効率を大幅に高めることができます。

この記事では、batchRunReports の具体的な実装コードから、返却されるレスポンスの構造解読、押さえておくべき制限事項までを丁寧に解説します。


runReport と batchRunReports の違い

項目 runReport batchRunReports
取得できるレポート数 1リクエストにつき 1件 1リクエストにつき 最大5件
HTTPリクエスト回数 レポートごとに1回 1回で完了
主なユースケース 単一のグラフや数値を更新したいとき 複数のグラフ・表を同時に描画するダッシュボード画面など
リクエスト構造 直下に dimensions や metrics を指定 requests 配列の中に個別のレポート定義を格納

前提条件・準備

1. ライブラリのインストール

公式の @google-analytics/data を使用します。

npm install @google-analytics/data

2. サービスアカウントの設定

GCPコンソールでサービスアカウントを発行し、GA4の管理画面(「プロパティのアクセス管理」)でサービスアカウントのメールアドレスに「閲覧者」以上の権限を付与しておきます。


実装コード (TypeScript)

以下の例では、1回のリクエストで以下の2つの異なるレポートを同時に取得しています。

  1. レポート1: 直近7日間の日別推移(日付、アクティブユーザー数、セッション数、ページビュー数)
  2. レポート2: 直近7日間のデバイスカテゴリ別内訳(deviceCategory、セッション数)
import { BetaAnalyticsDataClient } from '@google-analytics/data';

// クライアントの初期化(環境変数 GOOGLE_APPLICATION_CREDENTIALS を参照)
const analyticsDataClient = new BetaAnalyticsDataClient();

interface ReportOptions {
  propertyId: string;
}

async function fetchMultipleReports({ propertyId }: ReportOptions) {
  try {
    const [response] = await analyticsDataClient.batchRunReports({
      // プロパティIDは必ず "properties/数値" の形式
      property: `properties/${propertyId}`,
      requests: [
        // レポート1: 日別の推移データ
        {
          dateRanges: [{ startDate: '7daysAgo', endDate: 'today' }],
          dimensions: [{ name: 'date' }],
          metrics: [
            { name: 'activeUsers' },
            { name: 'sessions' },
            { name: 'screenPageViews' },
          ],
          orderBys: [
            {
              dimension: { dimensionName: 'date' },
              desc: false,
            },
          ],
        },
        // レポート2: デバイスカテゴリ別の割合
        {
          dateRanges: [{ startDate: '7daysAgo', endDate: 'today' }],
          dimensions: [{ name: 'deviceCategory' }],
          metrics: [{ name: 'sessions' }],
          orderBys: [
            {
              metric: { metricName: 'sessions' },
              desc: true,
            },
          ],
        },
      ],
    });

    console.log('=== batchRunReports 取得成功 ===\n');

    // response.reports にリクエスト順と同じ並びで結果が格納される
    const reports = response.reports || [];

    // --- レポート1 の処理 ---
    console.log('【1. 日別推移レポート】');
    reports[0]?.rows?.forEach((row) => {
      const date = row.dimensionValues?.[0]?.value;
      const users = row.metricValues?.[0]?.value;
      const sessions = row.metricValues?.[1]?.value;
      const pv = row.metricValues?.[2]?.value;
      console.log(`日付: ${date} | ユーザー: ${users} | セッション: ${sessions} | PV: ${pv}`);
    });

    console.log('\n----------------------------------------\n');

    // --- レポート2 の処理 ---
    console.log('【2. デバイス別セッションレポート】');
    reports[1]?.rows?.forEach((row) => {
      const device = row.dimensionValues?.[0]?.value;
      const sessions = row.metricValues?.[0]?.value;
      console.log(`デバイス: ${device?.padEnd(10)} | セッション数: ${sessions}`);
    });

  } catch (error) {
    console.error('API呼び出し中にエラーが発生しました:', error);
  }
}

// 実行(プロパティIDはご自身のGA4プロパティIDに置き換えてください)
fetchMultipleReports({ propertyId: '123456789' });

実行結果 / レスポンスの解読

コンソール出力例

=== batchRunReports 取得成功 ===

【1. 日別推移レポート】
日付: 20260914 | ユーザー: 142 | セッション: 168 | PV: 345
日付: 20260915 | ユーザー: 189 | セッション: 210 | PV: 412
日付: 20260916 | ユーザー: 165 | セッション: 198 | PV: 380
日付: 20260917 | ユーザー: 204 | セッション: 235 | PV: 490
日付: 20260918 | ユーザー: 178 | セッション: 195 | PV: 360
日付: 20260919 | ユーザー: 130 | セッション: 142 | PV: 290
日付: 20260920 | ユーザー: 155 | セッション: 170 | PV: 320

----------------------------------------

【2. デバイス別セッションレポート】
デバイス: mobile     | セッション数: 840
デバイス: desktop    | セッション数: 438
デバイス: tablet     | セッション数: 30

レスポンスJSON構造のポイント

返却されるオブジェクトの最上位には reports 配列が入っています。

  • response.reports[0] : 1つ目のリクエストに対する RunReportResponse
  • response.reports[1] : 2つ目のリクエストに対する RunReportResponse

各要素の内部構造(dimensionHeaders, metricHeaders, rows, rowCount 等)は、通常の runReport の戻り値と完全に同一です。そのため、既存の runReport 用のパース関数をそのまま流用できます。


ハマりどころ・注意点(仕様上の制約)

1. 同時にリクエストできるのは「最大5件」まで

requests 配列に格納できるレポート定義は 最大5個 です。6個以上渡すと 400 Bad Request(requests array cannot contain more than 5 requests)エラーが発生します。 5件を超えるレポートが必要な場合は、リクエストを5件単位で分割(チャンク化)して送信してください。

2. 複数のプロパティをまたぐことはできない

property パラメータは batchRunReports のリクエスト最上位で指定します。そのため、「プロパティAのデータとプロパティBのデータを1つのバッチで取得する」といったことはできません。すべてのレポートは同一のGA4プロパティに対するクエリである必要があります。

3. いずれか1件でも構文エラーがあると全体が失敗する

requests 内のどれか1つでも存在しないメトリクス名(例: active_users などのタイポ)や無効なディメンションを指定していると、他の正常なレポートも含めてリクエスト全体がエラー(400)になります。「有効なものだけ部分的に返る」という挙動にはならないため注意してください。

4. クオータ(APIトークン制限)の消費について

batchRunReports を使っても、GA4 API のトークン消費(Core Tokens)が1回分に割引されるわけではありません。消費されるトークンは、バッチ内に含まれる各レポートの計算コストの合算となります。 ただし、接続確立のオーバーヘッドやHTTPラウンドトリップが削減されるため、レスポンス速度とネットワーク効率の面で大きなメリットがあります。


参考リンク