Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
186 changes: 186 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
# 🤖 Telegram-бот для проекта [`lab_grader_web`](https://github.com/markpolyak/lab_grader_web)

Этот проект представляет собой Telegram-бота, взаимодействующего с FastAPI-бэкендом. Он автоматизирует процесс регистрации студентов и проверки лабораторных работ через GitHub Classroom и Google Таблицы.

## 📁 Структура проекта

> **Важно:** все файлы из папки `telegram_bot/` должны быть перемещены в **корневую директорию проекта**, а не оставаться внутри вложенной папки.

Проект включает в себя следующие компоненты:

| Файл/директива | Назначение |
|----------------------|-------------------------------------------------------------|
| `main.py` | FastAPI-бэкенд с API для работы с курсами и Google Таблицей |
| `bot2.py` | Telegram-бот на `python-telegram-bot`, взаимодействующий с API |
| `backend.Dockerfile` | Docker-образ для запуска `main.py` |
| `bot.Dockerfile` | Docker-образ для запуска `bot2.py` |
| `docker-compose.yml` | Конфигурация запуска обоих сервисов в Docker |
| `config.py` | Конфигурация токена Telegram-бота (`TOKEN = "..."`) |
| `.env` | Секреты для доступа к GitHub и авторизации |
| `credentials.json` | Доступ к Google Sheets API |
| `users.db` | SQLite-база данных для хранения состояния пользователей |
| `courses/` | Каталог с YAML-файлами курсов |

## 🚀 Быстрый запуск

> Перед запуском убедитесь, что у вас установлен **Docker** и **docker-compose**.

### 1. Клонируйте репозиторий

```bash
git clone ...
cd <путь_к_проекту>
```

### 2. Подготовьте необходимые файлы

- `credentials.json` — JSON-файл с ключом для доступа к Google Sheets API.
- `.env` — переменные окружения (создайте вручную):

```env
GITHUB_TOKEN=ghp_...
ADMIN_LOGIN=...
ADMIN_PASSWORD=...
SECRET_KEY=any-secret-key
```

- `config.py` — должен содержать Telegram-токен:

```python
TOKEN = "ваш_токен_бота"
```

### 3. Переместите файлы из `telegram_bot/` в корень

### 4. Запустите в Docker из корневой папки проекта

```bash
cd <путь_к_проекту>
docker compose up --build
```

---

## 🧠 Архитектура

Проект состоит из двух основных компонентов:

### 🖥️ Бэкенд (`main.py`)

Бэкенд реализован на FastAPI и предоставляет REST API для:

- получения списка курсов и групп;
- регистрации студента по ФИО;
- записи GitHub-ника студента в Google Таблицу;
- получения GitHub-ника из таблицы;
- запуска проверки лабораторной на GitHub через CI;
- обновления таблицы результатами проверки.

#### Используемые технологии:
- **FastAPI** — HTTP-сервер и маршрутизация;
- **gspread** + **Google API** — работа с Google Таблицами;
- **httpx** — асинхронные HTTP-запросы к GitHub API;
- **YAML** — описание курсов в директории `courses/`.

#### Особенности:
- Все проверки CI сравниваются с версией первого коммита (`test_main.py`, `tests/`, `.github/workflows`);
- При успешной проверке в таблице проставляется символ `✓` в нужную ячейку;

### 🤖 Telegram-бот (`bot2.py`)

Бот предоставляет двуязычный интерфейс (русский и английский) с возможностью:

- выбора языка;
- авторизации по номеру группы и ФИО;
- регистрации GitHub-ника;
- синхронизации GitHub-ника из таблицы;
- запуска проверки прохождения тестов с выбором курса и лабораторной работы.

#### Используемые технологии:
- **python-telegram-bot** — реализация логики взаимодействия с пользователем;
- **SQLite (`users.db`)** — хранение авторизационных данных, последнего сообщения и состояния меню;
- **httpx** — вызов API-бэкенда для регистрации, получения списка курсов и проверки лабораторных;
- **ConversationHandler** — пошаговая авторизация, регистрация и взаимодействие через inline-кнопки.

#### Поведение:
- Бот сохраняет последнее состояние (меню и сообщение) и восстанавливает его при следующем запуске;
- Все действия сопровождаются подробными текстовыми подсказками и возможностью отмены;

---

## 👤 Пользовательское руководство

После запуска бота пользователь взаимодействует с ним через команды и inline-кнопки. Всё поведение построено на диалогах и зависит от действий пользователя.

### 🔑 Авторизация

Перед использованием бот запрашивает номер группы и ФИО. Варианты развития:

- ✅ **Группа и ФИО найдены в таблице**
→ бот показывает данные и предлагает подтвердить.
→ после подтверждения авторизация завершается, и пользователь переходит в главное меню.

- ❌ **Группа не найдена среди курсов**
→ бот сообщает об ошибке и предлагает ввести данные заново.

- ❌ **ФИО не найдено в группе**
→ бот сообщает, что студент не найден, и предлагает повторить ввод.

### 📝 Регистрация GitHub-ника

Пункт доступен только после авторизации. Пользователь вводит GitHub-ник, который далее проверяется через GitHub API:

- ✅ **GitHub-пользователь существует** и в таблице есть пустая ячейка
→ бот записывает ник в таблицу и сообщает об успешной регистрации.

- ℹ️ **Такой GitHub-ник уже был указан ранее этим студентом**
→ бот сообщает, что ник уже зарегистрирован, но подтверждение повторно не требуется.

- 🚫 **В таблице уже указан другой GitHub-ник**
→ бот не перезаписывает данные и просит обратиться к преподавателю.

- ❌ **Пользователь не существует на GitHub**
→ бот сообщает об ошибке, регистрация невозможна.

### 🔄 Синхронизация GitHub-ника

Бот получает GitHub-ник из таблицы и сохраняет его в свою локальную базу:

- ✅ **Если GitHub-ник найден**, он сохраняется, и становится доступен для последующих проверок.
- ❌ **Если ник не найден в таблице** или возникла ошибка (например, отсутствует столбец), бот уведомляет об этом.

### 🧪 Проверка выполнения лабораторной

Процесс проверки происходит пошагово:

1. **Определение курса**:
- Если для группы найден один курс → он выбирается автоматически.
- Если найдено несколько курсов → бот предлагает выбрать курс вручную.

2. **Выбор лабораторной**:
- Список формируется на основе таблицы и YAML-описания курса.
- Если список пуст → бот уведомляет об этом.

3. **Запуск проверки**:
- Бот отправляет запрос в API с текущим GitHub-ником.
- Бэкенд анализирует:
- наличие коммитов;
- соответствие `test_main.py`, `tests/`, `.github/workflows/` первому коммиту;
- результат CI на последнем коммите.
- В ответ бот выводит подробный результат, включая статус каждой проверки.

Возможные исходы:

- ✅ **Все проверки CI пройдены** — бот выводит успех и сообщает, что результат записан в таблицу.
- ❌ **Обнаружены изменения в файлах** — бот указывает, что тесты не могут быть засчитаны.
- ❌ **Проблемы с GitHub API или CI** — бот сообщает об ошибке (например, отсутствие проверок или коммитов).

### 🔁 Повторные обращения

- При повторном запуске бота:
- если пользователь уже авторизован, бот восстанавливает последнее состояние меню и сообщения;
- если нет — вновь запрашивает данные.

- Все действия можно выполнять многократно (регистрация, синхронизация, проверка), при этом предыдущие данные сохраняются.

Бот обрабатывает ошибки API, отсутствие данных, проблемы с сетью и корректно завершает диалог, возвращая пользователя к безопасной точке.
14 changes: 14 additions & 0 deletions telegram_bot/backend.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir --upgrade pip \
&& pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
9 changes: 9 additions & 0 deletions telegram_bot/bot.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM python:3.12-slim

WORKDIR /app

COPY . .

RUN pip install --no-cache-dir -r requirements.txt

CMD ["python", "bot2.py"]
Loading