Настройка Slack
Подключите Hermes Agent к Slack в качестве бота, используя Socket Mode. Socket Mode работает через WebSocket вместо публичных HTTP-эндпоинтов, поэтому вашему экземпляру Hermes не нужен публичный доступ — он работает за файрволами, на вашем ноутбуке или на частном сервере.
Классические Slack-приложения (использующие RTM API) были полностью прекратили поддержку в марте 2025 года. Hermes использует современный Bolt SDK с Socket Mode. Если у вас есть старое классическое приложение, создайте новое, следуя инструкциям ниже.
Обзор
| Компонент | Значение |
|---|---|
| Библиотека | slack-bolt / slack_sdk для Python (Socket Mode) |
| Подключение | WebSocket — публичный URL не требуется |
| Необходимые токены | Токен бота (xoxb-) + Токен уровня приложения (xapp-) |
| Идентификация пользователей | Slack Member ID (например, U01ABC2DEF3) |
Шаг 1: Создание Slack-приложения
Самый быстрый способ — вставить манифест, который Hermes генерирует для вас. Он объявляет все встроенные слеш-команды (/btw, /stop, /model, …), все необходимые OAuth-области, все подписки на события и включает Socket Mode — всё сразу.
Вариант A: Из манифеста, сгенерированного Hermes (рекомендуется)
-
Сгенерируйте манифест:
bash hermes slack manifest --writeЭто запишет файл~/.hermes/slack-manifest.jsonи выведет инструкции по вставке. -
Перейдите на https://api.slack.com/apps → Create New App → From an app manifest
-
Выберите свою рабочую область, вставьте содержимое JSON, проверьте, нажмите Next → Create
-
Переходите сразу к Шагу 6: Установка приложения в рабочую область. Манифест уже настроил области, события и слеш-команды за вас.
Вариант B: С нуля (вручную)
-
Перейдите на https://api.slack.com/apps
-
Нажмите Create New App
-
Выберите From scratch
-
Введите название приложения (например, «Hermes Agent») и выберите рабочую область
-
Нажмите Create App
Вы окажетесь на странице Basic Information приложения. Продолжайте выполнение шагов 2–6 ниже.
Шаг 2: Настройка областей токена бота
Перейдите в Features → OAuth & Permissions на боковой панели. Прокрутите до Scopes → Bot Token Scopes и добавьте следующее:
| Область | Назначение |
|---|---|
chat:write |
Отправка сообщений от имени бота |
app_mentions:read |
Обнаружение упоминаний @в каналах |
channels:history |
Чтение сообщений в публичных каналах, где находится бот |
channels:read |
Просмотр списка и информации о публичных каналах |
groups:history |
Чтение сообщений в приватных каналах, куда приглашён бот |
im:history |
Чтение истории личных сообщений |
im:read |
Просмотр базовой информации о личных сообщениях |
im:write |
Открытие и управление личными сообщениями |
users:read |
Поиск информации о пользователях |
files:read |
Чтение и скачивание прикреплённых файлов, включая голосовые заметки/аудио |
files:write |
Загрузка файлов (изображения, аудио, документы) |
Без
channels:history и groups:history бот не будет получать сообщения в каналах — он будет работать только в личных сообщениях. Без files:read Hermes сможет общаться, но не сможет надёжно читать прикреплённые пользователем файлы. Это наиболее часто пропускаемые области.
Дополнительные области:
| Область | Назначение |
|---|---|
groups:read |
Просмотр списка и информации о приватных каналах |
Шаг 3: Включение Socket Mode
Socket Mode позволяет боту подключаться через WebSocket вместо необходимости публичного URL.
-
На боковой панели перейдите в Settings → Socket Mode
-
Включите тумблер Enable Socket Mode
-
Вам будет предложено создать App-Level Token:
- Назовите его, например,
hermes-socket(название не имеет значения) - Добавьте область
connections:write -
Нажмите Generate
-
Скопируйте токен — он начинается с
xapp-. Это вашSLACK_APP_TOKEN
Шаг 4: Подписка на события
Этот шаг критически важен — он определяет, какие сообщения бот может видеть.
-
На боковой панели перейдите в Features → Event Subscriptions
-
Включите тумблер Enable Events
-
Разверните Subscribe to bot events и добавьте:
| Событие | Обязательно? | Назначение |
|---|---|---|
message.im |
Да | Бот получает личные сообщения |
message.channels |
Да | Бот получает сообщения в публичных каналах, куда он добавлен |
message.groups |
Рекомендуется | Бот получает сообщения в приватных каналах, куда он приглашён |
app_mention |
Да | Предотвращает ошибки Bolt SDK при @упоминании бота |
- Нажмите Save Changes внизу страницы
Если бот работает в личных сообщениях, но не работает в каналах, вы почти наверняка забыли добавить
message.channels (для публичных каналов) и/или message.groups (для приватных каналов). Без этих событий Slack просто не доставляет сообщения из каналов боту.
Шаг 5: Включение вкладки сообщений
Этот шаг включает личные сообщения боту. Без него пользователи видят «Sending messages to this app has been turned off» при попытке написать боту в личные сообщения.
-
На боковой панели перейдите в Features → App Home
-
Прокрутите до Show Tabs
-
Включите тумблер Messages Tab
-
Отметьте «Allow users to send Slash commands and messages from the messages tab»
Даже со всеми правильными областями и подписками на события Slack не позволит пользователям отправлять личные сообщения боту, пока не включена вкладка сообщений. Это требование платформы Slack, а не проблема настройки Hermes.
Шаг 6: Установка приложения в рабочую область
-
На боковой панели перейдите в Settings → Install App
-
Нажмите Install to Workspace
-
Проверьте разрешения и нажмите Allow
-
После авторизации вы увидите Bot User OAuth Token, начинающийся с
xoxb- -
Скопируйте этот токен — это ваш
SLACK_BOT_TOKEN
Шаг 7: Поиск ID пользователей для белого списка
Hermes использует Slack Member ID (не имена пользователей или отображаемые имена) для белого списка.
Чтобы найти Member ID:
-
В Slack нажмите на имя или аватар пользователя
-
Нажмите View full profile
-
Нажмите кнопку ⋮ (ещё)
-
Выберите Copy member ID
Member ID выглядят как U01ABC2DEF3. Вам нужен как минимум ваш собственный Member ID.
Шаг 8: Настройка Hermes
Добавьте следующее в ваш файл ~/.hermes/.env:
# Required
SLACK_BOT_TOKEN=xoxb-y...here
SLACK_APP_TOKEN=xapp-your-app-token-here
SLACK_ALLOWED_USERS=U01ABC2DEF3 # Comma-separated Member IDs
# Optional
SLACK_HOME_CHANNEL=C01234567890 # Default channel for cron/scheduled messages
SLACK_HOME_CHANNEL_NAME=general # Human-readable name for the home channel (optional)
Или запустите интерактивную настройку:
hermes gateway setup # Select Slack when prompted
Затем запустите gateway:
hermes gateway # Foreground
hermes gateway install # Install as a user service
sudo hermes gateway install --system # Linux only: boot-time system service
Шаг 9: Приглашение бота в каналы
После запуска gateway вам нужно пригласить бота в каждый канал, где вы хотите, чтобы он отвечал:
/invite @Hermes Agent
Бот не будет автоматически присоединяться к каналам. Вы должны приглашать его в каждый канал отдельно.
Слеш-команды
Каждая команда Hermes (/btw, /stop, /new, /model, /help, …)
является нативной слеш-командой Slack — точно так же, как они работают в Telegram
и Discord. Введите / в Slack, и автодополнение покажет все
команды Hermes с их описаниями.
Как это работает под капотом: Hermes поставляется с сгенерированным манифестом Slack-приложения (см.
Шаг 1, Вариант A), который объявляет каждую команду из
COMMAND_REGISTRY
как слеш-команду. В Socket Mode Slack направляет событие команды
через WebSocket независимо от поля url в манифесте.
Обновление слеш-команд после обновлений
Когда Hermes добавляет новые команды (например, после hermes update), перегенерируйте
манифест и обновите ваше Slack-приложение:
hermes slack manifest --write
Затем в Slack:
-
Откройте https://api.slack.com/apps → ваше приложение Hermes
-
Features → App Manifest → Edit
-
Вставьте новое содержимое
~/.hermes/slack-manifest.json -
Save. Slack предложит переустановить приложение, если области или слеш-команды изменились.
Устаревшая /hermes <subcommand> всё ещё работает
Для обратной совместимости со старыми манифестами вы всё ещё можете ввести
/hermes btw run the tests — Hermes обработает это так же, как /btw
run the tests. Свободные вопросы тоже работают: /hermes what's the
weather? будет воспринято как обычное сообщение.
Расширенное: вывод только массива слеш-команд
Если вы поддерживаете манифест Slack вручную и хотите только список слеш-команд:
hermes slack manifest --slashes-only > /tmp/slashes.json
Вставьте этот массив в ключ features.slash_commands вашего
существующего манифеста.
Как бот отвечает
Понимание поведения Hermes в разных контекстах:
| Контекст | Поведение |
|---|---|
| Личные сообщения | Бот отвечает на каждое сообщение — @упоминание не требуется |
| Каналы | Бот отвечает только при @упоминании (например, @Hermes Agent сколько времени?). В каналах Hermes отвечает в треде, прикреплённом к этому сообщению. |
| Треды | Если вы @упомянули Hermes в существующем треде, он отвечает в этом же треде. Как только у бота появится активная сессия в треде, последующие ответы в этом треде не требуют @упоминания — бот естественно продолжает разговор. |
Параметры настройки
Помимо обязательных переменных окружения из Шага 8, вы можете настроить поведение Slack-бота через ~/.hermes/config.yaml.
Поведение тредов и ответов
platforms:
slack:
# Controls how multi-part responses are threaded
# "off" — never thread replies to the original message
# "first" — first chunk threads to user's message (default)
# "all" — all chunks thread to user's message
reply_to_mode: "first"
extra:
# Whether to reply in a thread (default: true).
# When false, channel messages get direct channel replies instead
# of threads. Messages inside existing threads still reply in-thread.
reply_in_thread: true
# Also post thread replies to the main channel
# (Slack's "Also send to channel" feature).
# Only the first chunk of the first reply is broadcast.
reply_broadcast: false
| Ключ | По умолчанию | Описание |
|---|---|---|
platforms.slack.reply_to_mode |
"first" |
Режим threading для многочастных сообщений: "off", "first" или "all" |
platforms.slack.extra.reply_in_thread |
true |
Если false, сообщения в каналах получают прямые ответы вместо тредов. Сообщения внутри существующих тредов всё равно отвечают в треде. |
platforms.slack.extra.reply_broadcast |
false |
Если true, ответы в тредах также публикуются в основной канал. Только первая часть первого ответа транслируется. |
Изоляция сессий
# Global setting — applies to Slack and all other platforms
group_sessions_per_user: true
Если true (по умолчанию), каждый пользователь в общем канале получает свою изолированную сессию разговора. Два человека, общающиеся с Hermes в #general, будут иметь отдельные истории и контексты.
Установите false, если нужен совместный режим, где весь канал использует одну сессию разговора. Имейте в виду, что пользователи будут делить рост контекста и затраты на токены, а /reset одного пользователя очистит сессию для всех.
Поведение упоминаний и триггеров
slack:
# Require @mention in channels (this is the default behavior;
# the Slack adapter enforces @mention gating in channels regardless,
# but you can set this explicitly for consistency with other platforms)
require_mention: true
# Prevent thread auto-engagement: only reply to channel messages that
# contain an explicit @mention. With this OFF (default), Slack can
# "auto-engage" — remembering past mentions in a thread and following
# up on bot-message replies, and resuming active sessions without a
# fresh mention. With strict_mention ON, every new channel message
# must @mention the bot before Hermes will respond.
strict_mention: false
# Custom mention patterns that trigger the bot
# (in addition to the default @mention detection)
mention_patterns:
- "hey hermes"
- "hermes,"
# Text prepended to every outgoing message
reply_prefix: ""
strict_mentionУстановите
true в занятых рабочих пространствах, где поведение Slack по умолчанию «бот помнит этот тред» может удивить пользователей — например, в длинном треде техподдержки, где бот помогал в начале, и вы предпочли бы, чтобы он молчал, пока его явно не позовут. Личные сообщения и активные интерактивные сессии не затрагиваются.
Обработка неавторизованных пользователей
slack:
# What happens when an unauthorized user (not in SLACK_ALLOWED_USERS) DMs the bot
# "pair" — prompt them for a pairing code (default)
# "ignore" — silently drop the message
unauthorized_dm_behavior: "pair"
Вы также можете установить это глобально для всех платформ:
unauthorized_dm_behavior: "pair"
Настройка для конкретной платформы в разделе slack: имеет приоритет над глобальной настройкой.
Транскрибация голоса
# Global setting — enable/disable automatic transcription of incoming voice messages
stt_enabled: true
Если true (по умолчанию), входящие аудиосообщения автоматически транскрибируются с использованием настроенного STT-провайдера перед обработкой агентом.
Полный пример
# Global gateway settings
group_sessions_per_user: true
unauthorized_dm_behavior: "pair"
stt_enabled: true
# Slack-specific settings
slack:
require_mention: true
unauthorized_dm_behavior: "pair"
# Platform config
platforms:
slack:
reply_to_mode: "first"
extra:
reply_in_thread: true
reply_broadcast: false
Домашний канал
Установите SLACK_HOME_CHANNEL — ID канала, куда Hermes будет доставлять запланированные сообщения, результаты cron-задач и другие проактивные уведомления. Чтобы найти ID канала:
-
Щёлкните правой кнопкой мыши по названию канала в Slack
-
Нажмите View channel details
-
Прокрутите вниз — ID канала отображается там
SLACK_HOME_CHANNEL=C01234567890
Убедитесь, что бот приглашён в канал (/invite @Hermes Agent).
Поддержка нескольких рабочих областей
Hermes может подключаться к нескольким Slack-рабочим областям одновременно, используя один экземпляр gateway. Каждая рабочая область аутентифицируется независимо со своим собственным ID пользователя-бота.
Конфигурация
Укажите несколько токенов бота как список через запятую в SLACK_BOT_TOKEN:
# Multiple bot tokens — one per workspace
SLACK_BOT_TOKEN=xoxb-w...oken,xoxb-w...oken,xoxb-w...oken
# A single app-level token is still used for Socket Mode
SLACK_APP_TOKEN=xapp-your-app-token
Или в ~/.hermes/config.yaml:
platforms:
slack:
token: "xoxb-w...oken,xoxb-w...oken"
Файл OAuth-токенов
В дополнение к токенам в окружении или конфиге, Hermes также загружает токены из файла OAuth-токенов по пути:
~/.hermes/slack_tokens.json
Этот файл представляет собой JSON-объект, сопоставляющий ID команд с записями токенов:
{
"T01ABC2DEF3": {
"token": "xoxb-w...here",
"team_name": "My Workspace"
}
}
Токены из этого файла объединяются с любыми токенами, указанными через SLACK_BOT_TOKEN. Дублирующиеся токены автоматически удаляются.
Как это работает
-
Первый токен в списке является основным токеном, используемым для подключения Socket Mode (AsyncApp).
-
Каждый токен аутентифицируется через
auth.testпри запуске. Gateway сопоставляет каждыйteam_idсо своим собственнымWebClientиbot_user_id. -
Когда приходит сообщение, Hermes использует правильный клиент для конкретной рабочей области для ответа.
-
Основной
bot_user_id(из первого токена) используется для обратной совместимости с функциями, которые ожидают единую идентичность бота.
Голосовые сообщения
Hermes поддерживает голос в Slack:
-
Входящие: Голосовые/аудиосообщения автоматически транскрибируются с использованием настроенного STT-провайдера: локальный
faster-whisper, Groq Whisper (GROQ_API_KEY) или OpenAI Whisper (VOICE_TOOLS_OPENAI_KEY) -
Исходящие: TTS-ответы отправляются как вложения аудиофайлов
Промпты для отдельных каналов
Назначайте эфемерные системные промпты для конкретных Slack-каналов. Промпт внедряется во время выполнения на каждом шаге — никогда не сохраняется в истории транскриптов — поэтому изменения вступают в силу немедленно.
slack:
channel_prompts:
"C01RESEARCH": |
You are a research assistant. Focus on academic sources,
citations, and concise synthesis.
"C02ENGINEERING": |
Code review mode. Be precise about edge cases and
performance implications.
Ключи — это ID Slack-каналов (найти их можно в деталях канала → «About» → прокрутить вниз). Все сообщения в соответствующем канале получают промпт в виде эфемерной системной инструкции.
Привязки навыков для отдельных каналов
Автоматически загружайте навык при запуске новой сессии в конкретном канале или личном сообщении. В отличие от промптов для каналов (которые внедряются на каждом шаге), привязки навыков внедряют содержимое навыка как пользовательское сообщение при запуске сессии — оно становится частью истории разговора и не требует повторной загрузки на последующих шагах.
Это идеально для личных сообщений или каналов с определённой целью (флеш-карточки, бот для вопросов и ответов в конкретной области, канал поддержки и т.д.), где вы не хотите, чтобы собственный выбор навыка модели решал, загружать ли его при каждом коротком ответе.
slack:
channel_skill_bindings:
# DM channel — always runs in "german-flashcards" mode
- id: "D0ATH9TQ0G6"
skills:
- german-flashcards
# Research channel — preload multiple skills in order
- id: "C01RESEARCH"
skills:
- arxiv
- writing-plans
# Short form: single skill as a string
- id: "C02SUPPORT"
skill: hubspot-on-demand
Примечания:
-
Привязка сопоставляется по ID канала. Для сообщений в тредах в привязанном канале тред наследует привязку родительского канала.
-
Навык загружается только при запуске сессии (новая сессия или после автосброса). Если вы измените привязку, выполните
/newили дождитесь автосброса сессии, чтобы изменения вступили в силу. -
Комбинируйте с
channel_promptsдля настройки тона/ограничений для конкретного канала поверх инструкций навыка.
Устранение неполадок
| Проблема | Решение |
|---|---|
| Бот не отвечает в личных сообщениях | Проверьте, что message.im есть в подписках на события, и приложение переустановлено |
| Бот работает в ЛС, но не в каналах | Самая частая проблема. Добавьте message.channels и message.groups в подписки на события, переустановите приложение и пригласите бота в канал через /invite @Hermes Agent |
| Бот не отвечает на @упоминания в каналах | 1) Проверьте, что событие message.channels подписано. 2) Бот должен быть приглашён в канал. 3) Убедитесь, что область channels:history добавлена. 4) Переустановите приложение после изменений областей/событий |
| Бот игнорирует сообщения в приватных каналах | Добавьте подписку на событие message.groups и область groups:history, затем переустановите приложение и пригласите бота через /invite |
| «Sending messages to this app has been turned off» в ЛС | Включите Messages Tab в настройках App Home (см. Шаг 5) |
| Ошибки «not_authed» или «invalid_auth» | Перегенерируйте токен бота и токен приложения, обновите .env |
| Бот отвечает, но не может писать в канал | Пригласите бота в канал через /invite @Hermes Agent |
| Бот может общаться, но не может читать загруженные изображения/файлы | Добавьте files:read, затем переустановите приложение. Hermes теперь отображает диагностику доступа к вложениям в чате, когда Slack возвращает ошибки областей/аутентификации/разрешений. |
Ошибка missing_scope |
Добавьте требуемую область в OAuth & Permissions, затем переустановите приложение |
| Частые отключения Socket | Проверьте свою сеть; Bolt автоматически переподключается, но нестабильные соединения вызывают задержки |
| Изменил области/события, но ничего не изменилось | После любого изменения областей или подписок на события вы обязаны переустановить приложение в рабочей области |
Краткий контрольный список
Если бот не работает в каналах, проверьте всё следующее:
-
✅ Событие
message.channelsподписано (для публичных каналов) -
✅ Событие
message.groupsподписано (для приватных каналов) -
✅ Событие
app_mentionподписано -
✅ Область
channels:historyдобавлена (для публичных каналов) -
✅ Область
groups:historyдобавлена (для приватных каналов) -
✅ Приложение переустановлено после добавления областей/событий
-
✅ Бот приглашён в канал (
/invite @Hermes Agent) -
✅ Вы @упоминаете бота в своём сообщении
Безопасность
-
Токены должны храниться в
~/.hermes/.env(права доступа к файлу600) -
Периодически меняйте токены через настройки Slack-приложения
-
Проверяйте, кто имеет доступ к вашей директории конфигурации Hermes
-
Socket Mode означает, что публичный эндпоинт не открыт — на одну поверхность атаки меньше