Módulo 3: Google Calendar

Listar y Buscar Eventos

Descripción de la cápsula

Crear eventos es solo la mitad. La otra mitad es leer la agenda: saber qué hay ahí antes de actuar.

¿Por qué importa? Porque casi nunca quieres crear eventos "a ciegas". Antes de agendar una llamada quieres saber si ese horario está libre. Antes de mandar un recordatorio quieres listar las citas de mañana. Antes de cancelar un evento tienes que encontrarlo primero. Leer la agenda es lo que conecta a Calendar con el resto del workflow.

Esta cápsula cubre las operaciones de lectura: Get Many (listar eventos en un rango de fechas) y Get (traer un evento concreto). Y aplica un patrón que ya conoces del Módulo 1 — "buscar antes de actuar" — al calendario: buscar si ya existe un evento antes de crear uno, para no llenar la agenda de duplicados.


Lo que vas a aprender

Al terminar esta cápsula serás capaz de:

  • Listar eventos de un calendario en un rango de fechas
  • Filtrar eventos por texto y otros criterios
  • Traer un evento específico por su ID
  • Entender el output de un evento: qué campos te da
  • Aplicar "buscar antes de crear" para no duplicar eventos
  • Limitar resultados para no traer una agenda entera

Las dos operaciones de lectura

OperaciónQué haceCuándo usarla
Get ManyLista los eventos de un calendario en un rango"Dame las citas de esta semana"
GetTrae un evento por su IDCuando ya tienes el ID de un evento concreto

La que más vas a usar es Get Many.


Listar eventos con Get Many

Configuración del nodo Google Calendar:

  • Resource: Event
  • Operation: Get Many
  • Calendar: el calendario a consultar
  • After / Before: el rango de fechas (desde — hasta)
  • Limit: cuántos eventos máximo traer

El rango de fechas

A diferencia de leer una hoja (donde lees "todas las filas"), una agenda no tiene fin — siempre hay más eventos en el futuro. Por eso Get Many casi siempre necesita un rango:

Quiero...AfterBefore
Eventos de hoyinicio de hoyfin de hoy
Eventos de mañanainicio de mañanafin de mañana
Esta semanahoydentro de 7 días

Con expressions:

After:  {{ $now.startOf('day').toISO() }}
Before: {{ $now.endOf('day').toISO() }}

Eso lista los eventos de hoy. Para mañana:

After:  {{ $now.plus({ days: 1 }).startOf('day').toISO() }}
Before: {{ $now.plus({ days: 1 }).endOf('day').toISO() }}

startOf('day') lleva la fecha al inicio del día (00:00); endOf('day') al final (23:59). Combinados, definen "todo el día X" — el rango más común.

Resultado

Get Many devuelve un item por evento en el rango. Si mañana tienes 4 citas, recibes 4 items.


Filtrar lo que listas

Además del rango de fechas, Get Many acepta filtros para acotar más:

  • Query / Search: trae solo eventos cuyo texto (título, descripción) coincide con un término
  • Single Events: si lo activas, los eventos recurrentes se "expanden" en sus repeticiones individuales en vez de venir como una sola entrada (útil cuando trabajas con eventos repetidos — más en la cápsula 06)

Ejemplo: listar las "llamadas" de esta semana:

After:  {{ $now.startOf('day').toISO() }}
Before: {{ $now.plus({ days: 7 }).toISO() }}
Query:  llamada

Igual que con Sheets y Gmail: acota siempre. Un rango amplio sin query y sin límite puede traer cientos de eventos. Específico es mejor.


Qué te da cada evento

Cuando lees un evento, llega como un item con campos. Los principales:

CampoQué contiene
idEl identificador único del evento
summaryEl título
descriptionLa descripción
startFecha/hora de inicio
endFecha/hora de fin
attendeesLos invitados
locationLa ubicación
statusEstado: confirmed, cancelled, tentative
htmlLinkUn enlace directo al evento en Google Calendar

Truco práctico: igual que en los módulos anteriores, antes de construir el resto del workflow, ejecuta el Get Many y mira el output real. Los campos de fecha (start, end) en particular tienen una estructura interna — míralos para saber exactamente cómo acceder a ellos.

El htmlLink es especialmente útil: si tu workflow notifica a alguien sobre un evento, incluir ese enlace le permite abrirlo directo.


Traer un evento específico con Get

Cuando ya tienes el ID de un evento (porque lo creaste antes y guardaste el ID, o porque lo obtuviste de un Get Many), puedes traerlo directo:

  • Operation: Get
  • Calendar: el calendario
  • Event ID: {{ $json.id }}

Te devuelve ese evento concreto, con todos sus campos actualizados. Útil para "ver el estado actual" de un evento antes de modificarlo o cancelarlo (cápsula 05).


El patrón: "buscar antes de crear"

Aquí aplicamos al calendario el patrón estrella del Módulo 1.

El problema

Tu workflow crea un evento cada vez que llega un lead. Pero:

  • El mismo lead llena el formulario dos veces → dos eventos idénticos
  • Pruebas el workflow 5 veces → 5 eventos en la agenda
  • El workflow se reintenta → evento duplicado

La agenda se llena de citas repetidas. Confuso para todos.

La solución

Antes de crear, busca si ya existe:

Trigger
   │
   ▼
Google Calendar (Get Many)  ──  rango: el día/hora de la cita propuesta
                                 query: el nombre del cliente
   │
   ▼
IF: ¿el lookup devolvió 0 eventos?
   │
   ┌──────────┴──────────┐
   ▼ SÍ (no existe)      ▼ NO (ya hay un evento)
 Google Calendar          no crear (o actualizar — cápsula 05)
 (Create)

La condición del IF, como en el Módulo 1:

{{ $('Google Calendar').all().length === 0 }}

Con esto, el workflow es idempotente: el mismo lead, las mismas pruebas, no generan duplicados en la agenda.

Matiz: "buscar antes de crear" en Calendar es un poco más sutil que en Sheets. Una hoja tiene una columna clave clara (email, ID). Un evento no — dos personas distintas pueden tener una cita "a las 10:00". Para que el lookup sea confiable, busca por una combinación específica: el rango de fecha exacto + algo identificable del cliente en el título o descripción. El mini-proyecto (cápsula 08) lo aplica con cuidado.


Trampas comunes

Trampa 1: Get Many sin rango de fechas

Qué pasa: Listas "los eventos" sin After/Before y traes cientos, o el nodo no sabe qué traer.

Cómo evitar: Una agenda no tiene fin — siempre define un rango. After y Before son tu acotación principal.


Trampa 2: Rango de fechas mal construido

Qué pasa: Quieres "los eventos de hoy" pero pones After = hoy y Before = hoy a la misma hora → rango de duración cero, 0 resultados.

Cómo evitar: Usa startOf('day') para el After y endOf('day') para el Before. El rango debe cubrir el período, no ser un punto.


Trampa 3: Asumir un único resultado del lookup

Qué pasa: Buscas eventos de un cliente y asumes que hay exactamente uno, pero hay dos (uno viejo, uno nuevo). El workflow procesa el equivocado.

Cómo evitar: Maneja el caso de "varios resultados" — o haz el lookup tan específico (rango + identificador) que solo uno pueda coincidir.


Trampa 4: Buscar solo por título y chocar con homónimos

Qué pasa: Buscas por query "Llamada con Ana" y traes la cita de otra Ana.

Cómo evitar: Para lookups confiables, combina criterios: rango de fecha estrecho + un identificador único (email del cliente en la descripción, por ejemplo).


Trampa 5: No mirar la estructura de start y end

Qué pasa: Intentas usar {{ $json.start }} directo y obtienes un objeto, no una fecha legible.

Cómo evitar: Ejecuta el Get Many, mira el output, y accede al subcampo correcto de start (tiene una estructura interna). No adivines.


Ejercicio: lee tu agenda

Objetivo: practicar el listado con rangos y el patrón "buscar antes de crear".

Preparación

Asegúrate de tener algunos eventos de prueba en tu calendario (los del ejercicio de la cápsula 03 sirven).

Tu tarea

  1. Eventos de hoy: Manual Trigger → Google Calendar (Get Many) con After/Before del día de hoy. ¿Cuántos trae?
  2. Eventos de la semana: cambia el rango a los próximos 7 días
  3. Búsqueda con query: agrega un Query para traer solo los eventos que contienen cierta palabra en el título
  4. "Buscar antes de crear": construye Get Many (busca un evento específico) → IF (length === 0) → Create (solo si no existe). Ejecútalo dos veces y verifica que no se duplica
Ver pistas
  1. After: {{ $now.startOf('day').toISO() }}, Before: {{ $now.endOf('day').toISO() }}
  2. Before: {{ $now.plus({ days: 7 }).endOf('day').toISO() }}
  3. Campo Query con la palabra a buscar
  4. La condición del IF: {{ $('Google Calendar').all().length === 0 }} — Create va en la rama true

Resumen y siguiente paso

  • Get Many lista eventos en un rango de fechas (After/Before) — una agenda no tiene fin, siempre acota
  • Usa startOf('day') / endOf('day') para construir rangos de "todo el día X"
  • Get trae un evento concreto por su ID
  • Cada evento te da: id, summary, start, end, attendees, status, htmlLinkmira el output real, sobre todo la estructura de start/end
  • El patrón "buscar antes de crear" evita duplicados en la agenda — pero el lookup debe ser específico (rango + identificador), no solo por título
  • 5 trampas: sin rango, rango de duración cero, asumir un resultado, buscar solo por título, no mirar la estructura de las fechas

Antes de avanzar deberías poder:

  • Listar los eventos de un día y de una semana
  • Construir un rango de fechas correcto con expressions
  • Aplicar "buscar antes de crear" con un lookup específico

Lo que sigue (cápsula 05):

Ya sabes crear y leer. Faltan las dos operaciones que cierran el ciclo de vida de un evento: actualizar (cambiar la hora de una cita, agregar un invitado) y eliminar (cancelar). La cápsula 05 las cubre — y aquí el ID del evento se vuelve protagonista.


Recursos adicionales

  1. n8n Google Calendar node Docs - Operaciones Get y Get Many.
  2. n8n: métodos de fecha - startOf, endOf, plus para construir rangos.
  3. n8n IF node Docs - Para el patrón "buscar antes de crear".

Creado: Mayo 14, 2026 Versión: 1.0