NousResearch/hermes-agent

Telegram/Slack mention gating and bot filtering

Cluster 15415. Data as of

Nothing open on GitHub. Fix merged in #16379 on 27 Apr 2026. Check it covers your case.

The short answer

0open issues
0open PRs
3items grouped
Known?
Yes. 3 related items grouped here, 1 issue already closed.
Fix event
A fix was merged to main in PR #16379. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this resolved, deciding PR #16379. That is separate from the fix event.
Still open
Nothing open on GitHub.

These issues and PRs address how require_mention rules are enforced in Telegram group chats and Slack group DMs, including slash command handling, bot-originated message filtering, and a proposed TELEGRAM_ALLOW_BOTS configuration option.

Open issues0

No open issues.

Open PRs0

No open pull requests.

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #16379 fix(telegram): accept /cmd@botname from bot menu in groups

    merged to main

    files: gateway/platforms/telegram.py, tests/gateway/test_telegram_group_gating.py

    Show the diff
    • gateway/platforms/telegram.py
      @@ -2353,6 +2353,26 @@ def _iter_sources():
                           user = getattr(entity, "user", None)
                           if user and getattr(user, "id", None) == bot_id:
                               return True
      +                elif entity_type == "bot_command" and expected:
      +                    # Telegram's official group-disambiguation form for slash
      +                    # commands (``/cmd@botname``) is emitted as a single
      +                    # ``bot_command`` entity covering the whole span — there
      +                    # is no accompanying ``mention`` entity. Treat it as a
      +                    # direct address to this bot when the ``@botname`` suffix
      +                    # matches. This is the form Telegram's own command menu
      +                    # autocomplete produces in groups, so dropping it at the
      +                    # mention gate would break /new, /reset, /help, ... for
      +                    # every group that has ``require_mention`` enabled (#15415).
      +                    offset = int(getattr(entity, "offset", -1))
      +                    length = int(getattr(entity, "length", 0))
      +                    if offset < 0 or length <= 0:
      +                        continue
      +                    command_text = source_text[offset:offset + length]
      +                    at_index = command_text.find("@")
      +                    if at_index < 0:
      +                        continue
      +                    if command_text[at_index:].strip().lower() == expected:
      +                        return True
               return False
       
           def _message_matches_mention_patterns(self, message: Message) -> bool:
    • tests/gateway/test_telegram_group_gating.py
      @@ -59,6 +59,17 @@ def _mention_entity(text, mention="@hermes_bot"):
           return SimpleNamespace(type="mention", offset=offset, length=len(mention))
       
       
      +def _bot_command_entity(text, command):
      +    """Entity Telegram emits for a ``/cmd`` or ``/cmd@botname`` token.
      +
      +    Telegram parses slash commands server-side. For ``/cmd@botname`` the
      +    client does NOT emit a separate ``mention`` entity — the whole span
      +    is a single ``bot_command`` entity.
      +    """
      +    offset = text.index(command)
      +    return SimpleNamespace(type="bot_command", offset=offset, length=len(command))
      +
      +
       def test_group_messages_can_be_opened_via_config():
           adapter = _make_adapter(require_mention=False)
       
      @@ -73,12 +84,34 @@ def test_group_messages_can_require_direct_trigger_via_config():
           assert adapter._should_process_message(_group_message("replying", reply_to_bot=True)) is True
           # Commands must also respect require_mention when it is enabled
           assert adapter._should_process_message(_group_message("/status"), is_command=True) is False
      -    # But commands with @mention still pass (Telegram emits a MENTION entity
      -    # for /cmd@botname — the bot menu and python-telegram-bot's CommandHandler
      -    # rely on this same mechanism)
      +    # Telegram's group command menu sends ``/cmd@botname`` as a single
      +    # ``bot_command`` entity spanning the whole token (no separate mention
      +    # entity). We must accept it so the menu works when require_mention is on.
           assert adapter._should_process_message(
      -        _group_message("/status@hermes_bot", entities=[_mention_entity("/status@hermes_bot")])
      +        _group_message(
      +            "/status@hermes_bot",
      +            entities=[_bot_command_entity("/status@hermes_bot", "/status@hermes_bot")],
      +        ),
      +        is_command=True,
           ) is True
      +    # A bot_command entity addressed at a different bot must not satisfy
      +    # the mention gate — Telegram groups can host multiple bots that
      +    # register the same command name.
      +    assert adapter._should_process_message(
      +        _group_message(
      +            "/status@other_bot",
      +            entities=[_bot_command_entity("/status@other_bot", "/status@other_bot")],
      +        ),
      +        is_command=True,
      +    ) is False
      +    # Bare ``/status`` (no @botname) must still be dropped in groups with
      +    # require_mention=True — Telegram delivers it only when the bot's
      +    # privacy mode is off, and even then we should not respond unless the
      +    # user explicitly addressed the bot.
      +    assert adapter._should_process_message(
      +        _group_message("/status", entities=[_bot_command_entity("/status", "/status")]),
      +        is_command=True,
      +    ) is False
           # And commands still pass unconditionally when require_mention is disabled
           adapter_no_mention = _make_adapter(require_mention=False)
           assert adapter_no_mention._should_process_message(_group_message("/status"), is_command=True) is True

1 PR closed without merging

From the close comments: merged via another change 1

  • #15417 fix(telegram): accept /cmd@botname from bot menu in groups · merged via another change → 3ff3dfb, #16379, #15415
Closed issues · 1
  • Closed#15415Telegram bot-menu slash commands (`/cmd@botname`) dropped in groups with require_mention=true
How this cluster was grouped
  • Link evidence (structural links throughout): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
  • Pairwise link density 0.67: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. 1.00 means every pair is linked.

Pick up a Lab task

Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.

Open the Lab

At a glance

Merged PRs
#16379
Closed issues
1
Attempts
1 PR closed without merging
Fix link checked
27 Apr 2026. This confirmation is old and may be out of date (a revert or reopen would not have invalidated it here); re-verify.

For your agent

The same facts, typed.