290 lines
10 KiB
JavaScript
290 lines
10 KiB
JavaScript
const express = require('express');
|
|
const bodyParser = require('body-parser');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const app = express();
|
|
const port = 3000;
|
|
const client = require('../src/index')
|
|
const multer = require('multer');
|
|
const upload = multer();
|
|
const { getActivities } = require('../src/functions/handlers/handleCommands');
|
|
|
|
app.use(bodyParser.urlencoded({ extended: true }));
|
|
app.use(express.static(path.join(__dirname, 'public')));
|
|
app.use(upload.fields([{ name: 'new-bot-avatar' }, { name: 'new-bot-banner' }]));
|
|
|
|
|
|
|
|
function loadConfig() {
|
|
const configPath = path.join(__dirname, '../config.json');
|
|
if (fs.existsSync(configPath)) {
|
|
return JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
}
|
|
return {};
|
|
}
|
|
|
|
app.get('/', (req, res) => {
|
|
res.sendFile(path.join(__dirname, 'views', 'index.html'));
|
|
});
|
|
|
|
app.get('/bot', (req, res) => {
|
|
res.sendFile(path.join(__dirname, 'views', 'botprofile.html'));
|
|
});
|
|
|
|
app.get('/config', (req, res) => {
|
|
res.sendFile(path.join(__dirname, 'views', 'config.html'));
|
|
});
|
|
|
|
app.get('/commands', (req, res) => {
|
|
res.sendFile(path.join(__dirname, 'views', 'commands.html'));
|
|
});
|
|
|
|
app.get('/errors', (req, res) => {
|
|
res.sendFile(path.join(__dirname, 'views', 'errors.html'));
|
|
});
|
|
|
|
app.get('/guilds', (req, res) => {
|
|
res.sendFile(path.join(__dirname, 'views', 'guilds.html'));
|
|
});
|
|
|
|
app.get('/api/bot-info', async (req, res) => {
|
|
try {
|
|
|
|
const fetchedUser = await client.users.fetch(client.user.id, { force: true });
|
|
const botStatus = client.presence.status;
|
|
const botName = client.user.username;
|
|
const botAvatar = `https://cdn.discordapp.com/avatars/${client.user.id}/${client.user.avatar}.png`;
|
|
|
|
const botId = client.user.id;
|
|
const botBanner = `https://cdn.discordapp.com/banners/${client.user.id}/${fetchedUser.banner}.png`;
|
|
|
|
const isVerified = client.user.verified;
|
|
res.json({
|
|
botStatus,
|
|
botName,
|
|
botId,
|
|
botBanner,
|
|
botAvatar,
|
|
isVerified
|
|
})
|
|
} catch (err) {
|
|
console.error('Error fetching bot info:', err);
|
|
res.status(500).json({ error: 'Internal Server Error' });
|
|
}
|
|
})
|
|
|
|
app.post('/api/update-bot', async (req, res) => {
|
|
const { newBotName } = req.body;
|
|
|
|
if (newBotName) {
|
|
try {
|
|
await client.user.setUsername(newBotName);
|
|
} catch (error) {
|
|
console.error('Error updating bot name:', error);
|
|
return res.json({ success: false, message: 'Failed to update bot name' });
|
|
}
|
|
}
|
|
|
|
// Update bot avatar if provided
|
|
const avatarFile = req.files['new-bot-avatar']?.[0];
|
|
if (avatarFile) {
|
|
try {
|
|
await client.user.setAvatar(avatarFile.buffer); // Use buffer for the image
|
|
} catch (error) {
|
|
console.error('Error updating bot avatar:', error);
|
|
return res.json({ success: false, message: 'Failed to update bot avatar' });
|
|
}
|
|
}
|
|
|
|
const bannerFile = req.files['new-bot-banner']?.[0];
|
|
if (bannerFile) {
|
|
try {
|
|
await client.user.setBanner(bannerFile.buffer);
|
|
} catch (error) {
|
|
console.error('Error updating bot banner:', error);
|
|
return res.json({ success: false, message: 'Failed to update bot banner' });
|
|
}
|
|
}
|
|
|
|
return res.json({ success: true });
|
|
});
|
|
|
|
app.get('/api/guilds', async (req, res) => {
|
|
const guildsData = client.guilds.cache.map(guild => ({
|
|
id: guild.id,
|
|
name: guild.name,
|
|
icon: guild.iconURL(),
|
|
memberCount: guild.memberCount,
|
|
}));
|
|
|
|
res.json(guildsData);
|
|
});
|
|
|
|
app.get('/api/bot-stats', async (req, res) => {
|
|
try {
|
|
const totalServers = client.guilds.cache.size;
|
|
const totalCommands = (client.commands ? client.commands.size : 0) + (client.prefix ? client.prefix.size : 0);
|
|
const botName = client.user.username;
|
|
const botIcon = `https://cdn.discordapp.com/avatars/${client.user.id}/${client.user.avatar}.png`;
|
|
let totalUsers = 0;
|
|
client.guilds.cache.forEach(guild => {
|
|
totalUsers += guild.memberCount;
|
|
});
|
|
|
|
res.json({
|
|
totalServers,
|
|
totalUsers,
|
|
totalCommands,
|
|
botName,
|
|
botIcon
|
|
});
|
|
} catch (err) {
|
|
console.error('Error fetching bot stats:', err);
|
|
res.status(500).json({ error: 'Internal Server Error' });
|
|
}
|
|
});
|
|
|
|
app.post('/update-config', (req, res) => {
|
|
// Load the existing config
|
|
const currentConfig = loadConfig();
|
|
|
|
// Update only the fields that are provided
|
|
const newConfig = {
|
|
bot: {
|
|
...currentConfig.bot, // Keep existing values
|
|
...(req.body.token && { token: req.body.token }), // Update token if provided
|
|
...(req.body.id && { id: req.body.id }), // Update id if provided
|
|
...(req.body.admins && { admins: req.body.admins.split(',') }), // Update admins if provided
|
|
...(req.body.ownerId && { ownerId: req.body.ownerId }), // Update ownerId if provided
|
|
...(req.body.developerCommandsServerIds && {
|
|
developerCommandsServerIds: req.body.developerCommandsServerIds.split(','),
|
|
}), // Update developerCommandsServerIds if provided
|
|
},
|
|
database: {
|
|
...(currentConfig.database || {}),
|
|
...(req.body.mongodbUrl && { mongodbUrl: req.body.mongodbUrl }),
|
|
},
|
|
logging: {
|
|
...(currentConfig.logging || {}),
|
|
...(req.body.guildJoinLogsId && { guildJoinLogsId: req.body.guildJoinLogsId }),
|
|
...(req.body.guildLeaveLogsId && { guildLeaveLogsId: req.body.guildLeaveLogsId }),
|
|
...(req.body.commandLogsChannelId && { commandLogsChannelId: req.body.commandLogsChannelId }),
|
|
...(req.body.errorLogs && { errorLogs: req.body.errorLogs }),
|
|
},
|
|
prefix: {
|
|
...(currentConfig.prefix || {}),
|
|
...(req.body.prefix && { value: req.body.prefix }),
|
|
},
|
|
};
|
|
|
|
fs.writeFileSync(path.join(__dirname, '../config.json'), JSON.stringify(newConfig, null, 2));
|
|
res.redirect('/config?success=true');
|
|
});
|
|
|
|
app.get('/api/commands', (req, res) => {
|
|
const slashCommandsDir = path.join(__dirname, '../src/commands');
|
|
const prefixCommandsDir = path.join(__dirname, '../src/messages');
|
|
const commands = {
|
|
slash: [],
|
|
prefix: []
|
|
};
|
|
|
|
// A function to read commands from a directory
|
|
function readCommands(dir, commandArray, type) {
|
|
return new Promise((resolve, reject) => {
|
|
fs.readdir(dir, (err, files) => {
|
|
if (err) {
|
|
return reject(`Error reading ${type} commands`);
|
|
}
|
|
|
|
const promises = files.map(file => {
|
|
const filePath = path.join(dir, file);
|
|
return new Promise((resolveFile, rejectFile) => {
|
|
fs.stat(filePath, (err, stats) => {
|
|
if (err) {
|
|
return rejectFile('Error reading file stats');
|
|
}
|
|
|
|
if (stats.isDirectory()) {
|
|
readCommands(filePath, commandArray, type).then(resolveFile).catch(rejectFile);
|
|
} else if (path.extname(file) === '.js') {
|
|
const command = require(filePath);
|
|
if (type === 'slash') {
|
|
commandArray.push({
|
|
name: command.data.name,
|
|
description: command.data.description
|
|
});
|
|
} else {
|
|
commandArray.push({
|
|
name: command.name,
|
|
description: command.description
|
|
});
|
|
}
|
|
resolveFile();
|
|
} else {
|
|
resolveFile(); // Handle non-JS files gracefully
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
// Wait for all promises to resolve
|
|
Promise.all(promises).then(resolve).catch(reject);
|
|
});
|
|
});
|
|
}
|
|
|
|
// Read slash commands and then prefix commands
|
|
readCommands(slashCommandsDir, commands.slash, 'slash')
|
|
.then(() => readCommands(prefixCommandsDir, commands.prefix, 'prefix'))
|
|
.then(() => {
|
|
res.json(commands); // Send response after both commands are read
|
|
})
|
|
.catch(err => {
|
|
console.error(err);
|
|
res.status(500).json({ error: err });
|
|
});
|
|
});
|
|
|
|
app.get('/api/activities', (req, res) => {
|
|
const activities = getActivities();
|
|
res.json(activities);
|
|
});
|
|
|
|
app.get('/api/errors', (req, res) => {
|
|
const errorsDir = path.join(__dirname, '../errors'); // Path to the errors folder
|
|
|
|
// Ensure that the folder exists
|
|
if (!fs.existsSync(errorsDir)) {
|
|
return res.json({ errors: [], message: 'No errors found' });
|
|
}
|
|
|
|
// Read the files from the errors folder
|
|
fs.readdir(errorsDir, (err, files) => {
|
|
if (err) {
|
|
return res.status(500).json({ error: 'Unable to read error logs' });
|
|
}
|
|
|
|
// Sort files by date (latest first)
|
|
files.sort((a, b) => fs.statSync(path.join(errorsDir, b)).mtime - fs.statSync(path.join(errorsDir, a)).mtime);
|
|
|
|
// Prepare an array to store errors
|
|
const errorLogs = [];
|
|
|
|
// Read the content of each error file
|
|
files.forEach(file => {
|
|
const filePath = path.join(errorsDir, file);
|
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
errorLogs.push({ fileName: file, content });
|
|
});
|
|
|
|
// Send the error logs to the front-end
|
|
res.json({ errors: errorLogs });
|
|
});
|
|
});
|
|
|
|
// Start the server
|
|
app.listen(port, () => {
|
|
console.log(`Admin dashboard running at http://localhost:${port}`);
|
|
});
|