8.4 DEV 1
Changed JSON to SQLlite Added Suggestion Forums Added /suggestadmin
This commit is contained in:
1 parent
c6db929d12
commit
a05d65099b
40 files changed
+1562
-1522
No files matched your search
+41
-27
@@ -1,12 +1,27 @@
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const Discord = require("discord.js");
|
||||
const { GatewayIntentBits, Partials } = require('discord.js');
|
||||
const yaml = require("js-yaml");
|
||||
const { Command, Event } = require('./Addon.js'); // Adjust the path as needed
|
||||
const { Command, Event } = require('./Addon.js');
|
||||
|
||||
const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8"));
|
||||
const cmdconfig = yaml.load(fs.readFileSync("./Configs/commands.yml", "utf8"));
|
||||
|
||||
function walk(dir, ext = ".js", fileList = []) {
|
||||
const files = fs.readdirSync(dir);
|
||||
for (const file of files) {
|
||||
const full = `${dir}/${file}`;
|
||||
const stat = fs.statSync(full);
|
||||
if (stat.isDirectory()) {
|
||||
walk(full, ext, fileList);
|
||||
} else if (file.endsWith(ext)) {
|
||||
fileList.push(full);
|
||||
}
|
||||
}
|
||||
return fileList;
|
||||
}
|
||||
|
||||
class Client extends Discord.Client {
|
||||
constructor() {
|
||||
super({
|
||||
@@ -23,7 +38,7 @@ class Client extends Discord.Client {
|
||||
}
|
||||
|
||||
async getChannel(channel, guild) {
|
||||
if (!channel) return null; // Add check for undefined channel
|
||||
if (!channel) return null;
|
||||
return guild.channels.cache.find(
|
||||
(c) =>
|
||||
(c.type === Discord.ChannelType.GuildText || c.type === Discord.ChannelType.GuildNews) &&
|
||||
@@ -32,14 +47,14 @@ class Client extends Discord.Client {
|
||||
}
|
||||
|
||||
async getRole(role, guild) {
|
||||
if (!role) return null; // Add check for undefined role
|
||||
if (!role) return null;
|
||||
return guild.roles.cache.find(
|
||||
(r) => r.id === role || (r.name && r.name.toLowerCase() === role.toLowerCase())
|
||||
);
|
||||
}
|
||||
|
||||
async getCategory(category, guild) {
|
||||
if (!category) return null; // Add check for undefined category
|
||||
if (!category) return null;
|
||||
return guild.channels.cache.find(
|
||||
(c) =>
|
||||
c.type === Discord.ChannelType.GuildCategory &&
|
||||
@@ -48,72 +63,75 @@ class Client extends Discord.Client {
|
||||
}
|
||||
|
||||
async start(token) {
|
||||
let tempCommandFiles = fs.readdirSync("./Commands").filter((file) => file.endsWith(".js"));
|
||||
let tempCommandFiles = walk("./Commands");
|
||||
|
||||
if (cmdconfig.Suggestion.Enabled === false) {
|
||||
tempCommandFiles = tempCommandFiles.filter(item => item !== "suggest.js");
|
||||
tempCommandFiles = tempCommandFiles.filter(item => path.basename(item) !== "suggest.js");
|
||||
}
|
||||
|
||||
if (cmdconfig.Suggestion.Enabled === false) {
|
||||
tempCommandFiles = tempCommandFiles.filter(item => path.basename(item) !== "suggestadmin.js");
|
||||
}
|
||||
|
||||
if (cmdconfig.Help.Enabled === false) {
|
||||
tempCommandFiles = tempCommandFiles.filter(item => item !== "help.js");
|
||||
tempCommandFiles = tempCommandFiles.filter(item => path.basename(item) !== "help.js");
|
||||
}
|
||||
|
||||
if (cmdconfig.Info.Enabled === false) {
|
||||
tempCommandFiles = tempCommandFiles.filter(item => item !== "info.js");
|
||||
tempCommandFiles = tempCommandFiles.filter(item => path.basename(item) !== "info.js");
|
||||
}
|
||||
|
||||
if (cmdconfig.OpenTicket.Enabled === false) {
|
||||
tempCommandFiles = tempCommandFiles.filter(item => item !== "ticket.js");
|
||||
tempCommandFiles = tempCommandFiles.filter(item => path.basename(item) !== "ticket.js");
|
||||
}
|
||||
|
||||
if (cmdconfig.CloseTicket.Enabled === false) {
|
||||
tempCommandFiles = tempCommandFiles.filter(item => item !== "close.js");
|
||||
tempCommandFiles = tempCommandFiles.filter(item => path.basename(item) !== "close.js");
|
||||
}
|
||||
|
||||
if (cmdconfig.Embed.Enabled === false) {
|
||||
tempCommandFiles = tempCommandFiles.filter(item => item !== "embed.js");
|
||||
tempCommandFiles = tempCommandFiles.filter(item => path.basename(item) !== "embed.js");
|
||||
}
|
||||
|
||||
if (cmdconfig.Translate.Enabled === false) {
|
||||
tempCommandFiles = tempCommandFiles.filter(item => item !== "translate.js");
|
||||
tempCommandFiles = tempCommandFiles.filter(item => path.basename(item) !== "translate.js");
|
||||
}
|
||||
|
||||
if (cmdconfig.UserInfo.Enabled === false) {
|
||||
tempCommandFiles = tempCommandFiles.filter(item => item !== "userinfo.js");
|
||||
tempCommandFiles = tempCommandFiles.filter(item => path.basename(item) !== "userinfo.js");
|
||||
}
|
||||
|
||||
if (cmdconfig.Ping.Enabled === false) {
|
||||
tempCommandFiles = tempCommandFiles.filter(item => item !== "Ping.js");
|
||||
tempCommandFiles = tempCommandFiles.filter(item => path.basename(item) !== "Ping.js");
|
||||
}
|
||||
|
||||
if (cmdconfig.AddUser.Enabled === false) {
|
||||
tempCommandFiles = tempCommandFiles.filter(item => item !== "addUser.js");
|
||||
tempCommandFiles = tempCommandFiles.filter(item => path.basename(item) !== "addUser.js");
|
||||
}
|
||||
|
||||
if (cmdconfig.RemoveUser.Enabled === false) {
|
||||
tempCommandFiles = tempCommandFiles.filter(item => item !== "removeUser.js");
|
||||
tempCommandFiles = tempCommandFiles.filter(item => path.basename(item) !== "removeUser.js");
|
||||
}
|
||||
|
||||
if (cmdconfig.ForceAddUser.Enabled === false) {
|
||||
tempCommandFiles = tempCommandFiles.filter(item => item !== "forceaddUser.js");
|
||||
tempCommandFiles = tempCommandFiles.filter(item => path.basename(item) !== "forceaddUser.js");
|
||||
}
|
||||
|
||||
if (cmdconfig.Profile.Enabled === false) {
|
||||
tempCommandFiles = tempCommandFiles.filter(item => item !== "profile.js");
|
||||
tempCommandFiles = tempCommandFiles.filter(item => path.basename(item) !== "profile.js");
|
||||
}
|
||||
|
||||
if (cmdconfig.Settings.Enabled === false) {
|
||||
tempCommandFiles = tempCommandFiles.filter(item => item !== "settings.js");
|
||||
tempCommandFiles = tempCommandFiles.filter(item => path.basename(item) !== "settings.js");
|
||||
}
|
||||
|
||||
if (cmdconfig.Mod.Enabled === false) {
|
||||
tempCommandFiles = tempCommandFiles.filter(item => item !== "mod.js");
|
||||
tempCommandFiles = tempCommandFiles.filter(item => path.basename(item) !== "mod.js");
|
||||
}
|
||||
|
||||
const commandFiles = tempCommandFiles;
|
||||
const commands = commandFiles.map((file) => require(`../Commands/${file}`));
|
||||
const commands = commandFiles.map((file) => require(`../${file}`));
|
||||
|
||||
// Load main commands
|
||||
console.log(`\u001b[33m`, "――――――――――――――――――――――――――――――――――――――――――――");
|
||||
|
||||
commands.forEach((cmd) => {
|
||||
@@ -121,7 +139,6 @@ class Client extends Discord.Client {
|
||||
this.commands.set(cmd.name, cmd);
|
||||
});
|
||||
|
||||
// Load addon commands and events
|
||||
console.log(`\u001b[33m`, "▬▬▬▬▬▬▬ Commands ▬▬▬▬▬▬▬");
|
||||
|
||||
if (supportbot.General.Addons.Enabled) {
|
||||
@@ -133,7 +150,6 @@ class Client extends Discord.Client {
|
||||
return addon;
|
||||
});
|
||||
|
||||
// Addons
|
||||
console.log(" ");
|
||||
console.log(`\u001b[33m`, "▬▬▬▬▬▬▬ Addons ▬▬▬▬▬▬▬");
|
||||
|
||||
@@ -163,8 +179,6 @@ class Client extends Discord.Client {
|
||||
console.log(`\u001b[33m`, "▬▬▬▬▬▬▬ Addons ▬▬▬▬▬▬▬");
|
||||
}
|
||||
|
||||
// Register Slash Commands
|
||||
|
||||
this.once("ready", async () => {
|
||||
await this.guilds.cache.first()?.commands.set(this.commands);
|
||||
console.log(
|
||||
@@ -196,4 +210,4 @@ class Client extends Discord.Client {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Client;
|
||||
module.exports = Client;
|
||||
@@ -0,0 +1,227 @@
|
||||
// SupportBot | Emerald Services
|
||||
// Database Structure
|
||||
|
||||
const Database = require("better-sqlite3");
|
||||
const path = require("path");
|
||||
|
||||
const db = new Database(path.join(__dirname, "../Data/supportbot.db"));
|
||||
|
||||
// ----- Core tables -----
|
||||
db.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS suggestions (
|
||||
thread_id TEXT PRIMARY KEY,
|
||||
author_id TEXT,
|
||||
text TEXT,
|
||||
status TEXT DEFAULT 'Created'
|
||||
)
|
||||
`).run();
|
||||
|
||||
db.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS profiles (
|
||||
user_id TEXT PRIMARY KEY,
|
||||
bio TEXT,
|
||||
timezone TEXT,
|
||||
clockedIn INTEGER DEFAULT 0
|
||||
)
|
||||
`).run();
|
||||
|
||||
db.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS tickets (
|
||||
ticket_id TEXT PRIMARY KEY,
|
||||
user_id TEXT,
|
||||
status TEXT DEFAULT 'open',
|
||||
created_at INTEGER,
|
||||
updated_at INTEGER,
|
||||
subject TEXT,
|
||||
description TEXT
|
||||
)
|
||||
`).run();
|
||||
|
||||
try {
|
||||
db.prepare("ALTER TABLE tickets ADD COLUMN voiceChannelId TEXT").run();
|
||||
} catch (e) {
|
||||
if (!String(e).includes("duplicate column name")) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
db.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS ticket_panel (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
message_id TEXT,
|
||||
channel_id TEXT,
|
||||
created_at INTEGER
|
||||
)
|
||||
`).run();
|
||||
|
||||
db.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS ticket_users (
|
||||
ticket_id TEXT,
|
||||
user_id TEXT,
|
||||
PRIMARY KEY(ticket_id, user_id)
|
||||
)
|
||||
`).run();
|
||||
|
||||
/* ---- NEW table for global bot settings ---- */
|
||||
db.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
id INTEGER PRIMARY KEY,
|
||||
data TEXT
|
||||
)
|
||||
`).run();
|
||||
|
||||
module.exports = {
|
||||
// ----- Suggestions -----
|
||||
addSuggestion(threadId, authorId, text) {
|
||||
db.prepare(`
|
||||
INSERT INTO suggestions (thread_id, author_id, text)
|
||||
VALUES (@threadId, @authorId, @text)
|
||||
ON CONFLICT(thread_id) DO NOTHING
|
||||
`).run({ threadId, authorId, text });
|
||||
},
|
||||
|
||||
setSuggestionStatus(threadId, status) {
|
||||
db.prepare(`
|
||||
UPDATE suggestions SET status=@status WHERE thread_id=@threadId
|
||||
`).run({ threadId, status });
|
||||
},
|
||||
|
||||
getSuggestion(threadId) {
|
||||
return db.prepare(`
|
||||
SELECT * FROM suggestions WHERE thread_id=@threadId
|
||||
`).get({ threadId });
|
||||
},
|
||||
|
||||
// ----- Profiles -----
|
||||
getProfile(userId) {
|
||||
const row = db.prepare(`SELECT * FROM profiles WHERE user_id=?`).get(userId);
|
||||
if (!row) {
|
||||
db.prepare(`
|
||||
INSERT INTO profiles (user_id, bio, timezone, clockedIn)
|
||||
VALUES (?, '', '', 0)
|
||||
`).run(userId);
|
||||
return { user_id: userId, bio: "", timezone: "", clockedIn: 0 };
|
||||
}
|
||||
return row;
|
||||
},
|
||||
|
||||
updateProfile(userId, data) {
|
||||
const { bio = "", timezone = "", clockedIn = 0 } = data;
|
||||
db.prepare(`
|
||||
INSERT INTO profiles (user_id, bio, timezone, clockedIn)
|
||||
VALUES (@userId, @bio, @timezone, @clockedIn)
|
||||
ON CONFLICT(user_id) DO UPDATE SET
|
||||
bio = excluded.bio,
|
||||
timezone = excluded.timezone,
|
||||
clockedIn = excluded.clockedIn
|
||||
`).run({ userId, bio, timezone, clockedIn });
|
||||
},
|
||||
|
||||
setClockedIn(userId, value) {
|
||||
db.prepare(`UPDATE profiles SET clockedIn=? WHERE user_id=?`)
|
||||
.run(value ? 1 : 0, userId);
|
||||
},
|
||||
|
||||
// ----- Tickets -----
|
||||
addTicket(ticket) {
|
||||
const now = Date.now();
|
||||
db.prepare(`
|
||||
INSERT INTO tickets (ticket_id, user_id, subject, description, created_at, updated_at)
|
||||
VALUES (@ticket_id, @user_id, @subject, @description, @created_at, @updated_at)
|
||||
ON CONFLICT(ticket_id) DO NOTHING
|
||||
`).run({
|
||||
ticket_id: ticket.id,
|
||||
user_id: ticket.user,
|
||||
subject: ticket.reason || "",
|
||||
description: ticket.description || "",
|
||||
created_at: now,
|
||||
updated_at: now
|
||||
});
|
||||
},
|
||||
|
||||
updateTicketVoice(ticketId, voiceChannelId) {
|
||||
db.prepare(`
|
||||
UPDATE tickets SET voiceChannelId=@voiceChannelId, updated_at=@updatedAt WHERE ticket_id=@ticketId
|
||||
`).run({ ticketId, voiceChannelId, updatedAt: Date.now() });
|
||||
},
|
||||
|
||||
getTicketVoice(ticketId) {
|
||||
return db.prepare(`SELECT voiceChannelId FROM tickets WHERE ticket_id=?`).get(ticketId);
|
||||
},
|
||||
|
||||
deleteTicketVoice(ticketId) {
|
||||
db.prepare(`
|
||||
UPDATE tickets SET voiceChannelId=NULL, updated_at=@updatedAt WHERE ticket_id=@ticketId
|
||||
`).run({ ticketId, updatedAt: Date.now() });
|
||||
},
|
||||
|
||||
updateTicketStatus(ticketId, status) {
|
||||
db.prepare(`
|
||||
UPDATE tickets SET status=@status, updated_at=@updatedAt WHERE ticket_id=@ticketId
|
||||
`).run({ status, updatedAt: Date.now(), ticketId });
|
||||
},
|
||||
|
||||
getTicket(ticketId) {
|
||||
return db.prepare(`
|
||||
SELECT * FROM tickets WHERE ticket_id=@ticketId
|
||||
`).get({ ticketId });
|
||||
},
|
||||
|
||||
getAllTickets() {
|
||||
return db.prepare(`SELECT * FROM tickets`).all();
|
||||
},
|
||||
|
||||
saveTicketPanel(messageId, channelId) {
|
||||
db.prepare(`
|
||||
INSERT INTO ticket_panel (message_id, channel_id, created_at)
|
||||
VALUES (@messageId, @channelId, @createdAt)
|
||||
`).run({ messageId, channelId, createdAt: Date.now() });
|
||||
},
|
||||
|
||||
getTicketPanel() {
|
||||
return db.prepare(`
|
||||
SELECT * FROM ticket_panel ORDER BY id DESC LIMIT 1
|
||||
`).get();
|
||||
},
|
||||
|
||||
// ----- Ticket participants -----
|
||||
addUserToTicket(ticketId, userId) {
|
||||
db.prepare(`
|
||||
INSERT INTO ticket_users (ticket_id, user_id)
|
||||
VALUES (?, ?)
|
||||
ON CONFLICT(ticket_id, user_id) DO NOTHING
|
||||
`).run(ticketId, userId);
|
||||
},
|
||||
|
||||
removeUserFromTicket(ticketId, userId) {
|
||||
db.prepare(`
|
||||
DELETE FROM ticket_users WHERE ticket_id=? AND user_id=?
|
||||
`).run(ticketId, userId);
|
||||
},
|
||||
|
||||
getTicketUsers(ticketId) {
|
||||
return db.prepare(`
|
||||
SELECT user_id FROM ticket_users WHERE ticket_id=?
|
||||
`).all(ticketId).map(r => r.user_id);
|
||||
},
|
||||
|
||||
// ----- Global Settings -----
|
||||
getSettings() {
|
||||
const row = db.prepare(`SELECT data FROM settings WHERE id=1`).get();
|
||||
if (!row) return {};
|
||||
try {
|
||||
return JSON.parse(row.data);
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
|
||||
saveSettings(obj) {
|
||||
const data = JSON.stringify(obj);
|
||||
db.prepare(`
|
||||
INSERT INTO settings (id, data)
|
||||
VALUES (1, @data)
|
||||
ON CONFLICT(id) DO UPDATE SET data = excluded.data
|
||||
`).run({ data });
|
||||
}
|
||||
};
|
||||
@@ -1,5 +1,6 @@
|
||||
// SupportBot | Emerald Services
|
||||
// Event Structure
|
||||
|
||||
class Event {
|
||||
constructor(event, run) {
|
||||
this.event = event;
|
||||
|
||||
+12
-29
@@ -1,47 +1,30 @@
|
||||
// SupportBot | Emerald Services
|
||||
// Ticket ID Structure
|
||||
|
||||
const fs = require("fs");
|
||||
const db = require("./Database")
|
||||
|
||||
class TicketNumberID {
|
||||
static async pad() {
|
||||
let num = await this.get();
|
||||
let n = num + "";
|
||||
await this.set(num + 1);
|
||||
return n.length >= 4 ? n : new Array(4 - n.length + 1).join("0") + n;
|
||||
let num = await this.get()
|
||||
let n = num + ""
|
||||
await this.set(num + 1)
|
||||
return n.length >= 4 ? n : new Array(4 - n.length + 1).join("0") + n
|
||||
}
|
||||
|
||||
static async get() {
|
||||
let ticketnumberID = await JSON.parse(
|
||||
fs.readFileSync("./Data/ticket-panel-id.json", "utf8")
|
||||
);
|
||||
if (!ticketnumberID.id) {
|
||||
return this.set(0);
|
||||
} else {
|
||||
return ticketnumberID.id;
|
||||
}
|
||||
const row = db.getTicketPanel()
|
||||
if (!row) return await this.set(0)
|
||||
return row.id
|
||||
}
|
||||
|
||||
static async set(value) {
|
||||
let ticketnumberID = await JSON.parse(
|
||||
fs.readFileSync("./Data/ticket-panel-id.json", "utf8")
|
||||
);
|
||||
|
||||
ticketnumberID.id = value;
|
||||
fs.writeFileSync(
|
||||
"./Data/ticket-panel-id.json",
|
||||
JSON.stringify(ticketnumberID, null, 4),
|
||||
(err) => {
|
||||
if (err) console.error(err);
|
||||
}
|
||||
);
|
||||
|
||||
return value;
|
||||
db.saveTicketPanel(`panel-${value}`, "none")
|
||||
return value
|
||||
}
|
||||
|
||||
static async reset() {
|
||||
return await this.set(0);
|
||||
return await this.set(0)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TicketNumberID;
|
||||
module.exports = TicketNumberID
|
||||
Reference in new issue
Block a user