- mail_archive.py: фикс вложений himalaya --dir → --downloads-dir; attachments/ только при has_attachment; идемпотентно - email_classifier.py: Qwen3:8b (Ollama) → теги info/urgent/task/meeting в frontmatter email.md - email_handlers.py: urgent→Telegram (Bot API+SOCKS5), task→Radicale VTODO, meeting→Radicale VEVENT; handled_* идемпотентность; --dry-run - .gitignore: игнор *.env.bak* - openspec: чейндж email-classification-handlers (в работе) - STATUS/TODO/WALKTHROUGH: прогресс сессии, подводные камни Radicale (http.client, Depth:1, формат дат)
5.2 KiB
Proposal: Классификация писем и подключение обработчиков
Why
Сейчас после скачивания письма с IMAP (mail_archive.py) письмо сохраняется как
email.md (YAML-frontmatter + текст) и на этом всё. Пользователь не получает
сигнала о том, что пришло важное письмо: что в письме задача, встреча, срочный
вопрос или просто информация. Каждое письмо нужно вручную открывать и читать.
При этом инфраструктура уже есть:
- Radicale (CalDAV/CardDAV) на
cal.nixg.ru— календари Личный/Рабочий/Задачи - Vikunja (трекер задач) — развёрнут, ждёт администратора
- Ollama с Qwen3:8b — локальная модель (не уходит в облако, приватно)
- Мессенджер — уведомления можно слать в Telegram
Хочется: после скачивания письма локальная модель классифицирует его и помечает тегами (информационное, требует срочного ответа, есть задача, назначена встреча и т.п.), а на основе тегов запускаются обработчики: уведомление в мессенджер, создание задачи в Vikunja, создание события в календаре Radicale.
Параллельно найден баг: вложения сейчас не скачиваются — get_attachments()
вызывает himalaya attachment download --dir, но правильный флаг --downloads-dir,
команда падает (exit 2), ошибка молча глотается except: pass, и папка
attachments/ всегда пустая. Чейндж чинит это: вложения должны попадать в каталог
письма (что логично — каталог письма уже создаётся).
What Changes
- Вложения скачиваются в каталог письма —
mail_archive.pyправит вызовhimalaya attachment download: использует--downloads-dirвместо--dir, кладёт файлы в<msg_dir>/attachments/. Проверяется на письме с вложением. - Классификатор писем — новый скрипт
email_classifier.py, который:- берёт неклассифицированные письма (нет
classificationв frontmatter) - отдаёт текст письма локальной модели Qwen3:8b (Ollama localhost:11434)
- получает JSON с тегами:
info,urgent,task,meeting(и, возможно,question,money,deadline) - пишет результат в frontmatter
email.md: полеclassification(тег) +classification_reason(короткое обоснование)
- берёт неклассифицированные письма (нет
- Обработчики по тегам — новый скрипт
email_handlers.py:urgent→ уведомление в мессенджер (Telegram, через Hermes gateway)task→ создание задачи в Vikunja (API tasks.nixg.ru)meeting→ создание события в Radicale (календарь Рабочий, cal.nixg.ru)info→ ничего, письмо просто помечено тегом- идемпотентность: письмо обрабатывается один раз (трекинг в state/SQLite)
- Cron — новый Hermes cron (или расширение существующего), который после архивации запускает классификатор и обработчики.
Capabilities
New Capabilities
email-classification: классификация писем локальной LLM + теги в frontmatteremail-handlers: подключение обработчиков (уведомление, задача, встреча) по тегамemail-attachments: скачивание вложений письма в его каталог (фикс бага)
Modified Capabilities
- (нет) — существующая capability
email-storage-formatне меняет требования по формату файла, только добавляет новые поля; это расширение, а не изменение существующих требований.
Impact
- Скрипты:
mail_archive.py(фикс вложений), новыеemail_classifier.py,email_handlers.py - Конфиг: Ollama (Qwen3:8b, уже есть), Vikunja API (нужен токен), Telegram (gateway/уведомления), Radicale (события)
- Frontmatter
email.md: новые поляclassification,classification_reason,has_attachments(если ещё нет) - Cron: новый классификатор/обработчики