Gateway Profiles — Slack Multiplex & Telegram Bots
This page documents how the Hermes messaging gateway on the Agent Host serves the
default, bourgon, and djuly profiles, and how each profile is reached from Slack
and Telegram. It supersedes the earlier per-profile gateway services.
Architecture in one line
Section titled “Architecture in one line”A single hermes-gateway.service serves all three profiles (gateway multiplexing).
The profile is selected differently depending on the platform:
- Slack — one shared bot; the inbound channel selects the profile via
profile_routes. - Telegram — one bot per profile; the bot itself selects the profile.
Slack: one bot, routed by channel
Section titled “Slack: one bot, routed by channel”Slack uses a single Socket Mode App (@hermes) owned by the default gateway.
The inbound channel determines which profile handles the message:
| Slack channel | Profile |
|---|---|
#djuly-diet (C0B786XP4FQ) |
djuly |
#chateaudebourgon-website (C0BCNA7V2TC) |
bourgon |
| any other channel / DM | default |
That routing is declared in the default profile’s config.yaml:
gateway: multiplex_profiles: true profile_routes: - name: bourgon-website platform: slack chat_id: C0BCNA7V2TC profile: bourgon - name: djuly-diet platform: slack chat_id: C0B786XP4FQ profile: djulyWhy not a per-profile Slack gateway? Slack Socket Mode forbids two concurrent
connections using the same App Token. Running default and bourgon as separate
gateways sharing the same token caused Slack app token already in use failures.
Channel allowlists would not help because the collision happens at connect time,
before any message filtering. A single gateway owning the ingress and routing
channels is the clean solution.
The named profiles must not start their own Slack adapters when the default gateway owns the shared ingress; their Slack adapters remain disabled.
Telegram (one bot per profile)
Section titled “Telegram (one bot per profile)”Each profile owns its own Telegram bot token (in its own .env). The multiplexed
gateway connects all three bots simultaneously:
| Telegram bot | Profile | Token fingerprint |
|---|---|---|
hermes_fducat_bot |
default |
bccbb31deaea |
bourgon |
bourgon |
4ab831bb220c |
nutry_djuly_bot |
djuly |
4a83bf72fcd5 |
A message to nutry_djuly_bot is handled by the djuly profile; a message to
hermes_fducat_bot by the default profile. No profile_routes work is needed —
the bot identity is the selector. There is no token collision because the bots are
distinct.
Runtime isolation
Section titled “Runtime isolation”Regardless of how a message was routed (channel or bot), the turn executes inside
the target profile’s isolated runtime: its own configuration, model, reasoning
settings, SOUL.md, skills, memory, credentials (.env), cron store, and
HERMES_HOME.
Legacy per-profile gateway units
Section titled “Legacy per-profile gateway units”The former dedicated units still exist on disk but are legacy and disabled:
hermes-gateway-bourgon.servicehermes-gateway-djuly.serviceDo not start them while the multiplexed gateway is authoritative; that would create
duplicate profile runtimes or duplicate platform adapters. Their definitive removal
is pending the dashboard profile status fix (the view still expects a process per
profile and can incorrectly report a multiplexed profile as “not started”).