Inicio / Proyectos / Plataforma de reservaciones

Reemplazar Typeform, Calendly y Zapier con una sola plataforma de reservaciones

Un solo sistema propio reemplazó tres suscripciones SaaS recurrentes — Typeform, Calendly y Zapier — llevando todo el flujo de reservaciones dentro de Google Workspace, personalizable en cada paso y sin depender de ningún proveedor externo.

Estado En producción · v3.2
Escala~4,000 reservaciones / mes
Tecnologías principalesGoogle Calendar API · Google Sheets API · Google Apps Script · TypeScript
01

Resumen

Un sistema de agendado que le permite a un equipo de servicios distribuido tomar reservaciones entre muchos profesionales sin jamás generar una doble reserva, manejar mal una zona horaria ni duplicar una cita en un reintento — con Google Calendar como la única fuente de verdad.

Qué se construyó

Una plataforma de reservaciones montada directamente sobre Google Workspace. Los clientes eligen un horario a partir de la disponibilidad calculada; la plataforma reserva, verifica y confirma la cita como una sola transacción idempotente, escribiendo el evento en el Google Calendar del profesional y notificando a ambas partes. No hay una base de datos de registro aparte — el calendario en el que el equipo ya vive sigue siendo la autoridad.

Para quién es

Un negocio de servicios que opera con varios profesionales, cada uno con sus propios horarios laborales, márgenes y días libres, tomando reservaciones desde un formulario web, correo electrónico y la ocasional llamada telefónica capturada después.

Contexto de negocio

El proceso manual que reemplazó perdía aproximadamente un horario por semana por dobles reservas y desfases de zona horaria — pocos en número, caros en confianza. El trabajo de la plataforma era hacer el calendario autoritativo y la reservación segura, sin agregar un segundo sistema que se desincronizara.

02

Arquitectura

Un coordinador delgado y sin estado frente a Google Calendar. Una reservación es una transacción corta e idempotente — reservar, verificar, confirmar — enrutada a través de una cola por profesional para que la condición de carrera que causa la doble reserva no pueda ocurrir.

Clienteformulario web / captación por correo
BordeCloud Function — validar + normalizar TZ
ColaCloud Tasks — FIFO por profesional
↓ una reservación a la vez, por profesional ↓
Coordinadorreservar → verificar → confirmar
RegistroFirestore — llaves de idempotencia (TTL)
Fuente de verdadGoogle Calendar — freebusy + eventos

Por qué una cola por profesional

La doble reserva es una condición de carrera entre escritores concurrentes por un solo recurso. En lugar de recurrir a candados distribuidos, cada solicitud para un profesional dado corre a través de una cola FIFO de un solo consumidor — una primitiva aburrida y depurable que hace la carrera imposible en vez de meramente recuperable. La concurrencia entre profesionales se mantiene alta; dentro de un mismo profesional baja a uno.

03

Componentes

La plataforma está construida a partir de nueve componentes. Cada uno está documentado como su propia sección de ingeniería — por qué existe, su arquitectura, las restricciones y casos límite que maneja, las disyuntivas tomadas y la implementación final. Expande cualquiera para leerlo.

C1Flujo de reservación en varios pasosde cara al cliente
Por qué existe
Convierte "encontrar una hora" en una secuencia guiada y retomable — servicio → profesional → fecha → horario → detalles → confirmar — que nunca presenta un horario que no pueda honrar.
Arquitectura
Un cliente sin estado impulsado por el motor de disponibilidad; cada paso se revalida contra la disponibilidad en vivo, así un horario que se llena a mitad del flujo se detecta antes del envío.
Restricciones
Debe funcionar desde un formulario web, un enlace de correo y una reservación telefónica capturada a mano; ningún paso puede depender del reloj del dispositivo del cliente.
Casos límite
Horario ocupado entre la visualización y el envío; reenvío con el botón de retroceso; un profesional que se va de descanso a mitad de sesión.
Disyuntivas
Revalidar cada paso cuesta una lectura extra de disponibilidad pero elimina la falla de "el horario que elegiste ya no está" al confirmar.
C2Motor de disponibilidadmodelo de lectura
Por qué existe
Calcula las ventanas reservables por profesional a partir de horarios laborales, márgenes, eventos existentes y días libres — el modelo de lectura desde el que se renderiza todo el flujo.
Arquitectura
Precalcula las ventanas de forma programada y ante webhooks de cambio de calendario, almacenándolas en caché en Firestore; el flujo lee la caché, no la Calendar API, en la ruta caliente.
Restricciones
Debe mantenerse correcto mientras los profesionales editan sus propios calendarios directamente; no debe exceder la cuota de lectura de Calendar bajo carga.
Casos límite
Eventos superpuestos, bloqueos de día completo, retenciones recurrentes y fronteras de DST donde una ventana de "9 a. m." se recorre.
Disyuntivas
Un TTL de caché corto cambia unos segundos de datos obsoletos por una gran caída en llamadas a la API; el paso de confirmación es la autoridad, así que una obsolescencia breve es segura.
C3API de reservación (reservar · verificar · confirmar)núcleo
Por qué existe
El núcleo transaccional: convierte una solicitud en exactamente un evento de calendario, de forma segura, incluso bajo concurrencia y reintentos.
Arquitectura
Cada solicitud para un profesional corre a través de la cola FIFO de un solo consumidor de ese profesional; confirm() revisa la disponibilidad dentro de esa ventana y escribe con una llave de idempotencia direccionada por contenido.
Contrato de API
POST /booking  → 201 {eventId}  | 409 SlotTaken
// idempotent: same intent ⇒ same eventId
key = sha256(practitionerId, startUTC, clientId)
Casos límite
Solicitudes concurrentes por un solo horario (serializadas y resueltas); reintentos de formulario/red (colapsan a un solo evento vía el registro); falla parcial tras la inserción (el commit al registro lo hace seguro ante reejecución).
Disyuntivas
La serialización por profesional agrega unos cuantos ms de latencia y elimina la carrera por construcción — elegida sobre los candados distribuidos.
C4Integración con Google CalendarWorkspace
Por qué existe
Mantiene Google Calendar como la fuente de verdad — leyendo la disponibilidad y escribiendo eventos — para que el equipo nunca deje la herramienta que ya usa.
Arquitectura
Usa la consulta agregada freebusy para la disponibilidad (sin detalle de eventos) y events.insert para las escrituras, etiquetando cada evento con su llave de reservación en propiedades extendidas privadas.
Restricciones
Cuotas de lectura por minuto; alcances con privilegios mínimos; debe sobrevivir a que los profesionales editen eventos a mano.
Casos límite
Eventos borrados manualmente, calendarios externos compartidos y reconciliación cuando el calendario y el registro no coinciden.
C5Manejo de zonas horariascorrección
Por qué existe
Garantiza que un horario signifique el mismo instante para el cliente, el profesional y el servidor a través de los cambios de horario de verano.
Arquitectura
Almacena el instante en UTC y la zona IANA prevista por el usuario como un campo separado; los dos se recombinan solo al renderizar.
Casos límite
Huecos de adelanto/atraso de reloj, zonas que observan el DST en fechas distintas y clientes que cambian la zona de su dispositivo después de reservar.
Disyuntivas
Cargar una zona explícita es más para almacenar que una marca de tiempo simple, pero es la única forma de preservar la promesa "9 a. m. en Lisboa."
C6Autenticación y permisosseguridad
Por qué existe
Permite que la plataforma actúe sobre los calendarios del dominio con la mínima autoridad que un equipo de seguridad aprobará.
Arquitectura
Una cuenta de servicio dedicada con delegación de dominio de alcance estrecho; cada cuenta se rastrea hasta un dueño y un registro de decisión.
Restricciones
Sin alcances amplios; llaves rotadas de forma programada; acceso revisado en un calendario, no de memoria.
Disyuntivas
El privilegio mínimo implica más configuración por adelantado a cambio de un modelo que pasa la revisión sin excepciones.
C7Notificacionesentrega
Por qué existe
Confirma, recuerda y cancela tanto para el cliente como para el profesional sin jamás enviar dos veces.
Arquitectura
Entrega al menos una vez vía Cloud Tasks con llaves de idempotencia y una cola de mensajes fallidos, para que un reintento nunca envíe por duplicado.
Casos límite
Limitación del proveedor, direcciones rebotadas y una reservación cancelada antes de que se dispare su recordatorio.
C8Generación de Google MeetWorkspace
Por qué existe
Adjunta un enlace de video funcional a cada reservación remota en el momento en que se crea el evento.
Arquitectura
Solicita los datos de conferencia en events.insert para que el enlace de Meet sea parte de la misma escritura atómica que la reservación.
Casos límite
Fallas en la creación de la conferencia (la reservación debe tener éxito de todos modos) y eventos reagendados que conservan su enlace.
C9Reportes en Google Sheetsoperaciones
Por qué existe
Le da al operador una vista familiar y en vivo de las reservaciones y la carga sin un tablero a la medida.
Arquitectura
Sincronización de solo anexado desde el registro hacia una Sheet, tratada como una réplica de lectura — nunca una fuente de verdad.
Disyuntivas
Una Sheet es limitada y ligeramente retrasada, pero es instantáneamente legible para alguien que no es ingeniero, que es justo el punto.
04

Salida visual

Lo que el sistema realmente produce para el cliente y para el operador. Estos son ejemplos del sistema en funcionamiento — cada uno con leyenda y enlazado al componente que lo crea. Coloca las capturas de pantalla reales en los marcos.

El flujo de reservación

El recorrido del cliente en tres pasos: servicio y horario → datos de contacto → fecha y hora → confirmación. Cada paso se revalida contra la disponibilidad en vivo.

El flujo de reservación

Captura real del sistema en funcionamientoComponente: Flujo de reservación en varios pasos

El registro del prospecto

Dónde aterrizan las respuestas del paso de contacto: una fila anexada a la Google Sheet — nombre, empresa, correo de trabajo, origen y marca de tiempo del envío. Usa datos anonimizados o de muestra.

El registro del prospecto

Captura real · datos de muestra / anonimizadosComponente: Reportes en Google Sheets

Evento de calendario creado

La API de reservación escribe directamente en el Google Calendar del profesional — título, hora, zona horaria, ambos asistentes, un enlace de Google Meet y el contexto de captación en la descripción. Prueba de que el sistema crea un artefacto de calendario nativo, no una fila de base de datos privada.

Evento de calendario creado

Componente: API de reservación · Integración con Calendar

Invitación y confirmación al cliente

Lo que recibe el cliente — la invitación y confirmación de Google Calendar, con los detalles de la reunión y el enlace de Meet.

Invitación y confirmación al cliente

Captura real · oculta los datos del destinatarioComponente: Notificaciones · Generación de Google Meet

Notificación interna

Lo que el equipo ve cuando aterriza una reservación — la notificación interna con el contexto de calificación capturado y el flujo de trabajo de origen.

Captura real — notificación interna de reservación

Captura real · anonimizadaComponente: Notificaciones

Falla y recuperación

Los estados que prueban el pensamiento de producción: un horario ocupado entre la visualización y el envío, y el reintento exitoso que sigue. Izquierda: conflicto. Derecha: recuperación.

Captura real — estado de horario ocupado / conflicto
Captura real — reintento exitoso / recuperación

Componente: API de reservación (disponibilidad y concurrencia)

05

Impacto

Resultados objetivos que se derivaron de poner la plataforma en producción — evidencia, no marketing.

Negocio
  • Reemplazó un stack de agendado de Calendly más Zapier con un solo sistema propio.
  • Eliminó el costo recurrente de suscripción a terceros y el pegamento que conectaba las herramientas.
Cliente
  • Confirmación inmediata y confiable en el momento de la reservación.
  • Menos fallas de agendado — ningún horario ofrecido que no se pueda honrar.
Operaciones
  • Reservaciones duplicadas eliminadas.
  • Manejo de zonas horarias automatizado de extremo a extremo.
  • Captura manual de calendario removida del día del equipo.
Ingeniería
  • Una única fuente de verdad — sin base de datos de reservaciones paralela que se desincronice.
  • Escrituras idempotentes y seguras ante reintentos; menos partes móviles que operar.
Escala
  • ~4,000 reservaciones / mes.
  • Cero dobles reservas desde que aterrizó la serialización v2.
06

Documentos técnicos

Registros de ingeniería cronológicos escritos mientras se construía la plataforma — las decisiones, los callejones sin salida y los incidentes tal como sucedieron. Los más recientes primero.

07

Caso de estudio

Una retrospectiva de la plataforma desde la perspectiva del negocio — por qué existe, el enfoque tomado y cómo resultó.

Problema
Un equipo de servicios manejaba su calendario a mano y perdía cerca de un horario por semana por dobles reservas y errores de zona horaria — barato de contar, caro en confianza del cliente.
Objetivo
Hacer el calendario autoritativo y la reservación segura, operable por una sola persona, sin un segundo sistema de registro.
Restricciones
Google Calendar sigue siendo la fuente de verdad; seguridad con privilegios mínimos; correcto bajo concurrencia y reintentos; dentro de las cuotas de la Calendar API.
Enfoque
Un coordinador delgado y sin estado frente a la Calendar API; serialización por profesional para eliminar la carrera; idempotencia direccionada por contenido para eliminar duplicados; UTC más intención para el tiempo.
Arquitectura
Captación → validación en el borde → cola FIFO por profesional → coordinador reservar/verificar/confirmar → Google Calendar, con un pequeño registro de idempotencia. Sin base de datos de reservaciones paralela.
Disyuntivas
Elegí una cola aburrida y demostrablemente correcta sobre los candados distribuidos; acepté segundos de obsolescencia en la disponibilidad por un gran ahorro de cuota; mantuve el estado en la plataforma que ya lo posee.
Resultado
En producción desde feb 2024, ~4,000 reservaciones/mes, cero dobles reservas desde que aterrizó la serialización v2; "¿mi reservación sí pasó?" se volvió un no-evento porque los reintentos son seguros.
Lecciones
  • Serializa el recurso en disputa; no bloquees el mundo entero.
  • La idempotencia es una funcionalidad, no una salvaguarda.
  • Deja que la plataforma conserve el estado que ya posee.
Futuro
Un flujo de reagendado de autoservicio, y mover la limpieza del TTL del registro de cron a la expiración de documentos.
← Todos los proyectos