From 5a1ed5aa1ab1dad06ebf30f43fbbb9b3d335f33d Mon Sep 17 00:00:00 2001 From: Dome Date: Thu, 9 Apr 2026 09:01:06 +0200 Subject: [PATCH] Update bot.py fix: resolve room aliases in setpower and filter unjoined space rooms This commit addresses two issues that caused API errors during room iteration and power level syncing: 1. Filter unjoined rooms in `get_space_roomlist`: Previously, the bot assumed it was a member of all child rooms returned by the parent space state. If the bot was missing from certain child rooms, it threw errors during subsequent operations. The room list is now intersected with `await self.client.get_joined_rooms()` to safely ignore rooms the bot hasn't actually joined yet. Logging has been added to indicate when rooms are skipped. 2. Fix alias resolution (Sigil Bug) in `room_setpower`: The `room_setpower ` command failed when users provided a standard room alias (starting with `#`) instead of an internal room ID (`!`), as the Matrix API expects the internal ID for state event operations. Added logic to detect aliases and explicitly resolve them to their respective `room_id` via `self.client.resolve_room_alias()` before attempting to update power levels. Appropriate error handling was also added to notify the user if the alias cannot be resolved. --- community/bot.py | 78 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 21 deletions(-) diff --git a/community/bot.py b/community/bot.py index 8cef124..8d9ffa3 100644 --- a/community/bot.py +++ b/community/bot.py @@ -430,7 +430,18 @@ class CommunityBot(Plugin): rooms.append(evt.state_key) except Exception as e: self.log.error(f"Error getting space roomlist: {e}") - return rooms + + try: + joined_rooms = await self.client.get_joined_rooms() + filtered_rooms = [r for r in rooms if r in joined_rooms] + + if len(rooms) != len(filtered_rooms): + self.log.info(f"Ignoriere {len(rooms) - len(filtered_rooms)} Räume aus dem Space, da der Bot dort kein Mitglied ist.") + + return filtered_rooms + except Exception as e: + self.log.error(f"Fehler beim Abgleich der joined_rooms: {e}") + return rooms async def generate_report(self) -> None: now = int(time.time() * 1000) @@ -2531,12 +2542,27 @@ class CommunityBot(Plugin): await evt.mark_read() if target_room: - roomlist = [target_room] + if target_room.startswith("#"): + try: + resolved_alias = await self.client.resolve_room_alias(target_room) + roomlist = [resolved_alias.room_id] + except Exception as e: + await evt.respond(f"Fehler: Konnte Alias {target_room} nicht in eine ID auflösen: {e}") + return + elif target_room.startswith("!"): + roomlist = [target_room] + else: + await evt.respond("Fehler: Der Raum muss mit ! (ID) oder # (Alias) beginnen.") + return target_msg = target_room else: roomlist = await self.get_space_roomlist() target_msg = "space rooms" + if not roomlist: + await evt.respond("Fehler: Keine gültigen Räume zum Aktualisieren gefunden. Ist der Bot in den Zielräumen Mitglied?") + return + msg = await evt.respond( f"Syncing power levels from parent room to {target_msg}..." ) @@ -2579,10 +2605,14 @@ class CommunityBot(Plugin): f"Parent room is modern (v{parent_version}), bot is not creator, power level set to 1000" ) else: - # In legacy parent rooms, ensure bot has highest power level - user_power_levels[self.client.mxid] = 1000 + # In legacy parent rooms, keep the bot at its actual current PL (cannot self-promote) + bot_pl = parent_power_levels.users.get( + self.client.mxid, + getattr(parent_power_levels, "users_default", 0), + ) + user_power_levels[self.client.mxid] = bot_pl self.log.info( - f"Parent room is legacy (v{parent_version}), bot power level set to 1000" + f"Parent room is legacy (v{parent_version}), bot power level retained at {bot_pl}" ) for room in roomlist: @@ -2695,20 +2725,15 @@ class CommunityBot(Plugin): else: mapped_power_levels[user] = level - # Handle bot power level based on whether it's a creator in the parent - if self.client.mxid in parent_creators: - # Bot is a creator in parent, but this is a legacy room - # Set bot to highest power level since creators don't have unlimited power in legacy rooms - mapped_power_levels[self.client.mxid] = 1000 - self.log.info( - f"Bot is creator in parent but target is legacy room - setting power level to 1000" - ) - else: - # Bot is not a creator in parent, set to highest power level - mapped_power_levels[self.client.mxid] = 1000 - self.log.info( - f"Bot is not creator in parent, setting power level to 1000 in legacy target room" - ) + # In a legacy target room, keep the bot at its actual current PL (cannot self-promote) + bot_pl = room_power_levels.users.get( + self.client.mxid, + getattr(room_power_levels, "users_default", 0), + ) + mapped_power_levels[self.client.mxid] = bot_pl + self.log.info( + f"Target room is legacy, bot power level retained at {bot_pl} in {roomname or room}" + ) room_power_levels.users = mapped_power_levels @@ -2717,7 +2742,18 @@ class CommunityBot(Plugin): self.log.info( f"Both rooms are legacy - direct power level transfer" ) - room_power_levels.users = user_power_levels + # Capture the bot's current PL in this child room before overwriting. + # This is always the value we use — the bot cannot self-promote above + # its current PL, and we must not demote it if it's higher than the parent. + child_bot_pl = room_power_levels.users.get( + self.client.mxid, + getattr(room_power_levels, "users_default", 0), + ) + room_power_levels.users = user_power_levels.copy() + room_power_levels.users[self.client.mxid] = child_bot_pl + self.log.info( + f"Both rooms legacy: bot PL retained at {child_bot_pl} in {roomname or room}" + ) # Send the updated power levels to this room await self.client.send_state_event( @@ -2751,7 +2787,7 @@ class CommunityBot(Plugin): else: results += f"Mapping Strategy: Parent room is legacy (v{parent_version}), using traditional power level system.
" results += ( - "• Bot power level set to 1000 for administrative control
" + "• Bot power level retained at its current level in legacy rooms
" ) results += "• Direct power level transfer to legacy child rooms
" results += "• Modern child rooms preserve their creator power levels

"