Настройка электронной почты

Hermes умеет принимать письма и отвечать на них по обычным протоколам IMAP и SMTP. Отправьте письмо на адрес агента — он ответит прямо в той же ветке. Никакого особого клиента или bot API не нужно. Подойдёт Gmail, Outlook, Yahoo, Fastmail и любой провайдер с поддержкой IMAP/SMTP.

инфо
Только адаптер шлюза, без внешних зависимостей

Эта страница про почтовый адаптер шлюза. Он работает на встроенных модулях Python imaplib, smtplib и email. Для такого способа подключения не нужны ни дополнительные пакеты, ни внешние сервисы.

Не путайте с встроенным навыком Himalaya для почты: тот даёт агенту управлять почтой через команды в терминале и требует внешнего CLI himalaya плюс конфиг-файл Himalaya.

ЗадачаЧто настраиватьВнешняя зависимость
Дать людям писать агенту Hermes и получать ответыПочтовый адаптер шлюза с этой страницыТолько аккаунт IMAP/SMTP, больше ничего
Дать агенту просматривать, составлять, перемещать и разбирать письма через терминальные инструментыНавык Himalaya для почтыCLI himalaya и ~/.config/himalaya/config.toml

Что понадобится заранее

  • Отдельный почтовый аккаунт под вашего агента Hermes (личную почту не используйте)
  • Включённый IMAP на этом аккаунте
  • Пароль приложения, если у вас Gmail или другой провайдер с двухфакторной аутентификацией

Настройка Gmail

  1. Включите двухфакторную аутентификацию в Google-аккаунте
  2. Откройте App Passwords
  3. Создайте новый пароль приложения (выберите «Mail» или «Other»)
  4. Скопируйте 16-символьный пароль — его и используйте вместо обычного

Outlook / Microsoft 365

  1. Зайдите в настройки безопасности
  2. Включите 2FA, если ещё не включена
  3. Создайте пароль приложения в разделе «Additional security options»
  4. IMAP-хост: outlook.office365.com, SMTP-хост: smtp.office365.com

Другие провайдеры

IMAP/SMTP поддерживает большинство почтовых сервисов. Загляните в документацию своего провайдера и уточните:

  • IMAP-хост и порт (обычно порт 993 с SSL)
  • SMTP-хост и порт (обычно порт 587 с STARTTLS)
  • нужны ли пароли приложений

Proton Mail Bridge и локальные релеи

Proton Mail Bridge (и похожие локальные релеи вроде самостоятельно поднятого MTA) слушают на loopback со STARTTLS и самоподписанным сертификатом, поэтому умолчания (неявный TLS на IMAP 993 и проверка сертификатов) подключиться не дадут. Переопределите транспорт в ~/.hermes/config.yaml:

platforms:
  email:
    enabled: true
    extra:
      imap_host: 127.0.0.1
      imap_security: starttls     # tls (по умолчанию) | starttls | plain
      imap_tls_verify: false      # у Bridge самоподписанный сертификат
      smtp_host: 127.0.0.1
      smtp_security: starttls     # по умолчанию: tls на порту 465, иначе starttls
      smtp_tls_verify: false

и пропишите EMAIL_IMAP_PORT=1143 и EMAIL_SMTP_PORT=1025 рядом с учётными данными Bridge в ~/.hermes/.env. Неизвестные значения *_security выдают предупреждение и откатываются к безопасному умолчанию. Отключать *_tls_verify стоит только для loopback-хостов — для любого другого хоста Hermes напишет в лог предупреждение о снятой проверке.


Шаг 1: Настройте Hermes

Самый простой путь:

hermes gateway setup

В меню платформ выберите Email. Мастер спросит ваш почтовый адрес, пароль, хосты IMAP/SMTP и список разрешённых отправителей.

Настройка вручную

Добавьте в ~/.hermes/.env:

# Обязательно
EMAIL_ADDRESS=hermes@gmail.com
EMAIL_PASSWORD=abcd efgh ijkl mnop    # Пароль приложения (не обычный пароль)
EMAIL_IMAP_HOST=imap.gmail.com
EMAIL_SMTP_HOST=smtp.gmail.com

# Безопасность (рекомендуется)
EMAIL_ALLOWED_USERS=your@email.com,colleague@work.com
# Обязательно: точный authserv-id в самом верхнем заголовке Authentication-Results
# вашего принимающего сервера (Gmail: mx.google.com).
# Этот сервер должен вырезать входящие заголовки с таким id, прежде чем добавить свой.
EMAIL_AUTHSERV_ID=mx.google.com

# Опционально
EMAIL_IMAP_PORT=993                    # По умолчанию: 993 (IMAP SSL)
EMAIL_SMTP_PORT=587                    # По умолчанию: 587 (SMTP STARTTLS)
EMAIL_POLL_INTERVAL=15                 # Секунд между проверками входящих (по умолчанию: 15)
EMAIL_HOME_ADDRESS=your@email.com      # Адрес доставки по умолчанию для cron-задач

Шаг 2: Запустите шлюз

hermes gateway              # Run in foreground
hermes gateway install      # Install as a user service
sudo hermes gateway install --system   # Linux only: boot-time system service

При старте адаптер:

  1. Проверяет соединения по IMAP и SMTP
  2. Помечает все письма во входящих как «прочитанные» (обрабатываются только новые)
  3. Начинает опрашивать ящик на предмет новых сообщений

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

Приём сообщений

Адаптер опрашивает IMAP-ящик на непрочитанные письма (UNSEEN) с заданным интервалом (по умолчанию — каждые 15 секунд). С каждым новым письмом происходит следующее:

  • Тема письма добавляется в контекст (например, [Subject: Deploy to production])
  • Ответные письма (тема начинается с Re:) идут без префикса темы — ветка уже задана
  • Вложения кешируются локально:
    • Картинки (JPEG, PNG, GIF, WebP) → доступны инструменту зрения
    • Документы (PDF, ZIP и т. д.) → доступны для работы с файлами
  • Письма только в HTML очищаются от тегов, чтобы извлечь обычный текст
  • Письма от самого агента отфильтровываются, чтобы не возникало петли ответов
  • Автоматические отправители и noreply молча игнорируются — noreply@, mailer-daemon@, bounce@, no-reply@, а также письма с заголовками Auto-Submitted, Precedence: bulk или List-Unsubscribe

Отправка ответов

Ответы уходят по SMTP с корректной привязкой к ветке:

  • Заголовки In-Reply-To и References держат письма в одной цепочке
  • Тема сохраняется с префиксом Re: (без двойного Re: Re:)
  • Message-ID генерируется с доменом агента
  • Ответ уходит обычным текстом (UTF-8)

Прикреплённые файлы

Агент может прикладывать файлы к ответам. Укажите в ответе MEDIA:/path/to/file, и файл прикрепится к исходящему письму.

Пропуск вложений

Чтобы игнорировать все входящие вложения (ради защиты от вредоносов или экономии трафика), добавьте в config.yaml:

platforms:
  email:
    skip_attachments: true

С этой настройкой вложения и встроенные части пропускаются ещё до декодирования содержимого. Текст письма при этом обрабатывается как обычно.


Контроль доступа

По умолчанию доступ к почте строже, чем на чат-платформах:

  1. EMAIL_ALLOWED_USERS задан → обрабатываются письма только с этих адресов (а также от GATEWAY_ALLOWED_USERS или одобренных через сопряжение)
  2. Список разрешений не задан → незнакомые отправители молча игнорируются
  3. EMAIL_ALLOW_ALL_USERS=true → принимается любой отправитель (осторожно с этим)
  4. platforms.email.unauthorized_dm_behavior: pair → незнакомый отправитель получает код для сопряжения
  5. platforms.email.unauthorized_dm_behavior: decline → незнакомый отправитель получает один вежливый отказ, а потом 24 часа — ничего

Записи списка разрешённых сверяются с адресом целиком. Голая запись вроде alice (скажем, имя пользователя чата в GATEWAY_ALLOWED_USERS) никогда не пропустит alice@ ни на каком домене, а письмо с такого адреса отбрасывается, без сопряжения и без отказа.

Hermes реагирует на письмо, только когда заголовок Authentication-Results, проставленный вашим принимающим сервером, подтверждает домен из From: (DMARC или выровненные SPF/DKIM). Это верно и при открытом доступе (EMAIL_ALLOW_ALL_USERS / GATEWAY_ALLOW_ALL_USERS): открытый доступ пускает любого отправителя, но каждый разговор и каждый ответ привязаны к From:, так что поддельный From: отправил бы текст злоумышленника в сессию этого адреса, а Hermes разослал бы его по почте. Коды сопряжения и отказы тоже требуют подтверждённого From:, поэтому ни то ни другое не уходит на поддельный адрес. Если ваш почтовый сервер такой заголовок не ставит, задайте platforms.email.require_authenticated_sender: false (или EMAIL_TRUST_FROM_HEADER=true) и примите этот риск. Иначе письмо допущенного отправителя без такого заголовка отбрасывается, а в журнале шлюза появляется предупреждение Dropping sender with unauthenticated From. Такое же предупреждение, но со ссылкой на platforms.email.authserv_id (EMAIL_AUTHSERV_ID), срабатывает, когда самый верхний заголовок Authentication-Results (тот, что добавляет ваш сервер; нижние никогда не учитываются) называет не в точности закреплённый authserv_id. Значение authserv_id должно в точности совпадать с authserv-id, который ваш сервер пишет перед первой ; этого заголовка. Письмо с адреса из EMAIL_ALLOWED_USERS / GATEWAY_ALLOWED_USERS, не прошедшее проверку по другой причине (например, у отправителя сломана DKIM или пересылка нарушает выравнивание), отбрасывается с тем же предупреждением и вердиктом, но без подсказки, как отказаться от проверки. Неудачные письма прочих отправителей, скажем с поддельным From: при открытом доступе, отбрасываются молча: только запись на уровне debug.

Закрепление authserv_id обязательно, пока включена проверка отправителя. Без platforms.email.authserv_id (EMAIL_AUTHSERV_ID) Hermes не отличит заголовок Authentication-Results вашего сервера от написанного самим отправителем (собственный MTA, который своего заголовка не добавляет, оставляет сверху заголовок отправителя), поэтому не доверяет ни одному: отбрасывается каждое письмо, которому нужен подтверждённый From:, а журнал шлюза один раз сообщает об этом и подсказывает исправление. Чтобы найти значение, откройте письмо, доставленное вашим сервером («показать оригинал» / исходный текст), и скопируйте токен перед первой ; в самом верхнем заголовке Authentication-Results, например mx.google.com для Gmail. Если этот токен меняется от письма к письму, перед вами имя хоста отдельного ретранслятора, а не authserv-id: RFC 8601 определяет authserv-id как стабильное имя административного домена, поэтому настройте свой MTA так, чтобы он ставил такое имя (например, AuthservID в OpenDKIM / OpenDMARC), и закрепите его. Совпадение id — это закрепление, а не доказательство происхождения: убедитесь, что ваш MTA вырезает входящие заголовки Authentication-Results с его id, прежде чем добавить свой. Если стабильный id закрепить нельзя, откажитесь от проверки явно через platforms.email.require_authenticated_sender: false (или EMAIL_TRUST_FROM_HEADER=true) и примите, что From: тогда принимается на веру как написан.

внимание

Для обычной работы используйте отдельный почтовый ящик и настройте EMAIL_ALLOWED_USERS. Сопряжение по почте отключено по умолчанию: в общих ящиках часто скапливаются посторонние непрочитанные письма, и Hermes не должен отвечать этим отправителям автоматически.


Решение проблем

ПроблемаРешение
«IMAP connection failed» при стартеПроверьте EMAIL_IMAP_HOST и EMAIL_IMAP_PORT. Убедитесь, что IMAP включён на аккаунте. Для Gmail включите его в Settings → Forwarding and POP/IMAP.
«SMTP connection failed» при стартеПроверьте EMAIL_SMTP_HOST и EMAIL_SMTP_PORT. Убедитесь, что пароль верный (для Gmail — пароль приложения).
Сообщения не приходятПроверьте, что адрес отправителя есть в EMAIL_ALLOWED_USERS. Если в журнале шлюза написано authserv-id is not configured, задайте EMAIL_AUTHSERV_ID — точный id из самого верхнего заголовка Authentication-Results, который пишет ваш сервер. Загляните в спам — некоторые провайдеры помечают автоматические ответы.
«Authentication failed»Для Gmail нужен именно пароль приложения, а не обычный. Сначала включите 2FA.
Дублирующиеся ответыУбедитесь, что запущен лишь один экземпляр шлюза. Проверьте hermes gateway status.
Медленный ответИнтервал опроса по умолчанию — 15 секунд. Уменьшите через EMAIL_POLL_INTERVAL=5 ради скорости (но IMAP-соединений будет больше).
Ответы не складываются в веткуАдаптер использует заголовки In-Reply-To. Некоторые клиенты (особенно веб) могут неправильно группировать автоматические письма.

Безопасность

внимание

Заведите отдельный почтовый аккаунт. Личную почту не подключайте — агент хранит пароль в .env и через IMAP получает полный доступ к ящику.

  • Пользуйтесь паролями приложений вместо основного пароля (для Gmail с 2FA это обязательно)
  • Задайте EMAIL_ALLOWED_USERS, чтобы ограничить круг тех, кто может общаться с агентом
  • Задайте EMAIL_AUTHSERV_ID — точный id из самой верхней отметки Authentication-Results принимающего MTA — и убедитесь, что этот MTA вырезает входящие заголовки с таким id
  • Пароль лежит в ~/.hermes/.env — защитите этот файл (chmod 600)
  • По умолчанию IMAP идёт через SSL (порт 993), а SMTP — через STARTTLS (порт 587), так что соединения зашифрованы

Справочник переменных окружения

ПеременнаяОбязательнаПо умолчаниюОписание
EMAIL_ADDRESSДа—Почтовый адрес агента
EMAIL_PASSWORDДа—Пароль почты или пароль приложения
EMAIL_IMAP_HOSTДа—Хост IMAP-сервера (например, imap.gmail.com)
EMAIL_SMTP_HOSTДа—Хост SMTP-сервера (например, smtp.gmail.com)
EMAIL_IMAP_PORTНет993Порт IMAP-сервера
EMAIL_SMTP_PORTНет587Порт SMTP-сервера
EMAIL_POLL_INTERVALНет15Секунд между проверками входящих
EMAIL_ALLOWED_USERSНет—Разрешённые адреса отправителей через запятую
EMAIL_AUTHSERV_IDДа, если проверка отправителя не отключена—Точный authserv-id в самом верхнем заголовке Authentication-Results вашего принимающего сервера; без него отбрасывается каждое письмо, которому нужен подтверждённый From:
EMAIL_HOME_ADDRESSНет—Адрес доставки по умолчанию для cron-задач
EMAIL_ALLOW_ALL_USERSНетfalseПринимать всех отправителей (не рекомендуется)
перевод и редактура:

обновлено

⌕ ESC