Skip to content

Commit e234234

Browse files
authored
Add 6 new appealing slash commands to PN bot
* Add /serverinfo slash command with comprehensive server statistics * Add comprehensive user information slash command * Add clean userinfo slash command implementation * Add avatar slash command to display user avatars * Add fun 8ball slash command for predictions * Add fun 8-ball slash command for predictions * Add choose slash command for random decision making * Add ping slash command to show bot latency * Update bot.py to register all new slash commands
1 parent 0b79c20 commit e234234

7 files changed

Lines changed: 628 additions & 4 deletions

File tree

‎bot.py‎

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
1111
Features:
1212
- Prefix commands (e.g., !ping, !uptime, !userinfo, !serverinfo)
13-
- Slash commands (e.g., /hello, /echo)
13+
- Slash commands (e.g., /hello, /echo, /serverinfo, /userinfo, /avatar, /8ball, /choose, /ping)
1414
- Event handlers (e.g., on_message, on_member_join)
1515
"""
1616

@@ -34,7 +34,8 @@
3434

3535
# Configure bot intents for required functionality
3636
intents = discord.Intents.default()
37-
intents.message_content = True # Required for prefix commands and message events
37+
intents.message_content = True # Required for prefix commands and message events
38+
intents.members = True # Required for member-related commands like userinfo
3839

3940
# Initialize bot with prefix from environment (defaults to !)
4041
bot = commands.Bot(command_prefix=os.getenv("PREFIX", "!"), intents=intents)
@@ -56,19 +57,32 @@ async def load_extensions() -> None:
5657
even if some cogs are broken.
5758
"""
5859
for ext in [
60+
# Prefix commands
5961
"prefixcommands.ping",
6062
"prefixcommands.uptime",
6163
"prefixcommands.userinfo",
6264
"prefixcommands.serverinfo",
65+
# Slash commands - existing
6366
"slashcommands.hello",
6467
"slashcommands.echo",
68+
# New slash commands
69+
"slashcommands.serverinfo",
70+
"slashcommands.userinfo",
71+
"slashcommands.avatar",
72+
"slashcommands.8ball",
73+
"slashcommands.choose",
74+
"slashcommands.ping",
75+
# Event handlers
6576
"events.handlers",
6677
]:
6778
try:
6879
await bot.load_extension(ext)
6980
print(f"Loaded extension: {ext}")
7081
except Exception as e:
7182
print(f"Failed to load {ext}: {e}")
83+
# Print full traceback for debugging during development
84+
import traceback
85+
traceback.print_exc()
7286

7387

7488
@bot.event
@@ -94,10 +108,13 @@ async def setup_hook() -> None:
94108
await load_extensions()
95109
# Sync slash commands once when the bot starts
96110
try:
97-
await bot.tree.sync()
98-
print("Slash commands synced.")
111+
synced = await bot.tree.sync()
112+
print(f"Slash commands synced: {len(synced)} commands registered")
113+
print(f"Commands: {[cmd.name for cmd in synced]}")
99114
except Exception as e:
100115
print(f"Failed to sync slash commands: {e}")
116+
import traceback
117+
traceback.print_exc()
101118

102119

103120
if __name__ == "__main__":

‎slashcommands/8ball.py‎

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
"""
2+
Slash Command: 8-Ball
3+
4+
This module provides a magic 8-ball slash command for the PN bot.
5+
Users can ask the 8-ball a question and receive a random prediction.
6+
7+
Usage:
8+
/8ball <question>
9+
10+
Features:
11+
- Responds with random predictions from a curated list
12+
- Supports classic magic 8-ball responses
13+
- Interactive and engaging for users
14+
- Question parameter for user input
15+
16+
Dependencies:
17+
discord.py - Provides the commands framework and Discord API integration
18+
random - Python standard library for random responses
19+
"""
20+
21+
import discord
22+
from discord.ext import commands
23+
import random
24+
25+
26+
class EightBall(commands.Cog):
27+
"""A cog containing 8-ball prediction slash commands.
28+
29+
This cog provides a fun magic 8-ball command that gives random
30+
predictions in response to user questions.
31+
32+
Args:
33+
bot: The bot instance that this cog is attached to.
34+
"""
35+
36+
def __init__(self, bot: commands.Bot) -> None:
37+
"""Initialize the 8Ball cog.
38+
39+
Args:
40+
bot: The bot instance to attach this cog to.
41+
"""
42+
self.bot = bot
43+
44+
# Define 8-ball responses following the classic magic 8-ball format
45+
self.responses = [
46+
# Positive responses (10)
47+
"It is certain.",
48+
"It is decidedly so.",
49+
"Without a doubt.",
50+
"Yes definitely.",
51+
"You may rely on it.",
52+
"As I see it, yes.",
53+
"Most likely.",
54+
"Outlook good.",
55+
"Yes.",
56+
"Signs point to yes.",
57+
# Neutral responses (5)
58+
"Reply hazy, try again.",
59+
"Ask again later.",
60+
"Better not tell you now.",
61+
"Cannot predict now.",
62+
"Concentrate and ask again.",
63+
# Negative responses (5)
64+
"Don't count on it.",
65+
"My reply is no.",
66+
"My sources say no.",
67+
"Outlook not so good.",
68+
"Very doubtful."
69+
]
70+
71+
@discord.app_commands.command(name="8ball", description="Ask the magic 8-ball a question")
72+
@discord.app_commands.describe(question="Your question for the magic 8-ball")
73+
async def eightball(self, interaction: discord.Interaction, question: str) -> None:
74+
"""Ask the magic 8-ball a question and get a prediction.
75+
76+
This slash command takes a user's question and responds with a random
77+
prediction from the magic 8-ball's repertoire of responses.
78+
79+
Args:
80+
interaction: The Discord interaction object representing the slash command invocation.
81+
question: The question to ask the magic 8-ball (required parameter).
82+
83+
Returns:
84+
None. Responds to the interaction with an embed containing the prediction.
85+
"""
86+
# Get a random response from our predefined list
87+
response = random.choice(self.responses)
88+
89+
# Determine embed color based on response type
90+
if response in ["It is certain.", "It is decidedly so.", "Without a doubt.", "Yes definitely.", "You may rely on it.",
91+
"As I see it, yes.", "Most likely.", "Outlook good.", "Yes.", "Signs point to yes."]:
92+
color = discord.Color.green()
93+
itral in ["Reply hazy, try again.", "Ask again later.", "Better not tell you now.",
94+
itrate now."]: color = discord.Color.gold()
95+
color = discord.Color.red()
96+
color = discord.Color.red()
97+
color = discord.Color.red()
98+
color = discord.Color.red()

‎slashcommands/avatar.py‎

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
"""
2+
Slash Command: Avatar
3+
4+
This module provides an avatar slash command for the PN bot.
5+
Users can invoke /avatar to display a user's profile picture at full size.
6+
7+
Usage:
8+
/avatar [member]
9+
10+
Features:
11+
- Displays user's avatar in full resolution
12+
- Shows server-specific avatar if available
13+
- Defaults to command invoker if no member specified
14+
- Shows avatar in a clean embed format
15+
16+
Dependencies:
17+
discord.py - Provides the commands framework and Discord API integration
18+
"""
19+
20+
import discord
21+
from discord.ext import commands
22+
23+
24+
class Avatar(commands.Cog):
25+
"""A cog containing avatar slash commands.
26+
27+
This cog provides commands to display user avatars at full resolution.
28+
29+
Args:
30+
bot: The bot instance that this cog is attached to.
31+
"""
32+
33+
def __init__(self, bot: commands.Bot) -> None:
34+
"""Initialize the Avatar cog.
35+
36+
Args:
37+
bot: The bot instance to attach this cog to.
38+
"""
39+
self.bot = bot
40+
41+
@discord.app_commands.command(name="avatar", description="Display a user's avatar")
42+
@discord.app_commands.describe(member="The member whose avatar to show (defaults to you)")
43+
async def avatar(self, interaction: discord.Interaction, member: discord.Member = None) -> None:
44+
"""Display a user's avatar at full resolution.
45+
46+
This slash command shows a user's profile picture in full size.
47+
If the user has a server-specific avatar, it will be displayed.
48+
Otherwise, their global Discord avatar is shown.
49+
50+
Args:
51+
interaction: The Discord interaction object representing the slash command invocation.
52+
member: The member whose avatar to display. If not provided, shows the command invoker's avatar.
53+
54+
Returns:
55+
None. Responds to the interaction with an embed containing the avatar.
56+
"""
57+
# Default to the user who invoked the command if no member is specified
58+
if member is None:
59+
member = interaction.user
60+
61+
# Handle non-guild context gracefully
62+
if not isinstance(member, discord.Member):
63+
if interaction.guild:
64+
# Try to get proper Member object in guild context
65+
proper_member = interaction.guild.get_member(member.id)
66+
if proper_member:
67+
member = proper_member
68+
69+
# Create embed for avatar display
70+
embed = discord.Embed(
71+
title=f"🖼️ {member.display_name}'s Avatar",
72+
description=f"[Download Avatar]({member.display_avatar.url})",
73+
color=discord.Color.purple()
74+
)
75+
76+
# Set the avatar image
77+
embed.set_image(url=member.display_avatar.url)
78+
79+
# Add footer with user ID
80+
embed.set_footer(
81+
text=f"User ID: {member.id}",
82+
icon_url=member.display_avatar.url if hasattr(member.display_avatar, 'url') else None
83+
)
84+
85+
await interaction.response.send_message(embed=embed)
86+
87+
88+
async def setup(bot: commands.Bot) -> None:
89+
"""Register the Avatar cog with the bot.
90+
91+
Args:
92+
bot: The bot instance to register the cog with.
93+
"""
94+
await bot.add_cog(Avatar(bot))

‎slashcommands/choose.py‎

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
"""
2+
Slash Command: Choose
3+
4+
This module provides a random choice slash command for the PN bot.
5+
Users can provide multiple options and let the bot randomly select one.
6+
7+
Usage:
8+
/choose <option1> <option2> [option3] [option4] [option5]
9+
10+
Features:
11+
- Randomly selects from 2-5 provided options
12+
- Clean embed display of the chosen option
13+
- Useful for decision-making, games, and polls
14+
- Validates that at least 2 options are provided
15+
16+
Dependencies:
17+
discord.py - Provides the commands framework and Discord API integration
18+
random - Python standard library for random selection
19+
"""
20+
21+
import discord
22+
from discord.ext import commands
23+
import random
24+
25+
26+
class Choose(commands.Cog):
27+
"""A cog containing random choice slash commands.
28+
29+
This cog provides a choose command that randomly selects from
30+
multiple user-provided options.
31+
32+
Args:
33+
bot: The bot instance that this cog is attached to.
34+
"""
35+
36+
def __init__(self, bot: commands.Bot) -> None:
37+
"""Initialize the Choose cog.
38+
39+
Args:
40+
bot: The bot instance to attach this cog to.
41+
"""
42+
self.bot = bot
43+
44+
@discord.app_commands.command(name="choose", description="Randomly choose between multiple options")
45+
@discord.app_commands.describe(
46+
option1="First option",
47+
option2="Second option",
48+
option3="Third option (optional)",
49+
option4="Fourth option (optional)",
50+
option5="Fifth option (optional)"
51+
)
52+
async def choose(
53+
self,
54+
interaction: discord.Interaction,
55+
option1: str,
56+
option2: str,
57+
option3: str = None,
58+
option4: str = None,
59+
option5: str = None
60+
) -> None:
61+
"""Randomly choose one option from a list.
62+
63+
This slash command takes 2-5 options and randomly selects one,
64+
making it perfect for decision-making or adding randomness to activities.
65+
66+
Args:
67+
interaction: The Discord interaction object representing the slash command invocation.
68+
option1: The first option to choose from (required).
69+
option2: The second option to choose from (required).
70+
option3: The third option to choose from (optional).
71+
option4: The fourth option to choose from (optional).
72+
option5: The fifth option to choose from (optional).
73+
74+
Returns:
75+
None. Responds to the interaction with an embed containing the chosen option.
76+
"""
77+
# Collect all provided options into a list
78+
options = [option1, option2]
79+
if option3:
80+
options.append(option3)
81+
if option4:
82+
options.append(option4)
83+
if option5:
84+
options.append(option5)
85+
86+
# Validate that we have at least 2 options (enforced by required params, but good practice)
87+
if len(options) < 2:
88+
aawait interaction.response.send_message("Please provide at least 2 options!", ephemeral=True)
89+
rreturn
90+
# Randomly select one option ition = random.choice(options) # Create embed with the result # Create embed with the result # Create embed with the result # Create embed with the result il = "🎲 Random Choice" description="", color=discord.Color.random() ) embed.add_field( name=f"Chosen from {len(options)} options:", value=f"**{chosen}**", inline=False ) # List all options for context options_text = "\".join(options) if len(options_text) > 1000: # Truncate if too long options_text = options_text[:997] + "..." embed.add_field( name="All Options:", value=options_text, inline=False ) # Set footer with requester info embed.set_footer( text=f"Requested by {interaction.user}", icon_url=interaction.user.display_avatar.url if interaction.user.display_avatar else None ) # Send response await interaction.response.send_message(embed=embed)

0 commit comments

Comments
 (0)