mirror of
https://github.com/xHyroM/bun-discord-bot.git
synced 2024-11-21 22:21:05 +01:00
feat: make autocomplete options working
This commit is contained in:
parent
38acccfa2b
commit
c4b21275f9
8 changed files with 86 additions and 15 deletions
|
@ -1,10 +1,11 @@
|
|||
import { SlashCommandStringOption } from "discord.js";
|
||||
import { defineCommand } from "../loaders/commands";
|
||||
import { AutocompleteContext } from "../structs/context/AutocompleteContext";
|
||||
import { Option } from "../structs/Command";
|
||||
import { InteractionCommandContext } from "../structs/context/CommandContext";
|
||||
|
||||
defineCommand({
|
||||
name: "docs",
|
||||
description: "Search at docs",
|
||||
options: [
|
||||
{
|
||||
...new SlashCommandStringOption()
|
||||
|
@ -13,9 +14,14 @@ defineCommand({
|
|||
.setAutocomplete(true)
|
||||
.setDescription("Select query")
|
||||
.toJSON(),
|
||||
run: (_: Option, context: AutocompleteContext) => {
|
||||
return context.interaction.respond([{ name: "heh", value: "heh" }]);
|
||||
run: (context: AutocompleteContext) => {
|
||||
return context.respond([{ name: "heh", value: "heh" }]);
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
run: (context: InteractionCommandContext) => {
|
||||
context.reply({
|
||||
content: "ccc"
|
||||
});
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
import "./version.ts";
|
||||
import "./docs.ts";
|
||||
|
||||
import { registerCommands } from "../loaders/commands.ts";
|
||||
await registerCommands();
|
||||
|
|
|
@ -4,6 +4,7 @@ import { InteractionCommandContext } from "../structs/context/CommandContext.ts"
|
|||
|
||||
export default defineCommand({
|
||||
name: "version",
|
||||
description: "Show version",
|
||||
options: [],
|
||||
run: (context: InteractionCommandContext) => {
|
||||
context.interaction.reply({
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
import { Events, Interaction, ChatInputCommandInteraction } from "discord.js";
|
||||
import { Events, Interaction, ChatInputCommandInteraction, AutocompleteInteraction } from "discord.js";
|
||||
import { COMMANDS } from "../loaders/commands.ts";
|
||||
import { defineListener } from "../loaders/listeners.ts";
|
||||
import { InteractionCommandContext } from "../structs/context/CommandContext.ts";
|
||||
import { AutocompleteContext } from "../structs/context/AutocompleteContext.ts";
|
||||
import { StringOption } from "../structs/Command.ts";
|
||||
|
||||
defineListener({
|
||||
event: Events.InteractionCreate,
|
||||
run: (interaction: Interaction) => {
|
||||
if (interaction.isChatInputCommand()) return handleCommand(interaction);
|
||||
run: async(interaction: Interaction) => {
|
||||
if (interaction.isChatInputCommand()) return await handleCommand(interaction);
|
||||
if (interaction.isAutocomplete()) return await handleAutocomplete(interaction);
|
||||
|
||||
return;
|
||||
}
|
||||
})
|
||||
|
||||
function handleCommand(interaction: ChatInputCommandInteraction) {
|
||||
async function handleCommand(interaction: ChatInputCommandInteraction) {
|
||||
const command = COMMANDS.get(interaction.commandName);
|
||||
|
||||
if (!command || !command.run) {
|
||||
|
@ -23,5 +26,37 @@ function handleCommand(interaction: ChatInputCommandInteraction) {
|
|||
return;
|
||||
}
|
||||
|
||||
command.run(new InteractionCommandContext(command, interaction));
|
||||
const context = new InteractionCommandContext(command, interaction);
|
||||
await Promise.resolve(command.run(context))
|
||||
.catch(async error => {
|
||||
context.reply({
|
||||
content: `Something went wrong... ${error.message} (${error.code})`
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function handleAutocomplete(interaction: AutocompleteInteraction) {
|
||||
const command = COMMANDS.get(interaction.commandName);
|
||||
if (!command) return;
|
||||
|
||||
let options = command.options;
|
||||
|
||||
if (interaction.options.getSubcommandGroup(false))
|
||||
options = options.find(o => o.name === interaction.options.getSubcommandGroup())?.options;
|
||||
|
||||
if (interaction.options.getSubcommand(false))
|
||||
options = options.find(o => o.name === interaction.options.getSubcommand())?.options;
|
||||
|
||||
const focused = interaction.options.getFocused(true);
|
||||
const option = options.find(o => o.name === focused.name) as StringOption;
|
||||
if (!option) return;
|
||||
|
||||
|
||||
const context = new AutocompleteContext(option, command, interaction);
|
||||
await Promise.resolve(command.run(context))
|
||||
.catch(async error => {
|
||||
context.respond({
|
||||
content: `Something went wrong... ${error.message} (${error.code})`
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,7 +1,27 @@
|
|||
import { REST, Routes, SlashCommandBuilder } from "discord.js";
|
||||
import { Bubu } from "../structs/Client.ts";
|
||||
import type { Command } from "../structs/Command.ts";
|
||||
|
||||
export const COMMANDS: Map<string, Command> = new Map();
|
||||
export const REST_CLIENT = new REST().setToken(process.env.DISCORD_TOKEN);
|
||||
|
||||
export function defineCommand<T extends Command>(command: T) {
|
||||
COMMANDS.set(command.name, command);
|
||||
}
|
||||
|
||||
export async function registerCommands() {
|
||||
const commands = [...COMMANDS.values()];
|
||||
|
||||
await REST_CLIENT.put(
|
||||
Routes.applicationCommands("995690041793839124"),
|
||||
{
|
||||
body: commands.map(d => ({
|
||||
...new SlashCommandBuilder()
|
||||
.setName(d.name)
|
||||
.setDescription(d.description)
|
||||
.toJSON(),
|
||||
options: d.options
|
||||
}))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ export type Option = APIApplicationCommandAttachmentOption |
|
|||
APIApplicationCommandSubcommandGroupOption |
|
||||
StringOption;
|
||||
|
||||
interface StringOption {
|
||||
export interface StringOption {
|
||||
name: string;
|
||||
name_localizations?: LocalizationMap;
|
||||
description: string;
|
||||
|
@ -25,11 +25,12 @@ interface StringOption {
|
|||
type: ApplicationCommandOptionType.String;
|
||||
autocomplete?: boolean;
|
||||
choices?: APIApplicationCommandOptionChoice[];
|
||||
run: (option: Option, interaction: AutocompleteContext) => any;
|
||||
run: (interaction: AutocompleteContext) => any;
|
||||
}
|
||||
|
||||
export interface Command {
|
||||
name: string;
|
||||
description: string;
|
||||
options: Option[];
|
||||
run?: (
|
||||
context: CommandContext<true>
|
||||
|
|
|
@ -3,4 +3,3 @@ export interface Tag {
|
|||
answer: string;
|
||||
keywords: string[];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
import { AutocompleteInteraction } from "discord.js";
|
||||
import { Option } from "../Command.ts";
|
||||
import { ApplicationCommandOptionChoiceData, AutocompleteInteraction } from "discord.js";
|
||||
import { Command, Option } from "../Command.ts";
|
||||
|
||||
export class AutocompleteContext {
|
||||
public option: Option;
|
||||
public command: Command;
|
||||
public interaction: AutocompleteInteraction;
|
||||
|
||||
public constructor(option: Option, interaction: AutocompleteInteraction) {
|
||||
public constructor(option: Option, command: Command, interaction: AutocompleteInteraction) {
|
||||
this.option = option;
|
||||
this.command = command;
|
||||
this.interaction = interaction;
|
||||
}
|
||||
|
||||
|
@ -21,4 +23,8 @@ export class AutocompleteContext {
|
|||
get options() {
|
||||
return this.interaction.options;
|
||||
}
|
||||
|
||||
public respond(options: ApplicationCommandOptionChoiceData[]) {
|
||||
return this.interaction.respond(options);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue