refactor: reorganize project structure and improve user command handling

This commit is contained in:
grngxd 2025-07-31 19:25:31 +01:00
parent 5cfcb3ba0c
commit 49d6b51de6
7 changed files with 64 additions and 26 deletions

7
cmd/index.ts Normal file
View file

@ -0,0 +1,7 @@
import register from "./register";
import user from "./user";
export default [
user,
register
]

18
cmd/register.ts Normal file
View file

@ -0,0 +1,18 @@
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
import { db } from "../db/db";
export const data = new SlashCommandBuilder()
.setName("register")
.setDescription("create your stereo account");
export const execute = async (interaction: ChatInputCommandInteraction) => {
const existingUser = await db.get<{ id: string }>`SELECT id FROM users WHERE id = ${interaction.user.id}`;
if (existingUser) {
await interaction.reply({ content: "You already have a stereo account.", ephemeral: true });
return;
}
await interaction.reply({ content: "Your stereo account has been created!", ephemeral: true });
}
export default [data, execute] as const;

View file

@ -1,16 +1,26 @@
// commands/overview.ts // commands/overview.ts
import { ChatInputCommandInteraction, EmbedBuilder, MessageFlags, SlashCommandBuilder } from "discord.js"; import { ChatInputCommandInteraction, EmbedBuilder, MessageFlags, SlashCommandBuilder } from "discord.js";
import { db } from "../db"; import { db } from "../db/db";
import { formatSize } from "../lib"; import { formatSize } from "../lib/files";
import { StereoFile } from "../types"; import { StereoFile } from "../types/files";
export const data = new SlashCommandBuilder() export const data = new SlashCommandBuilder()
.setName("user") .setName("user")
.addUserOption(option => option.setName("user").setDescription("user to look up").setRequired(false)) .addUserOption(option => option.setName("user").setDescription("user to look up").setRequired(false))
.setDescription("get information about a user (or yourself) on stereo"); .setDescription("get information about a user (or yourself) on stereo");
export const execute = async (interaction: ChatInputCommandInteraction) => { export const execute = async (interaction: ChatInputCommandInteraction) => {
const user = interaction.options.getUser("user") || interaction.user; const user = interaction.options.getUser("user") || interaction.user;
if (user.id === interaction.client.user?.id) {
await interaction.reply({ content: "hey! stop that!!!!", flags: MessageFlags.Ephemeral });
return;
}
if (user.bot) {
await interaction.reply({ content: "bots can't have stereo accounts...", flags: MessageFlags.Ephemeral });
return;
}
if (!user) { if (!user) {
await interaction.reply({ content: "couldn't find user", flags: MessageFlags.Ephemeral }); await interaction.reply({ content: "couldn't find user", flags: MessageFlags.Ephemeral });
return; return;
@ -18,6 +28,11 @@ export const execute = async (interaction: ChatInputCommandInteraction) => {
const id = await db.get<{ id: string }>`SELECT id FROM users WHERE id = ${user.id}`; const id = await db.get<{ id: string }>`SELECT id FROM users WHERE id = ${user.id}`;
if (!id) { if (!id) {
if (user.id === interaction.user.id) {
await interaction.reply({ content: "you don't have a stereo account yet, use the `/register` command to make one", flags: MessageFlags.Ephemeral });
return;
}
await interaction.reply({ content: "this user doesn't have a stereo account", flags: MessageFlags.Ephemeral }); await interaction.reply({ content: "this user doesn't have a stereo account", flags: MessageFlags.Ephemeral });
return; return;
} }

View file

View file

@ -1,22 +1,23 @@
import { ActivityType, Client, Events, GatewayIntentBits, REST, Routes } from "discord.js"; import { ActivityType, Client, Events, GatewayIntentBits, REST, Routes } from "discord.js";
import user from "./cmd/user"; import commands from "./cmd";
import { db } from "./db"; import { db } from "./db/db";
import { StereoFile } from "./types"; import { StereoFile } from "./types/files";
const client = new Client({ const client = new Client({
intents: [ intents: [
GatewayIntentBits.Guilds, GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent, GatewayIntentBits.MessageContent,
] ]
}); });
const rest = new REST({ version: "10" }).setToken(process.env.TOKEN);
const rest = new REST({ version: "10" })
.setToken(process.env.TOKEN);
client.once(Events.ClientReady, async (c) => { client.once(Events.ClientReady, async (c) => {
await rest.put( await rest.put(
Routes.applicationCommands(process.env.CLIENT_ID), Routes.applicationCommands(process.env.CLIENT_ID),
{ body: commands.map(([data]) => data) } { body: commands.map(([data, _]) => data) }
); );
const files = (await db.all<StereoFile[]>`SELECT * FROM files`).length const files = (await db.all<StereoFile[]>`SELECT * FROM files`).length
@ -28,20 +29,17 @@ client.once(Events.ClientReady, async (c) => {
console.log(c.user.tag); console.log(c.user.tag);
}); });
const commands = [
user
]
client.on(Events.InteractionCreate, async interaction => { client.on(Events.InteractionCreate, async interaction => {
if (!interaction.isChatInputCommand()) return; if (!interaction.isChatInputCommand()) return;
const cmd = commands.find(([data]) => data.name === interaction.commandName); const cmd = commands.find(([data]) => data.name === interaction.commandName);
if (!cmd) return; if (!cmd) return;
try {
await cmd[1](interaction); try {
} catch (err) { await cmd[1](interaction);
console.error(err); } catch (err) {
await interaction.reply({ content: "there was an error executing this command", ephemeral: true }); console.error(err);
} await interaction.reply({ content: "there was an error executing this command", ephemeral: true });
}
}); });
client.login(process.env.TOKEN).catch((err) => { client.login(process.env.TOKEN).catch((err) => {