From 14a1052cd86ae941143491829de235ac6fd5ea46 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Mon, 27 Mar 2023 01:00:35 +0200 Subject: [PATCH] feat: clone message to create a poll --- src/commands/misc.rs | 68 +++++++++++++++++++++++--------------------- src/utils/embed.rs | 26 ----------------- src/utils/message.rs | 55 +++++++++++++++++++++++++++++++++++ src/utils/mod.rs | 2 +- 4 files changed, 92 insertions(+), 59 deletions(-) delete mode 100644 src/utils/embed.rs create mode 100644 src/utils/message.rs diff --git a/src/commands/misc.rs b/src/commands/misc.rs index 87736b7..031a75f 100644 --- a/src/commands/misc.rs +++ b/src/commands/misc.rs @@ -1,7 +1,7 @@ -use chrono::Utc; -use poise::serenity_prelude::{self as serenity, MessageId, ReactionType}; +use poise::serenity_prelude::{self as serenity, MessageId, ParseValue, ReactionType}; use poise::ReplyHandle; +use crate::utils::message::clone_message; use crate::{Context, Error}; /// Make the Discord bot sentient. @@ -50,43 +50,47 @@ pub async fn reply( #[poise::command(slash_command)] pub async fn poll( ctx: Context<'_>, - #[description = "The id of the poll"] id: u64, - #[description = "The poll message"] message: String, - #[description = "The poll title"] title: String, + #[description = "The id of the poll"] id: u64, /* This is currently unused in the API, leaving as a placeholder in case it is required. */ + #[description = "The link to a message to clone"] message_link: String, #[description = "The minumum server age in days to allow members to poll"] age: u16, ) -> Result<(), Error> { - let data = ctx.data().read().await; - let configuration = &data.configuration; - let embed_color = configuration.general.embed_color; + let get_id = + |segments: &mut std::str::Split| segments.next_back().unwrap().parse::(); + + let url = reqwest::Url::parse(&message_link)?; + let mut segments = url.path_segments().ok_or("Invalid Discord message link")?; + + if segments.clone().count() != 4 { + return Err("Invalid Discord message link".into()); + } + + let message_id = get_id(&mut segments)?; + let channel_id = get_id(&mut segments)?; + + let message = ctx + .discord() + .http + .get_message(channel_id, message_id) + .await?; ctx.send(|m| { - m.embed(|e| { - let guild = &ctx.guild().unwrap(); - if let Some(url) = guild.icon_url() { - e.thumbnail(url.clone()).footer(|f| { - f.icon_url(url).text(format!( - "{} • {}", - guild.name, - Utc::today().format("%Y/%m/%d") - )) - }) - } else { - e - } - .title(title) - .description(message) - .color(embed_color) - }) - .components(|c| { - c.create_action_row(|r| { - r.create_button(|b| { - b.label("Vote") - .emoji(ReactionType::Unicode("🗳️".to_string())) - .custom_id(format!("poll:{id}:{age}")) + clone_message(&message, m) + .components(|c| { + c.create_action_row(|r| { + r.create_button(|b| { + b.label("Vote") + .emoji(ReactionType::Unicode("🗳️".to_string())) + .custom_id(format!("poll:{id}:{age}")) + }) }) }) - }) + .allowed_mentions(|am| { + am.parse(ParseValue::Users) + .parse(ParseValue::Roles) + .parse(ParseValue::Everyone) + }) }) .await?; + Ok(()) } diff --git a/src/utils/embed.rs b/src/utils/embed.rs deleted file mode 100644 index b6d0815..0000000 --- a/src/utils/embed.rs +++ /dev/null @@ -1,26 +0,0 @@ -use poise::serenity_prelude::CreateEmbed; - -trait PoiseEmbed { - fn create_embed(self, embed: &mut CreateEmbed) -> &mut CreateEmbed; -} - -impl PoiseEmbed for crate::model::application::Embed { - fn create_embed(self, embed: &mut CreateEmbed) -> &mut CreateEmbed { - embed - .title(self.title) - .description(self.description) - .color(self.color) - .fields( - self.fields - .iter() - .map(|field| (field.name.clone(), field.value.clone(), field.inline)), - ) - .footer(|f| { - f.text(self.footer.text); - f.icon_url(self.footer.icon_url) - }) - .thumbnail(self.thumbnail.url) - .image(self.image.url) - .author(|a| a.name(self.author.name).icon_url(self.author.icon_url)) - } -} diff --git a/src/utils/message.rs b/src/utils/message.rs new file mode 100644 index 0000000..d6a9fff --- /dev/null +++ b/src/utils/message.rs @@ -0,0 +1,55 @@ +use chrono::Utc; +use poise::serenity_prelude::Message; +use poise::CreateReply; + +pub fn clone_message<'a, 'b>( + message: &'a Message, + to_reply: &'b mut CreateReply<'a>, +) -> &'b mut CreateReply<'a> { + let mut reply = to_reply.content(message.content.as_str()); + + if let Some(embed) = message.embeds.get(0) { + reply = reply.embed(|e| { + let mut new_embed = e; + + if let Some(color) = embed.colour { + new_embed = new_embed.color(color); + } + + new_embed = new_embed.timestamp(Utc::now().to_rfc3339()); + + if let Some(title) = &embed.title { + new_embed = new_embed.title(title); + } + + if let Some(description) = &embed.description { + new_embed = new_embed.description(description); + } + + if let Some(footer) = &embed.footer { + new_embed = new_embed.footer(|f| f.text(&footer.text)); + } + + if let Some(author) = &embed.author { + new_embed = new_embed.author(|a| a.name(&author.name)); + } + + if let Some(image) = &embed.image { + new_embed = new_embed.image(image.url.as_str()); + } + + if let Some(thumbnail) = &embed.thumbnail { + new_embed = new_embed.thumbnail(thumbnail.url.as_str()); + } + + for field in &embed.fields { + new_embed = + new_embed.field(field.name.as_str(), field.value.as_str(), field.inline); + } + + new_embed + }) + } + + reply +} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 47276fc..6d1e09d 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -4,7 +4,7 @@ pub mod autorespond; pub mod bot; pub mod code_embed; pub mod decancer; -pub mod embed; +pub mod message; pub mod macros; pub mod media_channel; pub mod moderation;