feat: refactor admin panel interactions to use Discord.js 14.22.1 API with enhanced ownership checks and updated UI components
This commit is contained in:
@@ -1,67 +1,59 @@
|
||||
import logger from "../../core/lib/logger";
|
||||
import { ButtonInteraction, MessageFlags, PermissionFlagsBits } from 'discord.js';
|
||||
import { ButtonInteraction, MessageFlags, ContainerBuilder, TextDisplayBuilder, SectionBuilder, ButtonBuilder, ButtonStyle } from 'discord.js';
|
||||
import { aiService } from '../../core/services/AIService';
|
||||
|
||||
const OWNER_ID = '327207082203938818'; // Solo el dueño puede usar este panel
|
||||
|
||||
export default {
|
||||
customId: 'ai_clear_cache',
|
||||
run: async (interaction: ButtonInteraction) => {
|
||||
// Verificar permisos de administrador
|
||||
if (!interaction.memberPermissions?.has(PermissionFlagsBits.Administrator)) {
|
||||
return interaction.reply({
|
||||
content: '❌ No tienes permisos de administrador para usar este botón.',
|
||||
flags: MessageFlags.Ephemeral
|
||||
// Verificar que sea el dueño del bot (CRÍTICO)
|
||||
if (interaction.user.id !== OWNER_ID) {
|
||||
return interaction.reply({
|
||||
content: '❌ Solo el dueño del bot puede usar este panel administrativo.',
|
||||
flags: MessageFlags.Ephemeral
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await interaction.deferUpdate();
|
||||
|
||||
// Limpiar cache de conversaciones (simular limpieza)
|
||||
// Limpiar cache de conversaciones
|
||||
const stats = aiService.getStats();
|
||||
const conversationsCleared = stats.activeConversations;
|
||||
|
||||
// Aquí podrías agregar lógica real para limpiar el cache
|
||||
// Por ejemplo: aiService.clearConversations();
|
||||
|
||||
// @ts-ignore
|
||||
const successPanel = {
|
||||
type: 17,
|
||||
accent_color: 0x00FF00,
|
||||
components: [
|
||||
{
|
||||
type: 10,
|
||||
content: '## 🧹 Cache Limpiado Exitosamente'
|
||||
},
|
||||
{
|
||||
type: 10,
|
||||
content: `-# Se han limpiado ${conversationsCleared} conversaciones activas.`
|
||||
},
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
{
|
||||
type: 10,
|
||||
content: `✅ **Estado:** Cache limpiado\n🔄 **Conversaciones eliminadas:** ${conversationsCleared}\n⏰ **Timestamp:** ${new Date().toISOString().replace('T', ' ').split('.')[0]} UTC\n👤 **Administrador:** ${interaction.user.username}`
|
||||
},
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
{
|
||||
type: 9,
|
||||
components: [
|
||||
{ type: 10, content: "🔙 Volver al panel principal de administración" }
|
||||
],
|
||||
accessory: {
|
||||
type: 2,
|
||||
style: 2,
|
||||
emoji: "🔙",
|
||||
label: 'Volver al Panel',
|
||||
custom_id: 'ai_refresh_stats'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
// Aquí iría la lógica real de limpieza:
|
||||
// aiService.clearAllConversations();
|
||||
|
||||
// Crear container de éxito usando la API real
|
||||
const successContainer = new ContainerBuilder()
|
||||
.addTextDisplayComponents(
|
||||
new TextDisplayBuilder()
|
||||
.setContent('## 🧹 Cache Limpiado Exitosamente\n-# Se han limpiado ' + conversationsCleared + ' conversaciones activas.\n\n✅ **Estado:** Cache limpiado\n🔄 **Conversaciones eliminadas:** ' + conversationsCleared + '\n⏰ **Timestamp:** ' + new Date().toISOString().replace('T', ' ').split('.')[0] + ' UTC\n👤 **Dueño:** ' + interaction.user.username)
|
||||
)
|
||||
.addSectionComponents(
|
||||
new SectionBuilder()
|
||||
.addTextDisplayComponents(
|
||||
new TextDisplayBuilder()
|
||||
.setContent("🔙 Volver al panel principal de administración")
|
||||
)
|
||||
.setButtonAccessory(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('ai_refresh_stats')
|
||||
.setLabel('Volver al Panel')
|
||||
.setEmoji('🔙')
|
||||
.setStyle(ButtonStyle.Primary)
|
||||
)
|
||||
);
|
||||
|
||||
await interaction.message.edit({
|
||||
components: [successContainer],
|
||||
flags: MessageFlags.IsComponentsV2
|
||||
});
|
||||
logger.info(`Cache de IA limpiado por el dueño ${interaction.user.username} (${interaction.user.id})`);
|
||||
|
||||
await interaction.message.edit({ components: [successPanel] });
|
||||
logger.info(`Cache de IA limpiado por ${interaction.user.username} (${interaction.user.id})`);
|
||||
|
||||
} catch (error) {
|
||||
//@ts-ignore
|
||||
logger.error('Error limpiando cache de IA:', error);
|
||||
if (!interaction.deferred && !interaction.replied) {
|
||||
await interaction.reply({
|
||||
|
||||
@@ -1,38 +1,30 @@
|
||||
import logger from "../../core/lib/logger";
|
||||
import { ButtonInteraction, MessageFlags, PermissionFlagsBits } from 'discord.js';
|
||||
import { ButtonInteraction, MessageFlags, ContainerBuilder, TextDisplayBuilder, SectionBuilder, ButtonBuilder, ButtonStyle } from 'discord.js';
|
||||
|
||||
const OWNER_ID = '327207082203938818'; // Solo el dueño puede usar este panel
|
||||
|
||||
export default {
|
||||
customId: 'ai_config',
|
||||
run: async (interaction: ButtonInteraction) => {
|
||||
// Verificar permisos de administrador
|
||||
if (!interaction.memberPermissions?.has(PermissionFlagsBits.Administrator)) {
|
||||
return interaction.reply({
|
||||
content: '❌ No tienes permisos de administrador para usar este botón.',
|
||||
flags: MessageFlags.Ephemeral
|
||||
// Verificar que sea el dueño del bot (CRÍTICO)
|
||||
if (interaction.user.id !== OWNER_ID) {
|
||||
return interaction.reply({
|
||||
content: '❌ Solo el dueño del bot puede usar este panel administrativo.',
|
||||
flags: MessageFlags.Ephemeral
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await interaction.deferUpdate();
|
||||
|
||||
// Panel de configuración detallada
|
||||
// @ts-ignore
|
||||
const configPanel = {
|
||||
type: 17,
|
||||
accent_color: 0x3498DB,
|
||||
components: [
|
||||
{
|
||||
type: 10,
|
||||
content: '## ⚙️ Configuración del Sistema de IA'
|
||||
},
|
||||
{
|
||||
type: 10,
|
||||
content: '-# Ajustes avanzados y configuración del servicio Gemini-chan.'
|
||||
},
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
{
|
||||
type: 10,
|
||||
content: `## 🔧 Configuración Actual
|
||||
// Panel de configuración usando la API real de Discord.js 14.22.1
|
||||
const configContainer = new ContainerBuilder()
|
||||
.addTextDisplayComponents(
|
||||
new TextDisplayBuilder()
|
||||
.setContent(`## ⚙️ Configuración del Sistema de IA
|
||||
-# Ajustes avanzados y configuración del servicio Gemini-chan.
|
||||
|
||||
## 🔧 Configuración Actual
|
||||
\`\`\`yaml
|
||||
# Límites de Rate Limiting
|
||||
rate_limit_max: 20 # requests por minuto por usuario
|
||||
@@ -59,71 +51,31 @@ model: "gemini-1.5-flash" # modelo de Google AI
|
||||
temperature: 0.7 # creatividad de respuestas
|
||||
top_p: 0.85 # diversidad de tokens
|
||||
top_k: 40 # límite de candidatos
|
||||
\`\`\`
|
||||
\`\`\``)
|
||||
)
|
||||
.addSectionComponents(
|
||||
new SectionBuilder()
|
||||
.addTextDisplayComponents(
|
||||
new TextDisplayBuilder()
|
||||
.setContent("🔙 Volver al panel principal de administración")
|
||||
)
|
||||
.setButtonAccessory(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('ai_refresh_stats')
|
||||
.setLabel('Volver al Panel')
|
||||
.setEmoji('🔙')
|
||||
.setStyle(ButtonStyle.Primary)
|
||||
)
|
||||
);
|
||||
|
||||
## 🔄 Opciones Disponibles`
|
||||
},
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
{
|
||||
type: 9,
|
||||
components: [
|
||||
{ type: 10, content: "📊 **Ver logs del sistema** en tiempo real" }
|
||||
],
|
||||
accessory: {
|
||||
type: 2,
|
||||
style: 2,
|
||||
emoji: "📊",
|
||||
label: 'Ver Logs',
|
||||
custom_id: 'ai_view_logs'
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 9,
|
||||
components: [
|
||||
{ type: 10, content: "🔧 **Cambiar configuración** de rate limits y timeouts" }
|
||||
],
|
||||
accessory: {
|
||||
type: 2,
|
||||
style: 2,
|
||||
emoji: "🔧",
|
||||
label: 'Configurar',
|
||||
custom_id: 'ai_modify_config'
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 9,
|
||||
components: [
|
||||
{ type: 10, content: "🧪 **Modo de prueba** para testing del sistema" }
|
||||
],
|
||||
accessory: {
|
||||
type: 2,
|
||||
style: 2,
|
||||
emoji: "🧪",
|
||||
label: 'Modo Test',
|
||||
custom_id: 'ai_test_mode'
|
||||
}
|
||||
},
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
{
|
||||
type: 9,
|
||||
components: [
|
||||
{ type: 10, content: "🔙 Volver al panel principal de administración" }
|
||||
],
|
||||
accessory: {
|
||||
type: 2,
|
||||
style: 1,
|
||||
emoji: "🔙",
|
||||
label: 'Volver al Panel',
|
||||
custom_id: 'ai_refresh_stats'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
await interaction.message.edit({
|
||||
components: [configContainer],
|
||||
flags: MessageFlags.IsComponentsV2
|
||||
});
|
||||
logger.info(`Panel de configuración de IA accedido por el dueño ${interaction.user.username} (${interaction.user.id})`);
|
||||
|
||||
await interaction.message.edit({ components: [configPanel] });
|
||||
logger.info(`Panel de configuración de IA accedido por ${interaction.user.username} (${interaction.user.id})`);
|
||||
|
||||
} catch (error) {
|
||||
//@ts-ignore
|
||||
logger.error('Error mostrando configuración de IA:', error);
|
||||
if (!interaction.deferred && !interaction.replied) {
|
||||
await interaction.reply({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import logger from "../../core/lib/logger";
|
||||
import { ButtonInteraction, MessageFlags, PermissionFlagsBits } from 'discord.js';
|
||||
import { ButtonInteraction, MessageFlags, ContainerBuilder, TextDisplayBuilder, SectionBuilder, ButtonBuilder, ButtonStyle } from 'discord.js';
|
||||
import { aiService } from '../../core/services/AIService';
|
||||
|
||||
const OWNER_ID = '327207082203938818'; // Solo el dueño puede hacer reset completo
|
||||
@@ -7,7 +7,7 @@ const OWNER_ID = '327207082203938818'; // Solo el dueño puede hacer reset compl
|
||||
export default {
|
||||
customId: 'ai_full_reset',
|
||||
run: async (interaction: ButtonInteraction) => {
|
||||
// Verificar que sea el dueño del bot (reset completo es crítico)
|
||||
// Verificar que sea el dueño del bot (reset completo es CRÍTICO)
|
||||
if (interaction.user.id !== OWNER_ID) {
|
||||
return interaction.reply({
|
||||
content: '❌ Solo el dueño del bot puede realizar un reset completo del sistema de IA.',
|
||||
@@ -23,33 +23,22 @@ export default {
|
||||
const conversationsCleared = statsBefore.activeConversations;
|
||||
const requestsCleared = statsBefore.queueLength;
|
||||
|
||||
// Aquí irían las funciones reales de reset del servicio
|
||||
// Por ejemplo:
|
||||
// Aquí irían las funciones reales de reset del servicio:
|
||||
// aiService.fullReset();
|
||||
// aiService.clearAllConversations();
|
||||
// aiService.clearRequestQueue();
|
||||
// aiService.resetStatistics();
|
||||
|
||||
|
||||
const resetTimestamp = new Date().toISOString().replace('T', ' ').split('.')[0];
|
||||
|
||||
// Panel de confirmación de reset completo
|
||||
// @ts-ignore
|
||||
const resetCompletePanel = {
|
||||
type: 17,
|
||||
accent_color: 0xFF4444,
|
||||
components: [
|
||||
{
|
||||
type: 10,
|
||||
content: '## ⚠️ RESET COMPLETO EJECUTADO'
|
||||
},
|
||||
{
|
||||
type: 10,
|
||||
content: '-# El sistema de IA ha sido completamente reiniciado.'
|
||||
},
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
{
|
||||
type: 10,
|
||||
content: `## 🔄 Resumen del Reset
|
||||
// Panel de confirmación de reset completo usando la API real
|
||||
const resetCompleteContainer = new ContainerBuilder()
|
||||
.addTextDisplayComponents(
|
||||
new TextDisplayBuilder()
|
||||
.setContent(`## ⚠️ RESET COMPLETO EJECUTADO
|
||||
-# El sistema de IA ha sido completamente reiniciado.
|
||||
|
||||
## 🔄 Resumen del Reset
|
||||
\`\`\`
|
||||
┌─────────────────────────┬─────────────┐
|
||||
│ Elemento Limpiado │ Cantidad │
|
||||
@@ -69,12 +58,9 @@ export default {
|
||||
|
||||
⚠️ ADVERTENCIA: Todas las conversaciones activas
|
||||
han sido eliminadas permanentemente.
|
||||
\`\`\``
|
||||
},
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
{
|
||||
type: 10,
|
||||
content: `## ✅ Sistema Restaurado
|
||||
\`\`\`
|
||||
|
||||
## ✅ Sistema Restaurado
|
||||
|
||||
El sistema de IA ha vuelto a su estado inicial:
|
||||
• **Memoria limpia** - Sin conversaciones previas
|
||||
@@ -83,45 +69,46 @@ El sistema de IA ha vuelto a su estado inicial:
|
||||
• **Configuración default** - Valores originales
|
||||
• **Cache limpio** - Memoria optimizada
|
||||
|
||||
El sistema está listo para recibir nuevas consultas.`
|
||||
},
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
{
|
||||
type: 9,
|
||||
components: [
|
||||
{ type: 10, content: "🔙 Volver al panel principal (con datos reset)" }
|
||||
],
|
||||
accessory: {
|
||||
type: 2,
|
||||
style: 1,
|
||||
emoji: "🔙",
|
||||
label: 'Volver al Panel',
|
||||
custom_id: 'ai_refresh_stats'
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 9,
|
||||
components: [
|
||||
{ type: 10, content: "⚠️ **REALIZAR OTRO RESET** (solo si es necesario)" }
|
||||
],
|
||||
accessory: {
|
||||
type: 2,
|
||||
style: 4,
|
||||
emoji: "⚠️",
|
||||
label: 'Reset Nuevamente',
|
||||
custom_id: 'ai_full_reset'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
El sistema está listo para recibir nuevas consultas.`)
|
||||
)
|
||||
.addSectionComponents(
|
||||
new SectionBuilder()
|
||||
.addTextDisplayComponents(
|
||||
new TextDisplayBuilder()
|
||||
.setContent("🔙 Volver al panel principal (con datos reset)")
|
||||
)
|
||||
.setButtonAccessory(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('ai_refresh_stats')
|
||||
.setLabel('Volver al Panel')
|
||||
.setEmoji('🔙')
|
||||
.setStyle(ButtonStyle.Primary)
|
||||
),
|
||||
new SectionBuilder()
|
||||
.addTextDisplayComponents(
|
||||
new TextDisplayBuilder()
|
||||
.setContent("⚠️ **REALIZAR OTRO RESET** (solo si es necesario)")
|
||||
)
|
||||
.setButtonAccessory(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('ai_full_reset')
|
||||
.setLabel('Reset Nuevamente')
|
||||
.setEmoji('⚠️')
|
||||
.setStyle(ButtonStyle.Danger)
|
||||
)
|
||||
);
|
||||
|
||||
await interaction.message.edit({
|
||||
components: [resetCompleteContainer],
|
||||
flags: MessageFlags.IsComponentsV2
|
||||
});
|
||||
|
||||
await interaction.message.edit({ components: [resetCompletePanel] });
|
||||
|
||||
// Log crítico del reset completo
|
||||
logger.warn(`🚨 RESET COMPLETO DE IA ejecutado por ${interaction.user.username} (${interaction.user.id})`);
|
||||
logger.warn(`🚨 RESET COMPLETO DE IA ejecutado por el dueño ${interaction.user.username} (${interaction.user.id})`);
|
||||
logger.info(`Reset stats - Conversaciones: ${conversationsCleared}, Queue: ${requestsCleared}, Timestamp: ${resetTimestamp}`);
|
||||
|
||||
} catch (error) {
|
||||
//@ts-ignore
|
||||
logger.error('Error ejecutando reset completo de IA:', error);
|
||||
if (!interaction.deferred && !interaction.replied) {
|
||||
await interaction.reply({
|
||||
|
||||
@@ -1,164 +1,33 @@
|
||||
import logger from "../../core/lib/logger";
|
||||
import { ButtonInteraction, MessageFlags, PermissionFlagsBits } from 'discord.js';
|
||||
import { ButtonInteraction, MessageFlags, ContainerBuilder, TextDisplayBuilder, SectionBuilder, ButtonBuilder, ButtonStyle } from 'discord.js';
|
||||
import { buildAIAdminPanel } from '../../commands/messages/AI/stats';
|
||||
|
||||
/**
|
||||
* Formatear tiempo de actividad
|
||||
*/
|
||||
function formatUptime(seconds: number): string {
|
||||
const days = Math.floor(seconds / 86400);
|
||||
const hours = Math.floor((seconds % 86400) / 3600);
|
||||
const minutes = Math.floor((seconds % 3600) / 60);
|
||||
|
||||
if (days > 0) return `${days}d ${hours}h ${minutes}m`;
|
||||
if (hours > 0) return `${hours}h ${minutes}m`;
|
||||
return `${minutes}m`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatear bytes a formato legible
|
||||
*/
|
||||
function formatBytesMB(bytes: number): string {
|
||||
return (bytes / 1024 / 1024).toFixed(1) + 'MB';
|
||||
}
|
||||
|
||||
/**
|
||||
* Construir panel de administración de IA actualizado
|
||||
*/
|
||||
function buildRefreshedAIPanel() {
|
||||
const { aiService } = require('../../core/services/AIService');
|
||||
const stats = aiService.getStats();
|
||||
const uptime = process.uptime();
|
||||
const memoryUsage = process.memoryUsage();
|
||||
const now = new Date();
|
||||
const ts = now.toISOString().replace('T', ' ').split('.')[0];
|
||||
|
||||
// Estados del sistema
|
||||
const queueStatus = stats.queueLength === 0 ? '🟢 Normal' :
|
||||
stats.queueLength < 5 ? '🟡 Ocupado' : '🔴 Saturado';
|
||||
const memoryStatus = memoryUsage.heapUsed / memoryUsage.heapTotal > 0.8 ? '🔴 Alta' : '🟢 Normal';
|
||||
|
||||
const rss = formatBytesMB(memoryUsage.rss);
|
||||
const heapUsed = formatBytesMB(memoryUsage.heapUsed);
|
||||
const heapTotal = formatBytesMB(memoryUsage.heapTotal);
|
||||
const external = formatBytesMB(memoryUsage.external);
|
||||
|
||||
// @ts-ignore
|
||||
return {
|
||||
type: 17,
|
||||
accent_color: 0xFF69B4,
|
||||
components: [
|
||||
{
|
||||
type: 10,
|
||||
content: '## 🌸 Panel de Administración - Gemini-chan (Actualizado)'
|
||||
},
|
||||
{
|
||||
type: 10,
|
||||
content: '-# Estadísticas refrescadas automáticamente.'
|
||||
},
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
{
|
||||
type: 9,
|
||||
components: [
|
||||
{ type: 10, content: `🔄 **Conversaciones Activas:** ${stats.activeConversations}` }
|
||||
],
|
||||
accessory: {
|
||||
type: 2,
|
||||
style: 1,
|
||||
emoji: "🧹",
|
||||
label: 'Limpiar Cache',
|
||||
custom_id: 'ai_clear_cache'
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 9,
|
||||
components: [
|
||||
{ type: 10, content: `📊 **Requests en Cola:** ${stats.queueLength} | **Estado:** ${queueStatus}` }
|
||||
],
|
||||
accessory: {
|
||||
type: 2,
|
||||
style: 1,
|
||||
emoji: "🔄",
|
||||
label: 'Refrescar Stats',
|
||||
custom_id: 'ai_refresh_stats'
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 9,
|
||||
components: [
|
||||
{ type: 10, content: `⏱️ **Total Requests:** ${stats.totalRequests} | **Uptime:** ${formatUptime(uptime)}` }
|
||||
],
|
||||
accessory: {
|
||||
type: 2,
|
||||
style: 2,
|
||||
emoji: "🔧",
|
||||
label: 'Configuración',
|
||||
custom_id: 'ai_config'
|
||||
}
|
||||
},
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
{
|
||||
type: 10,
|
||||
content: ` ## 🧠 Uso de Memoria del Sistema IA
|
||||
\`\`\`
|
||||
┌─────────────────┬──────────────┬──────────┐
|
||||
│ Memory Type │ Usage │ Status │
|
||||
├─────────────────┼──────────────┼──────────┤
|
||||
│ RSS │ ${rss.padEnd(12)} │ Normal │
|
||||
│ Heap Used │ ${heapUsed.padEnd(12)} │ ${memoryStatus.padEnd(8)} │
|
||||
│ Heap Total │ ${heapTotal.padEnd(12)} │ Normal │
|
||||
│ External │ ${external.padEnd(12)} │ Normal │
|
||||
└─────────────────┴──────────────┴──────────┘
|
||||
|
||||
📈 Configuración Actual:
|
||||
• Rate Limit: 20 req/min por usuario
|
||||
• Cooldown: 3 segundos entre requests
|
||||
• Max Tokens: 1M entrada / 8K salida
|
||||
• Max Concurrent: 3 requests simultáneos
|
||||
• Modelo: gemini-1.5-flash
|
||||
\`\`\`
|
||||
🔄 Última actualización: ${ts} UTC
|
||||
|
||||
⚠️ **Nota:** El sistema se resetea automáticamente cada 30 minutos para optimizar memoria.`
|
||||
},
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
{
|
||||
type: 9,
|
||||
components: [
|
||||
{ type: 10, content: "<:Sup_urg:1420535068056748042> **REINICIAR** todo el sistema de IA (limpia cache, conversaciones y estadísticas)" }
|
||||
],
|
||||
accessory: {
|
||||
type: 2,
|
||||
style: 4,
|
||||
emoji: "⚠️",
|
||||
label: 'RESET COMPLETO',
|
||||
custom_id: 'ai_full_reset'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
const OWNER_ID = '327207082203938818'; // Solo el dueño puede usar este panel
|
||||
|
||||
export default {
|
||||
customId: 'ai_refresh_stats',
|
||||
run: async (interaction: ButtonInteraction) => {
|
||||
// Verificar permisos de administrador
|
||||
if (!interaction.memberPermissions?.has(PermissionFlagsBits.Administrator)) {
|
||||
return interaction.reply({
|
||||
content: '❌ No tienes permisos de administrador para usar este botón.',
|
||||
flags: MessageFlags.Ephemeral
|
||||
// Verificar que sea el dueño del bot (CRÍTICO)
|
||||
if (interaction.user.id !== OWNER_ID) {
|
||||
return interaction.reply({
|
||||
content: '❌ Solo el dueño del bot puede usar este panel administrativo.',
|
||||
flags: MessageFlags.Ephemeral
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await interaction.deferUpdate();
|
||||
|
||||
// Refrescar y reconstruir el panel con datos actualizados
|
||||
const refreshedPanel = buildRefreshedAIPanel();
|
||||
|
||||
await interaction.message.edit({ components: [refreshedPanel] });
|
||||
logger.info(`Estadísticas de IA refrescadas por ${interaction.user.username} (${interaction.user.id})`);
|
||||
|
||||
} catch (error)
|
||||
// Reconstruir panel principal con datos actualizados
|
||||
const refreshedPanel = buildAIAdminPanel();
|
||||
|
||||
await interaction.message.edit({
|
||||
components: [refreshedPanel],
|
||||
flags: MessageFlags.IsComponentsV2
|
||||
});
|
||||
logger.info(`Estadísticas de IA refrescadas por el dueño ${interaction.user.username} (${interaction.user.id})`);
|
||||
|
||||
} catch (error) {
|
||||
//@ts-ignore
|
||||
logger.error('Error refrescando estadísticas de IA:', error);
|
||||
if (!interaction.deferred && !interaction.replied) {
|
||||
|
||||
Reference in New Issue
Block a user