How to organize commands?
Hello,
Im new to TS and Discord.JS, but I have knowloadge on programming, but this framework is new to me, I need to make different commands, I have create 3 folders, user, admin, games, every dir has it owns games and class (not made all but im there), and this is a simple class Im not sure if this what Im doing is correct, but for organizing it should be.
this is the code I have made if there is a better way of doing this lmk:
import { ApplyOptions } from '@sapphire/decorators';
import { ChatInputCommand, Command } from '@sapphire/framework';
import { ChatInputCommandInteraction, EmbedBuilder } from 'discord.js';
import { createEmbed } from '../../lib/utils';
@ApplyOptions<Command.Options>({
description: 'Show user balance'
})
export class UserBalance extends Command {
public override registerApplicationCommands(registry: Command.Registry) {
registry.registerChatInputCommand((builder) => {
builder
.setName(this.name)
.setDescription(this.description)
.addUserOption((option) => option.setName('user').setDescription('The user to check').setRequired(false));
});
}
public override async chatInputRun(interaction: ChatInputCommandInteraction, _context: ChatInputCommand.RunContext) {
return this.sendInfo(interaction);
}
private async sendInfo(interaction: Command.ChatInputCommandInteraction) {
const user = interaction.options.getUser('user') ?? interaction.user;
const embed: EmbedBuilder = createEmbed('Balance', `balance of ${user.username}`);
await interaction.reply({ embeds: [embed] });
}
}
import { ApplyOptions } from '@sapphire/decorators';
import { ChatInputCommand, Command } from '@sapphire/framework';
import { ChatInputCommandInteraction, EmbedBuilder } from 'discord.js';
import { createEmbed } from '../../lib/utils';
@ApplyOptions<Command.Options>({
description: 'Show user balance'
})
export class UserBalance extends Command {
public override registerApplicationCommands(registry: Command.Registry) {
registry.registerChatInputCommand((builder) => {
builder
.setName(this.name)
.setDescription(this.description)
.addUserOption((option) => option.setName('user').setDescription('The user to check').setRequired(false));
});
}
public override async chatInputRun(interaction: ChatInputCommandInteraction, _context: ChatInputCommand.RunContext) {
return this.sendInfo(interaction);
}
private async sendInfo(interaction: Command.ChatInputCommandInteraction) {
const user = interaction.options.getUser('user') ?? interaction.user;
const embed: EmbedBuilder = createEmbed('Balance', `balance of ${user.username}`);
await interaction.reply({ embeds: [embed] });
}
}
5 Replies
what should be awaited??
this is simply a matter of personal preference, you can organize your commands and folders in any way you want, sapphire just provides the tooling
do you fetch remote data?
yes i fetch data from MongoDB
i do await
I Will send my code Later for review
@choke let me know if this is correct
import { ApplyOptions } from '@sapphire/decorators';
import { ChatInputCommand, Command } from '@sapphire/framework';
import { update, userExists } from '../../models/user';
import { ChatInputCommandInteraction } from 'discord.js';
import { amountToSuffix, createEmbed, suffixToAmount } from '../../lib/utils';
import { gemsIcon, knowIcon } from '../../lib/constants';
@ApplyOptions<Command.Options>({
description: 'Add user balance',
preconditions: ['OwnersOnly']
})
export class AdminAddBalance extends Command {
public override registerApplicationCommands(registry: Command.Registry) {
registry.registerChatInputCommand((builder) => {
builder
.setName(this.name)
.setDescription(this.description)
.addUserOption((option) => option.setName('user').setDescription('The user to add the balance').setRequired(true))
.addStringOption((option) => option.setName('amount').setDescription('The amount to add').setRequired(true));
});
}
public override async chatInputRun(interaction: ChatInputCommandInteraction, _context: ChatInputCommand.RunContext) {
return await this.sendInfo(interaction);
}
private async sendInfo(interaction: ChatInputCommandInteraction) {
const userOption = interaction.options.getUser('user');
const amountOption = interaction.options.getString('amount');
const { exists, user } = await userExists(userOption?.id as string);
if (!exists || !user) {
return await interaction.reply({ content: 'User not registered', ephemeral: true });
}
const amount = suffixToAmount(amountOption!);
await update(user, { balance: user.balance + amount });
const embed = createEmbed(`${knowIcon} Balance`, `Added ${gemsIcon}${amountToSuffix(amount)} to ${userOption?.username}'s balance.`);
return await interaction.reply({ embeds: [embed] });
}
}
import { ApplyOptions } from '@sapphire/decorators';
import { ChatInputCommand, Command } from '@sapphire/framework';
import { update, userExists } from '../../models/user';
import { ChatInputCommandInteraction } from 'discord.js';
import { amountToSuffix, createEmbed, suffixToAmount } from '../../lib/utils';
import { gemsIcon, knowIcon } from '../../lib/constants';
@ApplyOptions<Command.Options>({
description: 'Add user balance',
preconditions: ['OwnersOnly']
})
export class AdminAddBalance extends Command {
public override registerApplicationCommands(registry: Command.Registry) {
registry.registerChatInputCommand((builder) => {
builder
.setName(this.name)
.setDescription(this.description)
.addUserOption((option) => option.setName('user').setDescription('The user to add the balance').setRequired(true))
.addStringOption((option) => option.setName('amount').setDescription('The amount to add').setRequired(true));
});
}
public override async chatInputRun(interaction: ChatInputCommandInteraction, _context: ChatInputCommand.RunContext) {
return await this.sendInfo(interaction);
}
private async sendInfo(interaction: ChatInputCommandInteraction) {
const userOption = interaction.options.getUser('user');
const amountOption = interaction.options.getString('amount');
const { exists, user } = await userExists(userOption?.id as string);
if (!exists || !user) {
return await interaction.reply({ content: 'User not registered', ephemeral: true });
}
const amount = suffixToAmount(amountOption!);
await update(user, { balance: user.balance + amount });
const embed = createEmbed(`${knowIcon} Balance`, `Added ${gemsIcon}${amountToSuffix(amount)} to ${userOption?.username}'s balance.`);
return await interaction.reply({ embeds: [embed] });
}
}

this is what I have organized the commands