Implement bridged message replies
parent
079efa5095
commit
535afb4796
|
@ -70,6 +70,54 @@ impl Bridgers {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_related_messages(&self, source: &MessageReference) -> Option<Vec<MessageReference>> {
|
||||
let message_relations = self
|
||||
.db
|
||||
.open_tree("message_relations")
|
||||
.expect("Failed to open relations tree");
|
||||
|
||||
let key = bincode::serialize(source).expect("Failed to serialize message reference");
|
||||
message_relations
|
||||
.get(key)
|
||||
.expect("Failed to retrieve message references")
|
||||
.map(|r| {
|
||||
bincode::deserialize::<Vec<MessageReference>>(&r)
|
||||
.expect("Failed to deserialize message references")
|
||||
})
|
||||
}
|
||||
|
||||
fn get_related_discord_message(&self, source: &MessageReference) -> Option<(u64, u64)> {
|
||||
if let MessageReference::Discord(channel_id, message_id) = source {
|
||||
return Some((*channel_id, *message_id));
|
||||
}
|
||||
|
||||
if let Some(relations) = self.get_related_messages(source) {
|
||||
for relation in relations {
|
||||
if let MessageReference::Discord(channel_id, message_id) = relation {
|
||||
return Some((channel_id, message_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn get_related_matrix_message(&self, source: &MessageReference) -> Option<(String, String)> {
|
||||
if let MessageReference::Matrix(room_id, event_id) = source {
|
||||
return Some((room_id.to_string(), event_id.to_string()));
|
||||
}
|
||||
|
||||
if let Some(relations) = self.get_related_messages(source) {
|
||||
for relation in relations {
|
||||
if let MessageReference::Matrix(room_id, event_id) = relation {
|
||||
return Some((room_id, event_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn link_channels(&self, channels: &[ChannelReference]) {
|
||||
let discord_channels = self
|
||||
.db
|
||||
|
@ -111,7 +159,12 @@ impl Bridgers {
|
|||
|
||||
if let Some(discord) = self.discord.lock().unwrap().borrow().as_ref() {
|
||||
if let Some(channel) = self.get_linked_discord_channel(&message.source) {
|
||||
if let Some(m) = forward_to_discord(discord, channel, &message).await {
|
||||
let reply = message
|
||||
.replies_to
|
||||
.as_ref()
|
||||
.and_then(|r| self.get_related_discord_message(r));
|
||||
|
||||
if let Some(m) = forward_to_discord(discord, channel, &message, reply).await {
|
||||
related_messages.push(m);
|
||||
}
|
||||
}
|
||||
|
@ -119,7 +172,12 @@ impl Bridgers {
|
|||
|
||||
if let Some(matrix) = self.matrix.lock().unwrap().borrow().as_ref() {
|
||||
if let Some(room_id) = self.get_linked_matrix_room(&message.source) {
|
||||
if let Some(m) = forward_to_matrix(matrix, room_id, &message).await {
|
||||
let reply = message
|
||||
.replies_to
|
||||
.as_ref()
|
||||
.and_then(|r| self.get_related_matrix_message(r));
|
||||
|
||||
if let Some(m) = forward_to_matrix(matrix, room_id, &message, reply).await {
|
||||
related_messages.push(m);
|
||||
}
|
||||
}
|
||||
|
@ -136,10 +194,11 @@ impl Bridgers {
|
|||
.filter(|r| r != &source)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
tree.insert(
|
||||
bincode::serialize(source).expect("Failed to serialize message reference"),
|
||||
bincode::serialize(&relations).expect("Failed to serialize message relations"),
|
||||
)
|
||||
let key = bincode::serialize(source).expect("Failed to serialize message reference");
|
||||
let value =
|
||||
bincode::serialize(&relations).expect("Failed to serialize message relations");
|
||||
|
||||
tree.insert(key, value)
|
||||
.expect("Failed to store message relations");
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,11 @@ impl EventHandler for DiscordHandler {
|
|||
let content = discord_message_format::parse(&message.content);
|
||||
let content = message_ast::convert_discord(&content);
|
||||
|
||||
let replies_to = message
|
||||
.referenced_message
|
||||
.as_ref()
|
||||
.map(|m| MessageReference::from(m.as_ref()));
|
||||
|
||||
let _ = self.event_tx.send(MessageEvent::Send(SentMessage {
|
||||
source: message_ref,
|
||||
content,
|
||||
|
@ -71,6 +76,7 @@ impl EventHandler for DiscordHandler {
|
|||
.await
|
||||
.unwrap_or(message.author.name),
|
||||
},
|
||||
replies_to,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -79,10 +85,17 @@ pub async fn forward_to_discord(
|
|||
discord_ctx: &Context,
|
||||
channel: ChannelId,
|
||||
message: &SentMessage,
|
||||
reply: Option<(u64, u64)>,
|
||||
) -> Option<MessageReference> {
|
||||
channel
|
||||
.send_message(&discord_ctx.http, |m| {
|
||||
m.content(format_discord(&message.content))
|
||||
let b = m.content(format_discord(&message.content));
|
||||
|
||||
if let Some((channel_id, message_id)) = reply {
|
||||
b.reference_message((ChannelId(channel_id), MessageId(message_id)))
|
||||
} else {
|
||||
b
|
||||
}
|
||||
})
|
||||
.await
|
||||
.as_ref()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::sync::Arc;
|
||||
use std::{str::FromStr, sync::Arc};
|
||||
|
||||
use matrix_sdk::{
|
||||
room::{Joined, Room},
|
||||
|
@ -10,7 +10,8 @@ use matrix_sdk::{
|
|||
},
|
||||
redaction::RedactionEventContent,
|
||||
},
|
||||
AnyMessageEventContent, AnySyncRoomEvent, SyncMessageEvent,
|
||||
AnyMessageEvent, AnyMessageEventContent, AnyRoomEvent, AnySyncRoomEvent,
|
||||
SyncMessageEvent,
|
||||
},
|
||||
EventId, UserId,
|
||||
},
|
||||
|
@ -125,10 +126,21 @@ async fn on_room_message_event(
|
|||
let content = ctx.get_content(&text.body, &text.formatted);
|
||||
|
||||
if let Some(author) = ctx.get_message_author(&room, &event.sender).await {
|
||||
let replies_to =
|
||||
if let Some(Relation::Reply { in_reply_to }) = &event.content.relates_to {
|
||||
Some(MessageReference::from((
|
||||
room.room_id(),
|
||||
&in_reply_to.event_id,
|
||||
)))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let _ = ctx.message_tx.send(MessageEvent::Send(SentMessage {
|
||||
source: message_ref,
|
||||
content,
|
||||
author,
|
||||
replies_to,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -142,6 +154,7 @@ async fn on_room_message_event(
|
|||
source: message_ref,
|
||||
content,
|
||||
author,
|
||||
replies_to: None,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -158,16 +171,49 @@ pub async fn forward_to_matrix(
|
|||
client: &Client,
|
||||
room_id: RoomId,
|
||||
message: &SentMessage,
|
||||
reply: Option<(String, String)>,
|
||||
) -> Option<MessageReference> {
|
||||
if let Some(room) = client.get_joined_room(&room_id) {
|
||||
let replied_message_event = if let Some((room_id, event_id)) = reply {
|
||||
let event = room
|
||||
.send(
|
||||
AnyMessageEventContent::RoomMessage(MessageEventContent::text_html(
|
||||
.event(
|
||||
matrix_sdk::ruma::api::client::r0::room::get_room_event::Request::new(
|
||||
&RoomId::from_str(&room_id).unwrap(),
|
||||
&EventId::from_str(&event_id).unwrap(),
|
||||
),
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.event
|
||||
.deserialize()
|
||||
.unwrap();
|
||||
|
||||
if let AnyRoomEvent::Message(AnyMessageEvent::RoomMessage(original_message_event)) =
|
||||
event
|
||||
{
|
||||
Some(original_message_event)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let content = if let Some(replied_message_event) = &replied_message_event {
|
||||
MessageEventContent::text_reply_html(
|
||||
format_discord(&message.content),
|
||||
format_matrix(&message.content),
|
||||
)),
|
||||
None,
|
||||
replied_message_event,
|
||||
)
|
||||
} else {
|
||||
MessageEventContent::text_html(
|
||||
format_discord(&message.content),
|
||||
format_matrix(&message.content),
|
||||
)
|
||||
};
|
||||
|
||||
let event = room
|
||||
.send(AnyMessageEventContent::RoomMessage(content), None)
|
||||
.await
|
||||
.ok()?;
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ pub struct SentMessage {
|
|||
pub source: MessageReference,
|
||||
pub content: MessageContent,
|
||||
pub author: MessageAuthor,
|
||||
pub replies_to: Option<MessageReference>,
|
||||
}
|
||||
|
||||
pub struct EditedMessage {
|
||||
|
|
Loading…
Reference in New Issue