initial commit
Some checks failed
CI / Run tests (push) Has been cancelled
CI / Docker build test (push) Has been cancelled
CI / Lint (ruff + mypy) (push) Has been cancelled

This commit is contained in:
2026-03-30 16:46:26 +07:00
commit 2a7dfa95c8
67 changed files with 5864 additions and 0 deletions

277
README.md Normal file
View File

@@ -0,0 +1,277 @@
# GlitchUp Bot
Telegram-бот для GlitchTip, который:
- принимает webhook-алерты и отправляет их в Telegram;
- фильтрует окружения, делает dedup, mute по regex и мягкий rate limit;
- синхронизирует unresolved issues из GlitchTip API в локальный cache;
- строит digest, release summary и проектные сводки;
- поддерживает runtime-настройку ownership без рестарта через Telegram-команды;
- запускается локально через `uv` и в Docker через `docker compose`.
## Что сделано
В проекте уже реализовано:
- `POST /webhooks/glitchtip` для Slack-compatible payload из GlitchTip;
- Telegram polling с командами для просмотра сводок, релизов, sync-статуса и runtime-настроек;
- регулярный API sync в `issues_cache`;
- обновление `sync_state` для `api_sync` и `webhook`;
- release tracking через digest и команды `/releases`, `/release`;
- mute rules по regex с хранением в БД;
- rate limit для `P2`-алертов, при этом `P1` не режется;
- ownership overrides для project/topic/subscribers без рестарта;
- PostgreSQL + Alembic миграции;
- Docker-first запуск с авто-`alembic upgrade head`.
## Быстрый старт
### 1. Подготовить `.env`
Скопировать шаблон:
```bash
cp .env.example .env
```
Заполнить минимум:
```env
TELEGRAM_BOT_TOKEN=your-bot-token
TELEGRAM_GROUP_CHAT_ID=-1001234567890
GLITCHTIP_URL=https://glitchtip.example.com
GLITCHTIP_API_TOKEN=your-token
GLITCHTIP_ORG_SLUG=your-org
DATABASE_URL=postgresql+asyncpg://glitchup:glitchup@db:5432/glitchup
```
Если хочешь ограничить админ-команды, укажи:
```env
TELEGRAM_ADMIN_IDS=123456789,987654321
```
Если список пустой, команды изменения конфигурации будут доступны всем.
### 2. Локальный запуск через `uv`
```bash
uv sync --dev
uv run alembic upgrade head
uv run glitchup-bot
```
Полезные команды разработки:
```bash
uv run pytest
uv run ruff check
uv run ruff format --check
uv run python -m glitchup_bot
```
### 3. Запуск через Docker
```bash
docker compose up --build
```
Что произойдёт:
- поднимется PostgreSQL;
- контейнер приложения выполнит `alembic upgrade head`;
- затем стартуют FastAPI, Telegram polling и scheduler.
Webhook endpoint:
```text
http://<host>:8080/webhooks/glitchtip
```
Healthcheck:
```text
http://<host>:8080/health
```
## Как пользоваться ботом
### Главное изменение интерфейса
Теперь ботом можно пользоваться не только командами, но и через inline-кнопки в Telegram:
- `/help` открывает экран поддержки и быстрых действий;
- `/admin` открывает админ-панель с основными управляющими действиями;
- для частых сценариев больше не нужно помнить все команды вручную.
### Обычный сценарий
1. Добавить бота в Telegram-группу.
2. Включить forum/topics режим в группе.
3. Создать топики:
backend alerts, frontend alerts, digest.
4. Узнать их `topic_id` и записать в `.env`.
5. Добавить webhook в GlitchTip на `POST /webhooks/glitchtip`.
6. При необходимости задать `WEBHOOK_SECRET` и тот же заголовок в GlitchTip.
7. После запуска бот начнёт:
- слать `P1/P2` алерты в Telegram;
- синхронизировать issues из API;
- строить digest и отвечать на команды.
8. Открой `/help`, чтобы пользоваться ботом через кнопки.
### Что делает бот в работе
- `P1`:
критичный production alert, отправляется сразу.
- `P2`:
production alert без критического цвета, отправляется сразу, но может быть ограничен rate limit.
- `P3`:
не шлётся realtime, остаётся в sync/digest-данных.
- Uptime alert:
идёт как `P1`.
### Основные команды
- `/help` — экран помощи, поддержки и быстрых кнопок.
- `/week` — digest за неделю.
- `/today` — новые issues за сегодня.
- `/project <slug>` — сводка по одному проекту.
- `/top` — самые шумные unresolved issues.
- `/stale` — самые старые unresolved issues.
- `/releases` — список релизов с незакрытыми issues.
- `/release <version>` — детали по конкретному релизу.
- `/sync_status` — время последней синхронизации.
- `/subscribe <backend|frontend>` — добавить себе runtime DM-подписку.
- `/unsubscribe <backend|frontend>` — убрать свою runtime DM-подписку.
### Админ-команды
- `/admin` — кнопочная админ-панель.
- `/sync` — принудительный sync cache.
- `/ownership` — показать текущие overrides.
- `/owner <slug> <backend|frontend>` — привязать проект к группе.
- `/owner_reset <slug>` — удалить runtime override проекта.
- `/topic <backend|frontend|digest> <topic_id>` — переопределить topic.
- `/topic_reset <backend|frontend|digest>` — снять topic override.
- `/mute_add <regex>` — добавить regex mute rule.
- `/mute_list` — показать mute rules.
- `/mute_del <id>` — удалить mute rule.
## Конфигурация
Основные переменные окружения:
```env
TELEGRAM_BOT_TOKEN=your-bot-token-here
TELEGRAM_GROUP_CHAT_ID=-1001234567890
TELEGRAM_ADMIN_IDS=123456789
TELEGRAM_BACKEND_TOPIC_ID=1
TELEGRAM_FRONTEND_TOPIC_ID=2
TELEGRAM_DIGEST_TOPIC_ID=3
BACKEND_PROJECTS=backend-production,backend-staging
FRONTEND_PROJECTS=frontend-production,frontend-staging
BACKEND_SUBSCRIBERS=123456789,987654321
FRONTEND_SUBSCRIBERS=
GLITCHTIP_URL=https://glitchtip.example.com
GLITCHTIP_API_TOKEN=your-token
GLITCHTIP_ORG_SLUG=your-org
DATABASE_URL=postgresql+asyncpg://glitchup:glitchup@db:5432/glitchup
API_PORT=8080
WEBHOOK_SECRET=
DIGEST_CRON_DAY=mon
DIGEST_CRON_HOUR=10
DIGEST_CRON_MINUTE=0
DIGEST_TIMEZONE=Asia/Krasnoyarsk
SYNC_INTERVAL_MINUTES=30
ALERT_ENVIRONMENTS=production
DEDUP_WINDOW_HOURS=6
ALERT_RATE_LIMIT_COUNT=10
ALERT_RATE_LIMIT_WINDOW_MINUTES=15
```
## Как это работает
### Webhook-контур
Для обычных issue-alert:
1. проверяется `X-Webhook-Secret`, если задан `WEBHOOK_SECRET`;
2. из attachment извлекается `Project`;
3. алерт фильтруется по `ALERT_ENVIRONMENTS`;
4. применяется dedup по fingerprint `project:title`;
5. `production + #e52b50` считается `P1`, остальное в production идёт как `P2`;
6. перед отправкой применяются mute rules;
7. для `P2` применяется rate limit по группе;
8. результат записывается в `notifications_sent`.
Для uptime-alert:
- сразу отправляется как `P1`;
- идёт в Telegram без обычного issue dedup.
### API sync
Sync:
- ходит в GlitchTip по всем проектам из конфигурации;
- upsert-ит unresolved issues в `issues_cache`;
- помечает пропавшие из unresolved issues как `resolved`;
- сохраняет release, regressions, event count, culprit и ссылки;
- обновляет `sync_state` для `api_sync`.
### Release tracking
- digest показывает блок "После релизов";
- `/releases` агрегирует issues по release;
- `/release <version>` показывает детали по одному релизу.
## Таблицы
Основные:
- `issues_cache` — кэш unresolved/resolved issues из API;
- `notifications_sent` — история alert/digest/uptime и статусы отправки;
- `sync_state` — состояние `api_sync` и `webhook`.
Runtime-настройки:
- `project_ownership_overrides` — project → group overrides;
- `group_topic_overrides` — topic overrides;
- `group_subscriber_overrides` — runtime subscriber overrides;
- `mute_rules` — regex mute rules.
## Тесты
```bash
uv run pytest
```
Покрыты базовые сценарии для:
- настроек;
- webhook endpoint;
- alert processor;
- digest builder;
- Telegram sender.
## Идеи и недоделки
Сейчас бот уже рабочий, но в этот блок вынесены идеи для следующих итераций:
- полноценный wizard-интерфейс в Telegram для изменения параметров без ручного ввода команд;
- отдельные команды для управления env-based подписчиками, а не только runtime overrides;
- более умный rate limit с burst/recovery-политикой и отдельной статистикой suppress-событий;
- mute rules с scope по проекту или группе, а не только глобальные regex;
- richer release analytics: сравнение "до/после релиза", отдельные regression-отчёты;
- отдельная admin-аутентификация вместо режима "если `TELEGRAM_ADMIN_IDS` пустой, можно всем";
- export/backup runtime-настроек ownership и mute rules;
- e2e-тесты с реальной БД и контейнерным прогоном;
- дополнительные команды для ручной диагностики sync и очередей уведомлений.