📑

GoでGoogle Analytics Data API(GA4)からデータを取得する

2023/04/07に公開

Analytics Data APIからデータを取得してみます。

データ取得に用いるコードを用意してみました。

https://github.com/hirokisan/ga4data

サンプルコードを手元で動かすため、GCP上でサービスアカウントを用意して、credential.jsonを取得しておきます。

ref: https://developers.google.com/analytics/devguides/reporting/data/v1/quickstart-client-libraries

GA4の管理画面で利用するプロパティを確認します。

e.g. properties/yourPropertyID

その際、作成したサービスアカウントのメールアドレスにプロパティへのアクセス権限を付与します。

データ取得用のコードは下記の通りです。

package main

import (
	"context"
	"errors"
	"fmt"
	"log"
	"os"

	"github.com/hirokisan/ga4data"
	analyticsdata "google.golang.org/api/analyticsdata/v1beta"
	"google.golang.org/api/option"
)

func main() {
	if err := run(); err != nil {
		log.Fatal(err)
	}
}

func run() error {
	ctx := context.Background()

	propertyID, ok := os.LookupEnv("PROPERTY_ID")
	if !ok {
		return errors.New("PROPERTY_ID needed as environment variable")
	}
	credentialPath, ok := os.LookupEnv("CREDENTIAL_PATH")
	if !ok {
		return errors.New("CREDENTIAL_PATH needed as environment variable")
	}

	service, err := analyticsdata.NewService(ctx, option.WithCredentialsFile(credentialPath))
	if err != nil {
		return err
	}

	dimensions := []string{ga4data.DimensionDate}
	metrics := []string{ga4data.MetricSessions}
	response, err := ga4data.RunReport(ctx, service, propertyID, ga4data.CreateRunReportRequest(
		analyticsdata.DateRange{
			StartDate: "2022-10-01",
			EndDate:   "2022-10-01",
		},
		ga4data.RunReportRequestWithDimensions(dimensions),
		ga4data.RunReportRequestWithMetricAggregations([]string{"MINIMUM", "MAXIMUM"}),
		ga4data.RunReportRequestWithMetrics(metrics),
		ga4data.RunReportRequestWithPropertyQuota(),
	))
	if err != nil {
		return err
	}

	printResponse(response)

	return nil
}

func printResponse(response *ga4data.RunReportResponse) {
	fmt.Println("==== dimensionHeaders ====")
	for _, header := range response.DimensionHeaders {
		fmt.Println(header.Name)
	}

	fmt.Println("==== metricHeaders ====")
	for _, header := range response.MetricHeaders {
		fmt.Println(header.Name)
	}

	fmt.Println("==== propertyQuota ====")
	fmt.Printf("concurrentRequests: consumed %d, remaining %d\n",
		response.PropertyQuota.ConcurrentRequests.Consumed,
		response.PropertyQuota.ConcurrentRequests.Remaining,
	)
	fmt.Printf("potentiallyThresholdedRequestsPerHour: consumed %d, remaining %d\n",
		response.PropertyQuota.PotentiallyThresholdedRequestsPerHour.Consumed,
		response.PropertyQuota.PotentiallyThresholdedRequestsPerHour.Remaining,
	)
	fmt.Printf("serverErrorsPerProjectPerHour: consumed %d, remaining %d\n",
		response.PropertyQuota.ServerErrorsPerProjectPerHour.Consumed,
		response.PropertyQuota.ServerErrorsPerProjectPerHour.Remaining,
	)
	fmt.Printf("tokensPerDay: consumed %d, remaining %d\n",
		response.PropertyQuota.TokensPerDay.Consumed,
		response.PropertyQuota.TokensPerDay.Remaining,
	)
	fmt.Printf("tokensPerHour: consumed %d, remaining %d\n",
		response.PropertyQuota.TokensPerHour.Consumed,
		response.PropertyQuota.TokensPerHour.Remaining,
	)
	fmt.Printf("tokensPerProjectPerHour: consumed %d, remaining %d\n",
		response.PropertyQuota.TokensPerProjectPerHour.Consumed,
		response.PropertyQuota.TokensPerProjectPerHour.Remaining,
	)

	fmt.Println("==== rowCount ====")
	fmt.Println(response.RowCount)

	fmt.Println("==== rows ====")
	for _, row := range response.Rows {
		var dimensions []string
		for _, dim := range row.DimensionValues {
			dimensions = append(dimensions, dim.Value)
		}
		var metrics []string
		for _, met := range row.MetricValues {
			metrics = append(metrics, met.Value)
		}
		fmt.Printf("dimensions: %s, metrics: %s \n", dimensions, metrics)
	}
}

それでは実行してみます。

$ PROPERTY_ID="properties/yourPropertyID" # yourPropertyIDを設定してください
$ CREDENTIAL_PATH="./credential.json" # main.goと同じ階層に置いているものと考えます
$ PROPERTY_ID=${PROPERTY_ID} CREDENTIAL_PATH=${CREDENTIAL_PATH} go run main.go

==== dimensionHeaders ====
date
==== metricHeaders ====
sessions
==== propertyQuota ====
concurrentRequests: consumed 0, remaining 10
potentiallyThresholdedRequestsPerHour: consumed 0, remaining 120
serverErrorsPerProjectPerHour: consumed 0, remaining 10
tokensPerDay: consumed 1, remaining 24999
tokensPerHour: consumed 1, remaining 4999
tokensPerProjectPerHour: consumed 1, remaining 1749
==== rowCount ====
1
==== rows ====
dimensions: [20221001], metrics: [3]

データを取得できました。


(雑談)

最近、quotaの消費token数が1になっているのが気になるところです。

少し前(2023年1月から3月くらい)までは大きなサイトで複雑なリクエストを投げると50程度消費していたのですが、最近は1になっているため気になっています。

GA4側でquota周りで変更が入るのか、バグなのか。何かご存知の方がいればこっそり教えていただけると幸いです。

一応質問投げています。

https://stackoverflow.com/questions/75883442/why-is-the-token-consumption-per-request-in-google-analytics-data-api-set-to-1

追記.

どうやら2023/04/09あたりに解消したようです。

追記(2023-05-09).

先ほど確認したら、API Quota上限が緩和されているようでした。

Core Tokens Per Project Per Property Per Hour

以前は1250だったのが14000になった感じ。

ref: https://developers.google.com/analytics/devguides/reporting/data/v1/quotas

変更後

変更前

Discussion