From ec4d1a1f502a06fb9ade2b31ac80b77279930e6b Mon Sep 17 00:00:00 2001 From: videogame hacker Date: Thu, 16 Sep 2021 04:29:00 +0100 Subject: [PATCH] Implement bridged message deletions --- .gitmodules | 3 +++ Cargo.lock | 10 ---------- Cargo.toml | 2 +- matrix-rust-sdk | 1 + src/bridgers.rs | 35 ++++++++++++++++++++++++++++++++--- src/discord.rs | 29 ++++++++++++++++++++++++++++- src/main.rs | 6 +++++- src/matrix.rs | 40 ++++++++++++++++++++++++++++++++++------ src/messages.rs | 5 +++++ 9 files changed, 109 insertions(+), 22 deletions(-) create mode 100644 .gitmodules create mode 160000 matrix-rust-sdk diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..5c217c7 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "matrix-rust-sdk"] + path = matrix-rust-sdk + url = https://git.lavender.software/charlotte/matrix-rust-sdk.git diff --git a/Cargo.lock b/Cargo.lock index c810d24..27f5976 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1237,8 +1237,6 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "matrix-qrcode" version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4231739aa2ff90c6c55b07d7179c52b496622a86fc2f7e0431336d109ba7838d" dependencies = [ "base64 0.13.0", "byteorder", @@ -1252,8 +1250,6 @@ dependencies = [ [[package]] name = "matrix-sdk" version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5834b96fef26d6d61c8ffd21dda3569c7c0fc688f9cc8aebd35f6f8c3068a186" dependencies = [ "backoff", "bytes 1.1.0", @@ -1280,8 +1276,6 @@ dependencies = [ [[package]] name = "matrix-sdk-base" version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97c4d675ff70395c1b0cd94fae869cea4efd3f148b74bf4186e969ee622a9c7" dependencies = [ "chacha20poly1305", "dashmap", @@ -1306,8 +1300,6 @@ dependencies = [ [[package]] name = "matrix-sdk-common" version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c004ca5d02a17eb827a2c3d8e34c9a84c075b42cfed7022895ba6418372ea5" dependencies = [ "async-trait", "futures", @@ -1323,8 +1315,6 @@ dependencies = [ [[package]] name = "matrix-sdk-crypto" version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d36626b188e0ea1d244eef6fe39ab1758c401de6ec84d0389df88f9f6ad761b9" dependencies = [ "aes", "aes-gcm", diff --git a/Cargo.toml b/Cargo.toml index 494fad7..2f791bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] bincode = "1.3.3" discord_message_format = { git = "https://git.lavender.software/charlotte/discord-message-format.git" } -matrix-sdk = "0.4" +matrix-sdk = { path = "./matrix-rust-sdk/crates/matrix-sdk" } serde = { version = "1.0.130", features = ["derive"] } sled = "0.34.7" tokio = { version = "1.11.0", features = ["full"] } diff --git a/matrix-rust-sdk b/matrix-rust-sdk new file mode 160000 index 0000000..d83d8b9 --- /dev/null +++ b/matrix-rust-sdk @@ -0,0 +1 @@ +Subproject commit d83d8b959c644db7581976374954906d45b765b9 diff --git a/src/bridgers.rs b/src/bridgers.rs index 5bcd63b..79c85a1 100644 --- a/src/bridgers.rs +++ b/src/bridgers.rs @@ -4,9 +4,9 @@ use sled::Db; use crate::{ channels::ChannelReference, - discord::{self, edit_on_discord, forward_to_discord}, - matrix::{self, edit_on_matrix, forward_to_matrix}, - messages::{EditedMessage, MessageReference, SentMessage}, + discord::{self, delete_on_discord, edit_on_discord, forward_to_discord}, + matrix::{self, delete_on_matrix, edit_on_matrix, forward_to_matrix}, + messages::{DeletedMessage, EditedMessage, MessageReference, SentMessage}, }; pub struct Bridgers { @@ -246,4 +246,33 @@ impl Bridgers { self.store_related_messages(&new_related_messages.into_iter().collect::>()) } } + + pub async fn delete_message(&self, message: DeletedMessage) { + if let Some(related_messages) = self.get_related_messages(&message.reference) { + for related_message in related_messages.iter() { + // TODO: What do we want to do with the success / failure ??? + + match related_message { + MessageReference::Discord(channel_id, message_id) => { + if let Some(discord) = self.discord.lock().unwrap().borrow().as_ref() { + let channel_id = discord::ChannelId(*channel_id); + let message_id = discord::MessageId(*message_id); + + let _success = + delete_on_discord(discord, channel_id, message_id, &message).await; + } + } + MessageReference::Matrix(room_id, event_id) => { + if let Some(matrix) = self.matrix.lock().unwrap().borrow().as_ref() { + let room_id = matrix::RoomId::from_str(room_id).unwrap(); + let event_id = matrix::EventId::from_str(event_id).unwrap(); + + let _success = + delete_on_matrix(matrix, room_id, event_id, &message).await; + } + } + } + } + } + } } diff --git a/src/discord.rs b/src/discord.rs index 2a3ef6d..52afe56 100644 --- a/src/discord.rs +++ b/src/discord.rs @@ -5,7 +5,9 @@ use tokio::sync::mpsc; use crate::{ channels::ChannelReference, message_ast::{self, format_discord}, - messages::{EditedMessage, MessageAuthor, MessageEvent, MessageReference, SentMessage}, + messages::{ + DeletedMessage, EditedMessage, MessageAuthor, MessageEvent, MessageReference, SentMessage, + }, }; pub use serenity::client::Context; @@ -111,6 +113,19 @@ impl EventHandler for DiscordHandler { })); } } + + async fn message_delete( + &self, + _ctx: Context, + channel_id: ChannelId, + deleted_message_id: MessageId, + _guild_id: Option, + ) { + let message_ref = MessageReference::Discord(channel_id.0, deleted_message_id.0); + let _ = self.event_tx.send(MessageEvent::Delete(DeletedMessage { + reference: message_ref, + })); + } } pub async fn forward_to_discord( @@ -151,6 +166,18 @@ pub async fn edit_on_discord( .map(MessageReference::from) } +pub async fn delete_on_discord( + discord_ctx: &Context, + channel_id: ChannelId, + message_id: MessageId, + _message: &DeletedMessage, +) -> bool { + channel_id + .delete_message(&discord_ctx, &message_id) + .await + .is_ok() +} + pub async fn create_discord_client( ctx_tx: mpsc::UnboundedSender, message_tx: mpsc::UnboundedSender, diff --git a/src/main.rs b/src/main.rs index 5c6d2cc..3249d7e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,7 +50,7 @@ async fn setup_matrix( .unwrap() .replace(Some(client.clone())); - let settings = matrix_sdk::SyncSettings::default().token(client.sync_token().await.unwrap()); + let settings = matrix::SyncSettings::default().token(client.sync_token().await.unwrap()); tokio::spawn(async move { client.sync(settings).await; }); @@ -93,6 +93,10 @@ async fn main() { MessageEvent::Edit(edited_message) => { bridgers.edit_message(edited_message).await; } + MessageEvent::Delete(deleted_message) => { + bridgers.delete_message(deleted_message).await; + } + MessageEvent::AdminLinkChannels(channels) => { bridgers.link_channels(&channels); } diff --git a/src/matrix.rs b/src/matrix.rs index 008e49c..c7ca5fb 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use matrix_sdk::{ + config::ClientConfig, room::{Joined, Room}, ruma::{ api, @@ -11,16 +12,16 @@ use matrix_sdk::{ FormattedBody, MessageEventContent, MessageFormat, MessageType, Relation, Replacement, }, - redaction::RedactionEventContent, + redaction::{RedactionEventContent, SyncRedactionEvent}, }, AnyMessageEvent, AnyMessageEventContent, AnyRoomEvent, AnySyncRoomEvent, SyncMessageEvent, }, UserId, }, - ClientConfig, SyncSettings, }; pub use matrix_sdk::{ + config::SyncSettings, ruma::{EventId, RoomId}, Client, }; @@ -34,7 +35,9 @@ use crate::{ convert_matrix, convert_plain, format_discord, format_matrix, MessageComponent, MessageContent, }, - messages::{EditedMessage, MessageAuthor, MessageEvent, MessageReference, SentMessage}, + messages::{ + DeletedMessage, EditedMessage, MessageAuthor, MessageEvent, MessageReference, SentMessage, + }, }; impl From<(&RoomId, &EventId)> for MessageReference { @@ -223,6 +226,14 @@ async fn on_message_edited( } } +async fn on_redact_event(ctx: Arc, event: SyncRedactionEvent, room: Room) { + let message_ref = MessageReference::from((room.room_id(), &event.redacts)); + + let _ = ctx.message_tx.send(MessageEvent::Delete(DeletedMessage { + reference: message_ref, + })); +} + pub async fn forward_to_matrix( client: &Client, room_id: RoomId, @@ -318,6 +329,19 @@ pub async fn edit_on_matrix( None } +pub async fn delete_on_matrix( + client: &Client, + room_id: RoomId, + event_id: EventId, + _message: &DeletedMessage, +) -> bool { + if let Some(room) = client.get_joined_room(&room_id) { + room.redact(&event_id, None, None).await.is_ok() + } else { + false + } +} + pub async fn create_matrix_client( homeserver_url: String, username: String, @@ -346,10 +370,14 @@ pub async fn create_matrix_client( current_user_id, }); + let on_msg_ctx = event_handler.clone(); client - .register_event_handler(move |ev, room| { - on_room_message_event(Arc::clone(&event_handler), ev, room) - }) + .register_event_handler(move |ev, room| on_room_message_event(on_msg_ctx.clone(), ev, room)) + .await; + + let on_redact_ctx = event_handler.clone(); + client + .register_event_handler(move |ev, room| on_redact_event(on_redact_ctx.clone(), ev, room)) .await; client diff --git a/src/messages.rs b/src/messages.rs index 2d4f0a6..3b05b0e 100644 --- a/src/messages.rs +++ b/src/messages.rs @@ -25,8 +25,13 @@ pub struct EditedMessage { pub author: MessageAuthor, } +pub struct DeletedMessage { + pub reference: MessageReference, +} + pub enum MessageEvent { AdminLinkChannels(Vec), Send(SentMessage), Edit(EditedMessage), + Delete(DeletedMessage), }