Skip to content

[Bug]: Telegram adapter never sets source.is_bot — bot messages bypass auth filter and trigger agent loop #32188

@AIAlhello

Description

@AIAlhello

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High — major feature broken, no workaroundcomp/gatewayGateway runner, session dispatch, deliveryplatform/telegramTelegram bot adaptertype/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions