Descripción general: qué hace
Junto a la cifra de visitantes únicos de cada tarjeta de Servicio ▸ Web hay dos iconos, y cada uno abre una ventana modal.
| Icono | Ventana | Fuente |
|---|---|---|
| Persona | Análisis de visitantes | Google Analytics 4 (Analytics Data API) |
| Lupa | Tráfico de búsqueda | Google Search Console (Search Analytics API) |
Mientras que la información de acceso de nginx_meta_ct de la tarjeta le dice qué recibió su servidor, estas dos ventanas le dicen de dónde vinieron los visitantes y qué términos de búsqueda los trajeron: información que sus registros de servidor sencillamente no contienen.
Lo que hace Site Kit en WordPress es, en el fondo, construir por usted las peticiones de informe. En Laravel las construye usted mismo y obtiene cifras idénticas, así que aquí no se usa ni un plugin ni
google/apiclient: todo el trabajo consiste en «firmar un JWT con la clave privada y canjearlo por un token de acceso», y el servidor lo firma de forma nativa. Arrastrar un árbol de dependencias enorme para llegar a dos endpoints REST es un mal negocio.
Cuándo utilizarlo
- El tráfico ha subido en una tarjeta y quiere saber qué canal y qué fuente lo han producido.
- Quiere las palabras clave de búsqueda que generan impresiones y clics, y a qué página llega cada palabra clave.
- Quiere ver de un vistazo la composición de la audiencia: proporción de visitantes nuevos, reparto por dispositivo, origen del tráfico.
- Está siguiendo impresiones, clics y posición media después de publicar contenido.
Disposición
Ambas ventanas se dividen en las pestañas Resumen / Palabras clave / Tráfico (la pestaña de palabras clave solo existe en la ventana de búsqueda), de modo que se cambia de pestaña en lugar de desplazarse. El selector de periodo ofrece 7 / 28 / 90 días, el mismo conjunto que el servidor incluye en su lista blanca.
Análisis de visitantes (GA4)
- Seis KPI: visitantes, visitantes nuevos, sesiones, páginas vistas, tasa de interacción y sesión media, cada uno con su variación respecto al periodo inmediatamente anterior.
- Tres franjas de composición: fidelidad de los visitantes (nuevos/recurrentes), reparto por dispositivo (escritorio frente a móvil y tableta) y origen del tráfico (búsqueda frente a otros). Las tres son divisiones en dos partes, así que comparten un mismo lenguaje visual y, como los KPI ya llevan las cifras absolutas, aquí se muestra solo la proporción.
- Gráfico de evolución: visitantes, sesiones y páginas vistas.
- Seis paneles (pestaña de tráfico): canales, fuentes, ciudades, países, dispositivos y páginas más vistas.
Canal y fuente no son lo mismo. El canal es la respuesta agrupada (
Organic Search); la fuente es la concreta (naver,github.com). En los sitios coreanos, sobre todo, naver frente a google es la diferencia entre dos historias de captación completamente distintas.
Tráfico de búsqueda (Search Console)
- Cinco KPI: clics, impresiones, CTR, posición media y número de palabras clave.
- Nube de palabras: el tamaño y el color codifican las impresiones, un ● marca las palabras clave que produjeron clics reales y las cifras son las impresiones
~1d / ~7d / all. - Tabla de palabras clave: clics, impresiones, CTR y posición.
- Página de entrada × consulta: despliegue una página para ver las palabras clave por las que se entró en ella.
- Tres paneles: páginas de entrada, países y dispositivos.
La posición media está ponderada por impresiones. Una media simple permite que una impresión en el puesto 1 compense diez mil en el puesto 40, lo que embellece la cifra de forma grave.
Cómo configurarlo
1. Cree una cuenta de servicio (Google Cloud)
- Google Cloud Console → elija o cree un proyecto → IAM y administración ▸ Cuentas de servicio → Crear cuenta de servicio. No hace falta ningún rol a nivel de proyecto.
- Abra la cuenta → Claves → Agregar clave ▸ Crear clave nueva ▸ JSON → descargue el archivo.
- En APIs y servicios ▸ Biblioteca, habilite Google Analytics Data API y Google Search Console API.
2. Regístrela en InfraGuard
En Servicio ▸ Web ▸ Gestionar sitios web ▸ pestaña de edición del sitio, bajo Integración con Google:
| Campo | Valor | Dónde encontrarlo |
|---|---|---|
| ID de propiedad de GA4 | solo dígitos (p. ej. 550688232) |
Administrador de GA4 ▸ Detalles de la propiedad, o la URL #/a<account>p<property>/: la parte posterior a p |
| Propiedad de Search Console | sc-domain:example.com o https://example.com/ |
exactamente la cadena que muestra el selector de propiedades de Search Console |
| JSON de la cuenta de servicio | pegue el archivo descargado entero | — |
El ID de propiedad de GA4 no es el ID de cuenta. En
#/a405285491p550688232/, la parte posterior aaes la cuenta y la parte posterior apes la propiedad. Google no distingue deliberadamente entre «no existe esa propiedad» y «no tiene permiso» (la existencia de una propiedad es en sí misma información), de modo que un número equivocado tiene exactamente el aspecto de un problema de permisos. Compruebe primero el ID de propiedad.
Nunca deduzca la propiedad de Search Console a partir del dominio. Solo quien verificó la propiedad sabe si es una propiedad de dominio (
sc-domain:) o un prefijo de URL (https://…/), y elegir mal devuelve un resultado vacío en lugar de un error.
3. Invite a la cuenta de servicio a cada propiedad
El JSON es solo una identidad; el acceso se concede por propiedad. Copie el client_email que aparece tras guardar y, a continuación:
| Propiedad | Dónde | Rol |
|---|---|---|
| GA4 | Administrador ▸ Gestión de acceso a la propiedad ▸ + |
Lector |
| Search Console | Configuración ▸ Usuarios y permisos ▸ Añadir usuario | Completo |
En GA4 se trata de la gestión de acceso a la propiedad, no de la gestión de acceso a la cuenta (la columna izquierda es la cuenta y la del medio, la propiedad). En Search Console debe ser Completo, no Restringido: la Search Analytics API rechaza a los usuarios restringidos. Las cuentas de servicio no tienen buzón, así que desmarque la casilla de «notificar por correo electrónico».
4. Pruebe la conexión
[Probar conexión] en la ventana de gestión consulta ambas APIs una vez (últimos 7 días) con la credencial guardada e informa de cada parte por separado.
| Estado | Significado |
|---|---|
ok |
Google ha respondido. Cero filas sigue siendo ok: un sitio nuevo y el retraso de GSC no son errores |
fail |
La redacción del propio Google, más el client_email al que invitar |
skip |
No hay ninguna propiedad configurada, así que se ha omitido (no es un fallo) |
Sin credencial alguna no llama a nada (cero peticiones salientes). Los cambios sin guardar no se prueban: guarde primero.
Reglas de exactitud: por qué las cifras se construyen así
Siguen las trampas que Site Kit ya ha demostrado, todas ellas basadas en evidencias.
| Regla | Motivo |
|---|---|
| La ventana termina ayer | Hoy está agregado solo en parte, así que incluirlo hace que el borde derecho se hunda siempre |
GA4 lee totals[0] de metricAggregations:['TOTAL'] |
Sumar filas que llevan un limit deja la cifra principal por debajo de lo real |
Un filtro de lista hostName en cada petición a GA4 |
Una misma propiedad abarca a menudo varios hosts, así que sin él la tarjeta muestra todo el tráfico de la propiedad. Enviamos todos los dominios que posee el servicio (principal, adicionales, www) para coincidir exactamente con la agregación vts de la tarjeta |
Las clasificaciones usan keepEmptyRows:false + notExpression{emptyFilter} |
El (not set) de GA4 supera habitualmente a ciudades y fuentes reales |
Las series temporales usan keepEmptyRows:true |
Un día sin tráfico no debe desaparecer del eje |
GSC usa dataState:'all' más un retraso de ~2 días |
Sin ello los días más recientes se leen como cero, lo que parece un desplome del tráfico |
Las propiedades de dominio se acotan con page contains |
sc-domain: abarca todos los subdominios, así que se cuelan palabras clave de sitios hermanos |
Fuentes de datos
| Objetivo | Conexión / ubicación | Función |
|---|---|---|
infr_web_service.ga4_property_id · gsc_site_url |
default (000771) | asignación de propiedad por sitio |
infr_web_service.google_cred_enc · google_cred_email |
default (000772) | cuenta de servicio por sitio (Crypt, solo escritura) |
Analytics Data API properties/{id}:runReport |
externa | informes de visitantes |
Search Console searchAnalytics/query |
externa | informes de tráfico de búsqueda |
Servicios: Services\Google\{GoogleTokenService, GoogleReportService, SiteInsightService}; endpoints Service\WebController@insight{Visitors,Search,Test}.
Caché: las respuestas de los informes se almacenan en caché y la clave de caché incluye la identidad que actúa (client_email). La misma URL y el mismo cuerpo pedidos con otra cuenta son una autorización distinta, así que compartir la clave entregaría a un sitio la respuesta en caché de otro.
Por qué las credenciales son por sitio
Una única clave global en .env no puede funcionar aquí. Los sitios registrados pertenecen a propietarios distintos y, por tanto, a cuentas de Google distintas, y una cuenta de servicio solo lee las propiedades a las que se la ha invitado: en cuanto están registrados los sitios de dos clientes, al menos uno falla siempre. De ahí el campo que se pega por sitio.
- Se guarda con
Crypt(APP_KEY) y es de solo escritura: el modelo oculta el texto cifrado, así que la interfaz nunca ve más que un booleano y elclient_email, que no es secreto. La clave privada no vuelve a salir. - Al guardar se valida de tres maneras: que el JSON se analice, que estén presentes
client_email/private_keyy que una comprobación de firma acepte la clave. Pegar el archivo truncado es habitual, y dejar pasar uno así aflora más tarde como un falso «permiso denegado» que le manda a rebuscar en el IAM de Google. - Una credencial de todo el servidor sigue existiendo como alternativa para despliegues de una sola cuenta; la credencial propia de un sitio siempre gana.
El campo de la credencial solo se transmite cuando usted lo toca. El formulario nunca recibe de vuelta la clave privada, así que tratar «ausente» como «borrar» eliminaría la credencial cada vez que alguien editase únicamente la nota. Vaciarlo de forma explícita es la única manera de eliminarla.
Permisos
- Lectura: cualquier usuario con sesión iniciada (
infr.auth, nivel ≥ 1). Solo lee estadísticas externas y no cambia nada en InfraGuard ni en Google, así que no hay verificación reforzada ni entrada de auditoría (la misma disciplina que en la consulta de reputación de IP). - Guardar credenciales/propiedades:
user_level >= 2(igual que guardar un sitio web), registrado eninfr_audit_log.
El objetivo se indica únicamente mediante el id del sitio registrado: un ID de propiedad no puede pasarse como parámetro. Si quien llama pudiera nombrar una propiedad, los permisos de nuestra cuenta de servicio se convertirían en una vía para leer las propiedades de GA4/Search Console de otras personas (la misma disciplina anti-SSRF que en las pruebas en vivo del Catálogo). El periodo está igualmente limitado en el servidor a 7/28/90.
Resolución de problemas · Preguntas frecuentes
- No hay iconos en la tarjeta: un sitio necesita tanto una credencial como una asignación de propiedad para que aparezcan los botones. La comprobación es por sitio, así que un sitio con su propia credencial funciona aunque el
.envglobal esté vacío. Guarde y recargue. - Todas las comprobaciones están en verde y aun así devuelve 0: eso es un problema de recogida, no de consulta. ① La ventana termina ayer, así que una etiqueta instalada hoy todavía queda fuera. ② Confirme que el ID de medición (
G-…) que sirve realmente el sitio pertenece a la propiedad que está consultando (Administrador de GA4 ▸ Flujos de datos); si los datos aterrizan en otra propiedad, leerá cero para siempre. ③ Search Console lleva ~2 días de retraso, y un sitio nuevo puede no tener todavía ninguna impresión. User does not have sufficient permissions: o falta el paso 3 (invitar a la cuenta) o el ID de propiedad de GA4 es incorrecto. Ambos producen una redacción idéntica, así que compruebe primero el ID de propiedad.- Solo Search Console vuelve vacío: lo más probable es que la cadena de la propiedad no coincida con la realidad (
sc-domain:frente ahttps://…/). Falla como resultado vacío en lugar de como error, así que compárela con el selector de propiedades. - La credencial desapareció al guardar: guardar con el campo vacío es una eliminación explícita. Si no lo toca, se conserva.
- La ventana muestra una insignia
Sample: todavía no se han recogido datos, así que se muestra una muestra ilustrativa para poder valorar la disposición. Cambia automáticamente a datos reales en cuanto llegan.
Relacionado
- Servicio ▸ Web: la propia pantalla de supervisión web (tarjetas, disponibilidad, certificados)
- Landing pública y analítica de visitantes: el lado de la recogida (gtag/GTM, verificación en Search Console)
- Consulta de reputación de IP: el mismo modelo de permisos de consulta externa de solo lectura
