Volver a Proyectos

📅 BookingApp

Del anuncio de Meta a la reunión en Google Meet, con recordatorios automáticos por WhatsApp

WhatsApp / Twilio Google Meet Meta Lead Ads

Escala del Proyecto

7Tablas
3Integraciones
2Recordatorios
21Archivos
5.1kLíneas

Descripción General

Un negocio que capta clientes con publicidad en Facebook e Instagram tiene un problema de continuidad: el anuncio genera el interés, pero entre el clic y la reunión efectiva se pierde la mitad de los leads. Alguien tiene que llamar, cuadrar agenda, crear la videollamada y recordarla.

BookingApp automatiza toda esa cadena. El usuario llega desde el anuncio a una landing de cuatro pasos, rellena sus datos, ve el calendario con la disponibilidad real, elige hora y confirma. En ese instante el sistema crea la sala de Google Meet, envía la confirmación por WhatsApp y registra todo.

Después vienen los recordatorios: uno 24 horas antes y otro 2 horas antes, este último con el enlace directo a la videollamada. Un cron se encarga de enviarlos. El panel de administración cierra el círculo con KPIs, gestión de citas, configuración de horario semanal, días bloqueados y el log de todos los mensajes enviados.

Tecnologías Utilizadas


PHP 8.1+

MySQL 8

PDO Singleton

Twilio WhatsApp

Google Calendar API

Meta Webhook

Cron

AJAX

Módulos Principales

🌐 Landing pública

Formulario de cuatro pasos con barra de progreso, calendario con disponibilidad en tiempo real por AJAX y diseño mobile-first sin dependencias externas.

📣 Webhook de Meta Lead Ads

Recibe los leads en tiempo real verificando la firma HMAC-SHA256, y asocia automáticamente los datos del lead a la cita.

📹 Google Meet

Crea la sala de reunión al confirmar la cita mediante la API de Google Calendar, e incluye el enlace en los recordatorios.

🔔 Notificaciones WhatsApp

Confirmación inmediata, recordatorio a 24 horas y recordatorio a 2 horas con el enlace de Meet. Todo queda registrado.

📊 Dashboard

KPIs en tiempo real: citas de hoy, de la semana, confirmadas y leads recibidos.

🗂️ Gestión de citas

Listado con filtros por estado, fecha y búsqueda, con acciones de cancelar y completar desde la propia tabla.

🕐 Disponibilidad

Horario semanal configurable día por día, con interruptores y duración de los tramos.

🚫 Días bloqueados

Excepciones puntuales para festivos y vacaciones, o para habilitar días extra.

📜 Log de notificaciones

Historial completo de los mensajes de WhatsApp enviados.

⏰ Cron de recordatorios

cron/reminders.php recorre las citas próximas y dispara los avisos correspondientes.

Arquitectura

Aplicación PHP plana con separación clara entre la parte pública, el panel privado, las integraciones y el cron. La conexión a base de datos se resuelve con un Singleton PDO en db.php, y cada integración externa está encapsulada en su propio fichero de includes/ para que se pueda sustituir sin tocar el flujo de reserva.

booking-app/
├── index.php              # landing con calendario
├── get_slots.php          # AJAX: tramos disponibles
├── process_booking.php    # confirmación de la reserva
├── confirm.php
├── webhook.php            # receptor de Meta Lead Ads
├── db.php                 # conexión PDO Singleton
├── includes/
│   ├── whatsapp.php       # Twilio WhatsApp API
│   ├── google_meet.php    # Google Calendar API
│   ├── helpers.php        # CSRF, formateo
│   └── auth_check.php     # middleware del panel
├── admin/                  # login, dashboard, citas, disponibilidad
├── cron/reminders.php      # recordatorios automáticos
└── sql/schema.sql

Base de Datos

7 tablas. La separación entre horario recurrente y excepciones puntuales es lo que permite configurar "los martes de 10 a 14" y a la vez bloquear un martes concreto sin romper la regla general.

TablaContenido
admin_usersUsuarios del panel de administración
leadsLeads recibidos desde Meta y Facebook Ads
appointmentsCitas agendadas con todos sus datos y su enlace de Meet
availability_scheduleHorario recurrente por día de la semana
availability_exceptionsDías bloqueados o habilitados de forma puntual
notification_logsRegistro de todos los mensajes de WhatsApp enviados

Integraciones Externas

Twilio WhatsApp API

Envío de la confirmación inmediata y de los dos recordatorios. Cada mensaje queda registrado en notification_logs.

Google Calendar API

Creación automática de la sala de Google Meet en el momento de confirmar la cita.

Meta for Developers

Webhook que recibe los leads de Facebook e Instagram Ads en tiempo real, con verificación de firma.

Cron del sistema

Ejecución programada de cron/reminders.php, protegida contra acceso web sin clave secreta.

Del Anuncio a la Reunión

  1. Clic en el anuncio: el usuario llega a la landing con su lead_id de Meta en la URL.
  2. Datos personales: primer paso del formulario: nombre, email y teléfono.
  3. Elección de día: el calendario muestra los días con disponibilidad real.
  4. Elección de hora: una llamada AJAX a get_slots.php devuelve los tramos libres de ese día.
  5. Confirmación: al confirmar se crea la sala de Google Meet, se envía la confirmación por WhatsApp y se registra todo en base de datos.
  6. Recordatorio a 24 horas: el cron detecta la cita del día siguiente y envía el aviso.
  7. Recordatorio a 2 horas: segundo aviso, esta vez con el enlace directo a Google Meet.
  8. Gestión: desde el panel se marca la cita como completada o cancelada.

Seguridad Implementada

  • Verificación HMAC-SHA256 de la firma en el webhook de Meta: sin firma válida no se procesa nada.
  • Token CSRF de sesión en todos los formularios.
  • Prepared statements en todas las consultas.
  • session_regenerate_id() en el login para evitar fijación de sesión.
  • Contraseñas con password_hash() y bcrypt.
  • Retardo de 1 segundo en los intentos de login fallidos como freno al ataque por fuerza bruta.
  • El cron está protegido contra ejecución por web sin clave secreta.
  • config.php y google_tokens.json excluidos del repositorio.

Retos Técnicos y Decisiones de Diseño

Disponibilidad real, no un calendario decorativo

Mostrar todos los tramos y descubrir al confirmar que ya estaba ocupado es la peor experiencia posible. El calendario consulta la disponibilidad por AJAX contra get_slots.php, que cruza el horario recurrente con las excepciones y con las citas ya existentes. Lo que se muestra es lo que hay.

Horario recurrente frente a excepciones

Modelar la agenda como una lista de huecos concretos obliga a generarlos con meses de antelación. Separar availability_schedule — la regla semanal — de availability_exceptions — el caso puntual — permite decir "los martes de 10 a 14" una sola vez y luego bloquear un martes de agosto sin tocar la regla.

Tres integraciones que pueden fallar en el peor momento

En la confirmación conviven tres servicios externos. Si Google falla, la cita no debe perderse; si Twilio falla, la reserva sigue siendo válida. Cada integración está aislada en su fichero, y el log de notificaciones permite ver exactamente qué se envió y qué no, en lugar de suponerlo.

Verificar el webhook antes de confiar en él

Un endpoint público que crea registros es una invitación. La verificación HMAC-SHA256 de la firma de Meta es lo que separa recibir leads de recibir basura: sin firma válida, la petición se descarta antes de tocar la base de datos.

Mi Rol

Desarrollador full stack — autor único.

Modelo de datos, landing multipaso, motor de disponibilidad, las tres integraciones externas, el cron de recordatorios, el panel de administración y la documentación de configuración en SETUP.md.

Estado del Proyecto

Marcado como listo para producción en el repositorio. Requiere PHP 8.1+, MySQL 8, acceso a cron y cuentas de Twilio, Google Cloud y Meta for Developers. Licencia MIT.

Código y Enlaces

La configuración detallada de las tres integraciones está en SETUP.md. Las credenciales viven en config.php, excluido del control de versiones.