Command Structure
Aphonos uses Discord.js slash commands with a modular architecture. Each command is a separate TypeScript module that exports adata object and an execute function.
Command Interface
All commands must implement theCommand interface defined in src/utils/commandLoader.ts:35:
Basic Command Template
Here’s the minimal structure for a new command:Real-World Examples
Simple Command: Avatar
Fromsrc/commands/avatar.ts, a basic utility command:
Moderation Command: Kick
Fromsrc/commands/kick.ts, showing moderation with logging:
Interactive Command: Help
Fromsrc/commands/help.ts, showing button interactions:
Adding a New Command
Command Options
Discord.js provides various option types:String Option
User Option
Integer Option
Boolean Option
Choice Option
Subcommands
For complex commands with multiple actions:Command Execution Flow
- User invokes slash command in Discord
- Discord sends interaction to bot
handleInteraction()receives the interaction (src/utils/eventHandlers.ts:21)- Permission checks are performed:
CommandAccessManager.canUseCommand()- Guild-level accessRolePermissions.hasCommandPermission()- Role-based permissionsRolePermissions.canUseCommandInChannel()- Channel restrictions
- Command is retrieved from the commands collection
command.execute()is called with the interaction- Command performs its logic and responds to the interaction
Best Practices
Always Handle Errors
Use Ephemeral for Errors
Error messages should be private:Check for Null/Undefined
Use Embeds for Rich Responses
Handle Deferred Responses
For long-running commands:Permission Levels
Commands can be restricted by role level:- Admin: Alterministrator role only
- Moderator: Moderator role and above
- Basic: All users
RolePermissions in the event handler.
Moderation Commands
Moderation commands receive a second parameter:/help/info/sins/avatar/archives/link/checklink/syncroles
Testing Your Command
- Start the bot in development mode
- Use the command in your test Discord server
- Test various inputs and edge cases
- Verify error handling works
- Check that permissions are respected
- Ensure embeds display correctly
- Test on mobile and desktop clients
Common Issues
Command not appearing in Discord
Command not appearing in Discord
- Ensure the command is registered in
commandLoader.ts - Rebuild the bot with
npm run build - Restart the bot
- Wait a few minutes for Discord to update slash commands
- Check console for registration errors
Permission errors
Permission errors
- Verify the bot has required permissions in the server
- Check role hierarchy (bot role must be higher than target roles)
- Ensure permission checks are implemented correctly
Import errors with .js extension
Import errors with .js extension
- TypeScript uses
.tsfiles but imports must use.js - This is required for ES module compatibility
- Example:
import * as mycommand from "../commands/mycommand.js";
Interaction already replied error
Interaction already replied error
- Don’t call
reply()twice on the same interaction - Use
editReply()orfollowUp()after the initial reply - Check if interaction was deferred before replying
Next Steps
- Review existing commands in
src/commands/for more examples - Read the Discord.js Guide
- Check the Discord.js Documentation
- Explore utility modules in
src/utils/for helper functions