From a2adf802794968a3eaa9e5feb6fd0fcfd2df9a76 Mon Sep 17 00:00:00 2001 From: liyunze <50455574+liyunze-coding@users.noreply.github.com> Date: Sat, 8 Nov 2025 22:12:05 +1100 Subject: [PATCH] added userinfo and serverinfo --- src/commands.rs | 1 + src/commands/info.rs | 132 +++++++++++++++++++++++++++++++++++++++++-- src/main.rs | 7 ++- 3 files changed, 135 insertions(+), 5 deletions(-) diff --git a/src/commands.rs b/src/commands.rs index 4b8757f..f94d476 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -1 +1,2 @@ +// this file is to let main.rs know the existence of the "commands" folder pub mod info; diff --git a/src/commands/info.rs b/src/commands/info.rs index 093df4b..95919ba 100644 --- a/src/commands/info.rs +++ b/src/commands/info.rs @@ -1,5 +1,5 @@ use poise::CreateReply; -use serenity::all::{Colour, CreateEmbed}; +use serenity::all::{Colour, CreateEmbed, GuildId, User}; use crate::{Context, Error}; use std::time::Instant; @@ -16,7 +16,7 @@ pub async fn help( ctx, command.as_deref(), poise::builtins::HelpConfiguration { - extra_text_at_bottom: "This is an example bot made to showcase features of my custom Discord bot framework", + extra_text_at_bottom: "made using Serenity Poise framework in Rust and with ❤️", ..Default::default() }, ) @@ -25,8 +25,6 @@ pub async fn help( } /// Ping the bot -/// -/// Check the bot's ping #[poise::command(slash_command)] pub async fn ping(ctx: Context<'_>) -> Result<(), Error> { let start = Instant::now(); @@ -53,3 +51,129 @@ pub async fn ping(ctx: Context<'_>) -> Result<(), Error> { Ok(()) } + +/// Display user's information +#[poise::command(slash_command)] +pub async fn userinfo( + ctx: Context<'_>, + #[description = "Specific user to show information about"] + #[autocomplete = "poise::builtins::autocomplete_command"] + user: Option, +) -> Result<(), Error> { + let discord_user: User = user.unwrap_or(ctx.author().to_owned()); + let discord_member = GuildId::member(ctx.guild_id().unwrap(), ctx, discord_user.id).await?; + + let embed_color = discord_user.accent_colour.unwrap_or(Colour::DARK_GREY); + + let member_created_at = discord_user.created_at().format("%d/%m/%Y %I:%M %p"); + let member_joined_at = discord_member + .joined_at + .unwrap() + .format("%d/%m/%Y %I:%M %p"); + + let user_id = &discord_user.id; + let username = &discord_user.name; + + let nickname = &discord_member.nick.unwrap_or(username.to_owned()); + + let role_ids = discord_member.roles; + let role_mentions: Vec = role_ids + .into_iter() + .map(|role_id| format!("<@&{}>", role_id)) + .collect(); + + let user_avatar_url = discord_user + .avatar_url() + .unwrap_or(discord_user.default_avatar_url()); + + let result_embed_msg = CreateEmbed::new() + .thumbnail(user_avatar_url) + .color(embed_color) + .title("User Info") + .description(format!( + "**ID**: {} \n\ + **Display Name**: {}\n\ + **Username**: {}\n\ + **Created At**: {}\n\ + **Joined At**: {}\n\ + **Roles**: {} + ", + user_id, + nickname, + username, + member_created_at, + member_joined_at, + role_mentions.join(" ") + )); + + ctx.send(CreateReply::default().embed(result_embed_msg)) + .await?; + + Ok(()) +} + +/// Display server's information +#[poise::command(slash_command)] +pub async fn serverinfo(ctx: Context<'_>) -> Result<(), Error> { + let embed_color = Colour::DARK_GREY; + + let partial_guild = ctx.partial_guild().await.unwrap(); + let member_count = { + let guild = ctx.guild(); + guild.as_deref().unwrap().member_count + }; + + let server_description_option = &partial_guild.description; + + let server_id = &partial_guild.id; + let server_name = &partial_guild.name; + // let no_of_members = &discord_server.approximate_member_count.unwrap(); + let owner_id = &partial_guild.owner_id; + + let server_description = server_description_option.as_deref().unwrap_or("N/A"); + + let server_icon = &partial_guild.icon_url().unwrap_or_default(); + + let roles: &Vec = &partial_guild + .roles + .into_keys() + .filter(|role_id| format!("{}", role_id) != format!("{}", server_id)) + .map(|role_id| format!("<@&{}>", role_id)) + .collect(); + + let rules_channel_id = &partial_guild.rules_channel_id; + + let rules_channel = if rules_channel_id.is_none() { + "N/A" + } else { + &format!("<#{}>", rules_channel_id.unwrap()) + }; + + let result_embed_msg = CreateEmbed::new() + .thumbnail(server_icon) + .title("Server Info") + .description(format!( + " + **Name**: {}\n\ + **ID**: {}\n\ + **Owner**: <@{}>\n\ + **Description**: {}\n\ + **Rules Channel**: {}\n\ + **No. of Members**: {}\n\ + **Roles**: {} + ", + server_id, + server_name, + owner_id, + server_description, + rules_channel, + member_count, + roles.join(" ") + )) + .color(embed_color); + + ctx.send(CreateReply::default().embed(result_embed_msg)) + .await?; + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index b072221..7beb26c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,7 +17,12 @@ async fn main() { let framework = poise::Framework::builder() .options(poise::FrameworkOptions { - commands: vec![commands::info::help(), commands::info::ping()], + commands: vec![ + commands::info::help(), + commands::info::ping(), + commands::info::userinfo(), + commands::info::serverinfo(), + ], ..Default::default() }) .setup(|ctx, _ready, framework| {