Claude da28d0ac1c uni-notify: Outlook + Teams → Telegram с LLM-фильтром
- Playwright держит открытыми веб-версии Outlook и Teams (постоянный профиль, Xvfb)
- watcher.js перехватывает уведомления клиента и изменения карточек в реальном времени
- pipeline: дедуп, baseline, VIP/MUTE, оценка важности через Haiku (OpenRouter)
- aiogram-бот: уведомления, дайджест, вопросы по журналу, /login с 2FA-кодом, ручное управление браузером
- Docker/compose, systemd-юнит, e2e-тест на поддельных страницах

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0194buWJjpDjU52JPX7PjsMs
2026-11-13 14:20:14 +01:00

uni-notify

Читает университетскую почту (Outlook) и Microsoft Teams через их веб-версии и присылает важное в Telegram. Ему можно задавать вопросы вроде «что препод писал про курсач?».

Как это работает

Chromium (Playwright, постоянный профиль, Xvfb)
 ├─ вкладка Outlook ─┐   watcher.js ловит:
 └─ вкладка Teams  ──┤    1) уведомления самого клиента (Notification / showNotification) — мгновенно
                     │    2) изменения карточек в списках писем/чатов (MutationObserver) — страховка
                     ▼
               pipeline: дедуп → baseline → VIP/MUTE → LLM (Haiku через OpenRouter) → уровень 0–3
                     ▼
               Telegram-бот (aiogram): 🔴 срочно / 🟡 важно / дайджест / ответы на вопросы
  • Реалтайм. Веб-клиенты Microsoft сами получают пуши. Бот держит их открытыми и перехватывает уведомления прямо в странице, поэтому задержка составляет секунды. Токены из браузера никуда не выносятся.
  • Сессия. Профиль браузера хранится в data/browser-profile. Вход нужен один раз, дальше клиент сам обновляет токены. Если сессия всё-таки слетит, бот напишет «нужен /login».
  • 2FA. /login заполняет обычную форму входа Microsoft, а 6-значный код спрашивает у тебя в Telegram. Если включено сопоставление чисел, бот присылает число, которое нужно выбрать в Authenticator.
  • Нестандартный SSO университета. Бот пришлёт скриншот. Дальше управляешь браузером через /click X Y, /type, /key Enter, /screen.
  • Хранилище. SQLite с полнотекстовым поиском (data/uni.db). По нему бот отвечает на вопросы.

Установка (Docker)

git clone https://git.azimkin.dev/Azimkin/uni-notify.git && cd uni-notify
cp .env.example .env && nano .env      # токен бота, OWNER_ID, ключ OpenRouter, UNI_EMAIL
docker compose up -d --build
docker compose logs -f

Потом в Telegram: /start, затем /login, затем введи код из приложения.

Нужно примерно 1,5–2 ГБ RAM: Teams в браузере прожорлив. Вкладки перезагружаются раз в RELOAD_HOURS.

Без Docker

sudo apt install -y xvfb
python3 -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt && playwright install --with-deps chromium
xvfb-run -a python -m app.main

systemd-юнит лежит в deploy/uni-notify.service.

Первый запуск: что важно знать

  1. Baseline. При самом первом старте всё, что уже лежит в списках, молча запоминается в течение 90 секунд. Старые письма не придут.

  2. Включи уведомления в веб-клиентах (настройки хранятся в аккаунте, можно сделать со своего браузера):

    • Outlook: Settings → General → Notifications → Desktop notifications → включить;
    • Teams: Settings → Notifications → включить уведомления для чатов, упоминаний и активности.

    Без этого бот всё равно работает через карточки списков, просто чуть менее точно.

  3. Проверка парсера: /debug mail и /debug teams показывают, какие карточки видит бот. Если пусто, у Microsoft поменялась вёрстка: поправь rowSelector в config/selectors.json и перезапусти.

Команды бота

Команда Что делает
любой текст вопрос по журналу событий («какие дедлайны на неделе?»)
/status состояние сессий, статистика за сутки
/recent [N] последние важные события
/digest дайджест неважного прямо сейчас
/login войти заново
/vip слово, /mute слово, /lists всегда срочно / никогда / показать списки
/screen [mail|teams] скриншот вкладки
/use, /click X Y, /type, /key, /goto ручное управление браузером
/reload, /debug перезагрузка вкладки / что видит парсер

Настройка важности

  • config/rules.md: правила на человеческом языке. LLM читает файл при каждой оценке, перезапуск не нужен.
  • .env: VIP, MUTE, NOTIFY_MIN_LEVEL, QUIET_HOURS, DIGEST_TIME.

Уровни: 3 срочно (со звуком даже в тихие часы), 2 важно, 1 в дайджест, 0 игнор. Если LLM недоступна, бот присылает всё подряд: лучше лишнее, чем пропустить.

Стоимость

Haiku через OpenRouter: одна пачка событий занимает примерно 1–2 тыс. токенов. При сотне событий в день выходит порядка $1–3 в месяц.

Тест

CHROMIUM_PATH=/usr/bin/google-chrome python -m tests.test_e2e

Тест поднимает поддельные страницы Outlook и Teams и проверяет перехват уведомлений, дедуп, baseline, VIP/MUTE и устойчивость к «тикающему» времени в карточках.

Риски

  • Автоматизация веб-клиента может противоречить правилам ИТ университета. Худший реалистичный исход: блокировка сессии или вопросы от админов.
  • Пароль, если указан в .env, хранится на сервере открытым текстом. Можно его не указывать: бот спросит пароль в Telegram при /login и сразу удалит сообщение. Пароль держится только в памяти.
Description
No description provided
Readme 60 KiB
Languages
Python 90.9%
JavaScript 8.1%
Dockerfile 1%