293 lines
9.4 KiB
JavaScript
293 lines
9.4 KiB
JavaScript
require('dotenv').config({ path: __dirname + '/.env' });
|
|
const express = require('express');
|
|
const cors = require('cors');
|
|
|
|
const app = express();
|
|
const port = process.env.PORT || 3001;
|
|
|
|
app.use(cors());
|
|
app.use(express.json());
|
|
|
|
const axios = require('axios');
|
|
|
|
app.get('/auth/discord', (req, res) => {
|
|
const url = `https://discord.com/api/oauth2/authorize?client_id=${process.env.DISCORD_CLIENT_ID}&redirect_uri=${encodeURIComponent('http://localhost:3002/auth/discord/callback')}&response_type=code&scope=identify%20guilds`;
|
|
res.redirect(url);
|
|
});
|
|
|
|
app.get('/auth/discord/callback', async (req, res) => {
|
|
const code = req.query.code;
|
|
if (!code) {
|
|
return res.status(400).send('No code provided');
|
|
}
|
|
|
|
try {
|
|
const params = new URLSearchParams();
|
|
params.append('client_id', process.env.DISCORD_CLIENT_ID);
|
|
params.append('client_secret', process.env.DISCORD_CLIENT_SECRET);
|
|
params.append('grant_type', 'authorization_code');
|
|
params.append('code', code);
|
|
params.append('redirect_uri', 'http://localhost:3002/auth/discord/callback');
|
|
|
|
const response = await axios.post('https://discord.com/api/oauth2/token', params, {
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
},
|
|
});
|
|
|
|
const { access_token } = response.data;
|
|
|
|
const userResponse = await axios.get('https://discord.com/api/users/@me', {
|
|
headers: {
|
|
Authorization: `Bearer ${access_token}`,
|
|
},
|
|
});
|
|
|
|
const guildsResponse = await axios.get('https://discord.com/api/users/@me/guilds', {
|
|
headers: {
|
|
Authorization: `Bearer ${access_token}`,
|
|
},
|
|
});
|
|
|
|
const adminGuilds = guildsResponse.data.filter(guild => (guild.permissions & 0x8) === 0x8);
|
|
|
|
const user = userResponse.data;
|
|
const db = readDb();
|
|
user.theme = db.users && db.users[user.id] ? db.users[user.id].theme : 'light';
|
|
const guilds = adminGuilds;
|
|
res.redirect(`http://localhost:3000/dashboard?user=${encodeURIComponent(JSON.stringify(user))}&guilds=${encodeURIComponent(JSON.stringify(guilds))}`);
|
|
} catch (error) {
|
|
console.error('Error during Discord OAuth2 callback:', error);
|
|
res.status(500).send('Internal Server Error');
|
|
}
|
|
});
|
|
|
|
const { readDb, writeDb } = require('./db');
|
|
|
|
app.get('/api/servers/:guildId/settings', (req, res) => {
|
|
const { guildId } = req.params;
|
|
const db = readDb();
|
|
const settings = db[guildId] || { pingCommand: false };
|
|
res.json(settings);
|
|
});
|
|
|
|
app.post('/api/servers/:guildId/settings', (req, res) => {
|
|
const { guildId } = req.params;
|
|
const newSettings = req.body || {};
|
|
const db = readDb();
|
|
if (!db[guildId]) db[guildId] = {};
|
|
// Merge incoming settings with existing settings to avoid overwriting unrelated keys
|
|
db[guildId] = { ...db[guildId], ...newSettings };
|
|
writeDb(db);
|
|
res.json({ success: true });
|
|
});
|
|
|
|
// Toggle a single command for a guild (preserves other toggles)
|
|
app.post('/api/servers/:guildId/commands/:cmdName/toggle', (req, res) => {
|
|
const { guildId, cmdName } = req.params;
|
|
const { enabled } = req.body; // boolean
|
|
const protectedCommands = ['help', 'manage-commands'];
|
|
if (protectedCommands.includes(cmdName)) {
|
|
return res.status(403).json({ success: false, message: 'This command is locked and cannot be toggled.' });
|
|
}
|
|
const db = readDb();
|
|
if (!db[guildId]) db[guildId] = {};
|
|
if (!db[guildId].commandToggles) db[guildId].commandToggles = {};
|
|
if (typeof enabled === 'boolean') {
|
|
db[guildId].commandToggles[cmdName] = enabled;
|
|
writeDb(db);
|
|
return res.json({ success: true, cmdName, enabled });
|
|
}
|
|
return res.status(400).json({ success: false, message: 'Missing or invalid "enabled" boolean in request body' });
|
|
});
|
|
|
|
app.get('/api/servers/:guildId/bot-status', (req, res) => {
|
|
const { guildId } = req.params;
|
|
const guild = bot.client.guilds.cache.get(guildId);
|
|
if (guild) {
|
|
res.json({ isBotInServer: true });
|
|
} else {
|
|
res.json({ isBotInServer: false });
|
|
}
|
|
});
|
|
|
|
app.get('/api/client-id', (req, res) => {
|
|
res.json({ clientId: process.env.DISCORD_CLIENT_ID });
|
|
});
|
|
|
|
app.post('/api/user/theme', (req, res) => {
|
|
const { userId, theme } = req.body;
|
|
const db = readDb();
|
|
if (!db.users) {
|
|
db.users = {};
|
|
}
|
|
if (!db.users[userId]) {
|
|
db.users[userId] = {};
|
|
}
|
|
db.users[userId].theme = theme;
|
|
writeDb(db);
|
|
res.json({ success: true });
|
|
});
|
|
|
|
app.post('/api/servers/:guildId/leave', async (req, res) => {
|
|
const { guildId } = req.params;
|
|
try {
|
|
const guild = await bot.client.guilds.fetch(guildId);
|
|
if (guild) {
|
|
await guild.leave();
|
|
res.json({ success: true });
|
|
} else {
|
|
res.status(404).json({ success: false, message: 'Bot is not in the specified server' });
|
|
}
|
|
} catch (error) {
|
|
console.error('Error leaving server:', error);
|
|
res.status(500).json({ success: false, message: 'Internal Server Error' });
|
|
}
|
|
});
|
|
|
|
app.get('/api/servers/:guildId/channels', async (req, res) => {
|
|
const { guildId } = req.params;
|
|
const guild = bot.client.guilds.cache.get(guildId);
|
|
if (!guild) {
|
|
return res.json([]);
|
|
}
|
|
try {
|
|
const channels = await guild.channels.fetch();
|
|
const textChannels = channels.filter(channel => channel.type === 0).map(channel => ({ id: channel.id, name: channel.name }));
|
|
res.json(textChannels);
|
|
} catch (error) {
|
|
console.error('Error fetching channels:', error);
|
|
res.status(500).json({ success: false, message: 'Internal Server Error' });
|
|
}
|
|
});
|
|
|
|
app.get('/api/servers/:guildId/welcome-leave-settings', (req, res) => {
|
|
const { guildId } = req.params;
|
|
const db = readDb();
|
|
const settings = db[guildId] || {};
|
|
|
|
const welcomeLeaveSettings = {
|
|
welcome: {
|
|
enabled: settings.welcomeEnabled || false,
|
|
channel: settings.welcomeChannel || '',
|
|
message: settings.welcomeMessage || 'Welcome to the server, {user}!',
|
|
customMessage: settings.welcomeCustomMessage || '',
|
|
},
|
|
leave: {
|
|
enabled: settings.leaveEnabled || false,
|
|
channel: settings.leaveChannel || '',
|
|
message: settings.leaveMessage || '{user} has left the server.',
|
|
customMessage: settings.leaveCustomMessage || '',
|
|
},
|
|
};
|
|
|
|
res.json(welcomeLeaveSettings);
|
|
});
|
|
|
|
app.post('/api/servers/:guildId/welcome-leave-settings', (req, res) => {
|
|
const { guildId } = req.params;
|
|
const newSettings = req.body;
|
|
const db = readDb();
|
|
|
|
if (!db[guildId]) {
|
|
db[guildId] = {};
|
|
}
|
|
|
|
db[guildId].welcomeEnabled = newSettings.welcome.enabled;
|
|
db[guildId].welcomeChannel = newSettings.welcome.channel;
|
|
db[guildId].welcomeMessage = newSettings.welcome.message;
|
|
db[guildId].welcomeCustomMessage = newSettings.welcome.customMessage;
|
|
|
|
db[guildId].leaveEnabled = newSettings.leave.enabled;
|
|
db[guildId].leaveChannel = newSettings.leave.channel;
|
|
db[guildId].leaveMessage = newSettings.leave.message;
|
|
db[guildId].leaveCustomMessage = newSettings.leave.customMessage;
|
|
|
|
writeDb(db);
|
|
|
|
res.json({ success: true });
|
|
});
|
|
|
|
app.get('/api/servers/:guildId/roles', async (req, res) => {
|
|
const { guildId } = req.params;
|
|
const guild = bot.client.guilds.cache.get(guildId);
|
|
if (!guild) {
|
|
return res.json([]);
|
|
}
|
|
try {
|
|
const rolesCollection = await guild.roles.fetch();
|
|
// Exclude @everyone (role.id === guild.id), exclude managed roles, and only include roles below the bot's highest role
|
|
const botHighest = guild.members.me.roles.highest.position;
|
|
const manageable = rolesCollection
|
|
.filter(role => role.id !== guild.id && !role.managed && role.position < botHighest)
|
|
.sort((a, b) => b.position - a.position)
|
|
.map(role => ({ id: role.id, name: role.name, color: role.hexColor }));
|
|
res.json(manageable);
|
|
} catch (error) {
|
|
console.error('Error fetching roles:', error);
|
|
res.status(500).json({ success: false, message: 'Internal Server Error' });
|
|
}
|
|
});
|
|
|
|
app.get('/api/servers/:guildId/autorole-settings', (req, res) => {
|
|
const { guildId } = req.params;
|
|
const db = readDb();
|
|
const settings = db[guildId] || {};
|
|
const autoroleSettings = settings.autorole || { enabled: false, roleId: '' };
|
|
res.json(autoroleSettings);
|
|
});
|
|
|
|
app.post('/api/servers/:guildId/autorole-settings', (req, res) => {
|
|
const { guildId } = req.params;
|
|
const { enabled, roleId } = req.body;
|
|
const db = readDb();
|
|
|
|
if (!db[guildId]) {
|
|
db[guildId] = {};
|
|
}
|
|
|
|
db[guildId].autorole = { enabled, roleId };
|
|
writeDb(db);
|
|
res.json({ success: true });
|
|
});
|
|
|
|
app.get('/', (req, res) => {
|
|
res.send('Hello from the backend!');
|
|
});
|
|
|
|
// Return list of bot commands and per-guild enabled/disabled status
|
|
app.get('/api/servers/:guildId/commands', (req, res) => {
|
|
try {
|
|
const { guildId } = req.params;
|
|
const db = readDb();
|
|
const guildSettings = db[guildId] || {};
|
|
const toggles = guildSettings.commandToggles || {};
|
|
const protectedCommands = ['manage-commands', 'help'];
|
|
|
|
const commands = Array.from(bot.client.commands.values()).map(cmd => {
|
|
const isLocked = protectedCommands.includes(cmd.name);
|
|
const isEnabled = isLocked ? true : (toggles[cmd.name] !== false && cmd.enabled !== false);
|
|
return {
|
|
name: cmd.name,
|
|
description: cmd.description || 'No description.',
|
|
enabled: isEnabled,
|
|
locked: isLocked,
|
|
hasSlashBuilder: !!cmd.builder,
|
|
};
|
|
});
|
|
|
|
res.json(commands);
|
|
} catch (error) {
|
|
console.error('Error returning commands:', error);
|
|
res.status(500).json({ success: false, message: 'Internal Server Error' });
|
|
}
|
|
});
|
|
|
|
const bot = require('../discord-bot');
|
|
|
|
bot.login();
|
|
|
|
app.listen(port, () => {
|
|
console.log(`Server is running on port ${port}`);
|
|
});
|