use kordophone::APIInterface; use kordophone::api::http_client::HTTPAPIClient; use kordophone::api::http_client::Credentials; use kordophone::api::InMemoryAuthenticationStore; use kordophone::api::event_socket::EventSocket; use anyhow::Result; use clap::Subcommand; use crate::printers::{ConversationPrinter, MessagePrinter}; use kordophone::model::event::Event; use futures_util::StreamExt; pub fn make_api_client_from_env() -> HTTPAPIClient { dotenv::dotenv().ok(); // read from env let base_url = std::env::var("KORDOPHONE_API_URL") .expect("KORDOPHONE_API_URL must be set"); let credentials = Credentials { username: std::env::var("KORDOPHONE_USERNAME") .expect("KORDOPHONE_USERNAME must be set"), password: std::env::var("KORDOPHONE_PASSWORD") .expect("KORDOPHONE_PASSWORD must be set"), }; HTTPAPIClient::new(base_url.parse().unwrap(), InMemoryAuthenticationStore::new(Some(credentials))) } #[derive(Subcommand)] pub enum Commands { /// Prints all known conversations on the server. Conversations, /// Prints all messages in a conversation. Messages { conversation_id: String, }, /// Prints the server Kordophone version. Version, /// Prints all events from the server. Events, /// Prints all raw updates from the server. RawUpdates, } impl Commands { pub async fn run(cmd: Commands) -> Result<()> { let mut client = ClientCli::new(); match cmd { Commands::Version => client.print_version().await, Commands::Conversations => client.print_conversations().await, Commands::Messages { conversation_id } => client.print_messages(conversation_id).await, Commands::RawUpdates => client.print_raw_updates().await, Commands::Events => client.print_events().await, } } } struct ClientCli { api: HTTPAPIClient, } impl ClientCli { pub fn new() -> Self { let api = make_api_client_from_env(); Self { api } } pub async fn print_version(&mut self) -> Result<()> { let version = self.api.get_version().await?; println!("Version: {}", version); Ok(()) } pub async fn print_conversations(&mut self) -> Result<()> { let conversations = self.api.get_conversations().await?; for conversation in conversations { println!("{}", ConversationPrinter::new(&conversation.into())); } Ok(()) } pub async fn print_messages(&mut self, conversation_id: String) -> Result<()> { let messages = self.api.get_messages(&conversation_id, None, None, None).await?; for message in messages { println!("{}", MessagePrinter::new(&message.into())); } Ok(()) } pub async fn print_events(&mut self) -> Result<()> { let socket = self.api.open_event_socket().await?; let mut stream = socket.events().await; while let Some(Ok(event)) = stream.next().await { match event { Event::ConversationChanged(conversation) => { println!("Conversation changed: {}", conversation.guid); } Event::MessageReceived(conversation, message) => { println!("Message received: msg: {} conversation: {}", message.guid, conversation.guid); } } } Ok(()) } pub async fn print_raw_updates(&mut self) -> Result<()> { let socket = self.api.open_event_socket().await?; println!("Listening for raw updates..."); let mut stream = socket.raw_updates().await; while let Some(update) = stream.next().await { println!("Got update: {:?}", update); } Ok(()) } }