mirror of
https://github.com/xHyroM/bun-discord-bot.git
synced 2024-11-22 06:31:06 +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 { SlashCommandStringOption } from "discord.js";
|
||||||
import { defineCommand } from "../loaders/commands";
|
import { defineCommand } from "../loaders/commands";
|
||||||
import { AutocompleteContext } from "../structs/context/AutocompleteContext";
|
import { AutocompleteContext } from "../structs/context/AutocompleteContext";
|
||||||
import { Option } from "../structs/Command";
|
import { InteractionCommandContext } from "../structs/context/CommandContext";
|
||||||
|
|
||||||
defineCommand({
|
defineCommand({
|
||||||
name: "docs",
|
name: "docs",
|
||||||
|
description: "Search at docs",
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
...new SlashCommandStringOption()
|
...new SlashCommandStringOption()
|
||||||
|
@ -13,9 +14,14 @@ defineCommand({
|
||||||
.setAutocomplete(true)
|
.setAutocomplete(true)
|
||||||
.setDescription("Select query")
|
.setDescription("Select query")
|
||||||
.toJSON(),
|
.toJSON(),
|
||||||
run: (_: Option, context: AutocompleteContext) => {
|
run: (context: AutocompleteContext) => {
|
||||||
return context.interaction.respond([{ name: "heh", value: "heh" }]);
|
return context.respond([{ name: "heh", value: "heh" }]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
run: (context: InteractionCommandContext) => {
|
||||||
|
context.reply({
|
||||||
|
content: "ccc"
|
||||||
|
});
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
import "./version.ts";
|
import "./version.ts";
|
||||||
import "./docs.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({
|
export default defineCommand({
|
||||||
name: "version",
|
name: "version",
|
||||||
|
description: "Show version",
|
||||||
options: [],
|
options: [],
|
||||||
run: (context: InteractionCommandContext) => {
|
run: (context: InteractionCommandContext) => {
|
||||||
context.interaction.reply({
|
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 { COMMANDS } from "../loaders/commands.ts";
|
||||||
import { defineListener } from "../loaders/listeners.ts";
|
import { defineListener } from "../loaders/listeners.ts";
|
||||||
import { InteractionCommandContext } from "../structs/context/CommandContext.ts";
|
import { InteractionCommandContext } from "../structs/context/CommandContext.ts";
|
||||||
|
import { AutocompleteContext } from "../structs/context/AutocompleteContext.ts";
|
||||||
|
import { StringOption } from "../structs/Command.ts";
|
||||||
|
|
||||||
defineListener({
|
defineListener({
|
||||||
event: Events.InteractionCreate,
|
event: Events.InteractionCreate,
|
||||||
run: (interaction: Interaction) => {
|
run: async(interaction: Interaction) => {
|
||||||
if (interaction.isChatInputCommand()) return handleCommand(interaction);
|
if (interaction.isChatInputCommand()) return await handleCommand(interaction);
|
||||||
|
if (interaction.isAutocomplete()) return await handleAutocomplete(interaction);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function handleCommand(interaction: ChatInputCommandInteraction) {
|
async function handleCommand(interaction: ChatInputCommandInteraction) {
|
||||||
const command = COMMANDS.get(interaction.commandName);
|
const command = COMMANDS.get(interaction.commandName);
|
||||||
|
|
||||||
if (!command || !command.run) {
|
if (!command || !command.run) {
|
||||||
|
@ -23,5 +26,37 @@ function handleCommand(interaction: ChatInputCommandInteraction) {
|
||||||
return;
|
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";
|
import type { Command } from "../structs/Command.ts";
|
||||||
|
|
||||||
export const COMMANDS: Map<string, Command> = new Map();
|
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) {
|
export function defineCommand<T extends Command>(command: T) {
|
||||||
COMMANDS.set(command.name, command);
|
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 |
|
APIApplicationCommandSubcommandGroupOption |
|
||||||
StringOption;
|
StringOption;
|
||||||
|
|
||||||
interface StringOption {
|
export interface StringOption {
|
||||||
name: string;
|
name: string;
|
||||||
name_localizations?: LocalizationMap;
|
name_localizations?: LocalizationMap;
|
||||||
description: string;
|
description: string;
|
||||||
|
@ -25,11 +25,12 @@ interface StringOption {
|
||||||
type: ApplicationCommandOptionType.String;
|
type: ApplicationCommandOptionType.String;
|
||||||
autocomplete?: boolean;
|
autocomplete?: boolean;
|
||||||
choices?: APIApplicationCommandOptionChoice[];
|
choices?: APIApplicationCommandOptionChoice[];
|
||||||
run: (option: Option, interaction: AutocompleteContext) => any;
|
run: (interaction: AutocompleteContext) => any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Command {
|
export interface Command {
|
||||||
name: string;
|
name: string;
|
||||||
|
description: string;
|
||||||
options: Option[];
|
options: Option[];
|
||||||
run?: (
|
run?: (
|
||||||
context: CommandContext<true>
|
context: CommandContext<true>
|
||||||
|
|
|
@ -3,4 +3,3 @@ export interface Tag {
|
||||||
answer: string;
|
answer: string;
|
||||||
keywords: string[];
|
keywords: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
import { AutocompleteInteraction } from "discord.js";
|
import { ApplicationCommandOptionChoiceData, AutocompleteInteraction } from "discord.js";
|
||||||
import { Option } from "../Command.ts";
|
import { Command, Option } from "../Command.ts";
|
||||||
|
|
||||||
export class AutocompleteContext {
|
export class AutocompleteContext {
|
||||||
public option: Option;
|
public option: Option;
|
||||||
|
public command: Command;
|
||||||
public interaction: AutocompleteInteraction;
|
public interaction: AutocompleteInteraction;
|
||||||
|
|
||||||
public constructor(option: Option, interaction: AutocompleteInteraction) {
|
public constructor(option: Option, command: Command, interaction: AutocompleteInteraction) {
|
||||||
this.option = option;
|
this.option = option;
|
||||||
|
this.command = command;
|
||||||
this.interaction = interaction;
|
this.interaction = interaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,4 +23,8 @@ export class AutocompleteContext {
|
||||||
get options() {
|
get options() {
|
||||||
return this.interaction.options;
|
return this.interaction.options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public respond(options: ApplicationCommandOptionChoiceData[]) {
|
||||||
|
return this.interaction.respond(options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue