Files
TGLotteryBot/README.zh-CN.md
T
Stardream eace48732d
Build and Push Docker Images / build (push) Successful in 17s
Initial release
2026-06-02 12:02:02 +10:00

316 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<div align="center"><a name="readme-top"></a>
# TGLotteryBot
**Telegram 抽奖机器人,内置 Mini App - 无需离开 Telegram 即可创建、发布和开奖**
[English](./README.md) · **简体中文**
[![][license-shield]][license-link]
[![][python-shield]][python-link]
[![][docker-shield]][docker-link]
[![][postgres-shield]][postgres-link]
</div>
---
- [✨ 功能特性](#-功能特性)
- [🚀 快速开始](#-快速开始)
- [🤖 Bot 配置](#-bot-配置)
- [📡 Bot 命令](#-bot-命令)
- [💻 本地开发](#-本地开发)
- [⚙️ 配置说明](#-配置说明)
- [🐳 服务容器](#-服务容器)
- [📁 项目结构](#-项目结构)
- [🤝 贡献](#-贡献)
- [📝 许可证](#-许可证)
## ✨ 功能特性
- **Telegram Mini App** - 完整的抽奖管理界面直接嵌入 Telegram,无需外部网站
- **抽奖生命周期** - 草稿 → 进行中 → 已结束的状态流转;草稿和进行中状态均可编辑奖品
- **多奖品抽奖** - 每个抽奖可设置多个奖品,每个奖品单独配置数量;开奖算法通过双重随机打乱实现公平分配
- **入群验证** - 可限制只有特定群组或频道的成员才能参与,支持对每个群组单独设置口令验证
- **多群同步公告** - 同时向多个群组或频道发布公告,抽奖信息修改后消息自动同步
- **定时自动开奖** - 设定具体日期和时间,到时自动开奖
- **深链接参与** - 公告消息附带 `/start lottery_<id>` 深链接,用户点击即可打开 Mini App 并参与
- **私信通知中奖者** - 每位中奖者将收到机器人发来的私信,包含中奖奖品详情
- **邀请链接管理** - 机器人可生成并缓存所需群组的永久邀请链接,用户加入前即可查看
## 🚀 快速开始
**1. 下载所需文件**
```bash
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. 配置环境变量**
```bash
cp .env.example .env
```
编辑 `.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. 启动服务**
```bash
docker compose up -d
```
**4. 注册 Mini App**
在 [@BotFather](https://t.me/BotFather) 发送 `/newapp`,将 Web App URL 指向 `https://your-domain.com`,用户即可从消息中直接打开抽奖管理界面。
**5. 使用机器人**
在 Telegram 中向你的机器人发送 `/start`,即可打开 Mini App。
> [!TIP]
> 生产部署时建议设置 `WEBHOOK_URL` 为公网 HTTPS 地址。不设置则退回长轮询模式,适合开发但生产效率较低。
**更新到新版本**
```bash
docker compose pull
docker compose up -d
```
<div align="right">
[![][back-to-top]](#readme-top)
</div>
## 🤖 Bot 配置
将 Bot 添加到群组或频道后,需要在 [@BotFather](https://t.me/BotFather) 中进行以下配置:
**关闭隐私模式**`/setprivacy` - Disabled
使用口令验证时必须关闭。Telegram Bot 默认只接收以 `/` 开头的消息,关闭隐私模式后 Bot 才能读取群组中的所有消息,从而识别用户发送的口令。
**授予管理员权限以识别匿名管理员**
如果群组中存在匿名管理员(开启了"隐藏管理员身份"的成员),Telegram 不会通过标准 `getChatMember` API 暴露其用户 ID。将 Bot 设为群组管理员后,Bot 才能在验证成员资格时识别匿名管理员。
> [!NOTE]
> 以上设置仅对使用了成员资格验证或口令验证的群组有效,频道或无参与要求的公开抽奖不需要这些配置。
<div align="right">
[![][back-to-top]](#readme-top)
</div>
## 📡 Bot 命令
| 命令 | 说明 |
|---|---|
| `/start` | 打开抽奖管理 Mini App |
| `/newlottery` | 创建新抽奖(直接跳转至 Mini App 创建页) |
| `/mylotteries` | 查看我的抽奖列表 |
| `/help` | 查看帮助与项目信息 |
所有抽奖管理操作(创建、编辑、发布、开奖)均在 Mini App 内完成,Bot 命令是进入对应页面的入口。
<div align="right">
[![][back-to-top]](#readme-top)
</div>
## 💻 本地开发
**前置条件:** Docker 和 Docker Compose
项目内置 `docker-compose.override.yml`,启动时自动生效:
- 后端挂载源码目录,uvicorn 开启 `--reload` 热重载
- 前端运行 Vite 开发服务器,使用文件轮询模式(适配 NAS / 网络文件系统)
- nginx 提供 Vite 构建产物,并将 `/api``/webhook` 反向代理到后端
```bash
cp .env.example .env
# 编辑 .env,填入 BOT_TOKEN、MINI_APP_URLWEBHOOK_URL 留空使用轮询模式
docker compose up --build
```
开发环境通过 `http://localhost`(或你设置的 `PORT`)访问。
保存后端文件后自动热重载,前端热更新由 Vite 处理。
<div align="right">
[![][back-to-top]](#readme-top)
</div>
## ⚙️ 配置说明
所有配置通过环境变量读取(或项目根目录的 `.env` 文件)。
| 变量 | 默认值 | 必填 | 说明 |
|---|---|---|---|
| `BOT_TOKEN` | - | **是** | 从 [@BotFather](https://t.me/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`。
<div align="right">
[![][back-to-top]](#readme-top)
</div>
## 🐳 服务容器
默认 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/`
<div align="right">
[![][back-to-top]](#readme-top)
</div>
## 📁 项目结构
```
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 # 环境变量模板
```
<div align="right">
[![][back-to-top]](#readme-top)
</div>
## 🤝 贡献
欢迎提交 Issue 和 Pull Request。重大变更请先开 Issue 讨论方向。
<div align="right">
[![][back-to-top]](#readme-top)
</div>
## 📝 许可证
Copyright © 2026 [Stardream](https://git.stdm.moe/Stardream)。本项目采用 [GNU Affero General Public License v3.0](./LICENSE) 许可证。
**权利**
| | |
|---|---|
| ✅ | 商业使用 |
| ✅ | 修改 |
| ✅ | 分发 |
| ✅ | 私人使用 |
**条件**
| | |
|---|---|
| ⚠️ | 公开源码 - 修改后的版本也必须开源 |
| ⚠️ | 相同许可证 - 衍生作品必须使用 AGPL-3.0 |
| ⚠️ | 网络使用 = 分发 - 若将修改版本作为网络服务运行,必须向用户提供源码 |
| ⚠️ | 标注修改 - 修改内容必须记录在案 |
简而言之:你可以自由使用、修改和自托管 TGLotteryBot。若将修改版本作为托管服务分发或提供,必须以 AGPL-3.0 发布完整源码。
---
<!-- LINK GROUP -->
[back-to-top]: https://img.shields.io/badge/-BACK_TO_TOP-black?style=flat-square
[license-shield]: https://img.shields.io/badge/license-AGPL--3.0-white?labelColor=black&style=flat-square
[license-link]: ./LICENSE
[python-shield]: https://img.shields.io/badge/python-3.12-blue?labelColor=black&logo=python&logoColor=white&style=flat-square
[python-link]: https://www.python.org/
[docker-shield]: https://img.shields.io/badge/docker-compose-2496ED?labelColor=black&logo=docker&logoColor=white&style=flat-square
[docker-link]: https://docs.docker.com/compose/
[postgres-shield]: https://img.shields.io/badge/postgres-16-336791?labelColor=black&logo=postgresql&logoColor=white&style=flat-square
[postgres-link]: https://www.postgresql.org/