diff --git a/src/bin/send.rs b/src/bin/send.rs new file mode 100644 index 0000000..a4d27e6 --- /dev/null +++ b/src/bin/send.rs @@ -0,0 +1,64 @@ +use std::path::Path; + +use anyhow::Context; +use matrix_sdk::{ + Client, + authentication::matrix::MatrixSession, + ruma::{OwnedRoomId, events::room::message::RoomMessageEventContent}, +}; +use serde::Deserialize; +use tokio::fs; + +#[derive(Debug, Deserialize)] +struct PersistedSession { + homeserver: String, + db_path: std::path::PathBuf, + user_session: MatrixSession, +} + +const STATE_DIR: &str = "/persist/damocles-lab/state"; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let args: Vec = std::env::args().collect(); + if args.len() < 3 { + eprintln!("usage: send "); + eprintln!(" send '!room:server' 'hello world'"); + eprintln!(" echo 'hello' | send '!room:server' -"); + std::process::exit(1); + } + + let room_id: OwnedRoomId = args[1].parse().context("invalid room ID")?; + let message = if args[2] == "-" { + use std::io::Read; + let mut buf = String::new(); + std::io::stdin().read_to_string(&mut buf)?; + buf.trim().to_owned() + } else { + args[2..].join(" ") + }; + + let session_file = Path::new(STATE_DIR).join("session.json"); + let data = fs::read_to_string(&session_file) + .await + .context("no session file - run the daemon first to log in")?; + let session: PersistedSession = serde_json::from_str(&data)?; + + let client = Client::builder() + .homeserver_url(&session.homeserver) + .sqlite_store(&session.db_path, None) + .build() + .await?; + + client.restore_session(session.user_session).await?; + + // need at least one sync so the client knows about joined rooms + client.sync_once(matrix_sdk::config::SyncSettings::default()).await?; + + let room = client.get_room(&room_id).context("room not found - has the bot joined it?")?; + let content = RoomMessageEventContent::text_plain(&message); + room.send(content).await?; + + eprintln!("sent to {room_id}"); + Ok(()) +}