mirror of
https://gitverse.ru/kpa39l/email-assistant.git
synced 2026-09-29 09:15:09 +00:00
6.4 KiB
6.4 KiB
Tasks: Потоковая синхронизация почты (IMAP IDLE) и онлайновая копия ящика
Задачи
Фаза 0: Подготовка и проверка авторизации
- 1. Установить/проверить
aioimaplib(pip) — библиотека для IDLE-потока; если не ставится — зафиксировать fallback на сырой socket. (2026-09-15:aioimaplibНЕ установлен; на следующем шаге — решить ставить или идти на сыром socket, т.к. imap_client.py уже это умеет.) - 2. Проверить авторизацию для stream-процесса:
himalaya логинится успешно (эталон), чистый IMAP-скрипт — нет.
Отработать AUTH=PLAIN (SASL-IR), формат login; зафиксировать рабочий
вариант в коде. (Блокер — без него stream не запустится.)
Выполнено 2026-09-15: создан
scripts/imap_client.pyс отдельной функциейimap_connect()(STARTTLS + LOGIN + re-try против rate-limit). Реальная проверка: LOGIN как e.storozhenko прошёл,fetch_attachments_imaplibчерез неё скачалПереместить стол.docx1.1 МБ (UID 14200) без \Seen. Rate-limit Exchange: после серии быстрых попыток сервер молчит (timeout), поэтому вimap_connect()re-try с экспоненциальной паузой. - 2b. Логирование авторизации + метрики доступности/сессии:
imap_log()пишет JSON-строки в/opt/hermes/email/logs/imap_client.log(conn_ok / conn_error / auth_ok / auth_failed / session_started / session_ended);imap_metrics()считает auth_success_rate, conn_error, sessions_active;imap_session— контекстный менеджер (гарантирует session_ended). Проверено:python3 imap_client.py --metricsпоказывает метрики. Пароль никогда не логируется. TODO (позже): полноценный мониторинг — Prometheus-формат/статус-эндпоинт для stream-сервиса, алерты при падении auth_success_rate / conn_error.
Фаза 1: Скелет сервиса imap_stream.py
- 3.
scripts/imap_stream.py: connect + STARTTLS + login; folder list (get_inbox_subfolders); SELECT INBOX; IDLE-цикл с обработкой untagged (EXISTS/EXPUNGE/FETCH FLAGS); reconnect при обрыве. - 4. Реализовать reconcile: UID FETCH новых писем (>last_uid) → событие
added+ архивация (переиспользовать mail_archive.py); сравнение FLAGS →flag_changed; отсутствие после EXPUNGE →deleted(soft). - 5. SQLite schema:
mailbox_state+mailbox_events(ChangeLog) — создать/opt/hermes/email/state/mailbox.db, функции init/insert/read.
Фаза 2: Change Analyzer
- 6.
scripts/change_analyzer.py: чтение mailbox_events от offset; наadded— классификация (email_classifier) + обработчики (email_handlers); наmoved/deleted/flag_changed— обновление mailbox_state, RAG-метка. Уведомления в ЛС Telegram уже проверены живьём (2026-09-15): письмо 3216 помечено urgent → доставка в private chat 281328953 (kpa39l), msg_id=60, подтверждено пользователем. Для ЛС нужен явныйTELEGRAM_CHAT_ID=281328953(дефолт в email_handlers.py — канал @dedinit_vesti). - 7. Обработка
replied: \Answered или новое письмо с In-Reply-To на известный Message-ID → событиеreplied; обновить thread в state.
Фаза 3: systemd и интеграция
- 8. systemd user units (
email-imap-stream.service,email-change-analyzer.service), автозапуск; проверка auto-restart. - 9. Hermes cron
mail-archive-every-5min→ fallback (идемпотентен с stream; не дублирует). Проверить, что при работающем stream cron не архивирует повторно (last_uid / state). - 10. Живой тест: новое письмо (отправить себе/ждущее), перемещение (через IMAP MOVE/клиент), удаление, ответ — всё фиксируется в ChangeLog и mailbox_state; \Seen не ставится (проверка флагов до/после).
Фаза 4: Документация и доводка
- 11. STATUS.md / README / WALKTHROUGH: сервисы, порты (нет новых внешних),
как смотреть ChangeLog (
sqlite3 mailbox.db 'select * from mailbox_events'), как перезапускать. - 12. RAG-интеграция (опционально, Фаза 2 проекта): индексация событий ChangeLog в Qdrant — чтобы агент мог ответить «что случилось с письмом».
Верификация
systemctl --user status email-imap-stream email-change-analyzer— active (running)sqlite3 /opt/hermes/email/state/mailbox.db 'select count(*) from mailbox_state'— растётsqlite3 ... 'select event, count(*) from mailbox_events group by event'— есть added/moved/deleted/flag_changed- Новое письмо в INBOX → архив появляется в течение ~1-2 мин (не 5)
- Перемещение письма в клиенте → в mailbox_state folder обновлён, в ChangeLog
moved - Удаление письма →
deletedв ChangeLog, файл email.md на месте (soft-delete) - Ответ →
repliedилиflag_changed(\Answered) - Флаги непрочитанного письма на IMAP после архивации:
()→()(Seen нет)