Módulo 3: Google Calendar
Mini-Proyecto: Crear Eventos desde Datos
Descripción de la cápsula
Hora de juntar el módulo en un workflow real — y, por primera vez en la guía, integrar tres herramientas.
El proyecto: un sistema de agendamiento de citas. Llega una solicitud de cita (nombre, email, fecha y hora deseada). El workflow verifica que no haya ya una cita igual, crea el evento en Google Calendar con la zona horaria correcta y un recordatorio, le manda un correo de confirmación al cliente (porque la invitación de Calendar no basta — cápsula 07), y registra la cita en una hoja de Google Sheets guardando el Event ID para poder reprogramarla después.
Es el proyecto más completo de la guía hasta ahora: usa todo el Módulo 3 (crear, buscar antes de crear, zonas horarias, recordatorios) más Gmail del Módulo 2 y Sheets del Módulo 1. Cuando lo termines, tendrás el esqueleto de un sistema de citas que conecta tres herramientas en un flujo de negocio coherente — exactamente el tipo de integración que el hub final de la guía (Módulo 8) lleva al máximo.
Lo que vas a construir
Un workflow llamado Agendador de Citas que:
- Recibe una solicitud de cita (nombre, email, fecha/hora deseada)
- Busca si esa persona ya tiene una cita igual agendada (no duplicar)
- Crea el evento en Calendar con la zona horaria correcta, el cliente como invitado y un recordatorio
- Manda un correo de confirmación al cliente con los detalles de la cita
- Registra la cita en una hoja, guardando el Event ID
Lo que vas a practicar
- ✅ Crear eventos desde datos con campos dinámicos (cápsula 03)
- ✅ "Buscar antes de crear" aplicado al calendario (cápsula 04)
- ✅ Zona horaria y recordatorios correctos (cápsula 06)
- ✅ El patrón "evento + correo de confirmación" (cápsula 07)
- ✅ Guardar el Event ID para futuras modificaciones (cápsula 05)
- ✅ Integrar tres herramientas — Calendar + Gmail + Sheets — en un flujo
Preparación
La hoja de citas
Crea una hoja Citas Agendadas con estas columnas en la fila 1:
| name | appointment_date | event_id | status | registration_date |
|---|
Formatea email y event_id como Texto sin formato (son identificadores).
El calendario
Usa el calendario dedicado Citas n8n que creaste en la cápsula 02 (o tu calendario principal para pruebas).
Tu zona horaria
Ten clara tu zona (ej. America/Mexico_City) — la vas a usar en el nodo Calendar.
Arquitectura del workflow
Manual Trigger (o Webhook en producción)
│
▼
Set: normalizar la solicitud de cita
│
▼
Google Calendar (Get Many) ── busca cita existente del cliente en esa fecha
│
▼
IF: ¿el lookup devolvió 0 eventos?
│
┌──────────────────┴──────────────────┐
▼ TRUE (no existe — agendar) ▼ FALSE (ya tiene cita)
Google Calendar (Create) Gmail (Send: "ya tienes
│ una cita agendada")
▼
Gmail (Send: confirmación de la cita)
│
▼
Google Sheets (Append: registrar con event_id)
Paso 1: el trigger y la solicitud
Para desarrollar, Manual Trigger → Set que simula la solicitud de cita:
Nodo Set:
name = Ana López
email = ana@example.com
desired_date = 2026-05-22T11:00:00
En producción, este Set se reemplaza por un Webhook Trigger que recibe la solicitud de un formulario de agendamiento. El resto del workflow no cambia. Usa una
desired_datereal futura para tus pruebas.
Paso 2: normalizar la solicitud
Un nodo Set que limpia y prepara los datos (diseño defensivo del Módulo 1):
name = {{ $json.name.trim() }}
email = {{ $json.email.toLowerCase().trim() }}
start = {{ $json.desired_date }}
end = {{ DateTime.fromISO($json.desired_date).plus({ minutes: 30 }).toISO() }}
registration_date = {{ $now.toFormat('yyyy-LL-dd HH:mm') }}
Nota: el end se calcula a partir del start + 30 minutos — la regla de oro de la cápsula 03.
Paso 3: buscar cita existente
Un nodo Google Calendar para no duplicar (patrón cápsula 04):
- Operation:
Get Many - Calendar:
Citas n8n - After:
{{ $('Set').item.json.start }} - Before:
{{ $('Set').item.json.end }} - Query:
{{ $('Set').item.json.email }}
Renombra este nodo a Find Appointment. La idea: busca eventos en exactamente esa franja horaria que mencionen el email del cliente. Si ya hay uno, es una cita duplicada.
Recuerda el matiz de la cápsula 04: el lookup en Calendar debe ser específico. Por eso combinamos el rango de fecha estrecho con el email como query — para que solo coincida la cita real de ese cliente, no la de otro.
Paso 4: el IF — ¿agendar o ya existe?
Un nodo IF después de Find Appointment:
- Condition (expression):
{{ $('Find Appointment').all().length === 0 }}
true→ no hay cita → agendarfalse→ ya tiene cita → avisar que ya está agendada
Paso 5: rama TRUE — crear el evento
En la salida true, un nodo Google Calendar:
- Operation:
Create - Calendar:
Citas n8n - Start:
{{ $('Set').item.json.start }} - End:
{{ $('Set').item.json.end }} - Timezone: tu zona, ej.
America/Mexico_City(¡no lo dejes por defecto! — cápsula 06) - Summary:
Cita con {{ $('Set').item.json.name }} - Description:
Cliente: {{ $('Set').item.json.name }} Email: {{ $('Set').item.json.email }} Agendado automáticamente. - Attendees:
{{ $('Set').item.json.email }}(en pruebas, usa tu propio correo) - Reminders: popup 30 minutos antes
Renombra este nodo a Create Event — vamos a usar su output (el event_id) en los pasos siguientes.
Paso 6: rama TRUE — correo de confirmación
Después de Create Event, un nodo Gmail:
- Operation:
Send - To:
{{ $('Set').item.json.email }} - Subject:
Tu cita está confirmada — {{ $('Set').item.json.name }} - Email Type:
HTML - Message:
<p>Hola {{ $('Set').item.json.name }},</p> <p>Tu cita quedó confirmada para el <strong>{{ DateTime.fromISO($('Set').item.json.start).toFormat('dd/LL/yyyy HH:mm') }}</strong>.</p> <p>También recibirás una invitación en tu calendario. Si necesitas reprogramar, responde a este correo.</p> <p>Saludos,<br>El equipo</p>
Este es el patrón clave de la cápsula 07: evento + correo explícito. La invitación de Calendar hace que aparezca en su agenda; el correo es lo que garantiza que el cliente se entere.
Paso 7: rama TRUE — registrar en la hoja
Después del correo, un nodo Google Sheets:
- Operation:
Append Row - Document:
Citas Agendadas - Mapping (manual):
email→{{ $('Set').item.json.email }}name→{{ $('Set').item.json.name }}appointment_date→{{ $('Set').item.json.start }}event_id→{{ $('Create Event').item.json.id }}status→confirmedregistration_date→{{ $('Set').item.json.registration_date }}
El campo clave: event_id. Guardamos el ID del evento que devolvió Create Event. Así, cuando el cliente quiera reprogramar, el workflow puede buscar su fila, sacar el event_id, y hacer un Update (cápsula 05) — sin tener que buscar el evento a ciegas.
Paso 8: rama FALSE — avisar que ya tiene cita
En la salida false del IF, un nodo Gmail:
- Operation:
Send - To:
{{ $('Set').item.json.email }} - Subject:
Ya tienes una cita agendada - Email Type:
HTML - Message:
<p>Hola {{ $('Set').item.json.name }},</p> <p>Notamos que ya tienes una cita agendada para esa fecha y hora. No creamos una nueva para evitar duplicados.</p> <p>Si necesitas cambiarla, responde a este correo.</p> <p>Saludos,<br>El equipo</p>
Esta rama es lo que hace el workflow idempotente y amable: si la solicitud se repite, no duplica la cita, y además le explica al cliente qué pasó.
Paso 9: probar el workflow
Prueba 1: cita nueva
- Ejecuta con
Ana López / ana@example.com / 2026-05-22T11:00:00(usa tu propio correo enemaily en Attendees para la prueba) - Verifica: el evento aparece en
Citas n8na la hora correcta, te llegó el correo de confirmación, hay una fila enCitas Agendadascon elevent_idlleno
Prueba 2: cita duplicada
- Ejecuta otra vez con los mismos datos
- Verifica: no se creó un segundo evento, te llegó el correo de "ya tienes una cita agendada", no hay fila nueva en la hoja
Prueba 3: cita distinta
- Cambia el Set a una fecha/hora diferente
- Verifica: se creó el evento nuevo, llegó la confirmación, nueva fila en la hoja
Prueba 4: la hora
- Abre uno de los eventos creados en calendar.google.com
- Verifica que la hora coincide exactamente con la
desired_dateque pediste — si no, revisa el Timezone del nodo Calendar (cápsula 06)
Checklist de éxito
- Una cita nueva crea el evento, manda confirmación y registra en la hoja
- El evento queda a la hora correcta (Timezone configurado)
- El evento tiene al cliente como invitado y un recordatorio
- El
event_idqueda guardado en la hoja - Una solicitud duplicada no crea un segundo evento — manda el aviso
- El cliente recibe un correo explícito, no solo la invitación de Calendar
- Las tres herramientas (Calendar, Gmail, Sheets) trabajan en un solo flujo
Cómo llevar esto a producción
Lo que construiste es un esqueleto reutilizable. Para producción:
- Cambia el Manual Trigger por un Webhook Trigger conectado a un formulario de agendamiento.
- Valida la fecha deseada: ¿está en el futuro? ¿es en horario de oficina? Un IF al inicio que rechace fechas inválidas.
- Maneja la reprogramación: un segundo workflow que, con el
event_idguardado en la hoja, hace Update del evento (cápsula 05) cuando el cliente quiere cambiar. - Verifica disponibilidad real: ahora solo evitas duplicados del mismo cliente. Podrías además verificar que el horario no choque con otra cita (otro Get Many sin el query del email).
- Maneja errores: si Calendar, Gmail o Sheets fallan, el workflow se detiene. G10 (Production) cubre la resiliencia.
Resumen del módulo
Con este proyecto cierras el Módulo 3 — Google Calendar. Recapitulando lo que ahora dominas:
- Conectar Calendar y entender el concepto de múltiples calendarios (cápsula 02)
- Crear eventos desde datos, con invitados y campos dinámicos (cápsula 03)
- Listar y buscar la agenda con rangos de fecha (cápsula 04)
- Actualizar y eliminar eventos usando el Event ID (cápsula 05)
- Zonas horarias y recordatorios — poner los eventos a la hora correcta (cápsula 06)
- Diagnosticar permisos, invitaciones y formatos de fecha (cápsula 07)
- Integrar tres herramientas en un sistema de agendamiento (esta cápsula)
El patrón estrella del módulo: un evento es un dato con horario y testigos — exige precisión en la zona horaria, y la invitación de Calendar siempre se acompaña de un correo explícito.
Lo que sigue (Módulo 4):
Sheets guarda, Gmail comunica con el cliente, Calendar agenda. El Módulo 4 — Slack lleva la comunicación hacia adentro: notificar al equipo. Vas a cerrar otro círculo — una cita se agenda (M03) y el equipo recibe un aviso en Slack al instante (M04).
Recursos adicionales
- n8n Google Calendar node Docs - Operaciones Create y Get Many.
- n8n Gmail node Docs - Para el correo de confirmación.
- n8n Google Sheets node Docs - Para registrar las citas con su Event ID.
Creado: Mayo 14, 2026 Versión: 1.0