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 # ------------------------------------------------------------------