A better Rust ATProto crate
103
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 13e7fd8a629aa37176eaaf4fba59cb1ee7a1f675 74 lines 2.2 kB view raw
1use clap::Parser; 2use jacquard::CowStr; 3use jacquard::api::app_bsky::feed::post::Post; 4use jacquard::client::{Agent, AgentSessionExt, FileAuthStore}; 5use jacquard::oauth::client::OAuthClient; 6use jacquard::oauth::loopback::LoopbackConfig; 7use jacquard::richtext::RichText; 8use jacquard::types::string::Datetime; 9 10#[derive(Parser, Debug)] 11#[command( 12 author, 13 version, 14 about = "Create a post with automatic facet detection" 15)] 16struct Args { 17 /// Handle (e.g., alice.bsky.social), DID, or PDS URL 18 input: CowStr<'static>, 19 20 /// Post text (can include @mentions, #hashtags, URLs, and [markdown](links)) 21 #[arg(short, long)] 22 text: String, 23 24 /// Path to auth store file (will be created if missing) 25 #[arg(long, default_value = "/tmp/jacquard-oauth-session.json")] 26 store: String, 27} 28 29#[tokio::main] 30async fn main() -> miette::Result<()> { 31 let args = Args::parse(); 32 33 let oauth = OAuthClient::with_default_config(FileAuthStore::new(&args.store)); 34 let session = oauth 35 .login_with_local_server(args.input, Default::default(), LoopbackConfig::default()) 36 .await?; 37 38 let agent: Agent<_> = Agent::from(session); 39 40 // Parse richtext with automatic facet detection 41 // This detects @mentions, #hashtags, URLs, and [markdown](links) 42 let richtext = RichText::parse(&args.text).build_async(&agent).await?; 43 44 println!( 45 "Detected {} facets:", 46 richtext.facets.as_ref().map(|f| f.len()).unwrap_or(0) 47 ); 48 if let Some(facets) = &richtext.facets { 49 for facet in facets { 50 let text_slice = 51 &richtext.text[facet.index.byte_start as usize..facet.index.byte_end as usize]; 52 println!(" - \"{}\" ({:?})", text_slice, facet.features); 53 } 54 } 55 56 // Create post with parsed facets 57 let post = Post { 58 text: richtext.text, 59 facets: richtext.facets, 60 created_at: Datetime::now(), 61 embed: None, 62 entities: None, 63 labels: None, 64 langs: None, 65 reply: None, 66 tags: None, 67 extra_data: Default::default(), 68 }; 69 70 let output = agent.create_record(post, None).await?; 71 println!("✓ Created post: {}", output.uri); 72 73 Ok(()) 74}