diff --git a/atrium-cli/README.md b/atrium-cli/README.md index da67cb9..e630638 100644 --- a/atrium-cli/README.md +++ b/atrium-cli/README.md @@ -23,6 +23,8 @@ Commands: get-profile Get detailed profile view of an actor get-preferences Get preferences of an actor list-notifications Get a list of notifications + list-convos Get a list of chat conversations + send-convo-message Send a message to a chat conversation create-post Create a new post delete-post Delete a post help Print this message or the help of the given subcommand(s) diff --git a/atrium-cli/src/commands.rs b/atrium-cli/src/commands.rs index 61d25f5..3c74213 100644 --- a/atrium-cli/src/commands.rs +++ b/atrium-cli/src/commands.rs @@ -35,6 +35,10 @@ pub enum Command { GetPreferences, /// Get a list of notifications. ListNotifications, + /// Get a list of chat conversations. + ListConvos, + /// Send a message to a chat conversation. + SendConvoMessage(SendConvoMessageArgs), /// Create a new post. CreatePost(CreatePostArgs), /// Delete a post. @@ -65,6 +69,16 @@ pub struct UriArgs { pub(crate) uri: AtUri, } +#[derive(Parser, Debug)] +pub struct SendConvoMessageArgs { + /// Actor's handle or did + #[arg(short, long, value_parser)] + pub(crate) actor: AtIdentifier, + /// Message text + #[arg(short, long)] + pub(crate) text: String, +} + #[derive(Parser, Debug)] pub struct CreatePostArgs { /// Post text diff --git a/atrium-cli/src/runner.rs b/atrium-cli/src/runner.rs index 4435075..c6124a8 100644 --- a/atrium-cli/src/runner.rs +++ b/atrium-cli/src/runner.rs @@ -1,6 +1,7 @@ use crate::commands::Command; use crate::store::SimpleJsonFileSessionStore; use anyhow::{Context, Result}; +use atrium_api::agent::bluesky::{AtprotoServiceType, BSKY_CHAT_DID}; use atrium_api::agent::{store::SessionStore, AtpAgent}; use atrium_api::records::{KnownRecord, Record}; use atrium_api::types::string::{AtIdentifier, Datetime, Handle}; @@ -263,6 +264,71 @@ impl Runner { ) .await?, ), + Command::ListConvos => self.print( + &self + .agent + .api_with_proxy( + BSKY_CHAT_DID.parse().expect("valid DID"), + AtprotoServiceType::BskyChat, + ) + .chat + .bsky + .convo + .list_convos(atrium_api::chat::bsky::convo::list_convos::Parameters { + cursor: None, + limit: Some(limit), + }) + .await?, + ), + Command::SendConvoMessage(args) => { + let did = match args.actor { + AtIdentifier::Handle(handle) => { + self.agent + .api + .com + .atproto + .identity + .resolve_handle( + atrium_api::com::atproto::identity::resolve_handle::Parameters { + handle: handle.clone(), + }, + ) + .await? + .did + } + AtIdentifier::Did(did) => did, + }; + let chat = &self + .agent + .api_with_proxy( + BSKY_CHAT_DID.parse().expect("valid DID"), + AtprotoServiceType::BskyChat, + ) + .chat; + let convo = chat + .bsky + .convo + .get_convo_for_members( + atrium_api::chat::bsky::convo::get_convo_for_members::Parameters { + members: vec![did], + }, + ) + .await?; + self.print( + &chat + .bsky + .convo + .send_message(atrium_api::chat::bsky::convo::send_message::Input { + convo_id: convo.convo.id, + message: atrium_api::chat::bsky::convo::defs::MessageInput { + embed: None, + facets: None, + text: args.text, + }, + }) + .await?, + ) + } Command::CreatePost(args) => { let mut images = Vec::new(); for image in &args.images {