Implement bridged message deletions

legacy
Charlotte Som 2021-09-16 04:29:00 +01:00
parent 6ad07c6855
commit ec4d1a1f50
9 changed files with 109 additions and 22 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "matrix-rust-sdk"]
path = matrix-rust-sdk
url = https://git.lavender.software/charlotte/matrix-rust-sdk.git

10
Cargo.lock generated
View File

@ -1237,8 +1237,6 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]] [[package]]
name = "matrix-qrcode" name = "matrix-qrcode"
version = "0.2.0" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4231739aa2ff90c6c55b07d7179c52b496622a86fc2f7e0431336d109ba7838d"
dependencies = [ dependencies = [
"base64 0.13.0", "base64 0.13.0",
"byteorder", "byteorder",
@ -1252,8 +1250,6 @@ dependencies = [
[[package]] [[package]]
name = "matrix-sdk" name = "matrix-sdk"
version = "0.4.1" version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5834b96fef26d6d61c8ffd21dda3569c7c0fc688f9cc8aebd35f6f8c3068a186"
dependencies = [ dependencies = [
"backoff", "backoff",
"bytes 1.1.0", "bytes 1.1.0",
@ -1280,8 +1276,6 @@ dependencies = [
[[package]] [[package]]
name = "matrix-sdk-base" name = "matrix-sdk-base"
version = "0.4.1" version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b97c4d675ff70395c1b0cd94fae869cea4efd3f148b74bf4186e969ee622a9c7"
dependencies = [ dependencies = [
"chacha20poly1305", "chacha20poly1305",
"dashmap", "dashmap",
@ -1306,8 +1300,6 @@ dependencies = [
[[package]] [[package]]
name = "matrix-sdk-common" name = "matrix-sdk-common"
version = "0.4.1" version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31c004ca5d02a17eb827a2c3d8e34c9a84c075b42cfed7022895ba6418372ea5"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"futures", "futures",
@ -1323,8 +1315,6 @@ dependencies = [
[[package]] [[package]]
name = "matrix-sdk-crypto" name = "matrix-sdk-crypto"
version = "0.4.1" version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d36626b188e0ea1d244eef6fe39ab1758c401de6ec84d0389df88f9f6ad761b9"
dependencies = [ dependencies = [
"aes", "aes",
"aes-gcm", "aes-gcm",

View File

@ -6,7 +6,7 @@ edition = "2018"
[dependencies] [dependencies]
bincode = "1.3.3" bincode = "1.3.3"
discord_message_format = { git = "https://git.lavender.software/charlotte/discord-message-format.git" } 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"] } serde = { version = "1.0.130", features = ["derive"] }
sled = "0.34.7" sled = "0.34.7"
tokio = { version = "1.11.0", features = ["full"] } tokio = { version = "1.11.0", features = ["full"] }

1
matrix-rust-sdk Submodule

@ -0,0 +1 @@
Subproject commit d83d8b959c644db7581976374954906d45b765b9

View File

@ -4,9 +4,9 @@ use sled::Db;
use crate::{ use crate::{
channels::ChannelReference, channels::ChannelReference,
discord::{self, edit_on_discord, forward_to_discord}, discord::{self, delete_on_discord, edit_on_discord, forward_to_discord},
matrix::{self, edit_on_matrix, forward_to_matrix}, matrix::{self, delete_on_matrix, edit_on_matrix, forward_to_matrix},
messages::{EditedMessage, MessageReference, SentMessage}, messages::{DeletedMessage, EditedMessage, MessageReference, SentMessage},
}; };
pub struct Bridgers { pub struct Bridgers {
@ -246,4 +246,33 @@ impl Bridgers {
self.store_related_messages(&new_related_messages.into_iter().collect::<Vec<_>>()) self.store_related_messages(&new_related_messages.into_iter().collect::<Vec<_>>())
} }
} }
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;
}
}
}
}
}
}
} }

View File

@ -5,7 +5,9 @@ use tokio::sync::mpsc;
use crate::{ use crate::{
channels::ChannelReference, channels::ChannelReference,
message_ast::{self, format_discord}, message_ast::{self, format_discord},
messages::{EditedMessage, MessageAuthor, MessageEvent, MessageReference, SentMessage}, messages::{
DeletedMessage, EditedMessage, MessageAuthor, MessageEvent, MessageReference, SentMessage,
},
}; };
pub use serenity::client::Context; 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<GuildId>,
) {
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( pub async fn forward_to_discord(
@ -151,6 +166,18 @@ pub async fn edit_on_discord(
.map(MessageReference::from) .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( pub async fn create_discord_client(
ctx_tx: mpsc::UnboundedSender<Context>, ctx_tx: mpsc::UnboundedSender<Context>,
message_tx: mpsc::UnboundedSender<MessageEvent>, message_tx: mpsc::UnboundedSender<MessageEvent>,

View File

@ -50,7 +50,7 @@ async fn setup_matrix(
.unwrap() .unwrap()
.replace(Some(client.clone())); .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 { tokio::spawn(async move {
client.sync(settings).await; client.sync(settings).await;
}); });
@ -93,6 +93,10 @@ async fn main() {
MessageEvent::Edit(edited_message) => { MessageEvent::Edit(edited_message) => {
bridgers.edit_message(edited_message).await; bridgers.edit_message(edited_message).await;
} }
MessageEvent::Delete(deleted_message) => {
bridgers.delete_message(deleted_message).await;
}
MessageEvent::AdminLinkChannels(channels) => { MessageEvent::AdminLinkChannels(channels) => {
bridgers.link_channels(&channels); bridgers.link_channels(&channels);
} }

View File

@ -1,6 +1,7 @@
use std::sync::Arc; use std::sync::Arc;
use matrix_sdk::{ use matrix_sdk::{
config::ClientConfig,
room::{Joined, Room}, room::{Joined, Room},
ruma::{ ruma::{
api, api,
@ -11,16 +12,16 @@ use matrix_sdk::{
FormattedBody, MessageEventContent, MessageFormat, MessageType, Relation, FormattedBody, MessageEventContent, MessageFormat, MessageType, Relation,
Replacement, Replacement,
}, },
redaction::RedactionEventContent, redaction::{RedactionEventContent, SyncRedactionEvent},
}, },
AnyMessageEvent, AnyMessageEventContent, AnyRoomEvent, AnySyncRoomEvent, AnyMessageEvent, AnyMessageEventContent, AnyRoomEvent, AnySyncRoomEvent,
SyncMessageEvent, SyncMessageEvent,
}, },
UserId, UserId,
}, },
ClientConfig, SyncSettings,
}; };
pub use matrix_sdk::{ pub use matrix_sdk::{
config::SyncSettings,
ruma::{EventId, RoomId}, ruma::{EventId, RoomId},
Client, Client,
}; };
@ -34,7 +35,9 @@ use crate::{
convert_matrix, convert_plain, format_discord, format_matrix, MessageComponent, convert_matrix, convert_plain, format_discord, format_matrix, MessageComponent,
MessageContent, MessageContent,
}, },
messages::{EditedMessage, MessageAuthor, MessageEvent, MessageReference, SentMessage}, messages::{
DeletedMessage, EditedMessage, MessageAuthor, MessageEvent, MessageReference, SentMessage,
},
}; };
impl From<(&RoomId, &EventId)> for MessageReference { impl From<(&RoomId, &EventId)> for MessageReference {
@ -223,6 +226,14 @@ async fn on_message_edited(
} }
} }
async fn on_redact_event(ctx: Arc<MatrixHandler>, 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( pub async fn forward_to_matrix(
client: &Client, client: &Client,
room_id: RoomId, room_id: RoomId,
@ -318,6 +329,19 @@ pub async fn edit_on_matrix(
None 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( pub async fn create_matrix_client(
homeserver_url: String, homeserver_url: String,
username: String, username: String,
@ -346,10 +370,14 @@ pub async fn create_matrix_client(
current_user_id, current_user_id,
}); });
let on_msg_ctx = event_handler.clone();
client client
.register_event_handler(move |ev, room| { .register_event_handler(move |ev, room| on_room_message_event(on_msg_ctx.clone(), ev, room))
on_room_message_event(Arc::clone(&event_handler), 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; .await;
client client

View File

@ -25,8 +25,13 @@ pub struct EditedMessage {
pub author: MessageAuthor, pub author: MessageAuthor,
} }
pub struct DeletedMessage {
pub reference: MessageReference,
}
pub enum MessageEvent { pub enum MessageEvent {
AdminLinkChannels(Vec<ChannelReference>), AdminLinkChannels(Vec<ChannelReference>),
Send(SentMessage), Send(SentMessage),
Edit(EditedMessage), Edit(EditedMessage),
Delete(DeletedMessage),
} }