Telegram
На этой странице Hermes Agent интегрируется с Telegram в качестве полнофункционального чат-бота. После подключения вы можете общаться с агентом с любого устройства, отправлять голосовые сообщения, которые автоматически расшифровываются, получать результаты запланированных задач и использовать агента в групповых чатах. Интеграция построена на python-telegram-bot и поддерживает текст, голос, изображения и вложения файлов.
Шаг 1: Создание бота через BotFather¶
Для каждого Telegram-бота требуется токен API, выдаваемый @BotFather, официальным инструментом управления ботами Telegram.
1. Откройте Telegram и найдите @BotFather или перейдите по ссылке t.me/BotFather
2. Отправьте /newbot
3. Выберите отображаемое имя (например, "Hermes Agent") — это может быть что угодно
4. Выберите username — он должен быть уникальным и заканчиваться на bot (например, my_hermes_bot)
5. BotFather ответит вашим токеном API. Он выглядит так:
[code] 123456789:ABCdefGHIjklMNOpqrSTUvwxYZ
[/code]
warning
Храните токен бота в секрете. Любой, у кого есть этот токен, может управлять вашим ботом. Если токен утёк, немедленно отзовите его через /revoke в BotFather.
Шаг 2: Настройка бота (опционально)¶
Эти команды BotFather улучшают пользовательский опыт. Напишите @BotFather и используйте:
Команда| Назначение
---|---
/setdescription| Текст "Что умеет этот бот?", показываемый до начала общения
/setabouttext| Краткий текст на странице профиля бота
/setuserpic| Загрузка аватарки для бота
/setcommands| Определение меню команд (кнопка / в чате)
/setprivacy| Управление доступом бота к сообщениям в группах (см. Шаг 3)
tip
Для /setcommands полезный начальный набор:
[code]
help - Показать справку
new - Начать новый разговор
sethome - Установить этот чат как домашний канал
[/code]
Шаг 3: Приватный режим (критично для групп)¶
У ботов Telegram есть приватный режим, который включён по умолчанию. Это самый распространённый источник путаницы при использовании ботов в группах.
При включённом приватном режиме бот видит только:
* Сообщения, начинающиеся с / команды
* Ответы на собственные сообщения бота
* Служебные сообщения (вход/выход участников, закреплённые сообщения и т.д.)
* Сообщения в каналах, где бот является администратором
При выключенном приватном режиме бот получает все сообщения в группе.
Как отключить приватный режим¶
- Напишите @BotFather
- Отправьте
/mybots - Выберите своего бота
- Перейдите в Bot Settings → Group Privacy → Turn off
warning После изменения настройки приватности необходимо удалить бота из группы и добавить заново. Telegram кэширует состояние приватности при добавлении бота в группу, и оно не обновится, пока бот не будет удалён и добавлен повторно. tip Альтернатива отключению приватного режима: сделайте бота администратором группы. Боты-администраторы всегда получают все сообщения независимо от настройки приватности, и это избавляет от необходимости переключать глобальный приватный режим.
Шаг 4: Поиск вашего用户 ID¶
Hermes Agent использует числовые Telegram user ID для контроля доступа. Ваш user ID — это не ваш username, это число, например 123456789.
Метод 1 (рекомендуется): Напишите @userinfobot — он мгновенно ответит вашим user ID.
Метод 2: Напишите @get_id_bot — ещё один надёжный вариант.
Сохраните это число; оно понадобится на следующем шаге.
Шаг 5: Настройка Hermes¶
Вариант A: Интерактивная настройка (рекомендуется)¶
[code] hermes gateway setup
[/code] Выберите Telegram при появлении запроса. Мастер запросит ваш токен бота и разрешённые user ID, затем запишет конфигурацию за вас.
Вариант B: Ручная настройка¶
Добавьте следующее в ~/.hermes/.env:
[code]
TELEGRAM_BOT_TOKEN=123456789:ABCdefGHIjklMNOpqrSTUvwxYZ
TELEGRAM_ALLOWED_USERS=123456789 # Через запятую для нескольких пользователей
[/code]
Запуск шлюза¶
[code] hermes gateway
[/code] Бот должен появиться онлайн в течение нескольких секунд. Отправьте ему сообщение в Telegram для проверки.
Отправка сгенерированных файлов из терминалов на базе Docker¶
Если ваш терминальный бэкенд — docker, имейте в виду, что вложения Telegram отправляются процессом шлюза, а не из контейнера. Это означает, что конечный путь MEDIA:/... должен быть доступен для чтения на хосте, где запущен шлюз.
Распространённая проблема:
* агент записывает файл внутри Docker в /workspace/report.txt
* модель отправляет MEDIA:/workspace/report.txt
* доставка в Telegram не удаётся, потому что /workspace/report.txt существует только внутри контейнера, а не на хосте
Рекомендуемый шаблон:
[code]
terminal:
backend: docker
docker_volumes:
- "/home/user/.hermes/cache/documents:/output"
[/code]
Затем:
* записывайте файлы внутри Docker в /output/...
* отправляйте видимый на хосте путь в MEDIA:, например: MEDIA:/home/user/.hermes/cache/documents/report.txt
Если у вас уже есть раздел docker_volumes:, добавьте новый монтируемый том в тот же список. Дублирующиеся ключи YAML молча переопределяют предыдущие.
Поддерживаемые расширения файлов MEDIA:¶
Шлюз извлекает теги MEDIA:/path/to/file из ответов агента и отправляет указанный файл как нативное вложение платформы. Поддерживаемые расширения на всех платформах шлюза:
Категория| Расширения
---|---
Изображения| png, jpg, jpeg, gif, webp, bmp, tiff, svg
Аудио| mp3, wav, ogg, m4a, opus, flac, aac
Видео| mp4, mov, webm, mkv, avi
Документы| pdf, txt, md, csv, json, xml, html, yaml, yml, log
Office| docx, xlsx, pptx, odt, ods, odp
Архивы| zip, rar, 7z, tar, gz, bz2
Книги / пакеты| epub, apk, ipa
Всё из этого списка доставляется как нативное вложение на поддерживающих платформах (Telegram, Discord, Signal, Slack, WhatsApp, Feishu, Matrix и др.); на платформах без нативной поддержки используется ссылка или текстовый индикатор. Жирным выделены категории, добавленные в последних релизах — если вы полагались на то, что модель говорит "вот файл: /path/to/report.docx", переключитесь на MEDIA:/path/to/report.docx для нативной доставки.
Режим Webhook¶
По умолчанию Hermes подключается к Telegram через long polling — шлюз отправляет исходящие запросы к серверам Telegram для получения новых обновлений. Это хорошо работает для локальных и постоянно работающих развёртываний.
Для облачных развёртываний (Fly.io, Railway, Render и др.) режим webhook более экономичен. Эти платформы могут автоматически пробуждать приостановленные машины при входящем HTTP-трафике, но не при исходящих соединениях. Поскольку polling — это исходящие запросы, polling-бот никогда не может "уснуть". Режим webhook меняет направление — Telegram отправляет обновления на HTTPS URL вашего бота, что позволяет развёртываниям "засыпать" в простое.
| Polling (по умолчанию)| Webhook
---|---|---
Направление| Шлюз → Telegram (исходящие)| Telegram → Шлюз (входящие)
Лучше всего для| Локальные, постоянно работающие серверы| Облачные платформы с автопробуждением
Настройка| Не требует дополнительной конфигурации| Установите TELEGRAM_WEBHOOK_URL
Стоимость простоя| Машина должна оставаться запущенной| Машина может "спать" между сообщениями
Конфигурация¶
Добавьте следующее в ~/.hermes/.env:
[code]
TELEGRAM_WEBHOOK_URL=https://my-app.fly.dev/telegram
TELEGRAM_WEBHOOK_SECRET="$(openssl rand -hex 32)" # обязательно
# TELEGRAM_WEBHOOK_PORT=8443 # опционально, по умолчанию 8443
[/code]
Переменная| Обязательно| Описание
---|---|---
TELEGRAM_WEBHOOK_URL| Да| Публичный HTTPS URL, на который Telegram будет отправлять обновления. Путь URL извлекается автоматически (например, /telegram из примера выше).
TELEGRAM_WEBHOOK_SECRET| Да (когда установлен TELEGRAM_WEBHOOK_URL)| Секретный токен, который Telegram повторяет в каждом запросе webhook для верификации. Шлюз отказывается запускаться без него — см. GHSA-3vpc-7q5r-276h. Сгенерируйте с помощью openssl rand -hex 32.
TELEGRAM_WEBHOOK_PORT| Нет| Локальный порт, на котором слушает сервер webhook (по умолчанию: 8443).
Когда установлен TELEGRAM_WEBHOOK_URL, шлюз запускает HTTP-сервер webhook вместо polling. Когда не установлен, используется режим polling — поведение не изменилось по сравнению с предыдущими версиями.
Пример облачного развёртывания (Fly.io)¶
- Добавьте переменные окружения в секреты вашего приложения Fly.io:
[code]
fly secrets set TELEGRAM_WEBHOOK_URL=https://my-app.fly.dev/telegram
fly secrets set TELEGRAM_WEBHOOK_SECRET=$(openssl rand -hex 32)
[/code]
2. Откройте порт webhook в вашем fly.toml:
[code]
[[services]]
internal_port = 8443
protocol = "tcp"
[[services.ports]]
handlers = ["tls", "http"]
port = 443
[/code] 3. Разверните:
[code] fly deploy
[/code]
В логах шлюза должно появиться: [telegram] Connected to Telegram (webhook mode).
Поддержка прокси¶
Если API Telegram заблокирован или вам нужно направлять трафик через прокси, установите URL прокси, специфичный для Telegram. Он имеет приоритет над общими переменными окружения HTTPS_PROXY / HTTP_PROXY.
Вариант 1: config.yaml (рекомендуется)
[code]
telegram:
proxy_url: "socks5://127.0.0.1:1080"
[/code] Вариант 2: переменная окружения [code] TELEGRAM_PROXY=socks5://127.0.0.1:1080
[/code]
Поддерживаемые схемы: http://, https://, socks5://.
Прокси применяется как к основному соединению Telegram, так и к запасному IP-транспорту. Если прокси, специфичный для Telegram, не установлен, шлюз использует HTTPS_PROXY / HTTP_PROXY / ALL_PROXY (или автоматическое определение системного прокси macOS).
Домашний канал¶
Используйте команду /sethome в любом чате Telegram (личном или групповом), чтобы назначить его домашним каналом. Запланированные задачи (cron) доставляют свои результаты в этот канал.
Вы также можете установить его вручную в ~/.hermes/.env:
[code]
TELEGRAM_HOME_CHANNEL=-1001234567890
TELEGRAM_HOME_CHANNEL_NAME=\"My Notes\"
[/code]
tip
ID групповых чатов — отрицательные числа (например, -1001234567890). ID вашего личного чата совпадает с вашим user ID.
Голосовые сообщения¶
Входящий голос (речь в текст)¶
Голосовые сообщения, отправленные вами в Telegram, автоматически расшифровываются настроенным STT-провайдером Hermes и вставляются в разговор как текст.
* local использует faster-whisper на машине, запускающей Hermes — не требует API-ключа
* groq использует Groq Whisper и требует GROQ_API_KEY
* openai использует OpenAI Whisper и требует VOICE_TOOLS_OPENAI_KEY
Исходящий голос (текст в речь)¶
Когда агент генерирует аудио через TTS, оно доставляется как нативные Telegram голосовые сообщения — круглые, воспроизводимые встроенным плеером. * OpenAI и ElevenLabs создают Opus нативно — дополнительная настройка не требуется * Edge TTS (бесплатный провайдер по умолчанию) выводит MP3 и требует ffmpeg для конвертации в Opus:
[code]
# Ubuntu/Debian
sudo apt install ffmpeg
# macOS
brew install ffmpeg
[/code]
Без ffmpeg аудио Edge TTS отправляется как обычный аудиофайл (всё ещё воспроизводимый, но используется прямоугольный плеер вместо голосового сообщения).
Настройте TTS-провайдера в вашем config.yaml в разделе tts.provider.
Использование в групповых чатах¶
Hermes Agent работает в групповых чатах Telegram с некоторыми особенностями:
* Приватный режим определяет, какие сообщения бот может видеть (см. Шаг 3)
* TELEGRAM_ALLOWED_USERS по-прежнему применяется — только авторизованные пользователи могут активировать бота, даже в группах
* Вы можете запретить боту отвечать на обычный групповой чат с помощью telegram.require_mention: true
* С telegram.require_mention: true групповые сообщения принимаются, если они:
* являются ответами на одно из сообщений бота
* содержат упоминание @botusername
* содержат /command@botusername (команда из меню бота Telegram, включающая имя бота)
* совпадают с одним из настроенных regex-триггеров в telegram.mention_patterns
* Используйте telegram.ignored_threads, чтобы Hermes молчал в определённых темах форума Telegram, даже если группа в остальном разрешает свободные ответы или ответы по упоминанию
* Если telegram.require_mention не установлен или false, Hermes сохраняет прежнее поведение открытой группы и отвечает на обычные групповые сообщения, которые может видеть
Устранение неполадок: работает в личных сообщениях, но не в группах¶
Если бот отвечает в личном чате, но молчит в группе, проверьте эти пункты по порядку:
1. Доставка Telegram: отключите приватный режим в BotFather, сделайте бота администратором группы или упомяните бота напрямую. Hermes не может отвечать на групповые сообщения, которые Telegram никогда не доставляет боту.
2. Повторное добавление после изменения приватности: удалите бота из группы и добавьте снова после изменения настроек приватности в BotFather. Telegram может сохранять старое поведение доставки для существующих членств.
3. Авторизация Hermes: убедитесь, что отправитель указан в TELEGRAM_ALLOWED_USERS или TELEGRAM_GROUP_ALLOWED_USERS, или разрешите групповой чат с помощью TELEGRAM_GROUP_ALLOWED_CHATS.
4. Фильтры упоминаний: если установлено telegram.require_mention: true, обычный групповой чат игнорируется, если только сообщение не является слеш-командой, ответом боту, упоминанием @botusername или совпадением с настроенными mention_patterns.
Отрицательные ID чатов нормальны для групп и супергрупп Telegram. Если вы используете авторизацию на уровне чата, помещайте эти ID в TELEGRAM_GROUP_ALLOWED_CHATS, а не в список разрешённых отправителей.
Пример конфигурации группового триггера¶
Добавьте это в ~/.hermes/config.yaml:
[code]
telegram:
require_mention: true
mention_patterns:
- "^\\s*chompy\\b"
ignored_threads:
- 31
- "42"
[/code]
Этот пример разрешает все обычные прямые триггеры, а также сообщения, начинающиеся с chompy, даже если они не используют @mention. Сообщения в темах Telegram 31 и 42 всегда игнорируются до выполнения проверок на упоминания и свободные ответы.
Примечания к mention_patterns¶
- Шаблоны используют регулярные выражения Python
- Регистр не учитывается
- Шаблоны проверяются как для текстовых сообщений, так и для подписей к медиа
- Некорректные regex-шаблоны игнорируются с предупреждением в логах шлюза, а не приводят к краху бота
- Если вы хотите, чтобы шаблон срабатывал только в начале сообщения, используйте якорь
^
Приватные темы чатов (Bot API 9.4)¶
Telegram Bot API 9.4 (февраль 2026) ввёл Приватные темы чатов — боты могут создавать темы в форумном стиле непосредственно в личных чатах 1-на-1, без необходимости в супергруппе. Это позволяет запускать несколько изолированных рабочих пространств в вашем существующем личном чате с Hermes.
Пример использования¶
Если вы работаете над несколькими долгосрочными проектами, темы сохраняют контекст отдельно: * Тема \"Веб-сайт\" — работа над производственным веб-сервисом * Тема \"Исследование\" — обзор литературы и изучение статей * Тема \"Общее\" — разрозненные задачи и быстрые вопросы
Каждая тема получает свой собственный сеанс разговора, историю и контекст — полностью изолированные от других.
Конфигурация¶
Предварительные требования Перед добавлением тем в конфигурацию пользователь должен включить режим тем в личном чате с ботом: 1. Откройте ваш личный чат с ботом Hermes в Telegram 2. Нажмите на имя бота вверху, чтобы открыть информацию о чате 3. Включите Темы (переключатель превращения чата в форум)
Без этого Hermes запишет The chat is not a forum при запуске и пропустит создание темы. Это настройка на стороне клиента Telegram — бот не может включить её программно.
Добавьте темы в раздел platforms.telegram.extra.dm_topics в ~/.hermes/config.yaml:
[code]
platforms:
telegram:
extra:
dm_topics:
- chat_id: 123456789 # Ваш Telegram user ID
topics:
- name: Общее
icon_color: 7322096
- name: Веб-сайт
icon_color: 9367192
- name: Исследование
icon_color: 16766590
skill: arxiv # Автозагрузка навыка в этой теме
[/code]
Поля:
Поле| Обязательно| Описание
---|---|---
name| Да| Отображаемое имя темы
icon_color| Нет| Код цвета иконки Telegram (целое число)
icon_custom_emoji_id| Нет| ID пользовательского эмодзи для иконки темы
skill| Нет| Навык для автозагрузки в новых сеансах этой темы
thread_id| Нет| Заполняется автоматически после создания темы — не устанавливайте вручную
Как это работает¶
- При запуске шлюза Hermes вызывает
createForumTopicдля каждой темы, у которой ещё нетthread_id thread_idавтоматически сохраняется обратно вconfig.yaml— последующие перезапуски пропускают API-вызов- Каждая тема сопоставляется с изолированным ключом сеанса:
agent:main:telegram:dm:{chat_id}:{thread_id} - Сообщения в каждой теме имеют свою собственную историю разговора, сброс памяти и контекстное окно
Привязка навыка¶
Темы с полем skill автоматически загружают этот навык при начале нового сеанса в теме. Это работает точно так же, как ввод /skill-name в начале разговора — содержимое навыка вставляется в первое сообщение, и последующие сообщения видят его в истории разговора.
Например, тема с skill: arxiv будет иметь предварительно загруженный навык arxiv всякий раз, когда её сеанс сбрасывается (из-за таймаута бездействия, ежедневного сброса или ручного /reset).
tip
Темы, созданные вне конфигурации (например, через ручной вызов Telegram API), обнаруживаются автоматически, когда приходит служебное сообщение forum_topic_created. Вы также можете добавлять темы в конфигурацию во время работы шлюза — они будут подхвачены при следующем промахе кэша.
Мультисеансовый режим личных сообщений (/topic)¶
Мультисеансовый личный чат в стиле ChatGPT — один бот, множество параллельных разговоров. В отличие от управляемых оператором extra.dm_topics выше, этот режим управляется пользователем: никакой конфигурации, никаких предварительно объявленных имён тем. Конечный пользователь включает его с помощью /topic, затем нажимает кнопку + в Telegram и создаёт столько тем, сколько хочет, каждая из которых является полностью независимым сеансом Hermes.
Подкоманды /topic¶
| Форма | Контекст | Действие |
|---|---|---|
/topic |
Корневой личный чат, ещё не включён | Проверить возможности BotFather, включить мультисеансовый режим, создать закреплённую системную тему |
/topic |
Корневой личный чат, уже включён | Показать статус: доступные для восстановления несвязанные сеансы |
/topic |
Внутри темы | Показать привязку сеанса текущей темы |
/topic help |
Любой | Встроенная справка |
/topic off |
Корневой личный чат | Отключить мультисеансовый режим и очистить все привязки тем для этого чата |
/topic <session-id> |
Внутри темы | Восстановить предыдущий сеанс Telegram в текущей теме |
Только авторизованные пользователи (из белого списка TELEGRAM_ALLOWED_USERS / конфигурации авторизации платформы) могут выполнять /topic. Неавторизованный отправитель получает отказ вместо активации. |
||
| ### Личные темы (DM Topics) против мультисеансового режима | ||
extra.dm_topics (на основе конфигурации) |
/topic (управляемый пользователем) |
|
| --- | --- | --- |
| Кто активирует | Оператор, в config.yaml |
Конечный пользователь, отправкой /topic |
| Список тем | Фиксированный набор, объявленный в конфиге | Пользователь свободно создаёт/удаляет темы |
| Имена тем | Выбраны оператором | Выбраны пользователем; автоматически переименовываются в название сеанса Hermes |
| Поведение корневого личного чата | Без изменений — обычный чат | Становится системным лобби (некомандные сообщения отклоняются) |
| Основной сценарий использования | Постоянные рабочие пространства с опциональной привязкой навыка | Разовые параллельные сеансы |
| Хранение | extra.dm_topics в конфиге |
Таблицы SQLite telegram_dm_topic_mode + telegram_dm_topic_bindings |
Обе функции могут сосуществовать на одном боте — вы запускаете /topic из личного чата пользователя, а extra.dm_topics продолжает управлять темами, объявленными оператором, для других чатов. |
||
| ### Предварительные требования | ||
| В @BotFather откройте вашего бота → Bot Settings → Threads Settings: | ||
1. Включите Threaded Mode (включает has_topics_enabled) |
||
2. Не отключайте возможность пользователей создавать темы (оставляет allows_users_to_create_topics включённым) |
Когда пользователь впервые запускает /topic, Hermes вызывает getMe для проверки обоих флагов. Если хотя бы один выключен, Hermes отправляет скриншот страницы Threads Settings в BotFather и объясняет, что нужно переключить — активация не происходит, пока предварительные требования не выполнены.
Процесс активации¶
Из корневого личного чата отправьте: [code] /topic
[/code]
Hermes выполнит:
1. Проверит getMe().has_topics_enabled и allows_users_to_create_topics
2. Если оба true, включит мультисеансовый режим тем для этого личного чата
3. Создаст и закрепит системную тему для статуса/команд (best-effort)
4. Ответит списком предыдущих несвязанных сеансов Telegram, которые пользователь может восстановить
После активации корневой личный чат становится лобби: обычные запросы отклоняются с указанием на Все сообщения. Системные команды (/status, /sessions, /usage, /help и т.д.) по-прежнему работают в корневом чате.
Создание новой темы (для конечного пользователя)¶
- Откройте личный чат с ботом в Telegram
- Нажмите Все сообщения в верхней части интерфейса бота, затем отправьте любое сообщение
- Telegram создаёт новую тему для этого сообщения
- Hermes отвечает внутри этой темы — тема теперь является самостоятельным сеансом
Каждая тема получает свою собственную историю разговора, состояние модели, выполнение инструментов и ID сеанса. Ключ изоляции: agent:main:telegram:dm:{chat_id}:{thread_id} — идентичен изоляции тем, управляемых через конфигурацию.
Автоматически переименованные темы¶
Когда Hermes генерирует название сеанса для темы (через конвейер авто-названий, после первого обмена), сама тема Telegram переименовывается соответствующим образом — например, "Новая тема" становится "План миграции базы данных". Переименование выполняется best-effort: сбои логируются, но не нарушают работу сеанса.
/new внутри темы¶
Сбрасывает сеанс текущей темы (новый ID сеанса, свежая история), не затрагивая другие темы. Hermes отвечает с напоминанием, что для параллельной работы обычно лучше создать другую тему (через Все сообщения).
Восстановление предыдущего сеанса¶
Внутри темы отправьте:
[code]
/topic
[/code] Это связывает текущую тему с существующим сеансом Hermes вместо начала нового. Полезно для продолжения разговора, который начался до включения режима тем. Ограничения: * Целевой сеанс должен принадлежать тому же пользователю Telegram * Целевой сеанс не должен быть уже привязан к другой теме
Hermes подтверждает названием сеанса и воспроизводит последнее сообщение ассистента для контекста.
Чтобы узнать ID сеансов, отправьте /topic (без аргументов) в корневом личном чате — Hermes перечислит несвязанные сеансы Telegram пользователя.
/topic внутри темы (без аргументов)¶
Показывает привязку текущей темы: название сеанса, ID сеанса и подсказки по /new или созданию другой темы.
Под капотом¶
- Активация сохраняется в
telegram_dm_topic_mode(chat_id, user_id, enabled, ...)вstate.db - Каждая привязка темы сохраняется в
telegram_dm_topic_bindings(chat_id, thread_id, session_id, ...)сON DELETE CASCADEнаsession_id— удаление сеанса автоматически очищает его привязку к теме - Миграция SQLite для режима тем опциональна: она запускается при первом вызове
/topic, никогда при запуске шлюза. Пока пользователь не выполнит/topicв этом профиле,state.dbне изменяется - Каждое входящее сообщение в личном чате ищет привязку
(chat_id, thread_id). Если она есть, маршрутизация направляет сообщение в привязанный сеанс черезSessionStore.switch_session(), чтобы отображение ключа сеанса в ID сеанса оставалось согласованным на диске /newвнутри темы перезаписывает строку привязки, указывая на новый ID сеанса, чтобы следующее сообщение оставалось в свежем сеансе- Темы, объявленные в
extra.dm_topics, никогда не переименовываются автоматически — имя, выбранное оператором, сохраняется, даже если включён мультисеансовый режим - Общая (закреплённая верхняя) тема в личном чате с форумом рассматривается как корневое лобби, независимо от того, доставляет ли Telegram её сообщения с
message_thread_id=1или без thread_id - Напоминания о корневом лобби ограничены по частоте: одно сообщение в 30 секунд на чат — пользователь, забывший о включённом режиме тем и напечатавший десять запросов в корневом чате, не получит десять ответов
- Скриншоты настроек BotFather ограничены по частоте: одна отправка в 5 минут на чат — повторные попытки
/topic, пока Threads Settings всё ещё отключены, не приведут к повторной загрузке того же изображения /background <prompt>, запущенный внутри темы, доставляет результат обратно в ту же тему; фоновые сеансы не вызывают автоматического переименования родительской темы/topicсам по себе защищён проверкой авторизации пользователя бота — неавторизованные личные чаты получают отказ вместо активации
Отключение мультисеансового режима¶
Отправьте /topic off в корневом личном чате. Hermes отключает режим, очищает привязки (thread_id → session_id) чата, и корневой личный чат возвращается к обычному чату Hermes. Существующие темы в Telegram не удаляются — они просто перестают быть независимыми сеансами. Повторный запуск /topic позже снова включит режим.
Если вам нужно очистить вручную (например, массовый сброс для многих чатов), удалите строки напрямую:
[code]
sqlite3 ~/.hermes/state.db \
\"UPDATE telegram_dm_topic_mode SET enabled = 0 WHERE chat_id = '
DELETE FROM telegram_dm_topic_bindings WHERE chat_id = '
[/code]
Понижение версии Hermes¶
Если вы понизите версию Hermes до той, что предшествует /topic, функция просто перестанет работать — таблицы telegram_dm_topic_mode и telegram_dm_topic_bindings останутся в state.db, но будут игнорироваться старым кодом. Личные чаты вернутся к нативной изоляции по потокам (каждый message_thread_id всё равно получает свой сеанс через build_session_key), так что ваши существующие темы Telegram продолжат работать как параллельные сеансы. Корневой личный чат перестаёт быть лобби — сообщения там снова попадают к агенту, как раньше. Повторное обновление реактивирует мультисеансовый режим ровно в том же состоянии.
Привязка навыков к темам групповых форумов¶
Супергруппы с включённым режимом тем (также называемые \"темы форума\") уже получают изоляцию сеансов по темам — каждый thread_id сопоставляется со своим разговором. Но вы можете захотеть автоматически загружать навык, когда сообщения приходят в определённую тему группы, так же, как работает привязка навыков к темам личных чатов.
Пример использования¶
Командная супергруппа с темами форума для разных рабочих потоков:
* Тема Разработка → автозагрузка навыка software-development
* Тема Исследование → автозагрузка навыка arxiv
* Тема Общее → без навыка, ассистент общего назначения
Конфигурация¶
Добавьте привязки тем в раздел platforms.telegram.extra.group_topics в ~/.hermes/config.yaml:
[code]
platforms:
telegram:
extra:
group_topics:
- chat_id: -1001234567890 # ID супергруппы
topics:
- name: Разработка
thread_id: 5
skill: software-development
- name: Исследование
thread_id: 12
skill: arxiv
- name: Общее
thread_id: 1
# Без навыка — общего назначения
[/code]
Поля:
Поле| Обязательно| Описание
---|---|---
chat_id| Да| Числовой ID супергруппы (отрицательное число, начинающееся с -100)
name| Нет| Человекочитаемая метка для темы (только для информации)
thread_id| Да| ID темы форума Telegram — виден в ссылках t.me/c/<group_id>/<thread_id>
skill| Нет| Навык для автозагрузки в новых сеансах этой темы
Как это работает¶
- Когда сообщение поступает в сопоставленную тему группы, Hermes ищет
chat_idиthread_idв конфигурацииgroup_topics - Если найдена запись с полем
skill, этот навык автоматически загружается для сеанса — идентично привязке навыков к темам личных чатов - Темы без ключа
skillполучают только изоляцию сеанса (существующее поведение, без изменений) - Несопоставленные
thread_idилиchat_idигнорируются молча — без ошибки, без навыка
Отличия от личных тем (DM Topics)¶
| Личные темы (DM Topics)| Групповые темы (Group Topics)
---|---|---
Ключ конфига| extra.dm_topics| extra.group_topics
Создание тем| Hermes создаёт темы через API, если thread_id отсутствует| Администратор создаёт темы в интерфейсе Telegram
thread_id| Заполняется автоматически после создания| Должен быть установлен вручную
icon_color / icon_custom_emoji_id| Поддерживается| Не применимо (администратор управляет внешним видом)
Привязка навыка| ✓| ✓
Изоляция сеанса| ✓| ✓ (уже встроена для тем форума)
tip
Чтобы узнать thread_id темы, откройте тему в Telegram Web или Desktop и посмотрите на URL: https://t.me/c/1234567890/5 — последнее число (5) и есть thread_id. ID чата для супергрупп — это ID группы с префиксом -100 (например, группа 1234567890 становится -1001234567890).
Новые функции Bot API¶
- Bot API 9.4 (февраль 2026): Приватные темы чатов — боты могут создавать темы форума в личных чатах 1-на-1 через
createForumTopic. Hermes использует это для двух различных функций: управляемые оператором Приватные темы чатов (на основе конфигурации, фиксированный список тем) и управляемый пользователем Мультисеансовый режим личных сообщений (активируется через/topic, неограниченное количество создаваемых пользователем тем). - Политика конфиденциальности: Telegram теперь требует, чтобы у ботов была политика конфиденциальности. Установите её через BotFather с помощью
/setprivacy_policy, иначе Telegram может автоматически сгенерировать заглушку. Это особенно важно, если ваш бот общедоступен. - Потоковая передача сообщений: Bot API 9.x добавил поддержку потоковой передачи длинных ответов, что может улучшить воспринимаемую задержку для длинных ответов агента.
Отображение: Таблицы и предпросмотр ссылок¶
MarkdownV2 в Telegram не имеет нативного синтаксиса таблиц — таблицы в формате pipe превращаются в зашумлённый текст с экранированными обратными слешами, если передавать их как есть. Hermes автоматически нормализует markdown-таблицы: * Небольшие таблицы преобразуются в маркированные списки по строкам — каждая строка становится читаемым маркированным списком под заголовками столбцов. Хорошо для 2–4 столбцов и коротких ячеек. * Более крупные или широкие таблицы преобразуются в блок кода (fenced code block) с выровненными столбцами, чтобы ничего не сворачивалось. Добавляется однострочная подсказка, чтобы агент знал, что в Telegram лучше использовать прозу, а не таблицы.
Настраивать ничего не нужно — адаптер выбирает подходящий вариант для каждого сообщения. Если вы хотите использовать устаревшее поведение \"всегда блок кода\", отключите нормализацию таблиц, установив telegram.pretty_tables: false в config.yaml (по умолчанию: true).
Предпросмотр ссылок. Telegram автоматически генерирует превью ссылок для URL в сообщениях бота. Если вы хотите отключить их (длинный вывод /tools, ответ агента с упоминанием десяти ссылок и т.д.):
[code]
gateway:
platforms:
telegram:
extra:
disable_link_previews: true
[/code]
Когда эта опция включена, Hermes добавляет LinkPreviewOptions(is_disabled=True) Telegram к каждому исходящему сообщению и использует устаревший параметр disable_web_page_preview на более старых версиях python-telegram-bot.
Белые списки для групп¶
Группы Telegram и форумные чаты имеют два независимых фильтра, которые можно настроить:
* ID отправителей (group_allow_from / TELEGRAM_GROUP_ALLOWED_USERS) — белый список на уровне отправителя, применяемый только к сообщениям групп/форумов. Используйте это, когда хотите, чтобы определённые пользователи могли вызывать бота в группах без добавления их в TELEGRAM_ALLOWED_USERS (что также дало бы им доступ к личным чатам).
* ID чатов (group_allowed_chats / TELEGRAM_GROUP_ALLOWED_CHATS) — белый список на уровне чата. Любой участник этих групп/форумов может взаимодействовать с ботом. Полезно для командных/поддерживающих ботов, где само членство в группе является сигналом доступа.
[code]
gateway:
platforms:
telegram:
extra:
# Глобальный доступ (личные чаты + группы). Эти пользователи всегда могут вызывать бота.
allow_from:
- \"123456789\"
# ID отправителей, разрешённые только в группах/форумах. НЕ даёт доступ к личным чатам.
group_allow_from:
- \"987654321\"
# Целые группы/форумы — любой участник авторизован.
group_allowed_chats:
- \"-1001234567890\"
[/code]
Эквивалентные переменные окружения:
[code]
TELEGRAM_ALLOWED_USERS=\"123456789\"
TELEGRAM_GROUP_ALLOWED_USERS=\"987654321\"
TELEGRAM_GROUP_ALLOWED_CHATS=\"-1001234567890\"
[/code]
Поведение:
* TELEGRAM_ALLOWED_USERS охватывает все типы чатов (личные, группы, форумы).
* TELEGRAM_GROUP_ALLOWED_USERS авторизует только указанных отправителей в группах/форумах. Они всё ещё не могут писать боту в личные чаты, если не указаны в TELEGRAM_ALLOWED_USERS.
* Чат из TELEGRAM_GROUP_ALLOWED_CHATS авторизует каждого участника этого чата, независимо от отправителя.
* Используйте * в любом из этих параметров, чтобы разрешить любого отправителя/чат.
* Это работает поверх существующих триггеров упоминаний/шаблонов и поверх group_topics + ignored_threads.
Миграция с версии до PR #17686¶
До этого разделения TELEGRAM_GROUP_ALLOWED_USERS был единственным параметром, и пользователи помещали в него ID чатов. Для обратной совместимости значения, похожие на ID чатов (начинающиеся с -), в TELEGRAM_GROUP_ALLOWED_USERS по-прежнему обрабатываются как ID чатов, и однократно логируется предупреждение об устаревании. Миграция:
[code]
# Старый способ (всё ещё работает, но устарел)
TELEGRAM_GROUP_ALLOWED_USERS=\"-1001234567890\"
# Новый способ
TELEGRAM_GROUP_ALLOWED_CHATS=\"-1001234567890\"
[/code]
Интерактивный выбор модели¶
Когда вы отправляете /model без аргументов в чат Telegram, Hermes показывает интерактивную встроенную клавиатуру для переключения моделей:
1. Выбор провайдера — кнопки, показывающие каждого доступного провайдера с количеством моделей (например, \"OpenAI (15)\", \"✓ Anthropic (12)\" для текущего провайдера).
2. Выбор модели — постраничный список моделей с навигацией Назад / Вперёд, кнопкой Назад для возврата к провайдерам и Отмена.
Текущая модель и провайдер отображаются вверху. Вся навигация происходит путём редактирования того же сообщения на месте (без засорения чата).
tip
Если вы знаете точное имя модели, введите /model <name> напрямую, чтобы пропустить выбор. Вы также можете ввести /model <name> --global, чтобы сохранить изменение между сеансами.
Запасные IP-адреса через DNS-over-HTTPS¶
В некоторых ограниченных сетях api.telegram.org может разрешаться в IP-адрес, который недоступен. Адаптер Telegram включает механизм запасных IP-адресов, который прозрачно повторяет попытки подключения к альтернативным IP-адресам, сохраняя правильное TLS-имя хоста и SNI.
Как это работает¶
- Если установлен
TELEGRAM_FALLBACK_IPS, эти IP-адреса используются напрямую. - В противном случае адаптер автоматически запрашивает Google DNS и Cloudflare DNS через DNS-over-HTTPS (DoH) для обнаружения альтернативных IP-адресов для
api.telegram.org. - IP-адреса, возвращённые DoH и отличающиеся от результата системного DNS, используются как запасные.
- Если DoH также заблокирован, используется жёстко заданный seed-IP (
149.154.167.220) как последнее средство. - Как только запасной IP-адрес срабатывает, он становится \"липким\" — последующие запросы используют его напрямую, без повторной попытки основного пути.
Конфигурация¶
[code]
# Явные запасные IP-адреса (через запятую)
TELEGRAM_FALLBACK_IPS=149.154.167.220,149.154.167.221
[/code]
Или в ~/.hermes/config.yaml:
[code]
platforms:
telegram:
extra:
fallback_ips:
- \"149.154.167.220\"
[/code]
tip
Обычно вам не нужно настраивать это вручную. Автообнаружение через DoH обрабатывает большинство сценариев с ограниченными сетями. Переменная TELEGRAM_FALLBACK_IPS нужна только в случае, если DoH также заблокирован в вашей сети.
Поддержка прокси¶
Если ваша сеть требует HTTP-прокси для доступа в интернет (распространено в корпоративных средах), адаптер Telegram автоматически считывает стандартные переменные окружения прокси и направляет все соединения через прокси.
Поддерживаемые переменные¶
Адаптер проверяет эти переменные окружения по порядку, используя первую установленную:
1. HTTPS_PROXY
2. HTTP_PROXY
3. ALL_PROXY
4. https_proxy / http_proxy / all_proxy (варианты в нижнем регистре)
Конфигурация¶
Установите прокси в вашем окружении перед запуском шлюза:
[code]
export HTTPS_PROXY=http://proxy.example.com:8080
hermes gateway
[/code]
Или добавьте в ~/.hermes/.env:
[code]
HTTPS_PROXY=http://proxy.example.com:8080
[/code]
Прокси применяется как к основному транспорту, так и ко всем запасным IP-транспортам. Дополнительная настройка Hermes не требуется — если переменная окружения установлена, она используется автоматически.
note
Это покрывает пользовательский слой запасного транспорта, который Hermes использует для соединений Telegram. Стандартный клиент httpx, используемый в других местах, уже поддерживает переменные окружения прокси нативно.
Реакции на сообщения¶
Бот может добавлять реакции-эмодзи на сообщения как визуальную обратную связь о обработке: * 👀 когда бот начинает обработку вашего сообщения * ✅ когда ответ успешно доставлен * ❌ если произошла ошибка во время обработки
Реакции отключены по умолчанию. Включите их в config.yaml:
[code]
telegram:
reactions: true
[/code] Или через переменную окружения: [code] TELEGRAM_REACTIONS=true
[/code] note В отличие от Discord (где реакции добавляются по одной), Bot API Telegram заменяет все реакции бота одним вызовом. Переход от 👀 к ✅/❌ происходит атомарно — вы не увидите обе одновременно. tip Если у бота нет разрешения добавлять реакции в группе, попытки реакции молча игнорируются, и обработка сообщения продолжается нормально.
Промпты для отдельных каналов¶
Назначайте эфемерные системные промпты для определённых групп Telegram или тем форума. Промпт внедряется во время выполнения на каждом шаге — никогда не сохраняется в истории транскрипции — поэтому изменения вступают в силу немедленно.
[code]
telegram:
channel_prompts:
\"-1001234567890\": |
Ты исследовательский ассистент. Сосредоточься на академических источниках,
цитировании и лаконичном синтезе.
\"42\": |
Эта тема предназначена для обратной связи по креативному письму. Будь тёплым и
конструктивным.
[/code]
Ключи — это ID чатов (групп/супергрупп) или ID тем форума. Для групп с форумом промпты уровня темы переопределяют промпт уровня группы:
* Сообщение в теме 42 внутри группы -1001234567890 → использует промпт темы 42
* Сообщение в теме 99 (нет явной записи) → использует промпт группы -1001234567890
* Сообщение в группе без записи → промпт канала не применяется
Числовые ключи YAML автоматически нормализуются в строки.
Устранение неполадок¶
| Проблема | Решение |
|---|---|
| Бот вообще не отвечает | Проверьте, правильный ли TELEGRAM_BOT_TOKEN. Проверьте логи hermes gateway на наличие ошибок. |
| Бот отвечает \"unauthorized\" | Ваш user ID отсутствует в TELEGRAM_ALLOWED_USERS. Перепроверьте с помощью @userinfobot. |
| Бот игнорирует групповые сообщения | Вероятно, включён приватный режим. Отключите его (Шаг 3) или сделайте бота администратором группы. Не забудьте удалить бота из группы и добавить заново после изменения приватности. |
| Голосовые сообщения не расшифровываются | Проверьте, доступен ли STT: установите faster-whisper для локальной транскрипции или укажите GROQ_API_KEY / VOICE_TOOLS_OPENAI_KEY в ~/.hermes/.env. |
| Голосовые ответы — файлы, а не голосовые сообщения | Установите ffmpeg (требуется для конвертации Edge TTS в Opus). |
| Токен бота отозван/недействителен | Сгенерируйте новый токен через /revoke, затем /newbot или /token в BotFather. Обновите ваш .env файл. |
| Webhook не получает обновления | Проверьте, что TELEGRAM_WEBHOOK_URL общедоступен (протестируйте с помощью curl). Убедитесь, что ваша платформа/обратный прокси маршрутизирует входящий HTTPS-трафик с порта URL на локальный порт прослушивания, указанный в TELEGRAM_WEBHOOK_PORT (они не обязательно должны совпадать). Убедитесь, что SSL/TLS активен — Telegram отправляет данные только на HTTPS URL. Проверьте правила брандмауэра. |
| ## Подтверждение выполнения команд | |
| Когда агент пытается выполнить потенциально опасную команду, он запрашивает ваше подтверждение в чате: | |
| > ⚠️ Эта команда потенциально опасна (рекурсивное удаление). Ответьте \"yes\" для подтверждения. | |
| Ответьте \"yes\"/\"y\" для подтверждения или \"no\"/\"n\" для отказа. | |
| ## Безопасность | |
| warning | |
Всегда устанавливайте TELEGRAM_ALLOWED_USERS, чтобы ограничить круг лиц, которые могут взаимодействовать с вашим ботом. Без этого шлюз по умолчанию отклоняет всех пользователей в качестве меры безопасности. |
|
Никогда не публикуйте токен вашего бота. Если он скомпрометирован, немедленно отзовите его через команду /revoke в BotFather. |
|
| Для получения дополнительной информации см. документацию по безопасности. Вы также можете использовать связывание личных чатов (DM pairing) для более динамичного подхода к авторизации пользователей. | |
| * Шаг 1: Создание бота через BotFather | |
| * Шаг 2: Настройка бота (опционально) | |
| * Шаг 3: Приватный режим (критично для групп) | |
| * Как отключить приватный режим | |
| * Шаг 4: Поиск вашего пользовательского ID | |
| * Шаг 5: Настройка Hermes | |
| * Вариант A: Интерактивная настройка (рекомендуется) | |
| * Вариант B: Ручная настройка | |
| * Запуск шлюза | |
| * Отправка сгенерированных файлов из терминалов на базе Docker | |
* Поддерживаемые расширения файлов MEDIA: |
|
| * Режим Webhook | |
| * Конфигурация | |
| * Пример облачного развёртывания (Fly.io) | |
| * Поддержка прокси | |
| * Домашний канал | |
| * Голосовые сообщения | |
| * Входящий голос (речь в текст) | |
| * Исходящий голос (текст в речь) | |
| * Использование в групповых чатах | |
| * Устранение неполадок: работает в личных сообщениях, но не в группах | |
| * Пример конфигурации группового триггера | |
* Примечания к mention_patterns |
|
| * Приватные темы чатов (Bot API 9.4) | |
| * Пример использования | |
| * Конфигурация | |
| * Как это работает | |
| * Привязка навыка | |
* Мультисеансовый режим личных сообщений (/topic) |
|
* Подкоманды /topic |
|
| * Личные темы (DM Topics) против мультисеансового режима | |
| * Предварительные требования | |
| * Процесс активации | |
| * Создание новой темы (для конечного пользователя) | |
| * Автоматически переименованные темы | |
* /new внутри темы |
|
| * Восстановление предыдущего сеанса | |
* /topic внутри темы (без аргументов) |
|
| * Под капотом | |
| * Отключение мультисеансового режима | |
| * Понижение версии Hermes | |
| * Привязка навыков к темам групповых форумов | |
| * Пример использования | |
| * Конфигурация | |
| * Как это работает | |
| * Отличия от личных тем (DM Topics) | |
| * Новые функции Bot API | |
| * Отображение: Таблицы и предпросмотр ссылок | |
| * Белые списки для групп | |
| * Миграция с версии до PR #17686 | |
| * Интерактивный выбор модели | |
| * Запасные IP-адреса через DNS-over-HTTPS | |
| * Как это работает | |
| * Конфигурация | |
| * Поддержка прокси | |
| * Поддерживаемые переменные | |
| * Конфигурация | |
| * Реакции на сообщения | |
| * Промпты для отдельных каналов | |
| * Устранение неполадок | |
| * Подтверждение выполнения команд | |
| * Безопасность |