100% vibecoded, no guarantees given but it seems to work.
Discord bot for weekly football prediction leagues. Admins create fixtures and enter results. Players submit score predictions by thread or DM. The bot stores picks, calculates points, and posts standings.
- Thread predictions on fixture announcement threads
- DM prediction flow via
/predict - Flexible score parsing:
2-1,2:1,2 : 1 - Per-fixture deadlines with late-pick handling
- Standings, saved predictions, and weekly results posting
- SQLite persistence with automatic backups after successful score calculation
/predict- start the DM prediction flow/fixtures- show open fixtures and deadlines/mypredictions- show your saved predictions for open fixtures/standings- show the leaderboard and latest scored fixture
/admin panel- open the admin panel for deletion, overrides, waivers, and result correction/admin fixture create- create a fixture by DM and post its prediction thread/admin fixture delete [week]- delete an open fixture/admin results enter [week]- enter actual results by DM/admin results calculate [week]- calculate scores and post results/admin results post- repost results with optional mentions
Admins need a Discord role named Admin or typer-admin.
Send MessagesRead Message HistoryAdd ReactionsCreate Public ThreadsUse Slash Commands
- Reply in the fixture thread with one line per match.
- Run
/predictor DM the bot and submit the same scores privately. - Thread submissions are one-shot. To replace a saved prediction, use
/predictor DM the bot again.
Example:
Team A - Team B 2:1
Team C - Team D 0:0
Team E - Team F 3:2
- Exact score: 3 points
- Correct outcome: 1 point
- Wrong outcome: 0 points
- Late predictions: 0 points unless an admin waives the penalty
- Match data, predictions, results, and scores are stored in SQLite.
- Active DM workflows and short-lived cooldowns are kept in memory.
- This includes the thread-post rate limiter and the
/admin results calculatecooldown. - The bot is intentionally single-process for v1. If the process restarts, in-progress DM workflows are lost and in-memory cooldowns reset.
DISCORD_TOKEN- Discord bot token
ENVIRONMENT-productionto run the bot; default isdevelopment, which only smoke-tests config and exitsDATA_DIR- base data directory; default./datalocally, set/app/dataon RailwayDB_PATH- database path; default{DATA_DIR}/typer.dbBACKUP_DIR- backup directory; default{DATA_DIR}/backupsTZ- timezone for admin deadline input; defaultUTCREMINDER_CHANNEL_ID- reminder channel IDLOG_LEVEL- logging level; defaultINFO
- Fork this repo.
- New Project on Railway -> Deploy from GitHub.
- Add a persistent volume mounted at
/app/data. - Set Variables:
DISCORD_TOKEN=<your token>ENVIRONMENT=productionDATA_DIR=/app/data- optional:
TZ=Europe/Warsaw
By default the bot runs in smoke-test mode. It validates config and exits without connecting to Discord. Local runs also default to DATA_DIR=./data and TZ=UTC.
git clone https://github.com/adrunkhuman/TyperBot
cd TyperBot
uv sync --group dev
export DISCORD_TOKEN="your_token"
uv run python -m typer_botLive run:
export DISCORD_TOKEN="your_token"
export ENVIRONMENT=production
uv run python -m typer_botWindows PowerShell:
$env:DISCORD_TOKEN="your_token"
$env:ENVIRONMENT="production"
uv run python -m typer_botuv sync --group dev
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run ty check typer_bot- Automatic: the database is backed up after each successful
/admin results calculate. The bot keeps the latest 10 backups inBACKUP_DIR. - Manual restore: run from the Railway shell.
ls /app/data/backups/
python scripts/restore_db.py /app/data/backups/backup_*.sqlThe restore script asks for confirmation, restores into a temporary SQLite file first, and only replaces the live database after a successful restore.
MIT.