From fe8e4b1cb47d54aa18699c838a2245672eb5e50c Mon Sep 17 00:00:00 2001 From: afterlifepro Date: Thu, 16 Oct 2025 21:08:08 +0100 Subject: [PATCH] add app password based example --- crates/jacquard/Cargo.toml | 33 +++++++++++++++---- examples/app_password_create_post.rs | 49 ++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 examples/app_password_create_post.rs diff --git a/crates/jacquard/Cargo.toml b/crates/jacquard/Cargo.toml index ce9c10fe0..3ae3f4929 100644 --- a/crates/jacquard/Cargo.toml +++ b/crates/jacquard/Cargo.toml @@ -17,16 +17,26 @@ derive = ["dep:jacquard-derive"] # Minimal API bindings api = ["jacquard-api/minimal"] # Bluesky API bindings -api_bluesky = ["api", "jacquard-api/bluesky" ] +api_bluesky = ["api", "jacquard-api/bluesky"] # Bluesky API bindings, plus a curated selection of community lexicons -api_full = ["api", "jacquard-api/bluesky", "jacquard-api/other", "jacquard-api/lexicon_community"] +api_full = [ + "api", + "jacquard-api/bluesky", + "jacquard-api/other", + "jacquard-api/lexicon_community", +] # All captured generated lexicon API bindings api_all = ["api_full", "jacquard-api/ufos"] # Propagate loopback to oauth (server + browser helper) loopback = ["jacquard-oauth/loopback", "jacquard-oauth/browser-open"] # Enable tracing instrumentation -tracing = ["dep:tracing", "jacquard-common/tracing", "jacquard-oauth/tracing", "jacquard-identity/tracing"] +tracing = [ + "dep:tracing", + "jacquard-common/tracing", + "jacquard-oauth/tracing", + "jacquard-identity/tracing", +] dns = ["jacquard-identity/dns"] streaming = ["jacquard-common/streaming"] websocket = ["jacquard-common/websocket"] @@ -83,10 +93,17 @@ name = "streaming_download" path = "../../examples/streaming_download.rs" required-features = ["api_bluesky", "streaming"] +[[example]] +name = "app_password_create_post" +path = "../../examples/app_password_create_post.rs" +required-features = ["api_bluesky"] + [dependencies] jacquard-api = { version = "0.5", path = "../jacquard-api" } -jacquard-common = { version = "0.5", path = "../jacquard-common", features = ["reqwest-client"] } +jacquard-common = { version = "0.5", path = "../jacquard-common", features = [ + "reqwest-client", +] } jacquard-oauth = { version = "0.5", path = "../jacquard-oauth" } jacquard-derive = { version = "0.5", path = "../jacquard-derive", optional = true } jacquard-identity = { version = "0.5", path = "../jacquard-identity" } @@ -112,7 +129,11 @@ rand_core.workspace = true tracing = { workspace = true, optional = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -reqwest = { workspace = true, features = ["http2", "system-proxy", "rustls-tls"] } +reqwest = { workspace = true, features = [ + "http2", + "system-proxy", + "rustls-tls", +] } tokio = { workspace = true, features = ["macros", "rt-multi-thread", "fs"] } [target.'cfg(target_family = "wasm")'.dependencies] @@ -123,4 +144,4 @@ clap.workspace = true miette = { workspace = true, features = ["fancy"] } [package.metadata.docs.rs] -features = [ "api_all", "derive", "dns", "loopback" ] +features = ["api_all", "derive", "dns", "loopback"] diff --git a/examples/app_password_create_post.rs b/examples/app_password_create_post.rs new file mode 100644 index 000000000..50701dbae --- /dev/null +++ b/examples/app_password_create_post.rs @@ -0,0 +1,49 @@ +use clap::Parser; +use jacquard::CowStr; +use jacquard::api::app_bsky::feed::post::Post; +use jacquard::client::{Agent, AgentSessionExt, MemoryCredentialSession}; +use jacquard::types::string::Datetime; + +#[derive(Parser, Debug)] +#[command(author, version, about = "Create a simple post")] +struct Args { + /// Handle (e.g., alice.bsky.social) or DID + input: CowStr<'static>, + + /// App Password + password: CowStr<'static>, + + /// Post text + #[arg(short, long)] + text: String, +} + +#[tokio::main] +async fn main() -> miette::Result<()> { + let args = Args::parse(); + + let (session, auth) = + MemoryCredentialSession::authenticated(args.input, args.password, None).await?; + println!("Signed in as {}", auth.handle); + + let agent: Agent<_> = Agent::from(session); + + // Create a simple text post using the Agent convenience method + let post = Post { + text: CowStr::from(args.text), + created_at: Datetime::now(), + embed: None, + entities: None, + facets: None, + labels: None, + langs: None, + reply: None, + tags: None, + extra_data: Default::default(), + }; + + let output = agent.create_record(post, None).await?; + println!("✓ Created post: {}", output.uri); + + Ok(()) +} -- 2.51.2