use futures::stream::StreamExt; use std::env::args; use std::process::exit; use std::str::FromStr; use tokio_xmpp::{Client, Stanza}; use xmpp_parsers::{ disco::{DiscoInfoQuery, DiscoInfoResult}, iq::{Iq, IqType}, jid::{BareJid, Jid}, ns, server_info::ServerInfo, }; #[tokio::main] async fn main() { env_logger::init(); let args: Vec = args().collect(); if args.len() != 4 { println!("Usage: {} ", args[0]); exit(1); } let jid = BareJid::from_str(&args[1]).expect(&format!("Invalid JID: {}", &args[1])); let password = args[2].clone(); let target = &args[3]; // Client instance let mut client = Client::new(jid, password); // Main loop, processes events while let Some(event) = client.next().await { if event.is_online() { println!("Online!"); let target_jid: Jid = target.clone().parse().unwrap(); let iq = make_disco_iq(target_jid); println!("Sending disco#info request to {}", target.clone()); println!(">> {:?}", iq); client.send_stanza(iq.into()).await.unwrap(); } else if let Some(Stanza::Iq(iq)) = event.into_stanza() { if let IqType::Result(Some(payload)) = iq.payload { if payload.is("query", ns::DISCO_INFO) { if let Ok(disco_info) = DiscoInfoResult::try_from(payload) { for ext in disco_info.extensions { if let Ok(server_info) = ServerInfo::try_from(ext) { print_server_info(server_info); } } } } break; } } } client.send_end().await.expect("Stream shutdown unclean"); } fn make_disco_iq(target: Jid) -> Iq { Iq::from_get("disco", DiscoInfoQuery { node: None }) .with_id(String::from("contact")) .with_to(target) } fn convert_field(field: Vec) -> String { field .iter() .fold((field.len(), String::new()), |(l, mut acc), s| { acc.push('<'); acc.push_str(&s); acc.push('>'); if l > 1 { acc.push(','); acc.push(' '); } (0, acc) }) .1 } fn print_server_info(server_info: ServerInfo) { if server_info.abuse.len() != 0 { println!("abuse: {}", convert_field(server_info.abuse)); } if server_info.admin.len() != 0 { println!("admin: {}", convert_field(server_info.admin)); } if server_info.feedback.len() != 0 { println!("feedback: {}", convert_field(server_info.feedback)); } if server_info.sales.len() != 0 { println!("sales: {}", convert_field(server_info.sales)); } if server_info.security.len() != 0 { println!("security: {}", convert_field(server_info.security)); } if server_info.support.len() != 0 { println!("support: {}", convert_field(server_info.support)); } }