본문으로 건너뛰기

Slack 설정

Socket Mode 사용해 Hermes Agent를 봇으로 Slack에 연결. Socket Mode는 WebSocket 사용, 공용 HTTP 엔드포인트 대신. Hermes 인스턴스 공개 접근 불필요 — 방화벽 뒤, 노트북, 사설 서버에서 동작.

Classic Slack Apps Deprecated

클래식 Slack 앱(RTM API 사용) 2025년 3월 완전 폐기. Hermes는 최신 Bolt SDK와 Socket Mode 사용. 구 클래식 앱 있으면, 아래 단계 따라 새로 만들어야 함. 필수.

개요

구성요소
라이브러리Python용 slack-bolt / slack_sdk (Socket Mode)
연결WebSocket — 공용 URL 불필요
필요 인증 토큰Bot Token (xoxb-) + App-Level Token (xapp-)
사용자 식별Slack Member ID (예: U01ABC2DEF3)

1단계: Slack App 생성

가장 빠른 경로는 Hermes가 생성한 manifest 붙여넣기. 내장 슬래시 명령 모두 선언(/btw, /stop, /model, …), 필수 OAuth 스코프 모두, 이벤트 구독 모두, Socket Mode 활성화 — 한번에 모두.

  1. manifest 생성:
    hermes slack manifest --write
    ``~/.hermes/slack-manifest.json` 작성, 붙여넣기 지침 출력.

  2. https://api.slack.com/apps 이동 → Create New AppFrom an app manifest
  3. 워크스페이스 선택, JSON 내용 붙여넣기, 검토, Next 클릭 → Create
  4. 6단계: Install App to Workspace로 건너뛰기. manifest가 스코프, 이벤트, 슬래시 명령 처리 완료.

옵션 B: 처음부터 (수동)

  1. https://api.slack.com/apps 이동
  2. Create New App 클릭
  3. From scratch 선택
  4. 앱 이름 입력 (예: "Hermes Agent"), 워크스페이스 선택
  5. Create App 클릭

앱의 Basic Information 페이지 도착. 아래 2~6단계 진행.


2단계: Bot Token 스코프 설정

사이드바에서 Features → OAuth & Permissions 이동. Scopes → Bot Token Scopes 스크롤, 다음 추가:

스코프용도
chat:write봇으로 메시지 전송
app_mentions:read채널에서 @멘션 감지
channels:history봇이 속한 공개 채널의 메시지 읽기
channels:read공개 채널 목록 및 정보 조회
groups:history봇이 초대된 비공개 채널 메시지 읽기
im:historyDM 기록 읽기
im:read기본 DM 정보 조회
im:writeDM 열기 및 관리
users:read사용자 정보 조회
files:read첨부 파일 읽기 및 다운로드, 음성 메모/오디오 포함
files:write파일 업로드 (이미지, 오디오, 문서)
Missing scopes = missing features

channels:historygroups:history 없으면, 봇 채널 메시지 수신 불가 — DM에서만 동작. files:read 없으면, Hermes 채팅 가능하지만 사용자 업로드 첨부 안정적으로 읽기 불가. 가장 흔히 누락되는 스코프.

선택 스코프:

스코프용도
groups:read비공개 채널 목록 및 정보 조회

3단계: Socket Mode 활성화

Socket Mode로 공용 URL 대신 WebSocket으로 연결 가능.

  1. 사이드바에서 Settings → Socket Mode 이동
  2. Enable Socket Mode ON 토글
  3. App-Level Token 생성 안내:
    • hermes-socket 같은 이름 (이름 무관)
    • connections:write 스코프 추가
    • Generate 클릭
  4. 토큰 복사xapp-로 시작. 이것이 SLACK_APP_TOKEN

Settings → Basic Information → App-Level Tokens에서 항상 app-level 토큰 조회/재생성 가능.


4단계: 이벤트 구독

이 단계 중요 — 봇이 볼 수 있는 메시지 제어.

  1. 사이드바에서 Features → Event Subscriptions 이동
  2. Enable Events ON 토글
  3. Subscribe to bot events 펼치고 추가:
이벤트필수?용도
message.im봇이 DM 수신
message.channels봇이 추가된 공개 채널에서 메시지 수신
message.groups권장봇이 초대된 비공개 채널에서 메시지 수신
app_mention봇 @멘션 시 Bolt SDK 오류 방지
  1. 페이지 하단 Save Changes 클릭
Missing event subscriptions is the #1 setup issue

봇이 DM에서 동작하나 채널에서 미동작이면, 거의 확실히 message.channels (공개 채널용) 또는 message.groups (비공개 채널용) 누락. 이 이벤트 없으면 Slack이 채널 메시지 봇에게 전달 안 함.


5단계: Messages 탭 활성화

이 단계로 봇에 DM 가능. 없으면 봇 DM 시도 시 "Sending messages to this app has been turned off" 표시.

  1. 사이드바에서 Features → App Home 이동
  2. Show Tabs 스크롤
  3. Messages Tab ON 토글
  4. "Allow users to send Slash commands and messages from the messages tab" 체크
Without this step, DMs are completely blocked

모든 스코프와 이벤트 구독 올바르더라도, Messages Tab 활성화 없으면 Slack은 사용자가 봇에 DM 보내는 것 차단. Slack 플랫폼 요구사항, Hermes 설정 문제 아님.


6단계: 워크스페이스에 앱 설치

  1. 사이드바에서 Settings → Install App 이동
  2. Install to Workspace 클릭
  3. 권한 검토 후 Allow 클릭
  4. 승인 후, xoxb-로 시작하는 Bot User OAuth Token 표시
  5. 이 토큰 복사 — 이것이 SLACK_BOT_TOKEN

이후 스코프나 이벤트 구독 변경 시, 앱 재설치 필수, 변경 사항 적용 위해. Install App 페이지에 재설치 안내 배너 표시.


7단계: 허용 목록용 사용자 ID 찾기

Hermes는 허용 목록에 Slack Member ID 사용 (사용자명/표시명 아님).

Member ID 찾기:

  1. Slack에서 사용자 이름/아바타 클릭
  2. View full profile 클릭
  3. (more) 버튼 클릭
  4. Copy member ID 선택

Member ID 형식 U01ABC2DEF3. 최소한 본인 Member ID 필요.


8단계: Hermes 설정

~/.hermes/.env 파일에 다음 추가:

# Required
SLACK_BOT_TOKEN=xoxb-your-bot-token-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 앱 manifest 포함 (1단계, 옵션 A 참조), COMMAND_REGISTRY의 모든 명령 슬래시 명령으로 선언. Socket Mode에서 Slack은 manifest ... 필드와 무관하게 WebSocket으로 명령 이벤트 라우팅.

업데이트 후 슬래시 명령 새로고침

Hermes에 새 명령 추가 시 (예: hermes update 이후), manifest 재생성 및 Slack 앱 업데이트:

hermes slack manifest --write

이후 Slack에서:

  1. https://api.slack.com/apps 열기 → Hermes 앱
  2. Features → App Manifest → Edit
  3. ~/.hermes/slack-manifest.json 내용 붙여넣기
  4. Save. 스코프나 슬래시 명령 변경되면 Slack이 앱 재설치 안내.

레거시 /hermes <subcommand> 여전히 작동

구 manifest와의 하위 호환성 위해, 여전히 /hermes btw run the tests 입력 가능 — Hermes는 /btw run the tests. Free-form questions also work: /hermes what's the weather?와 동일하게 라우팅, 일반 메시지로 처리.

스레드 내 명령 사용 (!cmd 접두사)

Slack 자체가 스레드 답글 내 네이티브 슬래시 명령 차단 — 스레드에서 /queue 시도하면 Slack이 "/queue is not supported in threads. Sorry!" 응답. 재활성화하는 앱 측 설정 없음; Slack이 Hermes에 전달 안 함.

대안으로 Hermes는 선두 !를 대체 명령 접두사로 인식, 스레드 (및 다른 곳) 동작. 일반 스레드 답글로 !queue, !stop, !model gpt-5.4 등 입력 — Hermes가 슬래시 형식과 동일하게 처리, 같은 스레드에 응답.

첫 토큰만 알려진 명령 목록과 대조, 따라서 !nice work 같은 일상 메시지는 변경 없이 에이전트로 전달.

고급: slash-commands 배열만 출력

Slack manifest 수동 관리, 슬래시 명령 목록만 필요할 때:

hermes slack manifest --slashes-only > /tmp/slashes.json

기존 manifest의 features.slash_commands 키에 배열 붙여넣기.


봇 응답 방식

서로 다른 컨텍스트에서 Hermes 동작 이해:

컨텍스트동작
DM봇이 모든 메시지에 응답 — @멘션 불필요
채널@멘션 시에만 응답 (예: @Hermes Agent what time is it?). 채널에서 Hermes는 해당 메시지에 연결된 스레드로 응답.
스레드기존 스레드 내에서 Hermes @멘션하면 같은 스레드에 응답. 스레드에 활성 세션 생기면, 이후 스레드 답글은 @멘션 불필요 — 봇이 대화 자연스럽게 따라감.

채널에서는 대화 시작 시 항상 봇 @멘션. 봇이 스레드에서 활성화되면, 멘션 없이 스레드 답글 가능. 스레드 밖에서는 @멘션 없는 메시지 무시, 바쁜 채널 소음 방지.


설정 옵션

8단계의 필수 환경 변수 외, ~/.hermes/config.yaml로 Slack 봇 동작 커스터마이즈 가능.

스레드 및 응답 동작

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"멀티파트 메시지 스레드 모드: "off", "first", "all"
platforms.slack.extra.reply_in_threadtruefalse이면, 채널 메시지가 스레드 대신 직접 답글. 기존 스레드 내 메시지는 여전히 스레드 내 응답.
platforms.slack.extra.reply_broadcastfalsetrue이면, 스레드 답글이 메인 채널에도 게시. 첫 청크만 브로드캐스트.

세션 격리

# Global setting — applies to Slack and all other platforms
group_sessions_per_user: true
``true` (기본값)이면, 공유 채널의 각 사용자가 자신의 격리된 대화 세션 보유. `#general`에서 Hermes와 대화하는 두 사람은 별도 기록과 컨텍스트 가짐.

전체 채널이 하나의 대화 세션 공유하는 협업 모드 원하면 `false`로 설정. 단, 사용자들이 context 증가와 토큰 비용 공유, 한 사용자의 `/reset`이 전원의 세션 삭제.

### 멘션 및 트리거 동작 \{#option-b-from-scratch-manual}

```yaml
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: ""
When to use strict_mention

Slack 기본 "봇이 이 스레드 기억" 동작이 사용자 놀라게 하는 바쁜 워크스페이스에서 true로 설정 — 예: 봇이 초반에 도왔던 긴 기술지원 스레드, 명시적 재핑 전까지 침묵 원할 때. DM과 활성 인터랙티브 세션은 영향 없음.

정보

Slack은 두 패턴 모두 지원: 기본은 대화 시작 시 @mention 필요, 단 특정 채널은 SLACK_FREE_RESPONSE_CHANNELS (쉼표 구분 채널 ID) 또는 config.yamlslack.free_response_channels로 제외 가능. 봇이 스레드에 활성 세션 보유하면, 이후 스레드 답글은 멘션 불필요. DM에서는 봇이 항상 멘션 없이 응답.

미인증 사용자 처리

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:` 하위 플랫폼별 설정이 전역 설정보다 우선.

### 음성 전사 \{#voice-transcription}

```yaml
# Global setting — enable/disable automatic transcription of incoming voice messages
stt_enabled: true
``true` (기본값)이면, 수신 오디오 메시지가 에이전트 처리 전 설정된 STT 제공자로 자동 전사.

### 전체 예제 \{#step-3-enable-socket-mode}

```yaml
# 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 찾기:

  1. Slack에서 채널명 우클릭
  2. View channel details 클릭
  3. 하단 스크롤 — Channel ID 표시
SLACK_HOME_CHANNEL=C01234567890

봇이 채널에 초대됨 확인 (/invite @Hermes Agent).


멀티 워크스페이스 지원

Hermes는 단일 gateway 인스턴스로 여러 Slack 워크스페이스에 동시 연결 가능. 각 워크스페이스는 자체 봇 사용자 ID로 독립 인증.

설정

SLACK_BOT_TOKEN쉼표 구분 목록으로 여러 봇 토큰 제공:

# Multiple bot tokens — one per workspace
SLACK_BOT_TOKEN=xoxb-workspace1-token,xoxb-workspace2-token,xoxb-workspace3-token

# 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-workspace1-token,xoxb-workspace2-token"

OAuth 토큰 파일

환경 변수나 설정 파일 토큰 외, Hermes는 다음 위치의 OAuth 토큰 파일에서도 토큰 로드:

~/.hermes/slack_tokens.json

이 파일은 팀 ID를 토큰 항목에 매핑하는 JSON 객체:

{
"T01ABC2DEF3": {
"token": "xoxb-workspace-token-here",
"team_name": "My Workspace"
}
}

이 파일의 토큰은 SLACK_BOT_TOKEN로 지정된 토큰과 병합. 중복 토큰 자동 중복제거.

동작 방식

  • 목록의 첫 토큰이 기본 토큰, Socket Mode 연결(AsyncApp)에 사용.
  • 각 토큰은 시작 시 auth.test로 인증. gateway는 각 team_id을 자체 WebClientbot_user_id에 매핑.
  • 메시지 도착 시, Hermes는 올바른 워크스페이스별 클라이언트로 응답.
  • 기본 bot_user_id (첫 토큰)는 단일 봇 identity 기대하는 기능과의 하위 호환성에 사용.

음성 메시지

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.

키는 Slack 채널 ID (채널 자세히 보기 → "About" → 하단 스크롤로 확인). 매칭 채널의 모든 메시지에 프롬프트가 일시적 시스템 지침으로 주입.

채널별 Skill 바인딩

특정 채널이나 DM에서 새 세션 시작 시 skill 자동 로드. 채널별 프롬프트(매 턴 주입)와 달리, skill 바인딩은 세션 시작 시 사용자 메시지로 skill 내용 주입 — 대화 기록의 일부가 되며 이후 턴마다 재로드 불필요.

DM이나 전용 목적 채널(플래시카드, 도메인 특화 Q&A 봇, 지원 분류 채널 등)에 적합. 짧은 답변마다 모델의 자체 skill selector가 로드 여부 결정하는 것 원치 않을 때 사용.

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

참고 사항:

  • 바인딩은 channel ID 기준으로 매칭됨. 바인딩된 channel 내 threaded message는 thread가 부모 channel 바인딩 상속.
  • skill은 session 시작 시에만 로드됨 (새 session 또는 auto-reset 후). binding 변경 시, 적용 위해 /new 실행하거나 session auto-reset 대기.
  • channel_prompts 와 결합하여 skill 지침 위에 채널별 톤/제약 추가.

Hermes Agent 문제 해결

문제해결 방법
DM에 봇이 응답하지 않음message.im이(가) 이벤트 구독에 포함되어 있는지 확인하고 앱을 재설치하세요
DM에서는 봇이 작동하지만 채널에서는 작동 안 함가장 흔한 문제. message.channelsmessage.groups 을 event subscriptions 에 추가하고, 앱을 재설치한 후, /invite @Hermes Agent 로 봇을 채널에 초대하세요
봇이 채널에서 @mentions에 응답 안 함1) message.channels 이벤트 구독 확인. 2) 봇이 채널에 초대되어 있어야 함. 3) channels:history scope 추가 확인. 4) scope/event 변경 후 앱 재설치
봇이 비공개 채널 메시지 무시message.groups 이벤트 구독과 groups:history scope를 모두 추가한 후, 앱을 재설치하고 봇을 /invite 하세요
DM에서 "이 앱으로의 메시지 전송이 비활성화되었습니다"App Home 설정에서 Messages Tab 활성화 (Step 5 참조)
"not_authed" 또는 "invalid_auth" 오류Bot Token과 App Token을 재발급하고 .env 업데이트
봇이 응답하지만 채널에 게시 불가/invite @Hermes Agent 로 봇을 채널에 초대하세요
봇이 채팅은 가능하지만 업로드된 이미지/파일은 읽지 못함files:read 추가 후 앱 재설치. Hermes는 Slack이 scope/auth/permission 실패 반환 시 첨부 파일 접근 진단을 채팅 내 표시.
missing_scope 오류OAuth & Permissions에서 필요한 scope 추가 후 앱 재설치
소켓 연결이 자주 끊김네트워크 확인; Bolt 자동 재연결되나 불안정한 연결 시 지연 발생
스코프/이벤트 변경했지만 아무것도 안 바뀜스코프나 이벤트 구독 변경 후 워크스페이스에 앱을 반드시 재설치 해야 함

빠른 체크리스트

봇이 채널에서 작동하지 않으면 다음 사항을 모두 확인:

  1. message.channels 이벤트 구독됨 (공개 채널용)
  2. message.groups 이벤트 구독됨 (프라이빗 채널용)
  3. app_mention 이벤트 구독됨
  4. channels:history scope 추가됨 (공개 채널용)
  5. groups:history scope 추가됨 (private 채널용)
  6. ✅ scope/event 추가 후 앱 재설치 완료
  7. ✅ 봇이 채널에 초대되었습니다 (/invite @Hermes Agent)
  8. ✅ 메시지에서 봇을 @멘션하고 있음

보안

{#advanced-emit-only-the-slash-commands-array}

SLACK_ALLOWED_USERS를 반드시 설정하여 인증된 사용자의 Member ID를 지정하세요. 이 설정 없이는 gateway는 안전 조치로 기본적으로 모든 메시지를 거부합니다. bot token은 절대 공유하지 마세요 — 비밀번호처럼 다루세요.

  • 토큰은 ~/.hermes/.env 에 저장해야 함 (파일 권한 600)
  • Slack 앱 설정에서 토큰을 주기적으로 교체
  • Hermes config 디렉터리 접근 권한 보유자 감사
  • Socket Mode는 공개 endpoint가 노출되지 않음을 의미 — 공격 표면 하나 감소