diff --git a/matrix_keycloak_bot.py b/matrix_keycloak_bot.py index 43977f5..1de8be4 100644 --- a/matrix_keycloak_bot.py +++ b/matrix_keycloak_bot.py @@ -9,7 +9,8 @@ from nio import ( RoomMessageText, ReactionEvent, RoomSendResponse, - InviteMemberEvent + InviteMemberEvent, + OlmUnverifiedDeviceError ) # ------------------------------------------------------------------------------ @@ -110,7 +111,7 @@ async def on_message(client: AsyncClient, room: MatrixRoom, event: RoomMessageTe parts = body.split(maxsplit=1) if len(parts) < 2: - await client.room_send( + await send_message_safe( room_id=room.room_id, message_type="m.room.message", content={"msgtype": "m.notice", "body": "Usage: !request "}, @@ -130,9 +131,9 @@ async def on_message(client: AsyncClient, room: MatrixRoom, event: RoomMessageTe f"React with 👍 to **Approve** or 👎 to **Deny**." ) - res = await client.room_send( + res = await send_message_safe( + client, room_id=ADMIN_ROOM_ID, - message_type="m.room.message", content={ "msgtype": "m.text", "body": admin_msg_body, @@ -151,15 +152,32 @@ async def on_message(client: AsyncClient, room: MatrixRoom, event: RoomMessageTe } # Confirm request receipt to the user - await client.room_send( + await send_message_safe( + client, room_id=room.room_id, - message_type="m.room.message", content={ "msgtype": "m.notice", "body": f"Request for group '{requested_group}' submitted for admin approval.", }, ) +async def send_message_safe( + client: AsyncClient, + room_id: str, + content: dict, + message_type: str = "m.room.message" +): + """Sends a message to a room, automatically trusting any unverified devices if an OlmUnverifiedDeviceError occurs.""" + while True: + try: + return await client.room_send( + room_id=room_id, + message_type=message_type, + content=content, + ) + except OlmUnverifiedDeviceError as e: + print(f"Auto-trusting unverified device '{e.device.device_id}' for user '{e.device.user_id}'...") + client.verify_device(e.device) async def on_reaction(client: AsyncClient, room: MatrixRoom, event: ReactionEvent): """Listens for reaction approvals/denials in the admin room.""" @@ -197,7 +215,7 @@ async def on_reaction(client: AsyncClient, room: MatrixRoom, event: ReactionEven f"🎉 Your request for access to group '{request['requested_group']}' " f"has been approved!" if success else f"⚠️ Approval failed: {msg}" ) - await client.room_send( + await send_message_safe( room_id=request["origin_room_id"], message_type="m.room.message", content={"msgtype": "m.notice", "body": user_msg}, @@ -209,7 +227,7 @@ async def on_reaction(client: AsyncClient, room: MatrixRoom, event: ReactionEven f"**User:** `{request['matrix_user']}` → **Group:** `{request['requested_group']}`" ) - await client.room_send( + await send_message_safe( room_id=request["origin_room_id"], message_type="m.room.message", content={ @@ -221,7 +239,7 @@ async def on_reaction(client: AsyncClient, room: MatrixRoom, event: ReactionEven return # Ignore other reactions # Update the original admin room message to reflect resolution status - await client.room_send( + await send_message_safe( room_id=ADMIN_ROOM_ID, message_type="m.room.message", content={