From 8453de086a446fd7eff33121448c1953d5f30c52 Mon Sep 17 00:00:00 2001 From: 2ndbeam <2ndbeam@disroot.org> Date: Thu, 11 Dec 2025 15:00:55 +0300 Subject: [PATCH] feat(discord): Added /social commands - Added /social msg to send messages - Added /social edit to edit sent messages --- discord/src/commands/mod.rs | 1 + discord/src/commands/social.rs | 157 +++++++++++++++++++++++++++++++++ discord/src/main.rs | 1 + 3 files changed, 159 insertions(+) create mode 100644 discord/src/commands/social.rs diff --git a/discord/src/commands/mod.rs b/discord/src/commands/mod.rs index 8e19a17..bcd5b73 100644 --- a/discord/src/commands/mod.rs +++ b/discord/src/commands/mod.rs @@ -5,6 +5,7 @@ use crate::{Context, Error}; pub mod quest; pub mod init; pub mod answer; +pub mod social; pub const ERROR_MSG: &str = "Server error :("; diff --git a/discord/src/commands/social.rs b/discord/src/commands/social.rs new file mode 100644 index 0000000..cf24086 --- /dev/null +++ b/discord/src/commands/social.rs @@ -0,0 +1,157 @@ +use poise::serenity_prelude::{Attachment, ChannelId, CreateAttachment, CreateMessage, EditMessage, Mentionable, MessageId, UserId}; + +use crate::{Context, Error}; + +#[poise::command( + prefix_command, + slash_command, + required_permissions = "ADMINISTRATOR", + guild_only, + subcommands("msg", "edit"), +)] +pub async fn social( _ctx: Context<'_> ) -> Result<(), Error> { + Ok(()) +} + +#[poise::command( + prefix_command, + slash_command, + required_permissions = "ADMINISTRATOR", + guild_only, +)] +pub async fn msg ( + ctx: Context<'_>, + channel: Option, + user: Option, + content: Option, + file: Option, + +) -> Result<(), Error> { + if channel.is_none() && user.is_none() { + let reply_string = "Please specify channel **or** user".to_string(); + ctx.reply(reply_string).await?; + return Ok(()); + } + + if channel.is_some() && user.is_some() { + let reply_string = "Please specify **only** channel or **only** user, not both".to_string(); + ctx.reply(reply_string).await?; + return Ok(()); + } + + if content.is_none() && file.is_none() { + let reply_string = "Please specify content and/or file".to_string(); + ctx.reply(reply_string).await?; + return Ok(()); + } + + let mut builder = CreateMessage::new(); + + if let Some(content) = content { + builder = builder.content(content); + } + + if let Some(file) = file { + ctx.defer().await?; + let attachment = CreateAttachment::url(ctx, &file.url).await; + match attachment { + Ok(attachment) => { builder = builder.add_file(attachment); }, + Err(error) => { + eprintln!("{error}"); + let reply_string = "Couldn't copy attachment, aborting"; + ctx.reply(reply_string).await?; + return Ok(()); + }, + } + } + + let reply_string = if let Some(channel) = channel { + let message = channel.send_message(ctx, builder).await?; + format!("Sent {message} ({message_id}) to {channel}!", + message = message.link(), + message_id = message.id, + channel = channel.mention(), + ) + } else if let Some(user) = user { + let message = user.dm(ctx, builder).await?; + format!("Sent {message} ({message_id}) to {user}", + message = message.link(), + message_id = message.id, + user = user.mention(), + ) + } else { + unreachable!(); + }; + + ctx.reply(reply_string).await?; + + Ok(()) +} + +#[poise::command( + prefix_command, + slash_command, + required_permissions = "ADMINISTRATOR", + guild_only, +)] +pub async fn edit ( + ctx: Context<'_>, + #[rename = "message"] + message_id: MessageId, + channel: Option, + user: Option, + content: Option, + file: Option, +) -> Result<(), Error> { + if channel.is_none() && user.is_none() { + let reply_string = "Please specify channel **or** user".to_string(); + ctx.reply(reply_string).await?; + return Ok(()); + } + + if channel.is_some() && user.is_some() { + let reply_string = "Please specify **only** channel or **only** user, not both".to_string(); + ctx.reply(reply_string).await?; + return Ok(()); + } + + if content.is_none() && file.is_none() { + let reply_string = "Please specify content and/or file".to_string(); + ctx.reply(reply_string).await?; + return Ok(()); + } + + let mut builder = EditMessage::new(); + + if let Some(content) = content { + builder = builder.content(content); + } + + if let Some(file) = file { + ctx.defer().await?; + let attachment = CreateAttachment::url(ctx, &file.url).await; + match attachment { + Ok(attachment) => { builder = builder.new_attachment(attachment); }, + Err(error) => { + eprintln!("{error}"); + let reply_string = "Couldn't copy attachment, aborting"; + ctx.reply(reply_string).await?; + return Ok(()); + }, + } + } + + if let Some(channel) = channel { + let mut message = channel.message(ctx, message_id).await?; + message.edit(ctx, builder).await?; + } else if let Some(user) = user { + let channel = user.create_dm_channel(ctx).await?; + let mut message = channel.message(ctx, message_id).await?; + message.edit(ctx, builder).await?; + } + + let reply_string = "Successfully edited message.".to_string(); + ctx.reply(reply_string).await?; + + Ok(()) +} diff --git a/discord/src/main.rs b/discord/src/main.rs index 2d5fd94..2aca609 100644 --- a/discord/src/main.rs +++ b/discord/src/main.rs @@ -40,6 +40,7 @@ async fn main() { commands::register(), commands::init::init(), commands::answer::answer(), + commands::social::social(), ], ..Default::default() })