feat: interaction handler, version command

This commit is contained in:
Jozef Steinhübl 2023-08-23 20:09:34 +02:00
parent 01fc5af809
commit 22fbcf4bf7
13 changed files with 137 additions and 22 deletions

View file

@ -6,7 +6,7 @@
"validate:tags": "cd scripts/validate_tags && bun install && bun start" "validate:tags": "cd scripts/validate_tags && bun install && bun start"
}, },
"devDependencies": { "devDependencies": {
"bun-types": "^0.7.0" "bun-types": "^0.7.3"
}, },
"dependencies": { "dependencies": {
"@paperdave/logger": "^3.0.1", "@paperdave/logger": "^3.0.1",

View file

@ -17,8 +17,8 @@ dependencies:
devDependencies: devDependencies:
bun-types: bun-types:
specifier: ^0.7.0 specifier: ^0.7.3
version: 0.7.0 version: 0.7.3
packages: packages:
@ -150,8 +150,8 @@ packages:
engines: {node: '>=12'} engines: {node: '>=12'}
dev: false dev: false
/bun-types@0.7.0: /bun-types@0.7.3:
resolution: {integrity: sha512-jXFiYtwSUQtD/Y3LHRWeWNwhFaUYvcO96zI7y3gSPgTq+ozxXpuTGDxABLdIKmFc672Q7Qp/OgrfJFEjg4Mnkg==} resolution: {integrity: sha512-kssLD5mDLoawmLZFgQRRq0Wy+dca/os6TZ0MHWyFVoVAEwSrpAxmNCZ1K1GUelfhlDaL2FikRxeF9GkATdzXZg==}
dev: true dev: true
/busboy@1.6.0: /busboy@1.6.0:

View file

@ -1,6 +1,17 @@
import { defineCommand } from "../loaders/commands"; import { defineCommand } from "../loaders/commands.ts";
import { COMMIT_HASH } from "../constants.ts";
import { CommandContext } from "../structs/context/CommandContext.ts";
export default defineCommand({ export default defineCommand({
name: "version", name: "version",
run: (context) => {} options: [],
run: (context: CommandContext) => {
context.interaction.reply({
content: [
`[git-bun-discord-bot-${COMMIT_HASH}](<https://github.com/xHyroM/bun-discord-bot/tree/${COMMIT_HASH}>)`,
`[v${Bun.version}](https://github.com/oven-sh/bun/releases/tag/bun-v${Bun.version})`
].join("\n"),
ephemeral: true,
});
}
}); });

5
src/constants.ts Normal file
View file

@ -0,0 +1,5 @@
import { spawnSync } from "bun";
export const COMMIT_HASH = spawnSync({
cmd: [ "git", "log", "--pretty=format:%h", "-n", "1" ]
}).stdout.toString();

View file

@ -1 +1,2 @@
import "./ready.ts"; import "./ready.ts";
import "./interaction_create.ts";

View file

@ -0,0 +1,29 @@
import { Events } from "discord.js";
import { COMMANDS } from "../loaders/commands.ts";
import { defineListener } from "../loaders/listeners.ts";
import { CommandContext } from "../structs/context/CommandContext.ts";
import { BaseInteraction } from "discord.js";
import { ChatInputCommandInteraction } from "discord.js";
defineListener({
event: Events.InteractionCreate,
run: (interaction: BaseInteraction) => {
if (interaction.isChatInputCommand()) return handleCommand(interaction);
return;
}
})
function handleCommand(interaction: ChatInputCommandInteraction) {
const command = COMMANDS.get(interaction.commandName);
if (!command) {
interaction.reply({
content: "Hmm.. Invalid command :P",
ephemeral: true,
})
return;
}
command.run(new CommandContext(command, interaction));
}

View file

@ -1,3 +1,4 @@
import { info } from "@paperdave/logger";
import { defineListener } from "../loaders/listeners.ts"; import { defineListener } from "../loaders/listeners.ts";
import { Client, Events } from "discord.js"; import { Client, Events } from "discord.js";
@ -5,6 +6,6 @@ defineListener({
event: Events.ClientReady, event: Events.ClientReady,
once: true, once: true,
run: (client: Client) => { run: (client: Client) => {
console.log("heeh"); info(`Logged in as ${client.user.tag} (${client.user.id})`);
} }
}) })

View file

@ -1,9 +1,4 @@
interface Command { import type { Command } from "../structs/Command.ts";
name: string;
run: (
context
) => any;
}
export const COMMANDS: Map<string, Command> = new Map(); export const COMMANDS: Map<string, Command> = new Map();

View file

@ -1,15 +1,14 @@
import type { ClientEvents } from "discord.js"; import type { ClientEvents } from "discord.js";
import { Bubu } from "../structs/Client.ts";
interface Listener<E extends keyof ClientEvents> { import { Listener } from "../structs/Listener.ts";
event: E;
once?: boolean;
run: (
...args: ClientEvents[E]
) => any;
}
export const LISTENERS: Listener<keyof ClientEvents>[] = []; export const LISTENERS: Listener<keyof ClientEvents>[] = [];
export function defineListener<T extends Listener<keyof ClientEvents>>(listener: T) { export function defineListener<T extends Listener<keyof ClientEvents>>(listener: T) {
LISTENERS.push(listener); LISTENERS.push(listener);
Bubu[listener.once ? "once" : "on"](
listener.event as keyof ClientEvents,
listener.run.bind(this)
);
} }

17
src/structs/Command.ts Normal file
View file

@ -0,0 +1,17 @@
import { SharedNameAndDescription, SlashCommandAttachmentOption, SlashCommandBooleanOption, SlashCommandChannelOption, SlashCommandIntegerOption, SlashCommandMentionableOption, SlashCommandNumberOption, SlashCommandRoleOption, SlashCommandStringOption, SlashCommandUserOption } from "discord.js";
import { AutocompleteContext } from "./context/AutocompleteContext";
import { CommandContext } from "./context/CommandContext";
export type Option = SlashCommandAttachmentOption | SlashCommandBooleanOption | SlashCommandChannelOption | SlashCommandIntegerOption | SlashCommandMentionableOption | SlashCommandNumberOption | SlashCommandRoleOption | SlashCommandUserOption | SharedNameAndDescription | StringOption;
interface StringOption extends SlashCommandStringOption {
run: (option: Option, interaction: AutocompleteContext) => void;
}
export interface Command {
name: string;
options: Option[];
run: (
context: CommandContext
) => any;
}

10
src/structs/Listener.ts Normal file
View file

@ -0,0 +1,10 @@
import type { ClientEvents } from "discord.js";
export interface Listener<E extends keyof ClientEvents> {
event: E;
once?: boolean;
run: (
...args: ClientEvents[E]
) => any;
}

View file

@ -0,0 +1,23 @@
import { AutocompleteInteraction } from "discord.js";
export class AutocompleteContext {
public option: Option;
public interaction: AutocompleteInteraction;
public constructor(option: Option, interaction: AutocompleteInteraction) {
this.option = option;
this.interaction = interaction;
}
get user() {
return this.interaction.user;
}
get member() {
return this.interaction.member;
}
get options() {
return this.interaction.options;
}
}

View file

@ -0,0 +1,24 @@
import { ChatInputCommandInteraction } from "discord.js";
import type { Command } from "../Command.ts";
export class CommandContext {
public command: Command;
public interaction: ChatInputCommandInteraction;
public constructor(command: Command, interaction: ChatInputCommandInteraction) {
this.command = command;
this.interaction = interaction;
}
get user() {
return this.interaction.user;
}
get member() {
return this.interaction.member;
}
get resolved() {
return this.interaction.options.resolved;
}
}