diff --git a/Addons/addon.js b/Addons/addon.js
deleted file mode 100644
index 7609fd7..0000000
--- a/Addons/addon.js
+++ /dev/null
@@ -1,26 +0,0 @@
-const Discord = require("discord.js");
-const fs = require("fs");
-const yaml = require("js-yaml");
-const { Command } = require('../Structures/Addon.js'); // Adjust the path as needed
-const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8"));
-
-module.exports = new Command({
- name: "addon",
- description: "This is a sample addon!",
- options: [],
- permissions: ["Administrator"],
-
- async run(interaction) {
- let disableCommand = true;
-
- const PingEmbed = new Discord.EmbedBuilder()
- .setDescription(
- `This is a sample addon.\n\nPong! \`${interaction.client.ws.ping} ms\``
- )
- .setColor(supportbot.Embed.Colours.General);
-
- interaction.reply({
- embeds: [PingEmbed],
- });
- },
- });
\ No newline at end of file
diff --git a/Commands/Tickets/close.js b/Commands/Tickets/close.js
index b56ef40..8ebf8e3 100644
--- a/Commands/Tickets/close.js
+++ b/Commands/Tickets/close.js
@@ -288,119 +288,154 @@ function parseMarkdown(content) {
function createTranscriptHTML(ticket, reason) {
return `
-
-
-
-
-
-
Ticket Transcript
-
Channel: ${ticket.name}
-
Ticket ID: ${ticket.id}
-
Message Count: ${ticket.messages.length}
-
Close Reason: ${reason}
-
-
-
- ${ticket.messages.map(msg => `
-
-
-
- ${parseMarkdown(msg.content)}
-
- ${msg.embeds.map(embed => `
-
- ${embed.title ? `
${embed.title}
` : ''}
- ${embed.description ? `
${embed.description}
` : ''}
- ${embed.fields.map(field => `
-
-
${field.name}:
-
${field.value}
-
- `).join('')}
-
- `).join('')}
-
- ${msg.attachments.map(att => `
-
- š ${att.name}
-
- `).join('')}
-
-
- `).join('')}
-
+
+
+
+
+
+
+
+
+
+
+
Ticket Transcript
+
+
Channel: ${ticket.name}
+
Ticket ID: ${ticket.id}
+
Message Count: ${ticket.messages.length}
+
Close Reason: ${reason}
-
-
+
+
+ ${ticket.messages.map(msg => `
+
+
+
+ ${parseMarkdown(msg.content)}
+
+ ${msg.embeds.map(embed => `
+
+ ${embed.title ? `
${embed.title}
` : ''}
+ ${embed.description ? `
${embed.description}
` : ''}
+ ${embed.fields.map(field => `
+
+
${field.name}:
+
${field.value}
+
+ `).join('')}
+
+ `).join('')}
+
+ ${msg.attachments.map(att => `
+
+ š ${att.name}
+
+ `).join('')}
+
+
+ `).join('')}
+
+
+
+
`;
}
diff --git a/Configs/messages.yml b/Configs/messages.yml
index 3253913..a728c11 100644
--- a/Configs/messages.yml
+++ b/Configs/messages.yml
@@ -22,27 +22,74 @@ Info:
Description: "SupportBot is an open-sourced support system for discord. It's completely free to use with high amounts of customization to match your own brand."
Button: "Visit Site"
URL: "https://docs.emeraldsrv.com"
- Colour: "#f74343"
+ Colour: "#45b463"
# ----------------------------
# Welcome/Leave Messages
# ----------------------------
Welcome:
- Embed:
- Colour: "#f74343"
- Title: "Welcome to ServerName"
- Message: ":smile: %joined_user% has just landed!"
- Thumbnail: "BOT"
+ Enabled: true
+ LayoutStyle: "modern"
+ # Available Layout Styles
+ # "modern" - For the new Discord v2 components
+ # "classic" - Use the classic Discord look.
- ImageEnabled: false
- ImageURL: "https://animagelink.png/"
+ Embed:
+ Colour: "#45b463"
+ Title: "Welcome to ServerName"
+ Message: ":smile: %joined_user% has just landed!\n\nšØ **Server Rules:** <#1202667199853232129>"
+ Icon:
+ Mode: "USER" # USER | BOT | CUSTOM
+ CustomURL: "https://example.com/custom.png"
+ Image:
+ Enabled: false
+ URL: "https://example.com/banner.png"
+ Buttons:
+ Enabled: true
+ List:
+ - label: "BuiltByBit"
+ style: "Link"
+ url: "https://your-website.com/how-to-play-java"
+ emoji: "āØļø"
+ - label: "GitHub"
+ style: "Link"
+ url: "https://your-website.com/how-to-play-bedrock"
+ emoji: "š¾"
+ - label: "Tebex"
+ style: "Link"
+ url: "https://your-store.tebex.io/"
+ emoji: "š"
+
+ Modern:
+ Colour: "#45b463"
+ Title: "**Welcome to ServerName**"
+ Body: ":smile: %joined_user% has just landed!\n\nšØ **Server Rules:** <#1202667199853232129>"
+ Icon:
+ Mode: "BOT" # USER | BOT | CUSTOM
+ CustomURL: "https://example.com/custom-icon.png"
+ Image:
+ Enabled: false
+ URL: "https://example.com/banner.png"
+ Buttons:
+ - label: "BuiltByBit"
+ style: "Link"
+ url: "https://your-website.com/how-to-play-java"
+ emoji: "āØļø"
+ - label: "GitHub"
+ style: "Link"
+ url: "https://your-website.com/how-to-play-bedrock"
+ emoji: "š¾"
+ - label: "Tebex"
+ style: "Link"
+ url: "https://your-store.tebex.io/"
+ emoji: "š"
Leave:
Embed:
Colour: "#f74343"
Title: "Goodbye!"
- Message: ":slight_frown: %joined_user% has recently dropped out!"
+ Message: ":slight_frown: %left_user% has recently dropped out!"
Thumbnail: "BOT"
ImageEnabled: false
diff --git a/Configs/supportbot.yml b/Configs/supportbot.yml
index d19a3e1..3498630 100644
--- a/Configs/supportbot.yml
+++ b/Configs/supportbot.yml
@@ -8,12 +8,12 @@
# Installed with MIT License
#
# Discord Support: https://discord.gg/emeraldsrv
-# Official Documentation: https://docs.emeraldsrv.com
-# Addons Marketplace: https://community.emeraldsrv.com
+# Official Documentation: https://docs.emeraldsrv.dev
+# Addons Marketplace: https://community.emeraldsrv.dev
#
# SupportBot Configuration (supportbot.yml)
-SupportBot_Version: "v8.4-DEV-1"
+SupportBot_Version: "v8.4-DEV-2"
# -------------------------
# General
@@ -21,7 +21,7 @@ SupportBot_Version: "v8.4-DEV-1"
General:
Name: "SupportBot"
- Token: "BOT_TOKEN"
+ Token: ""
Addons:
Enabled: true
@@ -144,7 +144,7 @@ VoiceTickets:
Category: "1419062819688550460"
Ticket:
- TicketType: "channels"
+ TicketType: "threads"
# Available TicketTypes:
# channels - Tickets will be created as channels in the TicketChannelsCategory
diff --git a/Configs/ticket-panel.yml b/Configs/ticket-panel.yml
index 5cb7f3d..c8e6b5b 100644
--- a/Configs/ticket-panel.yml
+++ b/Configs/ticket-panel.yml
@@ -19,6 +19,8 @@
Panel: true
+LayoutStyle: modern
+
# ----------------------------------------
# Ticket Panel Message Configuration #2b2d31
# ----------------------------------------
diff --git a/Data/supportbot.db b/Data/supportbot.db
deleted file mode 100644
index 672dfb3..0000000
Binary files a/Data/supportbot.db and /dev/null differ
diff --git a/Events/guildMemberAdd.js b/Events/guildMemberAdd.js
index f0b97fd..58692a7 100644
--- a/Events/guildMemberAdd.js
+++ b/Events/guildMemberAdd.js
@@ -1,56 +1,151 @@
-
-const Discord = require('discord.js');
+const {
+ EmbedBuilder,
+ ActionRowBuilder,
+ ButtonBuilder,
+ ButtonStyle,
+ MessageFlags,
+ ContainerBuilder,
+ TextDisplayBuilder,
+ SectionBuilder,
+ ThumbnailBuilder,
+ AttachmentBuilder
+} = require("discord.js");
const fs = require("fs");
-const Event = require("../Structures/Event.js");
const yaml = require("js-yaml");
+const Event = require("../Structures/Event.js");
const supportbot = yaml.load(
fs.readFileSync("./Configs/supportbot.yml", "utf8")
);
-
-const cmdconfig = yaml.load(
- fs.readFileSync("./Configs/commands.yml", "utf8")
-);
-
const msgconfig = yaml.load(
fs.readFileSync("./Configs/messages.yml", "utf8")
);
-module.exports = new Event("guildMemberAdd", async (client, member, interaction, guild) => {
+function getWelcomeThumbnail(client, member, iconCfg) {
+ switch ((iconCfg?.Mode || "").toUpperCase()) {
+ case "USER":
+ return member.user.displayAvatarURL();
+ case "BOT":
+ return client.user.displayAvatarURL();
+ case "CUSTOM":
+ return iconCfg.CustomURL;
+ default:
+ return null;
+ }
+}
- if (supportbot.Welcome.Enabled) {
- const WelcomeChannel = member.guild.channels.cache.get(supportbot.Welcome.Channel) ||
- member.guild.channels.cache.find(channel => channel.name === supportbot.Welcome.Channel);
+function buildModernComponents(client, member) {
+ const container = new ContainerBuilder().setAccentColor(
+ parseInt(msgconfig.Welcome.Modern.Colour.replace("#", ""), 16)
+ );
- const WelcomeEmbed = new Discord.EmbedBuilder()
- .setColor(msgconfig.Welcome.Embed.Colour)
- .setTitle(msgconfig.Welcome.Embed.Title)
- .setDescription(msgconfig.Welcome.Embed.Message.replace(/%joined_user%/g, member.user))
- .setTimestamp();
-
- if (msgconfig.Welcome.Embed.Thumbnail === "BOT") {
- WelcomeEmbed.setThumbnail(client.user.displayAvatarURL())
- } else if (msgconfig.Welcome.Embed.Thumbnail === "USER") {
- WelcomeEmbed.setThumbnail(member.user.displayAvatarURL())
- }
-
- if (msgconfig.Welcome.Embed.ImageEnabled) {
- WelcomeEmbed.setImage(msgconfig.Welcome.Embed.ImageURL)
- }
-
- if (WelcomeChannel) {
- WelcomeChannel.send({ embeds: [WelcomeEmbed] });
- }
-
- if (supportbot.Roles.AutoRole.Enabled) {
- const role = member.guild.roles.cache.get(supportbot.Roles.AutoRole.Role) ||
- member.guild.roles.cache.find(role => role.name === supportbot.Roles.AutoRole.Role);
- if (role) {
- member.roles.add(role);
- }
- }
-
- console.log(`\u001b[32m`, `[+]`, `\u001b[33m`, `${member.user.username} joined the server!`);
+ const section = new SectionBuilder().addTextDisplayComponents(
+ new TextDisplayBuilder().setContent(
+ msgconfig.Welcome.Modern.Title.replace(/%joined_user%/g, member.user)
+ ),
+ new TextDisplayBuilder().setContent(
+ msgconfig.Welcome.Modern.Body.replace(/%joined_user%/g, member.user)
+ )
+ );
+
+ const thumbUrl = getWelcomeThumbnail(client, member, msgconfig.Welcome.Modern.Icon);
+ if (thumbUrl) {
+ section.setThumbnailAccessory(
+ new ThumbnailBuilder()
+ .setURL(thumbUrl)
+ );
}
-});
\ No newline at end of file
+ container.addSectionComponents(section);
+
+ if (msgconfig.Welcome.Modern.Image?.Enabled && msgconfig.Welcome.Modern.Image.URL) {
+ container.addTextDisplayComponents(
+ new TextDisplayBuilder().setContent(
+ ``
+ )
+ );
+ }
+
+ if (Array.isArray(msgconfig.Welcome.Modern.Buttons)) {
+ const row = new ActionRowBuilder();
+ msgconfig.Welcome.Modern.Buttons.slice(0, 5).forEach(b => {
+ const btn = new ButtonBuilder()
+ .setLabel(b.label)
+ .setStyle(ButtonStyle[b.style])
+ .setEmoji(b.emoji || null);
+ if (b.style === "Link") btn.setURL(b.url);
+ else if (b.customId) btn.setCustomId(b.customId);
+ row.addComponents(btn);
+ });
+
+ container.addActionRowComponents(row);
+ }
+
+ return [container];
+}
+
+module.exports = new Event("guildMemberAdd", async (client, member) => {
+ if (!supportbot.Welcome.Enabled) return;
+
+ const WelcomeChannel =
+ member.guild.channels.cache.get(supportbot.Welcome.Channel) ||
+ member.guild.channels.cache.find(c => c.name === supportbot.Welcome.Channel);
+ if (!WelcomeChannel) return;
+
+ const style = (msgconfig.Welcome.LayoutStyle || "classic").toLowerCase();
+
+ if (style === "classic") {
+ const WelcomeEmbed = new EmbedBuilder()
+ .setColor(msgconfig.Welcome.Embed.Colour)
+ .setTitle(msgconfig.Welcome.Embed.Title || null)
+ .setDescription(
+ msgconfig.Welcome.Embed.Message.replace(/%joined_user%/g, member.user)
+ )
+ .setTimestamp();
+
+ const thumb = getWelcomeThumbnail(client, member, msgconfig.Welcome.Embed.Icon);
+ if (thumb) WelcomeEmbed.setThumbnail(thumb);
+
+ if (msgconfig.Welcome.Embed.Image?.Enabled && msgconfig.Welcome.Embed.Image.URL) {
+ WelcomeEmbed.setImage(msgconfig.Welcome.Embed.Image.URL);
+ }
+
+ const components = [];
+ if (
+ msgconfig.Welcome.Embed.Buttons?.Enabled &&
+ Array.isArray(msgconfig.Welcome.Embed.Buttons.List)
+ ) {
+ const row = new ActionRowBuilder();
+ msgconfig.Welcome.Embed.Buttons.List.slice(0, 5).forEach(b => {
+ const btn = new ButtonBuilder()
+ .setLabel(b.label)
+ .setStyle(ButtonStyle[b.style])
+ .setEmoji(b.emoji || null);
+ if (b.style === "Link") btn.setURL(b.url);
+ else if (b.customId) btn.setCustomId(b.customId);
+ row.addComponents(btn);
+ });
+ components.push(row);
+ }
+
+ await WelcomeChannel.send({ embeds: [WelcomeEmbed], components });
+ } else if (style === "modern") {
+ const components = buildModernComponents(client, member);
+ if (components.length > 0) {
+ await WelcomeChannel.send({
+ components,
+ flags: MessageFlags.IsComponentsV2
+ });
+ }
+ }
+
+ if (supportbot.Roles.AutoRole.Enabled) {
+ const role =
+ member.guild.roles.cache.get(supportbot.Roles.AutoRole.Role) ||
+ member.guild.roles.cache.find(r => r.name === supportbot.Roles.AutoRole.Role);
+ if (role) await member.roles.add(role);
+ }
+
+ console.log("\u001b[32m", "[+]", "\u001b[33m", `${member.user.username} joined the server!`);
+
+});
diff --git a/Events/guildMemberRemove.js b/Events/guildMemberRemove.js
index 3004af7..f4d1bb2 100644
--- a/Events/guildMemberRemove.js
+++ b/Events/guildMemberRemove.js
@@ -1,50 +1,40 @@
-
-const Discord = require('discord.js');
+const { EmbedBuilder } = require("discord.js");
const fs = require("fs");
-const Event = require("../Structures/Event.js");
const yaml = require("js-yaml");
+const Event = require("../Structures/Event.js");
-const supportbot = yaml.load(
- fs.readFileSync("./Configs/supportbot.yml", "utf8")
-);
-
-const cmdconfig = yaml.load(
- fs.readFileSync("./Configs/commands.yml", "utf8")
-);
-
-const msgconfig = yaml.load(
- fs.readFileSync("./Configs/messages.yml", "utf8")
-);
+const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8"));
+const msgconfig = yaml.load(fs.readFileSync("./Configs/messages.yml", "utf8"));
-module.exports = new Event("guildMemberRemove", async (client, member, interaction, guild) => {
+module.exports = new Event("guildMemberRemove", async (client, member) => {
- if (supportbot.Leave.Enabled) {
- const LeaveChannel = member.guild.channels.cache.get(supportbot.Leave.Channel) ||
- member.guild.channels.cache.find(channel => channel.name === supportbot.Leave.Channel);
+ if (!supportbot.Leave || !supportbot.Leave.Enabled) return;
- const LeaveEmbed = new Discord.EmbedBuilder()
- .setColor(msgconfig.Leave.Embed.Colour)
- .setTitle(msgconfig.Leave.Embed.Title)
- .setDescription(msgconfig.Leave.Embed.Message.replace(/%left_user%/g, member.user))
- .setTimestamp();
-
- if (msgconfig.Leave.Embed.Thumbnail === "BOT") {
- LeaveEmbed.setThumbnail(client.user.displayAvatarURL());
- } else if (msgconfig.Leave.Embed.Thumbnail === "USER") {
- LeaveEmbed.setThumbnail(member.user.displayAvatarURL());
- }
-
- if (msgconfig.Leave.Embed.ImageEnabled) {
- LeaveEmbed.setImage(msgconfig.Leave.Embed.ImageURL);
- }
-
- if (LeaveChannel) {
- LeaveChannel.send({
- embeds: [LeaveEmbed]
- });
- }
-
- console.log(`\u001b[31m`, `[-]`, `\u001b[33m`, `${member.user.username} left the server!`);
+ const leaveChannel =
+ member.guild.channels.cache.get(supportbot.Leave.Channel) ||
+ member.guild.channels.cache.find(c => c.name === supportbot.Leave.Channel);
+
+ if (!leaveChannel) return;
+
+ const leaveEmbed = new EmbedBuilder()
+ .setColor(msgconfig.Leave.Embed.Colour)
+ .setTitle(msgconfig.Leave.Embed.Title)
+ .setDescription(
+ msgconfig.Leave.Embed.Message.replace(/%left_user%/g, member.user.toString())
+ )
+ .setTimestamp();
+
+ if (msgconfig.Leave.Embed.Thumbnail === "BOT") {
+ leaveEmbed.setThumbnail(client.user.displayAvatarURL());
+ } else if (msgconfig.Leave.Embed.Thumbnail === "USER") {
+ leaveEmbed.setThumbnail(member.user.displayAvatarURL());
}
-});
\ No newline at end of file
+ if (msgconfig.Leave.Embed.ImageEnabled) {
+ leaveEmbed.setImage(msgconfig.Leave.Embed.ImageURL);
+ }
+
+ await leaveChannel.send({ embeds: [leaveEmbed] });
+
+ console.log(`[-] ${member.user.tag} left the server`);
+});
diff --git a/Events/interactionCreate.js b/Events/interactionCreate.js
index 2346eeb..a52dd32 100644
--- a/Events/interactionCreate.js
+++ b/Events/interactionCreate.js
@@ -25,7 +25,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
if (!command)
return interaction.reply({
embeds: [NotValid],
- ephemeral: true,
+ flags: Discord.MessageFlags.Ephemeral,
});
const permission = interaction.member.permissions.has(command.permissions);
@@ -39,7 +39,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
if (!permission)
return interaction.reply({
embeds: [ValidPerms],
- ephemeral: true,
+ flags: Discord.MessageFlags.Ephemeral,
});
try {
@@ -66,7 +66,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
console.error("Error executing command:", error);
await interaction.reply({
content: "An error occurred while executing the command.",
- ephemeral: true,
+ flags: Discord.MessageFlags.Ephemeral,
});
}
}
@@ -97,7 +97,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
if (!ticketChannel) {
return interaction.reply({
content: "Ticket channel not found.",
- ephemeral: true,
+ flags: Discord.MessageFlags.Ephemeral,
});
}
try {
@@ -107,16 +107,17 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
.setColor(supportbot.Embed.Colours.Success);
return interaction.reply({
embeds: [renamedsuccess],
- ephemeral: true,
+ flags: Discord.MessageFlags.Ephemeral,
});
} catch (error) {
console.error("Error renaming the ticket:", error);
return interaction.reply({
content: "There was an error renaming the ticket.",
- ephemeral: true,
+ flags: Discord.MessageFlags.Ephemeral,
});
}
}
+
if (interaction.isStringSelectMenu()) {
if (interaction.customId === "ticketcontrolpanel") {
const selectedOption = interaction.values[0];
@@ -151,7 +152,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
if (!VCcategory) {
return interaction.reply({
content: "ā ļø The Support VC category does not exist!",
- ephemeral: true,
+ flags: Discord.MessageFlags.Ephemeral,
});
}
@@ -343,7 +344,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
.setColor(supportbot.Embed.Colours.Success);
await interaction.reply({
embeds: [successEmbed],
- ephemeral: true,
+ flags: Discord.MessageFlags.Ephemeral,
});
} else {
const errorEmbed = new Discord.EmbedBuilder()
@@ -351,7 +352,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
.setColor(supportbot.Embed.Colours.Error);
await interaction.reply({
embeds: [errorEmbed],
- ephemeral: true,
+ flags: Discord.MessageFlags.Ephemeral,
});
}
} catch (error) {
@@ -361,7 +362,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
.setColor(supportbot.Embed.Colours.Error);
await interaction.reply({
embeds: [errorEmbed],
- ephemeral: true,
+ flags: Discord.MessageFlags.Ephemeral,
});
}
} else {
@@ -370,7 +371,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
.setColor(supportbot.Embed.Colours.Warn);
await interaction.reply({
embeds: [errorEmbed],
- ephemeral: true,
+ flags: Discord.MessageFlags.Ephemeral,
});
}
}
@@ -462,7 +463,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
console.error("Error executing the ticket command:", error);
await interaction.reply({
content: "An error occurred while creating the ticket.",
- ephemeral: true,
+ flags: Discord.MessageFlags.Ephemeral,
});
}
}
@@ -500,7 +501,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
if (!ticketChannel) {
return interaction.reply({
content: "Ticket channel not found.",
- ephemeral: true,
+ flags: Discord.MessageFlags.Ephemeral,
});
}
@@ -675,7 +676,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
await interaction.reply({
embeds: [embed],
- ephemeral: true,
+ flags: Discord.MessageFlags.Ephemeral,
});
}
@@ -725,7 +726,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
console.error("Failed to update profile data: ", error);
await interaction.reply({
content: "There was an error while updating your profile. Please try again later.",
- ephemeral: true,
+ flags: Discord.MessageFlags.Ephemeral,
});
}
}
diff --git a/Events/messageDelete.js b/Events/messageDelete.js
index 49807f7..5490f9c 100644
--- a/Events/messageDelete.js
+++ b/Events/messageDelete.js
@@ -3,41 +3,34 @@ const fs = require("fs");
const yaml = require("js-yaml");
const Event = require("../Structures/Event.js");
-// Load the configuration files
const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8"));
const msgconfig = yaml.load(fs.readFileSync("./Configs/messages.yml", "utf8"));
module.exports = new Event("messageDelete", async (client, message) => {
+ if (!message.guild) return;
- // Check if the message is from a guild and not from a bot
- if (!message.guild || message.author.bot) return;
+ const author = message.author || (message.partial ? await message.fetch().then(m => m.author).catch(() => null) : null);
+ if (!author || author.bot) return;
+
+ const content = message.content || (message.attachments.size > 0 ? "Contains attachment(s)" : "*No content*");
- // Get the delete log channel either by ID or by name
const deleteLogChannel = message.guild.channels.cache.get(supportbot.MessageDelete.Channel) ||
- message.guild.channels.cache.find(channel => channel.name === supportbot.MessageDelete.Channel);
+ message.guild.channels.cache.find(c => c.name === supportbot.MessageDelete.Channel);
- // Create the embed for the deleted message
const deletedMessageEmbed = new EmbedBuilder()
.setColor(supportbot.MessageDelete.Colour)
.setTitle("Message Deleted")
- .setDescription(`> **Channel:** <#${message.channel.id}>\n> **Message ID** [${message.id}](https://discord.com/channels/${message.guild.id}/${message.channel.id}/${message.id})\n> **Message author:** ${message.author.tag} (${message.author.id})\n> **Message Crated:**
`)
- .addFields(
- { name: 'Message', value: message.content || '*No content*', inline: false }
- )
- .setThumbnail(message.author.displayAvatarURL())
+ .setDescription(`> **Channel:** <#${message.channel.id}>\n> **Message ID:** ${message.id}\n> **Message author:** ${author.tag} (${author.id})\n> **Message Created:** `)
+ .addFields({ name: "Deleted Content", value: content, inline: false })
+ .setThumbnail(author.displayAvatarURL())
.setTimestamp();
- // If the message contains an attachment, add it to the embed
if (message.attachments.size > 0) {
const attachment = message.attachments.first();
- deletedMessageEmbed.addFields({ name: 'Attachment', value: `[${attachment.name}](${attachment.proxyURL})` });
+ deletedMessageEmbed.addFields({ name: "Attachment", value: `[${attachment.name}](${attachment.proxyURL})` });
}
- // Send the embed to the delete log channel if the channel is found
if (deleteLogChannel) {
- deleteLogChannel.send({
- embeds: [deletedMessageEmbed]
- });
+ deleteLogChannel.send({ embeds: [deletedMessageEmbed] });
}
});
-
diff --git a/Events/ready.js b/Events/ready.js
index b4d575d..6921a17 100644
--- a/Events/ready.js
+++ b/Events/ready.js
@@ -125,4 +125,4 @@ module.exports = new Event("clientReady", async (client) => {
setActivity(client, supportbot?.Activity?.Type, supportbot?.Activity?.Status);
await logStartup(client);
await checkConfigs(client);
-});
+});
\ No newline at end of file
diff --git a/LICENSE.md b/LICENSE.md
index 0899fec..801ae42 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2024 Emerald Services
+Copyright (c) 2025 Emerald Services
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/Structures/Client.js b/Structures/Client.js
index a1388fe..e3ac602 100644
--- a/Structures/Client.js
+++ b/Structures/Client.js
@@ -8,6 +8,7 @@ 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) {
@@ -179,7 +180,7 @@ class Client extends Discord.Client {
console.log(`\u001b[33m`, "ā¬ā¬ā¬ā¬ā¬ā¬ā¬ Addons ā¬ā¬ā¬ā¬ā¬ā¬ā¬");
}
- this.once("ready", async () => {
+ this.once("clientReady", async () => {
await this.guilds.cache.first()?.commands.set(this.commands);
console.log(
"\u001b[32m",
diff --git a/Structures/Database.js b/Structures/Database.js
index 7134056..9b10848 100644
--- a/Structures/Database.js
+++ b/Structures/Database.js
@@ -6,7 +6,6 @@ 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,
@@ -62,7 +61,6 @@ db.prepare(`
)
`).run();
-/* ---- NEW table for global bot settings ---- */
db.prepare(`
CREATE TABLE IF NOT EXISTS settings (
id INTEGER PRIMARY KEY,
@@ -71,7 +69,6 @@ db.prepare(`
`).run();
module.exports = {
- // ----- Suggestions -----
addSuggestion(threadId, authorId, text) {
db.prepare(`
INSERT INTO suggestions (thread_id, author_id, text)
@@ -122,7 +119,6 @@ module.exports = {
.run(value ? 1 : 0, userId);
},
- // ----- Tickets -----
addTicket(ticket) {
const now = Date.now();
db.prepare(`
@@ -184,7 +180,6 @@ module.exports = {
`).get();
},
- // ----- Ticket participants -----
addUserToTicket(ticketId, userId) {
db.prepare(`
INSERT INTO ticket_users (ticket_id, user_id)
@@ -205,7 +200,6 @@ module.exports = {
`).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 {};
diff --git a/index.js b/index.js
index 7343fe9..7690bda 100644
--- a/index.js
+++ b/index.js
@@ -8,9 +8,10 @@
// Installed with MIT License
//
// Discord Support: https://emeraldsrv.dev/discord
-// Community Resources: https://emeraldsrv.dev/resources
+// Community Resources: https://community.emeraldsrv.dev
const fs = require("fs");
+const path = require("path");
const yaml = require("js-yaml");
const supportbot = yaml.load(
@@ -24,13 +25,51 @@ const client = new Client({
client.start(supportbot.General.Token);
-
-
-
-
-
-
-
+// SupportBot - New Logging System
+
+const logTypes = ["Output", "Warn", "Error"];
+
+if (!fs.existsSync("./Logs")) {
+ fs.mkdirSync("./Logs");
+}
+logTypes.forEach((type) => {
+ const dir = `./Logs/${type}`;
+ if (!fs.existsSync(dir)) {
+ fs.mkdirSync(dir);
+ }
+});
+
+function logToFile(type, data) {
+ const date = new Date().toISOString().split("T")[0];
+ const file = path.join(`./logs/${type}`, `${type}-${date}.log`);
+ fs.appendFileSync(file, `[${new Date().toISOString()}] ${data}\n`);
+}
+
+const origLog = console.log;
+console.log = (...args) => {
+ origLog(...args);
+ logToFile("output", args.join(" "));
+};
+
+const origWarn = console.warn;
+console.warn = (...args) => {
+ origWarn(...args);
+ logToFile("warn", args.join(" "));
+};
+
+const origError = console.error;
+console.error = (...args) => {
+ origError(...args);
+ logToFile("error", args.join(" "));
+};
+
+process.on("unhandledRejection", (reason) => {
+ console.error("Unhandled Rejection:", reason);
+});
+
+process.on("uncaughtException", (err) => {
+ console.error("Uncaught Exception:", err);
+});
diff --git a/package.json b/package.json
index af2d866..eea17b1 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "supportbot",
- "version": "8.3",
+ "version": "8.4",
"description": "SupportBot is an open-sourced support system for discord. It's completely free to use with high amounts of customization to match your own brand.",
"main": "index.js",
"scripts": {
@@ -18,8 +18,6 @@
},
"homepage": "https://community.emeraldsrv.dev",
"dependencies": {
- "@paypal/checkout-server-sdk": "^1.0.3",
- "@vitalets/google-translate-api": "^8.0.0",
"axios": "^1.7.2",
"better-sqlite3": "^12.2.0",
"discord.js": "^14.13.0",