---
name: gsc_list_sites
kind: function
lang: py
domain: infra
version: "1.0.0"
purity: impure
signature: "def gsc_list_sites(credentials_path: str = \"\") -> list"
description: "Lista las propiedades de Google Search Console a las que tiene acceso una cuenta de servicio. Verificacion de acceso del capability group seo: tras dar de alta la service account y anadir su email como usuario en Search Console, esta funcion confirma que el acceso funciona y muestra que site_url usar y con que nivel de permiso. Autentica con gsc_auth del registry (que resuelve credentials_path o, si esta vacio, la env var GSC_SA_JSON) y llama a service.sites().list().execute(). Aplana la respuesta {siteEntry: [...]} a una lista de dicts [{site_url, permission_level}, ...]. Devuelve lista vacia (sin lanzar) si la cuenta no tiene propiedades accesibles. Requiere google-api-python-client y google-auth."
tags: [seo, gsc, search-console, infra]
uses_functions: [gsc_auth_py_infra]
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [infra.gsc_auth]
params:
  - name: credentials_path
    desc: "ruta al JSON de la service account de GCP. Si esta vacio, se delega en gsc_auth, que lo lee de la env var GSC_SA_JSON. El JSON es un secreto: resolver desde pass o una ruta fuera del repo, nunca commitear."
output: "list. Lista de dicts [{\"site_url\": <siteUrl>, \"permission_level\": <permissionLevel>}, ...] con una entrada por propiedad de Search Console accesible. site_url de dominio sale como 'sc-domain:ejemplo.com' y el de prefijo como URL completa 'https://ejemplo.com/'. permission_level es uno de siteOwner / siteFullUser / siteRestrictedUser / siteUnverifiedUser. Lista vacia si la SA no tiene propiedades accesibles (no lanza)."
tested: true
tests:
  - "test_aplana_siteurl_y_permissionlevel"
  - "test_site_entry_ausente_devuelve_lista_vacia"
test_file_path: "python/functions/infra/gsc_list_sites_test.py"
file_path: "python/functions/infra/gsc_list_sites.py"
---

## Ejemplo

```python
import sys
sys.path.insert(0, "python/functions")
from infra import gsc_list_sites

# Opcion A: ruta explicita al JSON de la service account
sites = gsc_list_sites(credentials_path="/home/enmanuel/secrets/gsc-sa.json")

# Opcion B: leer la ruta de la env var GSC_SA_JSON
#   export GSC_SA_JSON=/home/enmanuel/secrets/gsc-sa.json
sites = gsc_list_sites()

for s in sites:
    print(s["site_url"], "->", s["permission_level"])
# sc-domain:ejemplo.com -> siteOwner
# El site_url que imprime es exactamente el valor que va en GSC_SITE_URL
# al configurar el pipeline de ingesta.
```

Lanzable directo (lee `GSC_SA_JSON` del entorno):

```bash
export GSC_SA_JSON=/home/enmanuel/secrets/gsc-sa.json
./fn run gsc_list_sites
```

## Cuando usarla

Primer paso tras dar acceso a la service account en Search Console (anadir su
email en Settings > Users and permissions): la usas para verificar que el
acceso funciona y descubrir el `site_url` exacto antes de configurar el
pipeline de ingesta. El valor de `site_url` que devuelve es el que pones en
`GSC_SITE_URL` / pasas a `pull_gsc_search_analytics`.

## Gotchas

- **Impura**: autentica contra Google y hace una llamada HTTP a la Search
  Console API. No es determinista ni componible en el nucleo puro.
- **Lista vacia = falta acceso**: si devuelve `[]`, el email de la service
  account no esta anadido como usuario en Search Console (Settings > Users and
  permissions) o la propiedad no existe. La auth puede funcionar igualmente; lo
  que falta es el alta de la SA como usuario de la propiedad.
- **Formato del site_url**: la propiedad de dominio sale como
  `sc-domain:ejemplo.com` y la de prefijo como la URL completa
  `https://ejemplo.com/`. Copia el valor tal cual al configurar el pipeline.
- **API habilitada**: la "Search Console API" debe estar habilitada en el
  proyecto GCP de la service account, o el `.execute()` falla.
- **El JSON de la SA es un secreto**: nunca commitear. Guardar en `pass` o en
  una ruta fuera del repo y pasar la ruta por `credentials_path` o la env var
  `GSC_SA_JSON`.
- **Dependencias**: requiere `google-api-python-client` y `google-auth` en el
  venv (ya en `python/pyproject.toml`).

## Capability growth log

(sin cambios — v1.0.0 inicial)
