Commit inicial: Sales Bot - Sistema de Automatización de Ventas
- Stack completo con Mattermost, NocoDB y Sales Bot - Procesamiento OCR de tickets con Tesseract - Sistema de comisiones por tubos de tinte - Comandos slash /metas y /ranking - Documentación completa del proyecto Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
329
docs/API.md
Normal file
329
docs/API.md
Normal file
@@ -0,0 +1,329 @@
|
||||
# Documentación de API
|
||||
|
||||
## Sales Bot API
|
||||
|
||||
### Base URL
|
||||
```
|
||||
http://192.168.10.204:5000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Endpoints
|
||||
|
||||
### Health Check
|
||||
|
||||
Verifica el estado del servicio.
|
||||
|
||||
```http
|
||||
GET /health
|
||||
```
|
||||
|
||||
**Respuesta exitosa (200):**
|
||||
```json
|
||||
{
|
||||
"status": "healthy",
|
||||
"timestamp": "2024-01-15T10:30:45.123456",
|
||||
"version": "1.0.0",
|
||||
"services": {
|
||||
"mattermost": "connected",
|
||||
"nocodb": "connected"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Webhook Mattermost
|
||||
|
||||
Recibe webhooks salientes de Mattermost cuando se envía un mensaje de venta.
|
||||
|
||||
```http
|
||||
POST /webhook/mattermost
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
```
|
||||
|
||||
**Parámetros:**
|
||||
|
||||
| Campo | Tipo | Descripción |
|
||||
|-------|------|-------------|
|
||||
| token | string | Token de verificación del webhook |
|
||||
| team_id | string | ID del team |
|
||||
| team_domain | string | Dominio del team |
|
||||
| channel_id | string | ID del canal |
|
||||
| channel_name | string | Nombre del canal |
|
||||
| timestamp | number | Timestamp del mensaje |
|
||||
| user_id | string | ID del usuario |
|
||||
| user_name | string | Nombre de usuario |
|
||||
| post_id | string | ID del post |
|
||||
| text | string | Texto del mensaje |
|
||||
| file_ids | string | IDs de archivos adjuntos (separados por coma) |
|
||||
|
||||
**Respuesta exitosa (200):**
|
||||
```json
|
||||
{
|
||||
"response_type": "comment",
|
||||
"text": "✅ Venta registrada correctamente\n\n**Monto:** $1,500.00\n**Cliente:** Juan Pérez\n**Vendedor:** @vendedor1\n\n📊 **Estadísticas del día:**\n- Tubos vendidos: 5\n- Meta diaria: 3\n- Comisión: $20.00"
|
||||
}
|
||||
```
|
||||
|
||||
**Error (400):**
|
||||
```json
|
||||
{
|
||||
"error": "Token inválido"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Webhook NocoDB
|
||||
|
||||
Recibe webhooks de NocoDB cuando hay cambios en las tablas.
|
||||
|
||||
```http
|
||||
POST /webhook/nocodb
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**Payload:**
|
||||
```json
|
||||
{
|
||||
"type": "records.after.insert",
|
||||
"data": {
|
||||
"table_name": "Ventas",
|
||||
"rows": [...]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Comando /metas
|
||||
|
||||
Muestra el progreso de metas del vendedor.
|
||||
|
||||
```http
|
||||
POST /comando/metas
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
```
|
||||
|
||||
**Parámetros:**
|
||||
|
||||
| Campo | Tipo | Descripción |
|
||||
|-------|------|-------------|
|
||||
| user_name | string | Nombre de usuario que ejecuta el comando |
|
||||
| channel_id | string | ID del canal |
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"response_type": "ephemeral",
|
||||
"text": "📊 **Tus metas - Enero 2024**\n\n**Tubos vendidos hoy:** 5/3 ✅\n**Comisión del día:** $20.00\n\n**Mes actual:**\n- Total tubos: 45\n- Comisión acumulada: $150.00\n- Total vendido: $15,000.00"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Comando /ranking
|
||||
|
||||
Muestra el ranking de vendedores.
|
||||
|
||||
```http
|
||||
POST /comando/ranking
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
```
|
||||
|
||||
**Parámetros:**
|
||||
|
||||
| Campo | Tipo | Descripción |
|
||||
|-------|------|-------------|
|
||||
| channel_id | string | ID del canal |
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"response_type": "in_channel",
|
||||
"text": "🏆 **Ranking de Vendedores - Enero 2024**\n\n1. 🥇 @vendedor1 - $25,000.00 (75 tubos)\n2. 🥈 @vendedor2 - $20,000.00 (60 tubos)\n3. 🥉 @vendedor3 - $15,000.00 (45 tubos)"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## NocoDB API
|
||||
|
||||
### Base URL
|
||||
```
|
||||
http://192.168.10.204:8080/api/v2
|
||||
```
|
||||
|
||||
### Autenticación
|
||||
```http
|
||||
xc-token: <API_TOKEN>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Listar Vendedores
|
||||
|
||||
```http
|
||||
GET /tables/{TABLE_ID}/records
|
||||
xc-token: <TOKEN>
|
||||
```
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"list": [
|
||||
{
|
||||
"Id": 1,
|
||||
"username": "vendedor1",
|
||||
"nombre_completo": "Juan Pérez",
|
||||
"email": "juan@ejemplo.com",
|
||||
"meta_diaria_tubos": 3,
|
||||
"activo": true,
|
||||
"fecha_registro": "2024-01-01T00:00:00.000Z"
|
||||
}
|
||||
],
|
||||
"pageInfo": {
|
||||
"totalRows": 1,
|
||||
"page": 1,
|
||||
"pageSize": 25
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Crear Venta
|
||||
|
||||
```http
|
||||
POST /tables/{TABLE_ID}/records
|
||||
xc-token: <TOKEN>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**Body:**
|
||||
```json
|
||||
{
|
||||
"vendedor_username": "vendedor1",
|
||||
"monto": 1500.00,
|
||||
"cliente": "Juan Pérez",
|
||||
"fecha_venta": "2024-01-15T10:30:00.000Z",
|
||||
"estado": "completada",
|
||||
"canal": "ventas-general",
|
||||
"mensaje_id": "abc123",
|
||||
"descripcion": "Venta de tintes"
|
||||
}
|
||||
```
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"Id": 1,
|
||||
"vendedor_username": "vendedor1",
|
||||
"monto": 1500.00,
|
||||
"cliente": "Juan Pérez",
|
||||
"fecha_venta": "2024-01-15T10:30:00.000Z",
|
||||
"estado": "completada",
|
||||
"canal": "ventas-general",
|
||||
"mensaje_id": "abc123",
|
||||
"descripcion": "Venta de tintes"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Filtrar Ventas por Fecha
|
||||
|
||||
```http
|
||||
GET /tables/{TABLE_ID}/records?where=(fecha_venta,gte,2024-01-15)~and(fecha_venta,lt,2024-01-16)
|
||||
xc-token: <TOKEN>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Obtener Ranking
|
||||
|
||||
```http
|
||||
GET /tables/{TABLE_ID}/records?sort=-monto&limit=10
|
||||
xc-token: <TOKEN>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Mattermost API
|
||||
|
||||
### Base URL
|
||||
```
|
||||
http://192.168.10.204:8065/api/v4
|
||||
```
|
||||
|
||||
### Autenticación
|
||||
```http
|
||||
Authorization: Bearer <BOT_TOKEN>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Enviar Mensaje
|
||||
|
||||
```http
|
||||
POST /posts
|
||||
Authorization: Bearer <TOKEN>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**Body:**
|
||||
```json
|
||||
{
|
||||
"channel_id": "abc123",
|
||||
"message": "Mensaje de texto"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Agregar Reacción
|
||||
|
||||
```http
|
||||
POST /reactions
|
||||
Authorization: Bearer <TOKEN>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**Body:**
|
||||
```json
|
||||
{
|
||||
"user_id": "user123",
|
||||
"post_id": "post123",
|
||||
"emoji_name": "white_check_mark"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Obtener Archivo
|
||||
|
||||
```http
|
||||
GET /files/{file_id}
|
||||
Authorization: Bearer <TOKEN>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Códigos de Error
|
||||
|
||||
| Código | Descripción |
|
||||
|--------|-------------|
|
||||
| 200 | Éxito |
|
||||
| 400 | Solicitud inválida |
|
||||
| 401 | No autorizado |
|
||||
| 403 | Prohibido |
|
||||
| 404 | No encontrado |
|
||||
| 500 | Error interno del servidor |
|
||||
|
||||
## Rate Limiting
|
||||
|
||||
- Sales Bot: Sin límite interno
|
||||
- Mattermost: 10 requests/segundo por usuario
|
||||
- NocoDB: 100 requests/minuto por token
|
||||
208
docs/ARQUITECTURA.md
Normal file
208
docs/ARQUITECTURA.md
Normal file
@@ -0,0 +1,208 @@
|
||||
# Arquitectura del Sistema
|
||||
|
||||
## Diagrama General
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ INFRAESTRUCTURA │
|
||||
│ (Docker Compose) │
|
||||
└─────────────────────────────────────┘
|
||||
│
|
||||
┌──────────────────────────────────────────┼──────────────────────────────────────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐
|
||||
│ MATTERMOST │ │ SALES BOT │ │ NOCODB │
|
||||
│ (Puerto 8065) │◄────────────────►│ (Puerto 5000) │◄────────────────►│ (Puerto 8080) │
|
||||
├─────────────────────┤ ├─────────────────────┤ ├─────────────────────┤
|
||||
│ - Chat empresarial │ │ - Flask/Gunicorn │ │ - UI visual │
|
||||
│ - Webhooks │ │ - OCR Tesseract │ │ - API REST │
|
||||
│ - Comandos slash │ │ - WebSocket client │ │ - Relaciones │
|
||||
│ - Archivos/imágenes │ │ - Handlers │ │ - Webhooks │
|
||||
├─────────────────────┤ ├─────────────────────┤ ├─────────────────────┤
|
||||
│ PostgreSQL │ │ Python 3.12 │ │ PostgreSQL │
|
||||
└─────────────────────┘ └─────────────────────┘ └─────────────────────┘
|
||||
```
|
||||
|
||||
## Flujo de Datos
|
||||
|
||||
```
|
||||
┌──────────┐ ┌────────────┐ ┌───────────┐ ┌─────────┐ ┌────────────┐
|
||||
│ VENDEDOR │────►│ MATTERMOST │────►│ SALES BOT │────►│ NOCODB │────►│ RESPUESTA │
|
||||
└──────────┘ └────────────┘ └───────────┘ └─────────┘ └────────────┘
|
||||
│ │ │ │ │
|
||||
│ │ │ │ │
|
||||
▼ ▼ ▼ ▼ ▼
|
||||
Mensaje Webhook POST Procesamiento Registro DB Mensaje +
|
||||
+ Imagen + Payload OCR + Datos Reacción
|
||||
```
|
||||
|
||||
## Redes Docker
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ HOST (192.168.10.204) │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ │
|
||||
│ │ mattermost-network │ │ sales-bot-network │ │ nocodb-network │ │
|
||||
│ │ (bridge) │ │ (bridge) │ │ (bridge) │ │
|
||||
│ ├─────────────────────┤ ├─────────────────────┤ ├─────────────────────┤ │
|
||||
│ │ mattermost:8065 ◄┼──┼► sales-bot:5000 ◄┼──┼► nocodb:8080 │ │
|
||||
│ │ postgres:5432 │ │ │ │ postgres:5432 │ │
|
||||
│ └─────────────────────┘ └─────────────────────┘ └─────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Componentes del Sales Bot
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ SALES BOT │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
||||
│ │ app.py │ │ handlers.py │ │ ocr_processor │ │
|
||||
│ │ ─────────────── │ │ ─────────────── │ │ ─────────────── │ │
|
||||
│ │ Flask App │────►│ handle_venta │────►│ Tesseract OCR │ │
|
||||
│ │ Endpoints │ │ Lógica negocio │ │ OpenCV │ │
|
||||
│ │ Inicialización │ │ Comisiones │ │ Preprocesamiento│ │
|
||||
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
|
||||
│ │ │ │ │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
||||
│ │ websocket_ │ │ mattermost_ │ │ nocodb_ │ │
|
||||
│ │ listener.py │ │ client.py │ │ client.py │ │
|
||||
│ │ ─────────────── │ │ ─────────────── │ │ ─────────────── │ │
|
||||
│ │ Eventos tiempo │ │ API Mattermost │ │ API NocoDB │ │
|
||||
│ │ real │ │ Mensajes │ │ CRUD tablas │ │
|
||||
│ │ Thread separado │ │ Archivos │ │ Comisiones │ │
|
||||
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ utils.py │ │
|
||||
│ │ ─────────────────────────────────────────────────────────────── │ │
|
||||
│ │ extraer_monto() │ extraer_cliente() │ extraer_tubos() │ etc. │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Proceso de Venta
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ PROCESO DE REGISTRO DE VENTA │
|
||||
├────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 1. RECEPCIÓN │
|
||||
│ ┌─────────────────┐ │
|
||||
│ │ Vendedor envía │ │
|
||||
│ │ mensaje + foto │ │
|
||||
│ └────────┬────────┘ │
|
||||
│ │ │
|
||||
│ 2. WEBHOOK │
|
||||
│ ┌────────▼────────┐ │
|
||||
│ │ Mattermost │ │
|
||||
│ │ Outgoing Hook │ │
|
||||
│ └────────┬────────┘ │
|
||||
│ │ │
|
||||
│ 3. EXTRACCIÓN │
|
||||
│ ┌────────▼────────┐ ┌─────────────────┐ │
|
||||
│ │ Parseo de texto │────►│ @monto 1500 │ │
|
||||
│ │ │ │ @cliente Juan │ │
|
||||
│ │ │ │ @tubos 5 │ │
|
||||
│ └────────┬────────┘ └─────────────────┘ │
|
||||
│ │ │
|
||||
│ 4. OCR (si hay imagen) │
|
||||
│ ┌────────▼────────┐ ┌─────────────────┐ │
|
||||
│ │ Descargar img │────►│ Preprocesamiento│ │
|
||||
│ │ de Mattermost │ │ OCR Tesseract │ │
|
||||
│ └────────┬────────┘ │ Detección tubos │ │
|
||||
│ │ └─────────────────┘ │
|
||||
│ │ │
|
||||
│ 5. VALIDACIÓN │
|
||||
│ ┌────────▼────────┐ │
|
||||
│ │ Monto OCR vs │ │
|
||||
│ │ Monto mensaje │ │
|
||||
│ │ (tolerancia 5%) │ │
|
||||
│ └────────┬────────┘ │
|
||||
│ │ │
|
||||
│ 6. REGISTRO │
|
||||
│ ┌────────▼────────┐ ┌─────────────────┐ │
|
||||
│ │ NocoDB API │────►│ Vendedor │ │
|
||||
│ │ │ │ Venta │ │
|
||||
│ │ │ │ Detalle │ │
|
||||
│ │ │ │ Meta │ │
|
||||
│ └────────┬────────┘ └─────────────────┘ │
|
||||
│ │ │
|
||||
│ 7. COMISIONES │
|
||||
│ ┌────────▼────────┐ ┌─────────────────┐ │
|
||||
│ │ Calcular │────►│ tubos > 3? │ │
|
||||
│ │ comisión │ │ comisión = $10 │ │
|
||||
│ │ │ │ × (tubos - 3) │ │
|
||||
│ └────────┬────────┘ └─────────────────┘ │
|
||||
│ │ │
|
||||
│ 8. RESPUESTA │
|
||||
│ ┌────────▼────────┐ │
|
||||
│ │ Mensaje en │ │
|
||||
│ │ Mattermost + │ │
|
||||
│ │ Reacción ✓ │ │
|
||||
│ └─────────────────┘ │
|
||||
│ │
|
||||
└────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Seguridad
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ CAPA DE SEGURIDAD │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────┐ ┌─────────────────────┐ │
|
||||
│ │ Mattermost Auth │ │ NocoDB Auth │ │
|
||||
│ │ ───────────────── │ │ ───────────────── │ │
|
||||
│ │ Bot Token │ │ API Token (JWT) │ │
|
||||
│ │ Webhook Secret │ │ Bearer Auth │ │
|
||||
│ └─────────────────────┘ └─────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ Contenedor Sales Bot │ │
|
||||
│ │ ───────────────────────────────────────────────── │ │
|
||||
│ │ Usuario: salesbot (no-root) │ │
|
||||
│ │ Filesystem: read-only donde es posible │ │
|
||||
│ │ Red: bridge aislada │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Escalabilidad
|
||||
|
||||
```
|
||||
┌─────────────────────┐
|
||||
│ Load Balancer │
|
||||
│ (futuro) │
|
||||
└──────────┬──────────┘
|
||||
│
|
||||
┌───────────────────┼───────────────────┐
|
||||
│ │ │
|
||||
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
|
||||
│ Sales Bot │ │ Sales Bot │ │ Sales Bot │
|
||||
│ Worker 1 │ │ Worker 2 │ │ Worker 3 │
|
||||
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
|
||||
│ │ │
|
||||
└───────────────────┼───────────────────┘
|
||||
│
|
||||
┌──────────▼──────────┐
|
||||
│ NocoDB │
|
||||
│ (PostgreSQL) │
|
||||
└─────────────────────┘
|
||||
```
|
||||
|
||||
El sistema está preparado para escalar horizontalmente gracias a:
|
||||
- Gunicorn con múltiples workers
|
||||
- Base de datos centralizada
|
||||
- Contenedores stateless
|
||||
296
docs/INSTALACION.md
Normal file
296
docs/INSTALACION.md
Normal file
@@ -0,0 +1,296 @@
|
||||
# Guía de Instalación
|
||||
|
||||
## Requisitos del Sistema
|
||||
|
||||
### Hardware Mínimo
|
||||
- CPU: 2 cores
|
||||
- RAM: 4 GB
|
||||
- Disco: 20 GB
|
||||
|
||||
### Software
|
||||
- Docker 20.10+
|
||||
- Docker Compose 2.0+
|
||||
- Git
|
||||
|
||||
### Red
|
||||
- Puerto 5000 (Sales Bot)
|
||||
- Puerto 8065 (Mattermost)
|
||||
- Puerto 8080 (NocoDB)
|
||||
|
||||
---
|
||||
|
||||
## Instalación Paso a Paso
|
||||
|
||||
### 1. Clonar el Repositorio
|
||||
|
||||
```bash
|
||||
git clone https://git.consultoria-as.com/<usuario>/stacks.git
|
||||
cd stacks
|
||||
```
|
||||
|
||||
### 2. Configurar Variables de Entorno
|
||||
|
||||
Copiar el archivo de ejemplo y editar:
|
||||
|
||||
```bash
|
||||
cd sales-bot
|
||||
cp .env.example .env
|
||||
nano .env
|
||||
```
|
||||
|
||||
Configurar las siguientes variables:
|
||||
|
||||
```env
|
||||
# Mattermost
|
||||
MATTERMOST_URL=http://<IP>:8065
|
||||
MATTERMOST_BOT_TOKEN=<tu_token>
|
||||
MATTERMOST_TEAM_NAME=sales
|
||||
MATTERMOST_WEBHOOK_SECRET=<tu_secret>
|
||||
MATTERMOST_WEBHOOK_URL=http://<IP>:8065/hooks/<hook_id>
|
||||
|
||||
# NocoDB
|
||||
NOCODB_URL=http://<IP>:8080
|
||||
NOCODB_TOKEN=<tu_token>
|
||||
NOCODB_TABLE_VENDEDORES=<table_id>
|
||||
NOCODB_TABLE_VENTAS=<table_id>
|
||||
NOCODB_TABLE_VENTAS_DETALLE=<table_id>
|
||||
NOCODB_TABLE_METAS=<table_id>
|
||||
|
||||
# Flask
|
||||
FLASK_PORT=5000
|
||||
LOG_LEVEL=INFO
|
||||
TZ_OFFSET=-6
|
||||
```
|
||||
|
||||
### 3. Iniciar Mattermost
|
||||
|
||||
```bash
|
||||
cd ../mattermost
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Esperar a que inicie completamente:
|
||||
```bash
|
||||
docker compose logs -f
|
||||
# Esperar mensaje "Server is listening"
|
||||
```
|
||||
|
||||
Acceder a http://<IP>:8065 y completar la configuración inicial:
|
||||
1. Crear cuenta de administrador
|
||||
2. Crear team "sales"
|
||||
3. Crear canales necesarios
|
||||
|
||||
### 4. Configurar Bot en Mattermost
|
||||
|
||||
1. Ir a **Integraciones > Bot Accounts**
|
||||
2. Crear nuevo bot:
|
||||
- Username: `salesbot`
|
||||
- Copiar el token generado
|
||||
|
||||
3. Ir a **Integraciones > Outgoing Webhooks**
|
||||
4. Crear webhook:
|
||||
- Canal: canal de ventas
|
||||
- URL: `http://<IP>:5000/webhook/mattermost`
|
||||
- Copiar el token
|
||||
|
||||
5. Ir a **Integraciones > Slash Commands**
|
||||
6. Crear comandos:
|
||||
- `/metas` → `http://<IP>:5000/comando/metas`
|
||||
- `/ranking` → `http://<IP>:5000/comando/ranking`
|
||||
|
||||
### 5. Iniciar NocoDB
|
||||
|
||||
```bash
|
||||
cd ../nocodb
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Acceder a http://<IP>:8080 y:
|
||||
1. Crear cuenta
|
||||
2. Crear base de datos
|
||||
3. Crear tablas (ver estructura en docs/ARQUITECTURA.md)
|
||||
4. Obtener API token en Settings
|
||||
|
||||
### 6. Configurar Tablas en NocoDB
|
||||
|
||||
Crear las siguientes tablas:
|
||||
|
||||
**Vendedores:**
|
||||
```
|
||||
- Id (Auto)
|
||||
- username (Text, Required)
|
||||
- nombre_completo (Text)
|
||||
- email (Email)
|
||||
- meta_diaria_tubos (Number, Default: 3)
|
||||
- activo (Checkbox, Default: true)
|
||||
- fecha_registro (DateTime)
|
||||
```
|
||||
|
||||
**Ventas:**
|
||||
```
|
||||
- Id (Auto)
|
||||
- vendedor_username (Text, Required)
|
||||
- monto (Currency)
|
||||
- cliente (Text)
|
||||
- fecha_venta (DateTime)
|
||||
- estado (SingleSelect: pendiente, completada, cancelada)
|
||||
- canal (Text)
|
||||
- mensaje_id (Text)
|
||||
- imagen_ticket (Attachment)
|
||||
- descripcion (LongText)
|
||||
```
|
||||
|
||||
**Ventas Detalle:**
|
||||
```
|
||||
- Id (Auto)
|
||||
- venta_id (Number)
|
||||
- producto (Text)
|
||||
- marca (Text)
|
||||
- cantidad (Number)
|
||||
- precio_unitario (Currency)
|
||||
- importe (Currency)
|
||||
```
|
||||
|
||||
**Metas:**
|
||||
```
|
||||
- Id (Auto)
|
||||
- vendedor_username (Text)
|
||||
- mes (Text)
|
||||
- tubos_vendidos (Number)
|
||||
- comision (Currency)
|
||||
- meta_diaria (Number)
|
||||
- porcentaje_completado (Percent)
|
||||
- total_vendido (Currency)
|
||||
```
|
||||
|
||||
### 7. Obtener IDs de Tablas
|
||||
|
||||
En NocoDB, para cada tabla:
|
||||
1. Abrir la tabla
|
||||
2. Copiar el ID de la URL: `/table/<TABLE_ID>`
|
||||
|
||||
Actualizar estos IDs en el archivo `.env`.
|
||||
|
||||
### 8. Iniciar Sales Bot
|
||||
|
||||
```bash
|
||||
cd ../sales-bot
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Verificar que esté corriendo:
|
||||
```bash
|
||||
curl http://localhost:5000/health
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Verificación de la Instalación
|
||||
|
||||
### 1. Verificar Servicios
|
||||
|
||||
```bash
|
||||
# Mattermost
|
||||
curl http://localhost:8065/api/v4/system/ping
|
||||
|
||||
# NocoDB
|
||||
curl http://localhost:8080/api/v2/health
|
||||
|
||||
# Sales Bot
|
||||
curl http://localhost:5000/health
|
||||
```
|
||||
|
||||
### 2. Probar Flujo Completo
|
||||
|
||||
1. Enviar mensaje en Mattermost:
|
||||
```
|
||||
venta @monto 100 @cliente Prueba
|
||||
```
|
||||
|
||||
2. Verificar que el bot responda
|
||||
3. Verificar registro en NocoDB
|
||||
|
||||
---
|
||||
|
||||
## Solución de Problemas
|
||||
|
||||
### Sales Bot no responde
|
||||
|
||||
```bash
|
||||
# Ver logs
|
||||
docker compose -f sales-bot/compose.yaml logs -f
|
||||
|
||||
# Reiniciar
|
||||
docker compose -f sales-bot/compose.yaml restart
|
||||
```
|
||||
|
||||
### Error de conexión a Mattermost
|
||||
|
||||
Verificar:
|
||||
1. Token del bot es correcto
|
||||
2. Bot tiene permisos en el canal
|
||||
3. URL de Mattermost es accesible
|
||||
|
||||
### Error de conexión a NocoDB
|
||||
|
||||
Verificar:
|
||||
1. Token de API es correcto
|
||||
2. IDs de tablas son correctos
|
||||
3. URL de NocoDB es accesible
|
||||
|
||||
### OCR no funciona
|
||||
|
||||
Verificar:
|
||||
1. Tesseract está instalado en el contenedor
|
||||
2. Imagen es legible
|
||||
3. Ver logs para errores específicos
|
||||
|
||||
---
|
||||
|
||||
## Actualización
|
||||
|
||||
```bash
|
||||
# Detener servicios
|
||||
docker compose -f sales-bot/compose.yaml down
|
||||
docker compose -f mattermost/compose.yaml down
|
||||
docker compose -f nocodb/compose.yaml down
|
||||
|
||||
# Actualizar código
|
||||
git pull
|
||||
|
||||
# Reconstruir imágenes
|
||||
docker compose -f sales-bot/compose.yaml build
|
||||
|
||||
# Iniciar servicios
|
||||
docker compose -f mattermost/compose.yaml up -d
|
||||
docker compose -f nocodb/compose.yaml up -d
|
||||
docker compose -f sales-bot/compose.yaml up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Backup y Restauración
|
||||
|
||||
### Backup
|
||||
|
||||
```bash
|
||||
# Backup de Mattermost
|
||||
docker compose -f mattermost/compose.yaml exec postgres \
|
||||
pg_dump -U consultoria-as mattermost > mattermost_backup.sql
|
||||
|
||||
# Backup de NocoDB
|
||||
docker compose -f nocodb/compose.yaml exec postgres \
|
||||
pg_dump -U consultoria-as nocodb > nocodb_backup.sql
|
||||
```
|
||||
|
||||
### Restauración
|
||||
|
||||
```bash
|
||||
# Restaurar Mattermost
|
||||
cat mattermost_backup.sql | docker compose -f mattermost/compose.yaml exec -T postgres \
|
||||
psql -U consultoria-as mattermost
|
||||
|
||||
# Restaurar NocoDB
|
||||
cat nocodb_backup.sql | docker compose -f nocodb/compose.yaml exec -T postgres \
|
||||
psql -U consultoria-as nocodb
|
||||
```
|
||||
Reference in New Issue
Block a user