2021-08-12 09:47:38 +00:00
|
|
|
use matrix_sdk::{
|
|
|
|
async_trait,
|
|
|
|
room::Room,
|
|
|
|
ruma::{
|
|
|
|
events::{
|
2021-09-10 04:44:00 +00:00
|
|
|
room::{
|
|
|
|
message::{MessageEventContent, MessageFormat, MessageType, Relation},
|
|
|
|
redaction::RedactionEventContent,
|
|
|
|
},
|
|
|
|
AnyMessageEventContent, AnySyncRoomEvent, SyncMessageEvent,
|
2021-08-12 09:47:38 +00:00
|
|
|
},
|
2021-09-10 04:44:00 +00:00
|
|
|
EventId, RoomId,
|
2021-08-12 09:47:38 +00:00
|
|
|
},
|
2021-09-10 04:44:00 +00:00
|
|
|
ClientConfig, EventHandler, SyncSettings,
|
2021-08-12 09:47:38 +00:00
|
|
|
};
|
|
|
|
|
2021-09-10 04:44:00 +00:00
|
|
|
pub use matrix_sdk::Client;
|
|
|
|
use tokio::sync::mpsc;
|
|
|
|
use url::Url;
|
2021-08-12 09:47:38 +00:00
|
|
|
|
2021-09-10 04:44:00 +00:00
|
|
|
use crate::{message_ast::convert_plain, MessageReference, SentMessage};
|
|
|
|
|
|
|
|
impl From<(&RoomId, &EventId)> for MessageReference {
|
|
|
|
fn from((room_id, event_id): (&RoomId, &EventId)) -> Self {
|
|
|
|
let room_string = room_id.as_str().to_string();
|
|
|
|
let event_string = event_id.as_str().to_string();
|
2021-08-12 09:47:38 +00:00
|
|
|
|
|
|
|
Self::Matrix(room_string, event_string)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-10 04:44:00 +00:00
|
|
|
fn _find_content(event: &AnySyncRoomEvent) -> Option<AnyMessageEventContent> {
|
|
|
|
match event {
|
|
|
|
AnySyncRoomEvent::Message(message) => Some(message.content()),
|
|
|
|
AnySyncRoomEvent::RedactedMessage(message) => {
|
|
|
|
if let Some(ref redaction_event) = message.unsigned().redacted_because {
|
|
|
|
Some(AnyMessageEventContent::RoomRedaction(
|
|
|
|
redaction_event.content.clone(),
|
|
|
|
))
|
|
|
|
} else {
|
|
|
|
Some(AnyMessageEventContent::RoomRedaction(
|
|
|
|
RedactionEventContent::new(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
AnySyncRoomEvent::RedactedState(state) => {
|
|
|
|
if let Some(ref redaction_event) = state.unsigned().redacted_because {
|
|
|
|
Some(AnyMessageEventContent::RoomRedaction(
|
|
|
|
redaction_event.content.clone(),
|
|
|
|
))
|
|
|
|
} else {
|
|
|
|
Some(AnyMessageEventContent::RoomRedaction(
|
|
|
|
RedactionEventContent::new(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct MatrixHandler {
|
|
|
|
message_tx: mpsc::UnboundedSender<SentMessage>,
|
|
|
|
}
|
2021-08-12 09:47:38 +00:00
|
|
|
|
|
|
|
#[async_trait]
|
|
|
|
impl EventHandler for MatrixHandler {
|
|
|
|
async fn on_room_message(&self, room: Room, event: &SyncMessageEvent<MessageEventContent>) {
|
2021-09-10 04:44:00 +00:00
|
|
|
let message_ref = MessageReference::from((room.room_id(), &event.event_id));
|
|
|
|
|
|
|
|
let message_type =
|
|
|
|
if let Some(Relation::Replacement(replacement)) = &event.content.relates_to {
|
|
|
|
&replacement.new_content.msgtype
|
|
|
|
} else {
|
|
|
|
&event.content.msgtype
|
|
|
|
};
|
|
|
|
|
|
|
|
match message_type {
|
|
|
|
MessageType::Text(text) => {
|
|
|
|
let content = if let Some(_html) = text
|
|
|
|
.formatted
|
|
|
|
.as_ref()
|
|
|
|
.filter(|f| f.format == MessageFormat::Html)
|
|
|
|
.map(|f| &f.body)
|
2021-08-12 09:47:38 +00:00
|
|
|
{
|
2021-09-10 04:44:00 +00:00
|
|
|
todo!("Parse html_body into MessageContent AST")
|
|
|
|
} else {
|
|
|
|
convert_plain(&text.body)
|
|
|
|
};
|
|
|
|
|
|
|
|
let _ = self.message_tx.send(SentMessage {
|
|
|
|
source: message_ref,
|
|
|
|
content,
|
|
|
|
});
|
2021-08-12 09:47:38 +00:00
|
|
|
}
|
2021-09-10 04:44:00 +00:00
|
|
|
|
|
|
|
MessageType::Emote(_emote) => {
|
|
|
|
// TODO
|
|
|
|
}
|
|
|
|
|
|
|
|
_ => {}
|
|
|
|
};
|
2021-08-12 09:47:38 +00:00
|
|
|
}
|
|
|
|
}
|
2021-09-10 04:44:00 +00:00
|
|
|
|
|
|
|
pub async fn create_matrix_client(
|
|
|
|
homeserver_url: String,
|
|
|
|
username: String,
|
|
|
|
password: String,
|
|
|
|
message_tx: mpsc::UnboundedSender<SentMessage>,
|
|
|
|
) -> Client {
|
|
|
|
let client_config = ClientConfig::new().store_path("./matrix");
|
|
|
|
|
|
|
|
let homeserver_url =
|
|
|
|
Url::parse(&homeserver_url).expect("Failed to parse the matrix homeserver URL");
|
|
|
|
let client = Client::new_with_config(homeserver_url, client_config).unwrap();
|
|
|
|
|
|
|
|
client
|
|
|
|
.login(&username, &password, None, Some("phoebe"))
|
|
|
|
.await
|
|
|
|
.expect("Failed to log in");
|
|
|
|
|
|
|
|
client.sync_once(SyncSettings::default()).await.unwrap();
|
|
|
|
|
|
|
|
let event_handler = MatrixHandler { message_tx };
|
|
|
|
client.set_event_handler(Box::new(event_handler)).await;
|
|
|
|
|
|
|
|
client
|
|
|
|
}
|