A better Rust ATProto crate
102
fork

Configure Feed

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

add app password based example

authored by

afterlifepro and committed by
Orual
fe8e4b1c f9da6477

+76 -6
+27 -6
crates/jacquard/Cargo.toml
··· 17 17 # Minimal API bindings 18 18 api = ["jacquard-api/minimal"] 19 19 # Bluesky API bindings 20 - api_bluesky = ["api", "jacquard-api/bluesky" ] 20 + api_bluesky = ["api", "jacquard-api/bluesky"] 21 21 # Bluesky API bindings, plus a curated selection of community lexicons 22 - api_full = ["api", "jacquard-api/bluesky", "jacquard-api/other", "jacquard-api/lexicon_community"] 22 + api_full = [ 23 + "api", 24 + "jacquard-api/bluesky", 25 + "jacquard-api/other", 26 + "jacquard-api/lexicon_community", 27 + ] 23 28 # All captured generated lexicon API bindings 24 29 api_all = ["api_full", "jacquard-api/ufos"] 25 30 26 31 # Propagate loopback to oauth (server + browser helper) 27 32 loopback = ["jacquard-oauth/loopback", "jacquard-oauth/browser-open"] 28 33 # Enable tracing instrumentation 29 - tracing = ["dep:tracing", "jacquard-common/tracing", "jacquard-oauth/tracing", "jacquard-identity/tracing"] 34 + tracing = [ 35 + "dep:tracing", 36 + "jacquard-common/tracing", 37 + "jacquard-oauth/tracing", 38 + "jacquard-identity/tracing", 39 + ] 30 40 dns = ["jacquard-identity/dns"] 31 41 streaming = ["jacquard-common/streaming"] 32 42 websocket = ["jacquard-common/websocket"] ··· 83 93 path = "../../examples/streaming_download.rs" 84 94 required-features = ["api_bluesky", "streaming"] 85 95 96 + [[example]] 97 + name = "app_password_create_post" 98 + path = "../../examples/app_password_create_post.rs" 99 + required-features = ["api_bluesky"] 100 + 86 101 87 102 [dependencies] 88 103 jacquard-api = { version = "0.5", path = "../jacquard-api" } 89 - jacquard-common = { version = "0.5", path = "../jacquard-common", features = ["reqwest-client"] } 104 + jacquard-common = { version = "0.5", path = "../jacquard-common", features = [ 105 + "reqwest-client", 106 + ] } 90 107 jacquard-oauth = { version = "0.5", path = "../jacquard-oauth" } 91 108 jacquard-derive = { version = "0.5", path = "../jacquard-derive", optional = true } 92 109 jacquard-identity = { version = "0.5", path = "../jacquard-identity" } ··· 112 129 tracing = { workspace = true, optional = true } 113 130 114 131 [target.'cfg(not(target_arch = "wasm32"))'.dependencies] 115 - reqwest = { workspace = true, features = ["http2", "system-proxy", "rustls-tls"] } 132 + reqwest = { workspace = true, features = [ 133 + "http2", 134 + "system-proxy", 135 + "rustls-tls", 136 + ] } 116 137 tokio = { workspace = true, features = ["macros", "rt-multi-thread", "fs"] } 117 138 118 139 [target.'cfg(target_family = "wasm")'.dependencies] ··· 123 144 miette = { workspace = true, features = ["fancy"] } 124 145 125 146 [package.metadata.docs.rs] 126 - features = [ "api_all", "derive", "dns", "loopback" ] 147 + features = ["api_all", "derive", "dns", "loopback"]
+49
examples/app_password_create_post.rs
··· 1 + use clap::Parser; 2 + use jacquard::CowStr; 3 + use jacquard::api::app_bsky::feed::post::Post; 4 + use jacquard::client::{Agent, AgentSessionExt, MemoryCredentialSession}; 5 + use jacquard::types::string::Datetime; 6 + 7 + #[derive(Parser, Debug)] 8 + #[command(author, version, about = "Create a simple post")] 9 + struct Args { 10 + /// Handle (e.g., alice.bsky.social) or DID 11 + input: CowStr<'static>, 12 + 13 + /// App Password 14 + password: CowStr<'static>, 15 + 16 + /// Post text 17 + #[arg(short, long)] 18 + text: String, 19 + } 20 + 21 + #[tokio::main] 22 + async fn main() -> miette::Result<()> { 23 + let args = Args::parse(); 24 + 25 + let (session, auth) = 26 + MemoryCredentialSession::authenticated(args.input, args.password, None).await?; 27 + println!("Signed in as {}", auth.handle); 28 + 29 + let agent: Agent<_> = Agent::from(session); 30 + 31 + // Create a simple text post using the Agent convenience method 32 + let post = Post { 33 + text: CowStr::from(args.text), 34 + created_at: Datetime::now(), 35 + embed: None, 36 + entities: None, 37 + facets: None, 38 + labels: None, 39 + langs: None, 40 + reply: None, 41 + tags: None, 42 + extra_data: Default::default(), 43 + }; 44 + 45 + let output = agent.create_record(post, None).await?; 46 + println!("✓ Created post: {}", output.uri); 47 + 48 + Ok(()) 49 + }