Bot modular para Discord desarrollado en Python, orientado a comunidades, moderación y utilidades reales.
Autor: Alejandro Daniel Di Stefano
PyBot es un bot de Discord construido como un proyecto de software mantenible, no como una colección de handlers en un único archivo.
La versión 2.0 reorganiza completamente el proyecto alrededor de:
- slash commands nativos de Discord;
- arquitectura modular mediante Cogs;
- persistencia local con SQLite;
- llamadas HTTP asíncronas;
- configuración por servidor;
- moderación con validaciones de permisos y jerarquía;
- recordatorios persistentes;
- roles autoasignables controlados;
- CI, tests y linting;
- configuración segura mediante variables de entorno;
- documentación de arquitectura, comandos y despliegue.
La implementación está pensada para ser útil en un servidor real y, al mismo tiempo, funcionar como material educativo sobre desarrollo profesional de bots con Python y discord.py.
/ayuda: centro de ayuda del bot./ping: latencia actual./about: versión, framework y autor./serverinfo: información del servidor./userinfo: información de un miembro./avatar: avatar en alta resolución.
/dolar: cotización de dólar oficial, blue, MEP, CCL, tarjeta, mayorista o cripto./encuesta: encuesta con hasta cinco opciones./elegir: selección aleatoria entre alternativas./dado: dados configurables./moneda: cara o cruz./mapa: enlace seguro de búsqueda en Google Maps.
La consulta del dólar se realiza de manera asíncrona contra DolarAPI.com, evitando bloquear el event loop de Discord.
/recordar tiempo mensaje/recordatorios/borrar-recordatorio id
Ejemplos de duración:
30s
15m
2h
3d
1w
Los recordatorios se guardan en SQLite, por lo que sobreviven a reinicios del proceso.
- bienvenida configurable;
- despedida configurable;
- autorol para nuevos miembros;
- roles autoasignables seguros;
- mod-log configurable.
Administración:
/config-ver
/config-bienvenida
/config-despedida
/config-modlog
/config-autorol
/config-rol-agregar
/config-rol-quitar
Miembros:
/roles
/rol
A diferencia del comportamiento histórico basado en reaccionar a cualquier emoji cuyo nombre coincidiera con un rol, la versión actual usa una allowlist persistente de roles autoasignables. Esto evita que un usuario pueda obtener accidentalmente un rol sensible.
/limpiar/timeout/untimeout/expulsar/banear/slowmode
Los comandos verifican:
- permisos del moderador;
- permisos del bot;
- jerarquía de roles;
- owner del servidor;
- imposibilidad de automoderarse;
- límites propios de Discord.
Si existe un canal de mod-log, las acciones relevantes quedan auditadas allí.
Discord Gateway / Interactions
│
▼
┌──────────────────────────────┐
│ PyBot Core │
│ commands.Bot · CommandTree │
│ intents · lifecycle · errors │
└──────────────┬───────────────┘
│
┌───────┴─────────────────────────┐
▼ ▼
┌─────────────────────┐ ┌─────────────────────┐
│ Cogs │ │ Services │
│ core │ │ aiohttp session │
│ community │ │ SQLite repository │
│ moderation │ │ external APIs │
│ utilities │ └──────────┬──────────┘
│ reminders │ │
└─────────────────────┘ ▼
┌───────────────┐
│ SQLite │
│ settings │
│ reminders │
│ self roles │
└───────────────┘
Más detalle en docs/ARCHITECTURE.md.
Pybot/
├── .github/
│ └── workflows/
│ └── ci.yml
├── docs/
│ ├── ARCHITECTURE.md
│ ├── COMMANDS.md
│ └── DEPLOYMENT.md
├── pybot/
│ ├── cogs/
│ │ ├── core.py
│ │ ├── community.py
│ │ ├── moderation.py
│ │ ├── reminders.py
│ │ └── utilities.py
│ ├── utils/
│ │ └── timeparse.py
│ ├── bot.py
│ ├── config.py
│ ├── database.py
│ └── logging_config.py
├── tests/
├── .env.example
├── Dockerfile
├── main.py
├── pyproject.toml
├── requirements.txt
└── requirements-dev.txt
- Python 3.11 o superior;
- una aplicación creada en Discord Developer Portal;
- token del bot;
- acceso para invitar el bot al servidor.
La versión de referencia usa discord.py 2.7.1.
- Ir a Discord Developer Portal.
- Crear una New Application.
- Entrar a Bot y crear/configurar el bot.
- Regenerar/copiar el token y guardarlo únicamente en
.env. - Habilitar Server Members Intent.
Message Content Intentpuede permanecer deshabilitado con la configuración estándar de PyBot.- En OAuth2 → URL Generator, seleccionar:
botapplications.commands
- Seleccionar sólo los permisos que realmente utilizará el bot.
- View Channels
- Send Messages
- Embed Links
- Add Reactions
- Read Message History
Agregar, según las funciones deseadas:
- Manage Messages
- Moderate Members
- Kick Members
- Ban Members
- Manage Channels
- Manage Roles
No es recomendable conceder
Administratorsólo para simplificar la configuración.
git clone https://github.com/Drako01/Pybot.git
cd PybotLinux/macOS:
python -m venv .venv
source .venv/bin/activateWindows PowerShell:
python -m venv .venv
.\.venv\Scripts\Activate.ps1python -m pip install --upgrade pip
pip install -r requirements.txtcp .env.example .envEn Windows podés copiarlo manualmente o usar:
Copy-Item .env.example .envEditar .env:
DISCORD_TOKEN=tu-token-real
DEV_GUILD_ID=
DATABASE_PATH=data/pybot.db
LOG_LEVEL=INFO
SYNC_COMMANDS=true
ENABLE_MESSAGE_CONTENT_INTENT=false
BOT_STATUS=Usá /ayuda
CURRENCY_API_BASE_URL=https://dolarapi.com/v1
HTTP_TIMEOUT_SECONDS=8python main.pyLos slash commands globales pueden tardar en propagarse por Discord.
Durante desarrollo es conveniente establecer:
DEV_GUILD_ID=123456789012345678En ese caso PyBot copia y sincroniza los comandos directamente al servidor de desarrollo, haciendo que los cambios aparezcan mucho más rápido.
Para producción puede dejarse vacío y usar sincronización global.
SQLite se inicializa automáticamente en:
data/pybot.db
Se almacenan:
- configuración por guild;
- canales de bienvenida/despedida/mod-log;
- autorol;
- roles autoasignables;
- recordatorios pendientes.
La carpeta data/ está ignorada por Git.
En Docker o un proveedor cloud se debe montar como volumen persistente si se quiere conservar la información entre recreaciones del contenedor.
Instalar tooling:
pip install -r requirements-dev.txtLint:
ruff check .Compilación estática básica:
python -m compileall -q main.py pybotTests:
pytest -qGitHub Actions ejecuta para Python 3.11 y 3.12:
install dependencies
↓
ruff check
↓
compileall
↓
pytest
El objetivo es evitar que cambios en un Cog, configuración o persistencia lleguen a main sin validación automática.
Construir:
docker build -t pybot .Ejecutar:
docker run --rm \
--env-file .env \
-v "$(pwd)/data:/app/data" \
pybotEn Windows PowerShell:
docker run --rm --env-file .env -v "${PWD}/data:/app/data" pybotMás opciones en docs/DEPLOYMENT.md.
Nunca subir al repositorio:
DISCORD_TOKEN;- archivos
.envreales; - secretos de APIs;
- bases SQLite de producción;
- logs con información sensible.
Si un token de Discord se publica accidentalmente, no alcanza con borrar el archivo o commit: debe regenerarse inmediatamente desde Discord Developer Portal.
Consultar SECURITY.md.
El bot ya no depende de inspeccionar todos los mensajes del servidor para ejecutar sus funciones principales. Esto mejora UX, descubribilidad y reduce la necesidad del intent privilegiado MESSAGE_CONTENT.
La implementación anterior usaba requests.get() dentro de una coroutine. Ahora se comparte una única aiohttp.ClientSession, evitando bloquear el event loop.
Cada dominio tiene responsabilidad acotada. Agregar una funcionalidad nueva no exige modificar un archivo monolítico.
SQLite conserva configuración y recordatorios sin requerir un servidor de base de datos externo.
Los comandos de moderación usan checks de permisos y validan jerarquía antes de ejecutar acciones destructivas.
El token se obtiene del entorno y .env permanece fuera de Git.
La arquitectura permite incorporar posteriormente, sin reescribir el core:
- tickets de soporte;
- warnings persistentes;
- sistema de sugerencias;
- estadísticas y observabilidad externa;
- dashboard web;
- PostgreSQL para despliegues multi-instancia;
- métricas Prometheus;
- internacionalización;
- plugins/cogs opcionales por servidor.
MIT. Ver LICENSE.
Alejandro Daniel Di Stefano
GitHub: @Drako01
PyBot se mantiene como proyecto práctico de referencia sobre Python asíncrono, Discord, arquitectura modular, persistencia y buenas prácticas de ingeniería de software.