diff --git a/euphoxide-bot/Cargo.toml b/euphoxide-bot/Cargo.toml index 988a1d7..e3ad556 100644 --- a/euphoxide-bot/Cargo.toml +++ b/euphoxide-bot/Cargo.toml @@ -10,5 +10,11 @@ log = { workspace = true } tokio = { workspace = true, features = ["rt"] } tokio-tungstenite = { workspace = true } +[dev-dependencies] +anyhow = { workspace = true } +rustls = { workspace = true } +tokio = { workspace = true, features = ["full"] } +tokio-tungstenite = { workspace = true, features = ["rustls-tls-native-roots"] } + [lints] workspace = true diff --git a/euphoxide-bot/examples/examplebot_instance.rs b/euphoxide-bot/examples/examplebot_instance.rs new file mode 100644 index 0000000..bf58734 --- /dev/null +++ b/euphoxide-bot/examples/examplebot_instance.rs @@ -0,0 +1,99 @@ +use std::time::Duration; + +use euphoxide::{ + api::{Data, Message, Nick, Send}, + client::conn::ClientConnHandle, +}; +use euphoxide_bot::{Instance, InstanceEvent, ServerConfig}; +use tokio::sync::mpsc; + +async fn set_nick(conn: &ClientConnHandle) -> anyhow::Result<()> { + conn.send_only(Nick { + name: "examplebot".to_string(), + }) + .await?; + + Ok(()) +} + +async fn send_pong(conn: &ClientConnHandle, msg: Message) -> anyhow::Result<()> { + conn.send_only(Send { + content: "Pong!".to_string(), + parent: Some(msg.id), + }) + .await?; + + Ok(()) +} + +async fn send_pyramid(conn: &ClientConnHandle, msg: Message) -> anyhow::Result<()> { + let mut parent = msg.id; + + for _ in 0..3 { + let first = conn + .send(Send { + content: "brick".to_string(), + parent: Some(parent), + }) + .await?; + + conn.send_only(Send { + content: "brick".to_string(), + parent: Some(parent), + }) + .await?; + + parent = first.await?.0.id; + tokio::time::sleep(Duration::from_secs(1)).await; + } + + conn.send_only(Send { + content: "brick".to_string(), + parent: Some(parent), + }) + .await?; + + Ok(()) +} + +async fn on_data(conn: ClientConnHandle, data: Data) { + let result = match data { + Data::SnapshotEvent(_) => set_nick(&conn).await, + Data::SendEvent(event) if event.0.content == "!ping" => send_pong(&conn, event.0).await, + Data::SendEvent(event) if event.0.content == "!pyramid" => { + send_pyramid(&conn, event.0).await + } + _ => Ok(()), + }; + + if let Err(err) = result { + println!("Error while responding: {err}"); + } +} + +async fn run() -> anyhow::Result<()> { + let config = ServerConfig::default() + .instance("test") + .with_username("examplebot"); + + let (event_tx, mut event_rx) = mpsc::channel(10); + let _instance = Instance::new((), config, event_tx); // Don't drop or instance stops + + while let Some(event) = event_rx.recv().await { + if let InstanceEvent::Packet { conn, packet, .. } = event { + let data = packet.into_data()?; + tokio::task::spawn(on_data(conn, data)); + } + } + + Ok(()) +} + +#[tokio::main] +async fn main() { + loop { + if let Err(err) = run().await { + println!("Error while running: {err}"); + } + } +}