A Persian-first, high-traffic 20 Questions bot rebuilt for busy Telegram groups and Railway. It uses Mistral AI, batches simultaneous questions, enforces backpressure, and keeps the game readable with a compact RTL board.
- Compact rotating board: the active board is edited in place, then a fresh board is posted after every 4 counted questions so it never disappears too far up the chat.
- Question batching: up to 6 questions received together become one Mistral request.
- Per-user cooldown: one player cannot flood the game.
- Bounded queue: load is rejected safely instead of consuming unlimited memory.
- Coalesced board refreshes: many state changes produce at most one edit per refresh window.
- Shared HTTP client + connection pooling: no new HTTP client/TLS handshake for every question.
- Global AI concurrency limit, retries, and 429/5xx backoff.
- Answer cache: repeated questions about the same word do not call Mistral again.
- Telegram concurrent update processing with a larger connection pool.
- Optional cleanup: if the bot is an admin with Delete Messages permission,
/q,/guess, and/hintmessages are removed after being queued, keeping the group clean. - True Persian RTL layout: every UI line receives an explicit right-to-left marker, including lines containing Latin usernames.
- Playful roast mode: varied Persian banter and mild vulgar jokes keep wrong guesses and weak questions entertaining without using hate speech or threats.
The included word bank contains 600+ curated Persian words across 10 categories. Every round can be configured for 20 or 30 questions before choosing the category.
| Command | Purpose |
|---|---|
/new or /play |
Choose 20/30 questions, then a category |
/q آیا زنده است؟ |
Submit a question |
/guess فیل |
Guess the secret word |
/hint |
Unlock one hint after 4 answered questions |
/status |
Refresh the existing live board |
/rules |
Show rules |
/stop |
Stop the game (starter/admin only) |
Players may also reply directly to the live board with a question. Ordinary group messages are ignored.
Requires Python 3.11+.
python -m venv .venv
source .venv/bin/activate # Windows: .venv\\Scripts\\activate
pip install -r requirements.txt
cp .env.example .envSet these required variables in your shell or .env manager:
TELEGRAM_BOT_TOKEN=your_new_botfather_token
MISTRAL_API_KEY=your_mistral_api_key
MISTRAL_MODEL=mistral-small-latestThe bot intentionally contains no token or API key. Run it with:
python bot.py- Add the bot to the group.
- For the clean one-board experience, promote it and grant Delete messages. This is optional; the game still works without it.
- In BotFather, privacy mode may stay enabled because
/qand replies to the bot's board are enough. - Run
/new, choose a category, and play.
- Push this folder to a new GitHub repository.
- In Railway, choose New Project → Deploy from GitHub repo.
- Add Railway variables:
TELEGRAM_BOT_TOKENMISTRAL_API_KEY- optional
MISTRAL_MODEL=mistral-small-latest
- Deploy.
railway.json/Procfilestartspython bot.pyas a worker. - Do not add a public domain; this build uses long polling and needs no web server.
Railway will restart the worker on failure. Active rounds are held in memory and reset on a deployment/restart; no user data or secret words are stored externally.
Defaults are already conservative for a free Mistral key:
PER_USER_COOLDOWN=8
AI_BATCH_SIZE=6
AI_BATCH_WINDOW=0.45
MAX_PARALLEL_AI_CALLS=4
BOARD_REFRESH_SECONDS=1.4
MAX_QUEUE_SIZE=48If the free API tier rate-limits you, increase AI_BATCH_WINDOW to 0.8, reduce MAX_PARALLEL_AI_CALLS to 2, or increase PER_USER_COOLDOWN to 12. Do not blindly raise concurrency: free-tier limits, not CPU, are normally the bottleneck.
- The expired credentials from the old single-file bot were removed.
- Never commit
.env; it is included in.gitignore. - Create fresh Telegram and Mistral credentials before deploying.
- Mistral output is constrained to
Y/N/M/R; the bot itself renders answers and never displays raw model output.
python -m compileall .
python -m unittest discover -s tests -vbot.py— Telegram handlers, queue workers, live board, anti-spam controlscore.py— Persian normalization, exact guessing, forbidden-question filtermistral_client.py— batched Mistral client, cache, retries, concurrency controlwords.py— categorized Persian word bankconfig.py— validated environment configurationrailway.json,Procfile,runtime.txt— Railway deploymenttests/— core safety and word-bank checks