Del anuncio de Meta a la reunión en Google Meet, con recordatorios automáticos por WhatsApp
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.
Formulario de cuatro pasos con barra de progreso, calendario con disponibilidad en tiempo real por AJAX y diseño mobile-first sin dependencias externas.
Recibe los leads en tiempo real verificando la firma HMAC-SHA256, y asocia automáticamente los datos del lead a la cita.
Crea la sala de reunión al confirmar la cita mediante la API de Google Calendar, e incluye el enlace en los recordatorios.
Confirmación inmediata, recordatorio a 24 horas y recordatorio a 2 horas con el enlace de Meet. Todo queda registrado.
KPIs en tiempo real: citas de hoy, de la semana, confirmadas y leads recibidos.
Listado con filtros por estado, fecha y búsqueda, con acciones de cancelar y completar desde la propia tabla.
Horario semanal configurable día por día, con interruptores y duración de los tramos.
Excepciones puntuales para festivos y vacaciones, o para habilitar días extra.
Historial completo de los mensajes de WhatsApp enviados.
cron/reminders.php recorre las citas próximas y dispara los
avisos correspondientes.
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
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.
| Tabla | Contenido |
|---|---|
| admin_users | Usuarios del panel de administración |
| leads | Leads recibidos desde Meta y Facebook Ads |
| appointments | Citas agendadas con todos sus datos y su enlace de Meet |
| availability_schedule | Horario recurrente por día de la semana |
| availability_exceptions | Días bloqueados o habilitados de forma puntual |
| notification_logs | Registro de todos los mensajes de WhatsApp enviados |
Envío de la confirmación inmediata y de los dos recordatorios. Cada mensaje
queda registrado en notification_logs.
Creación automática de la sala de Google Meet en el momento de confirmar la cita.
Webhook que recibe los leads de Facebook e Instagram Ads en tiempo real, con verificación de firma.
Ejecución programada de cron/reminders.php, protegida contra
acceso web sin clave secreta.
lead_id de Meta en la URL.get_slots.php
devuelve los tramos libres de ese día.session_regenerate_id() en el login para evitar fijación de
sesión.password_hash() y bcrypt.config.php y google_tokens.json excluidos del
repositorio.
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.
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.
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.
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.
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.
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.
La configuración detallada de las tres integraciones está en SETUP.md.
Las credenciales viven en config.php, excluido del control de
versiones.