feat: Implement file-based persistence for user registration

This commit introduces a file-based persistence layer to store and retrieve registered user chat IDs.

Previously, the bot used an in-memory `set` to track registered users, which was cleared on every restart. This caused the bot to lose track of all registered users, preventing them from accessing registered-only features.

This commit resolves the issue by:
- Creating a `data/registered_users.txt` file to store user chat IDs.
- Implementing a `load_registered_users` function to load the user data from the file at startup.
- Modifying the `register_user` function to append new user chat IDs to the file.
- Calling `load_registered_users` from `main.py` at startup to initialize the user state.
This commit is contained in:
google-labs-jules[bot]
2025-12-23 05:15:39 +00:00
parent 36b7154c6e
commit cfe6d96113
2 changed files with 62 additions and 7 deletions

View File

@@ -18,7 +18,10 @@ from telegram.ext import Application, Defaults, CommandHandler, ContextTypes
# --- IMPORTAR HABILIDADES ---
from modules.flow_builder import load_flows
from modules.logger import log_request
from modules.database import chat_id_exists # Importar chat_id_exists
from modules.database import (
chat_id_exists,
load_registered_users,
) # Importar chat_id_exists y load_registered_users
from modules.ui import main_actions_keyboard
from modules.rh_requests import vacaciones_handler, permiso_handler
@@ -106,6 +109,11 @@ async def menu_principal(update: Update, context: ContextTypes.DEFAULT_TYPE):
async def post_init(application: Application):
"""Tareas a ejecutar después de que el bot se haya inicializado."""
# Cargar usuarios registrados desde el archivo de persistencia.
# Es crucial que esto se ejecute antes de que el bot empiece a recibir updates.
load_registered_users()
# Mantén los comandos rápidos disponibles en el menú de Telegram
await application.bot.set_my_commands(
[

View File

@@ -1,4 +1,15 @@
import logging
import os
# --- CONFIGURACIÓN DE PERSISTENCIA ---
# Usamos un archivo de texto para persistir los chat_id de usuarios registrados.
# Esto es una solución temporal y ligera hasta que se implemente una base de datos.
DATA_DIR = os.path.join(os.path.dirname(__file__), "..", "..", "data")
USERS_FILE = os.path.join(DATA_DIR, "registered_users.txt")
# Asegurarse de que el directorio de datos exista
os.makedirs(DATA_DIR, exist_ok=True)
# MOCK DATABASE MODULE
# Since the actual DB is removed temporarily, this module provides mock implementations.
@@ -9,23 +20,59 @@ SessionVanityAttendance = None
_REGISTERED_USERS = set()
def load_registered_users():
"""Carga los chat_id de usuarios registrados desde el archivo de texto."""
try:
if os.path.exists(USERS_FILE):
with open(USERS_FILE, "r") as f:
for line in f:
try:
_REGISTERED_USERS.add(int(line.strip()))
except ValueError:
logging.warning(
f"[DB] Se ignoró una línea no válida en {USERS_FILE}: {line.strip()}"
)
logging.info(
f"[DB] Se cargaron {len(_REGISTERED_USERS)} usuarios registrados desde {USERS_FILE}"
)
else:
logging.info(f"[DB] No se encontró el archivo de usuarios en {USERS_FILE}, se creará uno nuevo al primer registro.")
except Exception as e:
logging.error(f"[DB] Error al cargar usuarios registrados: {e}")
def chat_id_exists(chat_id: int) -> bool:
"""Mock check: returns True if user is in in-memory set."""
return int(chat_id) in _REGISTERED_USERS
def register_user(user_data: dict) -> bool:
"""Mock register: adds user to in-memory set."""
"""
Mock register: adds user to in-memory set and appends to the persistence file.
"""
try:
meta = user_data.get("meta", {})
metadata = user_data.get("metadata", {})
tid = meta.get("telegram_id") or metadata.get("telegram_id") or metadata.get("chat_id")
if tid:
_REGISTERED_USERS.add(int(tid))
logging.info(f"[MockDB] User {tid} registered in memory.")
chat_id = int(tid)
if chat_id not in _REGISTERED_USERS:
_REGISTERED_USERS.add(chat_id)
# Persistir en el archivo de texto
with open(USERS_FILE, "a") as f:
f.write(f"{chat_id}\n")
logging.info(f"[DB] User {chat_id} registered in memory and persisted to file.")
else:
logging.info(f"[DB] User {chat_id} was already registered.")
return True
logging.warning("[MockDB] Could not find telegram_id in user_data.")
logging.warning("[DB] Could not find telegram_id in user_data to register.")
return False
except (ValueError, TypeError) as e:
logging.error(f"[DB] Invalid telegram_id format: {tid}. Error: {e}")
return False
except Exception as e:
logging.error(f"[MockDB] Register error: {e}")
logging.error(f"[DB] Register error: {e}")
return False