Yato uses the gcommands framework to handle commands. Commands are automatically loaded from the src/commands/ directory and work as both slash commands and mention-based commands.
Command module structure
All commands follow a standard module.exports pattern. There are two ways to define commands:
Simple export
Class-based
The most common pattern used in Yato: src/commands/utilities/ping.js
const { MessageEmbed } = require ( 'discord.js' );
const colors = require ( '../../config/colors.json' );
module . exports = {
name: 'ping' ,
slash: true ,
description: 'Checks the bot ping!' ,
run : ({ client , respond }) => {
const choices = [
'Is this really my ping?' ,
'Is this okay? i can \' t look!' ,
'I hope it isn \' t bad!'
];
const response = choices [ Math . floor ( Math . random () * choices . length )];
const embed = new MessageEmbed ()
. setTitle ( `:ping_pong: ${ response } ` )
. setColor ( colors . default )
. addField ( 'API Latency' , `** ${ Math . round ( client . ws . ping ) } ms**` );
respond ( embed );
}
};
For more complex commands: src/commands/misc/activities.js
const { Command } = require ( 'gcommands' );
const { MessageEmbed } = require ( 'discord.js' );
module . exports = class Activities extends Command {
constructor ( ... args ) {
super ( ... args , {
name: 'activities' ,
slash: true ,
description: 'The all new Discord Activities (BETA)' ,
args: [
{
name: 'voicechannel' ,
type: '7' ,
description: 'Select Voice Channel' ,
required: true
}
],
userRequiredPermissions: 'CREATE_INSTANT_INVITE' ,
cooldown: 10
});
}
async run ({ client , guild , respond }, arrayArgs , args ) {
// Command logic here
}
};
Creating a new command
Choose a category
Determine which category your command belongs to:
games/ - Game integrations
images/ - Image generation and reactions
information/ - Server and user information
memes/ - Entertainment and memes
misc/ - Miscellaneous features
moderation/ - Moderation tools
utilities/ - Bot utilities
weeb/ - Anime and manga features
Create the command file
Create a new .js file in the appropriate category directory: touch src/commands/utilities/mycommand.js
Define the command structure
Use the standard module.exports pattern with required properties: module . exports = {
name: 'mycommand' ,
slash: true ,
description: 'What this command does' ,
run : ({ client , respond }) => {
// Your command logic
}
};
Restart the bot
Commands are loaded on startup, so restart the bot to register your new command:
Command properties
All available properties you can use in command definitions:
Required properties
Property Type Description namestring Command name (lowercase, no spaces) descriptionstring What the command does runfunction Command execution logic
Optional properties
Property Type Description slashboolean Enable as slash command (default: false) cooldownnumber Cooldown in seconds guildOnlystring Restrict to specific guild ID userRequiredPermissionsstring Required user permissions clientRequiredPermissionsstring Required bot permissions minArgsnumber Minimum argument count expectedArgsstring|array Argument definitions
Set slash: true to enable the command as a slash command. Without this, the command only works with the mention prefix.
Defining arguments
There are two ways to define command arguments:
Argument types
Common Discord slash command option types:
Type Code Description String 3 Text input Integer 4 Whole number Boolean 5 True/false User 6 User mention Channel 7 Channel mention Role 8 Role mention
Run function parameters
The run function receives destructured parameters:
run : async ({ client , guild , channel , member , respond , edit }, arrayArgs , args ) => {
// client - Discord.js client instance
// guild - The guild where command was used
// channel - The channel where command was used
// member - The member who used the command
// respond - Function to send response
// edit - Function to edit response
// arrayArgs - Arguments as array
// args - Arguments as object
}
Responding to commands
Use the respond() function to send messages:
Simple embed
Ephemeral message
Deferred response
With components
const embed = new MessageEmbed ()
. setColor ( colors . default )
. setDescription ( 'Hello!' );
respond ( embed );
Permission checks
Add permission requirements to your command:
src/commands/moderation/ban.js
module . exports = {
name: 'ban' ,
userRequiredPermissions: 'BAN_MEMBERS' ,
clientRequiredPermissions: 'BAN_MEMBERS' ,
run : async ({ guild , member , respond }, arrayArgs , args ) => {
// gcommands automatically checks permissions
// This code only runs if both user and bot have BAN_MEMBERS
}
};
Common permissions:
ADMINISTRATOR
MANAGE_GUILD
MANAGE_CHANNELS
KICK_MEMBERS
BAN_MEMBERS
MANAGE_MESSAGES
CREATE_INSTANT_INVITE
Using shared utilities
Import shared utilities from the structures folder:
const utils = require ( '../../structures/utils' );
const colors = require ( '../../config/colors.json' );
const emojis = require ( '../../config/emojis.json' );
module . exports = {
run : async ({ client , channel , respond }) => {
// Use utility functions
const embeds = await utils . animeMangaSearch ( 'anime' , query , channel );
// Use config values
const TickYes = client . emojis . cache . get ( emojis . TickYes );
const embed = new MessageEmbed ()
. setColor ( colors . green )
. setDescription ( ` ${ TickYes } Success!` );
}
};
Interactive components
Create commands with buttons and collectors:
src/commands/weeb/anime.js
const { MessageButton , MessageActionRow } = require ( 'gcommands' );
module . exports = {
run : async ({ member , respond , edit }) => {
// Create buttons
const nextPage = new MessageButton ()
. setStyle ( 'gray' )
. setLabel ( 'Next' )
. setID ( 'next' )
. toJSON ();
const buttonRow = new MessageActionRow ()
. addComponent ( nextPage );
const msg = await respond ({
content: embed ,
components: buttonRow
});
// Create collector
const filter = ( button ) => button . clicker . user . id === member . user . id ;
const collector = msg . createButtonCollector ( filter , {
time: 60000
});
collector . on ( 'collect' , ( button ) => {
button . edit ({ content: newEmbed });
});
}
};
Example: Complete command
Here’s a complete example combining multiple features:
src/commands/utilities/serverinfo.js
const { MessageEmbed } = require ( 'discord.js' );
const moment = require ( 'moment' );
const colors = require ( '../../config/colors.json' );
module . exports = {
name: 'serverinfo' ,
slash: true ,
description: 'Display information about the server' ,
cooldown: 5 ,
run : ({ guild , respond }) => {
const embed = new MessageEmbed ()
. setTitle ( guild . name )
. setColor ( colors . default )
. setThumbnail ( guild . iconURL ({ dynamic: true }))
. addField ( 'Owner' , `<@ ${ guild . ownerID } >` , true )
. addField ( 'Members' , guild . memberCount . toString (), true )
. addField ( 'Created' , moment ( guild . createdAt ). format ( 'MMM DD, YYYY' ), true )
. addField ( 'Channels' , guild . channels . cache . size . toString (), true )
. addField ( 'Roles' , guild . roles . cache . size . toString (), true )
. setFooter ( `ID: ${ guild . id } ` );
respond ( embed );
}
};
Check existing commands in src/commands/ for more examples and patterns used throughout Yato.