use env_logger; use std::str::FromStr; use xmpp::{action, ClientBuilder, ClientFeature, ClientType, Event}; use xmpp_parsers::{BareJid, JidParseError}; #[derive(Debug)] enum Error { Syntax(String), Jid(String, JidParseError), XMPP(tokio_xmpp::Error), } impl From for Error { fn from(e: tokio_xmpp::Error) -> Error { Error::XMPP(e) } } struct Args { jid: BareJid, password: String, room: BareJid, } impl Args { fn from_cli() -> Result, Error> { let mut args = std::env::args(); let binary_name = args.next().unwrap(); let jid = args .next() .ok_or(Error::Syntax("Missing argument: jid".into()))?; match jid.to_lowercase().as_str() { "help" | "-h" | "--help" => { help(&binary_name); return Ok(None); } _ => {} } let jid = BareJid::from_str(&jid).map_err(|e| Error::Jid(jid, e))?; let password = args .next() .ok_or(Error::Syntax("Missing argument: password".into()))?; let room = args .next() .ok_or(Error::Syntax("Missing argument: room".into()))?; let room = BareJid::from_str(&room).map_err(|e| Error::Jid(room, e))?; Ok(Some(Args { jid, password, room, })) } } fn help(name: &str) { println!("A bot that welcomes you when you say hello"); println!("Usage: {} ", name); println!("NOTE: Run with RUST_LOG=debug for debug logs"); } #[tokio::main] async fn main() -> Result<(), Error> { env_logger::init(); let args = if let Some(args) = Args::from_cli()? { args } else { return Ok(()); }; let nick = String::from("actions_bot"); // Client instance let mut client = ClientBuilder::new(args.jid.clone(), &args.password) .set_client(ClientType::Bot, "xmpp-rs") .set_website("https://gitlab.com/xmpp-rs/xmpp-rs") .set_default_nick(&nick) .enable_feature(ClientFeature::JoinRooms) .build(); while let Some(events) = client.wait_for_events().await { for event in events { match event { Event::Online => { println!("Online."); client .action(action::room_join(args.room.clone(), &nick)) .await?; } Event::Disconnected => { println!("Disconnected"); } Event::RoomMessage(_id, room_jid, author, body) => { println!( "Message in room {} from {}: {}", &room_jid, &author, &body.0 ); let msg = body.0.trim().to_lowercase(); if msg == "hello" { client .action(action::room_message( room_jid, format!("Hello, {}", &author), )) .await?; } } Event::RoomPrivateMessage(_id, room_jid, nick, body) => { println!( "Private Message from room {} from {}: {}", &room_jid, &nick, body.0 ); client .action(action::room_private_message( room_jid, nick, format!("You said: {}", body.0), )) .await?; } Event::ChatMessage(_id, jid, body) => { println!("Message from {}: {}", jid, body.0); client .action(action::message(jid, format!("You said: {}", body.0))) .await?; } Event::RoomJoined(jid) => { println!("Joined room {}.", jid); client .action(action::room_message(jid, "Hello, world!")) .await?; } _ => (), } } } Ok(()) }