This commit is contained in:
1tzEmerald committed 2025-09-23 23:23:19 +01:00
1 parent 7383bd2c48
commit 2de7c7b19c
8 files changed
+329 -129

No files matched your search

+45
View File
@@ -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,
});
},
});
+70 -43
View File
@@ -289,112 +289,141 @@ function parseMarkdown(content) {
function createTranscriptHTML(ticket, reason) {
return `
<!DOCTYPE html>
<html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ticket Transcript</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
<style>
body {
background: url('file-EWLgzFEYsq16ANVg6ENJrP.png') no-repeat center center fixed;
background-size: cover;
background: linear-gradient(135deg, #0f2027, #203a43, #2c5364);
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
color: #ffffff;
color: #e5e7eb;
margin: 0;
padding: 20px;
padding: 40px;
}
.container {
max-width: 1000px;
margin: 0 auto;
padding: 20px;
backdrop-filter: blur(10px);
background: rgba(0,0,0,0.4);
margin: auto;
padding: 25px;
border-radius: 20px;
box-shadow: 0 8px 32px rgba(0,0,0,0.5);
backdrop-filter: blur(18px) saturate(180%);
background: rgba(17, 25, 40, 0.75);
box-shadow: 0 8px 32px rgba(0,0,0,0.6);
border: 1px solid rgba(255, 255, 255, 0.1);
}
h1 {
font-size: 2.5rem;
font-weight: bold;
font-size: 2rem;
font-weight: 700;
text-align: center;
color: #22c55e; /* green accent */
margin-bottom: 20px;
text-shadow: 0 0 4px rgba(34,197,94,0.4); /* subtle glow */
}
.ticket-info {
margin-bottom: 25px;
padding: 15px;
border-radius: 12px;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255,255,255,0.1);
}
.ticket-info p {
margin: 5px 0;
margin: 6px 0;
font-size: 0.95rem;
}
.message {
backdrop-filter: blur(15px);
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.2);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 15px;
padding: 15px;
padding: 16px;
margin-bottom: 15px;
transition: transform 0.2s;
transition: all 0.2s ease-in-out;
}
.message:hover {
transform: scale(1.02);
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: 10px;
margin-bottom: 12px;
}
.avatar {
width: 50px;
height: 50px;
width: 45px;
height: 45px;
border-radius: 50%;
margin-right: 15px;
border: 2px solid rgba(255,255,255,0.3);
margin-right: 12px;
border: 2px solid rgba(34,197,94,0.6);
}
.username {
font-weight: bold;
color: #00ffe4;
font-size: 1.1rem;
font-weight: 600;
color: #22c55e;
}
.timestamp {
margin-left: auto;
color: #aaa;
font-size: 0.85rem;
color: #9ca3af;
}
.content {
word-break: break-word;
font-size: 1rem;
font-size: 0.95rem;
line-height: 1.4rem;
}
.embed {
border-left: 4px solid #00ffe4;
padding-left: 10px;
margin: 10px 0;
background: rgba(255, 255, 255, 0.05);
border-radius: 10px;
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-color: rgba(0, 255, 228, 0.1);
border: 1px solid #00ffe4;
border-radius: 5px;
padding: 5px 10px;
margin: 5px 0;
color: #00ffe4;
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 mb-6">
<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>
@@ -426,9 +455,7 @@ function createTranscriptHTML(ticket, reason) {
`).join('')}
${msg.attachments.map(att => `
<a href="${att.url}" class="attachment" target="_blank">
📎 ${att.name}
</a>
<a href="${att.url}" class="attachment" target="_blank">📎 ${att.name}</a>
`).join('')}
</div>
</div>
+60 -26
View File
@@ -11,6 +11,9 @@ const {
ButtonStyle,
MessageCollector,
MessageFlags,
SeparatorBuilder,
ContainerBuilder,
TextDisplayBuilder
} = require("discord.js");
const yaml = require("js-yaml");
@@ -455,32 +458,57 @@ module.exports = new Command({
.setColor(supportbot.Embed.Colours.General);
await interaction.reply({ embeds: [CreatedTicket], flags: MessageFlags.Ephemeral });
const TicketMessage = new EmbedBuilder()
.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)
// TICKET MESSAGE - UPDATED WITH COMPONENTS V2
const ticketMsgContainer = new ContainerBuilder()
if (supportbot.Embed.Colours.General) {
ticketMsgContainer.setAccentColor(
parseInt(supportbot.Embed.Colours.General.replace("#", ""), 16)
)
.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) {
TicketMessage.addFields(
{ name: "Reason", value: TicketReason, inline: false }
);
}
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()
.setCustomId("ticketcontrolpanel")
.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({
embeds: [TicketMessage],
components: [row2],
flags: MessageFlags.IsComponentsV2,
components: [ticketMsgContainer],
});
if (supportbot.Ticket.Questions.Enabled) {
+84 -16
View File
@@ -5,6 +5,12 @@ const {
ActionRowBuilder,
ButtonBuilder,
MessageFlags,
ContainerBuilder,
TextDisplayBuilder,
MediaGalleryBuilder,
SeparatorBuilder,
ThumbnailBuilder,
SectionBuilder
} = require("discord.js");
const yaml = require("js-yaml");
@@ -52,6 +58,7 @@ module.exports = new Command({
}
const panelRow = db.getTicketPanel();
if (panelRow) {
try {
await channel.messages.fetch(panelRow.message_id);
@@ -62,24 +69,35 @@ module.exports = new Command({
} catch (err) {}
}
let embed = new EmbedBuilder()
.setTitle(panelconfig.PanelTitle)
.setColor(panelconfig.PanelColour)
.setFooter({
text: supportbot.Embed.Footer,
iconURL: interaction.user.displayAvatarURL(),
});
const panelContainer = new ContainerBuilder()
if (panelconfig.TicketPanel_Description) {
embed.setDescription(panelconfig.PanelMessage);
if (panelconfig.Style.Color) {
panelContainer.setAccentColor(
parseInt(panelconfig.Style.Color.replace("#", ""), 16)
)
}
if (panelconfig.TicketPanel_Thumbnail) {
embed.setThumbnail(panelconfig.PanelThumbnail);
const panelTitle = new TextDisplayBuilder().setContent(
panelconfig.Style.Title,
);
const topSeperator = new SeparatorBuilder()
.setDivider(true)
if (panelconfig.Settings.TopTitle) {
panelContainer.addTextDisplayComponents(panelTitle)
}
if (panelconfig.TicketPanel_Image) {
embed.setImage(panelconfig.PanelImage);
if (panelconfig.Settings.TopDivider) {
panelContainer.addSeparatorComponents(topSeperator)
}
const panelDesc = new TextDisplayBuilder().setContent(
panelconfig.Style.Description,
);
if (panelconfig.Style.Layout === "3") {
panelContainer.addTextDisplayComponents(panelDesc)
}
const createTicketButton = new ButtonBuilder()
@@ -88,12 +106,62 @@ module.exports = new Command({
.setEmoji(panelconfig.Button.Emoji)
.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 {
const message = await channel.send({
embeds: [embed],
components: [row],
flags: MessageFlags.IsComponentsV2,
components: [panelContainer],
});
db.saveTicketPanel(message.id, channel.id);