AI Skill Report Card
Developing Discord Bots
YAML--- name: developing-discord-bots description: Develops advanced Discord bots with professional architecture patterns, slash commands, event handling, database integration, and deployment strategies. Use when building Discord applications or troubleshooting bot issues. ---
Quick Start
Pythonimport discord from discord.ext import commands import asyncio import logging class ProfessionalBot(commands.Bot): def __init__(self): intents = discord.Intents.default() intents.message_content = True intents.guilds = True super().__init__(command_prefix='!', intents=intents) async def setup_hook(self): await self.load_extension('cogs.admin') await self.load_extension('cogs.moderation') await self.tree.sync() async def on_ready(self): logging.info(f'{self.user} connected to {len(self.guilds)} guilds') bot = ProfessionalBot() bot.run('TOKEN')
Workflow
Progress:
- Project architecture setup (cogs, utils, config)
- Database schema design and migrations
- Core command implementation with error handling
- Event listeners and middleware
- Permission system and security
- Testing framework setup
- CI/CD pipeline configuration
- Production deployment and monitoring
1. Project Structure Setup
discord_bot/
├── bot.py # Entry point
├── config.py # Configuration management
├── database/
│ ├── models.py # SQLAlchemy/AsyncPG models
│ └── migrations.py # Database migrations
├── cogs/ # Command modules
│ ├── admin.py
│ ├── moderation.py
│ └── utils.py
├── utils/
│ ├── checks.py # Custom decorators
│ ├── embeds.py # Embed builders
│ └── paginator.py # Pagination utility
└── tests/
2. Advanced Cog Architecture
Pythonclass ModerationCog(commands.Cog): def __init__(self, bot): self.bot = bot self.db = bot.db_pool @app_commands.command() @app_commands.describe(user="User to moderate", reason="Reason for action") async def ban(self, interaction: discord.Interaction, user: discord.Member, reason: str = None): await interaction.response.defer(ephemeral=True) # Permission check if not interaction.user.guild_permissions.ban_members: return await interaction.followup.send("Insufficient permissions") # Database logging await self.log_moderation_action(user.id, "ban", reason, interaction.user.id) # Execute ban await user.ban(reason=reason) embed = discord.Embed(title="User Banned", color=0xff0000) embed.add_field(name="User", value=f"{user.mention} ({user.id})") embed.add_field(name="Moderator", value=interaction.user.mention) embed.add_field(name="Reason", value=reason or "No reason provided") await interaction.followup.send(embed=embed)
3. Database Integration
Pythonimport asyncpg import asyncio class DatabaseManager: def __init__(self, connection_string): self.connection_string = connection_string self.pool = None async def create_pool(self): self.pool = await asyncpg.create_pool(self.connection_string) await self.setup_tables() async def setup_tables(self): async with self.pool.acquire() as conn: await conn.execute(""" CREATE TABLE IF NOT EXISTS mod_logs ( id SERIAL PRIMARY KEY, user_id BIGINT NOT NULL, action VARCHAR(50) NOT NULL, reason TEXT, moderator_id BIGINT NOT NULL, timestamp TIMESTAMP DEFAULT NOW() ) """)
Examples
Example 1: Slash Command with Autocomplete
Python@app_commands.command() async def role(self, interaction: discord.Interaction, role_name: str): # Command logic pass @role.autocomplete('role_name') async def role_autocomplete(self, interaction: discord.Interaction, current: str): roles = [r.name for r in interaction.guild.roles if current.lower() in r.name.lower()] return [app_commands.Choice(name=role, value=role) for role in roles[:25]]
Example 2: Advanced Error Handling
Python@commands.Cog.listener() async def on_app_command_error(self, interaction: discord.Interaction, error): if isinstance(error, app_commands.MissingPermissions): embed = discord.Embed(title="Permission Error", color=0xff0000) embed.description = "You don't have permission to use this command" await interaction.response.send_message(embed=embed, ephemeral=True) elif isinstance(error, app_commands.CommandOnCooldown): await interaction.response.send_message( f"Command on cooldown. Try again in {error.retry_after:.2f}s", ephemeral=True )
Example 3: Paginated Embed System
Pythonclass PaginatedEmbed: def __init__(self, pages: list[discord.Embed]): self.pages = pages self.current_page = 0 def get_view(self): view = discord.ui.View(timeout=180) @discord.ui.button(emoji="◀️", style=discord.ButtonStyle.gray) async def previous(interaction: discord.Interaction, button: discord.ui.Button): self.current_page = max(0, self.current_page - 1) await interaction.response.edit_message(embed=self.pages[self.current_page], view=view) @discord.ui.button(emoji="▶️", style=discord.ButtonStyle.gray) async def next(interaction: discord.Interaction, button: discord.ui.Button): self.current_page = min(len(self.pages) - 1, self.current_page + 1) await interaction.response.edit_message(embed=self.pages[self.current_page], view=view) view.add_item(previous) view.add_item(next) return view
Best Practices
Security & Permissions
- Always validate user permissions before executing commands
- Use ephemeral responses for sensitive information
- Implement rate limiting with
@commands.cooldown() - Never hardcode tokens or sensitive data
Performance Optimization
- Use connection pooling for database operations
- Implement caching for frequently accessed data
- Batch database operations when possible
- Use
defer()for long-running commands
Code Organization
- Separate commands into logical cogs
- Use dependency injection for shared resources
- Implement proper logging with structured formats
- Create reusable utility functions
Error Handling
- Implement global error handlers
- Provide user-friendly error messages
- Log errors with context for debugging
- Use try-catch blocks for external API calls
Testing Strategy
Pythonimport pytest import discord.ext.test as dpytest @pytest.mark.asyncio async def test_ban_command(): await dpytest.message("!ban @user spam") assert dpytest.verify().message().contains("User Banned")
Common Pitfalls
Authentication Issues
- Don't store tokens in source code - use environment variables
- Don't share bot tokens publicly or in repositories
- Don't use user tokens for bot applications
Rate Limiting
- Don't ignore Discord's rate limits - implement proper backoff
- Don't spam API endpoints - batch operations when possible
- Don't forget to handle 429 responses gracefully
Memory Management
- Don't cache large amounts of data without cleanup
- Don't create infinite loops in event listeners
- Don't forget to close database connections properly
Command Design
- Don't create commands without proper permission checks
- Don't make commands that can be easily abused
- Don't forget to validate user input thoroughly
Deployment Considerations
- Use process managers (PM2, systemd) for production
- Implement health checks and restart mechanisms
- Monitor memory usage and performance metrics
- Set up proper logging aggregation and alerting