From 1773e3d647915deb4e225d19693ef88ddc7fb752 Mon Sep 17 00:00:00 2001 From: Mibayy Date: Thu, 9 Apr 2026 13:35:13 -0700 Subject: [PATCH] feat(slack): add allow_bots config for bot-to-bot communication Three modes: "none" (default, backward-compatible), "mentions" (accept bot messages only when they @mention us), "all" (accept all bot messages except our own, to prevent echo loops). Configurable via: slack: allow_bots: mentions Or env var: SLACK_ALLOW_BOTS=mentions Self-message guard always active regardless of mode. Based on PR #3200 by Mibayy, adapted to current main with config.yaml bridging support. --- gateway/config.py | 2 ++ gateway/platforms/slack.py | 21 +++++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/gateway/config.py b/gateway/config.py index 47b779eb8e..a50c9331ca 100644 --- a/gateway/config.py +++ b/gateway/config.py @@ -553,6 +553,8 @@ def load_gateway_config() -> GatewayConfig: if isinstance(slack_cfg, dict): if "require_mention" in slack_cfg and not os.getenv("SLACK_REQUIRE_MENTION"): os.environ["SLACK_REQUIRE_MENTION"] = str(slack_cfg["require_mention"]).lower() + if "allow_bots" in slack_cfg and not os.getenv("SLACK_ALLOW_BOTS"): + os.environ["SLACK_ALLOW_BOTS"] = str(slack_cfg["allow_bots"]).lower() frc = slack_cfg.get("free_response_channels") if frc is not None and not os.getenv("SLACK_FREE_RESPONSE_CHANNELS"): if isinstance(frc, list): diff --git a/gateway/platforms/slack.py b/gateway/platforms/slack.py index d2f5090721..825cc2511c 100644 --- a/gateway/platforms/slack.py +++ b/gateway/platforms/slack.py @@ -941,9 +941,26 @@ class SlackAdapter(BasePlatformAdapter): if v > cutoff } - # Ignore bot messages (including our own) + # Bot message filtering (SLACK_ALLOW_BOTS / config allow_bots): + # "none" — ignore all bot messages (default, backward-compatible) + # "mentions" — accept bot messages only when they @mention us + # "all" — accept all bot messages (except our own) if event.get("bot_id") or event.get("subtype") == "bot_message": - return + allow_bots = self.config.extra.get("allow_bots", "") + if not allow_bots: + allow_bots = os.getenv("SLACK_ALLOW_BOTS", "none") + allow_bots = str(allow_bots).lower().strip() + if allow_bots == "none": + return + elif allow_bots == "mentions": + text_check = event.get("text", "") + if self._bot_user_id and f"<@{self._bot_user_id}>" not in text_check: + return + # "all" falls through to process the message + # Always ignore our own messages to prevent echo loops + msg_user = event.get("user", "") + if msg_user and self._bot_user_id and msg_user == self._bot_user_id: + return # Ignore message edits and deletions subtype = event.get("subtype")