アクセス解析担当者がGTMについて語るブログ

GTM(Google Tag Manager)・GA(Google Analytics)の中~上級者向け情報を中心に発信

Windows PowerShellでGoogle Analytics Data APIを実行する

Windows PowerShellでgcloud cliを使いつつGoogle Analytics Data APIを実行するにあたり、認証周りで失敗が多かったために備忘録。

最終的にはInvoke-RestMethodでリクエスト送信しているのでgcloud cli要素はToken取得関連のみ。

1. gcloud 側の準備

プロジェクト設定

gcloud init だと対話的でちょっと楽かも。

gcloud config set project $YOUR_GCP_PROJECT_ID

Data API を有効化。Google Cloudの管理画面からでも作業はできる

gcloud services enable analyticsdata.googleapis.com

2. 認証まわり

ユーザーADCでログイン(スコープ必須)

サービスアカウントでもよかったのだけれど、今回はADCでログイン。scopesを複数の場合はダブルクォートでくくる必要があった。

gcloud auth application-default revoke
gcloud auth application-default login --scopes="https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/analytics.readonly"

quota project を紐付け(明示しておくと安心)

gcloud auth application-default set-quota-project $YOUR_GCP_PROJECT_ID

トークン取得。ここではscopesの指定不要。

$Token = gcloud auth application-default print-access-token

3. トークンの検証

$TokenInfo = Invoke-RestMethod "https://oauth2.googleapis.com/tokeninfo?access_token=$Token"
"--- Token Scopes ---"
$TokenInfo.scope
"--- Token Email ---"
$TokenInfo.email
"--- Token Expires In (sec) ---"
$TokenInfo.expires_in

期待値:scope に
   https://www.googleapis.com/auth/cloud-platform
   https://www.googleapis.com/auth/analytics.readonly
が含まれていること。

email は空でも問題ない。

4. API 呼び出し例

ヘッダー作成

ProjectId, Content-Type を必ず付与。

$ProjectId = gcloud config get-value project
$Headers = @{
  "Authorization"      = "Bearer $Token"
  "Content-Type"       = "application/json"
  "x-goog-user-project"= $ProjectId
}

metadata でテスト

プロパティIDはGA管理画面から取得可能。URLからも推測できる。

$PropertyId = "YOUR_GA4_PROPERTY_ID"
$MetaUrl = "https://analyticsdata.googleapis.com/v1beta/properties/$PropertyId/metadata"
Invoke-RestMethod -Method Get -Uri $MetaUrl -Headers $Headers

runReport(例:国別 Active Users)

$Url = "https://analyticsdata.googleapis.com/v1beta/properties/$PropertyId`:runReport"
$BodyObj = @{
  dateRanges = @(@{ startDate = "2025-01-01"; endDate = "2025-02-01" })
  dimensions = @(@{ name = "country" })
  metrics    = @(@{ name = "activeUsers" })
}
$BodyJson = $BodyObj | ConvertTo-Json -Depth 5

$resp = Invoke-RestMethod -Method Post -Uri $Url -Headers $Headers -Body $BodyJson

# 結果整形
$rows = $resp.rows | ForEach-Object {
  [pscustomobject]@{
    country     = $_.dimensionValues[0].value
    activeUsers = [int]$_.metricValues[0].value
  }
}
$rows | Format-Table -AutoSize

こちらで成功しました。

引っ掛かりポイントはHeaderの作り方と、login時のscopeの指定。

ChatGPTに壁打ちしながらだと英語が怖くなくなったり、孤独感が消えてよいという知見がありました。