From 85170b8072f663c53a5ea78acec619aa3a90c34c Mon Sep 17 00:00:00 2001 From: Akinator31 <99099121+Akinator31@users.noreply.github.com> Date: Wed, 14 Oct 2026 15:35:39 +0200 Subject: [PATCH 1/2] fix(message): honor custom embeds in interaction followups --- crates/rustmail/src/utils/message/message_builder.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/rustmail/src/utils/message/message_builder.rs b/crates/rustmail/src/utils/message/message_builder.rs index 32d5de2..b43bb51 100644 --- a/crates/rustmail/src/utils/message/message_builder.rs +++ b/crates/rustmail/src/utils/message/message_builder.rs @@ -562,7 +562,9 @@ impl<'a> MessageBuilder<'a> { pub async fn build_interaction_message_followup(&self) -> CreateInteractionResponseFollowup { let mut message = CreateInteractionResponseFollowup::new(); - if self.should_use_embed().await { + if let Some(embed) = &self.custom_embed { + message = message.embed(embed.clone()); + } else if self.should_use_embed().await { message = message.embed(self.build_embed().await); message = message.content(""); } else { From 4767ba276d6e1e3c8d0e29aaf6ab3173711f8099 Mon Sep 17 00:00:00 2001 From: Akinator31 <99099121+Akinator31@users.noreply.github.com> Date: Wed, 14 Oct 2026 15:36:13 +0200 Subject: [PATCH 2/2] fix(baninfo): answer the slash command through its deferred interaction --- .../commands/baninfo/slash_command/baninfo.rs | 14 +++- .../commands/baninfo/text_command/baninfo.rs | 64 +++++++++++-------- 2 files changed, 47 insertions(+), 31 deletions(-) diff --git a/crates/rustmail/src/commands/baninfo/slash_command/baninfo.rs b/crates/rustmail/src/commands/baninfo/slash_command/baninfo.rs index 4ede5bf..1fb8791 100644 --- a/crates/rustmail/src/commands/baninfo/slash_command/baninfo.rs +++ b/crates/rustmail/src/commands/baninfo/slash_command/baninfo.rs @@ -1,4 +1,6 @@ -use crate::commands::baninfo::text_command::{resolve_banned_users, send_baninfo_response}; +use crate::commands::baninfo::text_command::{ + BaninfoReplyTarget, resolve_banned_users, send_baninfo_response, +}; use crate::prelude::commands::*; use crate::prelude::config::*; use crate::prelude::errors::*; @@ -96,8 +98,14 @@ impl RegistrableCommand for BaninfoCommand { let guild_id = config.bot.get_community_guild_id().to_string(); let matches = resolve_banned_users(&guild_id, &query, pool).await?; - send_baninfo_response(&ctx, &config, command.channel_id, &query, &matches).await; - Ok(()) + send_baninfo_response( + &ctx, + &config, + BaninfoReplyTarget::Interaction(&command), + &query, + &matches, + ) + .await }) } } diff --git a/crates/rustmail/src/commands/baninfo/text_command/baninfo.rs b/crates/rustmail/src/commands/baninfo/text_command/baninfo.rs index 3d11394..edeeceb 100644 --- a/crates/rustmail/src/commands/baninfo/text_command/baninfo.rs +++ b/crates/rustmail/src/commands/baninfo/text_command/baninfo.rs @@ -5,7 +5,9 @@ use crate::prelude::errors::*; use crate::prelude::handlers::*; use crate::prelude::i18n::*; use crate::prelude::utils::*; -use serenity::all::{Colour, Context, CreateEmbed, GuildId, Message, RoleId}; +use serenity::all::{ + ChannelId, Colour, CommandInteraction, Context, CreateEmbed, GuildId, Message, RoleId, +}; use std::collections::HashMap; use std::sync::Arc; @@ -38,8 +40,14 @@ pub async fn baninfo( let guild_id = config.bot.get_community_guild_id().to_string(); let matches = resolve_banned_users(&guild_id, &query, pool).await?; - send_baninfo_response(&ctx, config, msg.channel_id, &query, &matches).await; - Ok(()) + send_baninfo_response( + &ctx, + config, + BaninfoReplyTarget::Channel(msg.channel_id), + &query, + &matches, + ) + .await } pub async fn resolve_banned_users( @@ -108,26 +116,27 @@ async fn resolve_role_labels(ctx: &Context, config: &Config, role_ids: &[String] .collect() } +pub enum BaninfoReplyTarget<'a> { + Channel(ChannelId), + Interaction(&'a CommandInteraction), +} + pub async fn send_baninfo_response( ctx: &Context, config: &Config, - channel: serenity::all::ChannelId, + target: BaninfoReplyTarget<'_>, query: &str, matches: &[BannedUser], -) { - if matches.is_empty() { +) -> ModmailResult<()> { + let builder = MessageBuilder::system_message(ctx, config); + + let builder = if matches.is_empty() { let mut params = HashMap::new(); params.insert("query".to_string(), query.to_string()); - let _ = MessageBuilder::system_message(ctx, config) + builder .translated_content("baninfo.not_found", Some(¶ms), None, None) .await - .to_channel(channel) - .send(true) - .await; - return; - } - - if matches.len() > 1 { + } else if matches.len() > 1 { let header = get_translated_message(config, "baninfo.multiple_matches", None, None, None, None) .await; @@ -140,21 +149,20 @@ pub async fn send_baninfo_response( user.username, user.user_id, user.user_id )); } - let _ = MessageBuilder::system_message(ctx, config) - .content(body) - .to_channel(channel) - .send(true) - .await; - return; - } + builder.content(body) + } else { + let embed = build_baninfo_embed(ctx, config, &matches[0]).await; + builder.build_embed_only(embed) + }; - let user = &matches[0]; - let embed = build_baninfo_embed(ctx, config, user).await; - let _ = MessageBuilder::system_message(ctx, config) - .build_embed_only(embed) - .to_channel(channel) - .send(true) - .await; + match target { + BaninfoReplyTarget::Channel(channel) => builder.to_channel(channel).send(true).await?, + BaninfoReplyTarget::Interaction(command) => { + builder.send_interaction_followup(command, true).await? + } + }; + + Ok(()) } pub async fn build_baninfo_embed(ctx: &Context, config: &Config, user: &BannedUser) -> CreateEmbed {