# NousResearch/hermes-agent · Telegram ignored threads config feature request

## Open now

- Nothing open on GitHub.

These items all concern adding an \`ignored_threads\` configuration option to the Telegram gateway for filtering specific topics or threads. The group includes a feature request and related implementation pull requests.

## TL;DR

- 3 member(s): 0 open issue(s), 1 closed issue(s), 0 open PR(s), 1 merged PR(s), 1 PR(s) closed without merging.
- A fix was merged to main in PR #9530. Verify it addresses your case.
- **Recommended:** read PR #9530 (and any competing PRs below) before filing. Confirm the merged change covers your symptom.

## Maintainer resolution verdict

- Internal-tracker verdict over this cluster's issue members: `resolved` · deciding PR(s): `pr-9530`. This is distinct from the fix status above. Weigh it yourself.

## How this cluster was grouped

- Link evidence (`STRUCTURAL_SPANNING`): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
- Pairwise link density `0.67`: the share of member 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.

## Closed / duplicate issues

- #9208: \[Feature\]: ignored_threads config for Telegram topic filtering

## Prior & competing PRs

- **#9530: feat(gateway): add ignored_threads config for Telegram**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`
  - files: `gateway/config.py`, `gateway/platforms/telegram.py`, `tests/gateway/test_telegram_group_gating.py`
  - fix hunks:
  - `gateway/config.py`

    ```diff
    @@ -625,6 +625,11 @@ def load_gateway_config() -> GatewayConfig:
                         if isinstance(frc, list):
                             frc = ",".join(str(v) for v in frc)
                         os.environ["TELEGRAM_FREE_RESPONSE_CHATS"] = str(frc)
    +                ignored_threads = telegram_cfg.get("ignored_threads")
    +                if ignored_threads is not None and not os.getenv("TELEGRAM_IGNORED_THREADS"):
    +                    if isinstance(ignored_threads, list):
    +                        ignored_threads = ",".join(str(v) for v in ignored_threads)
    +                    os.environ["TELEGRAM_IGNORED_THREADS"] = str(ignored_threads)
                     if "reactions" in telegram_cfg and not os.getenv("TELEGRAM_REACTIONS"):
                         os.environ["TELEGRAM_REACTIONS"] = str(telegram_cfg["reactions"]).lower()
     
    ```
  - `gateway/platforms/telegram.py`

    ```diff
    @@ -1991,6 +1991,27 @@ def _telegram_free_response_chats(self) -> set[str]:
                 return {str(part).strip() for part in raw if str(part).strip()}
             return {part.strip() for part in str(raw).split(",") if part.strip()}
     
    +    def _telegram_ignored_threads(self) -> set[int]:
    +        raw = self.config.extra.get("ignored_threads")
    +        if raw is None:
    +            raw = os.getenv("TELEGRAM_IGNORED_THREADS", "")
    +
    +        if isinstance(raw, list):
    +            values = raw
    +        else:
    +            values = str(raw).split(",")
    +
    +        ignored: set[int] = set()
    +        for value in values:
    +            text = str(value).strip()
    +            if not text:
    +                continue
    +            try:
    +                ignored.add(int(text))
    +            except (TypeError, ValueError):
    +                logger.warning("[%s] Ignoring invalid Telegram thread id: %r", self.name, value)
    +        return ignored
    +
         def _compile_mention_patterns(self) -> List[re.Pattern]:
             """Compile optional regex wake-word patterns for group triggers."""
             patterns = self.config.extra.get("mention_patterns")
    ```

    ```diff
    @@ -2102,6 +2123,13 @@ def _should_process_message(self, message: Message, *, is_command: bool = False)
             """
             if not self._is_group_chat(message):
                 return True
    +        thread_id = getattr(message, "message_thread_id", None)
    +        if thread_id is not None:
    +            try:
    +                if int(thread_id) in self._telegram_ignored_threads():
    +                    return False
    +            except (TypeError, ValueError):
    +                logger.warning("[%s] Ignoring non-numeric Telegram message_thread_id: %r", self.name, thread_id)
             if str(getattr(getattr(message, "chat", None), "id", "")) in self._telegram_free_response_chats():
                 return True
             if not self._telegram_require_mention():
    ```
  - `tests/gateway/test_telegram_group_gating.py`

    ```diff
    @@ -5,7 +5,7 @@
     from gateway.config import Platform, PlatformConfig, load_gateway_config
     
     
    -def _make_adapter(require_mention=None, free_response_chats=None, mention_patterns=None):
    +def _make_adapter(require_mention=None, free_response_chats=None, mention_patterns=None, ignored_threads=None):
         from gateway.platforms.telegram import TelegramAdapter
     
         extra = {}
    ```

    ```diff
    @@ -15,6 +15,8 @@ def _make_adapter(require_mention=None, free_response_chats=None, mention_patter
             extra["free_response_chats"] = free_response_chats
         if mention_patterns is not None:
             extra["mention_patterns"] = mention_patterns
    +    if ignored_threads is not None:
    +        extra["ignored_threads"] = ignored_threads
     
         adapter = object.__new__(TelegramAdapter)
         adapter.platform = Platform.TELEGRAM
    ```

    ```diff
    @@ -28,7 +30,16 @@ def _make_adapter(require_mention=None, free_response_chats=None, mention_patter
         return adapter
     
     
    -def _group_message(text="hello", *, chat_id=-100, reply_to_bot=False, entities=None, caption=None, caption_entities=None):
    +def _group_message(
    +    text="hello",
    +    *,
    +    chat_id=-100,
    +    thread_id=None,
    +    reply_to_bot=False,
    +    entities=None,
    +    caption=None,
    +    caption_entities=None,
    +):
         reply_to_message = None
         if reply_to_bot:
             reply_to_message = SimpleNamespace(from_user=SimpleNamespace(id=999))
    ```

    ```diff
    @@ -37,6 +48,7 @@ def _group_message(text="hello", *, chat_id=-100, reply_to_bot=False, entities=N
             caption=caption,
             entities=entities or [],
             caption_entities=caption_entities or [],
    +        message_thread_id=thread_id,
             chat=SimpleNamespace(id=chat_id, type="group"),
             reply_to_message=reply_to_message,
         )
    ```

    ```diff
    @@ -69,6 +81,14 @@ def test_free_response_chats_bypass_mention_requirement():
         assert adapter._should_process_message(_group_message("hello everyone", chat_id=-201)) is False
     
     
    +def test_ignored_threads_drop_group_messages_before_other_gates():
    +    adapter = _make_adapter(require_mention=False, free_response_chats=["-200"], ignored_threads=[31, "42"])
    +
    +    assert adapter._should_process_message(_group_message("hello everyone", chat_id=-200, thread_id=31)) is False
    +    assert adapter._should_process_message(_group_message("hello everyone", chat_id=-200, thread_id=42)) is False
    +    assert adapter._should_process_message(_group_message("hello everyone", chat_id=-200, thread_id=99)) is True
    +
    +
     def test_regex_mention_patterns_allow_custom_wake_words():
         adapter = _make_adapter(require_mention=True, mention_patterns=[r"^\s*chompy\b"])
     
    ```

    ```diff
    @@ -108,3 +128,23 @@ def test_config_bridges_telegram_group_settings(monkeypatch, tmp_path):
         assert __import__("os").environ["TELEGRAM_REQUIRE_MENTION"] == "true"
         assert json.loads(__import__("os").environ["TELEGRAM_MENTION_PATTERNS"]) == [r"^\s*chompy\b"]
         assert __import__("os").environ["TELEGRAM_FREE_RESPONSE_CHATS"] == "-123"
    +
    +
    +def test_config_bridges_telegram_ignored_threads(monkeypatch, tmp_path):
    +    hermes_home = tmp_path / ".hermes"
    +    hermes_home.mkdir()
    +    (hermes_home / "config.yaml").write_text(
    +        "telegram:\n"
    +        "  ignored_threads:\n"
    +        "    - 31\n"
    +        "    - \"42\"\n",
    +        encoding="utf-8",
    +    )
    +
    +    monkeypatch.setenv("HERMES_HOME", str(hermes_home))
    +    monkeypatch.delenv("TELEGRAM_IGNORED_THREADS", raising=False)
    +
    +    config = load_gateway_config()
    +
    +    assert config is not None
    +    assert __import__("os").environ["TELEGRAM_IGNORED_THREADS"] == "31,42"
    ```
- **#9348: feat(gateway): add ignored_threads config for Telegram**. closed without merge
  - maintainer direction: category `merged_via`; implication `superseded`; refs `#9530`

## Fix status

- Merged to main in PR #9530 (cited above). No release data is tracked. Verify downstream.
- Fix last verified (merged) `2026-04-14`. This confirmation is old and may be out of date (a revert/reopen would not have invalidated it here); re-verify.
