Боты и уведомления
Приём заявок: bug_hunter
Для разработчиков. Состояние на 24.09.2026. Как пользоваться ботом сотрудникам — статья «Как сообщить об ошибке». Подробности и запуск — README Buharestskie/bug_hunter_bot.
Коротко
bug_hunter — приём заявок в разработку: сотрудник заводит ошибку или задачу в мини-приложении Telegram, заявка уходит ответственному за сервис, встаёт в общую очередь и связывается с задачей в YouGile. Разработчик работает в админке, в мини-приложении, в YouGile или через MCP-сервер из Claude Code — статус и переписка синхронизируются.
Где живёт
| Сервер | ulrica (Алматы — оттуда доступен Telegram); каталог и контейнеры — в README |
| Адрес | https://bug-hunter.donula26.ru (nginx на сервере) |
| Бот | @donula_bug_hunter_bot, вебхук Telegram |
| Админка | /admin — вход через Telegram, только ответственные; запасной вход — /start login в боте |
| Мини-приложение | /app — всем, кроме забаненных |
Один процесс FastAPI: вебхук Telegram, API, /mcp, /yougile/webhook и статика. Данные — Postgres, черновики ввода в чате — Redis, вложения — диск /data/media. Фронт собирается на машине разработчика и заливается готовым: Node на сервере нет. Миграции накатываются на старте контейнера.
Заявка: путь и статусы
| Статус | Смысл |
|---|---|
| Новая | ждёт разбора ответственным |
| На согласовании | задача ждёт согласующего; в очереди не стоит |
| В очереди | принята, ждёт исполнителя |
| В работе | кто-то взял |
| Нужны детали | задан вопрос автору; ответ автора возвращает прежний статус |
| Готово | сделано; автор задачи может вернуть в работу один раз за 14 дней |
| Отклонена / Не баг / Дубль / Отклонена при согласовании / Отозвана | закрыта без выполнения |
Куда встаёт новая задача: автор с правом согласования — сразу в очередь; «незнакомый» автор (ни одной разобранной заявки) — в «Новая», решает ответственный; остальные — на согласование, если есть согласующий уровнем выше, иначе в «Новая».
Очередь: срочность (Вне очереди → Срочно → В ближайшее время → Не срочно), затем уровень автора (только у задач), затем дата. У ошибки срочности нет, пока её не назначит ответственный. Объединённые заявки занимают одно место.
Кому уходит новая заявка: ответственным за сервис; если их нет — всем ответственным с пометкой «Ответственный за сервис не назначен». Задачи на согласовании не уведомляют никого — у согласующих только счётчик в приложении.
Переписка двигает статус: не внутреннее сообщение разработчика переводит заявку в «Нужны детали» (даже из «В работе»), ответ автора возвращает её обратно. Внутренние заметки статус не трогают и автору не видны.
Объединение: присоединённые заявки получают статус и задачу YouGile главной, смена статуса и срочности идёт на всю группу, автору — одно уведомление на все его заявки группы.
Каталог сервисов
Каталог — репозитории GitHub организации Buharestskie (сверка раз в час) плюс сервисы, заведённые руками. Новый репозиторий появляется скрытым: админам приходит «В GitHub появились новые репозитории… Задайте им названия, иначе они не будут видны в боте». Пока в админке «Сервисы» ему не дали человеческое имя и не включили видимость, сотрудники его не выберут. Архивные репозитории из бота пропадают сами. Там же назначаются ответственные за сервис — от этого зависит, кому уходят заявки.
YouGile
- Когда заводится задача: у ошибки — кнопкой «Создать задачу» в карточке, через MCP или переносом карточки на нашей доске в связанную колонку; у задачи — автоматически после согласования или «Принять в очередь».
- Содержимое: заголовок «[Сервис] кратко», описание — поля заявки, ссылки на вложения и на карточку; стикеры «Репозиторий» и «Срочность». Исполнитель — кто ведёт заявку, иначе ответственные за сервис, иначе нажавший кнопку. «Создал» в YouGile — всегда владелец API-ключа.
- От нас в YouGile: «Готово» — в завершающую колонку с отметкой выполнения; отказы — туда же без отметки и с комментарием причины; «В работе» — в рабочую колонку.
- Из YouGile к нам: вебхук (
task-moved,task-updated,task-deleted,chat_message-created) и сверка каждые 10 минут. Статус берётся из колонки: у каждой колонки доски в админке задано, какой статус она ставит. Удалили задачу в YouGile — открытые заявки становятся «Отклонена». - Комментарии из YouGile попадают в заявку, только если у автора комментария в «Людях» указан сотрудник YouGile, и только через вебхук — сверка их не догоняет.
- Доска на проде — «Новая доска» проекта «Разработка-2»: Заблокировано · Бэклог · Ожидает информации · В работе · на проверке · Готово.
MCP-сервер
POST https://bug-hunter.donula26.ru/mcp, JSON-RPC, заголовок Authorization: Bearer <MCP_TOKEN>. Действует от имени первичного админа с наименьшим Telegram ID из ADMIN_TELEGRAM_IDS.
| Инструмент | Что делает |
|---|---|
list_bugs, get_bug, get_queue | список, заявка целиком с перепиской и историей, очередь с местами |
set_status | статус группы: уведомления автору, перенос в YouGile |
set_urgency | срочность группы, стикер в YouGile |
route_task | задача «незнакомца»: принять или отправить на согласование |
merge_bugs, unmerge_bug | объединить дубли / отсоединить |
add_note | сообщение в заявку, по умолчанию внутреннее |
create_yougile_task | завести задачу в YouGile |
list_services | каталог сервисов |
MCP ведёт себя не во всём как API: add_note с internal=false не ставит «Нужны детали» и не уходит в YouGile; set_status «В работе» для уже взятой заявки молча ничего не делает (API ответил бы 409).
На что наступают
- Прод отстаёт от
main: на сервере7f7966a, не выкачен837f6c3(сверка с YouGile перестала откатывать статусы). До выкатки сверка может перезаписать «Нужны детали» и отказы статусом колонки. - Ошибки самого бота видны только в логах контейнера приложения. GlitchTip подключён в коде, но
SENTRY_DSNна проде не задан. Заявка, которую некому отправить, тоже только в логе. - «В работе», пришедшее из YouGile, автору не сообщается — только «готово», «отклонено» и сообщения.
- Автор дубля не узнаёт номер исходной заявки из уведомления — только в карточке.
- Сверка каждые 10 минут читает чат каждой карточки доски — сотни запросов к YouGile при общем на компанию лимите частоты.
- Анализатора нет. Блок «Гипотеза (ИИ)» в карточке и переменные
ANALYZER_*— заготовки. Мёртвые такжеYOUGILE_BOARD_NAME,YOUGILE_COLUMN_NAME,YOUGILE_REPO_STICKER_NAME: доска и стикеры берутся из настроек в базе. - Enum в базе хранится именами (
DONE, а неdone) — помнить в миграциях. - Локальный стек и прод делят один домен. Оба ставят вебхук Telegram на
PUBLIC_BASE_URLпри старте — кто стартовал последним, тот и получает обновления. Перед работой с прод-ботом локальныйdocker composeостановить. - Локальная копия боевой базы с включённой связью заводит в YouGile подписки на прод-домен с чужим секретом. Перед локальным запуском выключить связь в настройках или убрать
YOUGILE_API_KEY. - Бэкапов нет.
- Выкатка — с окном обслуживания: сервис на статус-странице как «Сбор багов и задач» (проба
/healthz).
Релей GlitchTip в Telegram
Для разработчиков. Состояние на 24.09.2026. Подробности — README Buharestskie/gitchtip_tg_bot. Отчёт по оплатам для группы ОС описан отдельно — статья «Отчёт по оплатам группы ОС».
Коротко
gitchtip_tg_bot — релей в Telegram. Принимает HTTP-вебхуки и пересылает их в чаты: алерты GlitchTip, обращения «Сообщить о проблеме» из дашбордов и виджетов, отчёт смены менеджера МОС. Сам следит, жив ли GlitchTip, и раз в день собирает отчёт по оплатам группы ОС.
Где живёт
| Сервер | ulrica — с российских площадок api.telegram.org недоступен; каталог, контейнер и адрес — в README |
| Адрес | HTTP без TLS и без reverse proxy, на отдельном порту ulrica |
| Код | доставляется git-бандлом: у ulrica нет доступа к GitHub |
Что куда уходит
Все пути защищены одним токеном в адресе: /hook/<WEBHOOK_TOKEN>. Чужой токен — 401.
| Кто шлёт | Путь | Как бот понимает, что это | Чат |
|---|---|---|---|
| GlitchTip (все проекты) | /hook/… | всё, что не подошло ниже | TELEGRAM_CHAT_ID |
| «Сообщить о проблеме»: МОС, МПП1, МПП2, виджет Яндекс.Диска, return_amo_hook_service | /hook/… (у отправителя — FEEDBACK_WEBHOOK_URL) | в теле есть непустой alias | TELEGRAM_CHAT_ID |
| Отчёт смены из виджета МОС | /mos-workday-report/… (у отправителя — WORKDAY_REPORT_WEBHOOK_URL) | в теле есть объект report | WORKDAY_REPORT_CHAT_ID |
| Ручной запуск отчёта по оплатам | POST /payments-report/… | — | PAYMENTS_REPORT_CHAT_ID |
Тип определяет тело, а не путь: отчёт смены, присланный на /hook/, всё равно уйдёт в чат отчётов.
Из пейлоада GlitchTip читаются только text и attachments[].title / title_link / text. Уровень события не читается — у любого алерта шапка «🔴 GlitchTip».
Подключить новый проект GlitchTip
- В GlitchTip, в настройках проекта, — правило алерта с интеграцией generic webhook.
- Адрес —
…/hook/<WEBHOOK_TOKEN>релея: проще всего скопировать из правила любого уже подключённого проекта; адрес — в README, токен — в.envрелея на сервере. - Как часто алертить, решает правило в GlitchTip: сам релей ничего не фильтрует и не склеивает — один POST, одно сообщение.
Монитор GlitchTip
Раз в 5 минут релей запрашивает GLITCHTIP_HEALTH_URL (таймаут 10 секунд). Пишет только при смене состояния: «🔴 GlitchTip недоступен» с причиной и «🟢 GlitchTip снова доступен». Одного неудачного опроса хватает для алерта; падение и подъём между двумя опросами не заметит.
На что наступают
- Нет очереди и повторов. Если Telegram отказал, отправитель получает
502и должен повторить сам — иначе сообщение потеряно. - Сообщение длиннее 4096 символов Telegram отклонит — тоже
502. Режется на части только отчёт по оплатам. - Сменили
WEBHOOK_TOKEN— поправить адрес в правилах GlitchTip иFEEDBACK_WEBHOOK_URL/WORKDAY_REPORT_WEBHOOK_URLу всех отправителей. - Токен в пути попадает в access-лог.
- Поля
…Secondsв отчёте смены МОС на самом деле минуты — дашборд уже переводит их, а имена полей не меняет. aiohttpне указан вrequirements.txt— работает транзитной зависимостью.- Отчёт по оплатам падает с
KeyErrorмолча — если зарплатный дашборд поменял формат ответа, в чат не придёт ни отчёт, ни сообщение о сбое. - Внешней пробы у релея нет — окно обслуживания при выкатке открыть не на что.