poixpixel-discord-bot/src/commands/util/restart.ts
2025-04-13 16:48:18 -04:00

93 lines
2.6 KiB
TypeScript

import { PermissionsBitField, SlashCommandBuilder } from 'discord.js';
import { exec } from 'child_process';
import { promisify } from 'util';
import { Command } from '@/types/CommandTypes.js';
import { loadConfig } from '@/util/configLoader.js';
import {
NotificationType,
notifyManagers,
} from '@/util/notificationHandler.js';
import { isRedisConnected } from '@/db/redis.js';
import { ensureDatabaseConnection } from '@/db/db.js';
const execAsync = promisify(exec);
const command: Command = {
data: new SlashCommandBuilder()
.setName('restart')
.setDescription('(Manager Only) Restart the bot'),
execute: async (interaction) => {
const config = loadConfig();
const managerRoleId = config.roles.staffRoles.find(
(role) => role.name === 'Manager',
)?.roleId;
const member = await interaction.guild?.members.fetch(interaction.user.id);
const hasManagerRole = member?.roles.cache.has(managerRoleId || '');
if (
!hasManagerRole &&
!interaction.memberPermissions?.has(
PermissionsBitField.Flags.Administrator,
)
) {
await interaction.reply({
content:
'You do not have permission to restart the bot. This command is restricted to users with the Manager role.',
flags: ['Ephemeral'],
});
return;
}
await interaction.reply({
content: 'Restarting the bot... This may take a few moments.',
flags: ['Ephemeral'],
});
const dbConnected = await ensureDatabaseConnection();
const redisConnected = isRedisConnected();
let statusInfo = '';
if (!dbConnected) {
statusInfo += '⚠️ Database is currently disconnected\n';
}
if (!redisConnected) {
statusInfo += '⚠️ Redis caching is currently unavailable\n';
}
if (dbConnected && redisConnected) {
statusInfo = '✅ All services are operational\n';
}
await notifyManagers(
interaction.client,
NotificationType.BOT_RESTARTING,
`Restart initiated by ${interaction.user.tag}\n\nCurrent service status:\n${statusInfo}`,
);
setTimeout(async () => {
try {
console.log(
`Bot restart initiated by ${interaction.user.tag} (${interaction.user.id})`,
);
await execAsync('yarn restart');
} catch (error) {
console.error('Failed to restart the bot:', error);
try {
await interaction.followUp({
content:
'Failed to restart the bot. Check the console for details.',
flags: ['Ephemeral'],
});
} catch {
// If this fails too, we can't do much
}
}
}, 1000);
},
};
export default command;