feat: message command context, message cmd handling

This commit is contained in:
Jozef Steinhübl 2023-08-24 07:21:01 +02:00
parent 22fbcf4bf7
commit c889e8be8a
5 changed files with 96 additions and 4 deletions

View file

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

View file

@ -3,3 +3,7 @@ import { spawnSync } from "bun";
export const COMMIT_HASH = spawnSync({
cmd: [ "git", "log", "--pretty=format:%h", "-n", "1" ]
}).stdout.toString();
export const PRODUCTION = process.env.NODE_ENV === "production";
export const MESSAGE_PREFIX = PRODUCTION ? "b" : "<>";

View file

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

View file

@ -0,0 +1,32 @@
import { Events, Message } from "discord.js";
import { defineListener } from "../loaders/listeners.ts";
import { MESSAGE_PREFIX } from "../constants.ts";
import { COMMANDS } from "../loaders/commands.ts";
import { MessageCommandContext } from "../structs/context/CommandContext.ts";
defineListener({
event: Events.MessageCreate,
run: async(message: Message) => {
if (!message.content.toLowerCase().startsWith(MESSAGE_PREFIX))
return;
const [commandName, ...args] = message.content
.slice(MESSAGE_PREFIX.length)
.trim()
.split(/ +/g);
if (commandName.length === 0) return;
const command = COMMANDS.get(commandName);
if (!command) return;
const context = new MessageCommandContext(command, message, args);
await Promise.resolve(command.run(context))
.catch(async error => {
context.reply({
content: `Something went wrong... ${error.message} (${error.code})`
});
});
}
});

View file

@ -1,7 +1,18 @@
import { ChatInputCommandInteraction } from "discord.js";
import { ChatInputCommandInteraction, InteractionReplyOptions, Message, MessageCreateOptions, MessagePayload, InteractionResponse, Channel, User, GuildMember, APIInteractionGuildMember } from "discord.js";
import type { Command } from "../Command.ts";
export class CommandContext {
export interface CommandContext<T extends boolean> {
command: Command;
isInteraction: T;
user: User;
member: GuildMember | APIInteractionGuildMember;
channel: Channel;
reply(options: string | MessagePayload | (T extends true ? InteractionReplyOptions : MessageCreateOptions)): (T extends true ? Promise<Message | InteractionResponse> : Promise<Message>);
}
export class InteractionCommandContext implements CommandContext<true> {
public command: Command;
public interaction: ChatInputCommandInteraction;
@ -10,6 +21,10 @@ export class CommandContext {
this.interaction = interaction;
}
get isInteraction(): true {
return true;
}
get user() {
return this.interaction.user;
}
@ -18,7 +33,47 @@ export class CommandContext {
return this.interaction.member;
}
get channel() {
return this.interaction.channel;
}
get resolved() {
return this.interaction.options.resolved;
}
public reply(options: string | MessagePayload | InteractionReplyOptions): Promise<Message | InteractionResponse> {
return this.interaction.reply(options);
}
}
export class MessageCommandContext implements CommandContext<false> {
public command: Command;
public message: Message;
public constructor(command: Command, message: Message, args: string[]) {
this.command = command;
this.message = message;
// change args structure to application commands like
}
get isInteraction(): false {
return false;
}
get user() {
return this.message.author;
}
get member() {
return this.message.member;
}
get channel() {
return this.message.channel;
}
public reply(options: string | MessagePayload | MessageCreateOptions): Promise<Message<boolean>> {
return this.channel.send(options);
}
}