diff options
author | ben <ben@nagy.contact> | 2025-05-19 11:46:37 -0700 |
---|---|---|
committer | ben <ben@nagy.contact> | 2025-05-19 11:46:37 -0700 |
commit | e7efe8c2e4aeb5adb3b967677b2d51ff1bc57f72 (patch) | |
tree | 81c88eccc9394b4c51ba941ce4af9bc212b029d8 | |
parent | 5d2f60e14bff742b34d55e9335aeff1e86b1f224 (diff) |
Added room redaction
-rw-r--r-- | matrix-redact.py | 80 |
1 files changed, 72 insertions, 8 deletions
diff --git a/matrix-redact.py b/matrix-redact.py index 788ce7d..e355cca 100644 --- a/matrix-redact.py +++ b/matrix-redact.py @@ -16,6 +16,10 @@ from nio import( MatrixRoom, LoginResponse, RoomInfo, + MessageDirection, + RedactedEvent, + RoomMessagesError, + RoomRedactError, responses ) from typing import Optional @@ -51,10 +55,71 @@ async def client_login() -> Optional[AsyncClient]: print("login was successful, returning client.") return client -# TODO: redact_room -async def redact_room() -> None: - # TODO: ensure user is 100% sure (verify correct room, etc.). This is a permanent action - return None +async def redact_room(client: AsyncClient, room: MatrixRoom) -> None: + print(f"\nAll events sent by '{client.user_id}' in " + + f"'{room['room_id']}' ({room['display_name']}) will be deleted.") + if not input("\n\nIs this room correct? (Type 'Continue') to proceed: ") == "Continue": + return None + + sync_resp = await client.sync(timeout=30000, full_state=True) + start_token = sync_resp.rooms.join[room['room_id']].timeline.prev_batch + current_token = start_token + + # BUG: This loops if messages are already redacted. + # NOTE: I wonder if we need to continuously sync? So perhaps it is necessary that we modularize fetching room events + +# TODO: if response = 429 (ratelimited), should pausae. + events_redacted = 0 + while True: + try: + print(f"getting messages in {room['room_id']}") + resp = await client.room_messages( + room['room_id'], + current_token, + limit=500, + direction=MessageDirection.back, + ) + except Exception as e: + print(f"could not get room message: {e}") + break + if isinstance(resp, RoomMessagesError): + print(f"Could not get room message: {resp}") + break + current_token = resp.end + if len(resp.chunk) == 0: + print("no more messages to fetch.") + break + + for event in resp.chunk: + if event.sender == client.user_id: + event_id = event.event_id + try: + redact_resp = await client.room_redact( + room['room_id'], + event_id, + reason="test test test" + ) + + if isinstance(redact_resp, RoomRedactError): + print(f"Could not redact event {event_id} in {room['room_id']}.") + else: + print(f"Successfuly redacted event {event_id} in {room['room_id']}.") + events_redacted += 1 + await asyncio.sleep(5) + except Exception as e: + print(f"Error redacting event {event_id}: {e}") + + if events_redacted: + print(f"Total messages redacted: {events_redacted}") + else: + print("could not redact any messages.") + + # NOTE: need to ensure event belongs to correct user ID (ie. client.user_id) + + # https://github.com/8go/matrix-commander/blob/master/matrix_commander/matrix_commander.py#L6241 + # https://github.com/8go/matrix-commander/blob/master/matrix_commander/matrix_commander.py#L4314 + # https://github.com/8go/matrix-commander/blob/master/matrix_commander/matrix_commander.py#L4402 + # https://github.com/8go/matrix-commander/blob/master/matrix_commander/matrix_commander.py#L4188f async def main(args) -> None: print("\n" + "="*80) @@ -67,7 +132,7 @@ async def main(args) -> None: - Operate *irreversibly* on the room ID you provide - Act as the logged-in user on the specified homeserver - THIS ACTION CANNOT BE UNDONE. + THIS ACTION IS DESTRUCTIVE AND CANNOT BE UNDONE. Make absolutely sure you understand what this program does before proceeding. We take zero liability for any misuse of this program. @@ -88,7 +153,6 @@ async def main(args) -> None: sys.exit(1) client = None - try: client = await client_login() if not client: @@ -98,8 +162,8 @@ async def main(args) -> None: sync_resp = await client.sync(timeout=30000, full_state=True) room = await select_room(client, sync_resp) - if not room: - sys.exit(1) + if room: + await redact_room(client, room) except Exception as e: print(f"Error: {e}") |