447 lines
17 KiB
Markdown
447 lines
17 KiB
Markdown
# NOCR - Система мониторинга Telegram-каналов
|
||
|
||
[](https://drone.musk.fun/nocr/flea)
|
||
|
||
Микросервисная система на базе Telegram Bot для мониторинга и уведомлений о текстовых совпадениях в открытых каналах и чатах.
|
||
|
||
## 📋 Обзор проекта
|
||
|
||
Это родительский проект, содержащий все сервисы как **git submodules**. Каждый сервис является отдельным репозиторием, что обеспечивает независимую разработку и версионирование.
|
||
|
||
### Архитектура сервисов
|
||
|
||
Система состоит из 4 основных микросервисов, взаимодействующих через RabbitMQ:
|
||
|
||
#### 1. [telegram-listener](https://gitea.musk.fun/nocr/telegram-listener)
|
||
**Назначение:** Сканирование открытых Telegram-каналов и чатов
|
||
- Подписка на каналы через Telegram MTProto API
|
||
- Публикация событий о новых и отредактированных сообщениях в message bus
|
||
- Хранение сессий пользователей
|
||
|
||
#### 2. [text-matcher](https://gitea.musk.fun/nocr/text-matcher)
|
||
**Назначение:** Сопоставление сообщений с пользовательскими подписками
|
||
- Обработка событий от telegram-listener
|
||
- Проверка совпадений по регулярным выражениям и ключевым словам
|
||
- Хранение истории совпадений в БД (MariaDB)
|
||
- Публикация событий о найденных совпадениях
|
||
|
||
#### 3. [telegram-client](https://gitea.musk.fun/nocr/telegram-client)
|
||
**Назначение:** Клиентский интерфейс бота для взаимодействия с пользователями
|
||
- Прием команд от пользователей через Telegram Bot API
|
||
- Управление подписками на каналы
|
||
- Отправка уведомлений о найденных совпадениях
|
||
- Интеграция с users и text-matcher через REST API
|
||
|
||
#### 4. [users](https://gitea.musk.fun/nocr/users)
|
||
**Назначение:** Управление пользователями и их настройками
|
||
- CRUD операции для пользователей
|
||
- Хранение предпочтений и подписок
|
||
- REST API для других сервисов
|
||
|
||
---
|
||
|
||
## 🚀 Быстрый старт
|
||
|
||
### Вариант 1: Docker Compose (рекомендуется)
|
||
|
||
```bash
|
||
# 1. Создайте файл с секретами
|
||
cp .nocr.env.example .nocr.env
|
||
|
||
# 2. Заполните ваши Telegram API ключи в .nocr.env
|
||
# - API ID и Hash: https://my.telegram.org/apps
|
||
# - Bot Token: @BotFather в Telegram
|
||
|
||
# 3. Запустите все сервисы
|
||
docker-compose up
|
||
```
|
||
|
||
**Проверка работоспособности:**
|
||
- Telegram Listener: http://localhost:5040/health
|
||
- Text Matcher: http://localhost:5041/health
|
||
- Users: http://localhost:5042/health
|
||
- Telegram Client: http://localhost:5050/health
|
||
- RabbitMQ UI: http://localhost:15672 (admin/admin)
|
||
|
||
### Вариант 2: Локальная разработка (VS Code)
|
||
|
||
```bash
|
||
# 1. Запустите инфраструктуру (RabbitMQ + базы данных)
|
||
docker-compose up nocr-rabbitmq nocr-text-matcher-db nocr-users-db -d
|
||
|
||
# 2. Создайте конфигурационные файлы для каждого сервиса
|
||
cd telegram-listener/src/Nocr.TelegramListener.Host
|
||
cp appsettings.Development.json.example appsettings.Development.json
|
||
# Повторите для всех сервисов
|
||
|
||
# 3. Заполните ваши секреты в appsettings.Development.json
|
||
|
||
# 4. Запустите сервисы через VS Code (F5)
|
||
```
|
||
|
||
**📖 Подробная документация:** См. [CONFIGURATION.md](CONFIGURATION.md)
|
||
|
||
---
|
||
|
||
## 🏗️ Архитектура взаимодействия
|
||
|
||
```
|
||
┌──────────────────┐ ┌───────────────┐ ┌──────────────────┐
|
||
│ Telegram Channel │────────▶│ Listener │────────▶│ Text Matcher │
|
||
│ (MTProto API) │ │ (Scan msgs) │ │ (Match rules) │
|
||
└──────────────────┘ └───────┬───────┘ └────────┬─────────┘
|
||
│ │
|
||
│ │
|
||
│ RabbitMQ │
|
||
│ Message Bus │
|
||
│ │
|
||
▼ ▼
|
||
┌───────────────┐ ┌──────────────────┐
|
||
│ Event Topics │ │ Telegram Bot │
|
||
│ & Queues │◀────────│ Client │
|
||
└───────────────┘ │ (Notifications) │
|
||
└──────────────────┘
|
||
│
|
||
▼
|
||
┌──────────────────┐
|
||
│ Users Service │
|
||
│ (User Management)│
|
||
└──────────────────┘
|
||
```
|
||
|
||
**Паттерн взаимодействия:**
|
||
- **Event-driven**: Асинхронная обработка через RabbitMQ
|
||
- **REST API**: Синхронные запросы между telegram-client и другими сервисами
|
||
- **Clean Architecture**: Разделение на слои Host/AppServices/Core/Persistence
|
||
|
||
**📖 Подробная диаграмма:** См. [architecture.md](architecture.md)
|
||
|
||
---
|
||
|
||
## 🔧 Технологический стек
|
||
|
||
- **.NET 8** - Фреймворк для всех сервисов
|
||
- **ASP.NET Core** - Web API
|
||
- **Entity Framework Core** - ORM для MariaDB
|
||
- **WTelegramClient** - MTProto API для telegram-listener
|
||
- **Telegram.Bot** - Bot API для telegram-client
|
||
- **Rebus** - Message bus поверх RabbitMQ
|
||
- **MariaDB** - Базы данных для text-matcher и users
|
||
- **RabbitMQ** - Брокер сообщений
|
||
- **Docker & Docker Compose** - Контейнеризация
|
||
- **Drone CI** - CI/CD на Kubernetes
|
||
|
||
---
|
||
|
||
## 📦 CI/CD Pipeline
|
||
|
||
Проект использует **Drone CI** с 5 специализированными пайплайнами:
|
||
|
||
### 1. 🧪 Feature Validation
|
||
**Триггер:** Push в ветки `feature/*`, `fix/*`, `issues/*`
|
||
**Длительность:** ~3-5 минут
|
||
- Сборка всех сервисов
|
||
- Запуск тестов с Testcontainers
|
||
- Быстрая обратная связь перед PR
|
||
|
||
### 2. ✅ Main Validation
|
||
**Триггер:** Push в ветку `main`
|
||
**Длительность:** ~3-5 минут
|
||
- Валидация после мерджа в main
|
||
- Гарантия стабильности основной ветки
|
||
|
||
### 3. 📝 Contracts-Only Publish
|
||
**Триггер:** Tag с сообщением `contracts_only:<service>`
|
||
**Длительность:** ~2 минуты
|
||
- Публикация NuGet-пакетов контрактов
|
||
- Без сборки Docker-образов
|
||
```bash
|
||
git commit -m "contracts_only:telegram_listener - Add MessageEdited event"
|
||
git tag v1.2.4-contracts && git push origin v1.2.4-contracts
|
||
```
|
||
|
||
### 4. 🚀 Full Release
|
||
**Триггер:** Tag без специальных маркеров
|
||
**Длительность:** ~8-10 минут
|
||
1. Публикация всех контрактов (параллельно)
|
||
2. Сборка Docker-образов с Kaniko (параллельно)
|
||
3. Деплой в Kubernetes (для тегов `v*`)
|
||
```bash
|
||
git tag v1.3.0 && git push origin v1.3.0
|
||
```
|
||
|
||
### 5. ⚡ Deploy-Only
|
||
**Триггер:** Tag с сообщением `deploy_only:`
|
||
**Длительность:** ~1 минута
|
||
- Деплой существующих образов без пересборки
|
||
- Откат к предыдущей версии
|
||
```bash
|
||
git commit --allow-empty -m "deploy_only: Rollback to v1.2.9"
|
||
git tag v1.2.9-deploy && git push origin v1.2.9-deploy
|
||
```
|
||
|
||
**📖 Полная документация CI/CD:** См. [_deploy/README.md](_deploy/README.md)
|
||
|
||
---
|
||
|
||
## 🛠️ Команды разработки
|
||
|
||
### Сборка
|
||
|
||
```bash
|
||
# Сборка конкретного сервиса
|
||
cd telegram-listener && dotnet build
|
||
|
||
# Сборка всех сервисов
|
||
dotnet build telegram-listener/Nocr.TelegramListener.sln
|
||
dotnet build telegram-client/Nocr.TelegramClient.sln
|
||
dotnet build text-matcher/Nocr.TextMatcher.sln
|
||
dotnet build users/Nocr.Users.sln
|
||
```
|
||
|
||
### Тестирование
|
||
|
||
```bash
|
||
# Запуск тестов (text-matcher)
|
||
cd text-matcher && dotnet test
|
||
```
|
||
|
||
### Миграции БД
|
||
|
||
```bash
|
||
# Добавить новую миграцию
|
||
cd text-matcher
|
||
./src/Nocr.TextMatcher.Migrator/AddMigration.sh MyMigrationName
|
||
|
||
cd users
|
||
./src/Nocr.Users.Migrator/AddMigration.sh MyMigrationName
|
||
|
||
# Применение миграций автоматически при запуске через docker-compose
|
||
```
|
||
|
||
### Работа с субмодулями
|
||
|
||
```bash
|
||
# Инициализация субмодулей после клонирования
|
||
git submodule update --init --recursive
|
||
|
||
# Обновление всех субмодулей до последних коммитов
|
||
git submodule update --remote --merge
|
||
|
||
# Автокоммит изменений в субмодулях (скрипт)
|
||
./commit-submodules.sh "Update submodules"
|
||
```
|
||
|
||
---
|
||
|
||
## 📊 Порты сервисов
|
||
|
||
При запуске через Docker Compose:
|
||
|
||
| Сервис | Порт | Health Check |
|
||
|--------|------|--------------|
|
||
| telegram-listener | 5040 | http://localhost:5040/health |
|
||
| text-matcher | 5041 | http://localhost:5041/health |
|
||
| users | 5042 | http://localhost:5042/health |
|
||
| telegram-client | 5050 | http://localhost:5050/health |
|
||
| RabbitMQ AMQP | 5672 | - |
|
||
| RabbitMQ Management | 15672 | http://localhost:15672 |
|
||
| MariaDB (text-matcher) | 3316 | - |
|
||
| MariaDB (users) | 3326 | - |
|
||
|
||
---
|
||
|
||
## 🔐 Конфигурация
|
||
|
||
### Приоритет источников конфигурации
|
||
|
||
1. **appsettings.json** (базовые настройки)
|
||
2. **appsettings.{Environment}.json** (Development/DockerCompose/Production)
|
||
3. **User Secrets** (только для Development)
|
||
4. **Environment Variables** ⬆️ **НАИВЫСШИЙ ПРИОРИТЕТ**
|
||
|
||
### Важные правила
|
||
|
||
- ❌ **Никогда не коммитьте секреты** в git
|
||
- ✅ Используйте файлы `.example` как шаблоны
|
||
- ✅ Environment Variables переопределяют все остальное
|
||
- ✅ Docker Compose использует `.nocr.env` (gitignored)
|
||
- ✅ Kubernetes использует Secrets
|
||
|
||
### Режим отладки
|
||
|
||
Для вывода маскированных значений конфигурации:
|
||
```bash
|
||
export NOCR_DEBUG_MODE=true
|
||
```
|
||
|
||
**📖 Полное руководство:** См. [CONFIGURATION.md](CONFIGURATION.md)
|
||
|
||
---
|
||
|
||
## 📚 Документация
|
||
|
||
- [CONFIGURATION.md](CONFIGURATION.md) - Подробное руководство по конфигурации
|
||
- [_deploy/README.md](_deploy/README.md) - CI/CD пайплайны и деплой
|
||
- [architecture.md](architecture.md) - Архитектурная диаграмма
|
||
- [CLAUDE.md](CLAUDE.md) - Инструкции для Claude Code AI
|
||
|
||
### Документация сервисов
|
||
|
||
- [telegram-listener/README.md](telegram-listener/README.md)
|
||
- [telegram-client/README.md](telegram-client/README.md)
|
||
- [text-matcher/README.md](text-matcher/README.md)
|
||
- [users/README.md](users/README.md)
|
||
|
||
---
|
||
|
||
## 🤝 Рабочий процесс разработки
|
||
|
||
### Создание новой функции
|
||
|
||
```bash
|
||
# 1. Создайте feature-ветку
|
||
git checkout -b feature/add-filter
|
||
|
||
# 2. Работайте в субмодуле
|
||
cd telegram-listener
|
||
git checkout -b feature/add-filter
|
||
# Внесите изменения...
|
||
git commit -m "Add new filter"
|
||
git push origin feature/add-filter
|
||
|
||
# 3. Обновите родительский проект
|
||
cd ..
|
||
git add telegram-listener
|
||
git commit -m "Update telegram-listener: Add new filter"
|
||
git push origin feature/add-filter
|
||
|
||
# 4. Создайте PR и дождитесь прохождения CI
|
||
```
|
||
|
||
### Релиз новой версии
|
||
|
||
```bash
|
||
# 1. Убедитесь, что все изменения в main
|
||
git checkout main && git pull
|
||
|
||
# 2. Создайте тег
|
||
git tag v1.4.0 -m "Release v1.4.0: New features"
|
||
git push origin v1.4.0
|
||
|
||
# 3. Drone автоматически:
|
||
# - Опубликует NuGet-пакеты
|
||
# - Соберет Docker-образы
|
||
# - Задеплоит в Kubernetes (для v* тегов)
|
||
```
|
||
|
||
---
|
||
|
||
## 🐛 Troubleshooting
|
||
|
||
### Сервис не подключается к RabbitMQ
|
||
|
||
```bash
|
||
# 1. Проверьте, что RabbitMQ запущен
|
||
docker-compose ps nocr-rabbitmq
|
||
|
||
# 2. Включите режим отладки
|
||
export NOCR_DEBUG_MODE=true
|
||
|
||
# 3. Проверьте ConnectionString в логах
|
||
# Для Docker: должно быть nocr-rabbitmq:5672, НЕ localhost:5672
|
||
```
|
||
|
||
### Ошибка подключения к базе данных
|
||
|
||
```bash
|
||
# 1. Проверьте статус БД
|
||
docker-compose ps nocr-text-matcher-db
|
||
|
||
# 2. Подождите прохождения healthcheck (10-30 сек при первом запуске)
|
||
|
||
# 3. Проверьте порт в connection string:
|
||
# - Docker: nocr-text-matcher-db:3306
|
||
# - Local: localhost:3316
|
||
```
|
||
|
||
### Pipeline падает на тестах
|
||
|
||
```bash
|
||
# 1. Проверьте, что Testcontainers может подключиться к Docker
|
||
# В pipeline должна быть переменная DOCKER_HOST
|
||
|
||
# 2. Запустите тесты локально
|
||
cd text-matcher
|
||
dotnet test
|
||
|
||
# 3. Проверьте логи в Drone UI
|
||
```
|
||
|
||
---
|
||
|
||
## 📈 Мониторинг
|
||
|
||
### Проверка здоровья сервисов
|
||
|
||
```bash
|
||
# Локально
|
||
curl http://localhost:5040/health # telegram-listener
|
||
curl http://localhost:5041/health # text-matcher
|
||
curl http://localhost:5042/health # users
|
||
curl http://localhost:5050/health # telegram-client
|
||
|
||
# В Kubernetes (из deploy pod)
|
||
cd _deploy/scripts
|
||
./health-check.sh
|
||
```
|
||
|
||
### Просмотр логов
|
||
|
||
```bash
|
||
# Docker Compose
|
||
docker-compose logs -f telegram-listener
|
||
docker-compose logs -f text-matcher
|
||
|
||
# Kubernetes
|
||
kubectl logs -f deployment/telegram-listener -n nocr
|
||
kubectl logs -f deployment/text-matcher -n nocr
|
||
```
|
||
|
||
---
|
||
|
||
## 📝 История изменений (15-16 октября 2025)
|
||
|
||
### Основные улучшения
|
||
|
||
- ✨ **Новый CI/CD**: 5 специализированных пайплайнов Drone
|
||
- 🔧 **Исправления .drone.yml**: Корректная обработка YAML с многострочными командами
|
||
- 📦 **Contracts-only пайплайн**: Быстрая публикация контрактов без пересборки образов
|
||
- 🚀 **Deploy-only пайплайн**: Быстрый откат и деплой существующих образов
|
||
- 🔄 **MessageEdited события**: Отдельная обработка отредактированных сообщений
|
||
- 📝 **Автокоммит субмодулей**: Скрипт для упрощения работы с субмодулями
|
||
- ⚡ **Оптимизации**: Shared NuGet cache, параллельная сборка, Kaniko caching
|
||
|
||
### Исправленные проблемы
|
||
|
||
- 🐛 Исправлен парсинг YAML в `.drone.yml` (строка 126)
|
||
- 🐛 Корректная обработка `${DRONE_COMMIT_SHA:0:7}` в командах
|
||
- 🐛 Правильные отступы в многострочных bash-скриптах
|
||
- 🐛 Зависимости между этапами pipeline
|
||
|
||
---
|
||
|
||
## 📄 Лицензия
|
||
|
||
[Укажите лицензию вашего проекта]
|
||
|
||
## 👥 Авторы
|
||
|
||
[Укажите авторов проекта]
|
||
|
||
---
|
||
|
||
**Дополнительные ссылки:**
|
||
- [Drone CI](https://drone.musk.fun/nocr/flea)
|
||
- [Gitea Repository](https://gitea.musk.fun/nocr/flea)
|