Saltar al contenido
Entrar
Suscribirme

Local

Guía

Cómo medir una ficha de Google con IA sin caer en sus trampas

Los datos de rendimiento del Perfil de Empresa cambian después de publicarse, el panel solo guarda 6 meses y hay clics que no cuenta nadie. Te enseño el método que uso para medir las fichas de mis clientes con un agente de IA: cómo pedir acceso a la API, el script para guardar la serie, el encargo que le doy a la IA y cómo compruebo las cifras.

Publicado el Revisado el 11 min de lectura

Local medir seo

En un artículo anterior conté tres trampas que encontré al medir fichas de Google de negocios de Canarias:

  1. La API reescribe el pasado. En una clínica dental, el mismo periodo daba 46 llamadas pedido en junio y 50 pedido en julio. Mi "+39 % de llamadas" estaba inflado y, con el trabajo terminado, el resultado era plano (−1,3 %).
  2. Con los 6 meses del panel no ves el año anterior. En un centro de fisioterapia, una caída que parecía estacional no lo era, y tras un cambio las impresiones subieron un 23 % sin un aumento comparable de las interacciones.
  3. Hay clics que la ficha no mide. En un comercio con tres locales, los clics a la web cayeron un 33 % con las impresiones intactas, y mi hipótesis es que la gente pulsaba el botón de WhatsApp de la ficha, que no cuentan ni la API ni la analítica de la web.

Aquí explico cómo lo monto, paso a paso, para que puedas replicarlo.

Yo lo hago con un agente de IA que trabaja en la terminal (uso Claude Code, pero sirve cualquiera que pueda ejecutar código): le explico qué quiero medir, escribe el script, lo ejecuta y me devuelve las tablas. No hace falta ser programador, pero sí revisar lo que hace, porque la IA trabaja tan bien como las reglas que le das. Si solo le preguntas "¿ha funcionado lo que hice en la ficha?", hará la comparación fácil: el mes de antes contra el de después, con los datos que tenga a mano. Es la misma comparación que me engañó en la clínica.

Paso 1. Pide acceso a la API (tarda)

  • Requisitos de Google: según su página de requisitos previos, necesitas una ficha verificada y activa desde hace más de 60 días, una web del negocio y un proyecto en Google Cloud.
  • La solicitud se hace con el formulario de contacto de la API, eligiendo "Application for Basic API Access", desde un correo que sea propietario o administrador de la ficha.
  • Cuando te aprueban, te llega un email, y en Google Cloud la cuota del proyecto pasa de 0 a 300 consultas por minuto. A mí me tardó dos semanas.
  • Después, en Google Cloud activa tres APIs: Business Profile Performance (los datos), Account Management y Business Information (para listar tus fichas).
  • Configura la pantalla de consentimiento OAuth y crea unas credenciales de tipo "aplicación de escritorio". Descarga el archivo y guárdalo como credentials.json.
  • Publica la app en modo "En producción". Si la dejas en modo de prueba, Google hace caducar el permiso guardado a los 7 días y la descarga programada empieza a fallar a la semana.

Paso 2. Descarga la serie y guarda cada descarga con su fecha

Este es el script completo. Usa el método fetchMultiDailyMetricsTimeSeries de la API y lo he probado mientras escribía este artículo: lista las fichas, guarda y renueva el permiso solo, y devuelve exactamente las cifras de la clínica (799 impresiones, 50 llamadas y 26 clics a la web entre el 29 de marzo y el 27 de abril). Necesita pip install requests google-auth-oauthlib:

import datetime, json, pathlib, requests
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow

SCOPES = ["https://www.googleapis.com/auth/business.manage"]
TOKEN = pathlib.Path("token.json")

def credenciales():
    creds = Credentials.from_authorized_user_file(TOKEN, SCOPES) if TOKEN.exists() else None
    if creds and creds.expired and creds.refresh_token:
        creds.refresh(Request())
    elif not creds or not creds.valid:
        flujo = InstalledAppFlow.from_client_secrets_file("credentials.json", SCOPES)
        creds = flujo.run_local_server(port=0)  # solo la primera vez: abre el navegador
    TOKEN.write_text(creds.to_json())
    return creds

H = {"Authorization": f"Bearer {credenciales().token}"}

def mis_fichas():
    cuentas = requests.get("https://mybusinessaccountmanagement.googleapis.com/v1/accounts",
                           headers=H, timeout=30).json().get("accounts", [])
    for cuenta in cuentas:
        url = f"https://mybusinessbusinessinformation.googleapis.com/v1/{cuenta['name']}/locations"
        r = requests.get(url, headers=H, params={"readMask": "name,title", "pageSize": 100}, timeout=30)
        for ficha in r.json().get("locations", []):
            print(ficha["name"], ficha.get("title"))

METRICAS = [
    "BUSINESS_IMPRESSIONS_MOBILE_SEARCH", "BUSINESS_IMPRESSIONS_DESKTOP_SEARCH",
    "BUSINESS_IMPRESSIONS_MOBILE_MAPS", "BUSINESS_IMPRESSIONS_DESKTOP_MAPS",
    "CALL_CLICKS", "WEBSITE_CLICKS", "BUSINESS_DIRECTION_REQUESTS",
]

def serie(ficha, desde, hasta):
    params = [("dailyMetrics", m) for m in METRICAS]
    for lado, d in (("start_date", desde), ("end_date", hasta)):
        params += [(f"dailyRange.{lado}.year", d.year),
                   (f"dailyRange.{lado}.month", d.month),
                   (f"dailyRange.{lado}.day", d.day)]
    url = f"https://businessprofileperformance.googleapis.com/v1/{ficha}:fetchMultiDailyMetricsTimeSeries"
    r = requests.get(url, headers=H, params=params, timeout=60)
    r.raise_for_status()
    dias = {}
    for bloque in r.json().get("multiDailyMetricTimeSeries", []):
        for ts in bloque["dailyMetricTimeSeries"]:
            for v in ts["timeSeries"].get("datedValues", []):
                f = v["date"]
                fecha = f"{f['year']}-{f['month']:02d}-{f['day']:02d}"
                dias.setdefault(fecha, {})[ts["dailyMetric"]] = int(v.get("value", 0))  # sin "value" = 0
    return dias

def guardar(ficha):
    ahora = datetime.datetime.now()
    desde = ahora.date() - datetime.timedelta(days=540)
    hasta = ahora.date() - datetime.timedelta(days=1)
    salida = pathlib.Path(f"serie-{ficha.split('/')[-1]}-{ahora:%Y%m%d-%H%M}.json")
    datos = {"ficha": ficha, "descargado": ahora.isoformat(timespec="minutes"),
             "desde": str(desde), "hasta": str(hasta), "dias": serie(ficha, desde, hasta)}
    with salida.open("x") as f:  # "x": falla si ya existe, nunca sobrescribe
        json.dump(datos, f, indent=1)
    print("guardado", salida)

if __name__ == "__main__":
    # mis_fichas()  # descomenta la primera vez para ver los identificadores
    guardar("locations/TU_ID")

Cómo se usa y qué detalles importan:

  • La primera vez se abre el navegador para que des permiso. Google te mostrará un aviso de que la aplicación no está verificada. Es normal, porque la app es tuya y solo la usas tú. El script guarda ese permiso en token.json y a partir de ahí lo renueva solo, sin volver a preguntar. Trata ese archivo y credentials.json como contraseñas: no los subas a ningún repositorio ni los compartas.
  • Para saber el identificador de cada ficha (locations/…), ejecuta una vez mis_fichas().
  • Cada descarga va a un archivo con la ficha, la fecha y la hora en el nombre, y nunca se sobrescribe (si el archivo ya existe, el script falla en vez de pisarlo). Dentro guarda también cuándo se descargó y qué rango se pidió. En el comercio, la misma semana de agosto decía 0 impresiones en la Búsqueda descargada el 1 de septiembre y 1.767 descargada el 16. Si guardas siempre en el mismo archivo, la revisión de Google pasa delante de ti sin que la veas.
  • 540 días son unos 18 meses. La documentación de la versión anterior de la API fija ahí el máximo, y la actual me los devuelve sin problema. Así tienes siempre el año anterior para comparar.
  • Los últimos días llegan a cero, sin ningún aviso. El 28 de septiembre de 2026, la clínica marca 0 impresiones el 26 y el 27, y 2 el 25. El resto de esa semana está entre 20 y 40 al día. Esos ceros son datos que todavía no han llegado. La misma documentación avisa de que pueden faltar datos de los días cercanos a la petición, y la API no distingue un cero real de un dato que aún no está: los dos llegan como cero.

Programa el script cada quince días (cron en Linux o Mac, el Programador de tareas en Windows). Si se te olvida un mes, no pasa nada: la siguiente descarga lo recupera, mientras no pasen 18 meses.

Paso 3. Dale a la IA las reglas, no solo la pregunta

Este es el encargo que uso, adaptado. Cambia lo que va entre corchetes:

Tengo varias descargas de la serie diaria de una ficha de Google
(archivos serie-*.json). El [fecha] cambié [qué cambié]. En esas
fechas también pasó esto: [otros cambios: web, anuncios, horario...].
Quiero saber si ha tenido efecto.

Reglas:
1. Antes de calcular nada, compara las descargas entre sí y dime qué
   días han cambiado de valor y cuánto. Para los cálculos, usa solo
   la descarga más reciente.
2. No uses las tres últimas semanas. Si una ventana las toca, avísame.
3. Compara los 28 días anteriores al cambio con los 28 posteriores
   (fechas inclusivas, el día del cambio fuera), y usa como control
   las mismas fechas del año anterior. Dime las fechas exactas.
4. Impresiones = las cuatro métricas BUSINESS_IMPRESSIONS_*.
   Interacciones = CALL_CLICKS + WEBSITE_CLICKS +
   BUSINESS_DIRECTION_REQUESTS. Dalas por separado y no las mezcles
   en una sola conclusión.
5. Si faltan días en alguna ventana, dilo antes de calcular.
6. Enséñame las sumas día a día de cada ventana, para poder comprobarlas.
7. Separa lo que es dato de lo que es interpretación. Si falta algo,
   dilo; no lo estimes. No hables de causas: solo de lo que se movió.

Cada regla tapa una trampa:

  • Las reglas 1 y 2 reducen el riesgo de comparar con datos que Google todavía está revisando, y te avisan si lo ha hecho.
  • La regla 3 separa tu trabajo del calendario, hasta donde da un año de control.
  • Las reglas 4 y 5 fijan qué se suma y qué falta. Separar impresiones e interacciones es lo que me hizo ver que la fisioterapia ganaba visibilidad sin ganar acciones.
  • Las reglas 6 y 7 te dejan comprobar a la IA en vez de creerla, y le impiden convertir una correlación en una causa.

Paso 4. Cruza con Search Console

Pon un parámetro UTM en el enlace "Sitio web" de cada ficha, por ejemplo ?utm_source=gbp. Después pídele a la IA que saque de la API de Search Console los clics por página y separe las URL con y sin ese parámetro. Así sabes qué parte de un cambio en la web viene de la ficha. Es lo que me dejó ver que dos tercios de la caída del comercio estaban en los enlaces de las fichas. Joy Hawkins llega a la misma conclusión en un estudio de Sterling Sky con 78 fichas: sin UTM no puedes separar en Search Console el tráfico del pack local del orgánico.

Además, esa URL con UTM es la misma página que la normal, pero sus clics vienen de la ficha y no del resultado web. Si cambias el title de la home, te sirve como comparación auxiliar: no es un grupo de control perfecto, pero es mejor que no tener ninguno.

Paso 5. Revisa tú las cifras que vas a enseñar

La IA hace las cuentas, pero no sabe qué datos son fiables ni qué ha pasado en el negocio. Antes de que un número salga en un informe:

  • Pide que te enseñe la cuenta, no solo el resultado.
  • Comprueba un par de valores a mano en el panel.
  • Si la ventana es reciente, vuelve a descargar antes de enviar nada.
  • Y pide al negocio sus propios registros del mismo periodo: llamadas, citas o pedidos por WhatsApp. Es la única forma de ver lo que la ficha no cuenta.

Así es como corregí el "+39 % de llamadas" de la clínica antes de enviárselo a nadie.

Errores comunes

  • Pedirle a la IA "cómo ha ido la ficha" sin reglas. Te dará una respuesta segura y bien redactada sobre datos que quizá no son definitivos.
  • Sobrescribir el archivo en cada descarga. Pierdes justo lo que te avisa de que Google ha cambiado los datos.
  • Dejar la app OAuth en modo de prueba. El script funciona una semana y luego falla en silencio.
  • Olvidar que las métricas de la ficha incluyen Google Ads. Lo dice la ayuda de Google. Si el negocio tiene campañas activas, parte de lo que ves no es orgánico, y el informe no lo separa.

Los límites de este método

  • No arregla lo que la API no mide. El botón de WhatsApp o las llamadas que no pasan por la ficha siguen fuera. Para eso hacen falta los registros del negocio.
  • Las tres semanas son una regla práctica, no un plazo de Google. En el comercio, la semana no ha vuelto a cambiar desde que tenía dos o tres semanas, pero en la clínica cambió un periodo que ya tenía más de seis. Por eso la regla 1 pide comparar descargas.
  • Un año de control es poco. Con 18 meses no separas del todo la estacionalidad de lo que pasó ese año concreto.
  • Nada de esto prueba causalidad. Separa lo que se movió de lo que se movía solo, que ya es mucho más de lo que da el panel.

Recapitulando

  • Guarda cada descarga de la serie con su fecha. Es tu única forma de ver cuándo Google cambia los datos.
  • Descarga 18 meses para tener siempre el año anterior como control.
  • Dale a la IA reglas explícitas: comparar descargas, excluir lo reciente, usar control, separar impresiones e interacciones y enseñar la cuenta.
  • Cruza con Search Console usando UTM en la ficha.
  • Revisa tú las cifras y pide al negocio sus registros.

Si montas algo parecido, me interesa saber cuánto tardan en estabilizarse los datos en tus fichas.

Markdown:

¿Es la noticia de septiembre?

Hasta el 7 de octubre, cada cuenta vota las piezas de septiembre que más le han aportado, todas las que quiera: la más votada sale en portada con el emblema de noticia del mes. Votan las personas con una cuenta abierta antes del 1 de octubre.

Entra para votarla

Ver las 37 piezas de septiembre

Comentarios

Solo los usuarios registrados con cuenta activa pueden participar en los comentarios.

No hay comentarios aún. Sé el primero en opinar.

Más en Local

Local Análisis

Tres trampas al medir una ficha de Google, con datos de tres negocios reales

Llevo meses midiendo por la API las fichas de Google de mis clientes, y desde agosto guardo la serie diaria de todas. En tres negocios de Canarias, los datos me dijeron algo distinto de lo que parecía: una subida que no se sostuvo, una caída que no era estacional y unos clics perdidos que quizá no se perdieron. Te cuento las tres trampas y cómo evitarlas.

Fabio Hallwyler 13 min
Siguiente noticia Google deja de revisar las quejas de quien abusa del soporte de Perfil de Empresa