diff --git a/src/matrix.rs b/src/matrix.rs index 3769de0b994eb24b98ee86cc5c51ca918e977228..08896e4a34f7a35efdf052bc2cd6c80565202979 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -1,4 +1,4 @@ -use crate::{cmd::package::CmdPackage, cmd::Cmd, config::Config}; +use crate::{cmd::package::CmdPackage, cmd::Cmd, config::Config, return_if}; use futures::future::join_all; use log::{error, info, warn}; use matrix_sdk::{ @@ -6,6 +6,7 @@ use matrix_sdk::{ room::{Invited, Room}, ruma::{ events::{ + reaction::{ReactionEventContent, Relation}, room::{ member::MemberEventContent, message::{MessageEventContent, MessageType, TextMessageEventContent}, @@ -16,7 +17,7 @@ use matrix_sdk::{ }, Client, Result, SyncSettings, }; -use std::{convert::TryFrom, lazy::SyncLazy, process::abort, sync::Arc, sync::Mutex, time}; +use std::{convert::TryFrom, lazy::SyncLazy, process::abort, sync::Arc, sync::Mutex}; use tokio::time::{sleep, Duration}; async fn join_room(room: &Invited) { @@ -97,59 +98,63 @@ pub async fn connect_and_handle(config: Config) -> Result<()> { }; GLOBAL_PKG.lock().unwrap().push(pkg); + let on_msg_room_reaction = |ev: SyncMessageEvent<ReactionEventContent>, + room: Room, + _: Option<EncryptionInfo>| async move { + let sender_id = ev.sender.clone(); + return_if!(sender_id.as_str() == room.own_user_id().as_str(), ()); + if let ( + Room::Joined(joined), + ReactionEventContent { + relates_to: Relation { + emoji, event_id, .. + }, + .. + }, + ) = (room, ev.content) + { + let msg_content = format!( + "Not handled reactions in room {} with event {event_id}, emoji was {emoji}", + joined.room_id() + ); + let msg = AnyMessageEventContent::RoomMessage(MessageEventContent::text_html( + msg_content.clone(), + msg_content, + )); + joined.send(msg, None).await.unwrap(); + }; + }; + let on_msg_room_event = |ev: SyncMessageEvent<MessageEventContent>, room: Room, - _encryption_info: Option<EncryptionInfo>| async { - let now = time::Instant::now(); - let sender_id = ev.sender; - if sender_id.as_str() == room.own_user_id().as_str() { - return (); - } - - if room.name().is_none() { - warn!("Unsupported rooms without names"); - return (); - } - - if let Room::Joined(joined) = room { - if let MessageType::Text(TextMessageEventContent { body, .. }) = ev.content.msgtype { - if body.starts_with("%") { - if let Some(stripped) = body.strip_prefix("%") { - let args = stripped.split(' ').collect::<Vec<&str>>(); - let mut res: String = format!("Command not found"); - if let Some(pkg) = GLOBAL_PKG - .lock() - .unwrap() - .iter() - .find(|x| x.has_command(&args)) - { - res = pkg.handle(&joined, &sender_id, args); - } - - let msg = AnyMessageEventContent::RoomMessage( - MessageEventContent::text_html(res.clone(), res), - ); - let elapsed_before_send = now.elapsed(); - joined.send(msg, None).await.unwrap(); - let elapsed_after_send = now.elapsed(); - warn!( - "Elapsed before send {}µs, elapsed after send {}ms", - elapsed_before_send.as_micros(), - elapsed_after_send.as_millis() - ); + __info: Option<EncryptionInfo>| async { + let sender_id = ev.sender.clone(); + return_if!(sender_id.as_str() == room.own_user_id().as_str(), ()); + + if let (Room::Joined(joined), MessageType::Text(TextMessageEventContent { ref body, .. })) = + (room, ev.content.msgtype.clone()) + { + if body.starts_with("%") { + if let Some(stripped) = body.strip_prefix("%") { + let args = stripped.split(' ').collect::<Vec<&str>>(); + let mut res: String = format!("Command not found"); + if let Some(pkg) = GLOBAL_PKG + .lock() + .unwrap() + .iter() + .find(|x| x.has_command(&args)) + { + res = pkg.handle(&joined, &sender_id, args); } + + let event = ev.into_full_event(joined.room_id().clone()); + let msg = AnyMessageEventContent::RoomMessage( + MessageEventContent::text_reply_html(res.clone(), res, &event), + ); + joined.send(msg, None).await.unwrap(); } } - } - - // if let Room::Invited(_) = room { - // warn!("Bot was invited by {sender_id} to room {room_id} a.k.a. {room_name}",); - // } - - // if let Room::Left(_) = room { - // error!("Bot left room {room_id} a.k.a. {room_name}") - // } - return (); + }; }; let alice = UserId::try_from(config.user_name)?; @@ -176,6 +181,7 @@ pub async fn connect_and_handle(config: Config) -> Result<()> { } client.register_event_handler(on_msg_room_event).await; + client.register_event_handler(on_msg_room_reaction).await; info!("Entering sync loop"); let token = client.sync_token().await.unwrap();