diff --git a/Cargo.lock b/Cargo.lock index 00f9bfc..18e02e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1167,6 +1167,18 @@ dependencies = [ "uuid", ] +[[package]] +name = "kordophone-utilities" +version = "0.1.0" +dependencies = [ + "env_logger 0.11.8", + "futures-util", + "hyper", + "kordophone", + "log", + "tokio", +] + [[package]] name = "kordophoned" version = "1.0.1" diff --git a/Cargo.toml b/Cargo.toml index e9fa9ed..f21f005 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,8 @@ members = [ "kordophone", "kordophone-db", "kordophoned", - "kpcli" + "kpcli", + "utilities", ] resolver = "2" diff --git a/utilities/Cargo.toml b/utilities/Cargo.toml new file mode 100644 index 0000000..1d970dd --- /dev/null +++ b/utilities/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "kordophone-utilities" +version = "0.1.0" +edition = "2024" + +[dependencies] +env_logger = "0.11.5" +futures-util = "0.3.31" +hyper = { version = "0.14" } +kordophone = { path = "../kordophone" } +log = { version = "0.4.21", features = [] } +tokio = { version = "1.37.0", features = ["full"] } \ No newline at end of file diff --git a/utilities/src/bin/snoozer.rs b/utilities/src/bin/snoozer.rs new file mode 100644 index 0000000..135baae --- /dev/null +++ b/utilities/src/bin/snoozer.rs @@ -0,0 +1,96 @@ +use std::env; +use std::process; + +use kordophone::{ + api::{HTTPAPIClient, InMemoryAuthenticationStore, EventSocket}, + model::{ConversationID, event::EventData}, + APIInterface, +}; +use kordophone::api::http_client::Credentials; + +use futures_util::StreamExt; +use hyper::Uri; + +#[tokio::main] +async fn main() -> Result<(), Box> { + env_logger::init(); + + let args: Vec = env::args().collect(); + if args.len() < 2 { + eprintln!("Usage: {} [conversation_id2] [conversation_id3] ...", args[0]); + eprintln!("Environment variables required:"); + eprintln!(" KORDOPHONE_API_URL - Server URL"); + eprintln!(" KORDOPHONE_USERNAME - Username for authentication"); + eprintln!(" KORDOPHONE_PASSWORD - Password for authentication"); + process::exit(1); + } + + // Read environment variables + let server_url: Uri = env::var("KORDOPHONE_API_URL") + .map_err(|_| "KORDOPHONE_API_URL environment variable not set")? + .parse()?; + + let username = env::var("KORDOPHONE_USERNAME") + .map_err(|_| "KORDOPHONE_USERNAME environment variable not set")?; + + let password = env::var("KORDOPHONE_PASSWORD") + .map_err(|_| "KORDOPHONE_PASSWORD environment variable not set")?; + + let credentials = Credentials { username, password }; + + // Collect all conversation IDs from command line arguments + let target_conversation_ids: Vec = args[1..].iter() + .map(|id| id.clone()) + .collect(); + + println!("Monitoring {} conversation(s) for updates: {:?}", + target_conversation_ids.len(), target_conversation_ids); + + let auth_store = InMemoryAuthenticationStore::new(Some(credentials.clone())); + let mut client = HTTPAPIClient::new(server_url, auth_store); + + // Authenticate first + let _token = client.authenticate(credentials).await?; + println!("Authenticated successfully"); + + // Open event socket + let event_socket = client.open_event_socket(None).await?; + let (mut stream, _sink) = event_socket.events().await; + + println!("Connected to event stream, waiting for updates..."); + + // Process events + while let Some(event_result) = stream.next().await { + match event_result { + Ok(socket_event) => { + match socket_event { + kordophone::api::event_socket::SocketEvent::Update(event) => { + match event.data { + EventData::MessageReceived(conversation, _message) => { + if target_conversation_ids.contains(&conversation.guid) { + println!("Message update detected for conversation {}, marking as read...", conversation.guid); + match client.mark_conversation_as_read(&conversation.guid).await { + Ok(_) => println!("Successfully marked conversation {} as read", conversation.guid), + Err(e) => eprintln!("Failed to mark conversation {} as read: {:?}", conversation.guid, e), + } + } + }, + + _ => {} + } + }, + kordophone::api::event_socket::SocketEvent::Pong => { + // Ignore pong messages + } + } + }, + Err(e) => { + eprintln!("Error receiving event: {:?}", e); + break; + } + } + } + + println!("Event stream ended"); + Ok(()) +}