Files
hermes-config/skills/autonomous-ai-agents/hermes-telegram/SKILL.md
T
2026-07-12 10:17:17 -04:00

15 KiB

name, description, version, author, license, platforms, metadata, related_skills
name description version author license platforms metadata related_skills
hermes-telegram Configure, troubleshoot, and manage Telegram integration for Hermes Agent — bot setup, .env configuration, gateway restart, and common failure modes. 1.0.0 Hermes Agent MIT
linux
macos
hermes
tags related_skills
hermes
telegram
messaging
gateway
bot
hermes-agent
hermes-agent

Hermes Telegram Integration

Configure the Hermes Agent gateway to send and receive messages on Telegram. Covers bot creation, .env setup, allowed users, home channel, gateway restart, and troubleshooting.

Prerequisites

  • Hermes Agent gateway installed and running (hermes gateway status or ps aux | grep 'hermes gateway run')
  • A Telegram account to create and manage the bot

Setup Steps

1. Create a Bot on Telegram

Message @BotFather on Telegram:

/newbot

Follow the prompts to choose a name and username. BotFather will return a bot token like:

8971430276:AAFu...Amq4

Save this token — you'll need it in the next step.

2. Find Your Numeric IDs

You need numeric Telegram IDs, not usernames. Message @userinfobot on Telegram — it will reply with:

  • Your user ID (a number like 123456789) — used for TELEGRAM_ALLOWED_USERS
  • For groups/channels: add the bot to the group, send a message, then use @userinfobot in the group to get the chat ID

Note: TELEGRAM_ALLOWED_USERS and TELEGRAM_HOME_CHANNEL require numeric IDs, not @username strings.

3. Configure .env

Edit the .env file. The default template has all Telegram variables commented out — you must uncomment and fill them in:

hermes config env-path     # prints the path (typically ~/.hermes/.env)

The relevant lines (find them under the # TELEGRAM INTEGRATION section):

TELEGRAM_BOT_TOKEN=your_bot_token_here
TELEGRAM_ALLOWED_USERS=123456789           # Comma-separated numeric user IDs
TELEGRAM_HOME_CHANNEL=123456789            # Numeric chat ID for cron deliveries
TELEGRAM_HOME_CHANNEL_NAME=@yourusername   # Display name (optional, username is fine here)

Important: The default template uses a combined single-line format:

# TELEGRAM_BOT_TOKEN=*** TELEGRAM_ALLOWED_USERS=

When uncommenting, split this into separate lines as shown above — one variable per line. Use your editor or sed to do it cleanly.

For the HOME_CHANNEL, if you only want DM delivery (bot messages you directly), set it to your own user ID — same as ALLOWED_USERS.

4. Restart the Gateway

Configuration changes in .env are read at startup. Restart the gateway to pick them up:

hermes gateway restart

Or if running as a systemd user service:

systemctl --user restart hermes-gateway

Manual Restart (no systemd service)

If systemctl --user list-units --type=service --all | grep hermes returns nothing, the gateway was started manually. Kill and restart it:

# Find the gateway PID
ps aux | grep 'hermes gateway run'

# Kill it (use -9 if plain kill won't work)
kill -9 <PID>

# Wait for it to die
sleep 2

# Start fresh — MUST use background=true (nohup/disown is blocked by tool policy)
# In the Hermes CLI session:
#   terminal(background=true, notify_on_complete=true, command="hermes gateway run")

Important: Do not use nohup, disown, or trailing & in a foreground terminal() call — the tool policy blocks shell-level background wrappers. Always use terminal(background=true) so Hermes tracks the process.

5. Verify It's Working

Send a message to your bot on Telegram. It should respond. Check the gateway logs for confirmation:

grep -i telegram ~/.hermes/logs/gateway.log | tail -20

Look for these lines to confirm a successful connection:

Connecting to telegram...
[Telegram] Auto-discovered Telegram fallback IPs: 149.154.166.110
[Telegram] set_my_commands OK for scope BotCommandScopeDefault (30 cmds)
[Telegram] Connected to Telegram (polling mode)
✓ telegram connected

If you see Connected to Telegram (polling mode) and ✓ telegram connected, the bot is live.

For a full reference of restart commands, log signatures, curl test-message patterns, and sed snippets, see references/gateway-restart-and-test.md.

Sending a Test Message from the CLI

The Hermes send_message tool only works in sessions initiated from a messaging platform (Telegram, Discord, etc.). In a CLI session, it returns "No messaging platforms connected" even when the gateway has Telegram active.

Workaround — use the Telegram Bot API directly via curl:

curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
  -d "chat_id=${CHAT_ID}" \
  -d "text=Hello from Hermes! 👋"

The ${TELEGRAM_BOT_TOKEN} is the value set in .env and ${CHAT_ID} is the numeric user/chat ID. This sends a message bypassing the Hermes gateway — useful for testing or one-off notifications from the CLI.

Gateway Check

To see if the gateway is running before troubleshooting:

ps aux | grep 'hermes gateway run'

Key Configuration Variables

Variable Required Description
TELEGRAM_BOT_TOKEN Yes Bot token from @BotFather
TELEGRAM_ALLOWED_USERS Recommended Comma-separated numeric user IDs allowed to chat. Leave empty to allow anyone (not recommended for production).
TELEGRAM_HOME_CHANNEL For cron Default chat ID for cron job deliveries
TELEGRAM_HOME_CHANNEL_NAME No Display name for the home channel
TELEGRAM_CRON_THREAD_ID No Forum topic ID for cron deliveries in topic-mode groups

Long-Running Tasks & Blocking Behavior

The gateway processes one turn at a time per session. While the agent is inside a turn (thinking, running tools, waiting for a terminal command), it cannot receive or process new messages from you. Telegram shows "typing..." the entire time.

Why the bot blocks

Phase What's happening Can you message?
🔄 Agent calls a tool (e.g. terminal()) Blocks waiting for result Queued
🤖 Agent calls the LLM again with tool output Generating next action Queued
📨 Agent sends you a progress update Brief mid-turn message Still in same turn
Agent sends final response and ends turn Done Next message processed

"Typing..." = active LLM calls = cost

Every iteration of the agent loop makes a new API call to your LLM provider. While the bot shows "typing...", it is actively making LLM calls — you are being charged for input + output tokens each round. Input tokens grow each iteration as tool results are appended to the conversation context.

How to avoid blocking the bot

Three approaches, in order of preference:

Approach How Best for
Cron job cronjob(action='create', schedule='...', prompt='run my script', no_agent=True) — script runs independently, stdout delivered verbatim to Telegram Standalone scripts that run on a schedule or fire-and-forget
🏃 Background terminal terminal(command='python long_script.py', background=true, notify_on_complete=true) — agent returns immediately, pings you when done One-off long scripts the user triggers
📋 /queue In CLI: /queue <prompt> — queues work for after current turn ends Quick follow-ups during an active session

The cron approach is cleanest: the bot never blocks, and no_agent=True means zero LLM calls during execution — the script's stdout is delivered verbatim.

Verifying the bot is stuck mid-turn

Check the gateway logs for the last activity:

tail -20 ~/.hermes/logs/gateway.log

Look for:

  • inbound message: ... msg='your prompt' — last message received
  • Flushing text batch ... (N chars) — last update sent (but turn not over)
  • No new inbound message entries — session is blocked, new messages are queued

Pitfalls

  • Usernames are not IDs. TELEGRAM_ALLOWED_USERS and TELEGRAM_HOME_CHANNEL need numeric Telegram IDs, not @username strings. Use @userinfobot to get them.
  • All vars start commented out. The .env template ships with # prefix on every Telegram line. You must uncomment them.
  • Multi-variable line trap. The default .env template writes TELEGRAM_BOT_TOKEN and TELEGRAM_ALLOWED_USERS on the same line: # TELEGRAM_BOT_TOKEN=*** TELEGRAM_ALLOWED_USERS=. This is NOT valid env format with the token value — split into two separate lines when configuring.
  • Gateway restart required. .env is read at process startup. Simply running hermes in a new CLI session does not reload the gateway's env vars. Use hermes gateway restart (or systemctl --user restart hermes-gateway) every time you change TELEGRAM_* variables.
  • Config schema warnings can block clean startup. If gateway status/logs show custom_providers is a dict — it must be a YAML list, fix it in ~/.hermes/config.yaml by making custom_providers a list (or clear it with hermes config set custom_providers "[]"), then restart the gateway.
  • Token secrecy. The bot token is a secret — anyone with it can control your bot. Keep it out of version control and shell history.
  • Gateway API server must be running. The gateway also starts the API server (typically port 8642). If tools or web UI can't reach the agent, the root cause is often a stopped gateway, not Telegram itself.
  • send_message tool is CLI-blind to Telegram. From a CLI session, send_message(action=list) returns No messaging platforms connected even when the gateway has Telegram active. This is by design — the tool only routes through gateway-originated sessions. Use the Telegram Bot API directly via curl to send messages from CLI sessions (see the Verification section for the exact curl command).

Bot Commands: Registration & Limits

The gateway auto-registers bot commands from hermes_cli.commands.telegram_bot_commands() on startup. Commands come from three sources: built-in CommandDef entries, plugin slash commands, and skill entries. Gateway caps the command list at MAX_COMMANDS_PER_SCOPE = 30 (telegram.py:108) to stay under Telegram's undocumented ~4KB payload limit.

Adding a custom command persistently:

  1. Edit ~/.hermes/hermes-agent/hermes_cli/commands.py -- add your (name, description) pair at the end of telegram_bot_commands():
    result.append(("imagine", "Generate an image from a text prompt"))
    
  2. Add the command to _TELEGRAM_MENU_PRIORITY if the cap is tight -- commands outside the priority list get trimmed first.
  3. If you go over 30 commands, raise MAX_COMMANDS_PER_SCOPE in telegram.py.
  4. Restart the gateway to pick up changes.

Without these three changes, custom commands get overwritten on gateway restart or silently truncated at the 30-command cap.

Troubleshooting

Diagnostic Flow: Bot Not Responding

Start with a status check first — it's the fastest way to narrow the cause.

hermes gateway status    # Primary check

If that's unavailable, fall back to:

ps aux | grep 'hermes gateway run'   # Second — gateway process exists?
systemctl --user status hermes-gateway 2>/dev/null   # Third — systemd service?

Branch A: Gateway is not running

The most common cause of "stopped working" is the gateway having been shut down. Check the logs to find out why:

grep -i "telegram\|error\|fail\|warn\|sigterm\|sigkill\|oom" ~/.hermes/logs/gateway.log | tail -20

Common shutdown signatures in the logs:

Log pattern Likely cause Action
WARNING ... Shutdown context: signal=SIGTERM under_systemd=yes parent_pid=1 systemd sent SIGTERM (user logout, reboot, service stop) Restart gateway or install as permanent service
ERROR ... signal=SIGKILL OOM killer or forced kill Check memory pressure, `dmesg
ERROR ... Traceback (most recent call last) Crash / unhandled exception Read the traceback, fix the root cause
Logs end abruptly with no shutdown message Process was killed externally (shell session closed, SSH disconnect) Restart gateway
No Telegram-related log entries at all Telegram may not be configured or enabled in config Check .env for TELEGRAM_* vars, check config.yamltelegram section

If the log shows the gateway was working fine then received SIGTERM, the fix is straightforward — restart it:

hermes gateway run          # foreground (session-dependent)
hermes gateway install      # as permanent systemd user service (auto-restarts)

If no systemd service exists (systemctl --user list-units --type=service --all | grep hermes returns empty), the gateway was started manually and won't survive a logout/reboot without the service.

Branch B: Gateway is running but not responding

grep -i telegram ~/.hermes/logs/gateway.log | tail -30

Look for:

  • [Telegram] Connected to Telegram (polling mode) — connection was established
  • inbound message: platform=telegram user=... — messages are being received
  • Sending response (... chars) to 1498679692 — responses are being sent
  • ERROR or WARNING entries — something went wrong

If messages arrive but responses fail, check:

  1. TELEGRAM_BOT_TOKEN is correct and uncommented in .env
  2. The bot hasn't been blocked by Telegram (try sending a test from a different bot)
  3. Network/firewall: Telegram polling needs outbound connectivity to api.telegram.org

Branch C: Never worked (first-time setup)

If the user says the bot never responded:

  1. Follow the full Setup Steps section above
  2. Check that TELEGRAM_BOT_TOKEN is on its own line (not merged with another var)
  3. Verify with curl directly: curl -s "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getMe" — should return {"ok":true,"result":{"id":...,"is_bot":true,"first_name":"...","username":"..."}}
  4. Check TELEGRAM_ALLOWED_USERS — without it, the bot defaults to allowing everyone; if it's set to the wrong numeric ID, the bot ignores your messages
  5. After fixing, restart the gateway
  6. Wait 5-10 seconds, then send a message to the bot on Telegram

Symptom: "Bot responds to everyone / ignores me"

Check TELEGRAM_ALLOWED_USERS is set to your numeric user ID. Without this, the bot is open to anyone who finds it.

Symptom: "Cron messages don't arrive on Telegram"

  1. Ensure TELEGRAM_HOME_CHANNEL is set to the correct numeric chat ID
  2. The home channel is where cron delivers by default — if you DM'd the bot manually but set the home channel to a group, cron goes to the group, not your DMs

Symptom: "send_message tool says 'No messaging platforms connected' from CLI"

This is expected behavior — the send_message tool only routes through a session that was initiated from that platform. From a CLI session, it cannot discover Telegram even if the gateway has it connected.

Workaround: Call the Telegram Bot API directly:

curl -s -X POST "https://api.telegram.org/bot${TOKEN}/sendMessage" \
  -d "chat_id=${CHAT_ID}" \
  -d "text=Your message"

Symptom: "Can't restart — no systemd service found"

If systemctl --user list-units shows no hermes service, the gateway was started manually (e.g., via hermes gateway run in a background terminal). See the Manual Restart (no systemd service) section in step 4 above.