use crate::{config::Host, wol}; use std::time::Duration; use tracing::{error, info}; use async_trait::async_trait; use matrix_sdk::{ self, events::{ room::{ member::MemberEventContent, message::{MessageEvent, MessageEventContent, TextMessageEventContent}, }, stripped::StrippedStateEvent, }, Client, EventEmitter, SyncRoom, }; pub(crate) struct WakeOnLanBot { pub(crate) client: Client, pub(crate) hosts: Vec, } impl WakeOnLanBot { pub fn new(client: Client, hosts: Vec) -> Self { Self { client, hosts } } } #[async_trait] impl EventEmitter for WakeOnLanBot { async fn on_stripped_state_member( &self, room: SyncRoom, _room_member: &StrippedStateEvent, _: Option, ) { match room { SyncRoom::Invited(room) => { let room = room.read().await; info!("Autojoining room {}", room.room_id); let mut delay = 2; while let Err(err) = self.client.join_room_by_id(&room.room_id).await { // retry autojoin due to synapse sending invites, before the // invited user can join for more information see // https://github.com/matrix-org/synapse/issues/4345 info!( "Failed to join room {} ({:?}), retrying in {}s", room.room_id, err, delay ); tokio::time::delay_for(Duration::from_secs(delay)).await; delay *= 2; if delay > 3600 { error!("Can't join room {} ({:?})", room.room_id, err); break; } } info!("Successfully joined room {}", room.room_id); } _ => {} } } async fn on_room_message(&self, room: SyncRoom, event: &MessageEvent) { match room { SyncRoom::Joined(_room) => { let msg_body = if let MessageEvent { content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }), .. } = event { msg_body.clone() } else { String::new() }; for host in &self.hosts { //TODO: pull the host name out of the message and check it. If the hostname is //invalid, complain if msg_body == format!("!wake {}", host.name) { if host.users.contains(&event.sender.to_string()) { info!("Waking host {}", host.name); //TODO: reply here match wol::wake(host.mac_addr) { Ok(()) => info!("Magic packet sent to {} successfully", host.name), Err(e) => error!( "Couldn't send magic packet to {}, error: {}", host.name, e ), } } } } } _ => {} } } }