Files
feadulta/docs/analytics/ga4-setup.md
rafa 39256c0f9b GA4: traer el script de informes al repo bueno y filtrar por hostName
ga4_report.py vivia solo en el checkout separado feadulta-git, que apunta al Gitea
archivado y cuyo historial no tiene relacion con este repo. La copia canonica pasa a
estar aqui. El entorno de ejecucion (.venv/ y .secrets/ con el cliente OAuth y el token)
se queda en feadulta-git y nunca ha estado versionado -- por eso la doc sigue usando
rutas absolutas alli.

Ademas, el filtro que faltaba: la propiedad G-6RT9ZRS4LW recoge varios hostnames a la vez
-- el WordPress vivo (www.feadulta.com) y el archivo estatico del Joomla
(antiguo.feadulta.com, que lleva el mismo tag dentro del HTML capturado), mas restos
(wp-nuevo, bar). Cualquier informe sin filtro los sumaba en una cifra sin significado.

- preset "hosts": desglose de trafico por hostName.
- --host: filtro exacto, lista separada por comas, se combina con --page-path-regex en un
  andGroup.
- --host-not: negacion.

Refs #180, #187

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 15:05:50 -04:00

7.6 KiB

GA4 API setup for feadulta

This document describes the simplest practical path for querying Google Analytics 4 from this repo.

Where the code lives vs where it runs (2026-07-31). This script used to live only in the separate feadulta-git checkout, which points at the archived Gitea and never made it into this repo. The canonical copy is now here, in rafa/feadulta on gitea.feadulta.com. The runtime environment stays in /mnt/c/Users/Chia/feadulta-git: .venv/ and, above all, .secrets/ (OAuth client + cached token) are gitignored and were never versioned anywhere. That is why the commands below still use absolute paths into feadulta-git — the paths are correct, the code is just no longer only there.

Current known identifier

The site is tagged with GA4 measurement ID:

  • G-6RT9ZRS4LW

Important:

  • the GA4 measurement ID (G-...) is not the same as the GA4 property ID
  • the Data API runReport endpoint needs the property ID
  • the script added in this repo can resolve the property automatically if the authenticated Google user has access to the property

Official references:

Use OAuth desktop app credentials for a Google user that already has access to the GA4 property.

Why this is the easiest first step:

  • no need to create a service account and grant property access separately
  • no need to know the property ID upfront
  • the script can authenticate as you and search the accessible properties for the matching G-...

One-time Google Cloud setup

  1. Open Google Cloud Console.
  2. Create or reuse a project.
  3. Enable:
    • Google Analytics Data API
    • Google Analytics Admin API
  4. Create an OAuth client of type Desktop app.
  5. Download the client secrets JSON file.

Suggested local path:

  • /mnt/c/Users/Chia/feadulta-git/.secrets/ga4-oauth-client.json

Do not commit it.

Local Python environment

This repo is set up to use a local virtualenv so the host Python installation does not need to be modified.

Create it once:

python3 -m venv /mnt/c/Users/Chia/feadulta-git/.venv

Install the required packages inside that environment:

/mnt/c/Users/Chia/feadulta-git/.venv/bin/python -m pip install google-auth google-auth-oauthlib requests

Environment variables

You can configure the script with environment variables:

export GA4_CLIENT_SECRETS_PATH=/mnt/c/Users/Chia/feadulta-git/.secrets/ga4-oauth-client.json
export GA4_TOKEN_PATH=/mnt/c/Users/Chia/feadulta-git/.secrets/ga4-token.json
export GA4_MEASUREMENT_ID=G-6RT9ZRS4LW
export GA4_PROPERTY_ID=508378818

If GA4_PROPERTY_ID is omitted, the script can try to resolve it from GA4_MEASUREMENT_ID.

First run

Authenticate and resolve the property:

/mnt/c/Users/Chia/feadulta-git/.venv/bin/python scripts/ga4_report.py --measurement-id G-6RT9ZRS4LW resolve-property

If the local environment cannot open a browser directly, use manual mode:

/mnt/c/Users/Chia/feadulta-git/.venv/bin/python scripts/ga4_report.py --measurement-id G-6RT9ZRS4LW --no-browser resolve-property

This prints a Google authorization URL. Open it in the browser, sign in with a Google user that has access to the GA4 property, and complete the redirect back to the localhost callback URL shown in the command output.

On successful first run, the script stores a reusable token locally at:

  • /mnt/c/Users/Chia/feadulta-git/.secrets/ga4-token.json

Current known resolved property:

  • measurement ID: G-6RT9ZRS4LW
  • property ID: 508378818
  • property name: https://feadulta.com
  • account name: Portal feadulta.com
  • stream name: https://www.feadulta.com/

Example reports

Traffic overview:

/mnt/c/Users/Chia/feadulta-git/.venv/bin/python scripts/ga4_report.py --property-id 508378818 report --preset traffic --days 28

Top content:

/mnt/c/Users/Chia/feadulta-git/.venv/bin/python scripts/ga4_report.py --property-id 508378818 report --preset content --days 28 --limit 25

Landing pages:

/mnt/c/Users/Chia/feadulta-git/.venv/bin/python scripts/ga4_report.py --property-id 508378818 report --preset landing-pages --days 28 --limit 25

Traffic by source / medium:

/mnt/c/Users/Chia/feadulta-git/.venv/bin/python scripts/ga4_report.py --property-id 508378818 report --preset source-medium --days 28 --limit 25

Device mix:

/mnt/c/Users/Chia/feadulta-git/.venv/bin/python scripts/ga4_report.py --property-id 508378818 report --preset device --days 28 --limit 25

Export to CSV:

/mnt/c/Users/Chia/feadulta-git/.venv/bin/python scripts/ga4_report.py --property-id 508378818 report --preset content --days 28 --csv /tmp/ga4-content.csv

Splitting the live site from the static archive (--host)

This single property (G-6RT9ZRS4LW) collects several hostnames at once: the live WordPress (www.feadulta.com), the frozen Joomla archive (antiguo.feadulta.com, which carries the same GA tag inside its captured HTML), plus leftovers like wp-nuevo.feadulta.com. Any report without a host filter mixes them and means nothing.

Which hostnames are actually reporting:

/mnt/c/Users/Chia/feadulta-git/.venv/bin/python scripts/ga4_report.py --property-id 508378818 report --preset hosts --days 28

Only the live site:

/mnt/c/Users/Chia/feadulta-git/.venv/bin/python scripts/ga4_report.py --property-id 508378818 report --preset content --host www.feadulta.com --days 28 --limit 25

Only the archive:

/mnt/c/Users/Chia/feadulta-git/.venv/bin/python scripts/ga4_report.py --property-id 508378818 report --preset content --host antiguo.feadulta.com --days 28 --limit 25

--host takes a comma-separated list (exact match, case-insensitive) and combines with --page-path-regex as an AND group. --host-not negates it.

Practical future access

For future use, the shortest path is:

  1. Confirm these files still exist locally:
    • /mnt/c/Users/Chia/feadulta-git/.secrets/ga4-oauth-client.json
    • /mnt/c/Users/Chia/feadulta-git/.secrets/ga4-token.json
    • /mnt/c/Users/Chia/feadulta-git/.venv/
  2. Run reports directly with --property-id 508378818.
  3. Only rerun resolve-property if the token was deleted or the Google access changed.
  4. If the token expires, the script should refresh it automatically when possible.

About WordPress logs

If the question is “what content is being seen?”, GA4 is usually the better first tool because it gives:

  • page-level views
  • landing pages
  • traffic sources
  • device mix
  • trends over time

WordPress itself does not log page views by default in a way that is useful for editorial analysis.

If GA4 turns out to be incomplete or unreliable, the next fallback is usually:

  1. web server access logs
  2. reverse proxy logs
  3. plugin-specific event logging if the site has a dedicated analytics plugin

In this repo, there is no obvious WordPress analytics plugin configuration under wordpress/wp-content/mu-plugins/, so GA4 or server logs are the most likely useful sources.

Useful questions this script should answer

  • Which pages got the most views in the last 28 days?
  • Which landing pages attract the most traffic?
  • Which sources or source/medium pairs bring traffic?
  • Is mobile traffic increasing or decreasing?
  • Did traffic fall because fewer users arrived, or because fewer pages were viewed per session?