From da790b8afcd69eb44688f74678a3519bad905c64 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 20 Dec 2025 20:33:59 +0000 Subject: [PATCH] refactor: Overhaul project structure and role management This commit implements the first phase of the new architectural vision for the Talia Bot. Key changes include: - Renamed the main application directory from `app` to `talia_bot` and updated all associated imports and configurations (`Dockerfile`, tests). - Replaced the static, `.env`-based permission system with a dynamic, database-driven role management system. - Introduced a `db.py` module to manage a SQLite database (`users.db`) for user persistence. - Updated `identity.py` to fetch roles ('admin', 'crew', 'client') from the database. - Rewrote the `README.md` and `.env.example` to align with the new project specification. - Refactored the LLM module into the new `modules` structure. --- .env.example | 26 +- Dockerfile | 4 +- README.md | 338 +++++++----------- app/permissions.py | 39 -- {app => talia_bot}/config.py | 10 +- talia_bot/data/users.db | Bin 0 -> 16384 bytes talia_bot/db.py | 48 +++ {app => talia_bot}/main.py | 33 +- {app => talia_bot}/modules/admin.py | 0 {app => talia_bot}/modules/agenda.py | 4 +- {app => talia_bot}/modules/aprobaciones.py | 0 .../modules/calendar.py | 0 {app => talia_bot}/modules/citas.py | 0 {app => talia_bot}/modules/create_tag.py | 0 .../print.py => talia_bot/modules/debug.py | 6 +- {app => talia_bot}/modules/equipo.py | 0 talia_bot/modules/identity.py | 71 ++++ app/llm.py => talia_bot/modules/llm_engine.py | 4 +- {app => talia_bot}/modules/onboarding.py | 24 +- talia_bot/modules/printer.py | 1 + talia_bot/modules/sales_rag.py | 1 + {app => talia_bot}/modules/servicios.py | 0 {app => talia_bot}/modules/vikunja.py | 0 {app => talia_bot}/scheduler.py | 0 {app => talia_bot}/webhook_client.py | 0 test_calendar_debug.py | 4 +- 26 files changed, 299 insertions(+), 314 deletions(-) delete mode 100644 app/permissions.py rename {app => talia_bot}/config.py (86%) create mode 100644 talia_bot/data/users.db create mode 100644 talia_bot/db.py rename {app => talia_bot}/main.py (85%) rename {app => talia_bot}/modules/admin.py (100%) rename {app => talia_bot}/modules/agenda.py (95%) rename {app => talia_bot}/modules/aprobaciones.py (100%) rename app/google_calendar.py => talia_bot/modules/calendar.py (100%) rename {app => talia_bot}/modules/citas.py (100%) rename {app => talia_bot}/modules/create_tag.py (100%) rename app/modules/print.py => talia_bot/modules/debug.py (88%) rename {app => talia_bot}/modules/equipo.py (100%) create mode 100644 talia_bot/modules/identity.py rename app/llm.py => talia_bot/modules/llm_engine.py (92%) rename {app => talia_bot}/modules/onboarding.py (75%) create mode 100644 talia_bot/modules/printer.py create mode 100644 talia_bot/modules/sales_rag.py rename {app => talia_bot}/modules/servicios.py (100%) rename {app => talia_bot}/modules/vikunja.py (100%) rename {app => talia_bot}/scheduler.py (100%) rename {app => talia_bot}/webhook_client.py (100%) diff --git a/.env.example b/.env.example index 6c97a4e..3cb8950 100644 --- a/.env.example +++ b/.env.example @@ -1,12 +1,18 @@ +# --- TELEGRAM & SECURITY --- TELEGRAM_BOT_TOKEN= -OWNER_CHAT_ID= -ADMIN_CHAT_IDS= -TEAM_CHAT_IDS= -GOOGLE_SERVICE_ACCOUNT_FILE= -CALENDAR_ID= -N8N_WEBHOOK_URL= +ADMIN_ID= + +# --- AI CORE --- OPENAI_API_KEY= -OPENAI_MODEL=gpt-3.5-turbo -DAILY_SUMMARY_TIME=07:00 -CALENDLY_LINK=https://calendly.com/user/appointment-link -TIMEZONE=America/Mexico_City + +# --- INTEGRATIONS --- +VIKUNJA_API_URL=https://tuservidor.com/api/v1 +VIKUNJA_TOKEN= +GOOGLE_CREDENTIALS_PATH=./data/credentials.json + +# --- PRINT SERVICE --- +SMTP_SERVER=smtp.hostinger.com +SMTP_PORT=465 +SMTP_USER=print.service@vanityexperience.mx +SMTP_PASS= +IMAP_SERVER=imap.hostinger.com diff --git a/Dockerfile b/Dockerfile index ba2dbc1..08cade8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,14 +2,14 @@ FROM python:3.9-slim # Set working directory -WORKDIR /app +WORKDIR /talia_bot # Copy and install requirements COPY requirements.txt . RUN pip install -r requirements.txt # Copy app code -COPY app/ . +COPY talia_bot/ . # Run the bot CMD ["python", "main.py"] diff --git a/README.md b/README.md index f3c5e9c..206299f 100644 --- a/README.md +++ b/README.md @@ -1,257 +1,165 @@ -# Talía — Asistente Ejecutiva Inteligente +# 🤖 Talia Bot: Asistente Personal & Orquestador de Negocio -Talía es una asistente ejecutiva digital diseñada para centralizar, ordenar y coordinar la agenda, solicitudes y actividades de Marco. Funciona como un **punto único de entrada** para clientes, equipo y administradores, asegurando que cada solicitud se procese con contexto, validación y respeto por el tiempo disponible. - -Talía no improvisa ni asume. **Consulta, valida, confirma y ejecuta.** +Talia no es un simple chatbot; es un Middleware de Inteligencia Artificial alojado en un VPS que orquesta las operaciones diarias de administración, logística y ventas. Actúa como el puente central entre usuarios en Telegram y servicios críticos como Vikunja (Gestión de Proyectos), Google Calendar y Hardware de Impresión remota. --- -## 🎯 Propósito del Sistema +## 🚀 Concepto Central: Enrutamiento por Identidad -Talía existe para eliminar fricción operativa y proteger el tiempo ejecutivo. El sistema está diseñado para: +La característica core de Talia es su capacidad de cambiar de personalidad y permisos dinámicamente basándose en el Telegram ID del usuario: -* Centralizar todas las solicitudes de agenda, citas y actividades -* Validar disponibilidad real antes de comprometer tiempo -* Priorizar clientes sin romper compromisos existentes -* Delegar reglas de negocio y disponibilidad a flujos en n8n -* Mantener trazabilidad completa mediante eventos webhook -* Escalar de forma modular sin romper flujos existentes +| Rol | Icono | Descripción | Permisos | +| :------ | :---: | :------------------ | :-------------------------------------------------------------------------------- | +| **Admin** | 👑 | Dueño / Gerente | God Mode: Gestión total de proyectos, bloqueos de calendario, generación de identidad NFC e impresión. | +| **Crew** | 👷 | Equipo Operativo | Limitado: Solicitud de agenda (validada), asignación de tareas, impresión de documentos. | +| **Cliente** | 👤 | Usuario Público | Ventas: Embudo de captación, consulta de servicios (RAG) y agendamiento comercial. | --- -## 🧠 Personalidad, Actitud y Voz +## 🛠️ Arquitectura Técnica -Talía se comporta como una asistente ejecutiva profesional: +El sistema sigue un flujo modular: -* Educada, clara y precisa en cada respuesta -* Proactiva, pero nunca invasiva -* Siempre confirma antes de agendar o ejecutar acciones -* No improvisa horarios ni decisiones -* Comunica decisiones con calma, orden y neutralidad - -Talía no es informal, no es robótica y no utiliza sarcasmo. Su función es **ordenar el día, no interrumpirlo**. +1. **Input**: Telegram (Texto o Audio). +2. **STT**: Whisper (Conversión de Audio a Texto). +3. **Router**: Verificación de ID contra la base de datos de usuarios. +4. **Cerebro (LLM)**: OpenAI (Fase 1) / Google Gemini (Fase 2). +5. **Tools**: + * **Vikunja API**: Lectura/Escritura de tareas con filtrado de privacidad. + * **Google Calendar API**: Gestión de tiempos y reglas de disponibilidad. + * **SMTP/IMAP**: Comunicación bidireccional con impresoras. + * **NFC Gen**: Codificación Base64 para tags físicos. --- -## 👥 Roles y Niveles de Acceso +## 📋 Flujos de Trabajo (Features) -### Marco (Owner) +### 1. 👑 Gestión Admin (Proyectos & Identidad) -* Consulta agenda, pendientes y solicitudes activas -* Recibe resumen diario automático a las 7:00 AM -* Aprueba o rechaza solicitudes del equipo -* Puede interactuar desde su número privado -* Tiene prioridad absoluta sobre cualquier decisión +* **Proyectos (Vikunja)**: + * Resumen inteligente de estatus de proyectos. + * Comandos naturales: *"Marca el proyecto de web como terminado y comenta que se envió factura"*. +* **Wizard de Identidad (NFC)**: + * Flujo paso a paso para dar de alta colaboradores. + * Genera JSON de registro y String Base64 listo para escribir en Tags NFC. + * Inputs: Nombre, ID Empleado, Sucursal (Botones), Telegram ID. -### Clientes +### 2. 👷 Gestión Crew (Agenda & Tareas) -* Solicitan citas de duración fija (30 minutos) -* Visualizan únicamente horarios disponibles -* No tienen acceso a la agenda completa +* **Solicitud de Tiempo (Wizard)**: + * Solicita espacios de 1 a 4 horas. + * **Reglas de Negocio**: + * No permite fechas > 3 meses a futuro. + * **Gatekeeper**: Verifica Google Calendar. Si hay evento "Privado" del Admin, rechaza automáticamente. +* **Modo Buzón (Vikunja)**: + * Crea tareas asignadas al Admin. + * **Privacidad**: Solo pueden consultar el estatus de tareas creadas por ellos mismos. -### Equipo Autorizado +### 3. 🖨️ Sistema de Impresión Remota (Print Loop) -* Puede proponer actividades de mayor duración (ej. grabaciones) -* Puede solicitar acciones operativas -* Toda actividad que consuma tiempo requiere aprobación +* Permite enviar archivos desde Telegram a la impresora física de la oficina. +* **Envío (SMTP)**: El bot envía el documento a un correo designado. +* **Tracking**: El asunto del correo lleva un hash único: `PJ:{uuid}#TID:{telegram_id}`. +* **Confirmación (IMAP Listener)**: Un proceso en background escucha la respuesta de la impresora y notifica al usuario en Telegram. -### Administradores +### 4. 👤 Ventas Automáticas (RAG) -* Ejecutan acciones sensibles -* Requieren validación adicional -* Acceden a flujos administrativos restringidos +* Identifica usuarios nuevos (no registrados en la DB). +* Captura datos (Lead Magnet). +* Analiza ideas de clientes usando `servicios.json` (Base de conocimiento). +* Ofrece citas de ventas mediante link de Calendly. --- -## 🏗️ Arquitectura del Sistema +## ⚙️ Instalación y Configuración -Talía está construida en capas desacopladas que se comunican por eventos: +### Prerrequisitos -1. **Interfaz Conversacional** – Telegram / WhatsApp -2. **Cerebro Central** – Python -3. **Automatización y Reglas** – n8n -4. **Servicios Externos** – Google Calendar, IA, APIs +* Python 3.10+ +* Cuenta de Telegram Bot (@BotFather) +* Instancia de Vikunja (Self-hosted) +* Cuenta de Servicio Google Cloud (Calendar API) +* Servidor de Correo (SMTP/IMAP) -Cada capa es independiente y puede evolucionar sin afectar a las demás. +### 1. Clonar y Entorno Virtual ---- - -## 📁 Estructura del Proyecto - -```text -talia-bot/ -├── docker-compose.yml # Orquestación de contenedores -├── Dockerfile # Imagen del bot -├── .env.example # Variables de entorno -├── README.md # Documentación -└── app/ - ├── main.py # Cerebro del bot - ├── config.py # Configuración y credenciales - ├── permissions.py # Roles y validaciones - ├── scheduler.py # Resumen diario y recordatorios - ├── webhook_client.py # Comunicación con n8n - ├── calendar.py # Integración Google Calendar - ├── llm.py # Respuestas inteligentes (IA) - └── modules/ - ├── onboarding.py # Bienvenida y menú inicial - ├── agenda.py # Consulta de agenda - ├── citas.py # Citas con clientes - ├── equipo.py # Solicitudes del equipo - ├── aprobaciones.py # Aprobaciones del owner - ├── servicios.py # Servicios y cotizaciones - └── admin.py # Acciones administrativas +```bash +git clone https://github.com/marcogll/talia_bot_mg.git +cd talia_bot_mg +python -m venv venv +source venv/bin/activate # Windows: venv\Scripts\activate +pip install -r requirements.txt ``` ---- +### 2. Variables de Entorno (`.env`) -## 🧠 Cerebro del Sistema (`main.py`) - -`main.py` actúa como **orquestador central**. No contiene reglas de negocio complejas. Sus funciones son: - -* Recibir mensajes y callbacks -* Identificar usuario y rol -* Mantener contexto conversacional -* Delegar acciones a módulos -* Emitir y recibir eventos vía webhook - -Toda decisión importante se valida externamente. - ---- - -## 🧩 Módulos Funcionales - -Cada módulo cumple una responsabilidad única: - -* **onboarding.py**: inicio de conversación y opciones -* **agenda.py**: consulta de agenda y pendientes -* **citas.py**: flujo de citas con clientes -* **equipo.py**: solicitudes internas del equipo -* **aprobaciones.py**: aceptar o rechazar solicitudes -* **servicios.py**: información y cotización de proyectos -* **admin.py**: acciones administrativas -* **create_tag.py**: genera un tag de identificación en Base64 para NFC -* **print.py**: (admin) imprime la configuración actual del bot - ---- - -## ⚡ Comandos Adicionales - -### `/create_tag` - -Este comando inicia un flujo conversacional para generar un tag de identificación en formato Base64, compatible con aplicaciones de escritura NFC. El bot solicitará los siguientes datos: - -* **Nombre** -* **Número de empleado** -* **Sucursal** -* **ID de Telegram** - -Al finalizar, el bot devolverá una cadena de texto en Base64 que contiene un objeto JSON con la información proporcionada. - ---- - -## 🔁 Flujo General de Ejecución - -1. Usuario envía mensaje o interactúa con botones -2. Talía valida identidad y permisos -3. Se ejecuta el módulo correspondiente -4. Si se requiere lógica externa, se envía evento a n8n -5. n8n evalúa reglas y responde -6. Talía comunica el resultado -7. Si aplica, se agenda en Google Calendar - ---- - -## 📆 Gestión de Agenda - -### Citas con Clientes - -* Duración fija: 30 minutos -* Disponibilidad definida exclusivamente por n8n -* Confirmación explícita antes de agendar - -### Actividades del Equipo - -* Duración flexible -* Requieren aprobación del owner -* Solo usuarios autorizados pueden solicitarlas - ---- - -## ⏰ Resumen Diario - -Todos los días a las **7:00 AM**, Talía envía a Marco: - -* Agenda del día -* Pendientes activos -* Recordatorios importantes - ---- - -## 🔌 Webhooks - -Toda acción relevante genera o responde un evento webhook. - -Ejemplo: - -```json -{ - "event": "request_activity", - "from": "team", - "duration_hours": 4, - "description": "Grabación de proyecto" -} -``` - ---- - -## 🔐 Variables de Entorno +Crea un archivo `.env` en la raíz con la siguiente estructura: ```env -TELEGRAM_BOT_TOKEN= -OWNER_CHAT_ID= -ADMIN_CHAT_IDS= -TEAM_CHAT_IDS= -GOOGLE_CLIENT_ID= -GOOGLE_CLIENT_SECRET= -GOOGLE_REFRESH_TOKEN= -N8N_WEBHOOK_URL= -OPENAI_API_KEY= -TIMEZONE=America/Mexico_City +# --- TELEGRAM & SECURITY --- +TELEGRAM_BOT_TOKEN=tu_token_telegram +ADMIN_ID=tu_telegram_id + +# --- AI CORE --- +OPENAI_API_KEY=sk-... + +# --- INTEGRACIONES --- +VIKUNJA_API_URL=https://tuservidor.com/api/v1 +VIKUNJA_TOKEN=tu_token_vikunja +GOOGLE_CREDENTIALS_PATH=./data/credentials.json + +# --- PRINT SERVICE --- +SMTP_SERVER=smtp.hostinger.com +SMTP_PORT=465 +SMTP_USER=print.service@vanityexperience.mx +SMTP_PASS=tu_password_seguro +IMAP_SERVER=imap.hostinger.com +``` + +### 3. Estructura de Datos + +Asegúrate de tener los archivos base en `talia_bot/data/`: +* `servicios.json`: Catálogo de servicios para el RAG de ventas. +* `credentials.json`: Credenciales de Google Cloud. +* `users.db`: Base de datos SQLite. + +--- + +## 📂 Estructura del Proyecto + +```text +talia_bot_mg/ +├── talia_bot/ +│ ├── main.py # Entry Point y Router de Identidad +│ ├── db.py # Gestión de la base de datos +│ ├── config.py # Carga de variables de entorno +│ ├── modules/ +│ │ ├── identity.py # Lógica de Roles y Permisos +│ │ ├── llm_engine.py # Cliente OpenAI/Gemini +│ │ ├── vikunja.py # API Manager para Tareas +│ │ ├── calendar.py # Google Calendar Logic & Rules +│ │ ├── printer.py # SMTP/IMAP Loop +│ │ └── sales_rag.py # Lógica de Ventas y Servicios +│ └── data/ +│ ├── servicios.json # Base de conocimiento +│ ├── credentials.json # Credenciales de Google +│ └── users.db # Base de datos de usuarios +├── .env.example # Plantilla de variables de entorno +├── requirements.txt # Dependencias +├── Dockerfile # Configuración del contenedor +└── docker-compose.yml # Orquestador de Docker ``` --- -## 🐳 Despliegue con Docker Compose +## 🗓️ Roadmap -```yaml -version: "3.9" -services: - talia-bot: - build: . - container_name: talia-bot - env_file: - - .env - restart: unless-stopped -``` +- [ ] Implementar Wizard de creación de Tags NFC (Base64). +- [ ] Conectar Loop de Impresión (SMTP/IMAP). +- [ ] Migrar de OpenAI a Google Gemini 1.5 Pro. +- [ ] Implementar soporte para fotos en impresión. --- -## 🛠️ Guía de Desarrollo - -1. Clonar el repositorio -2. Crear archivo `.env` -3. Configurar bot de Telegram -4. Configurar flujos y reglas en n8n -5. Conectar Google Calendar -6. Levantar servicios con Docker Compose - ---- - -## ✨ Principio Rector - -Talía no es un bot que responde mensajes. -Es un sistema de criterio, orden y protección del tiempo. - -Si algo no está claro, pregunta. -Si algo invade la agenda, protege. -Si algo es importante, lo prioriza. +Desarrollado por: Marco G. +Asistente Personalizado v1.0 diff --git a/app/permissions.py b/app/permissions.py deleted file mode 100644 index ce012bb..0000000 --- a/app/permissions.py +++ /dev/null @@ -1,39 +0,0 @@ -# app/permissions.py -# Este script maneja los permisos de los usuarios según su ID de chat de Telegram. - -from config import OWNER_CHAT_ID, ADMIN_CHAT_IDS, TEAM_CHAT_IDS - -def get_user_role(chat_id): - """ - Determina el rol de un usuario basado en su ID de chat. - - Roles posibles: owner (dueño), admin (administrador), team (equipo), client (cliente). - """ - chat_id_str = str(chat_id) - - # Si el ID coincide con el del dueño - if chat_id_str == OWNER_CHAT_ID: - return "owner" - - # Si el ID está en la lista de administradores - if chat_id_str in ADMIN_CHAT_IDS: - return "admin" - - # Si el ID está en la lista del equipo - if chat_id_str in TEAM_CHAT_IDS: - return "team" - - # Si no es ninguno de los anteriores, es un cliente normal - return "client" - -def is_owner(chat_id): - """Verifica si un usuario es el dueño.""" - return get_user_role(chat_id) == "owner" - -def is_admin(chat_id): - """Verifica si un usuario es administrador o dueño.""" - return get_user_role(chat_id) in ["owner", "admin"] - -def is_team_member(chat_id): - """Verifica si un usuario es parte del equipo, administrador o dueño.""" - return get_user_role(chat_id) in ["owner", "admin", "team"] diff --git a/app/config.py b/talia_bot/config.py similarity index 86% rename from app/config.py rename to talia_bot/config.py index 53669f6..6056ad0 100644 --- a/app/config.py +++ b/talia_bot/config.py @@ -1,4 +1,4 @@ -# app/config.py +# talia_bot/config.py # Este archivo se encarga de cargar todas las variables de entorno y configuraciones del bot. # Las variables de entorno son valores que se guardan fuera del código por seguridad (como tokens y llaves API). @@ -14,13 +14,7 @@ load_dotenv(dotenv_path=env_path) TELEGRAM_BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN") # ID de chat del dueño del bot (para recibir notificaciones importantes) -OWNER_CHAT_ID = os.getenv("OWNER_CHAT_ID") - -# IDs de chat de los administradores, separados por comas en el archivo .env -ADMIN_CHAT_IDS = os.getenv("ADMIN_CHAT_IDS", "").split(",") - -# IDs de chat del equipo de trabajo, separados por comas -TEAM_CHAT_IDS = os.getenv("TEAM_CHAT_IDS", "").split(",") +ADMIN_ID = os.getenv("ADMIN_ID") # Ruta al archivo de credenciales de la cuenta de servicio de Google GOOGLE_SERVICE_ACCOUNT_FILE = os.getenv("GOOGLE_SERVICE_ACCOUNT_FILE") diff --git a/talia_bot/data/users.db b/talia_bot/data/users.db new file mode 100644 index 0000000000000000000000000000000000000000..9f8d355391cafa8022413608d8d9a403a15332cb GIT binary patch literal 16384 zcmeI%O;5rw7zgkU2pSSzZo57=SRf|Gvx!I=T^QrVEs@hQpz4xs$QYs*55|ih&hO*V zt${?C-VOOTS)15P$##AOHafKmY;|fB*#kxxgS_RGUp@9J>==EEj%qaCDYp zu@d2Qzgy^xc-!J+wJ!}$dt)1+8;Dktsl6G>k*cc7`&!PqT8d~XtK3e$yhV)??GhdwQZL6=F$qYSiTCGf0EPQbvxq None: logger.error("TELEGRAM_BOT_TOKEN no está configurado en las variables de entorno.") return + setup_database() + application = Application.builder().token(TELEGRAM_BOT_TOKEN).build() schedule_daily_summary(application) diff --git a/app/modules/admin.py b/talia_bot/modules/admin.py similarity index 100% rename from app/modules/admin.py rename to talia_bot/modules/admin.py diff --git a/app/modules/agenda.py b/talia_bot/modules/agenda.py similarity index 95% rename from app/modules/agenda.py rename to talia_bot/modules/agenda.py index a7f4b71..3c6265c 100644 --- a/app/modules/agenda.py +++ b/talia_bot/modules/agenda.py @@ -1,10 +1,10 @@ -# app/modules/agenda.py +# talia_bot/modules/agenda.py # Este módulo se encarga de manejar las peticiones relacionadas con la agenda. # Permite obtener y mostrar las actividades programadas para el día. import datetime import logging -from google_calendar import get_events +from talia_bot.modules.calendar import get_events logger = logging.getLogger(__name__) diff --git a/app/modules/aprobaciones.py b/talia_bot/modules/aprobaciones.py similarity index 100% rename from app/modules/aprobaciones.py rename to talia_bot/modules/aprobaciones.py diff --git a/app/google_calendar.py b/talia_bot/modules/calendar.py similarity index 100% rename from app/google_calendar.py rename to talia_bot/modules/calendar.py diff --git a/app/modules/citas.py b/talia_bot/modules/citas.py similarity index 100% rename from app/modules/citas.py rename to talia_bot/modules/citas.py diff --git a/app/modules/create_tag.py b/talia_bot/modules/create_tag.py similarity index 100% rename from app/modules/create_tag.py rename to talia_bot/modules/create_tag.py diff --git a/app/modules/print.py b/talia_bot/modules/debug.py similarity index 88% rename from app/modules/print.py rename to talia_bot/modules/debug.py index f0495bf..c83bd69 100644 --- a/app/modules/print.py +++ b/talia_bot/modules/debug.py @@ -1,11 +1,11 @@ -# app/modules/print.py +# talia_bot/modules/debug.py # Este módulo permite a los administradores imprimir los detalles de configuración del bot. # Es una herramienta útil para depuración (debugging). from telegram import Update from telegram.ext import ContextTypes -from permissions import is_admin -from config import TIMEZONE, CALENDAR_ID, N8N_WEBHOOK_URL +from talia_bot.modules.identity import is_admin +from talia_bot.config import TIMEZONE, CALENDAR_ID, N8N_WEBHOOK_URL async def print_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: """ diff --git a/app/modules/equipo.py b/talia_bot/modules/equipo.py similarity index 100% rename from app/modules/equipo.py rename to talia_bot/modules/equipo.py diff --git a/talia_bot/modules/identity.py b/talia_bot/modules/identity.py new file mode 100644 index 0000000..c169c32 --- /dev/null +++ b/talia_bot/modules/identity.py @@ -0,0 +1,71 @@ +# talia_bot/modules/identity.py +# Este script maneja los roles y permisos de los usuarios. + +import logging +from talia_bot.db import get_db_connection +from talia_bot.config import ADMIN_ID + +logger = logging.getLogger(__name__) + +def add_user(telegram_id, role, name=None, employee_id=None, branch=None): + """ + Añade un nuevo usuario o actualiza el rol de uno existente. + """ + try: + conn = get_db_connection() + cursor = conn.cursor() + cursor.execute(""" + INSERT INTO users (telegram_id, role, name, employee_id, branch) + VALUES (?, ?, ?, ?, ?) + ON CONFLICT(telegram_id) DO UPDATE SET + role = excluded.role, + name = excluded.name, + employee_id = excluded.employee_id, + branch = excluded.branch + """, (telegram_id, role, name, employee_id, branch)) + conn.commit() + logger.info(f"Usuario {telegram_id} añadido/actualizado con el rol {role}.") + return True + except Exception as e: + logger.error(f"Error al añadir/actualizar usuario {telegram_id}: {e}") + return False + finally: + if conn: + conn.close() + +def get_user_role(telegram_id): + """ + Determina el rol de un usuario. + Roles: 'admin', 'crew', 'client'. + """ + # El admin principal se define en el .env para el primer arranque + if str(telegram_id) == ADMIN_ID: + return 'admin' + + try: + conn = get_db_connection() + cursor = conn.cursor() + cursor.execute("SELECT role FROM users WHERE telegram_id = ?", (telegram_id,)) + user = cursor.fetchone() + + if user: + logger.debug(f"Rol encontrado para {telegram_id}: {user['role']}") + return user['role'] + else: + # Si no está en la DB, es un cliente nuevo + logger.debug(f"No se encontró rol para {telegram_id}, asignando 'client'.") + return 'client' + except Exception as e: + logger.error(f"Error al obtener el rol para {telegram_id}: {e}") + return 'client' # Fallback seguro + finally: + if conn: + conn.close() + +def is_admin(telegram_id): + """Verifica si un usuario es administrador.""" + return get_user_role(telegram_id) == 'admin' + +def is_crew(telegram_id): + """Verifica si un usuario es del equipo (crew) o administrador.""" + return get_user_role(telegram_id) in ['admin', 'crew'] diff --git a/app/llm.py b/talia_bot/modules/llm_engine.py similarity index 92% rename from app/llm.py rename to talia_bot/modules/llm_engine.py index a67b178..c146d2b 100644 --- a/app/llm.py +++ b/talia_bot/modules/llm_engine.py @@ -1,8 +1,8 @@ -# app/llm.py +# talia_bot/modules/llm_engine.py # Este script se encarga de la comunicación con la inteligencia artificial de OpenAI. import openai -from config import OPENAI_API_KEY, OPENAI_MODEL +from talia_bot.config import OPENAI_API_KEY, OPENAI_MODEL def get_smart_response(prompt): """ diff --git a/app/modules/onboarding.py b/talia_bot/modules/onboarding.py similarity index 75% rename from app/modules/onboarding.py rename to talia_bot/modules/onboarding.py index 567e7d8..795b5b7 100644 --- a/app/modules/onboarding.py +++ b/talia_bot/modules/onboarding.py @@ -1,23 +1,15 @@ -# app/modules/onboarding.py +# talia_bot/modules/onboarding.py # Este módulo maneja la primera interacción con el usuario (el comando /start). -# Se encarga de mostrar un menú diferente según quién sea el usuario (dueño, admin, equipo o cliente). +# Se encarga de mostrar un menú diferente según quién sea el usuario (admin, crew o cliente). from telegram import InlineKeyboardButton, InlineKeyboardMarkup -def get_owner_menu(): - """Crea el menú de botones para el Dueño (Owner).""" - keyboard = [ - [InlineKeyboardButton("📅 Ver mi agenda", callback_data='view_agenda')], - [InlineKeyboardButton("⏳ Ver pendientes", callback_data='view_pending')], - ] - return InlineKeyboardMarkup(keyboard) - def get_admin_menu(): """Crea el menú de botones principal para los Administradores.""" keyboard = [ - [InlineKeyboardButton("⏳ Revisar Pendientes", callback_data='view_pending')], + [InlineKeyboardButton("👑 Revisar Pendientes", callback_data='view_pending')], [InlineKeyboardButton("📅 Agenda", callback_data='view_agenda')], - [InlineKeyboardButton("🏷️ Crear Tag", callback_data='start_create_tag')], + [InlineKeyboardButton(" NFC", callback_data='start_create_tag')], [InlineKeyboardButton("▶️ Más opciones", callback_data='admin_menu')], ] return InlineKeyboardMarkup(keyboard) @@ -33,7 +25,7 @@ def get_admin_secondary_menu(): reply_markup = InlineKeyboardMarkup(keyboard) return text, reply_markup -def get_team_menu(): +def get_crew_menu(): """Crea el menú de botones para los Miembros del Equipo.""" keyboard = [ [InlineKeyboardButton("🕒 Proponer actividad", callback_data='propose_activity')], @@ -55,10 +47,10 @@ def handle_start(user_role): """ welcome_message = "Hola, soy Talía. ¿En qué puedo ayudarte hoy?" - if user_role in ["owner", "admin"]: + if user_role == "admin": menu = get_admin_menu() - elif user_role == "team": - menu = get_team_menu() + elif user_role == "crew": + menu = get_crew_menu() else: menu = get_client_menu() diff --git a/talia_bot/modules/printer.py b/talia_bot/modules/printer.py new file mode 100644 index 0000000..698f9c0 --- /dev/null +++ b/talia_bot/modules/printer.py @@ -0,0 +1 @@ +# This module will contain the SMTP/IMAP loop for the remote printing service. diff --git a/talia_bot/modules/sales_rag.py b/talia_bot/modules/sales_rag.py new file mode 100644 index 0000000..1f31fb9 --- /dev/null +++ b/talia_bot/modules/sales_rag.py @@ -0,0 +1 @@ +# This module will contain the sales RAG flow for new clients. diff --git a/app/modules/servicios.py b/talia_bot/modules/servicios.py similarity index 100% rename from app/modules/servicios.py rename to talia_bot/modules/servicios.py diff --git a/app/modules/vikunja.py b/talia_bot/modules/vikunja.py similarity index 100% rename from app/modules/vikunja.py rename to talia_bot/modules/vikunja.py diff --git a/app/scheduler.py b/talia_bot/scheduler.py similarity index 100% rename from app/scheduler.py rename to talia_bot/scheduler.py diff --git a/app/webhook_client.py b/talia_bot/webhook_client.py similarity index 100% rename from app/webhook_client.py rename to talia_bot/webhook_client.py diff --git a/test_calendar_debug.py b/test_calendar_debug.py index aa27442..501eee8 100644 --- a/test_calendar_debug.py +++ b/test_calendar_debug.py @@ -3,9 +3,9 @@ import sys import os # Add app directory to path -sys.path.append(os.path.join(os.getcwd(), 'app')) +sys.path.append(os.path.join(os.getcwd(), 'talia_bot')) -from google_calendar import get_events +from modules.calendar import get_events from config import CALENDAR_ID def test_get_events():