A better Rust ATProto crate
1use clap::Parser; 2use jacquard::api::app_bsky::feed::post::Post; 3use jacquard::client::{Agent, FileAuthStore}; 4use jacquard::oauth::atproto::AtprotoClientMetadata; 5use jacquard::oauth::client::OAuthClient; 6use jacquard::oauth::loopback::LoopbackConfig; 7use jacquard::types::string::Datetime; 8use jacquard::xrpc::XrpcClient; 9use jacquard::CowStr; 10use miette::IntoDiagnostic; 11 12#[derive(Parser, Debug)] 13#[command(author, version, about = "Create a simple post")] 14struct Args { 15 /// Handle (e.g., alice.bsky.social), DID, or PDS URL 16 input: CowStr<'static>, 17 18 /// Post text 19 #[arg(short, long)] 20 text: String, 21 22 /// Path to auth store file (will be created if missing) 23 #[arg(long, default_value = "/tmp/jacquard-oauth-session.json")] 24 store: String, 25} 26 27#[tokio::main] 28async fn main() -> miette::Result<()> { 29 let args = Args::parse(); 30 31 let oauth = OAuthClient::with_default_config(FileAuthStore::new(&args.store)); 32 let session = oauth 33 .login_with_local_server(args.input, Default::default(), LoopbackConfig::default()) 34 .await?; 35 36 let agent: Agent<_> = Agent::from(session); 37 38 // Create a simple text post using the Agent convenience method 39 let post = Post { 40 text: CowStr::from(args.text), 41 created_at: Datetime::now(), 42 embed: None, 43 entities: None, 44 facets: None, 45 labels: None, 46 langs: None, 47 reply: None, 48 tags: None, 49 extra_data: Default::default(), 50 }; 51 52 let output = agent.create_record(post, None).await?; 53 println!("✓ Created post: {}", output.uri); 54 55 Ok(()) 56}