Skip to content

[Feature] Add TELEGRAM_ALLOWED_CHATS — group whitelist restriction for Telegram bots #4526

Description

@Akah-dev

Problem

Currently there is no way to restrict a Telegram bot to only respond in specific groups. The existing settings are:

  • TELEGRAM_REQUIRE_MENTION=true -- bot only responds when @mentioned, but it responds in any group
  • TELEGRAM_FREE_RESPONSE_CHATS -- groups where bot responds without mention, but does NOT block other groups
  • TELEGRAM_DISABLE_DM -- blocks DMs, but does not affect groups

Use case: A CS bot that should ONLY work in the company group. If someone adds the bot to another group and @mentions it, it still responds -- which is undesired.

Proposed Solution

Add a new env var TELEGRAM_ALLOWED_CHATS (comma-separated chat IDs). When set, the bot silently ignores ALL group messages from non-whitelisted groups -- even @mentions, replies, and commands.

  • If empty/unset = current behavior (all groups allowed, backward compatible)
  • If set = ONLY respond in listed groups

Implementation

1. Add helper method to TelegramAdapter (gateway/platforms/telegram.py)

Add this method before _should_process_message:

def _telegram_allowed_chats(self) -> set[str]:
    """Return the set of chat IDs where the bot is allowed to respond in groups.

    Controlled via TELEGRAM_ALLOWED_CHATS env var (comma-separated chat IDs).
    If empty/unset, all groups are allowed (no restriction).
    """
    raw = os.getenv("TELEGRAM_ALLOWED_CHATS", "").strip()
    if not raw:
        return set()  # empty = no restriction
    return {part.strip() for part in raw.split(",") if part.strip()}

2. Add whitelist check inside _should_process_message

Right after the DM handling block (after return True for DMs), before the existing free_response_chats check:

# Whitelist check: if ALLOWED_CHATS is set, reject messages from other groups
allowed = self._telegram_allowed_chats()
if allowed:
    chat_id = str(getattr(getattr(message, "chat", None), "id", ""))
    if chat_id not in allowed:
        return False

Full modified _should_process_message:

def _should_process_message(self, message: Message, *, is_command: bool = False) -> bool:
    """Apply Telegram group trigger rules.

    DMs remain unrestricted. Group/supergroup messages are accepted when:
    - the chat is explicitly allowlisted in ``free_response_chats``
    - ``require_mention`` is disabled
    - the message is a command
    - the message replies to the bot
    - the bot is @mentioned
    - the text/caption matches a configured regex wake-word pattern

    If TELEGRAM_ALLOWED_CHATS is set, the bot will ONLY respond in those
    groups -- all other groups are silently ignored.
    """
    if not self._is_group_chat(message):
        if os.getenv("TELEGRAM_DISABLE_DM", "").lower() in ("true", "1", "yes"):
            return False
        return True
    # Whitelist check: if ALLOWED_CHATS is set, reject messages from other groups
    allowed = self._telegram_allowed_chats()
    if allowed:
        chat_id = str(getattr(getattr(message, "chat", None), "id", ""))
        if chat_id not in allowed:
            return False
    if str(getattr(getattr(message, "chat", None), "id", "")) in self._telegram_free_response_chats():
        return True
    if not self._telegram_require_mention():
        return True
    if is_command:
        return True
    if self._is_reply_to_bot(message):
        return True
    if self._message_mentions_bot(message):
        return True
    return self._message_matches_mention_patterns(message)

Usage

# Bot only responds in these groups (comma-separated chat IDs)
# Leave empty/unset to allow all groups (default behavior)
TELEGRAM_ALLOWED_CHATS=-1001234567890,-1009876543210

Benefits

  • Backward compatible -- empty/unset = current behavior
  • Zero config needed for users who don't need it
  • Consistent with existing env var patterns (FREE_RESPONSE_CHATS, DISABLE_DM, etc.)
  • Simple -- just one env var, no config.yaml changes required

Related

Similar to how TELEGRAM_DISABLE_DM blocks DMs, this blocks non-whitelisted groups.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low — cosmetic, nice to haveplatform/telegramTelegram bot adaptersweeper:implemented-on-mainSweeper: behavior already present on current maintype/featureNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions