Ir al contenido

Documentación

Wiki

Cómo se usa BogaBot y cómo levantar tu propia instancia en tu server. El bot es de uso libre: clonás el repo y lo corrés con tu propio bot y tus propios tokens.

Qué es

BogaBot es un bot de Discord modular. El módulo 1 (el MVP actual) es el ranking de League of Legends de un grupo de amigos: vincular cuenta de Riot → ingerir partidas desde la Riot API 1×/día → calcular un puntaje configurable por jugador → publicar rankings en Discord.

Está armado por capas reemplazables: el storage vive detrás de una interfaz (hoy es “Discord como base de datos”, migrar a SQLite o Postgres es una clase nueva), los módulos son cogs autocontenidos y la fórmula del ranking es un archivo YAML editable sin tocar código.

Python · discord.py · aiohttpLAS (la2 / americas) por defecto, configurable por regiónMVP · Módulo 1 (LoL)

Para jugadores

Si el bot ya está en tu server, lo único que tenés que hacer es vincularte:

  1. Corré /link Nombre#TAG con tu Riot ID completo (el nombre y el tag que ves en el cliente de LoL, ej. Faker#KR1).
  2. El bot valida la cuenta contra la Riot API. Si existe, queda vinculada y tus partidas de esta semana empiezan a contar.
  3. Usá /ranking cuando quieras ver la tabla, o esperá el posteo automático de cada noche.
Una partida solo cuenta si la jugaste con al menos otro miembro vinculado del grupo. Las que jugás sin nadie conocido se descartan.

Requisitos

RuntimePython · discord.py · aiohttp
Cuenta de DiscordCon permiso para crear una Application y un bot
Riot API keyDevelopment (vence cada 24 h) o Production
Server de DiscordDonde invitás el bot, con canales y roles propios
HostingLocal (python run.py) o una VPS con systemd

Setup en Windows / PowerShell: python -m venv venv venv\Scripts\activate pip install -r requirements.txt.

Crear el bot en Discord

Paso 1

Crear el bot en Discord

En el Developer Portal: New Application → pestaña Bot → Reset Token. Ese valor va en DISCORD_TOKEN. Dejá los Privileged Gateway Intents apagados, el bot no los necesita.

Paso 2

Invitarlo a tu server

OAuth2 → URL Generator. Scopes: bot y applications.commands. Permisos: Send Messages, Read Message History, Embed Links, View Channel y Manage Roles (esta última solo si vas a usar LOL_ROLE_ID).

Paso 3

Activar el modo desarrollador

Ajustes de usuario → Avanzado → Modo de desarrollador. Con eso, click derecho sobre cualquier canal, rol o server te deja copiar su ID.

Permisos al invitarlo

En OAuth2 → URL Generator, scopes bot y applications.commands. Bot permissions:

  • Send Messages, Embed Links, View Channel y Read Message History en los canales de storage y de rankings.
  • Manage Roles solo si vas a usar LOL_ROLE_ID (para que el bot asigne ese rol al vincular).
  • No requiere intents privilegiados: dejalos apagados.

Canales y roles

Con el modo desarrollador activado (Ajustes → Avanzado), click derecho sobre cada canal o rol te deja copiar su ID. Necesitás también el ID del server para DISCORD_GUILD_ID.

Creá estoTipoVariablePara qué
Canal de texto privado (solo lo ve el bot)canalSTORAGE_CHANNEL_IDEl bot lo usa como base de datos: guarda mensajes JSON acá. Nadie más debería verlo ni escribir en él.
Canal público para los rankingscanalRANKING_CHANNEL_IDDonde se postean el ranking diario y el recap semanal.
Canal de avisos de partida terminada · opcionalcanalMATCH_NOTIFY_CHANNEL_IDSi lo seteás, el bot avisa en vivo cuando termina una partida jugada por el grupo.
Canal general (papelones) · opcionalcanalGENERAL_CHANNEL_IDDonde caen los avisos de papelón (derrota antes de los 25 min).
Canal de logs del bot · opcionalcanalLOG_CHANNEL_IDEl bot reenvía acá sus logs WARNING+ (Riot caído, key vencida, etc.) además de la consola.
Canal para comandos de admin · opcionalcanalADMIN_CHANNEL_IDSi lo seteás, /link-admin e /ingest-now solo se pueden correr ahí.
Rol de quien administra el botrolDEV_ROLE_IDHabilita /link-admin, /unlink-admin e /ingest-now.
Rol de jugador / miembro del grupo · opcionalrolPLAYER_ROLE_IDSolo afecta qué comandos muestran /help y /ayuda.
Rol que se asigna solo al vincularse · opcionalrolLOL_ROLE_IDAl hacer /link, el bot te da este rol (necesita permiso Manage Roles).
El canal de STORAGE_CHANNEL_ID es la base de datos del bot (mensajes JSON). No debería verlo ni escribir en él nadie más que el bot.

Riot API key

En developer.riotgames.com generás la key. Va en RIOT_API_KEY.

Tipo de keyDuraciónCuándo
DevelopmentVence cada 24 h — hay que regenerarla a manoPruebas, desarrollo
ProductionEstableEl bot corriendo en serio

Ajustá también RIOT_PLATFORM y RIOT_REGION a tu región. Por defecto está en LAS: RIOT_PLATFORM=la2, RIOT_REGION=americas (LAS, LAN y NA rutean a americas).

Si la key vence mientras el bot corre, la ingesta se corta y el bot loguea un CRITICAL (con cooldown de 3 h) que llega a LOG_CHANNEL_ID si lo configuraste.

Variables de entorno

Todo sale de un archivo .env — el código nunca hardcodea secretos ni IDs. Ninguno de los .env.* reales se commitea.

VariableDescripción
DISCORD_TOKENToken del bot (pestaña Bot → Reset Token). Discord no lo vuelve a mostrar.
DISCORD_GUILD_IDID del server. Opcional, pero registra los slash commands al instante.
STORAGE_CHANNEL_IDCanal privado que el bot usa como base de datos.
RANKING_CHANNEL_IDCanal donde publica los rankings.
DEV_ROLE_IDRol habilitado para los comandos de administración.
ADMIN_CHANNEL_IDCanal donde se pueden correr esos comandos (opcional).
PLAYER_ROLE_IDRol de jugador; define qué ve /help y /ayuda.
LOL_ROLE_IDRol que el bot asigna al vincular una cuenta (opcional).
MATCH_NOTIFY_CHANNEL_IDCanal de avisos de partida terminada (opcional).
GENERAL_CHANNEL_IDCanal donde se avisan los papelones (opcional).
MATCH_POLL_INTERVAL_MINUTESCada cuántos minutos se chequean partidas nuevas para el aviso en vivo (default 5).
RIOT_API_KEYAPI key de Riot. La development key vence cada 24 h.
RIOT_PLATFORMPlataforma de la región (LAS → la2).
RIOT_REGIONRouting regional (LAS/LAN/NA → americas).
TIMEZONEZona horaria para los cortes de día/semana (default America/Argentina/Buenos_Aires).
DAILY_POST_HOUR / DAILY_POST_MINUTEHora local del job diario. Recomendado 23:55, para que el ranking de hoy no salga vacío.
LOG_CHANNEL_IDCanal donde el bot manda sus propios logs (opcional).
LOG_CHANNEL_LEVELNivel mínimo que se reenvía a ese canal (default WARNING).

Staging vs. producción

El ambiente lo elige la variable de shell BOGABOT_ENV (se setea en la terminal antes de correr, no dentro del .env):

BOGABOT_ENVCargaUso
sin setear o staging.env.stagingDefault. Desarrollo y pruebas.
production.env.productionEl bot real, en el server real.
# local, default staging
python run.py

# explícito
$env:BOGABOT_ENV = "production"
python run.py

# con el script (consola + log en logs\)
.\scripts\run_bot.ps1 -Environment production

El default es staging a propósito: si te olvidás de setear la variable, nunca corrés contra producción por accidente. Recomendado: staging apunta a otro bot y otro server, no al mismo, porque el storage vive en canales de Discord y mezclarías datos de prueba con datos reales.

Comandos

ComandoQué haceQuién
/link <Nombre#TAG>Vincula tu cuenta de Riot con tu Discord. Se valida contra la Riot API; si el Riot ID no existe, no guarda nada.todos
/unlinkDesvincula tu cuenta. Tus partidas dejan de contar para el ranking.todos
/ranking [Hoy | Semana]Muestra el ranking del grupo on-demand, sin esperar al posteo automático.todos
/help · /ayudaListan los comandos disponibles según tu rol. Son dos nombres para lo mismo.todos
/link-admin <usuario> <Nombre#TAG>Vincula la cuenta de Riot de otro usuario del server. Requiere el rol dev y, si está configurado, correrse en el canal de administración.rol dev
/unlink-admin <usuario>Desvincula la cuenta de otro usuario del server.rol dev
/ingest-nowFuerza una ingesta de partidas manual. Es idempotente: el dedup por (match_id, puuid) saltea lo que ya está guardado, así que correrlo de más no duplica nada.rol dev

/ingest-now es idempotente: el dedup por (match_id, puuid) saltea lo que ya está guardado, así que correrlo de más no duplica nada.

Cómo se calcula el ranking

  1. Cada partida se guarda como un registro por jugador, pero solo si la jugaste acompañado de al menos otro vinculado del grupo. Las solitarias se descartan en la ingesta (se chequea metadata.participants del JSON de match-v5).
  2. Se excluyen los remakes (menos de 5 min o early surrender).
  3. Las ventanas son día y semana desde el lunes 00:00 hora local (TIMEZONE, default Buenos Aires).
  4. En cada ventana se agregan las stats por jugador y el motor de scoring aplica la fórmula de config/scoring.yaml.
  5. El job diario corre a DAILY_POST_HOUR:DAILY_POST_MINUTE (recomendado 23:55): ingesta → ranking del día. Los lunes, además, el recap semanal “Trolls y Pros” de la semana que cerró — contando solo Ranked Flex (queue 440), para medir el juego serio del grupo.
  6. Dedup por (match_id, puuid)sin cursor: cada corrida pide “desde el lunes” y saltea lo ya guardado.

Motor de scoring

La fórmula vive en config/scoring.yaml y se edita sin tocar código. Para cada jugador se calcula cada métrica (promediada por partida), se normaliza entre todos los jugadores y el puntaje final es la suma de peso × valor_normalizado.

aggregationper_game_average — promedio por partida — justo para quien juega poco vs. mucho
normalizationzscore — (valor − promedio) / desvío, para que ninguna métrica domine por tener números más grandes

Métricas activas por defecto

MétricaPesoQué mide
win_rate5.0% de victorias
kda3.0(kills + assists) / muertes
avg_deaths2.0 muertes promedio por partida
damage_per_min1.5daño a campeones por minuto
avg_vision1.0vision score promedio
games_played0.5partidas jugadas (premia participación)

= menos es mejor (el valor normalizado se invierte). El motor soporta además avg_kills, avg_assists, cs_per_min, desactivadas por defecto — se activan agregándolas al YAML.

Avisos en vivo y logs

Partida terminada

Si MATCH_NOTIFY_CHANNEL_ID está seteado, cada MATCH_POLL_INTERVAL_MINUTES (5 por defecto) el bot chequea partidas nuevas y, por cada una jugada con otro vinculado, postea un mensaje etiquetando a los jugadores del grupo que la jugaron — con el resultado de cada uno, por si terminaron en equipos contrarios.

Trolleadas y papelones

Cada corrida del scheduler detecta, entre las últimas 48 h, partidas trolleadas (KDA < 0.5 y FF antes de los 20 min) y papelones (derrota antes de los 25 min). Las trolls avisan en RANKING_CHANNEL_ID; los papelones en GENERAL_CHANNEL_ID. Hay un ranking histórico de trolls, y el aviso consulta el timeline de la partida para mostrar en qué minuto moriste por primera vez.

Logs a Discord

Si LOG_CHANNEL_ID está seteado, los logs de nivel LOG_CHANNEL_LEVEL (WARNING por defecto) o superior se reenvían también a ese canal, además de la consola. Pensado para enterarte de errores (Riot caído, key vencida) sin mirar la terminal.

Deploy

Local

python run.py directo, o .\scripts\run_bot.ps1 [-Environment production], que abre consola visible y espeja todo a logs\<ambiente>\. No levantes dos instancias contra el mismo ambiente/server: te responderían los comandos dos veces.

VPS (systemd)

El repo trae deploy/bogabot.service. El setup es una vez: clonar, venv + pip install, copiar el .env por scp, instalar el service y systemctl enable --now bogabot. Después, cada push a main que pase los tests se despliega solo por GitHub Actions (git pull + pip install + systemctl restart).

sudo cp deploy/bogabot.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now bogabot
sudo journalctl -u bogabot -f  # logs en vivo

Estado y límites

  • Alcance: módulo 1 (ranking de LoL). Sin funciones de IA todavía — están en el backlog como cog aparte.
  • Storage: hoy es Discord (mensajes JSON en un canal privado + índice en memoria). Es O(n) mensajes; migrar a una DB real es una clase nueva en storage/ y una línea en bot.py.
  • Colas:el ranking diario/semanal cuenta todas las colas (incluye ARAM y rotativos); el recap “Trolls y Pros” solo Ranked Flex.
  • Región: decisión tomada para LAS (la2 / americas); configurable para otras.

Bugs, ideas y pedidos → issues del repo.