all commands and buttons are working

This commit is contained in:
VinceC
2024-11-28 04:47:58 -06:00
parent 92c1fa3a9e
commit 26a5edeb4f
7 changed files with 530 additions and 246 deletions

View File

@@ -1,9 +1,13 @@
const { ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js');
const EmbedBuilders = require('../utils/EmbedBuilders');
class CommandHandler {
constructor(playerService, supabase, logger, serverRegistrationService) {
constructor(playerService, supabase, logger, serverRegistrationService, subscriptionCommands) {
this.playerService = playerService;
this.supabase = supabase;
this.logger = logger;
this.serverRegistrationService = serverRegistrationService;
this.subscriptionCommands = subscriptionCommands;
}
async handleCommand(interaction) {
@@ -21,50 +25,66 @@ class CommandHandler {
case 'matchhistory':
await this.handleMatchHistory(interaction);
break;
case 'subscribe':
await this.subscriptionCommands.handleSubscribe(interaction);
break;
case 'unsubscribe':
await this.subscriptionCommands.handleUnsubscribe(interaction);
break;
case 'list_subscriptions':
await this.subscriptionCommands.handleListSubscriptions(interaction);
break;
default:
await interaction.editReply({ content: 'Unknown command', ephemeral: true });
await interaction.editReply({
content: '❌ Unknown command',
ephemeral: true
});
}
} catch (error) {
// Only log the error, let Bot class handle the response
this.logger.error('Command handling error:', {
command: interaction.commandName,
error: error.message,
stack: error.stack
});
throw error; // Re-throw to let Bot handle it
try {
await interaction.editReply({
content: '❌ An error occurred while processing your command.',
ephemeral: true
});
} catch (followUpError) {
this.logger.error('Failed to send error response:', {
error: followUpError.message,
originalError: error.message
});
}
}
}
async handleRegisterServer(interaction) {
if (!interaction.deferred) {
this.logger.warn('Interaction not deferred, cannot proceed', {
guildId: interaction.guildId
});
return;
}
// Get the server details first
const guildId = interaction.guildId;
const serverName = interaction.guild.name;
this.logger.debug('Starting server registration', {
guildId,
serverName,
timestamp: new Date().toISOString()
});
try {
// Log before database operation
this.logger.debug('Calling ServerRegistrationService.registerServer', {
// Check for admin permissions
if (!interaction.member.permissions.has('ADMINISTRATOR')) {
await interaction.editReply({
content: '❌ You need administrator permissions to register this server.',
ephemeral: true
});
return;
}
const guildId = interaction.guildId;
const serverName = interaction.guild.name;
this.logger.debug('Starting server registration', {
guildId,
serverName,
timestamp: new Date().toISOString()
});
// Attempt the database operation first
// Attempt the database operation
const result = await this.serverRegistrationService.registerServer(guildId, serverName);
// Log the result immediately
// Log the result
this.logger.debug('Server registration result received', {
status: result.status,
serverId: result.server?.id,
@@ -72,74 +92,146 @@ class CommandHandler {
timestamp: new Date().toISOString()
});
// Only after successful database operation, send the response
try {
const message = result.status === 'exists'
? 'This server is already registered!'
: 'Server successfully registered! You can now use subscription commands.';
await interaction.editReply({
content: message,
ephemeral: true
});
// Log the successful operation
this.logger.info('Server registration completed', {
status: result.status,
guildId,
serverId: result.server.id,
timestamp: new Date().toISOString()
});
} catch (replyError) {
// Log that we couldn't send the response but the registration was successful
this.logger.warn('Could not send response, but server registration was successful', {
error: replyError.message,
guildId,
serverId: result.server.id,
timestamp: new Date().toISOString()
});
// Prepare response message based on status
let message;
switch (result.status) {
case 'created':
message = 'Server successfully registered! You can now use subscription commands.';
break;
case 'updated':
message = '✅ Server information has been updated!';
break;
case 'exists':
message = '✅ This server is already registered and ready to use subscription commands!';
break;
default:
message = '❌ An unexpected error occurred during registration.';
}
return result;
await interaction.editReply({
content: message,
ephemeral: true
});
// Log the successful operation
this.logger.info('Server registration completed', {
status: result.status,
guildId,
serverId: result.server.id,
timestamp: new Date().toISOString()
});
} catch (error) {
// Log the error but let Bot.js handle the error response
this.logger.error('Failed to register server:', {
this.logger.error('Error in handleRegisterServer:', {
error: error.message,
stack: error.stack,
guildId,
serverName,
guildId: interaction.guildId,
serverName: interaction.guild?.name
});
// Send error message to user
const errorMessage = error.message === 'Invalid guildId provided' || error.message === 'Invalid serverName provided'
? '❌ Invalid server information provided.'
: '❌ An error occurred while registering the server. Please try again later.';
await interaction.editReply({
content: errorMessage,
ephemeral: true
});
throw error;
}
}
async handleFindUser(interaction) {
try {
const username = interaction.options.getString('username');
const gameFilter = interaction.options.getString('game');
const userData = await this.playerService.findUserByUsername(username);
if (!userData || !userData.success) {
await interaction.editReply({
content: '❌ User not found or an error occurred while fetching data.',
ephemeral: true
});
return;
}
const playerData = typeof userData.player_data === 'string'
? JSON.parse(userData.player_data)
: userData.player_data;
const embed = EmbedBuilders.createUserEmbed(playerData, gameFilter, this.playerService);
const row = this.createActionRow(playerData.username);
await interaction.editReply({
embeds: [embed],
components: [row],
ephemeral: true
});
} catch (error) {
this.logger.error('Error in handleFindUser:', {
error: error.message,
username: interaction.options.getString('username'),
timestamp: new Date().toISOString()
});
throw error;
}
}
async handleButton(interaction) {
const [action, ...params] = interaction.customId.split(':');
switch (action) {
case 'refresh':
await this.handleFindUser(interaction, params[0]);
break;
default:
async handleMatchHistory(interaction) {
try {
const username = interaction.options.getString('username');
const gameFilter = interaction.options.getString('game');
const userData = await this.playerService.findUserByUsername(username);
if (!userData || !userData.success) {
await interaction.editReply({
content: 'Unknown button interaction',
content: '❌ User not found or an error occurred while fetching data.',
ephemeral: true
});
return;
}
const playerData = typeof userData.player_data === 'string'
? JSON.parse(userData.player_data)
: userData.player_data;
// Extract matches from player data
const matches = Object.values(playerData.matches || {})
.filter(match => !gameFilter || match.game_name.toLowerCase() === gameFilter.toLowerCase())
.sort((a, b) => new Date(b.start_time) - new Date(a.start_time))
.slice(0, 10);
const embed = EmbedBuilders.createMatchHistoryEmbed(playerData, matches);
const row = EmbedBuilders.createActionRow(playerData.username, this.playerService);
await interaction.editReply({
embeds: [embed],
components: [row],
ephemeral: true
});
} catch (error) {
this.logger.error('Error in handleMatchHistory:', {
error: error.message,
username: interaction.options.getString('username'),
timestamp: new Date().toISOString()
});
throw error;
}
}
// Helper methods for creating embeds and action rows remain unchanged
createUserEmbed(playerData, gameFilter) {
// ... (keep existing implementation)
}
createMatchHistoryEmbed(playerData, matches) {
// ... (keep existing implementation)
}
createActionRow(username) {
// ... (keep existing implementation)
return new ActionRowBuilder().addComponents(
new ButtonBuilder()
.setLabel('🔵 View Profile')
.setStyle(ButtonStyle.Link)
.setURL(`https://www.vrbattles.gg/profile/${username}`),
new ButtonBuilder()
.setLabel('🟡 Join Main Discord')
.setStyle(ButtonStyle.Link)
.setURL('https://discord.gg/j3DKVATPGQ')
);
}
}