From c4344b1ddd4c14cc5e6aaf316d41b9d011ff2995 Mon Sep 17 00:00:00 2001 From: Johannes Heuel Date: Fri, 16 Feb 2024 16:54:04 +0100 Subject: [PATCH] add delete command to clean up the channel --- src/commands/delete.rs | 44 ++++++++++++++++++++++++++++++++++++++++++ src/commands/join.rs | 15 ++++++++------ src/commands/mod.rs | 3 +++ src/handler.rs | 5 ++++- src/main.rs | 12 ++++++++++-- 5 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 src/commands/delete.rs diff --git a/src/commands/delete.rs b/src/commands/delete.rs new file mode 100644 index 0000000..ad119c1 --- /dev/null +++ b/src/commands/delete.rs @@ -0,0 +1,44 @@ +use std::{env, error::Error, num::NonZeroU64, time::Duration}; +use tokio::time::sleep; +use tracing::info; +use twilight_model::{channel::Message, id::Id}; + +use crate::state::State; + +pub(crate) async fn delete( + msg: Message, + state: State, +) -> Result<(), Box> { + let admin = env::var("ADMIN")?.parse::()?; + if msg.author.id != Id::from(NonZeroU64::new(admin).unwrap()) { + return Ok(()); + } + let n = msg + .content + .split(' ') + .last() + .unwrap() + .parse::() + .unwrap_or(1); + if n > 100 { + return Ok(()); + } + let messages = state + .http + .channel_messages(msg.channel_id) + .before(msg.id) + .limit(n)? + .await? + .model() + .await?; + state.http.delete_message(msg.channel_id, msg.id).await?; + for message in messages { + info!("Delete message: {:?}: {:?}", message.author.name, message); + state + .http + .delete_message(msg.channel_id, message.id) + .await?; + sleep(Duration::from_secs(5)).await; + } + Ok(()) +} diff --git a/src/commands/join.rs b/src/commands/join.rs index 60df9b8..4b0ef94 100644 --- a/src/commands/join.rs +++ b/src/commands/join.rs @@ -7,8 +7,8 @@ pub(crate) async fn join( msg: Message, state: State, ) -> Result<(), Box> { - let user_id = msg.author.id; let guild_id = msg.guild_id.ok_or("No guild id attached to the message.")?; + let user_id = msg.author.id; let channel_id = state .cache .voice_state(user_id, guild_id) @@ -16,16 +16,19 @@ pub(crate) async fn join( .channel_id(); let channel_id = NonZeroU64::new(channel_id.into()).ok_or("Joined voice channel must have nonzero ID.")?; - state - .songbird - .join(guild_id, channel_id) - .await - .map_err(|e| format!("Could not join voice channel: {:?}", e))?; // signal that we are not listening if let Some(call_lock) = state.songbird.get(guild_id) { let mut call = call_lock.lock().await; call.deafen(true).await?; } + + // join the voice channel + state + .songbird + .join(guild_id, channel_id) + .await + .map_err(|e| format!("Could not join voice channel: {:?}", e))?; + Ok(()) } diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 134bd4c..cb82b6f 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -19,6 +19,9 @@ pub(crate) use resume::resume; mod stop; pub(crate) use stop::stop; +mod delete; +pub(crate) use delete::delete; + use twilight_model::application::command::CommandType; use twilight_util::builder::command::{CommandBuilder, StringBuilder}; diff --git a/src/handler.rs b/src/handler.rs index 7922b91..6e5a3ba 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -1,4 +1,4 @@ -use crate::commands::{join, leave, pause, play, queue, resume, stop}; +use crate::commands::{delete, join, leave, pause, play, queue, resume, stop}; use crate::state::State; use futures::Future; @@ -16,6 +16,7 @@ enum ChatCommand { Leave(Message), Join(Message), Queue(Message), + Delete(Message), NotImplemented, } @@ -36,6 +37,7 @@ fn parse_command(event: Event) -> Option { ["!leave"] | ["!leave", _] => Some(ChatCommand::Leave(msg_create.0)), ["!join"] | ["!join", _] => Some(ChatCommand::Join(msg_create.0)), ["!queue"] | ["!queue", _] => Some(ChatCommand::Queue(msg_create.0)), + ["!delete"] | ["!delete", _] => Some(ChatCommand::Delete(msg_create.0)), _ => Some(ChatCommand::NotImplemented), } } @@ -70,6 +72,7 @@ impl Handler { Some(ChatCommand::Leave(msg)) => spawn(leave(msg, Arc::clone(&self.state))), Some(ChatCommand::Join(msg)) => spawn(join(msg, Arc::clone(&self.state))), Some(ChatCommand::Queue(msg)) => spawn(queue(msg, Arc::clone(&self.state))), + Some(ChatCommand::Delete(msg)) => spawn(delete(msg, Arc::clone(&self.state))), _ => {} } } diff --git a/src/main.rs b/src/main.rs index b4749ca..2323fd5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,12 +27,18 @@ use crate::commands::get_chat_commands; async fn main() -> Result<(), Box> { dotenv().ok(); + println!("Starting up..."); + // Initialize the tracing subscriber. tracing_subscriber::fmt::init(); + info!("Starting up..."); + let (mut shards, state) = { - let token = env::var("DISCORD_TOKEN")?; - let app_id = env::var("DISCORD_APP_ID")?.parse()?; + let token = env::var("DISCORD_TOKEN").map_err(|_| "DISCORD_TOKEN is not set")?; + let app_id = env::var("DISCORD_APP_ID") + .map_err(|_| "DISCORD_APP_ID is not set")? + .parse()?; let http = HttpClient::new(token.clone()); let user_id = http.current_user().await?.model().await?.id; @@ -74,6 +80,8 @@ async fn main() -> Result<(), Box> { ) }; + info!("Ready to receive events"); + let mut handler = Handler::new(Arc::clone(&state)); let mut stop_rx = signal_handler(); let mut stream = ShardEventStream::new(shards.iter_mut());