use matrix_sdk::ruma::events::room::message; async fn on_room_message(event: message::OriginalSyncRoomMessageEvent, room: matrix_sdk::room::Room, client: matrix_sdk::Client) { let cl = client.clone(); let this_uid = cl.user_id().unwrap(); if event.clone().sender.matrix_uri(false) == this_uid.matrix_uri(false) { return; } let message::MessageType::Text(text_content) = event.clone().content.msgtype else { return; }; let r = client.get_joined_room(room.room_id()).unwrap(); if text_content.body.contains("!diru") { if text_content.body.contains("dpl") { deepl_translation(event, r, &text_content.body).await; } } } async fn autojoin_room(room_member: matrix_sdk::ruma::events::room::member::StrippedRoomMemberEvent, client: matrix_sdk::Client, room: matrix_sdk::room::Room) { if room_member.state_key != client.user_id().unwrap() { return; } tokio::spawn(async move { let rid = room.room_id(); tracing::info!("Autojoining {}", rid); let mut delay = 2; let r = client.get_invited_room(rid).unwrap(); while let Err(err) = r.accept_invitation().await { eprintln!("Failed to join room {} ({err:?}), retrying in {delay}s", room.room_id()); tokio::time::sleep(tokio::time::Duration::from_secs(delay)).await; delay *= 2; if delay > 3600 { eprintln!("Can't join room {} ({err:?})", room.room_id()); break; } } }); } async fn deepl_translation(event: message::OriginalSyncRoomMessageEvent, room: matrix_sdk::room::Joined, content: &str) { let txn_id = matrix_sdk::ruma::TransactionId::new(); let msg = message::RoomMessageEventContent::text_plain(format!("{}", content)) .make_reply_to(&event.clone().into_full_event(room.room_id().into())); room.send(msg, Some(&txn_id)).await.unwrap(); } async fn connect_to_matrix(hs: String, username: String, passwd:String) -> anyhow::Result<()> { let client = matrix_sdk::Client::builder().homeserver_url(hs).build().await.unwrap(); let device_id = std::env::var("DEVICE_ID"); match device_id { Ok(id) => { client .login_username(&username, &passwd) .device_id(&id) .send() .await?; }, Err(_) => { client.login_username(&username, &passwd) .initial_device_display_name("Diru Development") .send() .await?; } } println!("Logged in as {username}"); let response = client.sync_once(matrix_sdk::config::SyncSettings::default()).await?; client.add_event_handler(on_room_message); client.add_event_handler(autojoin_room); let stg = matrix_sdk::config::SyncSettings::default().token(response.next_batch); client.sync(stg).await?; Ok(()) } #[tokio::main] async fn main() -> anyhow::Result<()> { dotenvy::dotenv().ok(); tracing_subscriber::fmt::init(); let (homeserver_url, username, passwd) = match (std::env::var("HOMESERVER_URL"), std::env::var("MATRIX_BOT_NAME"), std::env::var("MATRIX_BOT_PASSWD")) { (Ok(a), Ok(b), Ok(c)) => (a, b, c), _ => { eprintln!("Please ensure the HOMESERVER_URL, MATRIX_BOT_NAME, and MATRIX_BOT_PASSWD environment variables are set."); std::process::exit(1) } }; connect_to_matrix(homeserver_url, username, passwd).await?; Ok(()) }