xmpp-rs-mirror/xmpp/examples/actions_bot.rs
2023-06-25 15:23:41 +02:00

143 lines
4.3 KiB
Rust

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<tokio_xmpp::Error> 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<Option<Args>, 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: {} <jid> <password> <room>", 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(())
}