refactor: Refactor interaction handling and event management
- Updated interactionCreate event to improve error handling and logging. - Enhanced ready event to ensure client user is available before proceeding. - Refactored voiceStateUpdate event for better clarity and error handling. - Adjusted index.ts to improve client initialization and command/event loading. - Improved Shoukaku event handling and initialization in ShoukakuEvents.ts. - Enhanced logger utility for better message formatting. - Updated TypeScript configuration for better compatibility and strictness. - Created a new botClient type definition for improved type safety.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { REST, Routes, APIApplicationCommand } from 'discord.js';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import logger from './src/utils/logger'; // Use default import now
|
||||
import dotenv from 'dotenv';
|
||||
import { REST, Routes, APIApplicationCommand } from "discord.js";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import logger from "./src/utils/logger"; // Use default import now
|
||||
import dotenv from "dotenv";
|
||||
|
||||
// --- Setup ---
|
||||
dotenv.config(); // Load .env variables
|
||||
@@ -16,83 +16,87 @@ const clientId = process.env.CLIENT_ID;
|
||||
const token = process.env.DISCORD_TOKEN;
|
||||
|
||||
if (!clientId || !token) {
|
||||
logger.error('Missing CLIENT_ID or DISCORD_TOKEN in .env file for command deployment!');
|
||||
process.exit(1);
|
||||
logger.error("Missing CLIENT_ID or DISCORD_TOKEN in .env file for command deployment!");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const commands: Omit<APIApplicationCommand, 'id' | 'application_id' | 'version'>[] = []; // Type the commands array more accurately
|
||||
const commands: Omit<APIApplicationCommand, "id" | "application_id" | "version">[] = []; // Type the commands array more accurately
|
||||
// Grab all the command files from the commands directory
|
||||
const commandsPath = path.join(__dirname, 'src', 'commands');
|
||||
const commandsPath = path.join(__dirname, "src", "commands");
|
||||
// Read .ts files now
|
||||
const commandFiles = fs.readdirSync(commandsPath).filter((file: string) => file.endsWith('.ts')); // Add string type
|
||||
const commandFiles = fs.readdirSync(commandsPath).filter((file: string) => file.endsWith(".ts")); // Add string type
|
||||
|
||||
// Grab the SlashCommandBuilder#toJSON() output of each command's data for deployment
|
||||
logger.info(`Started loading ${commandFiles.length} application (/) commands for deployment.`);
|
||||
|
||||
const loadCommandsForDeployment = async () => {
|
||||
for (const file of commandFiles) {
|
||||
const filePath = path.join(commandsPath, file);
|
||||
try {
|
||||
// Use dynamic import
|
||||
const commandModule = await import(filePath);
|
||||
// Assuming commands export default or have a 'default' property
|
||||
const command = commandModule.default || commandModule;
|
||||
for (const file of commandFiles) {
|
||||
const filePath = path.join(commandsPath, file);
|
||||
try {
|
||||
// Use dynamic import
|
||||
const commandModule = await import(filePath);
|
||||
// Assuming commands export default or have a 'default' property
|
||||
const command = commandModule.default || commandModule;
|
||||
|
||||
if (command && typeof command === 'object' && 'data' in command && typeof command.data.toJSON === 'function') {
|
||||
// We push the JSON representation which matches the API structure
|
||||
commands.push(command.data.toJSON());
|
||||
logger.info(`Loaded command for deployment: ${command.data.name}`);
|
||||
} else {
|
||||
logger.warn(`[WARNING] The command at ${filePath} is missing a required "data" property with a "toJSON" method.`);
|
||||
}
|
||||
} catch (error: unknown) { // Type error as unknown
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
logger.error(`Error loading command at ${filePath} for deployment: ${errorMessage}`, error);
|
||||
}
|
||||
if (
|
||||
command &&
|
||||
typeof command === "object" &&
|
||||
"data" in command &&
|
||||
typeof command.data.toJSON === "function"
|
||||
) {
|
||||
// We push the JSON representation which matches the API structure
|
||||
commands.push(command.data.toJSON());
|
||||
logger.info(`Loaded command for deployment: ${command.data.name}`);
|
||||
} else {
|
||||
logger.warn(
|
||||
`[WARNING] The command at ${filePath} is missing a required "data" property with a "toJSON" method.`,
|
||||
);
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
// Type error as unknown
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
logger.error(`Error loading command at ${filePath} for deployment: ${errorMessage}`, error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Construct and prepare an instance of the REST module
|
||||
const rest = new REST({ version: '10' }).setToken(token);
|
||||
const rest = new REST({ version: "10" }).setToken(token);
|
||||
|
||||
// Define the deployment function
|
||||
const deployCommands = async () => {
|
||||
try {
|
||||
await loadCommandsForDeployment(); // Wait for commands to be loaded
|
||||
try {
|
||||
await loadCommandsForDeployment(); // Wait for commands to be loaded
|
||||
|
||||
if (commands.length === 0) {
|
||||
logger.warn('No commands loaded for deployment. Exiting.');
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info(`Started refreshing ${commands.length} application (/) commands.`);
|
||||
|
||||
// The put method is used to fully refresh all commands
|
||||
const guildId = process.env.GUILD_ID;
|
||||
let data: any; // Type appropriately if possible, depends on discord.js version
|
||||
|
||||
if (guildId) {
|
||||
// Deploying to a specific guild (faster for testing)
|
||||
logger.info(`Deploying commands to guild: ${guildId}`);
|
||||
data = await rest.put(
|
||||
Routes.applicationGuildCommands(clientId, guildId),
|
||||
{ body: commands },
|
||||
);
|
||||
logger.info(`Successfully reloaded ${data.length} application (/) commands in guild ${guildId}.`);
|
||||
} else {
|
||||
// Deploying globally (can take up to an hour)
|
||||
logger.info('Deploying commands globally...');
|
||||
data = await rest.put(
|
||||
Routes.applicationCommands(clientId),
|
||||
{ body: commands },
|
||||
);
|
||||
logger.info(`Successfully reloaded ${data.length} global application (/) commands.`);
|
||||
}
|
||||
|
||||
} catch (error: unknown) { // Type error as unknown
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
logger.error(`Failed during command deployment: ${errorMessage}`, error);
|
||||
if (commands.length === 0) {
|
||||
logger.warn("No commands loaded for deployment. Exiting.");
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info(`Started refreshing ${commands.length} application (/) commands.`);
|
||||
|
||||
// The put method is used to fully refresh all commands
|
||||
const guildId = process.env.GUILD_ID;
|
||||
let data: any; // Type appropriately if possible, depends on discord.js version
|
||||
|
||||
if (guildId) {
|
||||
// Deploying to a specific guild (faster for testing)
|
||||
logger.info(`Deploying commands to guild: ${guildId}`);
|
||||
data = await rest.put(Routes.applicationGuildCommands(clientId, guildId), { body: commands });
|
||||
logger.info(
|
||||
`Successfully reloaded ${data.length} application (/) commands in guild ${guildId}.`,
|
||||
);
|
||||
} else {
|
||||
// Deploying globally (can take up to an hour)
|
||||
logger.info("Deploying commands globally...");
|
||||
data = await rest.put(Routes.applicationCommands(clientId), { body: commands });
|
||||
logger.info(`Successfully reloaded ${data.length} global application (/) commands.`);
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
// Type error as unknown
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
logger.error(`Failed during command deployment: ${errorMessage}`, error);
|
||||
}
|
||||
};
|
||||
|
||||
// Execute the deployment
|
||||
|
||||
Reference in New Issue
Block a user