- 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
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.
Первый запуск: что важно знать
-
Baseline. При самом первом старте всё, что уже лежит в списках, молча запоминается в течение 90 секунд. Старые письма не придут.
-
Включи уведомления в веб-клиентах (настройки хранятся в аккаунте, можно сделать со своего браузера):
- Outlook: Settings → General → Notifications → Desktop notifications → включить;
- Teams: Settings → Notifications → включить уведомления для чатов, упоминаний и активности.
Без этого бот всё равно работает через карточки списков, просто чуть менее точно.
-
Проверка парсера:
/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и сразу удалит сообщение. Пароль держится только в памяти.