guide · computers

Connecting Hermes Agent to Telegram: A First-Time Setup Guide

Step-by-step setup of the Hermes messaging gateway for Telegram: BotFather token, allow-list, home chat ID, and proof that the first message actually arrives back in the chat.

July 14, 2026 · By Alastair Fraser

A friendly retro-futurist robot sitting at a wooden desk, paired with a vintage teleprinter-style Telegram device on the right feeding a strip of yellow paper tape, while the robot types a reply on a small keyboard on the left.

A Hermes install with no gateway configured is half an install. The same agent that answers you in the terminal can answer you from Telegram — same memory, same skills, same model — but only after you wire at least one messaging platform into the gateway. Telegram is the easiest place to start because the bot setup protocol is well-documented and the runtime fits in the free tier.

This is the layer that runs after hermes chat -q "Reply with OK." proves the agent itself works. By the end you’ll have a Telegram chat where sending a message from your phone produces a Hermes reply within seconds, and that reply will outlive the terminal session because the gateway keeps the per-chat session in SQLite.

What the gateway does (and what it doesn’t)

The gateway is a single background process that connects your Hermes install to one or more messaging platforms. Each adapter speaks that platform’s protocol — Telegram’s long-poll via getUpdates, Discord’s gateway WebSocket, etc. — and routes inbound messages through a per-chat session store into the same AIAgent your terminal uses.

What it is not: a separate agent (same model, same memory), auto-started (nothing listens until you run or install), or free-for-all (default deny — unapproved chats are logged but never replied to). Approval happens once, at setup time.

The compact command set you’ll touch:

CommandJob
hermes gateway setupInteractive wizard for token + allow-list
hermes gateway listShow all platforms and their status
hermes gateway runForeground bridge (use this for the first test)
hermes gateway installRegister systemd/launchd service for autostart
hermes gateway start / stop / restartControl the installed service
hermes gateway status [--deep]Health check, adapter-by-adapter
hermes gateway uninstallRemove the service registration

You will run six of these, in order, to finish this guide.

Step 1: get a Telegram bot token

Every Telegram bot is born from a chat with BotFather:

  1. Send /newbot.
  2. BotFather asks for a display name — anything; it shows up in the chat header.
  3. BotFather asks for a username — must end in bot and be globally unique. You can’t change it later.
  4. BotFather returns an HTTP API token of the form 123456789:AA....

That token is the secret — anyone with it owns the bot.

DoDon’t
Paste it directly into hermes gateway setup.Paste it into a chat, an issue, a screenshot, or a git commit.
Store it in ~/.hermes/.env if scripting setup.Echo it into shell history on a shared host.
Revoke and re-issue (/revoke/token) if it leaks.Treat it as low-value “because it’s just Telegram.”

Step 2: run hermes gateway setup

The wizard is arrow-key driven:

hermes gateway setup

Pick Telegram, then answer: bot token from BotFather, your numeric user ID from @userinfobot, the home chat ID (blank → set later via /sethome), and “Start now?” → no (Step 4 does the foreground run).

For scripted provisioning, set the same fields directly. The home chat ID 8630382972 here is from the source install; substitute the chat you actually own (find it via https://api.telegram.org/bot<TOKEN>/getUpdates after sending yourself a message):

hermes config set gateway.platforms.telegram.token "$TELEGRAM_BOT_TOKEN"
hermes config set gateway.platforms.telegram.allowed_users "123456789"
hermes config set gateway.platforms.telegram.home_channel_chat_id "8630382972"

The wizard writes ~/.hermes/gateway.json (or $HERMES_HOME); the token lands in ~/.hermes/.env as TELEGRAM_BOT_TOKEN.

Step 3: confirm the allow-list is what you expect

Denial-by-default is the single biggest reason “the bot never replies.” Sanity-check with:

hermes gateway list
IndicatorMeaning
telegram - configuredToken loaded, allow-list non-empty, gateway not yet started.
telegram - runningForeground or service bridge is connected.
telegram - deniedToken set but home chat not in the allow-list — check ~/.hermes/gateway.json.

Three allow-list rules: allowed_users (required for DMs), allowed_chats (groups; IDs are negative, -100… for supergroups), and the per-group require_mention flag that defaults to true.

Step 4: foreground run for the first time

Start the bridge in the foreground so logs scroll past your terminal:

hermes gateway run

You should see, in order: adapter init lines (Telegram shows its bot username and configured chat IDs), cron scheduler started, and then the process holding the foreground. Ctrl-C to stop. Send hello from the bot chat in Telegram — you will see the inbound message, the session creation (agent:main:telegram:dm:<chat_id>), the agent turn, the outbound reply, and the Telegram API response in the same scrollback.

If multiple platforms are configured, hermes gateway run --platform telegram pins it to the one adapter. Most installs leave the default.

Step 5: send a test message (this is the proof)

Stop the foreground with Ctrl-C and restart it, then send this from your phone:

Reply with exactly: gateway smoke test OK at <current time>

If the gateway is wired correctly, the reply lands in the chat within 2-5 seconds and references the time you asked for. Three things were just proven:

  1. Inbound — token valid, your chat in the allow-list, long-poll alive.
  2. Session — agent picked the right session key; if memory is on it sees prior CLI context.
  3. Outbound — agent turn completed and the response was POSTed back via the Telegram Bot API.

If the bot doesn’t reply, jump to Common failures. Don’t install as a service until this works; installing a broken bridge just moves the failure to a less inspectable place.

Step 6: install as a service

Once the foreground proves the wiring is sound, register the gateway as a background service:

hermes gateway install
OSWhat install writes
Linux (systemd)~/.config/systemd/user/hermes-gateway.service
macOS (launchd)~/Library/LaunchAgents/ai.hermes.gateway.plist
WSL2Same as Linux, but systemd=true must be set in /etc/wsl.conf first or the unit silently fails to start.
DockerService does not apply. Run gateway run under s6 or docker-compose with restart: unless-stopped.
Native WindowsTask Scheduler task. Hermes recommends WSL2 over native Windows for anything gateway-shaped.

After install, enable linger on Linux hosts you SSH into (sudo loginctl enable-linger $USER), or the user-scoped service dies the moment your SSH session closes. hermes gateway status reports running only when the service is up and the adapter has a healthy getUpdates connection; if it stays disconnected, restart and check $HERMES_HOME/logs/gateway.log. hermes pairing approve telegram XKGH5N7P is the alternative to a hard-coded allow-list — a stranger who DMs the bot gets a one-time pairing code, you approve it, they are in.

Common failures

SymptomFirst checkFix
Bot never responds to a DMhermes gateway status --deepYour numeric user ID is not in allowed_users. Get it from @userinfobot, add it via hermes gateway setup.
Bot answers in DMs onlyhermes config get gateway.platforms.telegram.allowed_chatsAdd the group ID (negative for supergroups) to allowed_chats.
401 Unauthorized on first messageToken rotation/revoke then /token in BotFather; paste the new token into hermes gateway setup.
Gateway shows disconnectedhermes gateway status --deep and journalctl --user -u hermes-gateway -n 50Restart the service; most often a stale PID in ~/.local/state/hermes/gateway-locks/ from an earlier crashed run.
Bot answers once, then goes silentGateway log + cron logA long agent turn triggered a stall. /stop from the chat, then hermes gateway restart.
TELEGRAM_BOT_TOKEN empty in cron deliverygrep TELEGRAM /opt/data/.envSame token file the gateway uses; cron reads from .env too.
clock skew or repeated reconnectschronyc tracking (or w32tm /query /status on Windows)Bot API requires time within ~30s. Fix NTP first, then restart the gateway.
”Bot token already in use (PID NNNN)” where NNNN is a defunct processps -o pid,stat -p NNNNA previous gateway child died uncleanly; the lock-holder is a zombie. kill NNNN does nothing on zombies; clean up with hermes gateway uninstall && hermes gateway install, then restart.

The structural pattern: check the allow-list before changing the token, and check the service state before reading logs. Most “the bot is broken” reports are one of those two.

Verification checklist

Run these in order. Each row proves one layer.

#CommandWhat it proves
1hermes gateway listTelegram adapter is registered.
2hermes gateway setupToken and allow-list are saved.
3hermes gateway statusAdapter reports healthy at idle.
4hermes gateway run --platform telegramForeground bridge connects (Telegram long-poll goes green).
5Send a Telegram messageReply within seconds = inbound + agent + outbound all proven.
6hermes gateway installService registered for autostart.
7hermes gateway status after rebootService stayed up across the reboot.

Sources

Last verified: 2026-07-14 against Hermes v0.18.2 and gateway/platforms/telegram.py. Token is a secret — never paste it into a chat, an issue tracker, or git history; on leak, /revoke and hermes gateway setup.

Sources

#hermes#gateway#telegram#bot#messaging#setup#operator

Submit a take

Have a different read on this? Drop a comment below — your email isn't published, and I read every one. Nothing leaves the site until I approve it.

Your email address will not be published. Required fields are marked.