v2_send_once/
v2_send_once.rs1use vector_sdk::VectorBot;
11
12#[tokio::main]
13async fn main() -> vector_sdk::Result<()> {
14 let mut args = std::env::args().skip(1);
15 let invite = args.next().expect("arg 1: invite link");
16 let channel_name = args.next().expect("arg 2: channel name");
17 let text = args.next().expect("arg 3: message text");
18
19 let data_dir = std::env::temp_dir().join("v2_send_once_data");
20 let bot = VectorBot::builder().data_dir(&data_dir).build().await?;
21 println!("── sender online as {}", bot.npub());
22
23 println!("── joining via link…");
24 let summary = bot.core().join_community(&invite).await?;
25 let name = summary.get("name").and_then(|v| v.as_str()).unwrap_or("?");
26 println!("── joined \"{name}\"");
27
28 let mut channel_id: Option<String> = None;
31 for attempt in 0..10 {
32 for c in bot.core().list_communities().await {
33 if c.get("version").and_then(|v| v.as_u64()) != Some(2) {
34 continue;
35 }
36 let Some(chans) = c.get("channels").and_then(|v| v.as_array()) else { continue };
37 for ch in chans {
38 if ch.get("name").and_then(|n| n.as_str()) == Some(channel_name.as_str()) {
39 channel_id = ch.get("channel_id").and_then(|i| i.as_str()).map(String::from);
40 }
41 }
42 }
43 if channel_id.is_some() {
44 break;
45 }
46 if attempt == 0 {
47 println!("── \"{channel_name}\" not in the join snapshot; syncing for the control fold…");
48 }
49 let _ = bot.core().sync_communities().await;
50 tokio::time::sleep(std::time::Duration::from_secs(2)).await;
51 }
52 let Some(channel_id) = channel_id else {
53 eprintln!("!! channel \"{channel_name}\" never appeared; giving up");
54 std::process::exit(1);
55 };
56 println!("── channel \"{channel_name}\" = {channel_id}");
57
58 match bot.channel(&channel_id).send(&text).await {
59 Ok(id) => println!("── sent ✅ message id {id}"),
60 Err(e) => {
61 eprintln!("!! send failed: {e}");
62 std::process::exit(1);
63 }
64 }
65 tokio::time::sleep(std::time::Duration::from_secs(5)).await;
67 Ok(())
68}