From 85f3873bc68f28823fc4ce99ac80c7c199e0d071 Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Fri, 6 Sep 2024 16:44:01 +0200 Subject: [PATCH] Add a new command to indicate to users that they need to us the questions channel --- discord_bot/Cargo.lock | 1 + discord_bot/Cargo.toml | 1 + discord_bot/src/discord/mod.rs | 2 + discord_bot/src/discord/post_in_questions.rs | 95 +++++++++++++++++++ discord_bot/src/discord/thread_archiving.rs | 4 +- discord_bot/src/discord/thread_cleanup.rs | 26 ++--- .../src/discord/thread_closed_blocker.rs | 4 +- discord_bot/src/discord/thread_posted.rs | 4 +- .../src/discord/thread_support_answering.rs | 4 +- discord_bot/src/discord/ticket_reopen.rs | 4 +- discord_bot/src/main.rs | 10 +- discord_bot/src/webhooks/tasks.rs | 4 +- 12 files changed, 132 insertions(+), 27 deletions(-) create mode 100644 discord_bot/src/discord/post_in_questions.rs diff --git a/discord_bot/Cargo.lock b/discord_bot/Cargo.lock index 989f16aa54..bc16c84b87 100644 --- a/discord_bot/Cargo.lock +++ b/discord_bot/Cargo.lock @@ -691,6 +691,7 @@ dependencies = [ "itertools", "once_cell", "poise", + "rand", "reqwest", "serde", "serde_json", diff --git a/discord_bot/Cargo.toml b/discord_bot/Cargo.toml index e4e9005923..e54cf66425 100644 --- a/discord_bot/Cargo.toml +++ b/discord_bot/Cargo.toml @@ -19,6 +19,7 @@ indoc = "2.0.4" itertools = "0.12.0" once_cell = "1.19.0" poise = "0.6.1" +rand = "0.8.5" reqwest = { version = "0.11.23", features = ["json"] } serde = { version = "1.0.195", features = ["derive"] } serde_json = "1.0.111" diff --git a/discord_bot/src/discord/mod.rs b/discord_bot/src/discord/mod.rs index b30c30f501..4a1115962e 100644 --- a/discord_bot/src/discord/mod.rs +++ b/discord_bot/src/discord/mod.rs @@ -1,5 +1,6 @@ mod close_ticket; mod create_task; +mod post_in_questions; mod support_answering; mod task_fixed; mod thread_archiving; @@ -11,6 +12,7 @@ mod ticket_reopen; pub use close_ticket::*; pub use create_task::*; +pub use post_in_questions::*; pub use support_answering::*; pub use task_fixed::*; pub use thread_archiving::*; diff --git a/discord_bot/src/discord/post_in_questions.rs b/discord_bot/src/discord/post_in_questions.rs new file mode 100644 index 0000000000..b368096774 --- /dev/null +++ b/discord_bot/src/discord/post_in_questions.rs @@ -0,0 +1,95 @@ +use poise::{serenity_prelude::Mentionable, CreateReply}; +use rand::prelude::*; +use rand::seq::SliceRandom; +use rand::SeedableRng; +use std::time::{SystemTime, UNIX_EPOCH}; + +use crate::{check_is_contributor, Context, WinstonError, QUESTIONS_CHANNEL}; + +#[poise::command( + context_menu_command = "Post In Questions", + ephemeral, + check = "check_is_contributor" +)] +pub async fn post_in_questions( + ctx: Context<'_>, + #[description = "The message to reply to"] message: poise::serenity_prelude::Message, +) -> Result<(), WinstonError> { + let seed = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards") + .as_nanos(); + let mut rng = StdRng::seed_from_u64(seed as u64); + let reply = REPLIES + .choose(&mut rng) + .unwrap_or(&"Please use the questions channel.") + .replace("{channel}", &QUESTIONS_CHANNEL.mention().to_string()); + + message.reply_ping(ctx, reply).await?; + + ctx.reply("Replied to the question with").await?; + Ok(()) +} + +const REPLIES: &[&str] = &[ +"Oops! Looks like your question took a wrong turn. The {channel} is just around the corner! 🧭", +"Hold up! Your awesome question deserves a spotlight in our dedicated {channel}. It's like VIP treatment for curiosity! ✨", +"Psst... I heard the {channel} is throwing a party, and your question is the guest of honor! πŸŽ‰", +"Alert! Question detected in a question-free zone. Quick, teleport it to the {channel} before it gets lonely! πŸš€", +"Beep boop! My question sensors are tingling. May I suggest a cozy new home for your query in our dedicated {channel}? 🏠", +"Whoa there, curious cat! Your question is purr-fect for our special {channel}. It's feline fine over there! 🐱", +"Holy guacamole! Your question is so good, it deserves its own red carpet in the {channel}. Shall we roll it out? πŸ₯‘", +"Great Scott! Your question has traveled through time and space. Quick, let's redirect it to its true destination: the {channel}! ⏰", +"Woah, easy there, speed racer! Your question's burning rubber in the wrong lane. Want to cruise over to the {channel}? 🏎️", +"Shiver me timbers! Ye be asking questions in strange waters. How about we set sail for the {channel}, matey? ☠️", +"Bazinga! Your question is so smart, it deserves to hang out with its brainy buddies in the {channel}. Wadda ya say? 🧠", +"Kaboom! Your question just exploded with awesomeness. Let's clean up the glitter and move this party to the {channel}! πŸŽ†", +"Abracadabra! Your question's magical, but it needs the special enchanted grounds of the {channel} to truly shine! ✨", +"Cowabunga, dude! Your question's surfing the wrong waves. Let's catch the perfect curl over in the {channel}! πŸ„β€β™‚οΈ", +"Great galaxies! Your question's out of this world, but it's landed in the wrong solar system. Shall we warp to the {channel}? πŸš€", +"Jeepers creepers! Your question's giving me the heebie-jeebies... of excitement! Let's exorcise it over to the {channel}! πŸ‘»", +"Holy moly guacamole! Your question's spicier than a jalapeΓ±o popper. Let's cool it off in the refreshing waters of the {channel}! 🌢️", +"Gadzooks! Your question's got more buzz than a beehive. Let's guide this busy bee to its proper flower in the {channel}! 🐝", +"Jumpin' Jehoshaphat! Your question's bouncing off the walls. Let's give it a proper trampoline in the {channel}! πŸƒβ€β™‚οΈ", +"Lickety-split! Your question's faster than greased lightning. Let's race it over to the {channel} for a photo finish! 🏁", +"Mama mia! Your question's spicier than a pepperoni pizza. Let's serve this hot slice in the {channel}! πŸ•", +"Quibble me timbers! Your question's stirring up a storm in a teacup. Let's sail these choppy waters to the {channel}! β˜•", +"Tally-ho! Your question's on a fox hunt in the wrong field. Let's guide the hounds to the {channel} for the real chase! 🦊", +"Uber-cool! Your question's chillin' like a villain in the wrong hood. Let's cruise over to the {channel} in style! 😎", +"Voila! Your question's appeared like magic, but in the wrong hat! Let's pull this rabbit out in the {channel} instead! 🎩", +"Xtra! Xtra! Read all about it! Your question's making headlines in the wrong paper. Let's print the edition in the {channel}! πŸ“°", +"Zoinks! Your question's got more mystery than a Scooby-Doo episode. Let's unmask this villain in the {channel}! πŸ•΅οΈβ€β™‚οΈ", +"Zing! Your question's sharper than a tack. Let's pin this brilliant idea in the {channel} board! πŸ“Œ", +"Aye aye, captain! Your question's sailing in uncharted waters. Let's navigate to the safe harbor of the {channel}! βš“", +"Bada bing, bada boom! Your question's explosive, but it's in the wrong fireworks show. Let's light it up in the {channel}! πŸ’₯", +"Cha-ching! Your question's worth its weight in gold. Let's cash in this treasure in the {channel}! πŸ’°", +"Gee whiz! Your question's fizzier than a shaken soda. Let's pop the top in the {channel}! πŸ₯€", +"Ipso facto! Your question's presenting its case in the wrong court. Let's adjourn to the {channel} for the verdict! βš–οΈ", +"Mamma mia! Your question's saucier than a pizza with extra toppings. Let's slice and dice in the {channel}! πŸ•", +"Oh my stars and garters! Your question's more shocking than static electricity. Let's ground ourselves in the {channel}! ⚑", +"Pish posh! Your question's fancier than a teacup at the Queen's garden party. Let's sip and chat in the {channel}! β˜•πŸ‘‘", +"Querulous quails! Your question's ruffling feathers in the wrong coop. Let's migrate to the {channel} for nesting! 🐦", +"Razzle dazzle! Your question's shinier than a disco ball. Let's boogie on over to the {channel}! πŸ•Ί", +"Upsy-daisy! Your question's tumbled into the wrong ball pit. Let's bounce over to the fun zone in the {channel}! πŸ€", +"Vroom vroom! Your question's revving its engine at the wrong starting line. Let's zoom to the real race in the {channel}! 🏎️", +"Whoop-de-doo! Your question's doing cartwheels in the wrong circus. Let's flip over to the big top in the {channel}! πŸŽͺ", +"Xylophone! Your question's playing a beautiful tune, but in the wrong orchestra pit. Let's conduct this symphony in the {channel}! 🎼", +"Yum yum! Your question's deliciously intriguing, but it's on the wrong menu. Let's serve this gourmet dish in the {channel}! 🍽️", +"Bazinga! Your question's got more twists than a pretzel factory. Let's unravel this mystery in the {channel}! πŸ₯¨", +"Cowabunga! Your question's riding a gnarly wave, dude. Let's catch the perfect curl in the {channel}! πŸ„β€β™‚οΈ", +"Dagnabbit! Your question's digging for gold in the wrong mine. Let's strike it rich in the {channel}! β›οΈπŸ’°", +"Eureka! Your question's a golden discovery, but it's floating in the wrong bathtub. Let's make a splash in the {channel}! πŸ›", +"Fiddlesticks! Your question's playing a solo when we need a full orchestra. Let's tune up in the {channel}! 🎻", +"Hocus pocus! Your question's casting spells in the wrong wizard's tower. Let's find the right potion in the {channel}! πŸ§™β€β™‚οΈ", +"Inconceivable! Your question's scaling the wrong castle wall. Let's storm the correct fortress in the {channel}! 🏰", +"Jiminy Cricket! Your question's chirping up a storm, but in the wrong garden. Let's find the right leaf in the {channel}! πŸ¦—", +"Merlin's beard! Your question's more magical than a wizard's duel. Let's cast this spell in the {channel}! πŸ§™β€β™‚οΈβœ¨", +"Noodle noggin! Your question's got my brain tied up like spaghetti. Let's untangle this pasta in the {channel}! 🍝", +"Ubiquitous unicorns! Your question's sprouting rainbows in the wrong meadow. Let's prance to the magical {channel}! πŸ¦„", +"Vertigo! Your question's got me spinning like a top. Let's find our balance in the {channel}! πŸ’«", +"Xenon! Your question's glowing brighter than a noble gas. Let's light up the {channel} with this brilliance! πŸ’‘", +"Egad! Your question's more surprising than a jack-in-the-box. Let's pop this lid in the {channel}! 🎁", +"Great Scott! Your question's generating 1.21 gigawatts of curiosity. Let's time travel to the {channel} for answers! βš‘πŸš—", +"Indubitably! Your question's more mysterious than a Sherlock Holmes case. Let's deduce the answer in the {channel}, Watson! πŸ•΅οΈβ€β™‚οΈ", +"Leaping Leprechauns! Your question's luckier than a four-leaf clover. Let's find the pot of gold in the {channel}! πŸ€", +]; diff --git a/discord_bot/src/discord/thread_archiving.rs b/discord_bot/src/discord/thread_archiving.rs index e41cbb3503..ec17ecf16f 100644 --- a/discord_bot/src/discord/thread_archiving.rs +++ b/discord_bot/src/discord/thread_archiving.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use poise::serenity_prelude::{Context, EditThread, EventHandler, GuildChannel}; -use crate::{CloseReason, TICKET_FORUM_ID}; +use crate::{CloseReason, QUESTIONS_FORUM_ID}; pub struct ThreadArchivingHandler; @@ -39,7 +39,7 @@ impl EventHandler for ThreadArchivingHandler { return; }; - if parent.id != TICKET_FORUM_ID { + if parent.id != QUESTIONS_FORUM_ID { return; } diff --git a/discord_bot/src/discord/thread_cleanup.rs b/discord_bot/src/discord/thread_cleanup.rs index 5e4405b666..87777de174 100644 --- a/discord_bot/src/discord/thread_cleanup.rs +++ b/discord_bot/src/discord/thread_cleanup.rs @@ -6,14 +6,13 @@ use poise::serenity_prelude::{ }; use crate::{ - get_discord, webhooks::GetTagId, CloseReason, WinstonError, GUILD_ID, TICKET_FORUM_ID, + get_discord, webhooks::GetTagId, CloseReason, WinstonError, GUILD_ID, QUESTIONS_CHANNEL, QUESTIONS_FORUM_ID }; pub async fn cleanup_threads() -> Result<(), WinstonError> { let discord = get_discord()?; - let channel_id: ChannelId = TICKET_FORUM_ID.into(); - let guild_channel = channel_id + let guild_channel = QUESTIONS_CHANNEL .to_channel(&discord) .await? .guild() @@ -64,7 +63,7 @@ async fn is_ticket_forum_thread(channel: &channel::GuildChannel) -> bool { return false; }; - parent.get() == TICKET_FORUM_ID + parent.get() == QUESTIONS_FORUM_ID } async fn archive_thread( @@ -109,6 +108,16 @@ async fn resolve_answered_thread( println!("Auto Resolving thread {} ({})", thread.id, thread.name()); + + // Close the thread + let Some(resolved_tag) = available_tags.get_tag_id("resolved") else { + return Err(WinstonError::TagNotFound("resolved".to_string())); + }; + + thread + .edit_thread(&discord, EditThread::default().applied_tags([resolved_tag])) + .await?; + let owner_id = thread.owner_id.ok_or(WinstonError::NotAThreadChannel)?; thread @@ -135,15 +144,6 @@ async fn resolve_answered_thread( ) .await?; - // Close the thread - let Some(resolved_tag) = available_tags.get_tag_id("resolved") else { - return Err(WinstonError::TagNotFound("resolved".to_string())); - }; - - thread - .edit_thread(&discord, EditThread::default().applied_tags([resolved_tag])) - .await?; - Ok(()) } diff --git a/discord_bot/src/discord/thread_closed_blocker.rs b/discord_bot/src/discord/thread_closed_blocker.rs index c2d753da00..9d4d0411a2 100644 --- a/discord_bot/src/discord/thread_closed_blocker.rs +++ b/discord_bot/src/discord/thread_closed_blocker.rs @@ -4,7 +4,7 @@ use poise::serenity_prelude::{ Context, CreateMessage, EditMessage, EventHandler, Mentionable, Message, }; -use crate::{CloseReason, TICKET_FORUM_ID}; +use crate::{CloseReason, QUESTIONS_FORUM_ID}; pub struct ThreadClosedBlockerHandler; @@ -40,7 +40,7 @@ impl EventHandler for ThreadClosedBlockerHandler { return; }; - if parent.id != TICKET_FORUM_ID { + if parent.id != QUESTIONS_FORUM_ID { return; } diff --git a/discord_bot/src/discord/thread_posted.rs b/discord_bot/src/discord/thread_posted.rs index afe9e8d31d..aa783b9388 100644 --- a/discord_bot/src/discord/thread_posted.rs +++ b/discord_bot/src/discord/thread_posted.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use poise::serenity_prelude::{Context, EditThread, EventHandler, GuildChannel}; -use crate::{webhooks::GetTagId, TICKET_FORUM_ID}; +use crate::{webhooks::GetTagId, QUESTIONS_FORUM_ID}; pub struct ThreadPostedHandler; @@ -23,7 +23,7 @@ impl EventHandler for ThreadPostedHandler { return; }; - if parent.id != TICKET_FORUM_ID { + if parent.id != QUESTIONS_FORUM_ID { return; } diff --git a/discord_bot/src/discord/thread_support_answering.rs b/discord_bot/src/discord/thread_support_answering.rs index 51f97b90d6..debb8b2213 100644 --- a/discord_bot/src/discord/thread_support_answering.rs +++ b/discord_bot/src/discord/thread_support_answering.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use poise::serenity_prelude::{Context, EditThread, EventHandler, Message}; -use crate::{webhooks::GetTagId, CONTRIBUTOR_ROLE_ID, GUILD_ID, TICKET_FORUM_ID}; +use crate::{webhooks::GetTagId, CONTRIBUTOR_ROLE_ID, GUILD_ID, QUESTIONS_FORUM_ID}; pub struct SupportAnsweringHandler; @@ -37,7 +37,7 @@ impl EventHandler for SupportAnsweringHandler { return; }; - if parent.id != TICKET_FORUM_ID { + if parent.id != QUESTIONS_FORUM_ID { return; } diff --git a/discord_bot/src/discord/ticket_reopen.rs b/discord_bot/src/discord/ticket_reopen.rs index 222bbc5d95..6b4571dc7c 100644 --- a/discord_bot/src/discord/ticket_reopen.rs +++ b/discord_bot/src/discord/ticket_reopen.rs @@ -5,7 +5,7 @@ use poise::serenity_prelude::{ CreateQuickModal, EditThread, EventHandler, Interaction, Timestamp, }; -use crate::{check_permissions, webhooks::GetTagId, CONTRIBUTOR_ROLE_ID, TICKET_FORUM_ID}; +use crate::{check_permissions, webhooks::GetTagId, CONTRIBUTOR_ROLE_ID, QUESTIONS_FORUM_ID}; pub struct TicketReopenHandler; @@ -79,7 +79,7 @@ impl EventHandler for TicketReopenHandler { return; }; - if parent.id != TICKET_FORUM_ID { + if parent.id != QUESTIONS_FORUM_ID { return; } diff --git a/discord_bot/src/main.rs b/discord_bot/src/main.rs index 678695d837..901818aea6 100644 --- a/discord_bot/src/main.rs +++ b/discord_bot/src/main.rs @@ -26,7 +26,8 @@ pub type ApplicationContext<'a> = poise::ApplicationContext<'a, Data, WinstonErr const GUILD_ID: serenity::GuildId = serenity::GuildId::new(1054708062520360960); const CONTRIBUTOR_ROLE_ID: serenity::RoleId = serenity::RoleId::new(1054708457535713350); -const TICKET_FORUM_ID: u64 = 1199700329948782613; +const QUESTIONS_FORUM_ID: u64 = 1199700329948782613; +const QUESTIONS_CHANNEL: serenity::ChannelId = serenity::ChannelId::new(QUESTIONS_FORUM_ID); const CLICKUP_LIST_ID: &str = "901502296591"; const CLICKUP_USER_ID: u32 = 62541886; @@ -127,7 +128,12 @@ async fn startup_discord_bot() { let framework = poise::Framework::builder() .options(poise::FrameworkOptions { - commands: vec![create_task(), close_ticket(), support_answering()], + commands: vec![ + create_task(), + close_ticket(), + support_answering(), + post_in_questions(), + ], on_error: |error| Box::pin(on_error(error)), ..Default::default() }) diff --git a/discord_bot/src/webhooks/tasks.rs b/discord_bot/src/webhooks/tasks.rs index c6a1fbcef2..3d42c6aed0 100644 --- a/discord_bot/src/webhooks/tasks.rs +++ b/discord_bot/src/webhooks/tasks.rs @@ -3,8 +3,8 @@ use std::collections::HashMap; use indoc::formatdoc; use itertools::Itertools; use poise::serenity_prelude::{ - futures::TryFutureExt, ButtonStyle, ChannelId, CreateButton, CreateMessage, EditThread, - ForumTag, ForumTagId, Mentionable, ReactionType, UserId, + ButtonStyle, ChannelId, CreateButton, CreateMessage, EditThread, ForumTag, ForumTagId, + Mentionable, ReactionType, UserId, }; use crate::{