113 lines
4.6 KiB
Markdown
113 lines
4.6 KiB
Markdown
# Google Analytics (GA4)
|
||
|
||
Proxy over the GA4 **Data API** (`analyticsdata.googleapis.com/v1beta`) and
|
||
**Admin API** (`analyticsadmin.googleapis.com/v1beta`).
|
||
|
||
## Credentials
|
||
|
||
Token has precedence over the service account:
|
||
|
||
| Header | Meaning |
|
||
| --- | --- |
|
||
| `X-GA-Access-Token` | Ready OAuth2 access token, used directly as `Authorization: Bearer`. |
|
||
| `Authorization` | Standard `Authorization: Bearer <token>` header — equivalent alternative to `X-GA-Access-Token`. |
|
||
| `X-GA-Credentials` | **Base64** of a Google service-account JSON key. The proxy mints a short-lived token (scope `https://www.googleapis.com/auth/analytics.readonly`) via `google-auth` and caches it in memory until ~60 s before expiry. |
|
||
| `X-GA-Quota-Project` | Optional GCP project id → upstream `x-goog-user-project`. |
|
||
|
||
A ready access token can be supplied either in `X-GA-Access-Token` or in the
|
||
standard `Authorization: Bearer <token>` header. At least one credential source
|
||
(token header, `Authorization: Bearer`, or `X-GA-Credentials`) is required,
|
||
otherwise `401 missing_credentials`. Priority when several are present:
|
||
`X-GA-Access-Token` → `Authorization: Bearer` → `X-GA-Credentials`.
|
||
|
||
The service account (or token) must have access to the GA4 property — add its
|
||
`client_email` as a viewer in GA Admin → Property Access Management.
|
||
|
||
> Encoding the key: `base64 -w0 service-account.json` (Linux) or
|
||
> `[Convert]::ToBase64String([IO.File]::ReadAllBytes("service-account.json"))`
|
||
> (PowerShell).
|
||
|
||
## Kde získat údaje (návod pro klienta)
|
||
|
||
**ID property** (`property_id` v URL): GA4 → **Administrace → Nastavení
|
||
property** → *ID property* (např. `123456789`).
|
||
|
||
**A) Service account – doporučeno (`X-GA-Credentials`)**
|
||
|
||
1. [Google Cloud Console](https://console.cloud.google.com/) → projekt.
|
||
2. **APIs & Services → Library** → povolit **Google Analytics Data API** a
|
||
**Google Analytics Admin API**.
|
||
3. **IAM & Admin → Service Accounts → Create service account**.
|
||
4. U účtu **Keys → Add key → JSON** → stáhne se klíč.
|
||
5. `client_email` z JSON přidat v GA4 **Administrace → Správa přístupu k
|
||
property** jako **Viewer**.
|
||
6. JSON zakódovat do base64 (viz výše) → hlavička `X-GA-Credentials`.
|
||
|
||
**B) Hotový OAuth2 token – rychlý test (`X-GA-Access-Token`)**
|
||
|
||
1. [OAuth 2.0 Playground](https://developers.google.com/oauthplayground/).
|
||
2. Scope `https://www.googleapis.com/auth/analytics.readonly` → **Authorize
|
||
APIs** (Google účet s přístupem k property).
|
||
3. **Exchange authorization code for tokens** → *Access token* → hlavička
|
||
`X-GA-Access-Token` (platí ~1 h).
|
||
|
||
## Data API endpoints
|
||
|
||
`property_id` may be the bare number (`123456789`) or `properties/123456789`.
|
||
|
||
| Method | Path | Upstream |
|
||
| --- | --- | --- |
|
||
| POST | `/ga/data/properties/{id}/runReport` | `:runReport` |
|
||
| POST | `/ga/data/properties/{id}/runPivotReport` | `:runPivotReport` |
|
||
| POST | `/ga/data/properties/{id}/batchRunReports` | `:batchRunReports` |
|
||
| POST | `/ga/data/properties/{id}/batchRunPivotReports` | `:batchRunPivotReports` |
|
||
| POST | `/ga/data/properties/{id}/runRealtimeReport` | `:runRealtimeReport` |
|
||
| POST | `/ga/data/properties/{id}/checkCompatibility` | `:checkCompatibility` |
|
||
| GET | `/ga/data/properties/{id}/metadata` | `/metadata` |
|
||
|
||
The POST body is the GA4 request object, forwarded unchanged. Example
|
||
`runReport` body:
|
||
|
||
```json
|
||
{
|
||
"dateRanges": [{ "startDate": "7daysAgo", "endDate": "today" }],
|
||
"dimensions": [{ "name": "country" }],
|
||
"metrics": [{ "name": "activeUsers" }]
|
||
}
|
||
```
|
||
|
||
## Admin API endpoints (read)
|
||
|
||
| Method | Path | Notes |
|
||
| --- | --- | --- |
|
||
| GET | `/ga/admin/accounts` | `pageSize`, `pageToken` |
|
||
| GET | `/ga/admin/accountSummaries` | accounts + their properties |
|
||
| GET | `/ga/admin/properties?accountId=123` | builds `filter=parent:accounts/123` |
|
||
| GET | `/ga/admin/properties/{id}` | single property |
|
||
| GET | `/ga/admin/properties/{id}/dataStreams` | data streams |
|
||
|
||
## Errors
|
||
|
||
`UpstreamError` is returned as JSON with the upstream status and body:
|
||
|
||
```json
|
||
{
|
||
"error": "upstream_error",
|
||
"status": 403,
|
||
"detail": "User does not have sufficient permissions for this property.",
|
||
"upstream_status": 403,
|
||
"upstream_body": { "error": { "code": 403, "status": "PERMISSION_DENIED" } }
|
||
}
|
||
```
|
||
|
||
Timeouts → `504`, unreachable/transport → `502`, token minting failure → `401`.
|
||
|
||
## curl example
|
||
|
||
```bash
|
||
curl -X POST "https://services.csbot.cz/apps/analytics/ga/data/properties/123456789/runReport" \
|
||
-H "X-GA-Access-Token: ya29...." \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"dateRanges":[{"startDate":"7daysAgo","endDate":"today"}],"metrics":[{"name":"activeUsers"}]}'
|
||
```
|