- 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>
200 lines
6.4 KiB
Markdown
200 lines
6.4 KiB
Markdown
# Sales Bot - Aplicación Principal
|
|
|
|
Bot de automatización de ventas para Mattermost con procesamiento OCR de tickets.
|
|
|
|
## Arquitectura
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ Sales Bot │
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌─────────────┐ ┌──────────────┐ ┌──────────────────┐ │
|
|
│ │ Flask │ │ WebSocket │ │ OCR Processor │ │
|
|
│ │ (app.py) │ │ Listener │ │ │ │
|
|
│ └──────┬──────┘ └──────┬───────┘ └────────┬─────────┘ │
|
|
│ │ │ │ │
|
|
│ └──────────────────┼──────────────────────┘ │
|
|
│ │ │
|
|
│ ┌───────┴───────┐ │
|
|
│ │ Handlers │ │
|
|
│ │ (handlers.py) │ │
|
|
│ └───────┬───────┘ │
|
|
│ │ │
|
|
│ ┌──────────────────┼──────────────────┐ │
|
|
│ │ │ │ │
|
|
│ ┌──────┴──────┐ ┌─────┴──────┐ ┌─────┴──────┐ │
|
|
│ │ Mattermost │ │ NocoDB │ │ Utils │ │
|
|
│ │ Client │ │ Client │ │ │ │
|
|
│ └─────────────┘ └────────────┘ └────────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Módulos
|
|
|
|
### app.py
|
|
Aplicación Flask principal con los siguientes endpoints:
|
|
|
|
- `GET /health` - Health check
|
|
- `POST /webhook/mattermost` - Recibe webhooks de Mattermost
|
|
- `POST /webhook/nocodb` - Recibe webhooks de NocoDB
|
|
- `POST /comando/metas` - Comando slash /metas
|
|
- `POST /comando/ranking` - Comando slash /ranking
|
|
|
|
### handlers.py
|
|
Manejadores de eventos de ventas:
|
|
|
|
- `handle_venta_message()` - Procesa mensajes de venta
|
|
- `generar_reporte_diario()` - Genera reportes diarios
|
|
|
|
### mattermost_client.py
|
|
Cliente para la API de Mattermost:
|
|
|
|
```python
|
|
client = MattermostClient(url, token)
|
|
client.test_connection()
|
|
client.post_message(channel_id, message)
|
|
client.add_reaction(post_id, emoji)
|
|
client.get_file(file_id)
|
|
```
|
|
|
|
### nocodb_client.py
|
|
Cliente para la API de NocoDB:
|
|
|
|
```python
|
|
client = NocoDBClient(url, token)
|
|
client.crear_vendedor(username, nombre, email)
|
|
client.registrar_venta(vendedor, monto, cliente, imagen)
|
|
client.get_ventas_dia(vendedor, fecha)
|
|
client.get_ranking_vendedores(mes)
|
|
```
|
|
|
|
### ocr_processor.py
|
|
Procesador OCR para tickets:
|
|
|
|
```python
|
|
processor = OCRProcessor()
|
|
resultado = processor.procesar_imagen(imagen_bytes)
|
|
# Retorna: monto, fecha, productos, tubos_detectados
|
|
```
|
|
|
|
### websocket_listener.py
|
|
Listener para eventos en tiempo real de Mattermost:
|
|
|
|
```python
|
|
listener = MattermostWebsocketListener(url, token, callback)
|
|
listener.start() # Inicia en thread separado
|
|
```
|
|
|
|
### utils.py
|
|
Funciones de utilidad:
|
|
|
|
```python
|
|
extraer_monto(texto) # "@monto 1500" → 1500.0
|
|
extraer_cliente(texto) # "@cliente Juan" → "Juan"
|
|
extraer_tubos(texto) # "@tubos 5" → 5
|
|
formatear_moneda(1500) # → "$1,500.00"
|
|
```
|
|
|
|
## Instalación con Docker
|
|
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
## Instalación Manual
|
|
|
|
```bash
|
|
# Instalar Tesseract
|
|
apt-get install tesseract-ocr tesseract-ocr-eng tesseract-ocr-spa
|
|
|
|
# Instalar dependencias Python
|
|
pip install -r requirements.txt
|
|
|
|
# Ejecutar
|
|
python app.py
|
|
```
|
|
|
|
## Variables de Entorno
|
|
|
|
| Variable | Descripción | Ejemplo |
|
|
|----------|-------------|---------|
|
|
| MATTERMOST_URL | URL de Mattermost | http://192.168.10.204:8065 |
|
|
| MATTERMOST_BOT_TOKEN | Token del bot | xxx |
|
|
| MATTERMOST_TEAM_NAME | Nombre del team | sales |
|
|
| MATTERMOST_WEBHOOK_SECRET | Secret del webhook | xxx |
|
|
| NOCODB_URL | URL de NocoDB | http://192.168.10.204:8080 |
|
|
| NOCODB_TOKEN | Token de API | xxx |
|
|
| NOCODB_TABLE_* | IDs de tablas | xxx |
|
|
| FLASK_PORT | Puerto de Flask | 5000 |
|
|
| LOG_LEVEL | Nivel de logging | INFO |
|
|
| TZ_OFFSET | Offset de zona horaria | -6 |
|
|
|
|
## Formato de Mensajes de Venta
|
|
|
|
El bot reconoce varios formatos:
|
|
|
|
```
|
|
# Formato con @
|
|
venta @monto 1500 @cliente Juan @tubos 5
|
|
|
|
# Formato con etiquetas
|
|
venta monto: 1500 cliente: Juan
|
|
|
|
# Formato natural
|
|
venta $1,500 a Juan
|
|
```
|
|
|
|
## Procesamiento OCR
|
|
|
|
El procesador OCR detecta automáticamente:
|
|
- Monto total
|
|
- Fecha del ticket
|
|
- Lista de productos
|
|
- Cantidad de tubos de tinte
|
|
|
|
### Marcas de Tinte Reconocidas
|
|
- Alfaparf Evolution
|
|
- Wella Koleston
|
|
- Loreal
|
|
- Matrix
|
|
- Schwarzkopf
|
|
- Revlon
|
|
- Igora
|
|
- Majirel
|
|
|
|
## Sistema de Comisiones
|
|
|
|
```python
|
|
META_DIARIA_TUBOS = 3
|
|
COMISION_POR_TUBO = 10 # $10 MXN
|
|
|
|
def calcular_comision(tubos_vendidos):
|
|
if tubos_vendidos > META_DIARIA_TUBOS:
|
|
return (tubos_vendidos - META_DIARIA_TUBOS) * COMISION_POR_TUBO
|
|
return 0
|
|
```
|
|
|
|
## Logs
|
|
|
|
Los logs se escriben en `/app/logs/sales-bot.log` con formato:
|
|
```
|
|
2024-01-15 10:30:45 INFO [app] Venta registrada: $1,500.00 - Juan - vendedor1
|
|
```
|
|
|
|
## Health Check
|
|
|
|
```bash
|
|
curl http://localhost:5000/health
|
|
```
|
|
|
|
Respuesta:
|
|
```json
|
|
{
|
|
"status": "healthy",
|
|
"timestamp": "2024-01-15T10:30:45",
|
|
"version": "1.0.0"
|
|
}
|
|
```
|