ContributionGraphPopQuiz
An interactive Telegram quiz bot that gamifies GitHub contributions. Built with Python, SQLite, and the Telegram Bot API — it challenges you daily with CS and GitHub-themed questions, tracks streaks, and even triggers real commits to your contribution graph automatically. Hosted on Render (free tier) with a self-healing keepalive system.
Install / Use
/learn @mitraboga/ContributionGraphPopQuizREADME
<p align="center"> <a href="https://mitraboga.github.io/CloudCostCalculator/" target="_blank" rel="noopener noreferrer"> <img src="assets/Telegram_Quiz_Preview.gif" width="95%" alt="Live Cloud Cost Dashboard Preview"/> </a> </p>
🚀 Why I Created this Project
I wanted a daily discipline of contributing to GitHub—but I didn’t want to spam meaningless commits. Instead, I built a Telegram bot that sends me a daily 5-question CS quiz (DSA, Cloud, Cybersecurity, DevOps, AI/ML, Data Science, General CS). Each finished quiz day creates 5 lightweight commits to a repository I control. That way:
- I learn and sharpen my CS knowledge every day.
- I keep my GitHub contribution graph green with purposeful activity—one quiz = five commits.
- It’s automatic once configured, and runs 24/7 on Render (free tier) so I get my reminders even when my laptop is off.
⚙️What this project does
-
Telegram bot with commands:
/daily— take a 5-question CS quiz/notify HH:MM [TZ]— schedule a daily reminder (e.g.,/notify 07:30 Asia/Kolkata)/when— show your next reminder time/unnotify— disable your reminder/streak— show your current/best streak (completing all 5 in a day)/streakboard— leaderboard per chat/setuser <github-username>+/quiz— a separate GitHub contributions quiz mode/forcecommit [n] [tag]— manual commits for testing (optional)
-
Persists:
- Scores and streaks in
quiz_scores.db(SQLite) - Reminder preferences per user (time + timezone)
- Scores and streaks in
-
After you answer all 5 questions for the day, it triggers 5 GitHub commits via the GitHub API.
-
Runs locally (polling) or in webhook mode. On Render, you can run:
- Polling + keepalive (simple, works on free tier)
- Webhook mode (custom URL path using a secret)
📐Architecture at a glance
main.py # Telegram bot, commands, scheduling, webhook/polling
questions.py # Question bank + random question selection
quiz_engine.py # GitHub contribution-graph question generator (original mode)
storage.py # SQLite schema + CRUD for scores, reminders, streaks
github_committer.py # Minimal GitHub API client to create file commits
requirements.txt # Python dependencies
.env.example # Example env vars (copy to .env locally; never commit real secrets)
Key flows:
-
/notify HH:MM TZ→ saves your reminder in DB → schedules a daily JobQueue job at that time in your timezone. -
At reminder time → bot DM’s you a quiz prompt → you answer Q1..Q5 → when you hit 5 for that day, the bot:
- Marks your day complete (streak++)
- Calls
github_committer.pyto create 5 commits in your configured repo.
📄Requirements
-
Python 3.11+
-
A Telegram bot token from BotFather
-
A GitHub repo to write commits to (e.g.,
yourname/daily-quiz-commits) -
A GitHub Personal Access Token (PAT) with minimal scopes:
- Public repo:
public_repo - Private repo:
repo
- Public repo:
-
(Render deployment) A Render account
📲Installation (local)
# Clone your repo (omit if you already have it locally)
git clone https://github.com/<you>/Contribution-Graph-Pop-Quiz.git
cd Contribution-Graph-Pop-Quiz
# Create and activate a virtualenv (Windows PowerShell shown)
python -m venv .venv
.\.venv\Scripts\Activate.ps1
# Install dependencies
pip install -r requirements.txt
Recommended requirements.txt:
python-telegram-bot[job-queue]==20.7
python-dotenv==1.0.1
tzdata==2025.1
requests==2.32.3
💻Configure environment
Create .env (do not commit this file) based on .env.example:
# Telegram
BOT_TOKEN=123456789:AA...fromBotFather...
# GitHub commits
GITHUB_TOKEN=ghp_xxx... # classic PAT; public_repo or repo depending on target
GITHUB_REPO=yourname/daily-quiz-commits
GH_USER_NAME=Your Name
GH_USER_EMAIL=your-verified-email@example.com # must be a verified GitHub email
# Timezone for defaults
TZ=Asia/Kolkata
# (Webhook mode only)
WEBHOOK_SECRET=some-long-random-string
BASE_URL=https://your-render-service.onrender.com
PORT=10000 # Render injects this; you don't need it locally
Important: Your
GH_USER_EMAILmust be a verified email on your GitHub account, otherwise commits won’t show on your contribution graph.
🏃♂️➡️Run locally (polling)
# from your venv
python -u main.py
-
You should see logs like:
Keepalive HTTP on 8000Starting in polling modeApplication started
Now, in Telegram:
-
Send
/start -
Schedule a reminder:
/notify 11:00 Asia/Kolkata- You’ll receive a test question in ~2 seconds (confirms it’s armed).
-
Check next run:
/when -
Take a quiz:
/daily
🪝Webhook mode (optional)
If you prefer webhook mode, you can run:
python main.py --webhook
Ensure you have:
WEBHOOK_SECRETandBASE_URLset in your environment.- The app will register webhook at
BASE_URL + "/telegram/<WEBHOOK_SECRET>".
Note: Polling mode is simpler and works well on Render free tier (with our keepalive). Webhook mode is available but not required.
☁️ Render Deployment (Free Tier – 24/7 Hosting)
You can run the bot 24/7 on Render so you’ll get the daily notification even when your laptop is off.
Option A: Polling (simple, recommended)
-
Push your code to GitHub (without
.env). -
On Render:
-
Create New → Web Service
-
Link your GitHub repo
-
Build Command:
pip install -r requirements.txt -
Start Command:
python main.py -
Environment → Add:
BOT_TOKEN=... GITHUB_TOKEN=... GITHUB_REPO=yourname/daily-quiz-commits GH_USER_NAME=Your Name GH_USER_EMAIL=your-email@example.com TZ=Asia/Kolkata
-
-
Deploy. Logs should show:
Keepalive HTTP on <port>Starting in polling mode
-
In Telegram:
/notify 11:00 Asia/Kolkata→ you’ll get a test question in ~2 seconds./when→ shows next run (tomorrow at 11:00 IST).
Why this works on free tier: We run a tiny HTTP server inside
main.pyso Render’s health checks keep the service alive. PTB uses long-polling to fetch updates.
Option B: Webhook (optional)
-
Same as above but change Start Command to:
python main.py --webhook -
Add env vars:
WEBHOOK_SECRET=some-long-random-string BASE_URL=https://your-service.onrender.com -
Logs should show:
Starting in WEBHOOK mode at https://.../telegram/<secret>
This is what allows:
- Phone notifications
- Automated commits
- Laptop OFF
- System still running
Step 1 — Create Web Service
<p align="center"> <img src="assets/Render1.png" width="95%" /> </p>- New → Web Service
- Connect GitHub repo
- Python
- Free Plan
Step 2 — Add Environment Variables
<p align="center"> <img src="assets/Render2.png" width="95%" /> </p>Step 3 — Confirm Running Logs
<p align="center"> <img src="assets/Render3.png" width="95%" /> </p>You should see:
- Scheduler started
- Application started
- Webhook set successfully
- No errors
🎯 How It Updates My GitHub Contribution Graph?
After completing 5 questions:
- Bot marks day complete
- Calls GitHub REST API
- Creates 5 commits
- Commits authored with verified email
- GitHub counts them as contributions
One day → 5x green square.
🟢 Real Contribution Graph Result
<p align="center"> <img src="assets/CG_Update.png" width="95%" /> </p>This is 100% automated via:
- Telegram
- SQLite tracking
- APScheduler
- GitHub API
- Render cloud deployment
🔐 Requirements
- Python 3.11+
- Telegram Bot Token
- GitHub Personal Access Token
- Verified GitHub email
- Render account (free tier works)
💥 Why This Is Powerful
This isn't just a bot.
It’s:
- Behavioral reinforcement system
- Learning engine
- Automated GitHub contribution pipeline
- Cloud-hosted productivity system
It enforces discipline.
🐍How the 5 commits work (and how to make them count)
When you answer all 5 questions for the day via /daily, the bot:
- Marks the day completed in
daily_progress→ streak tracking. - Calls
github_committer.make_daily_commits_if_configured(n=5, tag=<user_id>). - That function creates/updates tiny files in
GITHUB_REPO, authored as `GH
