TGLotteryBot
Telegram lottery bot with built-in Mini App - create, announce, and draw lotteries without leaving Telegram
English · 简体中文
- ✨ Features
- 🚀 Quick Start
- 🤖 Bot Setup
- 📡 Bot Commands
- 💻 Local Development
- ⚙️ Configuration
- 🐳 Services
- 📁 Project Structure
- 🤝 Contributing
- 📝 License
✨ Features
- Telegram Mini App - full lottery management UI embedded inside Telegram; no external website required
- Lottery lifecycle - Draft → Active → Finished flow; prizes stay editable while the lottery is in Draft or Active
- Multi-prize draws - each lottery supports multiple prizes with independent quantities; the draw algorithm pairs participants with prizes fairly using a shuffle-based random selection
- Membership requirements - optionally restrict participation to members of specific groups or channels; supports passphrase verification per chat
- Multi-chat announcement - announce to multiple groups or channels simultaneously; messages stay in sync as lottery details change
- Scheduled auto-draw - set an exact date and time for the draw to run automatically
- Deep-link joining - announcement messages carry a
/start lottery_<id>deep link; users tap once to open the Mini App and join - Winner notifications - each winner receives a private congratulatory message from the bot with their prize details
- Invite links - the bot can generate and cache persistent invite links for required chats; participants see the link before they join
🚀 Quick Start
1. Download the required files
curl -LO https://git.stdm.moe/Stardream/TGLotteryBot/raw/branch/main/docker-compose.yml
curl -LO https://git.stdm.moe/Stardream/TGLotteryBot/raw/branch/main/.env.example
mkdir -p nginx
curl -o nginx/nginx.conf https://git.stdm.moe/Stardream/TGLotteryBot/raw/branch/main/nginx/nginx.conf
2. Configure environment
cp .env.example .env
Open .env and fill in the required values:
BOT_TOKEN=123456:ABC-your-bot-token-from-BotFather
MINI_APP_URL=https://your-domain.com
POSTGRES_PASSWORD=change-me
Important
BOT_TOKENandMINI_APP_URLare required. The Mini App URL must be an HTTPS address that Telegram can reach. For production, also setWEBHOOK_URLandWEBHOOK_SECRET.
3. Start
docker compose up -d
4. Register the Mini App
In @BotFather, send /newapp and point the Web App URL to https://your-domain.com. Users can then open the lottery manager directly from bot messages.
5. Open the bot
Send /start to your bot in Telegram to open the Mini App.
Tip
For production deployments, set
WEBHOOK_URLto your public HTTPS URL. Without it, the bot falls back to long-polling, which is fine for development but less efficient in production.
Updating to a newer version
docker compose pull
docker compose up -d
🤖 Bot Setup
After adding the bot to your groups or channels, configure the following in @BotFather:
Disable Privacy Mode (/setprivacy - Disabled)
Required if you use passphrase verification. By default, Telegram bots only receive messages that start with /. Disabling Privacy Mode allows the bot to read all messages in the group so it can detect passphrases sent by users.
Grant Admin rights for anonymous admin detection
If your group has anonymous administrators (members who toggled "Hide my name"), Telegram does not expose their user ID to bots via the standard getChatMember API. Granting the bot administrator rights in the group allows it to verify anonymous admins when checking membership.
Note
These settings only affect groups where you use membership requirements or passphrase verification. For channels or public lotteries without requirements, they are not needed.
📡 Bot Commands
| Command | Description |
|---|---|
/start |
Open the lottery manager Mini App |
/newlottery |
Create a new lottery (shortcut into the Mini App) |
/mylotteries |
View your lotteries |
/help |
Show help and project info |
All lottery management (creating, editing, announcing, drawing) happens inside the Mini App. Bot commands are entry points that open the appropriate Mini App screen.
💻 Local Development
Prerequisites: Docker and Docker Compose
The project ships a docker-compose.override.yml that activates automatically for development:
- Backend mounts the source tree and runs uvicorn with
--reload - Frontend runs the Vite dev server with filesystem polling (safe for NAS / network volumes)
- nginx serves the Vite output and proxies
/apiand/webhookto the backend
cp .env.example .env
# Edit .env - set BOT_TOKEN, MINI_APP_URL; leave WEBHOOK_URL empty for polling mode
docker compose up --build
The development stack is accessible at http://localhost (or whatever PORT you set).
Backend hot-reloads on file save. Frontend hot-reloads are handled by Vite.
⚙️ Configuration
All configuration is read from environment variables (or .env in the project root).
| Variable | Default | Required | Description |
|---|---|---|---|
BOT_TOKEN |
- | Yes | Telegram bot token from @BotFather |
MINI_APP_URL |
- | Yes | Public HTTPS URL where the Mini App frontend is served |
WEBHOOK_URL |
(empty) | No | Public HTTPS base URL for webhook mode. Leave empty to use long-polling |
WEBHOOK_SECRET |
(empty) | No | Secret token sent by Telegram in the X-Telegram-Bot-Api-Secret-Token header |
POSTGRES_PASSWORD |
postgres |
No | PostgreSQL password |
PORT |
80 |
No | Host port exposed by nginx |
DEBUG |
false |
No | Enable FastAPI debug mode |
AVATAR_CACHE_TTL |
3600 |
No | Seconds to cache user and chat avatars server-side |
Warning
Always change
POSTGRES_PASSWORDand generate a strongWEBHOOK_SECRETbefore exposing the deployment to the internet.
🐳 Services
The default compose stack starts four containers:
| Container | Image | Purpose |
|---|---|---|
backend |
tglotterybot-backend:latest |
FastAPI REST API + aiogram Telegram bot |
frontend |
tglotterybot-frontend:latest |
React + Vite Mini App (built static files) |
nginx |
nginx:alpine |
Reverse proxy; routes /api/* and /webhook/* to backend, everything else to frontend |
postgres |
postgres:16-alpine |
PostgreSQL persistent database |
Persistent data is stored in ./postgres_data/.
📁 Project Structure
TGLotteryBot/
├── backend/ # Python FastAPI + aiogram bot
│ ├── app/
│ │ ├── main.py # FastAPI app entrypoint + lifespan setup
│ │ ├── core/
│ │ │ ├── config.py # Pydantic settings (reads from env / .env)
│ │ │ ├── database.py # Async SQLAlchemy engine and session factory
│ │ │ └── security.py # Telegram initData HMAC-SHA256 validation
│ │ ├── api/
│ │ │ ├── deps.py # FastAPI dependencies (authentication)
│ │ │ ├── schemas.py # Pydantic request / response models
│ │ │ └── routers/
│ │ │ ├── lotteries.py # Lottery CRUD, draw, and announce endpoints
│ │ │ ├── prizes.py # Prize management endpoints
│ │ │ ├── participants.py # Join / leave endpoints
│ │ │ ├── chats.py # Managed chat list, links, and avatars
│ │ │ └── users.py # User profile and avatar endpoints
│ │ ├── bot/
│ │ │ ├── router.py # aiogram dispatcher and router registration
│ │ │ ├── handlers/ # Bot command and event handlers
│ │ │ └── keyboards/ # Inline keyboard builders
│ │ ├── models/ # SQLAlchemy 2.0 ORM models
│ │ │ ├── lottery.py # Lottery (status enum, all lottery fields)
│ │ │ ├── prize.py # Prize (name, quantity, sort order)
│ │ │ ├── participant.py # Lottery participants
│ │ │ ├── winner.py # Draw results
│ │ │ ├── user.py # Telegram users
│ │ │ ├── managed_chat.py # Groups / channels the bot manages
│ │ │ └── passphrase_verification.py
│ │ └── services/
│ │ ├── draw_service.py # Draw algorithm (shuffle-based, SELECT FOR UPDATE)
│ │ └── scheduler.py # Auto-draw scheduler + winner notifications
│ ├── alembic/ # Alembic database migrations
│ │ └── versions/
│ ├── requirements.txt
│ └── Dockerfile
├── frontend/ # React 18 + Vite Telegram Mini App
│ ├── src/
│ │ ├── pages/ # Route-level page components
│ │ ├── components/ # Shared UI components
│ │ ├── hooks/ # Custom React hooks
│ │ ├── lib/ # API client, Telegram SDK wrapper, utilities
│ │ └── types/ # TypeScript type definitions
│ ├── package.json
│ ├── vite.config.ts
│ ├── Dockerfile # Production build
│ └── Dockerfile.dev # Dev server (Vite)
├── nginx/
│ ├── nginx.conf # Production reverse proxy config
│ └── nginx.dev.conf # Development config
├── docker-compose.yml # Production service definitions
├── docker-compose.override.yml # Development overrides (auto-applied)
└── .env.example # Environment variable template
🤝 Contributing
Issues and pull requests are welcome. Please open an issue first for major changes so the direction can be discussed.
📝 License
Copyright © 2026 Stardream. This project is licensed under the GNU Affero General Public License v3.0.
Permissions
| ✅ | Commercial use |
| ✅ | Modification |
| ✅ | Distribution |
| ✅ | Private use |
Conditions
| ⚠️ | Disclose source - modified versions must also be open-source |
| ⚠️ | Same license - derivative works must use AGPL-3.0 |
| ⚠️ | Network use = distribution - if you run a modified version as a network service, you must make the source available to users |
| ⚠️ | State changes - modifications must be documented |
In short: you are free to use, modify, and self-host TGLotteryBot. If you distribute or offer a modified version as a hosted service, you must publish the full source under AGPL-3.0.