diff --git a/src/client/client.ts b/src/client/client.ts index adb3475..92df126 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -2,7 +2,8 @@ import { verifyKey } from "discord-interactions"; import { Env } from "env"; import { Command } from "types"; import { DiscordResponse } from "./response"; -import { APIBaseInteraction, InteractionResponseType, InteractionType } from "discord-api-types/v10"; +import { APIBaseInteraction, InteractionResponseType, InteractionType, APIApplicationCommandInteraction } from "discord-api-types/v10"; +import { SlashCommandInteraction } from "client"; export class DiscordClient { @@ -17,21 +18,36 @@ export class DiscordClient { this.ctx = ctx; } - async handle(request: Request): Promise + async handle(request: Request): Promise { const {body, valid} = await this.isRequestValid(request); if(!valid) { - return new DiscordResponse("Invalid request signature", { status: 401 }); + return new Response("Invalid request signature", { status: 401 }); } const interaction = JSON.parse(body) as APIBaseInteraction + + switch(interaction.type) + { + case InteractionType.Ping: + { + return new DiscordResponse(InteractionResponseType.Pong); + }; + case InteractionType.ApplicationCommand: + { + const slashInteraction = new SlashCommandInteraction(interaction); + + const command = this.commands.find(command => command.data.name == slashInteraction.interaction.data.name); - if (interaction.type == InteractionType.Ping) { - return new DiscordResponse({ type: InteractionResponseType.Pong }); + if(command) + { + return command.execute(slashInteraction); + } + } } - return new DiscordResponse("Not Found", {status: 404}); + return new Response("Not Found", {status: 404}); } async isRequestValid(request: Request): Promise<{body: string, valid: boolean}> diff --git a/src/client/index.ts b/src/client/index.ts index 61b907e..af1f7de 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -1,2 +1,3 @@ export * from "./client" -export * from "./response" \ No newline at end of file +export * from "./response" +export * from "./interaction" \ No newline at end of file diff --git a/src/client/interaction.ts b/src/client/interaction.ts new file mode 100644 index 0000000..61debdb --- /dev/null +++ b/src/client/interaction.ts @@ -0,0 +1,23 @@ +import { APIApplicationCommandInteraction, APIBaseInteraction, InteractionResponseType, InteractionType } from "discord-api-types/v10"; +import { DiscordResponse } from "./response"; + +export class SlashCommandInteraction +{ + interaction: APIApplicationCommandInteraction; + + constructor(interaction: APIBaseInteraction) + { + if(interaction.type != InteractionType.ApplicationCommand) + { + throw new Error("Invalid interaction type. Expected ApplicationCommand") + } + + this.interaction = interaction as APIApplicationCommandInteraction; + } + + reply(data: any) + { + return new DiscordResponse(InteractionResponseType.ChannelMessageWithSource, data); + } + +} \ No newline at end of file diff --git a/src/client/response.ts b/src/client/response.ts index 04f06ef..1d9d535 100644 --- a/src/client/response.ts +++ b/src/client/response.ts @@ -1,6 +1,8 @@ +import { InteractionResponseType } from "discord-api-types/v10"; + export class DiscordResponse extends Response { - constructor(body?: any, init?: ResponseInit) { - const jsonBody = JSON.stringify(body); + constructor(type: InteractionResponseType, data?: any, init?: ResponseInit) { + const jsonBody = JSON.stringify({type, data}); init = init || { headers: { 'content-type': 'application/json;charset=UTF-8', diff --git a/src/commands/help.ts b/src/commands/help.ts index 4ce4bf4..19bd221 100644 --- a/src/commands/help.ts +++ b/src/commands/help.ts @@ -1,11 +1,21 @@ import { Command } from "types"; -import {SlashCommandBuilder} from "@discordjs/builders"; +import {EmbedBuilder, SlashCommandBuilder} from "@discordjs/builders"; +import { DiscordResponse } from "client"; +import { InteractionResponseType } from "discord-api-types/v10"; const command = { data: new SlashCommandBuilder() .setName("help") - .setDescription("help me!") + .setDescription("help me!"), + execute(interaction) { + + const embed = new EmbedBuilder() + .setTitle("L skillissue") + .setDescription("git good lmao"); + + return interaction.reply({embeds: [embed]}); + }, } satisfies Command; export default command; \ No newline at end of file diff --git a/src/types.d.ts b/src/types.d.ts index d43773a..40e93b5 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -1,5 +1,7 @@ import {SlashCommandBuilder} from "@discordjs/builders"; +import { DiscordResponse, SlashCommandInteraction } from "client"; declare type Command = { - data: SlashCommandBuilder + data: SlashCommandBuilder, + execute(interaction: SlashCommandInteraction): DiscordResponse }; \ No newline at end of file