From b1bef9024f4ff76f224bcaa0d7874260fb086131 Mon Sep 17 00:00:00 2001 From: "Abiba (pi)" Date: Sat, 27 Jun 2026 05:51:12 +0000 Subject: [PATCH] fix(zulip): resolve bot user_id from /users/me for @mention detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The /register endpoint doesn't always return user_id on all Zulip server versions. Added _resolve_bot_user_id() that queries the /users/me endpoint as a fallback. This ensures @mention detection (is_direct_mention check) works even when register doesn't provide it. Also bumped to v1.0.3 — cumulative fixes since v1.0.1: - v1.0.2: BAD_EVENT_QUEUE_ID detection (silent queue expiry) - v1.0.3: bot user_id resolution (@mention detection) --- plugins/platforms/zulip/adapter.py | 31 ++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/plugins/platforms/zulip/adapter.py b/plugins/platforms/zulip/adapter.py index 13e50a6..66b5a29 100644 --- a/plugins/platforms/zulip/adapter.py +++ b/plugins/platforms/zulip/adapter.py @@ -259,6 +259,11 @@ class ZulipAdapter(BasePlatformAdapter): self._last_event_id = data.get("last_event_id", -1) self._bot_user_id = data.get("user_id") + # Resolve bot user_id if register endpoint didn't provide it + # (common on some Zulip versions) + if self._bot_user_id is None: + await self._resolve_bot_user_id() + # Gen 2: Try to resolve @all-bots user ID dynamically await self._resolve_all_bots_user_id() @@ -503,6 +508,32 @@ class ZulipAdapter(BasePlatformAdapter): "[%s] @all-bots refresh error (non-fatal)", self.name ) + # ------------------------------------------------------------------ + # Gen 5: Bot user ID resolution + # ------------------------------------------------------------------ + + async def _resolve_bot_user_id(self) -> None: + """Fetch the bot's own user ID from /api/v1/users/me. + + The /register endpoint does not always return user_id on + all Zulip server versions. This ensures @mention detection + works by resolving it from the identity endpoint. + """ + try: + resp, _ = await self._api_call("GET", "/api/v1/users/me") + if resp: + uid = resp.get("user_id") + if uid is not None: + self._bot_user_id = int(uid) + logger.info( + "[%s] Resolved bot user_id=%s from /users/me", + self.name, uid, + ) + except Exception as e: + logger.debug( + "[%s] Could not resolve bot user_id: %s", self.name, e + ) + # ------------------------------------------------------------------ # Gen 2: Dynamic @all-bots resolution # ------------------------------------------------------------------