feat: implement room state retrieval and

conditional avatar update

Introduces a new method `get_state_event` to asynchronously retrieve
state events for a given room and event type, enhancing the bot's
ability to fetch specific room states before performing actions. This
functionality is leveraged to conditionally update room avatars only if
they are not already set, reducing unnecessary updates and improving
efficiency. Additionally, the commit includes minor formatting
adjustments for better code readability.

Refactoring the avatar updating process to assess the current state
before action prevents redundant network calls and aligns with optimal
resource usage practices, contributing to a smoother operation and
potentially reducing the workload on the server.
This commit is contained in:
Kumi 2024-04-01 07:42:44 +02:00
parent d5a96aebb6
commit a9c23ee9c4
Signed by: kumi
GPG key ID: ECBCC9082395383F

View file

@ -34,6 +34,7 @@ from nio import (
DownloadResponse, DownloadResponse,
ToDeviceEvent, ToDeviceEvent,
ToDeviceError, ToDeviceError,
RoomGetStateError,
) )
from nio.store import SqliteStore from nio.store import SqliteStore
@ -329,7 +330,9 @@ class GPTBot:
elif isinstance(event, RoomMessageText): elif isinstance(event, RoomMessageText):
if event.body.split() == ["!gptbot", "ignoreolder"]: if event.body.split() == ["!gptbot", "ignoreolder"]:
break break
if (not event.body.startswith("!")) or (event.body.split()[1] == "custom"): if (not event.body.startswith("!")) or (
event.body.split()[1] == "custom"
):
messages.append(event) messages.append(event)
elif isinstance(event, RoomMessageNotice): elif isinstance(event, RoomMessageNotice):
@ -812,6 +815,22 @@ class GPTBot:
(message, room, tokens, api, datetime.now()), (message, room, tokens, api, datetime.now()),
) )
async def get_state_event(
self, room: MatrixRoom | str, event_type: str, state_key: Optional[str] = None
):
if isinstance(room, MatrixRoom):
room = room.room_id
state = await self.matrix_client.room_get_state(room)
if isinstance(state, RoomGetStateError):
self.logger.log(f"Could not get state for room {room}")
for event in state.events:
if event["type"] == event_type:
if state_key is None or event["state_key"] == state_key:
return event
async def run(self): async def run(self):
"""Start the bot.""" """Start the bot."""
@ -890,12 +909,14 @@ class GPTBot:
asyncio.create_task(self.matrix_client.set_avatar(uri)) asyncio.create_task(self.matrix_client.set_avatar(uri))
for room in self.matrix_client.rooms.keys(): for room in self.matrix_client.rooms.keys():
self.logger.log(f"Setting avatar for {room}...", "debug") room_avatar = await self.get_state_event(room, "m.room.avatar")
asyncio.create_task( if not room_avatar:
self.matrix_client.room_put_state( self.logger.log(f"Setting avatar for {room}...", "debug")
room, "m.room.avatar", {"url": uri}, "" asyncio.create_task(
self.matrix_client.room_put_state(
room, "m.room.avatar", {"url": uri}, ""
)
) )
)
# Start syncing events # Start syncing events
self.logger.log("Starting sync loop...", "warning") self.logger.log("Starting sync loop...", "warning")