Add links to reply embeds and fix nitro custom server avatars not displaying

This commit is contained in:
2025-08-24 15:45:54 -03:00
parent fc9bbcc87c
commit 39120a65fa
6 changed files with 56 additions and 6 deletions
+9 -3
View File
@@ -8,15 +8,21 @@ use twilight_model::util::ImageHash;
/// * `hash` - The user's avatar hash (if available). /// * `hash` - The user's avatar hash (if available).
/// * `user_id` - The user's ID. /// * `user_id` - The user's ID.
/// * `discriminator` - The user's discriminator. /// * `discriminator` - The user's discriminator.
/// * `guild_id` - The guild ID, **only set if the user has Nitro and a custom avatar for the
/// server. Otherwise, even in a server, this is NOT SET**.
/// ///
/// Returns: /// Returns:
/// [`String`] - The URL of the user's avatar. /// [`String`] - The URL of the user's avatar.
pub fn get_avatar_url(hash: Option<ImageHash>, user_id: u64, discriminator: u64) -> String { pub fn get_avatar_url(hash: Option<ImageHash>, user_id: u64, discriminator: u64, guild_id: Option<u64>) -> String {
if let Some(hash) = hash { if let Some(hash) = hash {
format!("https://cdn.discordapp.com/avatars/{user_id}/{hash}.png?size=256") if let Some(guild_id) = guild_id {
return format!("https://cdn.discordapp.com/guilds/{guild_id}/users/{user_id}/avatars/{hash}.webp?size=256");
}
format!("https://cdn.discordapp.com/avatars/{user_id}/{hash}.webp?size=256")
} else { } else {
format!( format!(
"https://cdn.discordapp.com/embed/avatars/{}.png?size=256", "https://cdn.discordapp.com/embed/avatars/{}.webp?size=256",
match discriminator.to_string().as_str() { match discriminator.to_string().as_str() {
"0" => (user_id >> 22) % 6, "0" => (user_id >> 22) % 6,
_ => discriminator % 6, _ => discriminator % 6,
+6
View File
@@ -43,6 +43,7 @@ pub(super) fn get_command_help_embed(
ctx.rt.app.bot.as_ref().unwrap().avatar, ctx.rt.app.bot.as_ref().unwrap().avatar,
ctx.rt.app.bot.as_ref().unwrap().id.get(), ctx.rt.app.bot.as_ref().unwrap().id.get(),
ctx.rt.app.bot.as_ref().unwrap().discriminator as u64, ctx.rt.app.bot.as_ref().unwrap().discriminator as u64,
None,
)) ))
.unwrap(), .unwrap(),
) )
@@ -53,6 +54,7 @@ pub(super) fn get_command_help_embed(
ctx.rt.app.bot.as_ref().unwrap().avatar, ctx.rt.app.bot.as_ref().unwrap().avatar,
ctx.rt.app.bot.as_ref().unwrap().id.get(), ctx.rt.app.bot.as_ref().unwrap().id.get(),
ctx.rt.app.bot.as_ref().unwrap().discriminator as u64, ctx.rt.app.bot.as_ref().unwrap().discriminator as u64,
None,
)) ))
.unwrap(), .unwrap(),
) )
@@ -90,6 +92,7 @@ pub(super) fn get_all_command_help_embed(
rt.app.bot.as_ref().unwrap().avatar, rt.app.bot.as_ref().unwrap().avatar,
rt.app.bot.as_ref().unwrap().id.get(), rt.app.bot.as_ref().unwrap().id.get(),
rt.app.bot.as_ref().unwrap().discriminator as u64, rt.app.bot.as_ref().unwrap().discriminator as u64,
None
)) ))
.unwrap())) .unwrap()))
.title("Pick up the phone and start making friends!") .title("Pick up the phone and start making friends!")
@@ -98,6 +101,7 @@ pub(super) fn get_all_command_help_embed(
rt.app.bot.as_ref().unwrap().avatar, rt.app.bot.as_ref().unwrap().avatar,
rt.app.bot.as_ref().unwrap().id.get(), rt.app.bot.as_ref().unwrap().id.get(),
rt.app.bot.as_ref().unwrap().discriminator as u64, rt.app.bot.as_ref().unwrap().discriminator as u64,
None
)) ))
.unwrap()) .unwrap())
.color(COLOR_WHITE) .color(COLOR_WHITE)
@@ -125,6 +129,7 @@ pub(super) fn get_command_not_found_embed<T>(rt: &Runtime<T, Extras>, name: Stri
rt.app.bot.as_ref().unwrap().avatar, rt.app.bot.as_ref().unwrap().avatar,
rt.app.bot.as_ref().unwrap().id.get(), rt.app.bot.as_ref().unwrap().id.get(),
rt.app.bot.as_ref().unwrap().discriminator as u64, rt.app.bot.as_ref().unwrap().discriminator as u64,
None
)) ))
.unwrap())) .unwrap()))
.title("That's not a command") .title("That's not a command")
@@ -133,6 +138,7 @@ pub(super) fn get_command_not_found_embed<T>(rt: &Runtime<T, Extras>, name: Stri
rt.app.bot.as_ref().unwrap().avatar, rt.app.bot.as_ref().unwrap().avatar,
rt.app.bot.as_ref().unwrap().id.get(), rt.app.bot.as_ref().unwrap().id.get(),
rt.app.bot.as_ref().unwrap().discriminator as u64, rt.app.bot.as_ref().unwrap().discriminator as u64,
None
)) ))
.unwrap()) .unwrap())
.build() .build()
+8
View File
@@ -27,6 +27,7 @@ pub fn first_warning_embed(
app.icon, app.icon,
app.bot.as_ref().unwrap().id.get(), app.bot.as_ref().unwrap().id.get(),
app.bot.as_ref().unwrap().discriminator as u64, app.bot.as_ref().unwrap().discriminator as u64,
None
) )
).unwrap() ).unwrap()
) )
@@ -49,6 +50,7 @@ pub fn first_warning_embed(
app.icon, app.icon,
app.bot.as_ref().unwrap().id.get(), app.bot.as_ref().unwrap().id.get(),
app.bot.as_ref().unwrap().discriminator as u64, app.bot.as_ref().unwrap().discriminator as u64,
None
)) ))
.unwrap() .unwrap()
) )
@@ -70,6 +72,7 @@ pub fn repeat_warning_embed(
app.icon, app.icon,
app.bot.as_ref().unwrap().id.get(), app.bot.as_ref().unwrap().id.get(),
app.bot.as_ref().unwrap().discriminator as u64, app.bot.as_ref().unwrap().discriminator as u64,
None
) )
).unwrap() ).unwrap()
) )
@@ -92,6 +95,7 @@ pub fn repeat_warning_embed(
app.icon, app.icon,
app.bot.as_ref().unwrap().id.get(), app.bot.as_ref().unwrap().id.get(),
app.bot.as_ref().unwrap().discriminator as u64, app.bot.as_ref().unwrap().discriminator as u64,
None
)) ))
.unwrap() .unwrap()
) )
@@ -113,6 +117,7 @@ pub fn first_ban_embed(
app.icon, app.icon,
app.bot.as_ref().unwrap().id.get(), app.bot.as_ref().unwrap().id.get(),
app.bot.as_ref().unwrap().discriminator as u64, app.bot.as_ref().unwrap().discriminator as u64,
None
) )
).unwrap() ).unwrap()
) )
@@ -135,6 +140,7 @@ pub fn first_ban_embed(
app.icon, app.icon,
app.bot.as_ref().unwrap().id.get(), app.bot.as_ref().unwrap().id.get(),
app.bot.as_ref().unwrap().discriminator as u64, app.bot.as_ref().unwrap().discriminator as u64,
None
)) ))
.unwrap() .unwrap()
) )
@@ -156,6 +162,7 @@ pub fn final_ban_embed(
app.icon, app.icon,
app.bot.as_ref().unwrap().id.get(), app.bot.as_ref().unwrap().id.get(),
app.bot.as_ref().unwrap().discriminator as u64, app.bot.as_ref().unwrap().discriminator as u64,
None
) )
).unwrap() ).unwrap()
) )
@@ -178,6 +185,7 @@ pub fn final_ban_embed(
app.icon, app.icon,
app.bot.as_ref().unwrap().id.get(), app.bot.as_ref().unwrap().id.get(),
app.bot.as_ref().unwrap().discriminator as u64, app.bot.as_ref().unwrap().discriminator as u64,
None
) )
).unwrap() ).unwrap()
) )
+29 -2
View File
@@ -6,6 +6,7 @@ use time::{Duration, UtcDateTime};
use twilight_http::{api_error::ApiError, error::ErrorType}; use twilight_http::{api_error::ApiError, error::ErrorType};
use twilight_model::{ use twilight_model::{
gateway::payload::incoming::{MessageCreate, MessageDelete, MessageUpdate}, gateway::payload::incoming::{MessageCreate, MessageDelete, MessageUpdate},
guild,
id::Id, id::Id,
}; };
use twilight_util::{ use twilight_util::{
@@ -110,6 +111,10 @@ impl OnMessageHandler<State, Extras> for CallMessageHandler {
return Ok(()); return Ok(());
} }
let Some(guild_id) = event.guild_id else {
return Ok(());
};
let prefixes = rt let prefixes = rt
.get_prefixes(event.guild_id.map(|i| i.get()), Some(event.author.id.get())) .get_prefixes(event.guild_id.map(|i| i.get()), Some(event.author.id.get()))
.await; .await;
@@ -252,6 +257,11 @@ impl OnMessageHandler<State, Extras> for CallMessageHandler {
.or(event.author.avatar), .or(event.author.avatar),
event.author.id.get(), event.author.id.get(),
event.author.discriminator as u64, event.author.discriminator as u64,
event
.member
.as_ref()
.and_then(|member| member.avatar)
.map(|_| guild_id.get()),
), ),
user.is_masked, user.is_masked,
&rt.state.db, &rt.state.db,
@@ -291,7 +301,11 @@ impl OnMessageHandler<State, Extras> for CallMessageHandler {
let mut embeds = vec![]; let mut embeds = vec![];
if let Some(replying_to) = replying_to { if let Some(replying_to) = replying_to {
if let Some(propagation_channel_id) = replying_to.data.propagation_channel_id { if let Some((propagation_channel_id, propagation_message_id)) = replying_to
.data
.propagation_channel_id
.zip(replying_to.data.propagation_message_id)
{
let (display_name, avatar_url) = let (display_name, avatar_url) =
if let Some(mask) = replying_to.data.author_mask { if let Some(mask) = replying_to.data.author_mask {
( (
@@ -313,11 +327,24 @@ impl OnMessageHandler<State, Extras> for CallMessageHandler {
) )
}; };
let message_link = if i64_to_u64(propagation_channel_id) == channel.id {
format!(
"https://discord.com/channels/{}/{}/{}",
opposite_channel.server_id, opposite_channel.id, replying_to.message_id
)
} else {
format!(
"https://discord.com/channels/{}/{}/{}",
channel.server_id, propagation_channel_id, propagation_message_id
)
};
embeds.push( embeds.push(
EmbedBuilder::new() EmbedBuilder::new()
.author( .author(
EmbedAuthorBuilder::new(format!("Replying to {display_name}",)) EmbedAuthorBuilder::new(format!("Replying to {display_name}",))
.icon_url(ImageSource::url(avatar_url).unwrap()), .icon_url(ImageSource::url(avatar_url).unwrap())
.url(message_link),
) )
.color(COLOR_WHITE) .color(COLOR_WHITE)
.description(ellipse(replying_to.data.content, 100)) .description(ellipse(replying_to.data.content, 100))
+3
View File
@@ -99,6 +99,7 @@ impl Command<State, Extras> for LeaderboardCommand {
ctx.rt.app.bot.as_ref().unwrap().avatar, ctx.rt.app.bot.as_ref().unwrap().avatar,
ctx.rt.app.bot.as_ref().unwrap().id.get(), ctx.rt.app.bot.as_ref().unwrap().id.get(),
ctx.rt.app.bot.as_ref().unwrap().discriminator as u64, ctx.rt.app.bot.as_ref().unwrap().discriminator as u64,
None,
)) ))
.unwrap(), .unwrap(),
), ),
@@ -108,6 +109,7 @@ impl Command<State, Extras> for LeaderboardCommand {
ctx.rt.app.bot.as_ref().unwrap().avatar, ctx.rt.app.bot.as_ref().unwrap().avatar,
ctx.rt.app.bot.as_ref().unwrap().id.get(), ctx.rt.app.bot.as_ref().unwrap().id.get(),
ctx.rt.app.bot.as_ref().unwrap().discriminator as u64, ctx.rt.app.bot.as_ref().unwrap().discriminator as u64,
None,
)) ))
.unwrap(), .unwrap(),
) )
@@ -117,6 +119,7 @@ impl Command<State, Extras> for LeaderboardCommand {
ctx.event.author.avatar, ctx.event.author.avatar,
ctx.event.author.id.get(), ctx.event.author.id.get(),
ctx.event.author.discriminator as u64, ctx.event.author.discriminator as u64,
None,
)) ))
.unwrap(), .unwrap(),
), ),
+1 -1
View File
@@ -24,7 +24,7 @@ impl Button<State, Extras> for ArrowIncidentButton {
} }
fn label(&self) -> Option<String> { fn label(&self) -> Option<String> {
Some(format!("{}", self.arrow)) Some(self.arrow.to_string())
} }
fn disabled(&self) -> bool { fn disabled(&self) -> bool {