Módulo 7: Calendly y Agendamiento

Mini-Proyecto: El Workflow Post-Reserva

Descripción de la cápsula

Hora de juntar el módulo en el workflow que la estrategia de esta guía señala para M07: el workflow post-reserva — confirmación y follow-up.

Este proyecto es el patrón que toda agenda comercial necesita: alguien reserva una cita en tu Calendly, y a partir de ese instante, sin que nadie haga nada a mano, se dispara todo lo que debe pasar — se confirma con un correo personalizado, se registra al lead en el CRM, se avisa al equipo, se programa el recordatorio. Y si el cliente cancela, el sistema también reacciona — limpia, avisa, cancela el seguimiento.

Es el proyecto que integra más herramientas de toda la guía hasta ahora: el webhook de Calendly como disparador, Gmail para confirmar, HubSpot para registrar el lead, Slack para avisar al equipo. Es la demostración de que las "integraciones de negocio" no son herramientas sueltas — son un flujo donde un evento (una reserva) recorre todo tu stack.


Lo que vas a construir

Un workflow llamado Post-Reserva que:

Cuando alguien reserva (invitee.created):

  1. Aplana los datos de la reserva
  2. Verifica que no sea una reserva duplicada
  3. Manda un correo de confirmación personalizado al cliente
  4. Registra al cliente en el CRM (HubSpot) como lead
  5. Avisa al equipo por Slack
  6. Programa un recordatorio antes de la cita

Cuando alguien cancela (invitee.canceled):

  1. Marca la cita como cancelada
  2. Avisa al equipo por Slack que se liberó el horario

Lo que vas a practicar

  • ✅ El webhook de Calendly como disparador (cápsula 04)
  • Separar reserva de cancelación con un Switch (cápsula 04)
  • Aplanar los datos de la reserva con un Set (cápsula 05)
  • Confirmar con Gmail, registrar en HubSpot, avisar por Slack — integración cross-módulo
  • Recordatorio con Wait (cápsula 06)
  • "Buscar antes de actuar" para evitar duplicados (Módulo 1)
  • ✅ La demostración de que las integraciones forman un flujo, no piezas sueltas

Preparación

Este proyecto usa varias herramientas que ya conectaste en módulos anteriores:

  • Calendly con webhooks disponibles (cápsula 02) y un tipo de evento configurado
  • Gmail (Módulo 2) — para el correo de confirmación
  • HubSpot (Módulo 6) — para registrar el lead
  • Slack (Módulo 4) — un canal #reservas con el bot invitado

Si alguna no la tienes lista, repásala — pero el patrón del workflow lo entiendes igual aunque uses solo algunas.


Arquitectura del workflow

Calendly Trigger (invitee.created + invitee.canceled)
   │
   ▼
Switch: ¿qué tipo de evento?
   │
   ┌──────────────────────────┴──────────────────────────┐
   ▼ invitee.created                                     ▼ invitee.canceled
Set: aplanar la reserva                            Set: aplanar la cancelación
   │                                                     │
   ▼                                                     ▼
HubSpot (Search por event_id)                      [marcar cita cancelada
   │                                                + avisar al equipo]
   ▼
IF: ¿ya estaba registrada?
   │
   ┌──────────┴──────────┐
   ▼ NO (procesar)       ▼ SÍ (ya procesada — terminar)
Gmail (confirmación)
   │
   ▼
HubSpot (Create or Update lead)
   │
   ▼
Slack (avisar al equipo)
   │
   ▼
Wait (hasta antes de la cita)
   │
   ▼
Gmail (recordatorio)

Paso 1: el Calendly Trigger

  • Credential: tu credencial de Calendly
  • Events: suscríbete a invitee.created e invitee.canceled — ambos (cápsula 04)

Paso 2: el Switch — separar reserva de cancelación

Justo después del trigger, un Switch que separa los dos casos según el tipo de evento del payload (mira el output real para el campo exacto — cápsula 04):

  • Salida invitee.created → rama de reserva nueva
  • Salida invitee.canceled → rama de cancelación

Paso 3 (rama RESERVA): aplanar los datos

Un nodo Set que aplana la reserva en campos planos (cápsula 05):

name       = [del payload]
email      = [del payload, .toLowerCase().trim()]
start_time = [del payload]
end_time   = [del payload]
event_type = [del payload]
event_id   = [del payload — la clave única]
reason     = [respuesta del formulario, || 'Sin especificar']

Renómbralo a Booking Data. Recuerda: mira el output real del trigger para las rutas exactas.


Paso 4 (rama RESERVA): evitar duplicados

Recuerda de la cápsula 04 y 07: un webhook puede llegar dos veces, o pruebas el workflow varias veces. Aplica "buscar antes de actuar" con el event_id como clave:

  • HubSpot (Search) o una consulta a una hoja — busca si ya existe un registro con ese event_id
  • IF: ¿el search devolvió algo?
    • NO (length === 0) → es nueva, procesar (sigue al paso 5)
    • → ya se procesó, terminar sin hacer nada

Esto hace el workflow idempotente: la misma reserva no se confirma ni se registra dos veces.


Paso 5 (rama RESERVA): correo de confirmación

Un nodo Gmail (Send) al cliente — personalizado con los datos de Booking Data (cápsula 05 y 06):

  • To: {{ $('Booking Data').item.json.email }}
  • Subject: Tu cita está confirmada — {{ $('Booking Data').item.json.event_type }}
  • Email Type: HTML
  • Message:
    <p>Hola {{ $('Booking Data').item.json.name }},</p>
    <p>Tu cita quedó confirmada:</p>
    <ul>
      <li><strong>Tipo:</strong> {{ $('Booking Data').item.json.event_type }}</li>
      <li><strong>Fecha:</strong> {{ DateTime.fromISO($('Booking Data').item.json.start_time).toFormat('dd/LL/yyyy HH:mm') }}</li>
    </ul>
    <p>Vi que quieres hablar sobre: <em>{{ $('Booking Data').item.json.reason }}</em>. Lo tendremos presente.</p>
    <p>¡Nos vemos pronto!</p>

El correo menciona el motivo que el cliente escribió al reservar — esto es lo que hace el follow-up relevante en vez de genérico (cápsula 06).


Paso 6 (rama RESERVA): registrar el lead en el CRM

Un nodo HubSpot (Contact: Create or Update) — el lead que reservó entra al CRM (Módulo 6):

  • Clave: el email (normalizado)
  • Propiedades: nombre, email, lifecyclestagelead
  • Idealmente, registra también una nota (cápsula 06 del M06): "Reservó una cita vía Calendly el [fecha], motivo: [motivo]" — la automatización visible

Create or Update deduplica por email (Módulo 6) — si ese cliente ya estaba en el CRM, se actualiza, no se duplica.


Paso 7 (rama RESERVA): avisar al equipo

Un nodo Slack (Send) al canal #reservas (Módulo 4), con formato (cápsula 04 del M04):

*📅 Nueva reserva*
• *Cliente:* {{ $('Booking Data').item.json.name }}
• *Cita:* {{ $('Booking Data').item.json.event_type }}
• *Cuándo:* {{ DateTime.fromISO($('Booking Data').item.json.start_time).toFormat('dd/LL HH:mm') }}
• *Motivo:* {{ $('Booking Data').item.json.reason }}

El equipo se entera al instante, con el contexto para prepararse.


Paso 8 (rama RESERVA): el recordatorio

Un nodo Wait que espera hasta unas horas antes de la cita (cápsula 06), seguido de un Gmail (Send) con un recordatorio breve al cliente.

  • Wait: hasta una fecha calculada a partir del start_time menos, por ejemplo, 3 horas
  • Gmail: un recordatorio corto — "Te esperamos en unas horas para tu cita"

Recuerda la cápsula 06: el Wait es apropiado para esperas cortas (horas, pocos días). Para este recordatorio cercano, es la opción simple y correcta. Un follow-up posterior de "¿cómo te fue?" — días después — sería mejor con el patrón Schedule que barre; queda como mejora de producción.


Paso 9 (rama CANCELACIÓN): manejar la cancelación

En la salida invitee.canceled del Switch:

  1. Un Set que aplana los datos de la cancelación (al menos el event_id y el name)
  2. Marcar la cita como cancelada donde la hayas registrado — buscar por event_id y actualizar el estado (en HubSpot, o en una hoja de seguimiento)
  3. Un Slack (Send) a #reservas: ❌ {{ name }} canceló su cita del {{ date }}. Horario liberado.

Esta rama es lo que hace el sistema completo y honesto (cápsulas 04, 06, 07): las cancelaciones no se ignoran — se procesan, y el equipo se entera.


Paso 10: probar el sistema

Prueba 1: una reserva nueva

  1. Activa el workflow
  2. Entra a tu Calendly y reserva una cita real (usa tu propio correo)
  3. Verifica: te llegó el correo de confirmación personalizado, el lead está en HubSpot con su nota, apareció el aviso en #reservas de Slack, y el workflow está en espera (Wait) para el recordatorio

Prueba 2: la misma reserva no se duplica

  1. Si puedes, fuerza un reenvío del webhook (o re-ejecuta sobre el mismo payload)
  2. Verifica: el IF de "buscar antes de actuar" la detecta como ya procesada — no se confirma ni se registra dos veces

Prueba 3: una cancelación

  1. Cancela la cita de prueba en Calendly
  2. Verifica: el workflow disparó por invitee.canceled, cayó en la rama de cancelación, marcó la cita y avisó en Slack

Prueba 4: el recordatorio

  1. Si configuraste el Wait para una cita cercana, espera a que llegue el momento
  2. Verifica: llegó el correo de recordatorio

Checklist de éxito

  • Una reserva dispara el flujo completo: confirmación + CRM + Slack + recordatorio programado
  • El correo de confirmación está personalizado (nombre, tipo, motivo)
  • El lead queda en HubSpot, con nota — la automatización es visible
  • El equipo recibe el aviso en Slack con contexto
  • Una reserva duplicada no se procesa dos veces
  • Una cancelación dispara la rama de cancelación — no se ignora
  • El workflow integra cuatro herramientas en un solo flujo

Cómo llevar esto a producción

Lo que construiste es un esqueleto reutilizable. Para producción:

  • Follow-up posterior: un segundo workflow con Schedule que barre (cápsula 06) que, días después de cada cita, mande "¿cómo te fue?" — verificando que la cita no se canceló (cápsula 07).
  • Manejar reprogramaciones: recuerda la cápsula 07 — una reprogramación llega como cancel + create. Asegúrate de que el workflow lo tolere (el "buscar antes de actuar" por event_id ayuda).
  • Enrutar según el tipo de cita: una demo de ventas y un soporte de 15 min no merecen la misma secuencia — un Switch por event_type.
  • Avisar al responsable correcto: mencionar en Slack al miembro del equipo que atenderá esa cita (búsqueda de usuario, M04 cápsula 05).
  • Maneja errores: si una herramienta falla a mitad del flujo, quedas con estado parcial. G10 (Production) cubre la resiliencia.

Resumen del módulo

Con este proyecto cierras el Módulo 7 — Calendly y scheduling. Recapitulando lo que ahora dominas:

  • Conectar Calendly y distinguir el nodo del trigger (cápsula 02)
  • El modelo: tipos de evento vs eventos agendados, el invitee (cápsula 03)
  • El webhook: recibir reservas y cancelaciones en tiempo real (cápsula 04)
  • Los datos de la reserva: aplanar el payload anidado (cápsula 05)
  • Recordatorios y follow-ups: el seguimiento, y el problema del "más tarde" (cápsula 06)
  • Diagnosticar webhooks, cancelaciones y reprogramaciones (cápsula 07)
  • El workflow post-reserva — el patrón completo, integrando cuatro herramientas (esta cápsula)

El patrón estrella del módulo: Calendly resuelve el "cuándo", n8n resuelve el "y luego qué" — y ese "y luego qué" es un flujo que recorre todo tu stack de herramientas.

Lo que sigue (Módulo 8):

Has aprendido siete herramientas — Sheets, Gmail, Calendar, Slack, Airtable/Notion, HubSpot, Calendly — y en cada mini-proyecto las fuiste combinando de a dos, tres, cuatro. El Módulo 8 — Proyecto: Hub de Integraciones es el capstone: un único sistema que conecta todas en un flujo de negocio coherente. El destino al que apuntaba toda la guía.


Recursos adicionales

  1. n8n Calendly Trigger Docs - El disparador del proyecto.
  2. n8n Wait node Docs - Para el recordatorio.
  3. n8n Switch node Docs - Para separar reserva de cancelación.

Creado: Mayo 14, 2026 Versión: 1.0