Skip to content

Commit

Permalink
feat(command): add help command
Browse files Browse the repository at this point in the history
  • Loading branch information
tinarskii committed Oct 27, 2022
1 parent 73abae8 commit a377f7b
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 91 deletions.
12 changes: 6 additions & 6 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# This is your database's credentials. It can be postgres or cockroachdb.
DATABASE_URL=
MOORE_DATABASE_URL=

# This is your discord bot tokens, you can get them from https://discordapp.com/developers/applications/me
DEV_TOKEN=
TOKEN=
MOORE_DEV_TOKEN=
MOORE_TOKEN=

# This is your discord bot client ID, you can get it from https://discordapp.com/developers/applications/me
DEV_CLIENT_ID=
CLIENT_ID=
MOORE_DEV_CLIENT_ID=
MOORE_CLIENT_ID=

# This is the test guild id
GUILD_ID=
MOORE_GUILD_ID=

# Set to production if you want to deploy command globally
NODE_ENV=
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "1.0.0",
"description": "An open-source, general purpose discord bot with a lot of commands and utilities",
"main": "src/index.js",
"type": "commonjs",
"type": "module",
"scripts": {
"start": "cd dist && node index",
"format": "prettier -w .",
Expand All @@ -18,10 +18,15 @@
"license": "Apache-2.0",
"dependencies": {
"@discordjs/builders": "^1.3.0",
"@discordx/importer": "^1.1.10",
"@discordx/pagination": "^3.3.1",
"@discordx/utilities": "^5.1.0",
"@types/node": "^18.11.3",
"@typescript-eslint/eslint-plugin": "^5.40.1",
"@typescript-eslint/parser": "^5.40.1",
"discord-api-types": "^0.37.14",
"discord.js": "~14.6.0",
"discordx": "^11.4.0",
"dotenv": "^16.0.3",
"eslint": "8.22",
"typescript": "^4.8.4"
Expand Down
107 changes: 107 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

76 changes: 36 additions & 40 deletions src/commands/misc/help.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,42 @@
import { ApplicationCommandRegistry } from "@sapphire/framework";
import { Subcommand } from "@sapphire/plugin-subcommands";
import { Discord, MetadataStorage, Slash, SlashGroup } from "discordx";
import { EmbedBuilder, Colors, CommandInteraction } from "discord.js";
import { Category, ICategory } from "@discordx/utilities";
import { Pagination } from "@discordx/pagination";
import { bot } from "../../index.js";
import type { DApplicationCommand } from "discordx";

export class HelpCommand extends Subcommand {
public constructor(context: Subcommand.Context, options: Subcommand.Options) {
super(context, {
...options,
name: "help",
description: "Shows a list of all commands or info about a specific command.",
subcommands: [
{
name: "all",
chatInputRun: "chatInputAll"
},
{
name: "command",
chatInputRun: "chatInputCommand"
}
]
@Discord()
@Category("Miscellaneous")
@SlashGroup({
description: "Shows a list of all commands or info about a specific command.",
name: "help"
})
@SlashGroup("help")
export class HelpCommand {
@Slash({ description: "Show all available commands" })
async all(interaction: CommandInteraction) {
const commands = MetadataStorage.instance.applicationCommandSlashesFlat.map((cmd: DApplicationCommand & ICategory) => {
return { description: cmd.description, name: cmd.name, category: cmd.category };
});
}
public override registerApplicationCommands(registry: ApplicationCommandRegistry) {
registry.registerChatInputCommand((builder) =>
builder
.setName("help")
.setDescription("Shows a list of commands.")
.addSubcommand((subcommand) => subcommand.setName("all").setDescription("Shows a list of all commands."))
.addSubcommand((subcommand) =>
subcommand
.setName("command")
.setDescription("Shows specific command information.")
.addStringOption((command) =>
command.setName("command").setDescription("The command to show information for.").setRequired(true),
),
),
);
}
public async chatInputAll(interaction: Subcommand.ChatInputInteraction) {
const commands = this.container.stores.get("commands");
const commandsMap = commands.map((cmd) => {
return { name: cmd.name, description: cmd.description };
const categories = new Set(commands.map((c) => c.category));
const pages = Array.from(categories).map((category, idx) => {
const categoryCommands = commands.filter((c) => c.category === category);
const embed = new EmbedBuilder()
.setColor(Colors.Blue)
.setFooter({
text: "You can send `/help command` follow with command name to get more information about it.",
iconURL: interaction.user.avatarURL()!,
})
.setThumbnail(bot.user!.displayAvatarURL())
.setTitle(`[Page ${idx + 1}/${categories.size}] Category: ${category}`);

categoryCommands.forEach((c) => {
embed.addFields({ name: `/${c.name}`, value: c.description });
});
return { embeds: [embed] };
});

const pagination = new Pagination(interaction, pages);
await pagination.send();
}
public async chatInputCommand(interaction: Subcommand.ChatInputInteraction) {}
}
39 changes: 15 additions & 24 deletions src/commands/misc/ping.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
import { isMessageInstance } from "@sapphire/discord.js-utilities";
import { ApplicationCommandRegistry, Command } from "@sapphire/framework";
import type { CommandInteraction } from "discord.js";
import { Discord, Slash } from "discordx";
import { bot } from "../../index.js";
import { Category } from "@discordx/utilities";

export class PingCommand extends Command {
public constructor(context: Command.Context, options: Command.Options) {
super(context, {
...options,
name: "ping",
description: "Replies with pong!",
@Discord()
@Category("Miscellaneous")
export class PingCommand {
@Slash({ description: "Replies with pong!", name: "ping" })
async ping(interaction: CommandInteraction): Promise<void> {
const sent = await interaction.reply({
content: "Pinging...",
fetchReply: true,
});
}
public override registerApplicationCommands(registry: ApplicationCommandRegistry) {
registry.registerChatInputCommand((builder) =>
builder.setName("ping").setDescription("Check the bot's ping")
);
}
public async chatInputRun(interaction: Command.ChatInputInteraction) {
const msg = await interaction.reply({ content: "Pinging...", fetchReply: true });

if (isMessageInstance(msg)) {
const diff = msg.createdTimestamp - interaction.createdTimestamp;
const ping = Math.round(this.container.client.ws.ping);
return interaction.editReply(`Round trip latency : ${diff}ms\nWebsocket heartbeat : ${ping}ms`);
}

return interaction.editReply("Failed to retrieve ping :(");
const timeDiff = (sent.createdTimestamp - interaction.createdTimestamp);
await interaction.editReply(`🏓Pong!\nRound-trip latency: ${timeDiff} ms\nWebsocket heartbeat: ${Math.round(bot.ws.ping)} ms`);
}
}
}
Loading

0 comments on commit a377f7b

Please sign in to comment.