From 67082454b7c31445626ea756f195e7982da0c2ca Mon Sep 17 00:00:00 2001 From: HerozDotExe Date: Thu, 19 Jun 2025 16:16:02 +0200 Subject: [PATCH] feat: extract client from main.ts for easy access and create settings store --- deno.json | 2 +- src/commands/text/selectChannel.ts | 19 +++++++++ src/commands/text/selectCharacter.ts | 60 ++++++++++++++++++++++++++++ src/main.ts | 27 +++---------- src/stores.ts | 8 +++- 5 files changed, 92 insertions(+), 24 deletions(-) create mode 100644 src/commands/text/selectChannel.ts create mode 100644 src/commands/text/selectCharacter.ts diff --git a/deno.json b/deno.json index fb2b391..7974c06 100644 --- a/deno.json +++ b/deno.json @@ -1,6 +1,6 @@ { "tasks": { - "dev": "deno run --watch --allow-env --allow-read=. --allow-net --env-file ./src/main.ts", + "dev": "deno run --watch --allow-env --allow-read=. --allow-net --env-file --unstable-temporal ./src/main.ts", "deployCommands": "deno run --env-file --allow-env --allow-net --allow-read=./src/ scripts/deployCommands.ts" } } diff --git a/src/commands/text/selectChannel.ts b/src/commands/text/selectChannel.ts new file mode 100644 index 0000000..08a4655 --- /dev/null +++ b/src/commands/text/selectChannel.ts @@ -0,0 +1,19 @@ +import { + CacheType, + ChatInputCommandInteraction, + InteractionContextType, + SlashCommandBuilder, +} from "npm:discord.js"; +import { Command } from "../../types.ts"; +import { settings } from "../../stores.ts"; + +export default { + data: new SlashCommandBuilder() + .setName("selectchannel") + .setDescription("Select the channel for futures chats.") + .setContexts(InteractionContextType.Guild), + async execute(interaction: ChatInputCommandInteraction) { + settings.textChannelId = interaction.channelId; + await interaction.reply(`Futures chats will be started in this channel.`); + }, +} as Command; diff --git a/src/commands/text/selectCharacter.ts b/src/commands/text/selectCharacter.ts new file mode 100644 index 0000000..26087ae --- /dev/null +++ b/src/commands/text/selectCharacter.ts @@ -0,0 +1,60 @@ +import { + CacheType, + ChatInputCommandInteraction, + EmbedBuilder, + InteractionContextType, + SlashCommandBuilder, +} from "npm:discord.js"; +import { Command } from "../../types.ts"; +import cai from "../../cai.ts"; + +export default { + data: new SlashCommandBuilder() + .setName("selectcharacter") + .setDescription("Select the channel for futures chats.") + .setContexts(InteractionContextType.Guild) + .addStringOption((option) => + option + .setName("character") + .setDescription("Character Id") + .setRequired(true) + ), + async execute(interaction: ChatInputCommandInteraction) { + await interaction.deferReply(); + const characterId = interaction.options.getString("character"); + const {character} = await cai.character.info(characterId); + console.log(`https://characterai.io/i/200/static/avatars/uploaded/${character.avatar_file_name}`) + const embed = new EmbedBuilder() + .setAuthor({ + name: "Selected Character", + }) + .setTitle(character.name) + .setURL( + `https://character.ai/chat/${character.external_id}` + ) + .setDescription( + character.description + ) + .addFields( + { + name: "Title", + value: character.title, + inline: true, + }, + { + name: "Greeting", + value: character.greeting, + inline: true, + } + ) + .setThumbnail( + `https://characterai.io/i/200/static/avatars/${character.avatar_file_name}` + ) + .setColor("#00b0f4") + .setFooter({ + text: `Created and last updated ${Temporal.PlainDateTime.from(character.updated).toLocaleString()} by ${character.participant__user__username} `, + }); + + await interaction.editReply({ embeds: [embed] }); + }, +} as Command; diff --git a/src/main.ts b/src/main.ts index 0bcd3e4..53ac6d1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,32 +1,15 @@ -import { - Client as _client, - ClientOptions, - Collection, - GatewayIntentBits, -} from "npm:discord.js"; const token = Deno.env.get("token"); import { Command, Event } from "./types.ts"; import { gatherPaths } from "./gatherer.ts"; import { exists } from "jsr:@std/fs/exists"; import cai from "./cai.ts"; import { commands } from "./stores.ts"; - -class Client extends _client { - commands: Collection; - constructor(options: ClientOptions) { - super(options); - this.commands = new Collection(); - } -} - -const client = new Client({ - intents: [GatewayIntentBits.Guilds, GatewayIntentBits.MessageContent], -}); +import { client } from "./stores.ts"; async function registerCommand(path: string) { const { default: command }: { default: Command } = await import(path); if ("data" in command && "execute" in command) { - commands[command.data.name] = command + commands[command.data.name] = command; } else { console.log( `[WARNING] The command at ${path} is missing a required "data" or "execute" property.` @@ -37,9 +20,9 @@ async function registerCommand(path: string) { async function registerEvent(path: string) { const { default: event }: { default: Event } = await import(path); if ("name" in event && "once" in event && "execute" in event) { - if(event.once) { - client.once(event.name, event.execute) - } else client.on(event.name, event.execute) + if (event.once) { + client.once(event.name, event.execute); + } else client.on(event.name, event.execute); } else { console.log( `[WARNING] The event at ${path} is missing a required "name", "once" or "execute" property.` diff --git a/src/stores.ts b/src/stores.ts index 94a1f6e..3f4fc0b 100644 --- a/src/stores.ts +++ b/src/stores.ts @@ -1,3 +1,4 @@ +import { GatewayIntentBits, Client } from "npm:discord.js"; import { Command } from "./types.ts"; // class Store { @@ -34,4 +35,9 @@ import { Command } from "./types.ts"; // } // } -export const commands: {[index:string]:Command} = {} \ No newline at end of file + +export const client = new Client({ + intents: [GatewayIntentBits.Guilds, GatewayIntentBits.MessageContent], +}); +export const commands: {[index:string]:Command} = {} +export const settings = {textChannelId: "", voiceChannelId: "", characterId: ""} \ No newline at end of file