Compare commits
19
Commits
v8.4-Beta-1
...
v8.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1b76a2b84 | ||
|
|
a1429aa723 | ||
|
|
2de7c7b19c | ||
|
|
7383bd2c48 | ||
|
|
dc88f6c51a | ||
|
|
d69fb0e26d | ||
|
|
4b2d53d3f4 | ||
|
|
e3fa8b6d72 | ||
|
|
71e33dbf66 | ||
|
|
d468ab1575 | ||
|
|
74482af471 | ||
|
|
3cdfaef942 | ||
|
|
fcf441a190 | ||
|
|
58eb37124e | ||
|
|
afeeda3a8d | ||
|
|
357a85fa3d | ||
|
|
1bb343e49a | ||
|
|
dffa5d4161 | ||
|
|
6e14ce209d |
No files matched your search
@@ -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],
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
// SupportBot | Emerald Services
|
||||||
|
// Info Command
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
|
||||||
|
const { ContainerBuilder, UserSelectMenuBuilder, ButtonStyle, MessageFlags } = require('discord.js');
|
||||||
|
const yaml = require("js-yaml");
|
||||||
|
|
||||||
|
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 db = require("../../Structures/Database.js");
|
||||||
|
const Command = require("../../Structures/Command.js");
|
||||||
|
|
||||||
|
module.exports = new Command({
|
||||||
|
name: "test",
|
||||||
|
description: cmdconfig.Info.Description,
|
||||||
|
options: [],
|
||||||
|
permissions: cmdconfig.Info.Permission,
|
||||||
|
|
||||||
|
async run(interaction, client) {
|
||||||
|
|
||||||
|
const ticketPanelembed = new ContainerBuilder()
|
||||||
|
.addTextDisplayComponents(
|
||||||
|
textDisplay => textDisplay
|
||||||
|
.setContent("SupportBot"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
await interaction.reply({
|
||||||
|
components: [ticketPanelembed],
|
||||||
|
flags: MessageFlags.IsComponentsV2,
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
});
|
||||||
+172
-110
@@ -288,119 +288,181 @@ function parseMarkdown(content) {
|
|||||||
|
|
||||||
function createTranscriptHTML(ticket, reason) {
|
function createTranscriptHTML(ticket, reason) {
|
||||||
return `
|
return `
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
|
<title>Ticket Transcript</title>
|
||||||
<style>
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
|
||||||
body {
|
<style>
|
||||||
background-color: #1a1a1a;
|
body {
|
||||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
background: linear-gradient(135deg, #0f2027, #203a43, #2c5364);
|
||||||
color: white;
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
margin: 0;
|
color: #e5e7eb;
|
||||||
padding: 20px;
|
margin: 0;
|
||||||
}
|
padding: 40px;
|
||||||
.container {
|
}
|
||||||
max-width: 1000px;
|
|
||||||
margin: 0 auto;
|
|
||||||
background-color: rgba(0, 0, 0, 0.3);
|
|
||||||
border-radius: 15px;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
.message {
|
|
||||||
background-color: rgba(255, 255, 255, 0.1);
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 15px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
.message-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
.avatar {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
border-radius: 50%;
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
.username {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #4CAF50;
|
|
||||||
}
|
|
||||||
.timestamp {
|
|
||||||
margin-left: auto;
|
|
||||||
color: #888;
|
|
||||||
font-size: 0.9em;
|
|
||||||
}
|
|
||||||
.content {
|
|
||||||
word-break: break-word;
|
|
||||||
}
|
|
||||||
.embed {
|
|
||||||
border-left: 4px solid #4CAF50;
|
|
||||||
padding-left: 10px;
|
|
||||||
margin: 10px 0;
|
|
||||||
background-color: rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
.attachment {
|
|
||||||
display: inline-block;
|
|
||||||
background-color: rgba(76, 175, 80, 0.1);
|
|
||||||
border: 1px solid #4CAF50;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 5px 10px;
|
|
||||||
margin: 5px 0;
|
|
||||||
color: #4CAF50;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<div class="mb-6">
|
|
||||||
<h1 class="text-3xl font-bold mb-4">Ticket Transcript</h1>
|
|
||||||
<p><strong>Channel:</strong> ${ticket.name}</p>
|
|
||||||
<p><strong>Ticket ID:</strong> ${ticket.id}</p>
|
|
||||||
<p><strong>Message Count:</strong> ${ticket.messages.length}</p>
|
|
||||||
<p><strong>Close Reason:</strong> ${reason}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="messages">
|
.container {
|
||||||
${ticket.messages.map(msg => `
|
max-width: 1000px;
|
||||||
<div class="message">
|
margin: auto;
|
||||||
<div class="message-header">
|
padding: 25px;
|
||||||
<img src="${msg.avatar}" alt="Avatar" class="avatar">
|
border-radius: 20px;
|
||||||
<span class="username">${msg.username}</span>
|
backdrop-filter: blur(18px) saturate(180%);
|
||||||
<span class="timestamp">${new Date(msg.timestamp).toLocaleString()}</span>
|
background: rgba(17, 25, 40, 0.75);
|
||||||
</div>
|
box-shadow: 0 8px 32px rgba(0,0,0,0.6);
|
||||||
<div class="content">
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
${parseMarkdown(msg.content)}
|
}
|
||||||
|
|
||||||
${msg.embeds.map(embed => `
|
h1 {
|
||||||
<div class="embed">
|
font-size: 2rem;
|
||||||
${embed.title ? `<div class="font-bold">${embed.title}</div>` : ''}
|
font-weight: 700;
|
||||||
${embed.description ? `<div>${embed.description}</div>` : ''}
|
text-align: center;
|
||||||
${embed.fields.map(field => `
|
color: #22c55e; /* green accent */
|
||||||
<div class="mt-2">
|
margin-bottom: 20px;
|
||||||
<strong>${field.name}:</strong>
|
text-shadow: 0 0 4px rgba(34,197,94,0.4); /* subtle glow */
|
||||||
<div>${field.value}</div>
|
}
|
||||||
</div>
|
|
||||||
`).join('')}
|
|
||||||
</div>
|
|
||||||
`).join('')}
|
|
||||||
|
|
||||||
${msg.attachments.map(att => `
|
.ticket-info {
|
||||||
<a href="${att.url}" class="attachment" target="_blank">
|
margin-bottom: 25px;
|
||||||
📎 ${att.name}
|
padding: 15px;
|
||||||
</a>
|
border-radius: 12px;
|
||||||
`).join('')}
|
background: rgba(255, 255, 255, 0.05);
|
||||||
</div>
|
border: 1px solid rgba(255,255,255,0.1);
|
||||||
</div>
|
}
|
||||||
`).join('')}
|
|
||||||
</div>
|
.ticket-info p {
|
||||||
|
margin: 6px 0;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
border-radius: 15px;
|
||||||
|
padding: 16px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.08);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 6px 20px rgba(0,0,0,0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 45px;
|
||||||
|
height: 45px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 12px;
|
||||||
|
border: 2px solid rgba(34,197,94,0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.username {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #22c55e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timestamp {
|
||||||
|
margin-left: auto;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #9ca3af;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
word-break: break-word;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
line-height: 1.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.embed {
|
||||||
|
margin-top: 12px;
|
||||||
|
border-left: 4px solid #22c55e;
|
||||||
|
padding-left: 12px;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: rgba(34,197,94,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.embed strong {
|
||||||
|
color: #f9fafb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment {
|
||||||
|
display: inline-block;
|
||||||
|
background: rgba(34,197,94,0.1);
|
||||||
|
border: 1px solid #22c55e;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
margin: 6px 0;
|
||||||
|
color: #22c55e;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment:hover {
|
||||||
|
background: rgba(34,197,94,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
code, pre {
|
||||||
|
background: rgba(0,0,0,0.4);
|
||||||
|
color: #f8fafc;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-family: 'Consolas', 'Monaco', monospace;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Ticket Transcript</h1>
|
||||||
|
<div class="ticket-info">
|
||||||
|
<p><strong>Channel:</strong> ${ticket.name}</p>
|
||||||
|
<p><strong>Ticket ID:</strong> ${ticket.id}</p>
|
||||||
|
<p><strong>Message Count:</strong> ${ticket.messages.length}</p>
|
||||||
|
<p><strong>Close Reason:</strong> ${reason}</p>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
|
||||||
</html>
|
<div class="messages">
|
||||||
|
${ticket.messages.map(msg => `
|
||||||
|
<div class="message">
|
||||||
|
<div class="message-header">
|
||||||
|
<img src="${msg.avatar}" alt="Avatar" class="avatar">
|
||||||
|
<span class="username">${msg.username}</span>
|
||||||
|
<span class="timestamp">${new Date(msg.timestamp).toLocaleString()}</span>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
${parseMarkdown(msg.content)}
|
||||||
|
|
||||||
|
${msg.embeds.map(embed => `
|
||||||
|
<div class="embed">
|
||||||
|
${embed.title ? `<div class="font-bold">${embed.title}</div>` : ''}
|
||||||
|
${embed.description ? `<div>${embed.description}</div>` : ''}
|
||||||
|
${embed.fields.map(field => `
|
||||||
|
<div class="mt-2">
|
||||||
|
<strong>${field.name}:</strong>
|
||||||
|
<div>${field.value}</div>
|
||||||
|
</div>
|
||||||
|
`).join('')}
|
||||||
|
</div>
|
||||||
|
`).join('')}
|
||||||
|
|
||||||
|
${msg.attachments.map(att => `
|
||||||
|
<a href="${att.url}" class="attachment" target="_blank">📎 ${att.name}</a>
|
||||||
|
`).join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`).join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
+60
-26
@@ -11,6 +11,9 @@ const {
|
|||||||
ButtonStyle,
|
ButtonStyle,
|
||||||
MessageCollector,
|
MessageCollector,
|
||||||
MessageFlags,
|
MessageFlags,
|
||||||
|
SeparatorBuilder,
|
||||||
|
ContainerBuilder,
|
||||||
|
TextDisplayBuilder
|
||||||
} = require("discord.js");
|
} = require("discord.js");
|
||||||
const yaml = require("js-yaml");
|
const yaml = require("js-yaml");
|
||||||
|
|
||||||
@@ -455,32 +458,57 @@ module.exports = new Command({
|
|||||||
.setColor(supportbot.Embed.Colours.General);
|
.setColor(supportbot.Embed.Colours.General);
|
||||||
await interaction.reply({ embeds: [CreatedTicket], flags: MessageFlags.Ephemeral });
|
await interaction.reply({ embeds: [CreatedTicket], flags: MessageFlags.Ephemeral });
|
||||||
|
|
||||||
const TicketMessage = new EmbedBuilder()
|
// TICKET MESSAGE - UPDATED WITH COMPONENTS V2
|
||||||
.setAuthor({
|
|
||||||
name: msgconfig.Ticket.TicketAuthorTitle.replace(/%ticketauthor%/g, interaction.user.id)
|
|
||||||
.replace(/%ticketid%/g, ticketChannel.id)
|
|
||||||
.replace(/%ticketusername%/g, interaction.user.username),
|
|
||||||
iconURL: interaction.user.displayAvatarURL(),
|
|
||||||
})
|
|
||||||
.setTitle(
|
|
||||||
msgconfig.Ticket.TicketTitle.replace(/%ticketauthor%/g, interaction.user.id)
|
|
||||||
.replace(/%ticketid%/g, ticketChannel.id)
|
|
||||||
.replace(/%ticketusername%/g, interaction.user.username)
|
|
||||||
)
|
|
||||||
.setDescription(
|
|
||||||
msgconfig.Ticket.TicketMessage.replace(/%ticketauthor%/g, interaction.user.id)
|
|
||||||
.replace(/%ticketid%/g, ticketChannel.id)
|
|
||||||
.replace(/%ticketusername%/g, interaction.user.username)
|
|
||||||
.replace(/%ticketreason%/g, TicketSubject)
|
|
||||||
)
|
|
||||||
.setColor(supportbot.Embed.Colours.General);
|
|
||||||
|
|
||||||
if (supportbot.Ticket.TicketReason && TicketReason) {
|
const ticketMsgContainer = new ContainerBuilder()
|
||||||
TicketMessage.addFields(
|
|
||||||
{ name: "Reason", value: TicketReason, inline: false }
|
if (supportbot.Embed.Colours.General) {
|
||||||
);
|
ticketMsgContainer.setAccentColor(
|
||||||
|
parseInt(supportbot.Embed.Colours.General.replace("#", ""), 16)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ticketAuthor = new TextDisplayBuilder().setContent(
|
||||||
|
msgconfig.Ticket.TicketAuthorTitle.replace(/%ticketauthor%/g, interaction.user.id)
|
||||||
|
.replace(/%ticketid%/g, ticketChannel.id)
|
||||||
|
.replace(/%ticketusername%/g, interaction.user.username),
|
||||||
|
);
|
||||||
|
|
||||||
|
ticketMsgContainer.addTextDisplayComponents(ticketAuthor)
|
||||||
|
|
||||||
|
const ticketTitle = new TextDisplayBuilder().setContent(
|
||||||
|
msgconfig.Ticket.TicketTitle.replace(/%ticketauthor%/g, interaction.user.id)
|
||||||
|
.replace(/%ticketid%/g, ticketChannel.id)
|
||||||
|
.replace(/%ticketusername%/g, interaction.user.username)
|
||||||
|
);
|
||||||
|
|
||||||
|
ticketMsgContainer.addTextDisplayComponents(ticketTitle)
|
||||||
|
|
||||||
|
const seperator2 = new SeparatorBuilder()
|
||||||
|
.setDivider(true)
|
||||||
|
|
||||||
|
ticketMsgContainer.addSeparatorComponents(seperator2)
|
||||||
|
|
||||||
|
const ticketDescription = new TextDisplayBuilder().setContent(
|
||||||
|
msgconfig.Ticket.TicketMessage.replace(/%ticketauthor%/g, interaction.user.id)
|
||||||
|
.replace(/%ticketid%/g, ticketChannel.id)
|
||||||
|
.replace(/%ticketusername%/g, interaction.user.username)
|
||||||
|
.replace(/%ticketreason%/g, TicketSubject)
|
||||||
|
);
|
||||||
|
|
||||||
|
ticketMsgContainer.addTextDisplayComponents(ticketDescription)
|
||||||
|
|
||||||
|
const seperator3 = new SeparatorBuilder()
|
||||||
|
.setDivider(true)
|
||||||
|
|
||||||
|
ticketMsgContainer.addSeparatorComponents(seperator3)
|
||||||
|
|
||||||
|
const ticketReason = new TextDisplayBuilder().setContent(
|
||||||
|
`**Reason:**\n ${TicketReason}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const selectMenuRow = new ActionRowBuilder();
|
||||||
|
|
||||||
const SelectMenus = new StringSelectMenuBuilder()
|
const SelectMenus = new StringSelectMenuBuilder()
|
||||||
.setCustomId("ticketcontrolpanel")
|
.setCustomId("ticketcontrolpanel")
|
||||||
.setPlaceholder("Ticket Control Panel")
|
.setPlaceholder("Ticket Control Panel")
|
||||||
@@ -529,11 +557,17 @@ module.exports = new Command({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const row2 = new ActionRowBuilder().addComponents(SelectMenus);
|
selectMenuRow.addComponents(SelectMenus)
|
||||||
|
|
||||||
|
ticketMsgContainer.addActionRowComponents(selectMenuRow)
|
||||||
|
|
||||||
|
if (supportbot.Ticket.TicketReason && TicketReason) {
|
||||||
|
ticketMsgContainer.addTextDisplayComponents(ticketReason)
|
||||||
|
}
|
||||||
|
|
||||||
await ticketChannel.send({
|
await ticketChannel.send({
|
||||||
embeds: [TicketMessage],
|
flags: MessageFlags.IsComponentsV2,
|
||||||
components: [row2],
|
components: [ticketMsgContainer],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (supportbot.Ticket.Questions.Enabled) {
|
if (supportbot.Ticket.Questions.Enabled) {
|
||||||
|
|||||||
@@ -5,6 +5,12 @@ const {
|
|||||||
ActionRowBuilder,
|
ActionRowBuilder,
|
||||||
ButtonBuilder,
|
ButtonBuilder,
|
||||||
MessageFlags,
|
MessageFlags,
|
||||||
|
ContainerBuilder,
|
||||||
|
TextDisplayBuilder,
|
||||||
|
MediaGalleryBuilder,
|
||||||
|
SeparatorBuilder,
|
||||||
|
ThumbnailBuilder,
|
||||||
|
SectionBuilder
|
||||||
} = require("discord.js");
|
} = require("discord.js");
|
||||||
const yaml = require("js-yaml");
|
const yaml = require("js-yaml");
|
||||||
|
|
||||||
@@ -52,6 +58,7 @@ module.exports = new Command({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const panelRow = db.getTicketPanel();
|
const panelRow = db.getTicketPanel();
|
||||||
|
|
||||||
if (panelRow) {
|
if (panelRow) {
|
||||||
try {
|
try {
|
||||||
await channel.messages.fetch(panelRow.message_id);
|
await channel.messages.fetch(panelRow.message_id);
|
||||||
@@ -62,24 +69,35 @@ module.exports = new Command({
|
|||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let embed = new EmbedBuilder()
|
const panelContainer = new ContainerBuilder()
|
||||||
.setTitle(panelconfig.PanelTitle)
|
|
||||||
.setColor(panelconfig.PanelColour)
|
|
||||||
.setFooter({
|
|
||||||
text: supportbot.Embed.Footer,
|
|
||||||
iconURL: interaction.user.displayAvatarURL(),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (panelconfig.TicketPanel_Description) {
|
if (panelconfig.Style.Color) {
|
||||||
embed.setDescription(panelconfig.PanelMessage);
|
panelContainer.setAccentColor(
|
||||||
|
parseInt(panelconfig.Style.Color.replace("#", ""), 16)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (panelconfig.TicketPanel_Thumbnail) {
|
const panelTitle = new TextDisplayBuilder().setContent(
|
||||||
embed.setThumbnail(panelconfig.PanelThumbnail);
|
panelconfig.Style.Title,
|
||||||
|
);
|
||||||
|
|
||||||
|
const topSeperator = new SeparatorBuilder()
|
||||||
|
.setDivider(true)
|
||||||
|
|
||||||
|
if (panelconfig.Settings.TopTitle) {
|
||||||
|
panelContainer.addTextDisplayComponents(panelTitle)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (panelconfig.TicketPanel_Image) {
|
if (panelconfig.Settings.TopDivider) {
|
||||||
embed.setImage(panelconfig.PanelImage);
|
panelContainer.addSeparatorComponents(topSeperator)
|
||||||
|
}
|
||||||
|
|
||||||
|
const panelDesc = new TextDisplayBuilder().setContent(
|
||||||
|
panelconfig.Style.Description,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (panelconfig.Style.Layout === "3") {
|
||||||
|
panelContainer.addTextDisplayComponents(panelDesc)
|
||||||
}
|
}
|
||||||
|
|
||||||
const createTicketButton = new ButtonBuilder()
|
const createTicketButton = new ButtonBuilder()
|
||||||
@@ -88,12 +106,62 @@ module.exports = new Command({
|
|||||||
.setEmoji(panelconfig.Button.Emoji)
|
.setEmoji(panelconfig.Button.Emoji)
|
||||||
.setStyle(panelconfig.Button.Color);
|
.setStyle(panelconfig.Button.Color);
|
||||||
|
|
||||||
let row = new ActionRowBuilder().addComponents(createTicketButton);
|
const middleSection = new SectionBuilder()
|
||||||
|
.addTextDisplayComponents(panelDesc)
|
||||||
|
.setButtonAccessory(createTicketButton)
|
||||||
|
|
||||||
|
if (panelconfig.Style.Layout === "1") {
|
||||||
|
panelContainer.addSectionComponents(middleSection)
|
||||||
|
}
|
||||||
|
|
||||||
|
const panelImage = new MediaGalleryBuilder()
|
||||||
|
.addItems([
|
||||||
|
{
|
||||||
|
media: {
|
||||||
|
url: panelconfig.Style.Image,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
if (panelconfig.Settings.Image) {
|
||||||
|
panelContainer.addMediaGalleryComponents(panelImage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// START OF STYLE 2 - TEXT UNDER THE IMAGE
|
||||||
|
|
||||||
|
const bottomSeperator = new SeparatorBuilder()
|
||||||
|
.setDivider(true)
|
||||||
|
|
||||||
|
if (panelconfig.Settings.BottomTitle) {
|
||||||
|
panelContainer.addTextDisplayComponents(panelTitle)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (panelconfig.Settings.BottomDivider) {
|
||||||
|
panelContainer.addSeparatorComponents(bottomSeperator)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (panelconfig.Style.Layout === "2") {
|
||||||
|
panelContainer.addSectionComponents(middleSection)
|
||||||
|
}
|
||||||
|
|
||||||
|
// START OF STYLE 3
|
||||||
|
|
||||||
|
const buttonRow = new ActionRowBuilder();
|
||||||
|
const ticketButtonRow = new ButtonBuilder()
|
||||||
|
.setCustomId("createticket")
|
||||||
|
.setLabel(panelconfig.Button.Text)
|
||||||
|
.setEmoji(panelconfig.Button.Emoji)
|
||||||
|
.setStyle(panelconfig.Button.Color);
|
||||||
|
buttonRow.addComponents(ticketButtonRow)
|
||||||
|
|
||||||
|
if (panelconfig.Style.Layout === "3") {
|
||||||
|
panelContainer.addActionRowComponents(buttonRow)
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const message = await channel.send({
|
const message = await channel.send({
|
||||||
embeds: [embed],
|
flags: MessageFlags.IsComponentsV2,
|
||||||
components: [row],
|
components: [panelContainer],
|
||||||
});
|
});
|
||||||
|
|
||||||
db.saveTicketPanel(message.id, channel.id);
|
db.saveTicketPanel(message.id, channel.id);
|
||||||
|
|||||||
+69
-17
@@ -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."
|
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"
|
Button: "Visit Site"
|
||||||
URL: "https://docs.emeraldsrv.com"
|
URL: "https://docs.emeraldsrv.com"
|
||||||
Colour: "#f74343"
|
Colour: "#45b463"
|
||||||
|
|
||||||
# ----------------------------
|
# ----------------------------
|
||||||
# Welcome/Leave Messages
|
# Welcome/Leave Messages
|
||||||
# ----------------------------
|
# ----------------------------
|
||||||
|
|
||||||
Welcome:
|
Welcome:
|
||||||
Embed:
|
Enabled: true
|
||||||
Colour: "#f74343"
|
LayoutStyle: "modern"
|
||||||
Title: "Welcome to ServerName"
|
# Available Layout Styles
|
||||||
Message: ":smile: %joined_user% has just landed!"
|
# "modern" - For the new Discord v2 components
|
||||||
Thumbnail: "BOT"
|
# "classic" - Use the classic Discord look.
|
||||||
|
|
||||||
ImageEnabled: false
|
Embed:
|
||||||
ImageURL: "https://animagelink.png/"
|
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:
|
Leave:
|
||||||
Embed:
|
Embed:
|
||||||
Colour: "#f74343"
|
Colour: "#f74343"
|
||||||
Title: "Goodbye!"
|
Title: "Goodbye!"
|
||||||
Message: ":slight_frown: %joined_user% has recently dropped out!"
|
Message: ":slight_frown: %left_user% has recently dropped out!"
|
||||||
Thumbnail: "BOT"
|
Thumbnail: "BOT"
|
||||||
|
|
||||||
ImageEnabled: false
|
ImageEnabled: false
|
||||||
@@ -70,8 +117,18 @@ Ticket:
|
|||||||
# <@%ticketauthor%> - Tags the user who created the ticket.
|
# <@%ticketauthor%> - Tags the user who created the ticket.
|
||||||
# <#%ticketid%> - Mentions the ticket channel.
|
# <#%ticketid%> - Mentions the ticket channel.
|
||||||
|
|
||||||
TicketAuthorTitle: "%ticketusername%'s Ticket"
|
# You can use Markdown formatting in this message:
|
||||||
TicketTitle: "Support Ticket"
|
# # Heading 1
|
||||||
|
# ## Heading 2
|
||||||
|
# ### Heading 3
|
||||||
|
# **Bold** text
|
||||||
|
# *Italic* text
|
||||||
|
# -# Small text
|
||||||
|
# - Bullet points
|
||||||
|
# Links: [text](https://example.com)
|
||||||
|
|
||||||
|
TicketAuthorTitle: "-# %ticketusername%'s Ticket"
|
||||||
|
TicketTitle: "## Support Ticket"
|
||||||
TicketMessage: "Hello <@%ticketauthor%>, Thank you for creating a support ticket\nPlease wait patiently whilst a member of our team reaches out to you."
|
TicketMessage: "Hello <@%ticketauthor%>, Thank you for creating a support ticket\nPlease wait patiently whilst a member of our team reaches out to you."
|
||||||
TicketThumbnail: "https://images.emojiterra.com/google/android-pie/512px/1f39f.png"
|
TicketThumbnail: "https://images.emojiterra.com/google/android-pie/512px/1f39f.png"
|
||||||
TicketCreatedAlert: ":ticket: Ticked Created: <#%ticketid%>"
|
TicketCreatedAlert: ":ticket: Ticked Created: <#%ticketid%>"
|
||||||
@@ -268,9 +325,4 @@ Error:
|
|||||||
EntryAlreadyExists: ":warning: Cannot complete the action, as the entry already exists."
|
EntryAlreadyExists: ":warning: Cannot complete the action, as the entry already exists."
|
||||||
EntryDoesNotExist: ":warning: Cannot complete the action, as the entry does not exist."
|
EntryDoesNotExist: ":warning: Cannot complete the action, as the entry does not exist."
|
||||||
ActionFailed: ":x: **Error!** An error occurred while processing your request. Please try again later."
|
ActionFailed: ":x: **Error!** An error occurred while processing your request. Please try again later."
|
||||||
|
InvalidChannel: ":x: **Error!** The suggestions channel has not been set up correctly."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
+32
-32
@@ -8,12 +8,12 @@
|
|||||||
# Installed with MIT License
|
# Installed with MIT License
|
||||||
#
|
#
|
||||||
# Discord Support: https://discord.gg/emeraldsrv
|
# Discord Support: https://discord.gg/emeraldsrv
|
||||||
# Official Documentation: https://docs.emeraldsrv.com
|
# Official Documentation: https://docs.emeraldsrv.dev
|
||||||
# Addons Marketplace: https://community.emeraldsrv.com
|
# Addons Marketplace: https://community.emeraldsrv.dev
|
||||||
#
|
#
|
||||||
# SupportBot Configuration (supportbot.yml)
|
# SupportBot Configuration (supportbot.yml)
|
||||||
|
|
||||||
SupportBot_Version: "v8.4-DEV-1"
|
SupportBot_Version: "v8.4"
|
||||||
|
|
||||||
# -------------------------
|
# -------------------------
|
||||||
# General
|
# General
|
||||||
@@ -50,10 +50,10 @@ Activity:
|
|||||||
|
|
||||||
Embed:
|
Embed:
|
||||||
Colours:
|
Colours:
|
||||||
General: 0x0cc559
|
General: "#0cc559"
|
||||||
Success: 0x04b545
|
Success: "#04b545"
|
||||||
Error: 0xd13030
|
Error: "#d13030"
|
||||||
Warn: 0xfca117
|
Warn: "#fca117"
|
||||||
|
|
||||||
Footer: "SupportBot | Developed by Emerald Development"
|
Footer: "SupportBot | Developed by Emerald Development"
|
||||||
|
|
||||||
@@ -66,12 +66,12 @@ Embed:
|
|||||||
Roles:
|
Roles:
|
||||||
AutoRole:
|
AutoRole:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
Role: "1202669457751801917"
|
Role: "1111111111111111"
|
||||||
|
|
||||||
StaffMember:
|
StaffMember:
|
||||||
Staff: "996420644373811371"
|
Staff: "1111111111111111"
|
||||||
Admin: "996419960442208326"
|
Admin: "1111111111111111"
|
||||||
Moderator: "996420644373811371"
|
Moderator: "1111111111111111"
|
||||||
|
|
||||||
Mod:
|
Mod:
|
||||||
AllowSupportStaff: false
|
AllowSupportStaff: false
|
||||||
@@ -84,11 +84,11 @@ Roles:
|
|||||||
|
|
||||||
Welcome:
|
Welcome:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
Channel: "1295788797065166869"
|
Channel: "1111111111111111"
|
||||||
|
|
||||||
Leave:
|
Leave:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
Channel: "1295788797065166869"
|
Channel: "1111111111111111"
|
||||||
|
|
||||||
# ----------------------------
|
# ----------------------------
|
||||||
# Suggestions
|
# Suggestions
|
||||||
@@ -96,8 +96,8 @@ Leave:
|
|||||||
|
|
||||||
Suggestions:
|
Suggestions:
|
||||||
Mode: "Channel" # Channel or Forum
|
Mode: "Channel" # Channel or Forum
|
||||||
ForumChannel: "1402655496477081671"
|
ForumChannel: "1111111111111111"
|
||||||
Channel: "1295788900094316706"
|
Channel: "1111111111111111"
|
||||||
|
|
||||||
UpvoteEmoji: "✅"
|
UpvoteEmoji: "✅"
|
||||||
DownvoteEmoji: "❌"
|
DownvoteEmoji: "❌"
|
||||||
@@ -130,10 +130,10 @@ Suggestions:
|
|||||||
# 4 - Red
|
# 4 - Red
|
||||||
|
|
||||||
Tags:
|
Tags:
|
||||||
Created: "1418937323118137435"
|
Created: "1111111111111111"
|
||||||
Considering: "1418937237156139130"
|
Considering: "1111111111111111"
|
||||||
Solved: "1418937168029679697"
|
Solved: "1111111111111111"
|
||||||
Denied: "1418937185469464647"
|
Denied: "1111111111111111"
|
||||||
|
|
||||||
# -------------------------
|
# -------------------------
|
||||||
# Tickets
|
# Tickets
|
||||||
@@ -141,25 +141,25 @@ Suggestions:
|
|||||||
|
|
||||||
VoiceTickets:
|
VoiceTickets:
|
||||||
Name: "%username%'s VC"
|
Name: "%username%'s VC"
|
||||||
Category: "1419062819688550460"
|
Category: "1111111111111111"
|
||||||
|
|
||||||
Ticket:
|
Ticket:
|
||||||
TicketType: "channels"
|
TicketType: "threads"
|
||||||
|
|
||||||
# Available TicketTypes:
|
# Available TicketTypes:
|
||||||
# channels - Tickets will be created as channels in the TicketChannelsCategory
|
# channels - Tickets will be created as channels in the TicketChannelsCategory
|
||||||
# threads - Tickets will be created as threads through the "TicketHome" channel.
|
# threads - Tickets will be created as threads through the "TicketHome" channel.
|
||||||
|
|
||||||
TicketHome: "1295784943204700171"
|
TicketHome: "1111111111111111"
|
||||||
|
|
||||||
# What is TicketHome?
|
# What is TicketHome?
|
||||||
# - Channel where the Ticket creation panel is sent.
|
# - Channel where the Ticket creation panel is sent.
|
||||||
# - Channel where ticket threads are made. (only if ticket threads is enabled above.)
|
# - Channel where ticket threads are made. (only if ticket threads is enabled above.)
|
||||||
|
|
||||||
# For TicketType: channels
|
# For TicketType: channels
|
||||||
TicketChannelsCategory: "1418988408193155112"
|
TicketChannelsCategory: "1111111111111111"
|
||||||
TicketChannelsCategory2: "1418988456167870615" # This will be used if the first category has reached the max channel limit.
|
TicketChannelsCategory2: "1111111111111111" # This will be used if the first category has reached the max channel limit.
|
||||||
TicketArchiveCategory: "1418988434600759348"
|
TicketArchiveCategory: "1111111111111111"
|
||||||
# ---
|
# ---
|
||||||
|
|
||||||
Channel: "ticket-" # The prefix for ticket channel names
|
Channel: "ticket-" # The prefix for ticket channel names
|
||||||
@@ -198,7 +198,7 @@ Ticket:
|
|||||||
|
|
||||||
ClaimTickets:
|
ClaimTickets:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
Channel: "1295789389619793961"
|
Channel: "1111111111111111"
|
||||||
# Channel where the ticket assignments are sent for staff to claim.
|
# Channel where the ticket assignments are sent for staff to claim.
|
||||||
|
|
||||||
ClaimAcceptTime: 120000
|
ClaimAcceptTime: 120000
|
||||||
@@ -221,7 +221,7 @@ Ticket:
|
|||||||
|
|
||||||
ReviewSystem:
|
ReviewSystem:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
Channel: "1304480728884445225"
|
Channel: "1111111111111111"
|
||||||
UseModal: true
|
UseModal: true
|
||||||
|
|
||||||
Questions:
|
Questions:
|
||||||
@@ -232,9 +232,9 @@ Ticket:
|
|||||||
- "Have you tried resolving the issue yourself?"
|
- "Have you tried resolving the issue yourself?"
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
TicketDataLog: "1339271338761650290"
|
TicketDataLog: "1111111111111111"
|
||||||
TickeDataTitle: "Ticket Data"
|
TickeDataTitle: "Ticket Data"
|
||||||
TicketBlacklistLog: "1339271338761650290"
|
TicketBlacklistLog: "1111111111111111"
|
||||||
|
|
||||||
# -------------------------
|
# -------------------------
|
||||||
# Buttons
|
# Buttons
|
||||||
@@ -287,12 +287,12 @@ SelectMenus:
|
|||||||
# -------------------------
|
# -------------------------
|
||||||
|
|
||||||
MessageDelete:
|
MessageDelete:
|
||||||
Channel: "1202671982932402246"
|
Channel: "1111111111111111"
|
||||||
Colour: "#d92525"
|
Colour: "#d92525"
|
||||||
|
|
||||||
MessageUpdate:
|
MessageUpdate:
|
||||||
Channel: "1202671982932402246"
|
Channel: "1111111111111111"
|
||||||
Colour: "#f2a024"
|
Colour: "#f2a024"
|
||||||
|
|
||||||
Translate:
|
Translate:
|
||||||
TranslateLog: "1202671982932402246"
|
TranslateLog: "1111111111111111"
|
||||||
@@ -23,13 +23,24 @@ Panel: true
|
|||||||
# Ticket Panel Message Configuration #2b2d31
|
# Ticket Panel Message Configuration #2b2d31
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
|
|
||||||
PanelTitle: "SupportBot"
|
Style:
|
||||||
PanelColour: "#0cc559"
|
Title: "## SupportBot Ticket Creation"
|
||||||
|
Description: "Click on the button to file a `Ticket` and our team will try their best to assist you in the best way we can!"
|
||||||
|
Image: "https://i.imgur.com/dejQvkg.png"
|
||||||
|
Color: "#45b463"
|
||||||
|
# Leave Color empty to remove the color from the embed/container.
|
||||||
|
|
||||||
|
Layout: "3"
|
||||||
|
|
||||||
|
# Available Layout Styles
|
||||||
|
# "1" - Style 1 - Title & Text, Button at the top -- Image at the bottom
|
||||||
|
# "2" - Style 2 - Title & Text, Button at the bottom -- Image at the top
|
||||||
|
# "3" - Style 3 - The classic look - Title & Text at the top -- Image in the middle -- Button at the bottom
|
||||||
|
|
||||||
Button:
|
Button:
|
||||||
Text: "Create Ticket"
|
Text: "Create Ticket"
|
||||||
Emoji: "🎫"
|
Emoji: "🎫"
|
||||||
Color: "2"
|
Color: "3"
|
||||||
|
|
||||||
# Available Button Styles
|
# Available Button Styles
|
||||||
# 1 - Blurple
|
# 1 - Blurple
|
||||||
@@ -37,10 +48,15 @@ Button:
|
|||||||
# 3 - Red
|
# 3 - Red
|
||||||
# 4 - Green
|
# 4 - Green
|
||||||
|
|
||||||
TicketPanel_Description: true
|
Settings:
|
||||||
TicketPanel_Thumbnail: false
|
Image: true
|
||||||
TicketPanel_Image: true
|
|
||||||
|
|
||||||
PanelMessage: "Click on the button to file a `Ticket` and our team will try their best to assist you in the best way we can!"
|
# Text and divider will appear above the image.
|
||||||
PanelThumbnail: "https://i.imgur.com/ieeZejl.png"
|
TopTitle: true
|
||||||
PanelImage: "https://i.imgur.com/dejQvkg.png"
|
TopDivider: true
|
||||||
|
|
||||||
|
# Text and divider will appear below the image.
|
||||||
|
BottomTitle: false
|
||||||
|
BottomDivider: false
|
||||||
|
|
||||||
|
# Note: If Image is set to false, the bottom and top settings will look the samme.
|
||||||
Binary file not shown.
+137
-40
@@ -1,56 +1,153 @@
|
|||||||
|
const {
|
||||||
const Discord = require('discord.js');
|
EmbedBuilder,
|
||||||
|
ActionRowBuilder,
|
||||||
|
ButtonBuilder,
|
||||||
|
ButtonStyle,
|
||||||
|
MessageFlags,
|
||||||
|
ContainerBuilder,
|
||||||
|
TextDisplayBuilder,
|
||||||
|
SectionBuilder,
|
||||||
|
ThumbnailBuilder,
|
||||||
|
AttachmentBuilder
|
||||||
|
} = require("discord.js");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const Event = require("../Structures/Event.js");
|
|
||||||
const yaml = require("js-yaml");
|
const yaml = require("js-yaml");
|
||||||
|
const Event = require("../Structures/Event.js");
|
||||||
|
|
||||||
const supportbot = yaml.load(
|
const supportbot = yaml.load(
|
||||||
fs.readFileSync("./Configs/supportbot.yml", "utf8")
|
fs.readFileSync("./Configs/supportbot.yml", "utf8")
|
||||||
);
|
);
|
||||||
|
|
||||||
const cmdconfig = yaml.load(
|
|
||||||
fs.readFileSync("./Configs/commands.yml", "utf8")
|
|
||||||
);
|
|
||||||
|
|
||||||
const msgconfig = yaml.load(
|
const msgconfig = yaml.load(
|
||||||
fs.readFileSync("./Configs/messages.yml", "utf8")
|
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) {
|
function buildModernComponents(client, member) {
|
||||||
const WelcomeChannel = member.guild.channels.cache.get(supportbot.Welcome.Channel) ||
|
const container = new ContainerBuilder()
|
||||||
member.guild.channels.cache.find(channel => channel.name === supportbot.Welcome.Channel);
|
.setAccentColor(
|
||||||
|
parseInt(msgconfig.Welcome.Modern.Colour.replace("#", ""), 16)
|
||||||
|
);
|
||||||
|
|
||||||
const WelcomeEmbed = new Discord.EmbedBuilder()
|
const section = new SectionBuilder().addTextDisplayComponents(
|
||||||
.setColor(msgconfig.Welcome.Embed.Colour)
|
new TextDisplayBuilder().setContent(
|
||||||
.setTitle(msgconfig.Welcome.Embed.Title)
|
msgconfig.Welcome.Modern.Title.replace(/%joined_user%/g, member.user)
|
||||||
.setDescription(msgconfig.Welcome.Embed.Message.replace(/%joined_user%/g, member.user))
|
),
|
||||||
.setTimestamp();
|
new TextDisplayBuilder().setContent(
|
||||||
|
msgconfig.Welcome.Modern.Body.replace(/%joined_user%/g, member.user)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if (msgconfig.Welcome.Embed.Thumbnail === "BOT") {
|
const thumbUrl = getWelcomeThumbnail(client, member, msgconfig.Welcome.Modern.Icon);
|
||||||
WelcomeEmbed.setThumbnail(client.user.displayAvatarURL())
|
if (thumbUrl) {
|
||||||
} else if (msgconfig.Welcome.Embed.Thumbnail === "USER") {
|
section.setThumbnailAccessory(
|
||||||
WelcomeEmbed.setThumbnail(member.user.displayAvatarURL())
|
new ThumbnailBuilder()
|
||||||
}
|
.setURL(thumbUrl)
|
||||||
|
);
|
||||||
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!`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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!`);
|
||||||
|
|
||||||
});
|
});
|
||||||
+28
-38
@@ -1,50 +1,40 @@
|
|||||||
|
const { EmbedBuilder } = require("discord.js");
|
||||||
const Discord = require('discord.js');
|
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const Event = require("../Structures/Event.js");
|
|
||||||
const yaml = require("js-yaml");
|
const yaml = require("js-yaml");
|
||||||
|
const Event = require("../Structures/Event.js");
|
||||||
|
|
||||||
const supportbot = yaml.load(
|
const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8"));
|
||||||
fs.readFileSync("./Configs/supportbot.yml", "utf8")
|
const msgconfig = yaml.load(fs.readFileSync("./Configs/messages.yml", "utf8"));
|
||||||
);
|
|
||||||
|
|
||||||
const cmdconfig = yaml.load(
|
module.exports = new Event("guildMemberRemove", async (client, member) => {
|
||||||
fs.readFileSync("./Configs/commands.yml", "utf8")
|
|
||||||
);
|
|
||||||
|
|
||||||
const msgconfig = yaml.load(
|
if (!supportbot.Leave || !supportbot.Leave.Enabled) return;
|
||||||
fs.readFileSync("./Configs/messages.yml", "utf8")
|
|
||||||
);
|
|
||||||
|
|
||||||
module.exports = new Event("guildMemberRemove", async (client, member, interaction, guild) => {
|
const leaveChannel =
|
||||||
|
member.guild.channels.cache.get(supportbot.Leave.Channel) ||
|
||||||
|
member.guild.channels.cache.find(c => c.name === supportbot.Leave.Channel);
|
||||||
|
|
||||||
if (supportbot.Leave.Enabled) {
|
if (!leaveChannel) return;
|
||||||
const LeaveChannel = member.guild.channels.cache.get(supportbot.Leave.Channel) ||
|
|
||||||
member.guild.channels.cache.find(channel => channel.name === supportbot.Leave.Channel);
|
|
||||||
|
|
||||||
const LeaveEmbed = new Discord.EmbedBuilder()
|
const leaveEmbed = new EmbedBuilder()
|
||||||
.setColor(msgconfig.Leave.Embed.Colour)
|
.setColor(msgconfig.Leave.Embed.Colour)
|
||||||
.setTitle(msgconfig.Leave.Embed.Title)
|
.setTitle(msgconfig.Leave.Embed.Title)
|
||||||
.setDescription(msgconfig.Leave.Embed.Message.replace(/%left_user%/g, member.user))
|
.setDescription(
|
||||||
.setTimestamp();
|
msgconfig.Leave.Embed.Message.replace(/%left_user%/g, member.user.toString())
|
||||||
|
)
|
||||||
|
.setTimestamp();
|
||||||
|
|
||||||
if (msgconfig.Leave.Embed.Thumbnail === "BOT") {
|
if (msgconfig.Leave.Embed.Thumbnail === "BOT") {
|
||||||
LeaveEmbed.setThumbnail(client.user.displayAvatarURL());
|
leaveEmbed.setThumbnail(client.user.displayAvatarURL());
|
||||||
} else if (msgconfig.Leave.Embed.Thumbnail === "USER") {
|
} else if (msgconfig.Leave.Embed.Thumbnail === "USER") {
|
||||||
LeaveEmbed.setThumbnail(member.user.displayAvatarURL());
|
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!`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (msgconfig.Leave.Embed.ImageEnabled) {
|
||||||
|
leaveEmbed.setImage(msgconfig.Leave.Embed.ImageURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
await leaveChannel.send({ embeds: [leaveEmbed] });
|
||||||
|
|
||||||
|
console.log(`[-] ${member.user.tag} left the server`);
|
||||||
});
|
});
|
||||||
+16
-15
@@ -25,7 +25,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
|
|||||||
if (!command)
|
if (!command)
|
||||||
return interaction.reply({
|
return interaction.reply({
|
||||||
embeds: [NotValid],
|
embeds: [NotValid],
|
||||||
ephemeral: true,
|
flags: Discord.MessageFlags.Ephemeral,
|
||||||
});
|
});
|
||||||
|
|
||||||
const permission = interaction.member.permissions.has(command.permissions);
|
const permission = interaction.member.permissions.has(command.permissions);
|
||||||
@@ -39,7 +39,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
|
|||||||
if (!permission)
|
if (!permission)
|
||||||
return interaction.reply({
|
return interaction.reply({
|
||||||
embeds: [ValidPerms],
|
embeds: [ValidPerms],
|
||||||
ephemeral: true,
|
flags: Discord.MessageFlags.Ephemeral,
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -66,7 +66,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
|
|||||||
console.error("Error executing command:", error);
|
console.error("Error executing command:", error);
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
content: "An error occurred while executing the command.",
|
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) {
|
if (!ticketChannel) {
|
||||||
return interaction.reply({
|
return interaction.reply({
|
||||||
content: "Ticket channel not found.",
|
content: "Ticket channel not found.",
|
||||||
ephemeral: true,
|
flags: Discord.MessageFlags.Ephemeral,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -107,16 +107,17 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
|
|||||||
.setColor(supportbot.Embed.Colours.Success);
|
.setColor(supportbot.Embed.Colours.Success);
|
||||||
return interaction.reply({
|
return interaction.reply({
|
||||||
embeds: [renamedsuccess],
|
embeds: [renamedsuccess],
|
||||||
ephemeral: true,
|
flags: Discord.MessageFlags.Ephemeral,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error renaming the ticket:", error);
|
console.error("Error renaming the ticket:", error);
|
||||||
return interaction.reply({
|
return interaction.reply({
|
||||||
content: "There was an error renaming the ticket.",
|
content: "There was an error renaming the ticket.",
|
||||||
ephemeral: true,
|
flags: Discord.MessageFlags.Ephemeral,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interaction.isStringSelectMenu()) {
|
if (interaction.isStringSelectMenu()) {
|
||||||
if (interaction.customId === "ticketcontrolpanel") {
|
if (interaction.customId === "ticketcontrolpanel") {
|
||||||
const selectedOption = interaction.values[0];
|
const selectedOption = interaction.values[0];
|
||||||
@@ -151,7 +152,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
|
|||||||
if (!VCcategory) {
|
if (!VCcategory) {
|
||||||
return interaction.reply({
|
return interaction.reply({
|
||||||
content: "⚠️ The Support VC category does not exist!",
|
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);
|
.setColor(supportbot.Embed.Colours.Success);
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
embeds: [successEmbed],
|
embeds: [successEmbed],
|
||||||
ephemeral: true,
|
flags: Discord.MessageFlags.Ephemeral,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const errorEmbed = new Discord.EmbedBuilder()
|
const errorEmbed = new Discord.EmbedBuilder()
|
||||||
@@ -351,7 +352,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
|
|||||||
.setColor(supportbot.Embed.Colours.Error);
|
.setColor(supportbot.Embed.Colours.Error);
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
embeds: [errorEmbed],
|
embeds: [errorEmbed],
|
||||||
ephemeral: true,
|
flags: Discord.MessageFlags.Ephemeral,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -361,7 +362,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
|
|||||||
.setColor(supportbot.Embed.Colours.Error);
|
.setColor(supportbot.Embed.Colours.Error);
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
embeds: [errorEmbed],
|
embeds: [errorEmbed],
|
||||||
ephemeral: true,
|
flags: Discord.MessageFlags.Ephemeral,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -370,7 +371,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
|
|||||||
.setColor(supportbot.Embed.Colours.Warn);
|
.setColor(supportbot.Embed.Colours.Warn);
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
embeds: [errorEmbed],
|
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);
|
console.error("Error executing the ticket command:", error);
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
content: "An error occurred while creating the ticket.",
|
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) {
|
if (!ticketChannel) {
|
||||||
return interaction.reply({
|
return interaction.reply({
|
||||||
content: "Ticket channel not found.",
|
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({
|
await interaction.reply({
|
||||||
embeds: [embed],
|
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);
|
console.error("Failed to update profile data: ", error);
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
content: "There was an error while updating your profile. Please try again later.",
|
content: "There was an error while updating your profile. Please try again later.",
|
||||||
ephemeral: true,
|
flags: Discord.MessageFlags.Ephemeral,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-18
@@ -3,41 +3,34 @@ const fs = require("fs");
|
|||||||
const yaml = require("js-yaml");
|
const yaml = require("js-yaml");
|
||||||
const Event = require("../Structures/Event.js");
|
const Event = require("../Structures/Event.js");
|
||||||
|
|
||||||
// Load the configuration files
|
|
||||||
const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8"));
|
const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8"));
|
||||||
const msgconfig = yaml.load(fs.readFileSync("./Configs/messages.yml", "utf8"));
|
const msgconfig = yaml.load(fs.readFileSync("./Configs/messages.yml", "utf8"));
|
||||||
|
|
||||||
module.exports = new Event("messageDelete", async (client, message) => {
|
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
|
const author = message.author || (message.partial ? await message.fetch().then(m => m.author).catch(() => null) : null);
|
||||||
if (!message.guild || message.author.bot) return;
|
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) ||
|
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()
|
const deletedMessageEmbed = new EmbedBuilder()
|
||||||
.setColor(supportbot.MessageDelete.Colour)
|
.setColor(supportbot.MessageDelete.Colour)
|
||||||
.setTitle("Message Deleted")
|
.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:** <t:${Math.floor(message.createdTimestamp / 1000)}:F>`)
|
.setDescription(`> **Channel:** <#${message.channel.id}>\n> **Message ID:** ${message.id}\n> **Message author:** ${author.tag} (${author.id})\n> **Message Created:** <t:${Math.floor(message.createdTimestamp / 1000)}:F>`)
|
||||||
.addFields(
|
.addFields({ name: "Deleted Content", value: content, inline: false })
|
||||||
{ name: 'Message', value: message.content || '*No content*', inline: false }
|
.setThumbnail(author.displayAvatarURL())
|
||||||
)
|
|
||||||
.setThumbnail(message.author.displayAvatarURL())
|
|
||||||
.setTimestamp();
|
.setTimestamp();
|
||||||
|
|
||||||
// If the message contains an attachment, add it to the embed
|
|
||||||
if (message.attachments.size > 0) {
|
if (message.attachments.size > 0) {
|
||||||
const attachment = message.attachments.first();
|
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) {
|
if (deleteLogChannel) {
|
||||||
deleteLogChannel.send({
|
deleteLogChannel.send({ embeds: [deletedMessageEmbed] });
|
||||||
embeds: [deletedMessageEmbed]
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ const { Command, Event } = require('./Addon.js');
|
|||||||
const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8"));
|
const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8"));
|
||||||
const cmdconfig = yaml.load(fs.readFileSync("./Configs/commands.yml", "utf8"));
|
const cmdconfig = yaml.load(fs.readFileSync("./Configs/commands.yml", "utf8"));
|
||||||
|
|
||||||
|
|
||||||
function walk(dir, ext = ".js", fileList = []) {
|
function walk(dir, ext = ".js", fileList = []) {
|
||||||
const files = fs.readdirSync(dir);
|
const files = fs.readdirSync(dir);
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
@@ -179,7 +180,7 @@ class Client extends Discord.Client {
|
|||||||
console.log(`\u001b[33m`, "▬▬▬▬▬▬▬ Addons ▬▬▬▬▬▬▬");
|
console.log(`\u001b[33m`, "▬▬▬▬▬▬▬ Addons ▬▬▬▬▬▬▬");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.once("ready", async () => {
|
this.once("clientReady", async () => {
|
||||||
await this.guilds.cache.first()?.commands.set(this.commands);
|
await this.guilds.cache.first()?.commands.set(this.commands);
|
||||||
console.log(
|
console.log(
|
||||||
"\u001b[32m",
|
"\u001b[32m",
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ const path = require("path");
|
|||||||
|
|
||||||
const db = new Database(path.join(__dirname, "../Data/supportbot.db"));
|
const db = new Database(path.join(__dirname, "../Data/supportbot.db"));
|
||||||
|
|
||||||
// ----- Core tables -----
|
|
||||||
db.prepare(`
|
db.prepare(`
|
||||||
CREATE TABLE IF NOT EXISTS suggestions (
|
CREATE TABLE IF NOT EXISTS suggestions (
|
||||||
thread_id TEXT PRIMARY KEY,
|
thread_id TEXT PRIMARY KEY,
|
||||||
@@ -62,7 +61,6 @@ db.prepare(`
|
|||||||
)
|
)
|
||||||
`).run();
|
`).run();
|
||||||
|
|
||||||
/* ---- NEW table for global bot settings ---- */
|
|
||||||
db.prepare(`
|
db.prepare(`
|
||||||
CREATE TABLE IF NOT EXISTS settings (
|
CREATE TABLE IF NOT EXISTS settings (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
@@ -71,7 +69,6 @@ db.prepare(`
|
|||||||
`).run();
|
`).run();
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// ----- Suggestions -----
|
|
||||||
addSuggestion(threadId, authorId, text) {
|
addSuggestion(threadId, authorId, text) {
|
||||||
db.prepare(`
|
db.prepare(`
|
||||||
INSERT INTO suggestions (thread_id, author_id, text)
|
INSERT INTO suggestions (thread_id, author_id, text)
|
||||||
@@ -122,7 +119,6 @@ module.exports = {
|
|||||||
.run(value ? 1 : 0, userId);
|
.run(value ? 1 : 0, userId);
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----- Tickets -----
|
|
||||||
addTicket(ticket) {
|
addTicket(ticket) {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
db.prepare(`
|
db.prepare(`
|
||||||
@@ -184,7 +180,6 @@ module.exports = {
|
|||||||
`).get();
|
`).get();
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----- Ticket participants -----
|
|
||||||
addUserToTicket(ticketId, userId) {
|
addUserToTicket(ticketId, userId) {
|
||||||
db.prepare(`
|
db.prepare(`
|
||||||
INSERT INTO ticket_users (ticket_id, user_id)
|
INSERT INTO ticket_users (ticket_id, user_id)
|
||||||
@@ -205,7 +200,6 @@ module.exports = {
|
|||||||
`).all(ticketId).map(r => r.user_id);
|
`).all(ticketId).map(r => r.user_id);
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----- Global Settings -----
|
|
||||||
getSettings() {
|
getSettings() {
|
||||||
const row = db.prepare(`SELECT data FROM settings WHERE id=1`).get();
|
const row = db.prepare(`SELECT data FROM settings WHERE id=1`).get();
|
||||||
if (!row) return {};
|
if (!row) return {};
|
||||||
|
|||||||
@@ -8,9 +8,10 @@
|
|||||||
// Installed with MIT License
|
// Installed with MIT License
|
||||||
//
|
//
|
||||||
// Discord Support: https://emeraldsrv.dev/discord
|
// Discord Support: https://emeraldsrv.dev/discord
|
||||||
// Community Resources: https://emeraldsrv.dev/resources
|
// Community Resources: https://community.emeraldsrv.dev
|
||||||
|
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
const yaml = require("js-yaml");
|
const yaml = require("js-yaml");
|
||||||
const supportbot = yaml.load(
|
const supportbot = yaml.load(
|
||||||
@@ -24,13 +25,51 @@ const client = new Client({
|
|||||||
|
|
||||||
client.start(supportbot.General.Token);
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-3
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "supportbot",
|
"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.",
|
"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",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -18,8 +18,6 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://community.emeraldsrv.dev",
|
"homepage": "https://community.emeraldsrv.dev",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@paypal/checkout-server-sdk": "^1.0.3",
|
|
||||||
"@vitalets/google-translate-api": "^8.0.0",
|
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
"better-sqlite3": "^12.2.0",
|
"better-sqlite3": "^12.2.0",
|
||||||
"discord.js": "^14.13.0",
|
"discord.js": "^14.13.0",
|
||||||
|
|||||||
Reference in new issue
Block a user