hermes - 💡(How to fix) Fix [Bug]: Telegram adapter never sets `source.is_bot` — bot messages bypass auth filter and trigger agent loop [1 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

Additional Logs / Traceback (optional)

Root Cause

Root Cause Analysis (optional)

Fix Action

Fixed

Code Example

Report       https://paste.rs/77ep3
  agent.log    https://paste.rs/KN8RP
  gateway.log  https://paste.rs/ZulL7

---



---

if getattr(source, "is_bot", False):
    allow_bots_var = platform_allow_bots_map.get(source.platform)
    if allow_bots_var and os.getenv(allow_bots_var, "none").lower().strip() in {"mentions", "all"}:
        return True

---

is_bot=getattr(user, "is_bot", False)

---

Platform.TELEGRAM: "TELEGRAM_ALLOW_BOTS",
RAW_BUFFERClick to expand / collapse

Bug Description

When running two Hermes profiles on the same machine with separate Telegram bot tokens, any message sent by one bot is received by the other gateway's polling loop and treated as an authorized inbound message. The second gateway then responds to it, causing duplicate/echo notifications.

This affects any setup where one Hermes profile sends Telegram messages programmatically (via hermes send, direct Bot API calls, or cron scripts) while a second Hermes profile is running on the same account.

Steps to Reproduce

  1. Set up two Hermes profiles on the same machine, each with a different Telegram bot token (e.g. default profile = @xyz_bot, grok profile = @grokxyz_bot)
  2. Start both gateways: hermes gateway start and hermes -p grok gateway start
  3. From any script, send a Telegram message via the default profile's bot token using the direct Bot API or hermes send
  4. Observe that the grok gateway receives the message and responds to it

Expected Behavior

Messages sent by a bot (is_bot=True in python-telegram-bot's User object) should be identified as bot-originated and filtered out by _is_user_authorized(). The second gateway should silently ignore messages whose sender is a bot, the same way Discord and Feishu handle this via their ALLOW_BOTS env vars.

Actual Behavior

The second gateway receives the bot message and processes it as if it were from an authorized human user. The agent loop fires and sends a response to the Telegram chat, resulting in duplicate messages — one from the intended bot, one echo from the second gateway.

Affected Component

Gateway (Telegram/Discord/Slack/WhatsApp)

Messaging Platform (if gateway-related)

Telegram

Debug Report

Report       https://paste.rs/77ep3
  agent.log    https://paste.rs/KN8RP
  gateway.log  https://paste.rs/ZulL7

Operating System

macOS 26.5

Python Version

3.9.6

Hermes Version

Hermes Agent v0.14.0 (2026.5.16)

Additional Logs / Traceback (optional)

Root Cause Analysis (optional)

_is_user_authorized() in gateway/run.py (line ~6370) has correct bot-filtering logic:

if getattr(source, "is_bot", False):
    allow_bots_var = platform_allow_bots_map.get(source.platform)
    if allow_bots_var and os.getenv(allow_bots_var, "none").lower().strip() in {"mentions", "all"}:
        return True

However, platform_allow_bots_map has entries for Discord and Feishu only — Telegram is missing.

More critically, gateway/platforms/telegram.py never sets is_bot on the source object when building a MessageEvent. The python-telegram-bot user.is_bot attribute is available and accurate, but it is never passed to build_source(). So getattr(source, "is_bot", False) always returns False for Telegram regardless of the actual sender type, and bot messages pass authorization as if they were from a human user.

Proposed Fix (optional)

Two changes needed:

  1. In gateway/platforms/telegram.py, where build_source() is called when processing inbound messages (around line 5568), add:
is_bot=getattr(user, "is_bot", False)
  1. In gateway/run.py, add Telegram to platform_allow_bots_map:
Platform.TELEGRAM: "TELEGRAM_ALLOW_BOTS",

This gives operators the same control as Discord/Feishu — TELEGRAM_ALLOW_BOTS=none (default) silently drops bot messages, mentions allows them only when the bot is @mentioned, all allows all bot messages. Fully backward compatible — existing single-bot setups are unaffected.

Are you willing to submit a PR for this?

  • I'd like to fix this myself and submit a PR

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING