A complete, containerizable Python application for managing photo submissions via Telegram for LED wall display at cricket match events. Built with FastAPI, aiogram, SQLAlchemy, and real-time WebSocket updates.
- Photo Submissions: Users send photos directly via Telegram
- Auto Queue Management: Photos are queued for admin approval
- Rate Limiting: 1 photo per user per 30 minutes to prevent spam
- Smart Queue Control: Automatic slow mode when queue is full (>10 pending)
- User Notifications: Automatic approval/scheduling notifications sent back to users
- Web Interface: Beautiful admin dashboard at
/admin - HTTP Basic Auth: Simple username/password authentication
- Pending Queue: Visual grid of all pending submissions with image previews
- One-Click Actions: Approve or reject with a single click
- Recent History: View recently approved submissions
- Full-Screen Display: Dedicated display page at
/display - Real-Time Updates: WebSocket-powered automatic image updates
- Auto-Scheduling: Approved images automatically scheduled (60s intervals)
- Smooth Transitions: Beautiful fade-in animations
- APScheduler: Automatic scheduling of approved images
- Queue Management: Smart scheduling based on queue status
- WebSocket Broadcasting: Real-time updates to all connected displays
┌─────────────────┐
│ Telegram Bot │ ──► Photo Submissions
│ (aiogram) │
└─────────────────┘
│
▼
┌─────────────────┐
│ SQLite DB │ ──► Queue Storage
│ (SQLAlchemy) │
└─────────────────┘
│
▼
┌─────────────────┐
│ APScheduler │ ──► Auto-Scheduling
│ Background │
└─────────────────┘
│
▼
┌─────────────────┐ ┌─────────────────┐
│ Admin Panel │ │ LED Display │
│ (FastAPI) │ │ (WebSocket) │
└─────────────────┘ └─────────────────┘
- Docker and Docker Compose
- Telegram Bot Token (get from @BotFather)
- Domain with Nginx configured (for production)
Pull and run the latest image:
docker pull ghcr.io/cse23-mora/hit-the-grounds-bot:latest
# Or use docker-compose with the pre-built image
# Update docker-compose.yml to use:
# image: ghcr.io/cse23-mora/hit-the-grounds-bot:latest
# instead of build: .git clone <repository-url>
cd "Hit The Grounds Bot"
# Copy environment template
cp .env.example .env
# Edit .env and add your Telegram bot token
nano .envEdit .env file:
# REQUIRED: Get from @BotFather on Telegram
BOT_TOKEN=your_telegram_bot_token_here
# Admin credentials for web panel
ADMIN_USER=admin
ADMIN_PASS=your_secure_password
# Your domain (for image URLs)
DOMAIN=https://yourdomain.com# Build and start
docker-compose up -d
# View logs
docker-compose logs -f
# Stop
docker-compose downThe application will be available at:
- API: http://localhost:8000
- Admin Panel: http://localhost:8000/admin
- Display: http://localhost:8000/display
Copy the sample Nginx configuration:
sudo cp docs/nginx.conf /etc/nginx/sites-available/hitthegrounds
sudo ln -s /etc/nginx/sites-available/hitthegrounds /etc/nginx/sites-enabled/Edit /etc/nginx/sites-available/hitthegrounds:
- Replace
yourdomain.comwith your actual domain - Update SSL certificate paths
- Update
alias /path/to/hit-the-grounds-bot/data/images/with actual path
# Using certbot (Let's Encrypt)
sudo certbot --nginx -d yourdomain.commkdir -p data/images
touch data/db.sqlite
chmod 777 data/images # Ensure Docker can writeIn production, you may want to:
- Use an external network
- Add restart policies
- Configure resource limits
sudo nginx -t
sudo systemctl reload nginx| Variable | Default | Description |
|---|---|---|
BOT_TOKEN |
- | Required Telegram bot token |
ADMIN_USER |
admin |
Admin username |
ADMIN_PASS |
changeme |
Admin password |
DB_PATH |
/app/db.sqlite |
Database file path |
IMAGES_PATH |
/app/images |
Images storage path |
DOMAIN |
https://yourdomain.com |
Base URL for images |
LOG_LEVEL |
INFO |
Logging level |
RATE_LIMIT_MINUTES |
30 |
Minutes between submissions per user |
QUEUE_FULL_THRESHOLD |
10 |
Queue size to trigger slow mode |
QUEUE_RESUME_THRESHOLD |
5 |
Queue size to resume submissions |
DISPLAY_INTERVAL_SECONDS |
60 |
Seconds between scheduled images |
GET /- API informationGET /health- Health checkGET /admin- Admin panel (auth required)POST /admin/approve/{id}- Approve submissionPOST /admin/reject/{id}- Reject submissionGET /display- Display pageWS /ws/display- WebSocket for real-time updates
id- Primary keyuser_id- Telegram user IDusername- Telegram usernameimage_path- Relative path to imagesubmitted_timestamp- When submittedapproval_status- PENDING | APPROVED | REJECTEDscheduled_time- When to display (null until approved)
id- Always 1 (singleton)submission_id- Current submission being displayedimage_path- Path to current imagedisplay_timestamp- When it started displaying
The project includes a GitHub Actions workflow that automatically builds and pushes Docker images to GitHub Container Registry (GHCR).
Images are automatically built and pushed on:
- Push to main/master branch: Tagged as
latest - Version tags (e.g.,
v1.0.0): Tagged with version numbers - Pull requests: Built but not pushed (for testing)
The workflow builds for both:
linux/amd64(x86_64)linux/arm64(ARM64/aarch64)
Update your docker-compose.yml:
services:
hit-the-grounds-bot:
image: ghcr.io/cse23-mora/hit-the-grounds-bot:latest
# Remove the 'build: .' line
container_name: hit-the-grounds-bot
# ... rest of configuration# Create virtual environment
python -m venv venv
source venv/bin/activate # or `venv\Scripts\activate` on Windows
# Install dependencies
pip install -r requirements.txt
# Create .env file
cp .env.example .env
# Run migrations
alembic upgrade head
# Start application
python main.pypytest tests/# Create a new migration
alembic revision --autogenerate -m "description"
# Apply migrations
alembic upgrade head
# Rollback
alembic downgrade -1- Check
BOT_TOKENis correct - Verify bot is not blocked
- Check logs:
docker-compose logs -f
- Verify Nginx configuration
- Check
DOMAINenvironment variable - Ensure images directory is mounted correctly
- Check file permissions on
data/images/
- Ensure Nginx has WebSocket support configured
- Check firewall allows WebSocket connections
- Verify
wss://(SSL) vsws://protocol
- Ensure only one instance is running
- Check file permissions on
db.sqlite - SQLite doesn't support high concurrency; consider PostgreSQL for production
- Change default
ADMIN_PASSimmediately - Use strong passwords
- Enable HTTPS (never run without SSL in production)
- Keep Telegram
BOT_TOKENsecret - Regularly update dependencies
- Consider implementing rate limiting on web endpoints
- Review and sanitize user-uploaded images
MIT License - feel free to use for your events!
For issues, questions, or contributions, please open an issue on GitHub.
Built with:
- FastAPI - Modern web framework
- aiogram - Telegram Bot framework
- SQLAlchemy - Database ORM
- APScheduler - Background scheduling
- Alembic - Database migrations
Made with ❤️ for cricket fans 🏏