feat: extract client from main.ts for easy access and create settings store

This commit is contained in:
HerozDotExe 2025-06-19 16:16:02 +02:00
parent efac1632d1
commit 67082454b7
5 changed files with 92 additions and 24 deletions

View file

@ -1,6 +1,6 @@
{ {
"tasks": { "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" "deployCommands": "deno run --env-file --allow-env --allow-net --allow-read=./src/ scripts/deployCommands.ts"
} }
} }

View file

@ -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<CacheType>) {
settings.textChannelId = interaction.channelId;
await interaction.reply(`Futures chats will be started in this channel.`);
},
} as Command;

View file

@ -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<CacheType>) {
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;

View file

@ -1,32 +1,15 @@
import {
Client as _client,
ClientOptions,
Collection,
GatewayIntentBits,
} from "npm:discord.js";
const token = Deno.env.get("token"); const token = Deno.env.get("token");
import { Command, Event } from "./types.ts"; import { Command, Event } from "./types.ts";
import { gatherPaths } from "./gatherer.ts"; import { gatherPaths } from "./gatherer.ts";
import { exists } from "jsr:@std/fs/exists"; import { exists } from "jsr:@std/fs/exists";
import cai from "./cai.ts"; import cai from "./cai.ts";
import { commands } from "./stores.ts"; import { commands } from "./stores.ts";
import { client } from "./stores.ts";
class Client extends _client {
commands: Collection<string, Command>;
constructor(options: ClientOptions) {
super(options);
this.commands = new Collection();
}
}
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.MessageContent],
});
async function registerCommand(path: string) { async function registerCommand(path: string) {
const { default: command }: { default: Command } = await import(path); const { default: command }: { default: Command } = await import(path);
if ("data" in command && "execute" in command) { if ("data" in command && "execute" in command) {
commands[command.data.name] = command commands[command.data.name] = command;
} else { } else {
console.log( console.log(
`[WARNING] The command at ${path} is missing a required "data" or "execute" property.` `[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) { async function registerEvent(path: string) {
const { default: event }: { default: Event } = await import(path); const { default: event }: { default: Event } = await import(path);
if ("name" in event && "once" in event && "execute" in event) { if ("name" in event && "once" in event && "execute" in event) {
if(event.once) { if (event.once) {
client.once(event.name, event.execute) client.once(event.name, event.execute);
} else client.on(event.name, event.execute) } else client.on(event.name, event.execute);
} else { } else {
console.log( console.log(
`[WARNING] The event at ${path} is missing a required "name", "once" or "execute" property.` `[WARNING] The event at ${path} is missing a required "name", "once" or "execute" property.`

View file

@ -1,3 +1,4 @@
import { GatewayIntentBits, Client } from "npm:discord.js";
import { Command } from "./types.ts"; import { Command } from "./types.ts";
// class Store<T> { // class Store<T> {
@ -34,4 +35,9 @@ import { Command } from "./types.ts";
// } // }
// } // }
export const commands: {[index:string]:Command} = {}
export const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.MessageContent],
});
export const commands: {[index:string]:Command} = {}
export const settings = {textChannelId: "", voiceChannelId: "", characterId: ""}