Files
WhatsAppCentralizado/docs/api/README.md
Claude AI a92a7efccc Initial commit: Documentación completa del proyecto WhatsApp Centralizado
- 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>
2026-01-29 09:29:57 +00:00

747 lines
12 KiB
Markdown

# API Reference
## Información General
- **Base URL:** `https://tu-dominio.com/api`
- **Autenticación:** Bearer Token (JWT)
- **Content-Type:** `application/json`
## Autenticación
### Login
```http
POST /auth/login
```
**Request:**
```json
{
"email": "usuario@empresa.com",
"password": "tu_password"
}
```
**Response:**
```json
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "bearer",
"user": {
"id": "uuid",
"email": "usuario@empresa.com",
"name": "Usuario",
"role": "admin"
}
}
```
### Refresh Token
```http
POST /auth/refresh
```
### Logout
```http
POST /auth/logout
```
### Usuario Actual
```http
GET /auth/me
```
---
## Usuarios
### Listar Usuarios
```http
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
```http
POST /api/users
```
**Request:**
```json
{
"email": "nuevo@empresa.com",
"password": "password123",
"name": "Nuevo Usuario",
"role": "agent"
}
```
### Obtener Usuario
```http
GET /api/users/{user_id}
```
### Actualizar Usuario
```http
PUT /api/users/{user_id}
```
### Eliminar Usuario
```http
DELETE /api/users/{user_id}
```
### Cambiar Estado
```http
PUT /api/users/{user_id}/status
```
**Request:**
```json
{
"status": "away"
}
```
---
## Cuentas WhatsApp
### Listar Cuentas
```http
GET /api/whatsapp/accounts
```
### Crear Cuenta (Iniciar conexión)
```http
POST /api/whatsapp/accounts
```
**Request:**
```json
{
"name": "Ventas Principal"
}
```
**Response:**
```json
{
"id": "uuid",
"name": "Ventas Principal",
"status": "disconnected",
"qr_code": null
}
```
### Obtener QR Code
```http
GET /api/whatsapp/accounts/{account_id}/qr
```
**Response:**
```json
{
"qr_code": "data:image/png;base64,..."
}
```
### Estado de Cuenta
```http
GET /api/whatsapp/accounts/{account_id}/status
```
### Desconectar Cuenta
```http
POST /api/whatsapp/accounts/{account_id}/disconnect
```
### Reconectar Cuenta
```http
POST /api/whatsapp/accounts/{account_id}/reconnect
```
---
## Contactos
### Listar Contactos
```http
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
```http
POST /api/contacts
```
**Request:**
```json
{
"phone_number": "+525551234567",
"name": "Juan Pérez",
"email": "juan@email.com",
"company": "Empresa ABC",
"tags": ["lead", "interesado"],
"metadata": {
"producto_interes": "Laptop Pro"
}
}
```
### Obtener Contacto
```http
GET /api/contacts/{contact_id}
```
### Actualizar Contacto
```http
PUT /api/contacts/{contact_id}
```
### Agregar Etiquetas
```http
POST /api/contacts/{contact_id}/tags
```
**Request:**
```json
{
"tags": ["vip", "cliente"]
}
```
### Sincronizar con Odoo
```http
POST /api/contacts/{contact_id}/sync-odoo
```
---
## Conversaciones
### Listar Conversaciones
```http
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
```http
GET /api/conversations/{conversation_id}
```
**Response:**
```json
{
"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
```http
POST /api/conversations/{conversation_id}/assign
```
**Request:**
```json
{
"user_id": "uuid"
}
```
### Transferir a Cola
```http
POST /api/conversations/{conversation_id}/transfer
```
**Request:**
```json
{
"queue_id": "uuid"
}
```
### Resolver Conversación
```http
POST /api/conversations/{conversation_id}/resolve
```
**Request:**
```json
{
"resolution_note": "Problema resuelto"
}
```
### Reabrir Conversación
```http
POST /api/conversations/{conversation_id}/reopen
```
---
## Mensajes
### Listar Mensajes de Conversación
```http
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
```http
POST /api/conversations/{conversation_id}/messages
```
**Request (texto):**
```json
{
"type": "text",
"content": "Hola, ¿en qué te puedo ayudar?"
}
```
**Request (imagen):**
```json
{
"type": "image",
"media_url": "https://example.com/image.jpg",
"content": "Caption opcional"
}
```
**Request (botones):**
```json
{
"type": "buttons",
"content": "¿Qué necesitas?",
"metadata": {
"buttons": [
{"id": "ventas", "text": "Ventas"},
{"id": "soporte", "text": "Soporte"},
{"id": "otro", "text": "Otro"}
]
}
}
```
**Request (lista):**
```json
{
"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
```http
POST /api/conversations/{conversation_id}/notes
```
**Request:**
```json
{
"content": "Cliente interesado, dar seguimiento"
}
```
---
## Flujos
### Listar Flujos
```http
GET /api/flows
```
### Crear Flujo
```http
POST /api/flows
```
**Request:**
```json
{
"name": "Bienvenida",
"description": "Flujo de bienvenida para nuevos contactos",
"trigger_type": "welcome",
"trigger_value": null,
"nodes": {
"nodes": [...],
"edges": [...],
"viewport": {...}
},
"is_active": true
}
```
### Obtener Flujo
```http
GET /api/flows/{flow_id}
```
### Actualizar Flujo
```http
PUT /api/flows/{flow_id}
```
### Duplicar Flujo
```http
POST /api/flows/{flow_id}/duplicate
```
### Activar/Desactivar Flujo
```http
PUT /api/flows/{flow_id}/toggle
```
### Probar Flujo
```http
POST /api/flows/{flow_id}/test
```
**Request:**
```json
{
"phone_number": "+525551234567",
"initial_message": "Hola"
}
```
---
## Colas
### Listar Colas
```http
GET /api/queues
```
### Crear Cola
```http
POST /api/queues
```
**Request:**
```json
{
"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
```http
GET /api/queues/{queue_id}
```
### Actualizar Cola
```http
PUT /api/queues/{queue_id}
```
### Agregar Agente a Cola
```http
POST /api/queues/{queue_id}/agents
```
**Request:**
```json
{
"user_id": "uuid",
"is_supervisor": false,
"skills": ["ventas", "ingles"]
}
```
### Remover Agente de Cola
```http
DELETE /api/queues/{queue_id}/agents/{user_id}
```
### Estadísticas de Cola
```http
GET /api/queues/{queue_id}/stats
```
**Response:**
```json
{
"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
```http
GET /api/quick-replies
```
### Crear Respuesta Rápida
```http
POST /api/quick-replies
```
**Request:**
```json
{
"shortcut": "/saludo",
"content": "¡Hola {{contact.name}}! Soy {{agent.name}}, ¿en qué te puedo ayudar?",
"queue_id": null
}
```
### Actualizar Respuesta Rápida
```http
PUT /api/quick-replies/{id}
```
### Eliminar Respuesta Rápida
```http
DELETE /api/quick-replies/{id}
```
---
## Odoo
### Probar Conexión
```http
POST /api/odoo/test-connection
```
### Sincronizar Contactos
```http
POST /api/odoo/sync-contacts
```
### Buscar Partner
```http
GET /api/odoo/partners/search
```
**Query Parameters:**
| Parámetro | Tipo | Descripción |
|-----------|------|-------------|
| phone | string | Buscar por teléfono |
| email | string | Buscar por email |
| name | string | Buscar por nombre |
### Buscar Pedidos
```http
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
```http
GET /api/odoo/products/{product_id}/stock
```
### Crear Lead
```http
POST /api/odoo/leads
```
**Request:**
```json
{
"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
```javascript
const socket = io('wss://tu-dominio.com', {
auth: {
token: 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...'
}
});
```
### Eventos del Servidor
**Nuevo mensaje:**
```javascript
socket.on('new_message', (data) => {
// data: { conversation_id, message }
});
```
**Estado de mensaje:**
```javascript
socket.on('message_status', (data) => {
// data: { message_id, status: 'delivered' | 'read' }
});
```
**Conversación asignada:**
```javascript
socket.on('conversation_assigned', (data) => {
// data: { conversation_id, assigned_to }
});
```
**QR Code:**
```javascript
socket.on('qr_code', (data) => {
// data: { account_id, qr_code }
});
```
**Estado de conexión WhatsApp:**
```javascript
socket.on('connection_status', (data) => {
// data: { account_id, status: 'connected' | 'disconnected' }
});
```
### Eventos del Cliente
**Unirse a conversación:**
```javascript
socket.emit('join_conversation', { conversation_id: 'uuid' });
```
**Escribiendo:**
```javascript
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:**
```json
{
"detail": {
"code": "VALIDATION_ERROR",
"message": "El campo email es requerido",
"field": "email"
}
}
```