A production-grade Telegram quiz platform — create, manage, and run interactive quizzes at scale.
Sponsored by Qzio • Developed by devgagan
🤖 Try the Live Bot → @advance_quiz_bot
- Features
- Architecture
- Prerequisites
- Quick Start
- Deploy on Heroku (PaaS)
- VPS Setup — Step-by-Step
- Running the Bots
- BotFather Setup
- Configuration Reference
- Project Structure
- Credits
| Category | Capability |
|---|---|
| Quiz Creation | Text input, TXT file, PDF, image/OCR, Drishti IAS URL, Wikipedia/BBC/news articles |
| Quiz Formats | Standard, Sectional (different timers per section), Marathon (unlimited questions) |
| Poll Support | Forward any Telegram quiz poll — bot auto-cleans [1/100] tags and filters |
| Smart Filtering | Remove usernames, links, or custom word lists from imported polls |
| Editing | Shuffle questions, add/change titles, edit timers, add/remove questions |
| Access Control | Free and paid quiz tiers — restrict by user ID or group chat |
| Analytics | Per-user performance, quiz engagement counters, topper comparison |
| HTML Reports | Beautiful self-contained HTML scorecards with light/dark theme |
| Scheduling | Launch quizzes at specific times via the scheduler bot |
| Inline Sharing | Share any quiz by ID via inline query |
| Assignments | Student submission tracking with creator reply forwarding |
| Broadcast | Send announcements to all users (owner only) |
Quizbot/
│
├── main.py ← Pyrogram bot (quiz creation, file imports, management)
├── bot.py ← PTB bot (quiz runner, scheduler, poll tracking)
├── func.py ← Shared helpers (DB, image, HTML, premium checks)
├── c.py ← HTML report generator
└── config.py ← Centralised configuration (reads from .env)
The two bots are independent processes sharing the same MongoDB database:
main.pyhandles everything that requires the MTProto client (file downloads, channel reading, inline queries, quiz creation).bot.pyhandles high-throughput quiz sessions — sending polls rapidly, tracking answers, building leaderboards.
| Requirement | Minimum Version | Notes |
|---|---|---|
| Python | 3.10+ | 3.11 recommended |
| MongoDB | Atlas free tier or self-hosted | MONGO_URI etc. in .env |
| Telegram API credentials | — | From my.telegram.org |
| Two Telegram bot tokens | — | One per bot, from @BotFather |
| VPS / Server | 1 vCPU, 1 GB RAM | Ubuntu 22.04 recommended |
git clone https://github.com/devgaganin/Quizbot.git
cd Quizbot
cp .env.example .env
nano .env # fill in your values
pip install -r requirements.txt
playwright install chromium # needed for PDF generation
python main.py &
python bot.py &Deploy Quizbot to Heroku without managing a server. Both bots run as separate dynos using the same MongoDB Atlas database.
Requirements: A free Heroku account, a GitHub account, and a MongoDB Atlas cluster.
- Go to github.com/devgaganin/Quizbot
- Click the Fork button (top-right corner)
- Select your GitHub account as the destination
- Your fork will be at
https://github.com/<your-username>/Quizbot
Heroku needs two files that may not be in the repo. Check your fork and add them if missing.
Create a file named exactly Procfile (no extension) in the repo root:
main: python main.py
bot: python bot.py
Each line becomes a dyno type —
mainrunsmain.pyandbotrunsbot.py.
Create runtime.txt in the repo root:
python-3.11.9
Commit and push both files to your fork before continuing.
- Log in at dashboard.heroku.com
- Click New → Create new app
- Choose an App name (e.g.
my-quizbot) and your region - Click Create app
- On your app's dashboard, open the Deploy tab
- Under Deployment method, click GitHub
- Click Connect to GitHub and authorise Heroku
- Search for
Quizbot(your fork) and click Connect

- Go to the Settings tab of your Heroku app
- Click Reveal Config Vars
- Add each variable from the table below — click Add after every key/value pair
| Key | Value |
|---|---|
API_ID |
Your Telegram API ID |
API_HASH |
Your Telegram API Hash |
BOT_TOKEN |
Token for the Pyrogram bot (main.py) |
BOT_TOKEN_2 |
Token for the PTB scheduler bot (bot.py) |
MONGO_URI |
Primary MongoDB Atlas connection string |
MONGO_URI_2 |
Secondary MongoDB connection string |
MONGO_URIX |
Async quizzes collection MongoDB URI |
DB_NAME |
quiz_bot (or your chosen DB name) |
OWNER_ID |
Your Telegram user ID |
LOG_GROUP |
Negative chat ID of your log channel |
FORCE_SUB |
Channel ID users must join |
BOT_GROUP |
Community group ID |
CHANNEL_ID |
Announcement channel ID |
MASTER_KEY |
AES key for quiz encryption |
IV_KEY |
AES IV prefix |
FREEMIUM_LIMIT |
0 (unlimited) or a number |
PREMIUM_LIMIT |
500 (default) |
FREE_BOT |
true to skip premium checks |
See Configuration Reference for full descriptions of each variable.
- Still on the Deploy tab, scroll to Manual deploy
- Select your branch (usually
mainormaster) - Click Deploy Branch
- Wait for the build to finish — you'll see a green ✅ and the message "Your app was successfully deployed"
Optionally enable Automatic Deploys so every push to your fork re-deploys automatically.
After a successful deploy, the two processes from your Procfile appear as dynos.
- Go to the Resources tab
- You will see two dynos listed:
main— the Pyrogram bot (main.py)bot— the PTB scheduler bot (bot.py)
- Click the pencil ✏️ icon next to
main, toggle it ON, and click Confirm - Repeat for
bot
Important: Heroku's free tier (Eco dynos) sleeps after 30 minutes of inactivity. For bots that must stay online 24/7, use Basic dynos ($7/month each) or a Hobby plan.
Check the live logs from the Heroku dashboard:
- Click More → View logs (top-right of the dashboard)
- You should see both bots starting up without errors
Or use the Heroku CLI:
heroku logs --tail --app my-quizbotIf you see auth errors, double-check your Config Vars in Settings → Reveal Config Vars.
| Task | How |
|---|---|
| Restart a dyno | Resources tab → toggle dyno off, then on |
| View logs | More → View logs, or heroku logs --tail |
| Update the bot | Push to your fork — Heroku auto-deploys if enabled |
| Scale dynos | Resources tab → change dyno quantity |
| Add a Heroku Postgres (MySQL alternative) | Resources → Add-ons → search "Heroku Postgres" |
Tested on Ubuntu 22.04 LTS. Commands require
sudowhere indicated.
sudo apt update && sudo apt upgrade -ysudo apt install -y python3.11 python3.11-venv python3.11-dev python3-pip
python3.11 --version # should print Python 3.11.xsudo apt install -y \
git \
build-essential \
libssl-dev \
libffi-dev \
libjpeg-dev \
libpng-dev \
libfreetype6-dev \
fonts-noto \
fonts-noto-cjk \
wget curl unzipcd /opt
sudo git clone https://github.com/devgaganin/Quizbot.git
sudo chown -R $USER:$USER /opt/Quizbot
cd /opt/Quizbotpython3.11 -m venv venv
source venv/bin/activatepip install --upgrade pip
pip install -r requirements.txtplaywright install chromium
playwright install-deps chromiumcp .env.example .env
nano .envFill in all required values (see Configuration Reference below). Save with Ctrl+O, exit with Ctrl+X.
python -c "from config import BOT_TOKEN; print('Config OK' if BOT_TOKEN else 'BOT_TOKEN missing')"The easiest way on a VPS is to use systemd services so both bots auto-restart on crash or reboot.
sudo nano /etc/systemd/system/quizbot-main.servicePaste:
[Unit]
Description=Quizbot — Pyrogram (main.py)
After=network.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/opt/Quizbot
ExecStart=/opt/Quizbot/venv/bin/python main.py
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.targetsudo nano /etc/systemd/system/quizbot-scheduler.servicePaste:
[Unit]
Description=Quizbot — PTB Scheduler (bot.py)
After=network.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/opt/Quizbot
ExecStart=/opt/Quizbot/venv/bin/python bot.py
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable quizbot-main quizbot-scheduler
sudo systemctl start quizbot-main quizbot-schedulersudo systemctl status quizbot-main
sudo systemctl status quizbot-scheduler# main.py logs
sudo journalctl -u quizbot-main -f
# bot.py logs
sudo journalctl -u quizbot-scheduler -f
# Both together
sudo journalctl -u quizbot-main -u quizbot-scheduler -fIf you prefer to run without systemd (e.g. for testing), use two terminal sessions or screen/tmux.
sudo apt install -y screen# In terminal 1 (or screen session)
cd /opt/Quizbot
source venv/bin/activate
python main.py# In terminal 2 (or another screen session)
cd /opt/Quizbot
source venv/bin/activate
python bot.py# Start main.py in a named screen
screen -S quiz-main -dm bash -c "cd /opt/Quizbot && source venv/bin/activate && python main.py"
# Start bot.py in a named screen
screen -S quiz-bot -dm bash -c "cd /opt/Quizbot && source venv/bin/activate && python bot.py"
# Attach to see output
screen -r quiz-main
screen -r quiz-bot
# Detach from screen (without stopping it)
# Press: Ctrl+A, then DAfter creating both bots with @BotFather, set their command menus.
All commands are ready to copy from BOTFATHER_COMMANDS.txt.
Steps:
- Open Telegram → search
@BotFather - Send
/setcommands - Select Bot 1 (creator/main bot)
- Open
BOTFATHER_COMMANDS.txt, copy the BOT 1 block (lines under the first=====section), paste and send - Send
/setcommandsagain - Select Bot 2 (scheduler bot)
- Copy the BOT 2 block and send
Additional recommended BotFather settings:
/setinline → Enable inline mode for Bot 1 (inline quiz sharing)
/setprivacy → Disable group privacy for Bot 2 (to read group messages)
/setjoingroups → Enable if you want users to add Bot 2 to groups
All values live in .env. Full documented template: .env.example
| Variable | Required | Description |
|---|---|---|
API_ID |
✅ | Telegram API ID from my.telegram.org |
API_HASH |
✅ | Telegram API Hash from my.telegram.org |
BOT_TOKEN |
✅ | Token for the Pyrogram bot (main.py) |
BOT_TOKEN_2 |
✅ | Token for the PTB scheduler bot (bot.py) |
MONGO_URI |
✅ | Primary MongoDB connection string |
MONGO_URI_2 |
✅ | Secondary MongoDB connection string |
MONGO_URIX |
✅ | Async quizzes collection MongoDB URI |
DB_NAME |
✅ | MongoDB database name (default: quiz_bot) |
OWNER_ID |
✅ | Space-separated Telegram user IDs |
LOG_GROUP |
✅ | Negative chat ID for error/log channel |
FORCE_SUB |
✅ | Channel ID users must join |
BOT_GROUP |
✅ | Main community group ID |
CHANNEL_ID |
✅ | Announcement channel ID |
MASTER_KEY |
✅ | AES key for quiz file encryption |
IV_KEY |
✅ | AES IV prefix |
FREEMIUM_LIMIT |
➖ | Free user question limit (0 = unlimited) |
PREMIUM_LIMIT |
➖ | Premium user question limit (default: 500) |
FREE_BOT |
➖ | true to skip all premium checks |
PAY_API |
➖ | Payment API endpoint URL |
MYSQL_HOST/USER/PASS/DB |
➖ | MySQL credentials for web panel |
Quizbot/
├── main.py # Pyrogram bot — quiz creation & management
├── bot.py # PTB bot — scheduler, runner, leaderboard
├── func.py # Core utilities, DB helpers, image processing
├── c.py # HTML quiz report generator
├── config.py # Central config (reads .env)
├── requirements.txt # Python dependencies
├── Procfile # Heroku process declarations (main + bot dynos)
├── runtime.txt # Heroku Python version pin
├── .env.example # Environment variable template
├── .gitignore
├── LICENSE
├── BOTFATHER_COMMANDS.txt # Ready-to-paste BotFather command lists
└── README.md
| Role | |
|---|---|
| Developed by | devgagan |
| Sponsored by | Qzio — The Smart Quiz Platform |
| Telegram Library | Pyrogram & python-telegram-bot |
| Database | MongoDB Atlas |
Built with ❤️ for educators, exam aspirants, and quiz creators.
© 2026 devgagan.in · Sponsored by Qzio