From 87346e14b8dce8834215d5997d13202b13872b93 Mon Sep 17 00:00:00 2001 From: qbit-mirror-bot Date: Thu, 2 Jul 2026 13:21:38 +0000 Subject: [PATCH] fix(qqbot): add is_reconnect param to QQAdapter.connect() --- gateway/platforms/qqbot/adapter.py | 43 +++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/gateway/platforms/qqbot/adapter.py b/gateway/platforms/qqbot/adapter.py index 9532662131df..e9628700428e 100644 --- a/gateway/platforms/qqbot/adapter.py +++ b/gateway/platforms/qqbot/adapter.py @@ -12,9 +12,9 @@ app_id: "your-app-id" # or QQ_APP_ID env var client_secret: "your-secret" # or QQ_CLIENT_SECRET env var markdown_support: true # enable QQ markdown (msg_type 2) - dm_policy: "open" # open | allowlist | disabled + dm_policy: "pairing" # open | allowlist | disabled | pairing allow_from: ["openid_1"] - group_policy: "open" # open | allowlist | disabled + group_policy: "pairing" # open | allowlist | disabled | pairing group_allow_from: ["group_openid_1"] stt: # Voice-to-text config (optional) provider: "zai" # zai (GLM-ASR), openai (Whisper), etc. @@ -208,11 +208,11 @@ def __init__(self, config: PlatformConfig): self._markdown_support = bool(extra.get("markdown_support", True)) # Auth/ACL policies - self._dm_policy = str(extra.get("dm_policy", "open")).strip().lower() + self._dm_policy = str(extra.get("dm_policy", "pairing")).strip().lower() self._allow_from = _coerce_list( extra.get("allow_from") or extra.get("allowFrom") ) - self._group_policy = str(extra.get("group_policy", "open")).strip().lower() + self._group_policy = str(extra.get("group_policy", "pairing")).strip().lower() self._group_allow_from = _coerce_list( extra.get("group_allow_from") or extra.get("groupAllowFrom") ) @@ -278,7 +278,7 @@ def enforces_own_access_policy(self) -> bool: # Connection lifecycle # ------------------------------------------------------------------ - async def connect(self) -> bool: + async def connect(self, *, is_reconnect: bool = False) -> bool: """Authenticate, obtain gateway URL, and open the WebSocket.""" if not AIOHTTP_AVAILABLE: message = "QQ startup failed: aiohttp not installed" @@ -1214,7 +1214,7 @@ async def _handle_c2c_message( user_openid = str(author.get("user_openid", "")) if not user_openid: return - if not self._is_dm_allowed(user_openid): + if not self._is_dm_intake_allowed(user_openid): return text = content @@ -1454,7 +1454,7 @@ async def _handle_dm_message( # Without this check any member of any guild the bot is in could # bypass the configured allowlist via direct messages. author_id = str(author.get("id", "")) - if not self._is_dm_allowed(author_id): + if not self._is_dm_intake_allowed(author_id): logger.debug( "[%s] Guild DM blocked by ACL: guild=%s user=%s", self._log_tag, guild_id, author_id, @@ -3142,19 +3142,44 @@ def _strip_at_mention(content: str) -> str: stripped = re.sub(r"^@\S+\s*", "", content.strip()) return stripped + def _open_dm_opted_in(self) -> bool: + if os.getenv("GATEWAY_ALLOW_ALL_USERS", "").lower() in {"true", "1", "yes"}: + return True + return os.getenv("QQ_ALLOW_ALL_USERS", "").lower() in {"true", "1", "yes"} + def _is_dm_allowed(self, user_id: str) -> bool: if self._dm_policy == "disabled": return False if self._dm_policy == "allowlist": return self._entry_matches(self._allow_from, user_id) - return True + if self._dm_policy == "open": + return self._open_dm_opted_in() + return False + + def _is_dm_intake_allowed(self, user_id: str) -> bool: + principal = str(user_id or "").strip() + if not principal: + return False + if self._dm_policy == "disabled": + return False + if self._dm_policy == "allowlist": + return self._entry_matches(self._allow_from, principal) + if self._dm_policy == "pairing": + return True + if self._dm_policy == "open": + return self._open_dm_opted_in() + return False def _is_group_allowed(self, group_id: str, user_id: str) -> bool: if self._group_policy == "disabled": return False if self._group_policy == "allowlist": return self._entry_matches(self._group_allow_from, group_id) - return True + if self._group_policy == "pairing": + return False + if self._group_policy == "open": + return True + return False @staticmethod def _entry_matches(entries: List[str], target: str) -> bool: