use std::env; use std::process; use kordophone::{ api::{HTTPAPIClient, InMemoryAuthenticationStore, EventSocket}, model::{ConversationID, event::EventData}, APIInterface, }; use kordophone::api::http_client::Credentials; use kordophone::api::AuthenticationStore; 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); // Kick auth... this is bad. Update monitor should do this. _ = client.get_conversations().await?; // 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(()) }