- README principal con descripción del proyecto - Documento de diseño completo (arquitectura, DB, flujos) - Documentación de API REST y WebSocket - Guía del Flow Builder (30+ tipos de nodos) - Documentación de integración con Odoo - Guía de despliegue con Docker - Esquema de base de datos - Estructura de carpetas del proyecto - Archivo .env.example con todas las variables Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
12 KiB
12 KiB
API Reference
Información General
- Base URL:
https://tu-dominio.com/api - Autenticación: Bearer Token (JWT)
- Content-Type:
application/json
Autenticación
Login
POST /auth/login
Request:
{
"email": "usuario@empresa.com",
"password": "tu_password"
}
Response:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "bearer",
"user": {
"id": "uuid",
"email": "usuario@empresa.com",
"name": "Usuario",
"role": "admin"
}
}
Refresh Token
POST /auth/refresh
Logout
POST /auth/logout
Usuario Actual
GET /auth/me
Usuarios
Listar Usuarios
GET /api/users
Query Parameters:
| Parámetro | Tipo | Descripción |
|---|---|---|
| role | string | Filtrar por rol (admin, supervisor, agent) |
| status | string | Filtrar por estado (online, offline, away) |
| page | int | Página (default: 1) |
| limit | int | Límite por página (default: 20) |
Crear Usuario
POST /api/users
Request:
{
"email": "nuevo@empresa.com",
"password": "password123",
"name": "Nuevo Usuario",
"role": "agent"
}
Obtener Usuario
GET /api/users/{user_id}
Actualizar Usuario
PUT /api/users/{user_id}
Eliminar Usuario
DELETE /api/users/{user_id}
Cambiar Estado
PUT /api/users/{user_id}/status
Request:
{
"status": "away"
}
Cuentas WhatsApp
Listar Cuentas
GET /api/whatsapp/accounts
Crear Cuenta (Iniciar conexión)
POST /api/whatsapp/accounts
Request:
{
"name": "Ventas Principal"
}
Response:
{
"id": "uuid",
"name": "Ventas Principal",
"status": "disconnected",
"qr_code": null
}
Obtener QR Code
GET /api/whatsapp/accounts/{account_id}/qr
Response:
{
"qr_code": "data:image/png;base64,..."
}
Estado de Cuenta
GET /api/whatsapp/accounts/{account_id}/status
Desconectar Cuenta
POST /api/whatsapp/accounts/{account_id}/disconnect
Reconectar Cuenta
POST /api/whatsapp/accounts/{account_id}/reconnect
Contactos
Listar Contactos
GET /api/contacts
Query Parameters:
| Parámetro | Tipo | Descripción |
|---|---|---|
| search | string | Buscar por nombre, teléfono o email |
| tags | string[] | Filtrar por etiquetas |
| has_odoo | boolean | Filtrar sincronizados con Odoo |
| page | int | Página |
| limit | int | Límite |
Crear Contacto
POST /api/contacts
Request:
{
"phone_number": "+525551234567",
"name": "Juan Pérez",
"email": "juan@email.com",
"company": "Empresa ABC",
"tags": ["lead", "interesado"],
"metadata": {
"producto_interes": "Laptop Pro"
}
}
Obtener Contacto
GET /api/contacts/{contact_id}
Actualizar Contacto
PUT /api/contacts/{contact_id}
Agregar Etiquetas
POST /api/contacts/{contact_id}/tags
Request:
{
"tags": ["vip", "cliente"]
}
Sincronizar con Odoo
POST /api/contacts/{contact_id}/sync-odoo
Conversaciones
Listar Conversaciones
GET /api/conversations
Query Parameters:
| Parámetro | Tipo | Descripción |
|---|---|---|
| status | string | bot, waiting, active, resolved |
| queue_id | uuid | Filtrar por cola |
| assigned_to | uuid | Filtrar por agente |
| priority | string | low, normal, high, urgent |
| page | int | Página |
| limit | int | Límite |
Obtener Conversación
GET /api/conversations/{conversation_id}
Response:
{
"id": "uuid",
"contact": {
"id": "uuid",
"name": "Juan Pérez",
"phone_number": "+525551234567"
},
"whatsapp_account": {
"id": "uuid",
"name": "Ventas Principal"
},
"status": "active",
"priority": "normal",
"assigned_to": {
"id": "uuid",
"name": "María García"
},
"queue": {
"id": "uuid",
"name": "Ventas"
},
"current_flow": null,
"sla_first_response_met": true,
"last_message_at": "2024-01-15T14:30:00Z",
"created_at": "2024-01-15T14:25:00Z"
}
Asignar Conversación
POST /api/conversations/{conversation_id}/assign
Request:
{
"user_id": "uuid"
}
Transferir a Cola
POST /api/conversations/{conversation_id}/transfer
Request:
{
"queue_id": "uuid"
}
Resolver Conversación
POST /api/conversations/{conversation_id}/resolve
Request:
{
"resolution_note": "Problema resuelto"
}
Reabrir Conversación
POST /api/conversations/{conversation_id}/reopen
Mensajes
Listar Mensajes de Conversación
GET /api/conversations/{conversation_id}/messages
Query Parameters:
| Parámetro | Tipo | Descripción |
|---|---|---|
| before | uuid | Mensajes antes de este ID |
| limit | int | Límite (default: 50) |
Enviar Mensaje
POST /api/conversations/{conversation_id}/messages
Request (texto):
{
"type": "text",
"content": "Hola, ¿en qué te puedo ayudar?"
}
Request (imagen):
{
"type": "image",
"media_url": "https://example.com/image.jpg",
"content": "Caption opcional"
}
Request (botones):
{
"type": "buttons",
"content": "¿Qué necesitas?",
"metadata": {
"buttons": [
{"id": "ventas", "text": "Ventas"},
{"id": "soporte", "text": "Soporte"},
{"id": "otro", "text": "Otro"}
]
}
}
Request (lista):
{
"type": "list",
"content": "Selecciona una opción:",
"metadata": {
"button_text": "Ver opciones",
"sections": [
{
"title": "Productos",
"rows": [
{"id": "laptop", "title": "Laptops", "description": "Ver laptops disponibles"},
{"id": "telefono", "title": "Teléfonos", "description": "Ver teléfonos"}
]
}
]
}
}
Enviar Nota Interna
POST /api/conversations/{conversation_id}/notes
Request:
{
"content": "Cliente interesado, dar seguimiento"
}
Flujos
Listar Flujos
GET /api/flows
Crear Flujo
POST /api/flows
Request:
{
"name": "Bienvenida",
"description": "Flujo de bienvenida para nuevos contactos",
"trigger_type": "welcome",
"trigger_value": null,
"nodes": {
"nodes": [...],
"edges": [...],
"viewport": {...}
},
"is_active": true
}
Obtener Flujo
GET /api/flows/{flow_id}
Actualizar Flujo
PUT /api/flows/{flow_id}
Duplicar Flujo
POST /api/flows/{flow_id}/duplicate
Activar/Desactivar Flujo
PUT /api/flows/{flow_id}/toggle
Probar Flujo
POST /api/flows/{flow_id}/test
Request:
{
"phone_number": "+525551234567",
"initial_message": "Hola"
}
Colas
Listar Colas
GET /api/queues
Crear Cola
POST /api/queues
Request:
{
"name": "Ventas",
"description": "Cola de atención de ventas",
"assignment_method": "least_busy",
"max_per_agent": 8,
"sla_first_response": 180,
"sla_resolution": 3600,
"business_hours": {
"monday": {"start": "09:00", "end": "18:00"},
"tuesday": {"start": "09:00", "end": "18:00"},
"wednesday": {"start": "09:00", "end": "18:00"},
"thursday": {"start": "09:00", "end": "18:00"},
"friday": {"start": "09:00", "end": "17:00"},
"saturday": {"start": "10:00", "end": "14:00"},
"sunday": null
},
"fallback_flow_id": "uuid"
}
Obtener Cola
GET /api/queues/{queue_id}
Actualizar Cola
PUT /api/queues/{queue_id}
Agregar Agente a Cola
POST /api/queues/{queue_id}/agents
Request:
{
"user_id": "uuid",
"is_supervisor": false,
"skills": ["ventas", "ingles"]
}
Remover Agente de Cola
DELETE /api/queues/{queue_id}/agents/{user_id}
Estadísticas de Cola
GET /api/queues/{queue_id}/stats
Response:
{
"waiting": 5,
"active": 12,
"resolved_today": 47,
"avg_first_response": 142,
"avg_resolution": 1823,
"sla_compliance": 0.91,
"agents": [
{
"user_id": "uuid",
"name": "María García",
"status": "online",
"active_conversations": 5,
"resolved_today": 12
}
]
}
Respuestas Rápidas
Listar Respuestas Rápidas
GET /api/quick-replies
Crear Respuesta Rápida
POST /api/quick-replies
Request:
{
"shortcut": "/saludo",
"content": "¡Hola {{contact.name}}! Soy {{agent.name}}, ¿en qué te puedo ayudar?",
"queue_id": null
}
Actualizar Respuesta Rápida
PUT /api/quick-replies/{id}
Eliminar Respuesta Rápida
DELETE /api/quick-replies/{id}
Odoo
Probar Conexión
POST /api/odoo/test-connection
Sincronizar Contactos
POST /api/odoo/sync-contacts
Buscar Partner
GET /api/odoo/partners/search
Query Parameters:
| Parámetro | Tipo | Descripción |
|---|---|---|
| phone | string | Buscar por teléfono |
| string | Buscar por email | |
| name | string | Buscar por nombre |
Buscar Pedidos
GET /api/odoo/orders
Query Parameters:
| Parámetro | Tipo | Descripción |
|---|---|---|
| partner_id | int | ID del partner en Odoo |
| state | string | Estado del pedido |
| limit | int | Límite |
Consultar Stock
GET /api/odoo/products/{product_id}/stock
Crear Lead
POST /api/odoo/leads
Request:
{
"name": "Interés en Producto X",
"contact_name": "Juan Pérez",
"phone": "+525551234567",
"email": "juan@email.com",
"description": "Cliente interesado en laptops",
"expected_revenue": 5000
}
WebSocket
Conexión
const socket = io('wss://tu-dominio.com', {
auth: {
token: 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...'
}
});
Eventos del Servidor
Nuevo mensaje:
socket.on('new_message', (data) => {
// data: { conversation_id, message }
});
Estado de mensaje:
socket.on('message_status', (data) => {
// data: { message_id, status: 'delivered' | 'read' }
});
Conversación asignada:
socket.on('conversation_assigned', (data) => {
// data: { conversation_id, assigned_to }
});
QR Code:
socket.on('qr_code', (data) => {
// data: { account_id, qr_code }
});
Estado de conexión WhatsApp:
socket.on('connection_status', (data) => {
// data: { account_id, status: 'connected' | 'disconnected' }
});
Eventos del Cliente
Unirse a conversación:
socket.emit('join_conversation', { conversation_id: 'uuid' });
Escribiendo:
socket.emit('typing', { conversation_id: 'uuid' });
Códigos de Error
| Código | Descripción |
|---|---|
| 400 | Bad Request - Datos inválidos |
| 401 | Unauthorized - Token inválido o expirado |
| 403 | Forbidden - Sin permisos |
| 404 | Not Found - Recurso no encontrado |
| 409 | Conflict - Conflicto de datos |
| 422 | Unprocessable Entity - Validación fallida |
| 429 | Too Many Requests - Rate limit excedido |
| 500 | Internal Server Error |
Formato de error:
{
"detail": {
"code": "VALIDATION_ERROR",
"message": "El campo email es requerido",
"field": "email"
}
}