- 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
95 lines
6.9 KiB
Markdown
95 lines
6.9 KiB
Markdown
# 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)
|
||
|
||
```bash
|
||
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
|
||
|
||
```bash
|
||
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 в месяц.
|
||
|
||
## Тест
|
||
|
||
```bash
|
||
CHROMIUM_PATH=/usr/bin/google-chrome python -m tests.test_e2e
|
||
```
|
||
|
||
Тест поднимает поддельные страницы Outlook и Teams и проверяет перехват уведомлений, дедуп, baseline, VIP/MUTE и устойчивость к «тикающему» времени в карточках.
|
||
|
||
## Риски
|
||
|
||
- Автоматизация веб-клиента может противоречить правилам ИТ университета. Худший реалистичный исход: блокировка сессии или вопросы от админов.
|
||
- Пароль, если указан в `.env`, хранится на сервере открытым текстом. Можно его не указывать: бот спросит пароль в Telegram при `/login` и сразу удалит сообщение. Пароль держится только в памяти.
|