12 KiB
✨ 功能特性
- Telegram Mini App - 完整的抽奖管理界面直接嵌入 Telegram,无需外部网站
- 抽奖生命周期 - 草稿 → 进行中 → 已结束的状态流转;草稿和进行中状态均可编辑奖品
- 多奖品抽奖 - 每个抽奖可设置多个奖品,每个奖品单独配置数量;开奖算法通过双重随机打乱实现公平分配
- 入群验证 - 可限制只有特定群组或频道的成员才能参与,支持对每个群组单独设置口令验证
- 多群同步公告 - 同时向多个群组或频道发布公告,抽奖信息修改后消息自动同步
- 定时自动开奖 - 设定具体日期和时间,到时自动开奖
- 深链接参与 - 公告消息附带
/start lottery_<id>深链接,用户点击即可打开 Mini App 并参与 - 私信通知中奖者 - 每位中奖者将收到机器人发来的私信,包含中奖奖品详情
- 邀请链接管理 - 机器人可生成并缓存所需群组的永久邀请链接,用户加入前即可查看
🚀 快速开始
1. 下载所需文件
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. 配置环境变量
cp .env.example .env
编辑 .env,填入必填项:
BOT_TOKEN=123456:ABC-your-bot-token-from-BotFather
MINI_APP_URL=https://your-domain.com
POSTGRES_PASSWORD=change-me
Important
BOT_TOKEN和MINI_APP_URL为必填项。Mini App URL 必须是 Telegram 可访问的 HTTPS 地址。生产环境还需设置WEBHOOK_URL和WEBHOOK_SECRET。
3. 启动服务
docker compose up -d
4. 注册 Mini App
在 @BotFather 发送 /newapp,将 Web App URL 指向 https://your-domain.com,用户即可从消息中直接打开抽奖管理界面。
5. 使用机器人
在 Telegram 中向你的机器人发送 /start,即可打开 Mini App。
Tip
生产部署时建议设置
WEBHOOK_URL为公网 HTTPS 地址。不设置则退回长轮询模式,适合开发但生产效率较低。
更新到新版本
docker compose pull
docker compose up -d
🤖 Bot 配置
将 Bot 添加到群组或频道后,需要在 @BotFather 中进行以下配置:
关闭隐私模式(/setprivacy - Disabled)
使用口令验证时必须关闭。Telegram Bot 默认只接收以 / 开头的消息,关闭隐私模式后 Bot 才能读取群组中的所有消息,从而识别用户发送的口令。
授予管理员权限以识别匿名管理员
如果群组中存在匿名管理员(开启了"隐藏管理员身份"的成员),Telegram 不会通过标准 getChatMember API 暴露其用户 ID。将 Bot 设为群组管理员后,Bot 才能在验证成员资格时识别匿名管理员。
Note
以上设置仅对使用了成员资格验证或口令验证的群组有效,频道或无参与要求的公开抽奖不需要这些配置。
📡 Bot 命令
| 命令 | 说明 |
|---|---|
/start |
打开抽奖管理 Mini App |
/newlottery |
创建新抽奖(直接跳转至 Mini App 创建页) |
/mylotteries |
查看我的抽奖列表 |
/help |
查看帮助与项目信息 |
所有抽奖管理操作(创建、编辑、发布、开奖)均在 Mini App 内完成,Bot 命令是进入对应页面的入口。
💻 本地开发
前置条件: Docker 和 Docker Compose
项目内置 docker-compose.override.yml,启动时自动生效:
- 后端挂载源码目录,uvicorn 开启
--reload热重载 - 前端运行 Vite 开发服务器,使用文件轮询模式(适配 NAS / 网络文件系统)
- nginx 提供 Vite 构建产物,并将
/api和/webhook反向代理到后端
cp .env.example .env
# 编辑 .env,填入 BOT_TOKEN、MINI_APP_URL;WEBHOOK_URL 留空使用轮询模式
docker compose up --build
开发环境通过 http://localhost(或你设置的 PORT)访问。
保存后端文件后自动热重载,前端热更新由 Vite 处理。
⚙️ 配置说明
所有配置通过环境变量读取(或项目根目录的 .env 文件)。
| 变量 | 默认值 | 必填 | 说明 |
|---|---|---|---|
BOT_TOKEN |
- | 是 | 从 @BotFather 获取的 Telegram 机器人 Token |
MINI_APP_URL |
- | 是 | Mini App 前端的公网 HTTPS 地址 |
WEBHOOK_URL |
(空) | 否 | Webhook 模式的公网 HTTPS 基础地址,留空则使用长轮询 |
WEBHOOK_SECRET |
(空) | 否 | Telegram 在 X-Telegram-Bot-Api-Secret-Token 请求头中发送的密钥 |
POSTGRES_PASSWORD |
postgres |
否 | PostgreSQL 密码 |
PORT |
80 |
否 | nginx 对外暴露的端口 |
DEBUG |
false |
否 | 启用 FastAPI 调试模式 |
AVATAR_CACHE_TTL |
3600 |
否 | 用户和群组头像的服务端缓存时间(秒) |
Warning
对外部署前务必修改
POSTGRES_PASSWORD并生成强随机的WEBHOOK_SECRET。
🐳 服务容器
默认 Compose 配置启动四个容器:
| 容器 | 镜像 | 用途 |
|---|---|---|
backend |
tglotterybot-backend:latest |
FastAPI REST API + aiogram Telegram 机器人 |
frontend |
tglotterybot-frontend:latest |
React + Vite Mini App(静态文件) |
nginx |
nginx:alpine |
反向代理;/api/* 和 /webhook/* 转发至后端,其余请求转发至前端 |
postgres |
postgres:16-alpine |
PostgreSQL 持久化数据库 |
持久化数据存储在 ./postgres_data/。
📁 项目结构
TGLotteryBot/
├── backend/ # Python FastAPI + aiogram 机器人
│ ├── app/
│ │ ├── main.py # FastAPI 应用入口 + 生命周期管理
│ │ ├── core/
│ │ │ ├── config.py # Pydantic 配置(从环境变量 / .env 读取)
│ │ │ ├── database.py # 异步 SQLAlchemy 引擎与会话工厂
│ │ │ └── security.py # Telegram initData HMAC-SHA256 验证
│ │ ├── api/
│ │ │ ├── deps.py # FastAPI 依赖项(身份认证)
│ │ │ ├── schemas.py # Pydantic 请求 / 响应模型
│ │ │ └── routers/
│ │ │ ├── lotteries.py # 抽奖 CRUD、开奖、公告端点
│ │ │ ├── prizes.py # 奖品管理端点
│ │ │ ├── participants.py # 参与 / 退出端点
│ │ │ ├── chats.py # 托管群组列表、链接、头像
│ │ │ └── users.py # 用户信息与头像端点
│ │ ├── bot/
│ │ │ ├── router.py # aiogram 调度器与路由注册
│ │ │ ├── handlers/ # Bot 命令与事件处理器
│ │ │ └── keyboards/ # 内联键盘构建器
│ │ ├── models/ # SQLAlchemy 2.0 ORM 模型
│ │ │ ├── lottery.py # 抽奖(状态枚举、所有抽奖字段)
│ │ │ ├── prize.py # 奖品(名称、数量、排序)
│ │ │ ├── participant.py # 参与者
│ │ │ ├── winner.py # 开奖结果
│ │ │ ├── user.py # Telegram 用户
│ │ │ ├── managed_chat.py # 机器人管理的群组 / 频道
│ │ │ └── passphrase_verification.py
│ │ └── services/
│ │ ├── draw_service.py # 开奖算法(双重随机 + SELECT FOR UPDATE)
│ │ └── scheduler.py # 定时自动开奖 + 中奖通知
│ ├── alembic/ # Alembic 数据库迁移
│ │ └── versions/
│ ├── requirements.txt
│ └── Dockerfile
├── frontend/ # React 18 + Vite Telegram Mini App
│ ├── src/
│ │ ├── pages/ # 路由级页面组件
│ │ ├── components/ # 通用 UI 组件
│ │ ├── hooks/ # 自定义 React Hooks
│ │ ├── lib/ # API 客户端、Telegram SDK 封装、工具函数
│ │ └── types/ # TypeScript 类型定义
│ ├── package.json
│ ├── vite.config.ts
│ ├── Dockerfile # 生产构建
│ └── Dockerfile.dev # 开发服务器(Vite)
├── nginx/
│ ├── nginx.conf # 生产环境反向代理配置
│ └── nginx.dev.conf # 开发环境配置
├── docker-compose.yml # 生产服务定义
├── docker-compose.override.yml # 开发覆盖配置(自动生效)
└── .env.example # 环境变量模板
🤝 贡献
欢迎提交 Issue 和 Pull Request。重大变更请先开 Issue 讨论方向。
📝 许可证
Copyright © 2026 Stardream。本项目采用 GNU Affero General Public License v3.0 许可证。
权利
| ✅ | 商业使用 |
| ✅ | 修改 |
| ✅ | 分发 |
| ✅ | 私人使用 |
条件
| ⚠️ | 公开源码 - 修改后的版本也必须开源 |
| ⚠️ | 相同许可证 - 衍生作品必须使用 AGPL-3.0 |
| ⚠️ | 网络使用 = 分发 - 若将修改版本作为网络服务运行,必须向用户提供源码 |
| ⚠️ | 标注修改 - 修改内容必须记录在案 |
简而言之:你可以自由使用、修改和自托管 TGLotteryBot。若将修改版本作为托管服务分发或提供,必须以 AGPL-3.0 发布完整源码。