Integración de calendario y reservas
Este tutorial muestra cómo crear un flujo de reserva de citas en el que los clientes agendan reuniones por WhatsApp y los eventos aparecen en el calendario de su equipo.
Descripción general de la arquitectura
La integración conecta tres sistemas:
watsi — recibe los mensajes de WhatsApp y envía las respuestas a través de la API- Su backend — procesa las solicitudes de reserva y gestiona la disponibilidad
- Proveedor de calendario — Google Calendar, Outlook, Cal.com o cualquier proveedor con una API de reservas
Customer → WhatsApp → watsi webhook → Your backend → Calendar APIConfigure un receptor de webhooks
Registre una suscripción de webhook para recibir eventos message.received. Consulte el tutorial de webhooks para ver el recorrido completo de configuración.
curl -X POST https://api.watsi.ai/api/v1/webhooks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhooks/watsi",
"events": ["message.received"]
}'Detecte la intención de reserva
Cuando llega un mensaje, verifique si el cliente está pidiendo reservar una cita. Puede usar coincidencia de palabras clave o un LLM para detectar la intención.
app.post('/webhooks/watsi', async (req, res) => {
const event = req.body
const message = event.data.message
// Simple keyword detection
const bookingKeywords = ['book', 'appointment', 'schedule', 'reserve', 'agendar', 'cita']
const wantsBooking = bookingKeywords.some(kw =>
message.body.toLowerCase().includes(kw)
)
if (wantsBooking) {
await handleBookingFlow(event.data)
}
res.sendStatus(200)
})Obtenga los horarios disponibles
Consulte a su proveedor de calendario los horarios disponibles. Este ejemplo usa la API FreeBusy de Google Calendar, pero el mismo patrón funciona con cualquier proveedor.
async function getAvailableSlots(date) {
const calendar = google.calendar({ version: 'v3', auth })
const busy = await calendar.freebusy.query({
requestBody: {
timeMin: startOfDay(date).toISOString(),
timeMax: endOfDay(date).toISOString(),
items: [{ id: CALENDAR_ID }],
},
})
// Compute free 30-minute windows from the busy blocks
return computeFreeWindows(busy.data, 30)
}Envíe los horarios disponibles por WhatsApp
Responda al cliente con los horarios disponibles. Cuando sea posible, dé formato a los horarios en la zona horaria del cliente.
async function sendAvailableSlots(conversationId, slots) {
const formatted = slots
.map((s, i) => `${i + 1}. ${formatTime(s.start)} - ${formatTime(s.end)}`)
.join('\n')
await fetch('https://api.watsi.ai/api/v1/messages', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
conversation_id: conversationId,
body: `Here are the available times:\n\n${formatted}\n\nReply with the number to book.`,
}),
})
}Confirme la reserva
Cuando el cliente responda con su selección, cree el evento de calendario y envíe un mensaje de confirmación.
async function confirmBooking(conversationId, slot, customer) {
// Create the calendar event
await calendar.events.insert({
calendarId: CALENDAR_ID,
requestBody: {
summary: `Meeting with ${customer.name}`,
start: { dateTime: slot.start },
end: { dateTime: slot.end },
attendees: [{ email: customer.email }],
},
})
// Send confirmation via watsi
await fetch('https://api.watsi.ai/api/v1/messages', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
conversation_id: conversationId,
body: `Your appointment is confirmed for ${formatTime(slot.start)}. See you then!`,
}),
})
}Consideraciones para producción
- Manejo de zonas horarias — almacene y muestre los horarios en la zona horaria del cliente. Use el perfil de contacto o pregúntelo durante el flujo.
- Concurrencia — vuelva a verificar la disponibilidad antes de confirmar para evitar reservas duplicadas cuando varios clientes seleccionan el mismo horario.
- Cancelaciones — escuche mensajes de seguimiento como “cancelar” y actualice el evento de calendario en consecuencia.
- Recordatorios — use plantillas de mensajes de WhatsApp para enviar recordatorios de citas fuera de la ventana de mensajería de 24 horas.
- Gestión de estado — lleve el seguimiento del estado del flujo de reserva por conversación (por ejemplo, esperando fecha, esperando selección de horario, confirmada) en su base de datos.
Guías relacionadas
- Descripción general de webhooks — modelo de entrega, encabezados y comportamiento de reintentos
- Tutorial de webhooks — configuración paso a paso del manejador de webhooks
- Referencia de la API — documentación completa de los endpoints de mensajes y conversaciones