diff --git a/gateway/config.py b/gateway/config.py index e4f04d891..98b191805 100644 --- a/gateway/config.py +++ b/gateway/config.py @@ -581,6 +581,12 @@ def load_gateway_config() -> GatewayConfig: if isinstance(ic, list): ic = ",".join(str(v) for v in ic) os.environ["DISCORD_IGNORED_CHANNELS"] = str(ic) + # allowed_channels: if set, bot ONLY responds in these channels (whitelist) + ac = discord_cfg.get("allowed_channels") + if ac is not None and not os.getenv("DISCORD_ALLOWED_CHANNELS"): + if isinstance(ac, list): + ac = ",".join(str(v) for v in ac) + os.environ["DISCORD_ALLOWED_CHANNELS"] = str(ac) # no_thread_channels: channels where bot responds directly without creating thread ntc = discord_cfg.get("no_thread_channels") if ntc is not None and not os.getenv("DISCORD_NO_THREAD_CHANNELS"): diff --git a/gateway/platforms/discord.py b/gateway/platforms/discord.py index 74aaa75a4..0e51fc75e 100644 --- a/gateway/platforms/discord.py +++ b/gateway/platforms/discord.py @@ -2234,6 +2234,7 @@ class DiscordAdapter(BasePlatformAdapter): # discord.require_mention: Require @mention in server channels (default: true) # discord.free_response_channels: Channel IDs where bot responds without mention # discord.ignored_channels: Channel IDs where bot NEVER responds (even when mentioned) + # discord.allowed_channels: If set, bot ONLY responds in these channels (whitelist) # discord.no_thread_channels: Channel IDs where bot responds directly without creating thread # discord.auto_thread: Auto-create thread on @mention in channels (default: true) @@ -2245,12 +2246,21 @@ class DiscordAdapter(BasePlatformAdapter): parent_channel_id = self._get_parent_channel_id(message.channel) if not isinstance(message.channel, discord.DMChannel): - # Check ignored channels first - never respond even when mentioned - ignored_channels_raw = os.getenv("DISCORD_IGNORED_CHANNELS", "") - ignored_channels = {ch.strip() for ch in ignored_channels_raw.split(",") if ch.strip()} channel_ids = {str(message.channel.id)} if parent_channel_id: channel_ids.add(parent_channel_id) + + # Check allowed channels - if set, only respond in these channels + allowed_channels_raw = os.getenv("DISCORD_ALLOWED_CHANNELS", "") + if allowed_channels_raw: + allowed_channels = {ch.strip() for ch in allowed_channels_raw.split(",") if ch.strip()} + if not (channel_ids & allowed_channels): + logger.debug("[%s] Ignoring message in non-allowed channel: %s", self.name, channel_ids) + return + + # Check ignored channels - never respond even when mentioned + ignored_channels_raw = os.getenv("DISCORD_IGNORED_CHANNELS", "") + ignored_channels = {ch.strip() for ch in ignored_channels_raw.split(",") if ch.strip()} if channel_ids & ignored_channels: logger.debug("[%s] Ignoring message in ignored channel: %s", self.name, channel_ids) return diff --git a/hermes_cli/config.py b/hermes_cli/config.py index a54d07562..93aa1cc0c 100644 --- a/hermes_cli/config.py +++ b/hermes_cli/config.py @@ -552,6 +552,7 @@ DEFAULT_CONFIG = { "discord": { "require_mention": True, # Require @mention to respond in server channels "free_response_channels": "", # Comma-separated channel IDs where bot responds without mention + "allowed_channels": "", # If set, bot ONLY responds in these channel IDs (whitelist) "auto_thread": True, # Auto-create threads on @mention in channels (like Slack) "reactions": True, # Add 👀/✅/❌ reactions to messages during processing },