readme.md
This commit is contained in:
parent
0d6b424e99
commit
7930ead4f1
473
README.md
473
README.md
|
|
@ -1 +1,474 @@
|
|||
# 🦋 Fly-Fly Team Bot
|
||||
|
||||
Telegram-бот для детской игровой программы **«Ловец бабочек»** — образовательная игра с рейтингом, стаями и школой бабочковода для детей 9–12 лет.
|
||||
|
||||
Бот: [@fly_fly_team_bot](https://t.me/fly_fly_team_bot)
|
||||
|
||||
---
|
||||
|
||||
## 📋 Содержание
|
||||
|
||||
- [Описание](#описание)
|
||||
- [Возможности](#возможности)
|
||||
- [Архитектура проекта](#архитектура-проекта)
|
||||
- [Установка](#установка)
|
||||
- [Конфигурация](#конфигурация)
|
||||
- [Запуск](#запуск)
|
||||
- [Как пользоваться ботом](#как-пользоваться-ботом)
|
||||
- [Система очков](#система-очков)
|
||||
- [Школа бабочковода](#школа-бабочковода)
|
||||
- [Стаи](#стаи)
|
||||
- [Реферальная система](#реферальная-система)
|
||||
- [Модерация фото](#модерация-фото)
|
||||
- [Проверка подписки на группу](#проверка-подписки-на-группу)
|
||||
- [База данных](#база-данных)
|
||||
- [Зависимости](#зависимости)
|
||||
- [Структура проекта](#структура-проекта)
|
||||
- [Лицензия](#лицензия)
|
||||
|
||||
---
|
||||
|
||||
## Описание
|
||||
|
||||
**Fly-Fly Team Bot** — это Telegram-бот, который:
|
||||
|
||||
- Проводит детей через **5-урочную «Школу бабочковода»** с образовательными текстами и вопросами
|
||||
- Позволяет создавать **стаи (команды)** и соревноваться в рейтинге
|
||||
- Начисляет **очки** за прохождение школы, приглашение друзей и другие действия
|
||||
- Проверяет **подписку на группу** Telegram перед доступом к функциям
|
||||
- Отправляет **фото на модерацию** администратору для ручного начисления очков
|
||||
|
||||
---
|
||||
|
||||
## Возможности
|
||||
|
||||
| Возможность | Описание |
|
||||
|---|---|
|
||||
| 📚 **Школа бабочковода** | 5 уроков о бабочках с вопросами и объяснениями |
|
||||
| 🦋 **Поймай друга** | Отправка GIF-анимации с реферальной ссылкой |
|
||||
| 🏆 **Рейтинг** | Топ-10 пользователей и рейтинг стай |
|
||||
| 📌 **Стая** | Создание/вступление в стаю, управление участниками |
|
||||
| ⚙️ **Управление стаей** | Переименование, исключение участников, роспуск стаи |
|
||||
| 📊 **Мои очки** | Персональная статистика + топ-10 ловцов |
|
||||
| 🛒 **Бабочкарий** | Ссылка на покупку продукта |
|
||||
| 🔒 **Проверка подписки** | Обязательная подписка на группу для доступа к функциям |
|
||||
| 📸 **Модерация фото** | Фото → модератор → кнопки начисления 5/15 очков |
|
||||
| 🎁 **Реферальный бонус** | +5 очков за каждого приглашённого друга |
|
||||
|
||||
---
|
||||
|
||||
## Архитектура проекта
|
||||
|
||||
```
|
||||
main.py
|
||||
└── src/bot.py # Основная логика бота (telebot)
|
||||
├── database.py # Работа с JSON-базой данных
|
||||
├── school.py # Учебная программа (5 вопросов)
|
||||
├── admin_tools.py# Инструменты администратора
|
||||
└── utils.py # Утилиты (валидаторы, форматирование)
|
||||
└── config/config.py # Конфигурация (токен, очки, ID)
|
||||
└── .env # Секреты (токен бота, ID группы)
|
||||
```
|
||||
|
||||
**Ключевые технологии:**
|
||||
- **pyTelegramBotAPI (telebot)** — библиотека для Telegram Bot API
|
||||
- **JSON-файлы** — хранение данных пользователей
|
||||
- **python-dotenv** — загрузка переменных окружения
|
||||
|
||||
---
|
||||
|
||||
## Установка
|
||||
|
||||
### 1. Клонирование репозитория
|
||||
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd fly-fly-team-bot
|
||||
```
|
||||
|
||||
### 2. Создание виртуального окружения
|
||||
|
||||
```bash
|
||||
python -m venv venv
|
||||
```
|
||||
|
||||
**Windows:**
|
||||
```bash
|
||||
venv\Scripts\activate
|
||||
```
|
||||
|
||||
**Linux/macOS:**
|
||||
```bash
|
||||
source venv/bin/activate
|
||||
```
|
||||
|
||||
### 3. Установка зависимостей
|
||||
|
||||
```bash
|
||||
pip install pyTelegramBotAPI python-dotenv requests
|
||||
```
|
||||
|
||||
### 4. Настройка конфигурации
|
||||
|
||||
```bash
|
||||
# Скопируйте пример конфигурации
|
||||
cp config/.env.example config/.env
|
||||
# Или используйте корневой .env
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Заполните `.env` своими значениями (см. [Конфигурация](#конфигурация)).
|
||||
|
||||
---
|
||||
|
||||
## Конфигурация
|
||||
|
||||
### Переменные окружения (`.env`)
|
||||
|
||||
| Переменная | Описание | Пример |
|
||||
|---|---|---|
|
||||
| `TELEGRAM_BOT_TOKEN` | Токен бота от @BotFather | `123456:ABC-DEF...` |
|
||||
| `ADMIN_ID` | Telegram ID администратора-модератора | `7665285886` |
|
||||
| `REQUIRED_GROUP_CHAT_ID` | ID группы для проверки подписки | `-1002395700013` |
|
||||
| `TELEGRAM_PROXY_URL` | Прокси для Telegram API (опционально) | `socks5://user:pass@host:port` |
|
||||
| `TELEGRAM_CONNECT_TIMEOUT` | Таймаут подключения (сек) | `30` |
|
||||
| `TELEGRAM_READ_TIMEOUT` | Таймаут чтения (сек) | `120` |
|
||||
| `DEBUG` | Режим отладки | `False` |
|
||||
| `LOG_LEVEL` | Уровень логирования | `INFO` |
|
||||
|
||||
### Константы системы (`config/config.py`)
|
||||
|
||||
| Константа | Значение | Описание |
|
||||
|---|---|---|
|
||||
| `POINTS_SCHOOL_COMPLETE` | `10` | Очков за прохождение школы |
|
||||
| `POINTS_REFERRAL_BONUS` | `5` | Очков за приглашённого друга |
|
||||
| `POINTS_BUTTERFLY_ACTIVATION` | `30` | Очков за активацию Бабочкария |
|
||||
| `REQUIRED_GROUP_LINK` | `https://t.me/+2RjGyDueqqAyM2Ey` | Ссылка на группу |
|
||||
|
||||
---
|
||||
|
||||
## Запуск
|
||||
|
||||
### Основной способ
|
||||
|
||||
```bash
|
||||
python main.py
|
||||
```
|
||||
|
||||
### Альтернативный запуск (напрямую из src)
|
||||
|
||||
```bash
|
||||
python -m src.bot
|
||||
```
|
||||
|
||||
### Вывод при запуске
|
||||
|
||||
```
|
||||
🦋 Бот Fly-Fly запущен!
|
||||
🤖 @fly_fly_team_bot
|
||||
Ожидаю сообщений...
|
||||
```
|
||||
|
||||
### Остановка
|
||||
|
||||
`Ctrl+C` в терминале.
|
||||
|
||||
---
|
||||
|
||||
## Как пользоваться ботом
|
||||
|
||||
### Первый запуск
|
||||
|
||||
1. Пользователь отправляет `/start` боту
|
||||
2. Бот создаёт профиль пользователя
|
||||
3. Отправляется приветственное сообщение с требованием подписки на группу
|
||||
4. Пользователь подписывается и отправляет **«Готово»**
|
||||
5. Бот подтверждает участие в конкурсе
|
||||
|
||||
### Главное меню
|
||||
|
||||
| Кнопка | Описание |
|
||||
|---|---|
|
||||
| 📚 Школа бабочковода | Пройти 5 уроков (если не пройдено) |
|
||||
| 🦋 Поймать друга | Отправить реферальную ссылку друзьям |
|
||||
| 📊 Мои очки | Персональная статистика + топ-10 |
|
||||
| 🏆 Рейтинг | Общий топ-10 ловцов |
|
||||
| 📌 Стая | Информация о стае (если участник) |
|
||||
| ⚙️ Управлять стаей | Управление (только капитан) |
|
||||
| 🛒 Купить Бабочкарий | Ссылка на покупку |
|
||||
| ❓ Справка | Правила игры |
|
||||
|
||||
---
|
||||
|
||||
## Система очков
|
||||
|
||||
| Действие | Очки |
|
||||
|---|---|
|
||||
| Прохождение школы | +10 ⭐ |
|
||||
| Приглашение друга | +5 ⭐ |
|
||||
| Фото одобрено модератором | +5 или +15 ⭐ |
|
||||
| Активация Бабочкария | +30 ⭐ |
|
||||
|
||||
Очки суммируются и определяют позицию в рейтинге.
|
||||
|
||||
---
|
||||
|
||||
## Школа бабочковода
|
||||
|
||||
5 уроков о бабочках:
|
||||
|
||||
| Урок | Тема |
|
||||
|---|---|
|
||||
| 1 | Кто такие бабочки? (4 крыла) |
|
||||
| 2 | Что едят бабочки? (хоботок) |
|
||||
| 3 | Жизненный цикл бабочки (4 стадии) |
|
||||
| 4 | Где живут бабочки? |
|
||||
| 5 | Как стать ловцом бабочек? |
|
||||
|
||||
Каждый урок состоит из:
|
||||
- **Обучающего текста** с интересными фактами
|
||||
- **Вопроса** с 4 вариантами ответа
|
||||
- **Объяснения** правильного/неправильного ответа
|
||||
|
||||
После прохождения всех 5 вопросов пользователь получает **+10 очков** и отметку `school_completed`.
|
||||
|
||||
---
|
||||
|
||||
## Стаи
|
||||
|
||||
### Создание стаи
|
||||
|
||||
> ⚠️ Возможность создания стаи отключена в текущей версии. Стаи создаются автоматически при определённых условиях.
|
||||
|
||||
### Вступление в стаю
|
||||
|
||||
Пользователь переходит по реферальной ссылке `/start <team_id>` и автоматически вступает в стаю.
|
||||
|
||||
### Управление стаей (капитан)
|
||||
|
||||
| Действие | Описание |
|
||||
|---|---|
|
||||
| ✏️ Изменить название | Переименовать стаю (до 30 символов) |
|
||||
| 👥 Исключить участника | Удалить участника из стаи |
|
||||
| 📊 Рейтинг участников | Внутренний рейтинг стаи |
|
||||
| 🚫 Разойти стаю | Распустить стаю (все участники выходят) |
|
||||
|
||||
### Выход из стаи (участник)
|
||||
|
||||
Участник может покинуть стаю через меню **«📌 Стая → 🚪 Выйти из стаи»** с подтверждением.
|
||||
|
||||
**Капитан не может покинуть стаю** — только распустить её.
|
||||
|
||||
---
|
||||
|
||||
## Реферальная система
|
||||
|
||||
### Как работает
|
||||
|
||||
1. Пользователь нажимает **«🦋 Поймать друга»**
|
||||
2. Получает GIF + реферальную ссылку вида:
|
||||
```
|
||||
https://t.me/fly_fly_team_bot?start=<telegram_id>
|
||||
```
|
||||
3. Друг переходит по ссылке и регистрируется
|
||||
4. Бот проверяет условия:
|
||||
- Пригласитель существует
|
||||
- Приглашённый ещё не учтён в `invited_friends`
|
||||
- Если задан `REQUIRED_GROUP_CHAT_ID` — приглашённый состоит в группе
|
||||
5. Пригласителю начисляется **+5 очков**
|
||||
|
||||
### Проверка членства в группе
|
||||
|
||||
При реферальном начислении бот проверяет, что приглашённый является участником группы через `bot.get_chat_member()`.
|
||||
|
||||
---
|
||||
|
||||
## Модерация фото
|
||||
|
||||
### Процесс
|
||||
|
||||
1. Пользователь находится в состоянии `awaiting_photo` (ожидание фото)
|
||||
2. Отправляет фото боту
|
||||
3. Бот пересылает фото **администратору** (`ADMIN_ID`) с inline-кнопками:
|
||||
- **«Дать 15 баллов»** — начислить +15 очков
|
||||
- **«Дать 5 баллов»** — начислить +5 очков
|
||||
- **«Отклонить»** — отклонить фото
|
||||
4. Администратор нажимает кнопку
|
||||
5. Бот начисляет очки пользователю и уведомляет обоих
|
||||
|
||||
### Callback-данные кнопок
|
||||
|
||||
| Callback | Действие |
|
||||
|---|---|
|
||||
| `award_15_<user_id>` | Начислить 15 очков |
|
||||
| `award_5_<user_id>` | Начислить 5 очков |
|
||||
| `award_reject_<user_id>` | Отклонить фото |
|
||||
|
||||
---
|
||||
|
||||
## Проверка подписки на группу
|
||||
|
||||
### Механизм
|
||||
|
||||
Бот проверяет подписку пользователя на группу перед каждым действием:
|
||||
|
||||
```python
|
||||
def is_user_subscribed(telegram_id, chat_id) -> bool:
|
||||
if not check_user_in_group(telegram_id):
|
||||
send_subscription_required(chat_id)
|
||||
return False
|
||||
return True
|
||||
```
|
||||
|
||||
### Проверка членства
|
||||
|
||||
```python
|
||||
def check_user_in_group(telegram_id) -> bool:
|
||||
member = bot.get_chat_member(REQUIRED_GROUP_CHAT_ID, telegram_id)
|
||||
return member.status in ['member', 'administrator', 'creator']
|
||||
```
|
||||
|
||||
### Подтверждение подписки
|
||||
|
||||
Пользователь отправляет **«Готово»** — бот повторно проверяет подписку и подтверждает участие.
|
||||
|
||||
---
|
||||
|
||||
## База данных
|
||||
|
||||
### Тип: JSON-файл
|
||||
|
||||
Данные хранятся в `data/users.json` в формате:
|
||||
|
||||
```json
|
||||
{
|
||||
"123456789": {
|
||||
"telegram_id": 123456789,
|
||||
"first_name": "Иван",
|
||||
"username": null,
|
||||
"is_butterfly_owner": false,
|
||||
"school_completed": true,
|
||||
"total_points": 45,
|
||||
"team_id": null,
|
||||
"team_name": null,
|
||||
"created_at": "2025-01-15T10:30:00",
|
||||
"last_activation_date": null,
|
||||
"invited_friends": [],
|
||||
"referred_by": 987654321,
|
||||
"profile_updated": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Класс `Database`
|
||||
|
||||
| Метод | Описание |
|
||||
|---|---|
|
||||
| `get_user(telegram_id)` | Получить пользователя |
|
||||
| `create_user(...)` | Создать пользователя |
|
||||
| `update_user(telegram_id, **kwargs)` | Обновить данные |
|
||||
| `add_points(telegram_id, points)` | Добавить очки |
|
||||
| `get_team_members(team_id)` | Участники стаи |
|
||||
| `get_users_ranking()` | Топ-10 пользователей |
|
||||
| `get_teams_ranking()` | Топ-10 стай |
|
||||
| `create_team(captain_id, team_name)` | Создать стаю |
|
||||
| `get_team(team_id)` | Информация о стае |
|
||||
| `add_member_to_team(team_id, user_id)` | Добавить в стаю |
|
||||
| `remove_member_from_team(team_id, user_id)` | Удалить из стаи |
|
||||
| `update_team_name(team_id, new_name)` | Переименовать стаю |
|
||||
| `disband_team(team_id)` | Распустить стаю |
|
||||
| `mark_school_completed(telegram_id)` | Отметить школу пройденной |
|
||||
|
||||
### Дополнительные файлы
|
||||
|
||||
- `data/points_log.json` — лог начислений очков (валидация повторных начислений)
|
||||
- `data/teams.json` — данные о стаях (через `TeamManager`)
|
||||
|
||||
---
|
||||
|
||||
## Зависимости
|
||||
|
||||
| Пакет | Версия | Описание |
|
||||
|---|---|---|
|
||||
| `pyTelegramBotAPI` | любая | Telegram Bot API клиент |
|
||||
| `python-dotenv` | любая | Загрузка .env файлов |
|
||||
| `requests` | любая | HTTP-запросы (для прокси) |
|
||||
|
||||
---
|
||||
|
||||
## Структура проекта
|
||||
|
||||
```
|
||||
fly-fly-team-bot/
|
||||
├── main.py # Точка входа (запуск bot.infinity_polling())
|
||||
├── README.md # Документация
|
||||
├── bot-cat.mp4 # GIF-анимация для «Поймай друга»
|
||||
├── bot-cat.gif # GIF-анимация (альтернатива)
|
||||
│
|
||||
├── config/
|
||||
│ ├── __init__.py # Экспорт конфигурации
|
||||
│ ├── config.py # Загрузка .env и константы
|
||||
│ ├── .env # Секреты (не коммитить!)
|
||||
│ └── .env.example # Пример конфигурации
|
||||
│
|
||||
├── src/
|
||||
│ ├── __init__.py # Экспорт bot и Database
|
||||
│ ├── bot.py # Основная логика бота (~1140 строк)
|
||||
│ ├── database.py # Класс Database (модель данных, CRUD)
|
||||
│ ├── school.py # SCHOOL_CURRICULUM (5 вопросов)
|
||||
│ ├── admin_tools.py # AdminTools, DebugTools
|
||||
│ └── utils.py # PointsValidator, TeamManager, MessageFormatter
|
||||
│
|
||||
├── data/
|
||||
│ ├── users.json # База пользователей
|
||||
│ └── points_log.json # Лог начислений очков
|
||||
│
|
||||
└── docs/ # Дополнительная документация
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Команды бота
|
||||
|
||||
| Команда | Описание |
|
||||
|---|---|
|
||||
| `/start` | Регистрация / приветствие |
|
||||
| `/start 0` | Регистрация как владелец Бабочкария |
|
||||
| `/start <id>` | Регистрация по реферальной ссылке |
|
||||
|
||||
---
|
||||
|
||||
## Обработчики сообщений
|
||||
|
||||
### Команды
|
||||
- `/start` — регистрация
|
||||
|
||||
### Текстовые кнопки
|
||||
- `📚 Школа бабочковода флай-флай` — начало школы
|
||||
- `🦋 Поймать друга` — реферальная ссылка + GIF
|
||||
- `📊 Мои очки` — статистика
|
||||
- `🏆 Рейтинг` — топ-10
|
||||
- `📌 Стая` — меню стаи
|
||||
- `⚙️ Управлять стаей` — управление (капитан)
|
||||
- `🛒 Купить Бабочкарий` — ссылка на покупку
|
||||
- `❓ Справка` — правила игры
|
||||
- `Готово` — подтверждение подписки
|
||||
|
||||
### Callback-запросы (inline-кнопки)
|
||||
- `answer_<num>_<idx>` — ответ на вопрос школы
|
||||
- `team_members`, `team_stats`, `team_link` — меню стаи
|
||||
- `leave_team`, `leave_confirm`, `leave_cancel` — выход из стаи
|
||||
- `award_15_<id>`, `award_5_<id>`, `award_reject_<id>` — модерация фото
|
||||
- `manage_rename`, `manage_remove`, `manage_rating`, `manage_disband` — управление стаей
|
||||
- `remove_<user_id>` — исключить участника
|
||||
- `disband_confirm` — подтвердить роспуск
|
||||
- `back_menu`, `back_to_main`, `back_to_main_menu` — назад
|
||||
|
||||
### Контент
|
||||
- **Фото** — пересылка модератору (если ожидается фото)
|
||||
|
||||
---
|
||||
|
||||
## Лицензия
|
||||
|
||||
© Fly-Fly Team. Все права защищены.
|
||||
|
|
|
|||
Loading…
Reference in New Issue