Compare commits

..
65 Commits
Author SHA1 Message Date
Noah 17ad1a15db Delete .DS_Store 2021-12-18 21:32:21 -06:00
Noah 4c89de9e76 Merge pull request #103 from Emerald-Services/dev
v7.4 Release
2021-12-18 21:31:56 -06:00
Noah 5f25af41f9 Merge branch 'release' into dev 2021-12-18 21:30:53 -06:00
Noah 3a3ee357fc Update packages 2021-12-18 21:17:06 -06:00
Noah 08a6d27903 Change to ephemeral 2021-12-18 20:56:30 -06:00
Noah 33f7675aac Added Max Ticket Count + Timeout 2021-12-18 20:54:01 -06:00
Noah 1178a0a611 Add StaffOnly close option 2021-12-18 19:39:59 -06:00
Noah 96ded77bec Fixed perms bug 2021-12-18 19:24:39 -06:00
Noah e83ca8cb2b add guild 2021-12-18 18:58:02 -06:00
Noah e507176d39 New addon handler 2021-12-18 18:57:45 -06:00
Noah 4e554b8bee rename slashCommandOptions to options, and permission to permissions 2021-12-18 18:57:26 -06:00
Noah bc649caa99 remove unused code 2021-12-18 18:56:25 -06:00
Noah f7a4c7b616 rename var + remove unused code 2021-12-18 18:56:02 -06:00
Noah 2c7be5882c Added getRole, getChannel, getCategory functions 2021-12-15 00:19:40 -06:00
Noah 6107d268f7 Fixed close + Send transcript to subusers 2021-12-14 18:04:38 -06:00
Noah 7760699155 Update node.js.yml 2021-12-04 21:30:48 -06:00
Noah acf349c72e Fix test mode 2021-12-04 21:26:55 -06:00
Noah 8096e5b882 Add npm test 2021-12-04 21:25:02 -06:00
Noah 873cfc7dc2 Merge branch 'dev' of https://github.com/Emerald-Services/SupportBot into dev 2021-12-04 21:22:10 -06:00
Noah 038174bc7e temp 2021-12-04 21:22:08 -06:00
Noah 14881096bb Update node.js.yml 2021-12-04 21:22:07 -06:00
Noah ed1905d8f4 Added test mode 2021-12-04 21:19:51 -06:00
Noah 72c0a2efa3 Update node.js.yml 2021-12-04 21:07:27 -06:00
Noah e599d48713 Update node.js.yml 2021-12-04 21:05:36 -06:00
Noah 7f44634d4f Delete prettier.yml 2021-12-04 21:04:47 -06:00
Noah 44170caac6 Update supportbot.yml 2021-12-04 21:01:34 -06:00
Noah adedfadd92 Prettier 2021-12-04 20:58:19 -06:00
Noah 6b01d0c8fe Possibly fix /close? 2021-12-04 20:57:23 -06:00
Noah d4d96f59ab Update 2021-12-04 20:25:49 -06:00
Noah a1bf7ed6bd Fix syntax 2021-12-04 20:25:35 -06:00
Noah 306e20efc9 Merge pull request #99 from DarkerInker/patch-1
wrong way to send embeds
2021-12-04 20:21:07 -06:00
Noah f593f6e0a8 Update close.js 2021-12-04 20:20:55 -06:00
DarkerInker 74646a4318 wrong way to send embeds
You are using the old way to send embeds. I'm not sure how you forgot about this one area but everyone makes mistakes :D
2021-12-02 13:52:07 -06:00
Noah 8bfcba8832 Merge pull request #97 from SypherRed/dev
fixed help command
2021-11-28 23:35:31 -06:00
SypherRed 4ba5621a4d Merge branch 'dev' into dev 2021-11-28 14:55:48 +01:00
N0ahMC 1f928324c2 Prettified Code! 2021-11-26 19:18:15 +00:00
Noah 3771872cd2 Update prettier.yml 2021-11-26 13:17:57 -06:00
Noah f359a60343 Update node.js.yml 2021-11-26 13:16:15 -06:00
Noah f53afd7bc9 Create prettier.yml 2021-11-26 13:13:15 -06:00
Noah e7dcc2ab29 Update help.js 2021-11-26 12:56:21 -06:00
SypherRed 0118b9e591 fixed help command 2021-11-25 01:51:56 +01:00
Noah ffe42f9777 Update ticket.js 2021-11-24 18:14:07 -06:00
Noah 5a467599e9 Update hello.js 2021-11-24 00:15:16 -06:00
Noah c56e78484a Update dependencies 2021-11-23 20:29:22 -06:00
Noah 1ee0d4a09e Update close.js 2021-11-23 18:09:06 -06:00
Noah ffdce5820b Fix close button 2021-11-23 18:08:45 -06:00
Noah 9fed504f37 Fixed /close 2021-11-23 17:37:25 -06:00
Noah 6c5799be0d Fix ID 2021-11-23 17:32:57 -06:00
Noah b6747a0340 Made warning ephemeral 2021-11-23 16:51:28 -06:00
Noah cd6df02e30 Changed TicketLog_Title 2021-11-23 15:50:56 -06:00
Noah edbef6a36f Fixed close command 2021-11-23 15:49:37 -06:00
Noah b6a0016f5f Changed TicketData Structure 2021-11-23 15:48:45 -06:00
Noah e740c17837 Update package-lock.json 2021-11-21 18:42:24 -06:00
Noah 7eb949f109 Better finds 2021-11-21 18:42:18 -06:00
Noah 02394e310d Exit if joins or leaves guild 2021-11-17 19:04:38 -06:00
Noah ef83832819 Added missing role and channel check 2021-11-17 19:04:20 -06:00
Noah a82101ab30 Register commands in Guild 2021-11-17 19:03:35 -06:00
Noah 007c78930e Added Guild to config 2021-11-17 19:03:11 -06:00
Noah 300c83512c Fixed token, and changed version for future 2021-11-11 17:18:30 -06:00
Noah b674872c56 Fixed Archive Bug 2021-11-10 21:41:12 -06:00
Noah 12a7680275 Fix spelling 2021-11-10 21:23:07 -06:00
Noah c9cf7c942b Prettier 2021-11-10 21:22:08 -06:00
Noah 8e0326c8f8 Removed HelpMenu 2021-11-10 21:21:50 -06:00
Noah 13972119a8 Update package-lock.json 2021-11-10 21:21:05 -06:00
Noah acf165a119 Add Button Emoji 2021-11-10 21:18:49 -06:00
30 changed files with 916 additions and 1000 deletions

No files matched your search

Vendored
BIN
View File
Binary file not shown.
+11 -9
View File
@@ -3,8 +3,7 @@ name: "\U0001F41B Bug report"
about: Create a report to help us improve about: Create a report to help us improve
title: "[BUG]" title: "[BUG]"
labels: Bug labels: Bug
assignees: '' assignees: ""
--- ---
**Describe the bug** **Describe the bug**
@@ -12,6 +11,7 @@ A clear and concise description of what the bug is.
**To Reproduce** **To Reproduce**
Steps to reproduce the behavior: Steps to reproduce the behavior:
1. Go to '...' 1. Go to '...'
2. Click on '....' 2. Click on '....'
3. Scroll down to '....' 3. Scroll down to '....'
@@ -24,15 +24,17 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem. If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):** **Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari] - OS: [e.g. iOS]
- Version [e.g. 22] - Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):** **Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1] - Device: [e.g. iPhone6]
- Browser [e.g. stock browser, safari] - OS: [e.g. iOS8.1]
- Version [e.g. 22] - Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context** **Additional context**
Add any other context about the problem here. Add any other context about the problem here.
+1 -2
View File
@@ -3,8 +3,7 @@ name: "❓Suggest an Idea?"
about: Suggest an idea for SupportBot? about: Suggest an idea for SupportBot?
title: "[SUGGESTION]" title: "[SUGGESTION]"
labels: Suggestion labels: Suggestion
assignees: '' assignees: ""
--- ---
**Is your feature request related to a problem? Please describe.** **Is your feature request related to a problem? Please describe.**
+4 -7
View File
@@ -5,9 +5,9 @@ name: Node.js CI
on: on:
push: push:
branches: [master] branches: [dev, release]
pull_request: pull_request:
branches: [master] branches: [dev, release]
jobs: jobs:
build: build:
@@ -15,7 +15,7 @@ jobs:
strategy: strategy:
matrix: matrix:
node-version: [10.x, 12.x, 14.x, 15.x] node-version: [16.x, 17.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/ # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps: steps:
@@ -25,7 +25,4 @@ jobs:
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
- run: npm ci - run: npm ci
- run: npm install discord.js --save - run: npm test
- run: npm install js-yaml
- run: npm run build --if-present
- run: node index.js
+30 -18
View File
@@ -10,24 +10,36 @@ const supportbot = yaml.load(
); );
const cmdconfig = yaml.load(fs.readFileSync("./Configs/commands.yml", "utf8")); const cmdconfig = yaml.load(fs.readFileSync("./Configs/commands.yml", "utf8"));
// Your Addon Config file! Saved in /Addons/Settings/YourAddonConfig.yml // Your Addon Config file! Saved in /Addons/Configs/YourAddonConfig.yml
// const exampleaddon = yaml.load(fs.readFileSync('./Addons/Settings/YourAddonConfig.yml', 'utf8')); // const config = yaml.load(fs.readFileSync('./Addons/Configs/YourAddonConfig.yml', 'utf8'));
const Command = require("../Structures/Command.js"); const { Command, Event } = require("../Structures/Addon");
module.exports = new Command({ module.exports.commands = [
name: "hello", /*
description: "hello", // EXAMPLE COMMAND
slashCommandOptions: [], new Command({
permission: "SEND_MESSAGES", name: "hello",
description: "hello",
options: [],
permissions: ["SEND_MESSAGES"],
async run(interaction) {
const Embed = new Discord.MessageEmbed()
.setDescription("Hello World!")
.setColor(supportbot.InfoColour);
async run(interaction) { interaction.reply({
const Embed = new Discord.MessageEmbed() embeds: [Embed],
.setDescription("Hello World!") });
.setColor(supportbot.InfoColour); },
}),
interaction.reply({ */
embeds: [Embed], ];
}); module.exports.events = [
}, /*
}); // EXAMPLE EVENT
new Event("ready", async (client) => {
console.log("Bot started!");
}),
*/
];
+52 -55
View File
@@ -12,16 +12,10 @@ const cmdconfig = yaml.load(fs.readFileSync("./Configs/commands.yml", "utf8"));
const Command = require("../Structures/Command.js"); const Command = require("../Structures/Command.js");
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
module.exports = new Command({ module.exports = new Command({
name: cmdconfig.TicketAdd, name: cmdconfig.TicketAdd,
description: cmdconfig.TicketAddDesc, description: cmdconfig.TicketAddDesc,
slashCommandOptions: [ options: [
{ {
name: "user", name: "user",
description: "User to add", description: "User to add",
@@ -29,22 +23,15 @@ module.exports = new Command({
required: true, required: true,
}, },
], ],
permission: "SEND_MESSAGES", permissions: ["SEND_MESSAGES"],
async run(interaction) { async run(interaction) {
let SupportStaff = const { getRole, getChannel, getCategory } = interaction.client;
interaction.guild.roles.cache.find( let SupportStaff = await getRole(supportbot.Staff, interaction.guild);
(SupportTeam) => SupportTeam.name === supportbot.Staff let Admin = await getRole(supportbot.Admin, interaction.guild);
) || if (!SupportStaff || !Admin)
interaction.guild.roles.cache.find( return interaction.reply(
(SupportTeam) => SupportTeam.id === supportbot.Staff "Some roles seem to be missing!\nPlease check for errors when starting the bot."
);
let Admins =
interaction.guild.roles.cache.find(
(AdminUser) => AdminUser.name === supportbot.Admin
) ||
interaction.guild.roles.cache.find(
(AdminUser) => AdminUser.id === supportbot.Admin
); );
const NoPerms = new Discord.MessageEmbed() const NoPerms = new Discord.MessageEmbed()
@@ -55,41 +42,51 @@ module.exports = new Command({
.setColor(supportbot.WarningColour); .setColor(supportbot.WarningColour);
if ( if (
interaction.member.roles.cache.has(SupportStaff.id) || !interaction.member.roles.cache.has(SupportStaff.id) &&
interaction.member.roles.cache.has(Admins.id) !interaction.member.roles.cache.has(Admin.id)
) { )
if (!interaction.channel.name.startsWith(`${supportbot.TicketPrefix}`)) {
const Exists = new Discord.MessageEmbed()
.setTitle("No Ticket Found!")
.setDescription(`${supportbot.NoValidTicket}`)
.setColor(supportbot.WarningColour);
return interaction.reply({ embeds: [Exists] });
}
let uMember = interaction.options.getUser("user");
const UserNotExist = new Discord.MessageEmbed()
.setTitle("User Not Found!")
.setDescription(
`${supportbot.UserNotFound}\n\nTry Again:\`/${cmdconfig.TicketAdd} <user#0000>\``
)
.setColor(supportbot.ErrorColour);
if (!uMember) return interaction.reply({ embeds: [UserNotExist] });
interaction.channel.permissionOverwrites.edit(uMember, {
VIEW_CHANNEL: true,
READ_MESSAGE_HISTORY: true,
SEND_MESSAGES: true,
});
const Complete = new Discord.MessageEmbed()
.setTitle("User Added!")
.setDescription(supportbot.AddedUser.replace(/%user%/g, uMember.id))
.setTimestamp()
.setColor(supportbot.EmbedColour);
interaction.reply({ embeds: [Complete] });
} else {
return interaction.reply({ embeds: [NoPerms] }); return interaction.reply({ embeds: [NoPerms] });
let TicketData = await JSON.parse(
fs.readFileSync("./Data/TicketData.json", "utf8")
);
let ticket = await TicketData.tickets.findIndex(
(t) => t.id == interaction.channel.id
);
if (ticket == -1) {
const Exists = new Discord.MessageEmbed()
.setTitle("No Ticket Found!")
.setDescription(`${supportbot.NoValidTicket}`)
.setColor(supportbot.WarningColour);
return interaction.reply({ embeds: [Exists] });
} }
let uMember = interaction.options.getUser("user");
const UserNotExist = new Discord.MessageEmbed()
.setTitle("User Not Found!")
.setDescription(
`${supportbot.UserNotFound}\n\nTry Again:\`/${cmdconfig.TicketAdd} <user#0000>\``
)
.setColor(supportbot.ErrorColour);
if (!uMember) return interaction.reply({ embeds: [UserNotExist] });
interaction.channel.permissionOverwrites.edit(uMember.id, {
VIEW_CHANNEL: true,
});
const Complete = new Discord.MessageEmbed()
.setTitle("User Added!")
.setDescription(supportbot.AddedUser.replace(/%user%/g, uMember.id))
.setTimestamp()
.setColor(supportbot.EmbedColour);
interaction.reply({ embeds: [Complete] });
TicketData.tickets[ticket].subUsers.push(uMember.id);
fs.writeFileSync(
"./Data/TicketData.json",
JSON.stringify(TicketData, null, 4),
(err) => {
if (err) console.error(err);
}
);
}, },
}); });
+135 -184
View File
@@ -11,35 +11,66 @@ const supportbot = yaml.load(
const cmdconfig = yaml.load(fs.readFileSync("./Configs/commands.yml", "utf8")); const cmdconfig = yaml.load(fs.readFileSync("./Configs/commands.yml", "utf8"));
const Command = require("../Structures/Command.js"); const Command = require("../Structures/Command.js");
const TicketNumberID = require("../Structures/TicketID.js");
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
module.exports = new Command({ module.exports = new Command({
name: cmdconfig.CloseTicket, name: cmdconfig.CloseTicket,
description: cmdconfig.CloseTicketDesc, description: cmdconfig.CloseTicketDesc,
slashCommandOptions: [ options: [
{ {
name: "reason", name: "reason",
description: "Ticket Close Reason", description: "Ticket Close Reason",
type: "STRING", type: "STRING",
}, },
], ],
permission: "SEND_MESSAGES", permissions: ["SEND_MESSAGES"],
async run(interaction) { async run(interaction) {
if (!interaction.channel.name.startsWith(`${supportbot.TicketPrefix}`)) { const { getRole, getChannel, getCategory } = interaction.client;
if (supportbot.StaffOnly) {
let SupportStaff = await getRole(supportbot.Staff, interaction.guild);
let Admin = await getRole(supportbot.Admin, interaction.guild);
if (!SupportStaff || !Admin)
return interaction.reply(
"Some roles seem to be missing!\nPlease check for errors when starting the bot."
);
const NoPerms = new Discord.MessageEmbed()
.setTitle("Invalid Permissions!")
.setDescription(
`${supportbot.IncorrectPerms}\n\nRole Required: \`${supportbot.Staff}\` or \`${supportbot.Admin}\``
)
.setColor(supportbot.WarningColour);
if (
!interaction.member.roles.cache.has(SupportStaff.id) &&
!interaction.member.roles.cache.has(Admin.id)
)
return interaction.reply({ embeds: [NoPerms] });
}
await interaction.deferReply();
let tickets = await JSON.parse(
fs.readFileSync("./Data/TicketData.json", "utf8")
).tickets.find((t) => t.id === interaction.channel.id);
let TicketData = await tickets.tickets.findIndex(
(t) => t.id == ticketChannel.id
);
if (!TicketData) {
const Exists = new Discord.MessageEmbed() const Exists = new Discord.MessageEmbed()
.setTitle("No Ticket Found!") .setTitle("No Ticket Found!")
.setDescription(`${supportbot.NoValidTicket}`) .setDescription(`${supportbot.NoValidTicket}`)
.setColor(supportbot.WarningColour); .setColor(supportbot.WarningColour);
return interaction.reply({ embed: Exists }); return interaction.followUp({ embeds: [Exists] });
} }
let tUser = interaction.client.users.cache.get(TicketData.user);
let transcriptChannel = await getChannel(
supportbot.TranscriptLog,
interaction.guild
);
let logChannel = await getChannel(supportbot.TicketLog, interaction.guild);
let reason =
(await interaction.options?.getString("reason")) || "No Reason Provided.";
if (!transcriptChannel || !logChannel)
return interaction.followUp("Some Channels seem to be missing!");
if (supportbot.CloseConfirmation) { if (supportbot.CloseConfirmation) {
const CloseTicketRequest = new Discord.MessageEmbed() const CloseTicketRequest = new Discord.MessageEmbed()
.setTitle(`**${supportbot.ClosingTicket}**`) .setTitle(`**${supportbot.ClosingTicket}**`)
@@ -47,185 +78,105 @@ module.exports = new Command({
`Please confirm by repeating the following word.. \`${supportbot.ClosingConfirmation_Word}\` ` `Please confirm by repeating the following word.. \`${supportbot.ClosingConfirmation_Word}\` `
) )
.setColor(supportbot.EmbedColour); .setColor(supportbot.EmbedColour);
await interaction.followUp({ embeds: [CloseTicketRequest] });
interaction let filter = (m) =>
.reply(CloseTicketRequest) m.content.toLowerCase() == supportbot.ClosingConfirmation_Word &&
.then((m) => { m.author.id == interaction.user.id;
interaction.channel await interaction.channel.awaitMessages({
.awaitMessages( filter,
(response) => max: 1,
response.content.toLowerCase() === time: 20000,
supportbot.ClosingConfirmation_Word, errors: ["time"],
{ });
max: 1,
time: 20000,
errors: ["time"],
}
)
.then((collected) => {
let logChannel =
interaction.guild.channels.cache.find(
(channel) => channel.name === supportbot.TranscriptLog
) ||
interaction.guild.channels.cache.find(
(channel) => channel.id === supportbot.TranscriptLog
);
let user = interaction.user;
let reason =
interaction.options.getString("reason") ||
"No Reason Provided.";
let name = interaction.channel.name;
let ticketChannel = interaction.channel;
interaction
.reply(`**${supportbot.ClosingTicket}**`)
.then(() => {
const logEmbed = new Discord.MessageEmbed()
.setTitle(supportbot.TranscriptTitle)
.setColor(supportbot.EmbedColour)
.setFooter(supportbot.EmbedFooter)
.addField("Closed By", interaction.user.tag)
.addField("Reason", reason);
interaction.channel.interactions
.fetch({ limit: 100 })
.then((msgs) => {
let html = "";
msgs = msgs.sort(
(a, b) => a.createdTimestamp - b.createdTimestamp
);
html += `<style>* {background-color: #2c2f33;color: #fff;font-family: Arial, Helvetica, sans-serif;}</style>`;
html += `<strong>Server Name:</strong> ${interaction.guild.name}<br>`;
html += `<strong>Ticket:</strong> ${ticketChannel.name}<br>`;
html += `<strong>Message:</strong> ${msgs.size} Messages<br><br><br>`;
msgs.forEach((msg) => {
if (msg.content) {
html += `<strong>User:</strong> ${msg.author.tag}<br>`;
html += `<strong>Message:</strong> ${msg.content}<br>`;
html += `-----<br><br>`;
}
});
logChannel.send({ embeds: [logEmbed] }).catch((err) => {
interaction.reply(err);
});
let file = new Discord.MessageAttachment(
Buffer.from(html),
`${name}.html`
);
logChannel
.send({ embeds: [logEmbed], files: [file] })
.catch((err) => {
interaction.reply(err);
});
interaction.channel.delete().catch((error) => {
if (
error.code !==
Discord.Constants.APIErrors.UNKNOWN_CHANNEL
) {
console.error(
"Failed to delete the interaction:",
error
);
}
});
});
});
});
})
.catch(() => {
interaction
.followUp({
content: "The request to close the ticket has timed out.",
})
.then((m2) => setTimeout(() => interaction.channel.delete(3000)));
});
} }
try {
tickets.tickets[TicketData].open = false;
fs.writeFileSync(
"./Data/TicketData.json",
JSON.stringify(tickets, null, 4),
(err) => {
if (err) console.error(err);
}
);
await interaction.followUp(`**${supportbot.ClosingTicket}**`);
const transcriptEmbed = new Discord.MessageEmbed()
.setTitle(supportbot.TranscriptTitle)
.setColor(supportbot.EmbedColour)
.setFooter(supportbot.EmbedFooter)
.addField(
"Ticket",
`${interaction.channel.name} (${interaction.channel.id})`
)
.addField(
"User",
`${tUser.username}#${tUser.discriminator} (${tUser.id})`
)
.addField("Closed By", interaction.user.tag)
.addField("Reason", reason);
const logEmbed = new Discord.MessageEmbed()
.setTitle(supportbot.TicketLog_Title)
.setColor(supportbot.EmbedColour)
.setFooter(supportbot.EmbedFooter)
.addField(
"Ticket",
`${interaction.channel.name} (${interaction.channel.id})`
)
.addField(
"User",
`${tUser.username}#${tUser.discriminator} (${tUser.id})`
)
.addField("Closed By", interaction.user.tag)
.addField("Reason", reason);
let msgs = await interaction.channel.messages.fetch();
let html = "";
if (!supportbot.CloseConfirmation) { msgs = msgs.sort((a, b) => a.createdTimestamp - b.createdTimestamp);
let logChannel = html += `<style>* {background-color: #2c2f33;color: #fff;font-family: Arial, Helvetica, sans-serif;}</style>`;
interaction.guild.channels.cache.find( html += `<strong>Server Name:</strong> ${interaction.guild.name}<br>`;
(channel) => channel.name === supportbot.TranscriptLog html += `<strong>Ticket:</strong> ${interaction.channel.name}<br>`;
) || html += `<strong>Message:</strong> ${msgs.size} Messages<br><br><br>`;
interaction.guild.channels.cache.find(
(channel) => channel.id === supportbot.TranscriptLog
);
let user = interaction.user;
let reason =
(await interaction.options.getString("reason")) ||
"No Reason Provided.";
let name = interaction.channel.name; await msgs.forEach((msg) => {
let ticketChannel = interaction.channel; if (msg.content) {
html += `<strong>User:</strong> ${msg.author.tag}<br>`;
html += `<strong>Message:</strong> ${msg.content}<br>`;
html += `-----<br><br>`;
}
});
interaction await logChannel.send({ embeds: [logEmbed] }).catch((err) => {
.reply(`**${supportbot.ClosingTicket}**`) console.error(err);
});
.then(() => { let file = new Discord.MessageAttachment(
const logEmbed = new Discord.MessageEmbed() Buffer.from(html),
.setTitle(supportbot.TranscriptTitle) `${interaction.channel.name}.html`
.setColor(supportbot.EmbedColour) );
.setFooter(supportbot.EmbedFooter) await transcriptChannel
.addField("Closed By", interaction.user.tag) .send({ embeds: [transcriptEmbed], files: [file] })
.addField("Reason", reason); .catch(async (err) => {
console.error(err);
interaction.channel.interactions
.fetch({ limit: 100 })
.then((msgs) => {
let html = "";
msgs = msgs.sort(
(a, b) => a.createdTimestamp - b.createdTimestamp
);
html += `<style>* {background-color: #2c2f33;color: #fff;font-family: Arial, Helvetica, sans-serif;}</style>`;
html += `<strong>Server Name:</strong> ${interaction.guild.name}<br>`;
html += `<strong>Ticket:</strong> ${ticketChannel.name}<br>`;
html += `<strong>Message:</strong> ${msgs.size} Messages<br><br><br>`;
msgs.forEach((msg) => {
if (msg.content) {
html += `<strong>User:</strong> ${msg.author.tag}<br>`;
html += `<strong>Message:</strong> ${msg.content}<br>`;
html += `-----<br><br>`;
}
});
logChannel.send({ embeds: [logEmbed] }).catch((err) => {
interaction.reply(err);
});
let file = new Discord.MessageAttachment(
Buffer.from(html),
`${name}.html`
);
logChannel
.send({ embeds: [logEmbed], files: [file] })
.catch((err) => {
interaction.reply(err);
});
interaction.channel.delete().catch((error) => {
if (
error.code !== Discord.Constants.APIErrors.UNKNOWN_CHANNEL
) {
console.error("Failed to delete the interaction:", error);
}
});
});
})
.catch(() => {
interaction
.followUp({
content: "The request to close the ticket has timed out.",
})
.then((m2) => setTimeout(() => interaction.channel.delete(3000)));
}); });
await tUser
.send({ embeds: [transcriptEmbed], files: [file] })
.catch(async (err) => {
console.error(err);
});
if (TicketData.subUsers) {
TicketData.subUsers.forEach(async (subUser) => {
interaction.client.users.cache
.get(subUser)
.send({ embeds: [transcriptEmbed], files: [file] });
});
}
await interaction.channel.delete().catch(async (error) => {
console.error(error);
if (error.code !== Discord.Constants.APIErrors.UNKNOWN_CHANNEL) {
console.error("Failed to delete the interaction:", error);
}
});
} catch (error) {
console.error(error);
} }
}, },
}); });
+10 -17
View File
@@ -15,7 +15,7 @@ const Command = require("../Structures/Command.js");
module.exports = new Command({ module.exports = new Command({
name: cmdconfig.EmbedCommand, name: cmdconfig.EmbedCommand,
description: cmdconfig.EmbedCommandDesc, description: cmdconfig.EmbedCommandDesc,
slashCommandOptions: [ options: [
{ {
name: "title", name: "title",
description: "Embed Title", description: "Embed Title",
@@ -28,24 +28,17 @@ module.exports = new Command({
type: "STRING", type: "STRING",
}, },
], ],
permission: "SEND_MESSAGES", permissions: ["SEND_MESSAGES"],
async run(interaction) { async run(interaction) {
let SupportStaff = const { getRole, getChannel, getCategory } = interaction.client;
interaction.guild.roles.cache.find( let SupportStaff = await getRole(supportbot.Staff, interaction.guild);
(SupportTeam) => SupportTeam.name === supportbot.Staff let Admin = await getRole(supportbot.Admin, interaction.guild);
) ||
interaction.guild.roles.cache.find(
(SupportTeam) => SupportTeam.id === supportbot.Staff
);
let Admins =
interaction.guild.roles.cache.find(
(AdminUser) => AdminUser.name === supportbot.Admin
) ||
interaction.guild.roles.cache.find(
(AdminUser) => AdminUser.id === supportbot.Admin
);
if (!SupportStaff || !Admin)
return interaction.reply(
"Some roles seem to be missing!\nPlease check for errors when starting the bot."
);
const NoPerms = new Discord.MessageEmbed() const NoPerms = new Discord.MessageEmbed()
.setTitle("Invalid Permissions!") .setTitle("Invalid Permissions!")
.setDescription( .setDescription(
@@ -55,7 +48,7 @@ module.exports = new Command({
if ( if (
interaction.member.roles.cache.has(SupportStaff.id) || interaction.member.roles.cache.has(SupportStaff.id) ||
interaction.member.roles.cache.has(Admins.id) interaction.member.roles.cache.has(Admin.id)
) { ) {
const EmbedTitle = interaction.options.getString("title"); const EmbedTitle = interaction.options.getString("title");
const EmbedSubject = interaction.options.getString("message"); const EmbedSubject = interaction.options.getString("message");
+54 -68
View File
@@ -21,86 +21,72 @@ async function asyncForEach(array, callback) {
module.exports = new Command({ module.exports = new Command({
name: cmdconfig.HelpCommand, name: cmdconfig.HelpCommand,
description: cmdconfig.HelpCommandDesc, description: cmdconfig.HelpCommandDesc,
slashCommandOptions: [], options: [],
permission: "SEND_MESSAGES", permissions: ["SEND_MESSAGES"],
async run(interaction) { async run(interaction) {
let SupportStaff = const { getRole, getChannel, getCategory } = interaction.client;
interaction.guild.roles.cache.find( let SupportStaff = await getRole(supportbot.Staff, interaction.guild);
(adminRole) => adminRole.name === supportbot.Staff let Admin = await getRole(supportbot.Admin, interaction.guild);
) || if (!SupportStaff || !Admin)
interaction.guild.roles.cache.find( return interaction.reply(
(staffRole) => staffRole.id === supportbot.Staff "Some roles seem to be missing!\nPlease check for errors when starting the bot."
);
let AdminStaff =
interaction.guild.roles.cache.find(
(adminRole) => adminRole.name === supportbot.Admin
) ||
interaction.guild.roles.cache.find(
(adminRole) => adminRole.id === supportbot.Admin
); );
if (supportbot.HelpMenu) { let botCommands = "";
let botCommands = ""; botCommands += `**/${cmdconfig.HelpCommand}** ${cmdconfig.HelpCommandDesc}\n`;
botCommands += `**/${cmdconfig.HelpCommand}** ${cmdconfig.HelpCommandDesc}\n`; botCommands += `**/${cmdconfig.InfoCommand}** ${cmdconfig.InfoCommandDesc}\n`;
botCommands += `**/${cmdconfig.InfoCommand}** ${cmdconfig.InfoCommandDesc}\n`; botCommands += `**/${cmdconfig.PingCommand}** ${cmdconfig.PingCommandDesc}\n`;
botCommands += `**/${cmdconfig.PingCommand}** ${cmdconfig.PingCommandDesc}\n`;
let ticketCommands = ""; let ticketCommands = "";
ticketCommands += `**/${cmdconfig.OpenTicket}** ${cmdconfig.OpenTicketDesc}\n`; ticketCommands += `**/${cmdconfig.OpenTicket}** ${cmdconfig.OpenTicketDesc}\n`;
ticketCommands += `**/${cmdconfig.CloseTicket}** ${cmdconfig.CloseTicketDesc}\n`; ticketCommands += `**/${cmdconfig.CloseTicket}** ${cmdconfig.CloseTicketDesc}\n`;
let staffCommands = ""; let staffCommands = "";
staffCommands += `**/${cmdconfig.TicketAdd}** ${cmdconfig.TicketAddDesc}\n`; staffCommands += `**/${cmdconfig.TicketAdd}** ${cmdconfig.TicketAddDesc}\n`;
staffCommands += `**/${cmdconfig.TicketRemove}** ${cmdconfig.TicketRemoveDesc}\n`; staffCommands += `**/${cmdconfig.TicketRemove}** ${cmdconfig.TicketRemoveDesc}\n`;
const HelpEmbed1 = new Discord.MessageEmbed() const HelpEmbed1 = new Discord.MessageEmbed()
.setTitle(supportbot.Name + " Commands") .setTitle(supportbot.Name + " Commands")
.setThumbnail(interaction.user.displayAvatarURL()) .setThumbnail(interaction.user.displayAvatarURL())
.addFields( .addFields(
{ {
name: "🖥️ General Commands\n", name: "🖥️ General Commands\n",
value: `${botCommands}\n`, value: `${botCommands}\n`,
inline: false, inline: false,
}, },
{ {
name: "🎫 Support Commands\n", name: "🎫 Support Commands\n",
value: `${ticketCommands}\n`, value: `${ticketCommands}\n`,
inline: false,
}
)
.setColor(supportbot.EmbedColour)
.setFooter(supportbot.EmbedFooter, interaction.user.displayAvatarURL());
if (interaction.member.roles.cache.has(SupportStaff.id)) {
HelpEmbed1.addFields({
name: "🔐 Staff Commands\n",
value: `${staffCommands}\n`,
inline: false, inline: false,
});
} else {
if (interaction.member.roles.cache.has(AdminStaff.id)) {
HelpEmbed1.addFields({
name: "🔐 Staff Commands\n",
value: `${staffCommands}\n`,
inline: false,
});
} }
} )
if (supportbot.SendHelpPage === "dm") { .setColor(supportbot.EmbedColour)
interaction.user.reply({ .setFooter(supportbot.EmbedFooter, interaction.user.displayAvatarURL());
embeds: [HelpEmbed1],
});
}
if (supportbot.SendHelpPage === "channel") { if (
interaction.reply({ interaction.member.roles.cache.has(SupportStaff.id) ||
embeds: [HelpEmbed1], interaction.member.roles.cache.has(Admin.id)
}); ) {
} HelpEmbed1.addFields({
name: "🔐 Staff Commands\n",
value: `${staffCommands}\n`,
inline: false,
});
}
if (supportbot.SendHelpPage === "dm") {
interaction.user.reply({
embeds: [HelpEmbed1],
});
}
if (supportbot.SendHelpPage === "channel") {
interaction.reply({
embeds: [HelpEmbed1],
});
} }
}, },
}); });
+2 -2
View File
@@ -15,8 +15,8 @@ const Command = require("../Structures/Command.js");
module.exports = new Command({ module.exports = new Command({
name: cmdconfig.InfoCommand, name: cmdconfig.InfoCommand,
description: cmdconfig.InfoCommandDesc, description: cmdconfig.InfoCommandDesc,
slashCommandOptions: [], options: [],
permission: "SEND_MESSAGES", permissions: ["SEND_MESSAGES"],
async run(interaction) { async run(interaction) {
const InfoButton = new Discord.MessageButton() const InfoButton = new Discord.MessageButton()
+2 -2
View File
@@ -15,8 +15,8 @@ const Command = require("../Structures/Command.js");
module.exports = new Command({ module.exports = new Command({
name: cmdconfig.PingCommand, name: cmdconfig.PingCommand,
description: cmdconfig.PingCommandDesc, description: cmdconfig.PingCommandDesc,
slashCommandOptions: [], options: [],
permission: "SEND_MESSAGES", permissions: ["SEND_MESSAGES"],
async run(interaction) { async run(interaction) {
const PingEmbed = new Discord.MessageEmbed() const PingEmbed = new Discord.MessageEmbed()
+54 -49
View File
@@ -21,7 +21,7 @@ async function asyncForEach(array, callback) {
module.exports = new Command({ module.exports = new Command({
name: cmdconfig.TicketRemove, name: cmdconfig.TicketRemove,
description: cmdconfig.TicketRemoveDesc, description: cmdconfig.TicketRemoveDesc,
slashCommandOptions: [ options: [
{ {
name: "user", name: "user",
description: "User to remove", description: "User to remove",
@@ -29,22 +29,15 @@ module.exports = new Command({
required: true, required: true,
}, },
], ],
permission: "SEND_MESSAGES", permissions: ["SEND_MESSAGES"],
async run(interaction) { async run(interaction) {
let SupportStaff = const { getRole, getChannel, getCategory } = interaction.client;
interaction.guild.roles.cache.find( let Staff = await getRole(supportbot.Staff, interaction.guild);
(SupportTeam) => SupportTeam.name === supportbot.Staff let Admin = await getRole(supportbot.Admin, interaction.guild);
) || if (!Staff || !Admin)
interaction.guild.roles.cache.find( return interaction.reply(
(SupportTeam) => SupportTeam.id === supportbot.Staff "Some roles seem to be missing!\nPlease check for errors when starting the bot."
);
let Admins =
interaction.guild.roles.cache.find(
(AdminUser) => AdminUser.name === supportbot.Admin
) ||
interaction.guild.roles.cache.find(
(AdminUser) => AdminUser.id === supportbot.Admin
); );
const NoPerms = new Discord.MessageEmbed() const NoPerms = new Discord.MessageEmbed()
@@ -55,41 +48,53 @@ module.exports = new Command({
.setColor(supportbot.WarningColour); .setColor(supportbot.WarningColour);
if ( if (
interaction.member.roles.cache.has(SupportStaff.id) || !interaction.member.roles.cache.has(Staff.id) &&
interaction.member.roles.cache.has(Admins.id) !interaction.member.roles.cache.has(Admin.id)
) { )
if (!interaction.channel.name.startsWith(`${supportbot.TicketPrefix}`)) {
const Exists = new Discord.MessageEmbed()
.setTitle("No Ticket Found!")
.setDescription(`${supportbot.NoValidTicket}`)
.setColor(supportbot.WarningColour);
return interaction.reply({ embeds: [Exists] });
}
let uMember = interaction.options.getUser("user");
const UserNotExist = new Discord.MessageEmbed()
.setTitle("User Not Found!")
.setDescription(
`${supportbot.UserNotFound}\n\nTry Again:\`/${cmdconfig.TicketRemove} <user#0000>\``
)
.setColor(supportbot.ErrorColour);
if (!uMember) return interaction.reply({ embeds: [UserNotExist] });
interaction.channel.permissionOverwrites.edit(uMember, {
VIEW_CHANNEL: false,
READ_MESSAGE_HISTORY: false,
SEND_MESSAGES: false,
});
const Complete = new Discord.MessageEmbed()
.setTitle("User Removed!")
.setDescription(supportbot.RemovedUser.replace(/%user%/g, uMember.id))
.setTimestamp()
.setColor(supportbot.EmbedColour);
interaction.reply({ embeds: [Complete] });
} else {
return interaction.reply({ embeds: [NoPerms] }); return interaction.reply({ embeds: [NoPerms] });
let TicketData = await JSON.parse(
fs.readFileSync("./Data/TicketData.json", "utf8")
);
let ticket = await TicketData.tickets.findIndex(
(t) => t.id == interaction.channel.id
);
if (ticket == -1) {
const Exists = new Discord.MessageEmbed()
.setTitle("No Ticket Found!")
.setDescription(`${supportbot.NoValidTicket}`)
.setColor(supportbot.WarningColour);
return interaction.reply({ embeds: [Exists] });
} }
let uMember = interaction.options.getUser("user");
const UserNotExist = new Discord.MessageEmbed()
.setTitle("User Not Found!")
.setDescription(
`${supportbot.UserNotFound}\n\nTry Again:\`/${cmdconfig.TicketRemove} <user#0000>\``
)
.setColor(supportbot.ErrorColour);
if (!uMember) return interaction.reply({ embeds: [UserNotExist] });
interaction.channel.permissionOverwrites.edit(uMember.id, {
VIEW_CHANNEL: false,
});
const Complete = new Discord.MessageEmbed()
.setTitle("User Removed!")
.setDescription(supportbot.RemovedUser.replace(/%user%/g, uMember.id))
.setTimestamp()
.setColor(supportbot.EmbedColour);
interaction.reply({ embeds: [Complete] });
TicketData.tickets[ticket].subUsers = TicketData.tickets[
ticket
].subUsers.filter((u) => u != uMember.id);
fs.writeFileSync(
"./Data/TicketData.json",
JSON.stringify(TicketData, null, 4),
(err) => {
if (err) console.error(err);
}
);
}, },
}); });
+7 -9
View File
@@ -15,23 +15,21 @@ const Command = require("../Structures/Command.js");
module.exports = new Command({ module.exports = new Command({
name: cmdconfig.SuggestCommand, name: cmdconfig.SuggestCommand,
description: cmdconfig.SuggestCommandDesc, description: cmdconfig.SuggestCommandDesc,
slashCommandOptions: [ options: [
{ {
name: "suggestion", name: "suggestion",
description: "Create a Suggestion", description: "Create a Suggestion",
type: "STRING", type: "STRING",
}, },
], ],
permission: "SEND_MESSAGES", permissions: ["SEND_MESSAGES"],
async run(interaction) { async run(interaction) {
const suggestChannel = const { getRole, getChannel, getCategory } = interaction.client;
interaction.guild.channels.cache.find( const suggestChannel = await getChannel(
(channel) => channel.name === supportbot.SuggestionChannel supportbot.SuggestionChannel,
) || interaction.guild
interaction.guild.channels.cache.find( );
(channel) => channel.id === supportbot.SuggestionChannel
);
const NoChannel = new Discord.MessageEmbed() const NoChannel = new Discord.MessageEmbed()
.setTitle("Missing Channel!") .setTitle("Missing Channel!")
+208 -249
View File
@@ -3,7 +3,12 @@
const fs = require("fs"); const fs = require("fs");
const Discord = require("discord.js"); const {
MessageEmbed,
Permissions,
MessageButton,
MessageActionRow,
} = require("discord.js");
const yaml = require("js-yaml"); const yaml = require("js-yaml");
const supportbot = yaml.load( const supportbot = yaml.load(
fs.readFileSync("./Configs/supportbot.yml", "utf8") fs.readFileSync("./Configs/supportbot.yml", "utf8")
@@ -13,52 +18,60 @@ const cmdconfig = yaml.load(fs.readFileSync("./Configs/commands.yml", "utf8"));
const Command = require("../Structures/Command.js"); const Command = require("../Structures/Command.js");
const TicketNumberID = require("../Structures/TicketID.js"); const TicketNumberID = require("../Structures/TicketID.js");
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
module.exports = new Command({ module.exports = new Command({
name: cmdconfig.OpenTicket, name: cmdconfig.OpenTicket,
description: cmdconfig.OpenTicketDesc, description: cmdconfig.OpenTicketDesc,
slashCommandOptions: [ options: [
{ {
name: "reason", name: "reason",
description: "Ticket Reason", description: "Ticket Reason",
type: "STRING", type: "STRING",
}, },
], ],
permission: "SEND_MESSAGES", permissions: ["SEND_MESSAGES"],
async run(interaction) { async run(interaction) {
let reactionUser = interaction.guild.members.cache.get(interaction.user.id); let TicketData = await JSON.parse(
fs.readFileSync("./Data/TicketData.json", "utf8")
);
const { getRole, getChannel, getCategory } = interaction.client;
let User = interaction.guild.members.cache.get(interaction.user.id);
if ( if (
reactionUser.roles.cache.find( supportbot.MaxAllowedTickets &&
(role) => role.name === supportbot.TicketBlackListRole TicketData.tickets.filter((t) => t.user == interaction.user.id && t.open)
) || .length >= supportbot.MaxAllowedTickets
reactionUser.roles.cache.find( ) {
(role) => role.id === supportbot.TicketBlackListRole return interaction.reply({
embeds: [
{
title: "Too Many Tickets!",
description: `You can't have more than ${supportbot.MaxAllowedTickets} open tickets!`,
color: supportbot.WarningColour,
},
],
ephemeral: true,
});
}
if (
User.roles.cache.has(
getRole(supportbot.TicketBlackListRole, interaction.guild).id
) )
) { ) {
return interaction return interaction.reply({
.reply({ content: supportbot.TicketBlackListMessage,
content: `<@${interaction.user.id}> ${supportbot.TicketBlackListMessage}`, ephemeral: true,
}) });
.then((msg) => {
setTimeout(() => msg.delete(), 3500);
});
} }
// Ticket ID // Ticket ID
let ticketNumberID = TicketNumberID.pad(interaction.guild.id); let ticketNumberID = await TicketNumberID.pad();
// Ticket Subject // Ticket Subject
const TicketSubject = const TicketSubject =
interaction.options?.getString("reason") || supportbot.NoTicketSubject; interaction.options?.getString("reason") || supportbot.NoTicketSubject;
const TicketExists = new Discord.MessageEmbed() const TicketExists = new MessageEmbed()
.setTitle("Ticket Exists!") .setTitle("Ticket Exists!")
.setDescription(`${supportbot.TicketExists}`) .setDescription(`${supportbot.TicketExists}`)
.setColor(supportbot.WarningColour); .setColor(supportbot.WarningColour);
@@ -68,112 +81,94 @@ module.exports = new Command({
ticketChannel.name === `${supportbot.TicketPrefix}${ticketNumberID}`; ticketChannel.name === `${supportbot.TicketPrefix}${ticketNumberID}`;
}) })
) { ) {
return interaction.reply({ embeds: [TicketExists] }); return await interaction.reply({ embeds: [TicketExists] });
} }
const Staff = const Staff = await getRole(supportbot.Staff, interaction.guild);
interaction.guild.roles.cache.find( const Admin = await getRole(supportbot.Admin, interaction.guild);
(SupportTeam) => SupportTeam.name === supportbot.Staff const DeptRole1 = await getRole(
) || supportbot.DepartmentRole_1,
interaction.guild.roles.cache.find( interaction.guild
(SupportTeam) => SupportTeam.id === supportbot.Staff );
); const DeptRole2 = await getRole(
const Admins = supportbot.DepartmentRole_2,
interaction.guild.roles.cache.find( interaction.guild
(AdminUser) => AdminUser.name === supportbot.Admin );
) || const DeptRole3 = await getRole(
interaction.guild.roles.cache.find( supportbot.DepartmentRole_3,
(AdminUser) => AdminUser.id === supportbot.Admin interaction.guild
); );
const DeptRole1 = if (!Staff || !Admin || !DeptRole1 || !DeptRole2 || !DeptRole3)
interaction.guild.roles.cache.find( return interaction.reply({
(DepartmentRole) => content:
DepartmentRole.name === `${supportbot.DepartmentRole_1}` "Some roles seem to be missing!\nPlease check for errors when starting the bot.",
) || ephemeral: true,
interaction.guild.roles.cache.find( });
(DepartmentRole) =>
DepartmentRole.id === `${supportbot.DepartmentRole_1}`
);
const DeptRole2 =
interaction.guild.roles.cache.find(
(DepartmentRole) =>
DepartmentRole.name === `${supportbot.DepartmentRole_2}`
) ||
interaction.guild.roles.cache.find(
(DepartmentRole) =>
DepartmentRole.id === `${supportbot.DepartmentRole_2}`
);
const DeptRole3 =
interaction.guild.roles.cache.find(
(DepartmentRole) =>
DepartmentRole.name === `${supportbot.DepartmentRole_3}`
) ||
interaction.guild.roles.cache.find(
(DepartmentRole) =>
DepartmentRole.id === `${supportbot.DepartmentRole_3}`
);
const Author = interaction.user; const Author = interaction.user;
const Everyone = interaction.guild.id; let TicketCategory = await getCategory(
supportbot.TicketCategory,
interaction.guild
);
const ticketChannel = await interaction.guild.channels.create( const ticketChannel = await interaction.guild.channels.create(
`${supportbot.TicketPrefix}${ticketNumberID}`, `${supportbot.TicketPrefix}${ticketNumberID}`,
{ {
type: "GUILD_TEXT", type: "GUILD_TEXT",
parent: TicketCategory.id,
permissionOverwrites: [
{
id: Admin.id,
allow: [Permissions.FLAGS.VIEW_CHANNEL],
},
{
id: Author.id,
allow: [Permissions.FLAGS.VIEW_CHANNEL],
deny: [Permissions.FLAGS.SEND_MESSAGES],
},
{
id: interaction.guild.id,
deny: [Permissions.FLAGS.VIEW_CHANNEL],
},
],
}
);
if (supportbot.AllowStaff) {
ticketChannel.permissionOverwrites.edit(Staff.id, {
VIEW_CHANNEL: true,
});
}
await TicketData.tickets.push({
id: ticketChannel.id,
name: ticketChannel.name,
user: Author.id,
number: ticketNumberID,
reason: TicketSubject,
open: true,
subUsers: [],
});
fs.writeFileSync(
"./Data/TicketData.json",
JSON.stringify(TicketData, null, 4),
(err) => {
if (err) console.error(err);
} }
); );
if ( const CreatedTicket = new MessageEmbed()
interaction.channel.name === supportbot.ReactionChannel || .setDescription(
interaction.channel.id === supportbot.ReactionChannel supportbot.TicketCreatedAlert.replace(
) { /%ticketauthor%/g,
const CreatedTicket = new Discord.MessageEmbed() interaction.user.id
.setDescription(
supportbot.TicketCreatedAlert.replace(
/%ticketauthor%/g,
interaction.user.id
)
.replace(/%ticketid%/g, ticketChannel.id)
.replace(/%ticketusername%/g, interaction.user.username)
) )
.setColor(supportbot.EmbedColour); .replace(/%ticketid%/g, ticketChannel.id)
interaction.reply({ embeds: [CreatedTicket], ephemeral: true }); .replace(/%ticketusername%/g, interaction.user.username)
} else { )
const CreatedTicket = new Discord.MessageEmbed() .setColor(supportbot.EmbedColour);
.setDescription( await interaction.reply({ embeds: [CreatedTicket], ephemeral: true });
supportbot.TicketCreatedAlert.replace(
/%ticketauthor%/g,
interaction.user.id
)
.replace(/%ticketid%/g, ticketChannel.id)
.replace(/%ticketusername%/g, interaction.user.username)
)
.setColor(supportbot.EmbedColour);
interaction.reply({ embeds: [CreatedTicket], ephemeral: true });
}
let AllowArr = [Staff, Staff, Admins, Author];
await asyncForEach(AllowArr, (index) => {
ticketChannel.permissionOverwrites.create(index, { VIEW_CHANNEL: true });
});
let DenyArr = [Everyone];
await asyncForEach(DenyArr, (index) => {
ticketChannel.permissionOverwrites.create(index, { VIEW_CHANNEL: false });
});
let TicketCategory =
interaction.guild.channels.cache.find(
(category) => category.name === supportbot.TicketCategory
) ||
interaction.guild.channels.cache.find(
(category) => category.id === supportbot.TicketCategory
);
if (TicketCategory) {
ticketChannel.setParent(TicketCategory.id);
}
if (supportbot.AllowTicketMentions) { if (supportbot.AllowTicketMentions) {
ticketChannel.send({ content: `${interaction.user}` }); await ticketChannel.send(`${interaction.user}`);
} }
const TicketMessage = new Discord.MessageEmbed() const TicketMessage = new MessageEmbed()
.setTitle( .setTitle(
supportbot.Ticket_Title.replace(/%ticketauthor%/g, interaction.user.id) supportbot.Ticket_Title.replace(/%ticketauthor%/g, interaction.user.id)
.replace(/%ticketid%/g, ticketChannel.id) .replace(/%ticketid%/g, ticketChannel.id)
@@ -194,7 +189,7 @@ module.exports = new Command({
if (supportbot.TicketSubject === "description") { if (supportbot.TicketSubject === "description") {
if (TicketSubject != "No Reason Provided.") { if (TicketSubject != "No Reason Provided.") {
ticketChannel.setTopic( await ticketChannel.setTopic(
`Reason: ${TicketSubject} - User ID: ${interaction.user.id} - Ticket: ${ticketChannel.name}` `Reason: ${TicketSubject} - User ID: ${interaction.user.id} - Ticket: ${ticketChannel.name}`
); );
} }
@@ -206,157 +201,121 @@ module.exports = new Command({
value: ` **${supportbot.DepartmentTitle_1}**\n **${supportbot.DepartmentTitle_2}**\n **${supportbot.DepartmentTitle_3}**`, value: ` **${supportbot.DepartmentTitle_1}**\n **${supportbot.DepartmentTitle_2}**\n **${supportbot.DepartmentTitle_3}**`,
}); });
} }
const CloseButton = new Discord.MessageButton() const CloseButton = new MessageButton()
.setCustomId("ticketclose") .setCustomId("ticketclose")
.setLabel("Close") .setLabel("Close")
.setStyle(supportbot.TicketCloseColour) .setStyle(supportbot.TicketCloseColour)
.setEmoji(supportbot.TicketCloseEmoji); .setEmoji(supportbot.TicketCloseEmoji);
const LockButton = new Discord.MessageButton() const LockButton = new MessageButton()
.setCustomId("ticketlock") .setCustomId("ticketlock")
.setLabel("Lock") .setLabel("Lock")
.setStyle(supportbot.TicketLockColour) .setStyle(supportbot.TicketLockColour)
.setEmoji(supportbot.TicketLockEmoji); .setEmoji(supportbot.TicketLockEmoji);
const row2 = new Discord.MessageActionRow().addComponents( const row2 = new MessageActionRow().addComponents(CloseButton, LockButton);
CloseButton,
LockButton
);
if (supportbot.TicketDepartments) { if (supportbot.TicketDepartments) {
let DenyArr = [DeptRole1, DeptRole2, DeptRole3]; try {
await asyncForEach(DenyArr, (index) => { const Department1Button = new MessageButton()
ticketChannel.permissionOverwrites.create(index, { .setCustomId("Department1")
VIEW_CHANNEL: false, .setLabel(supportbot.DepartmentTitle_1)
.setStyle(supportbot.TicketDept1Colour)
.setEmoji(supportbot.TicketDept1Emoji);
const Department2Button = new MessageButton()
.setCustomId("Department2")
.setLabel(supportbot.DepartmentTitle_2)
.setStyle(supportbot.TicketDept2Colour)
.setEmoji(supportbot.TicketDept2Emoji);
const Department3Button = new MessageButton()
.setCustomId("Department3")
.setLabel(supportbot.DepartmentTitle_3)
.setStyle(supportbot.TicketDept3Colour)
.setEmoji(supportbot.TicketDept3Emoji);
const row = new MessageActionRow().addComponents(
Department1Button,
Department2Button,
Department3Button
);
const m = await ticketChannel.send({
embeds: [TicketMessage],
components: [row],
}); });
});
const Department1Button = new Discord.MessageButton()
.setCustomId("Department1")
.setLabel(`${supportbot.DepartmentTitle_1}`)
.setStyle(supportbot.TicketDept1Colour)
.setEmoji(supportbot.TicketDept1Emoji);
const Department2Button = new Discord.MessageButton() const filter = (i) => i.user.id === interaction.user.id;
.setCustomId("Department2") let collector;
.setLabel(`${supportbot.DepartmentTitle_2}`) try {
.setStyle(supportbot.TicketDept2Colour) collector = await m.awaitMessageComponent({
.setEmoji(supportbot.TicketDept2Emoji); filter,
max: 1,
const Department3Button = new Discord.MessageButton() componentType: "BUTTON",
.setCustomId("Department3") time: supportbot.Timeout * 60000,
.setLabel(`${supportbot.DepartmentTitle_3}`)
.setStyle(supportbot.TicketDept3Colour)
.setEmoji(supportbot.TicketDept3Emoji);
const row = new Discord.MessageActionRow().addComponents(
Department1Button,
Department2Button,
Department3Button
);
const m = await ticketChannel.send({
embeds: [TicketMessage],
components: [row],
});
const filter = (i) => {
i.deferUpdate();
return i.user.id === interaction.user.id;
};
const collector = m.createMessageComponentCollector({
filter,
max: 1,
componentType: "BUTTON",
time: 60000,
});
collector.on("collect", async (i) => {
if (i.customId === "Department1") {
ticketChannel.permissionOverwrites.edit(DeptRole1, {
VIEW_CHANNEL: true,
READ_MESSAGE_HISTORY: true,
SEND_MESSAGES: true,
}); });
} catch (e) {
if (!supportbot.AllowStaff) { if (e.code == "INTERACTION_COLLECTOR_ERROR")
ticketChannel.permissionOverwrites.edit(Staff, { try {
VIEW_CHANNEL: false, let ticket = await TicketData.tickets.findIndex(
READ_MESSAGE_HISTORY: false, (t) => t.id == ticketChannel.id
SEND_MESSAGES: false, );
}); TicketData.tickets[ticket].open = false;
} fs.writeFileSync(
"./Data/TicketData.json",
const Department1 = new Discord.MessageEmbed() JSON.stringify(TicketData, null, 4),
.setDescription( (err) => {
`> Thank for reaching out to the **${supportbot.DepartmentTitle_1} Department**. Please provide us information regarding your query.` if (err) console.error(err);
) }
.setColor(supportbot.EmbedColour); );
ticketChannel.send({ embeds: [Department1] }); interaction.user.send(
"Your ticket has timed out. Please open a new one, and select a department."
if (supportbot.AllowTicketMentions) { );
ticketChannel.send({ content: `@here` }); } catch (e) {}
} return await ticketChannel.delete();
} }
i.message.edit({ embeds: [TicketMessage], components: [row2] }); let role;
let title;
if (i.customId === "Department2") { if (collector.customId === "Department1") {
ticketChannel.permissionOverwrites.edit(DeptRole2, { role = DeptRole1;
VIEW_CHANNEL: true, title = supportbot.DepartmentTitle_1;
READ_MESSAGE_HISTORY: true,
SEND_MESSAGES: true,
});
if (!supportbot.AllowStaff) {
ticketChannel.permissionOverwrites.edit(Staff, {
VIEW_CHANNEL: false,
READ_MESSAGE_HISTORY: false,
SEND_MESSAGES: false,
});
}
const Department2 = new Discord.MessageEmbed()
.setDescription(
`> Thank for reaching out to the **${supportbot.DepartmentTitle_2} Department**. Please provide us information regarding your query.`
)
.setColor(supportbot.EmbedColour);
ticketChannel.send({ embeds: [Department2] });
if (supportbot.AllowTicketMentions) {
ticketChannel.send({ content: `@here` });
}
i.message.edit({ embeds: [TicketMessage], components: [row2] });
} }
if (i.customId === "Department3") { if (collector.customId === "Department2") {
ticketChannel.permissionOverwrites.edit(DeptRole3, { role = DeptRole2;
VIEW_CHANNEL: true, title = supportbot.DepartmentTitle_2;
READ_MESSAGE_HISTORY: true,
SEND_MESSAGES: true,
});
if (!supportbot.AllowStaff) {
ticketChannel.permissionOverwrites.edit(Staff, {
VIEW_CHANNEL: false,
READ_MESSAGE_HISTORY: false,
SEND_MESSAGES: false,
});
}
const Department3 = new Discord.MessageEmbed()
.setDescription(
`> Thank for reaching out to the **${supportbot.DepartmentTitle_3} Department**. Please provide us information regarding your query.`
)
.setColor(supportbot.EmbedColour);
ticketChannel.send({ embeds: [Department3] });
if (supportbot.AllowTicketMentions) {
ticketChannel.send({ content: `@here` });
}
i.message.edit({ embeds: [TicketMessage], components: [row2] });
} }
}); if (collector.customId === "Department3") {
role = DeptRole3;
title = supportbot.DepartmentTitle_3;
}
ticketChannel.permissionOverwrites.edit(role.id, {
VIEW_CHANNEL: true,
});
ticketChannel.permissionOverwrites.edit(Author.id, {
SEND_MESSAGES: true,
});
await collector.reply({
embeds: [
{
description: `> Thank for reaching out to the **${title} Department**. Please provide us information regarding your query.`,
color: supportbot.EmbedColour,
},
],
});
if (supportbot.AllowTicketMentions) {
await ticketChannel.send("@here");
}
await collector.message.edit({
embeds: [TicketMessage],
components: [row2],
});
} catch (error) {}
} else { } else {
ticketChannel.send({ embeds: [TicketMessage], components: [row2] }); await ticketChannel.send({ embeds: [TicketMessage], components: [row2] });
} }
}, },
}); });
+11 -11
View File
@@ -10,15 +10,16 @@
# Discord Support: https://emeraldsrv.dev/discord # Discord Support: https://emeraldsrv.dev/discord
# Community Resources: https://emeraldsrv.dev/resources # Community Resources: https://emeraldsrv.dev/resources
SupportBot_Version: "7.3.1" SupportBot_Version: "7.4.0"
# ------------------------- # -------------------------
# General Configuration # General Configuration
# ------------------------- # -------------------------
Name: "SupportBot" Name: "SupportBot"
# No Prefix, as everything uses the new Slash (/) Commands feature!
Token: "BOT_TOKEN" Token: "BOT_TOKEN"
# Guild ID Ex: 123456789123456789
Guild: ""
# ------------------------- # -------------------------
# Activity Configuration # Activity Configuration
@@ -58,7 +59,6 @@ InfoColour: "#f74343"
# Help Configuration # Help Configuration
# ------------------------- # -------------------------
HelpMenu: true # Do not change!
SendHelpPage: "channel" # Set to channel or dm SendHelpPage: "channel" # Set to channel or dm
# ------------------------- # -------------------------
@@ -67,7 +67,6 @@ SendHelpPage: "channel" # Set to channel or dm
AutoRole: true AutoRole: true
AutoRole_Role: "Member" AutoRole_Role: "Member"
LockdownRole: "@everyone"
Staff: "Staff" Staff: "Staff"
Admin: "Admin" Admin: "Admin"
@@ -92,9 +91,11 @@ TicketLog: "logs"
TranscriptLog: "transcripts" TranscriptLog: "transcripts"
TranscriptTitle: "Ticket Transcript" TranscriptTitle: "Ticket Transcript"
TicketLog_Title: "Ticket Log" TicketLog_Title: "Ticket Closed"
TicketBlackListMessage: "You are not allowed to open a ticket" TicketBlackListMessage: "You are not allowed to open a ticket"
MaxAllowedTickets: 2
TicketSubject: "description" TicketSubject: "description"
# "description" will displays the ticket reason within the channel description # "description" will displays the ticket reason within the channel description
# "embed" will displays the ticket reason within the ticket embed # "embed" will displays the ticket reason within the ticket embed
@@ -127,13 +128,11 @@ RemovedUser: "👍 <@%user%> has been removed from this ticket"
# --- Start --- # --- Start ---
# Discord Button Colour Selection # Discord Button Colour Selection
# PRIMARY - Blurple # PRIMARY - Blue
# SECONDARY - Grey
# DANGER - Red # DANGER - Red
# SUCCESS - Green # SUCCESS - Green
# Secondary - Grey
TicketLockReaction: "🔒"
TicketDeleteReaction: "⛔"
LockTicketCategory: "Archive" LockTicketCategory: "Archive"
TicketCloseEmoji: "❌" TicketCloseEmoji: "❌"
@@ -155,13 +154,13 @@ TicketDept3Emoji: "3️⃣"
TranscriptSavedMessage: "📝 **Transcript Saved!**" TranscriptSavedMessage: "📝 **Transcript Saved!**"
TicketLockMessage: "❌ **Ticket Locked!**" TicketLockMessage: "❌ **Ticket Locked!**"
TicketDeleteMessage: "⚠ **Ticket Deleting!**" # Tickets deleting after 5 seconds by default. TicketDeleteMessage: "⚠ **Ticket Deleting!**" # Tickets deleting after 5 seconds by default.
TicketDeleteTime: 5000 # Time must be set in milliseconds.
# --- Departments Config --- # --- Departments Config ---
# --- Start --- # --- Start ---
TicketDepartments: true TicketDepartments: true
# Delete the ticket if no department selected. TIME IN MINUTES
Timeout: 5
AllowStaff: true AllowStaff: true
# If set to false users with the "Staff" role will not be able to view tickets # If set to false users with the "Staff" role will not be able to view tickets
# without a valid department role set below. # without a valid department role set below.
@@ -181,6 +180,7 @@ DepartmentRole_3: "Admin"
# --- Closing Config --- # --- Closing Config ---
# --- Start --- # --- Start ---
StaffOnly: true
ClosingTicket: ":warning: You have requested to close your support ticket." ClosingTicket: ":warning: You have requested to close your support ticket."
ClosingConfirmation_Word: "confirm" ClosingConfirmation_Word: "confirm"
CloseConfirmation: false CloseConfirmation: false
+2 -3
View File
@@ -1,5 +1,4 @@
{ {
"854057237495676938": { "id": 0,
"id": 2 "tickets": []
}
} }
+1 -3
View File
@@ -1,3 +1 @@
{ {"TicketPanelID":""}
"TicketPanelID": ""
}
+9
View File
@@ -0,0 +1,9 @@
const Event = require("../Structures/Event.js");
module.exports = new Event("guildCreate", async (client, guild) => {
console.log(
`\u001b[31m`,
`${client.user.username} is not in the correct server set in your config. Please leave all other servers and restart the bot.`
);
console.log(`\u001b[31m`, `${client.user.username} will now exit.`);
return process.exit(1);
});
+10
View File
@@ -0,0 +1,10 @@
const Event = require("../Structures/Event.js");
module.exports = new Event("guildDelete", async (client, guild) => {
console.log(
`\u001b[31m`,
`${client.user.username} is not in the correct server set in your config. Please join the server and restart the bot.`
);
console.log(`\u001b[31m`, `${client.user.username} will now exit.`);
return process.exit(1);
});
+15 -72
View File
@@ -12,14 +12,13 @@ const cmdconfig = yaml.load(fs.readFileSync("./Configs/commands.yml", "utf8"));
const Event = require("../Structures/Event.js"); const Event = require("../Structures/Event.js");
module.exports = new Event("interactionCreate", (client, interaction) => { module.exports = new Event("interactionCreate", async (client, interaction) => {
if (interaction.isCommand()) { if (interaction.isCommand()) {
const command = client.commands.find( const command = client.commands.find(
(cmd) => cmd.name.toLowerCase() == interaction.commandName (cmd) => cmd.name.toLowerCase() == interaction.commandName
); );
if (interaction.user.bot || !interaction.isCommand() || !interaction.guild) if (interaction.user.bot || !interaction.guild) return;
return;
const NotValid = new Discord.MessageEmbed() const NotValid = new Discord.MessageEmbed()
.setDescription(`:x: \`Invalid Command\` `) .setDescription(`:x: \`Invalid Command\` `)
@@ -57,79 +56,17 @@ module.exports = new Event("interactionCreate", (client, interaction) => {
} }
if (interaction.customId === "ticketclose") { if (interaction.customId === "ticketclose") {
if (interaction.channel.name.startsWith(`${supportbot.TicketPrefix}`)) { try {
interaction.message.fetch(); const cmd = client.commands.get(cmdconfig.CloseTicket);
interaction.deferUpdate(); if (!cmd) return;
const DeleteTicketEmbed = new Discord.MessageEmbed() cmd.run(interaction);
.setDescription(supportbot.TicketDeleteMessage) } catch (error) {
.setColor(supportbot.EmbedColour); console.error(error);
interaction.channel.send({ embeds: [DeleteTicketEmbed] });
let logChannel =
interaction.guild.channels.cache.find(
(channel) => channel.name === supportbot.TranscriptLog
) ||
interaction.guild.channels.cache.find(
(channel) => channel.id === supportbot.TranscriptLog
);
let user = interaction.user;
let name = interaction.channel.name;
let ticketChannel = interaction.channel;
let reason = "No Reason Provided.";
interaction.channel
.send({ content: `**${supportbot.ClosingTicket}**` })
.then(() => {
const logEmbed = new Discord.MessageEmbed()
.setTitle(supportbot.TranscriptTitle)
.setColor(supportbot.EmbedColour)
.setFooter(supportbot.EmbedFooter)
.addField("Closed By", user.username)
.addField("Reason", reason);
interaction.channel.messages.fetch({ limit: 100 }).then((msgs) => {
let html = "";
msgs = msgs.sort(
(a, b) => a.createdTimestamp - b.createdTimestamp
);
html += `<style>* {background-color: #2c2f33;color: #fff;font-family: Arial, Helvetica, sans-serif;}</style>`;
html += `<strong>Server Name:</strong> ${interaction.guild.name}<br>`;
html += `<strong>Ticket:</strong> ${ticketChannel.name}<br>`;
html += `<strong>Message:</strong> ${msgs.size} Messages<br><br><br>`;
msgs.forEach((msg) => {
if (msg.content) {
html += `<strong>User:</strong> ${msg.author.tag}<br>`;
html += `<strong>Message:</strong> ${msg.content}<br>`;
html += `-----<br><br>`;
}
});
const TranscriptSavedEmbed = new Discord.MessageEmbed()
.setDescription(supportbot.TranscriptSavedMessage)
.setColor(supportbot.SuccessColour);
interaction.channel.send({ embeds: [TranscriptSavedEmbed] });
let file = new Discord.MessageAttachment(
Buffer.from(html),
`${name}.html`
);
logChannel.send({ embeds: [logEmbed], files: [file] });
setTimeout(
() => interaction.channel.delete(),
supportbot.TicketDeleteTime
);
});
});
} }
} }
if (interaction.customId === "ticketlock") { if (interaction.customId === "ticketlock") {
if (interaction.channel.name.startsWith(`${supportbot.TicketPrefix}`)) { if (interaction.channel.name.startsWith(`${supportbot.TicketPrefix}`)) {
interaction.message.fetch(); interaction.message.fetch();
interaction.deferUpdate();
let Admin = let Admin =
interaction.guild.roles.cache.find( interaction.guild.roles.cache.find(
(AdminUser) => AdminUser.name === supportbot.Admin (AdminUser) => AdminUser.name === supportbot.Admin
@@ -137,6 +74,12 @@ module.exports = new Event("interactionCreate", (client, interaction) => {
interaction.guild.roles.cache.find( interaction.guild.roles.cache.find(
(AdminUser) => AdminUser.id === supportbot.Admin (AdminUser) => AdminUser.id === supportbot.Admin
); );
if (!interaction.member.roles.cache.has(Admin.id)) {
return await interaction.reply({
content: "You don't have permission to do that.",
ephemeral: true,
});
}
let all = interaction.channel.permissionOverwrites.cache; let all = interaction.channel.permissionOverwrites.cache;
let parent = let parent =
@@ -175,7 +118,7 @@ module.exports = new Event("interactionCreate", (client, interaction) => {
.setDescription(`Archived ${interaction.channel.name}`) .setDescription(`Archived ${interaction.channel.name}`)
.setColor(`${supportbot.SuccessColour}`); .setColor(`${supportbot.SuccessColour}`);
interaction.channel.send({ embeds: [ArchiveEmbed] }); interaction.reply({ embeds: [ArchiveEmbed] });
interaction.message.edit({ components: [row] }); interaction.message.edit({ components: [row] });
} }
} }
+73 -2
View File
@@ -14,7 +14,8 @@ const panelconfig = yaml.load(
const Event = require("../Structures/Event.js"); const Event = require("../Structures/Event.js");
module.exports = new Event("ready", (client) => { module.exports = new Event("ready", async (client) => {
const { getRole, getChannel, getCategory } = client;
client.user.setActivity(supportbot.BotActivity, { client.user.setActivity(supportbot.BotActivity, {
type: supportbot.ActivityType, type: supportbot.ActivityType,
url: supportbot.StreamingURL, url: supportbot.StreamingURL,
@@ -65,7 +66,76 @@ module.exports = new Event("ready", (client) => {
console.log(`\u001b[37m`, `SupportBot proudly created by Emerald Services`); console.log(`\u001b[37m`, `SupportBot proudly created by Emerald Services`);
console.log(` `); console.log(` `);
console.log(`\u001b[31m`, `――――――――――――――――――――――――――――――――――――――――――――`); console.log(`\u001b[31m`, `――――――――――――――――――――――――――――――――――――――――――――`);
if (
!supportbot.Guild ||
(await client.guilds.cache.size) !== 1 ||
(await client.guilds.cache.first().id) !== supportbot.Guild
) {
console.log(
`\u001b[31m`,
`${client.user.username} is not in the correct server set in your config. Please join the server and restart the bot.`
);
console.log(`\u001b[31m`, `${client.user.username} will now exit.`);
return process.exit(1);
}
const roles = [
supportbot.Admin,
supportbot.Staff,
supportbot.TicketBlackListRole,
supportbot.DepartmentRole_1,
supportbot.DepartmentRole_2,
supportbot.DepartmentRole_3,
];
if (supportbot.AutoRole) roles.push(supportbot.AutoRole_Role);
const channels = [
supportbot.SuggestionChannel,
supportbot.TicketLog,
supportbot.TranscriptLog,
panelconfig.Channel,
];
const categories = [supportbot.TicketCategory];
const missingC = [];
const missingR = [];
const missingCat = [];
for (let c of channels) {
const find = await getChannel(c, client.guilds.cache.first());
if (!find) missingC.push(c);
}
for (let r of roles) {
const find = await getRole(r, client.guilds.cache.first());
if (!find) missingR.push(r);
}
for (let cat of categories) {
const find = await getCategory(cat, client.guilds.cache.first());
if (!find) missingCat.push(cat);
}
if (missingR.length > 0) {
console.log(
"\u001b[33m",
`[WARN] The following Roles could not be found! Please check your configs!\n${missingR.join(
", "
)}`
);
}
if (missingC.length > 0) {
console.log(
"\u001b[33m",
`[WARN] The following Channels could not be found! Please check your configs!\n${missingC.join(
", "
)}`
);
}
if (missingCat.length > 0) {
console.log(
"\u001b[33m",
`[WARN] The following Categories could not be found! Please check your configs!\n${missingCat.join(
", "
)}`
);
}
if (panelconfig.TicketPanel) { if (panelconfig.TicketPanel) {
let chan1 = client.channels.cache.find( let chan1 = client.channels.cache.find(
(channel) => channel.name === panelconfig.Channel (channel) => channel.name === panelconfig.Channel
@@ -104,7 +174,8 @@ module.exports = new Event("ready", (client) => {
let button = new Discord.MessageButton() let button = new Discord.MessageButton()
.setLabel(panelconfig.ButtonLabel) .setLabel(panelconfig.ButtonLabel)
.setCustomId("openticket") .setCustomId("openticket")
.setStyle(panelconfig.ButtonColour); .setStyle(panelconfig.ButtonColour)
.setEmoji(panelconfig.ButtonEmoji);
let row = new Discord.MessageActionRow().addComponents(button); let row = new Discord.MessageActionRow().addComponents(button);
+1 -1
View File
@@ -2,7 +2,7 @@
## What is SupportBot? ## What is SupportBot?
SupportBot is an open-sourced support system for discord. It's completely free to use with high amounts of customisation to match your own brand. 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.
## Quick Links ## Quick Links
+21
View File
@@ -0,0 +1,21 @@
// SupportBot | Emerald Services
// Addon Structure
class Command {
constructor(options) {
this.name = options.name;
this.description = options.description;
this.permissions = options.permissions;
this.options = options.options || [];
this.run = options.run;
this.defaultPermission = true;
}
}
class Event {
constructor(event, run) {
this.event = event;
this.run = run;
}
}
module.exports = { Command, Event };
-25
View File
@@ -1,25 +0,0 @@
// SupportBot | Emerald Services
// Addon Structure
const fs = require("fs");
const Discord = require("discord.js");
const yaml = require("js-yaml");
const supportbot = yaml.load(
fs.readFileSync("./Configs/supportbot.yml", "utf8")
);
function RunFunction(interaction) {}
class Addon {
constructor(options) {
this.name = options.name;
this.description = options.description;
this.permission = options.permission;
this.slashCommandOptions = options.slashCommandOptions || [];
this.run = options.run;
}
}
module.exports = Addon;
+51 -54
View File
@@ -4,8 +4,6 @@
const fs = require("fs"); const fs = require("fs");
const Discord = require("discord.js"); const Discord = require("discord.js");
const Command = require("./Command.js");
const Event = require("./Event.js");
const intents = new Discord.Intents(32767); const intents = new Discord.Intents(32767);
const yaml = require("js-yaml"); const yaml = require("js-yaml");
@@ -19,6 +17,25 @@ class Client extends Discord.Client {
this.commands = new Discord.Collection(); this.commands = new Discord.Collection();
} }
async getChannel(channel, guild) {
return guild.channels.cache.find(
(c) =>
(c.type === "GUILD_TEXT" || c.type === "GUILD_NEWS") &&
(c.id === channel || c.name.toLowerCase() === channel.toLowerCase())
);
}
async getRole(role, guild) {
return guild.roles.cache.find(
(r) => r.id === role || r.name.toLowerCase() === role.toLowerCase()
);
}
async getCategory(category, guild) {
return guild.channels.cache.find(
(c) =>
c.type === "GUILD_CATEGORY" &&
(c.id === category || c.name.toLowerCase() === category.toLowerCase())
);
}
start(token) { start(token) {
const commandFiles = fs const commandFiles = fs
@@ -29,10 +46,15 @@ class Client extends Discord.Client {
.readdirSync("./Addons") .readdirSync("./Addons")
.filter((file) => file.endsWith(".js")); .filter((file) => file.endsWith(".js"));
const addons = addonFiles.map((file) => require(`../Addons/${file}`)); const addons = addonFiles.map((file) => {
let addon = require(`../Addons/${file}`);
addon.name = file.split(".")[0];
return addon;
});
const commands = commandFiles.map((file) => require(`../Commands/${file}`)); const commands = commandFiles.map((file) => require(`../Commands/${file}`));
// Commands
console.log(`\u001b[34;1m`, "▬▬▬▬▬▬▬ Commands ▬▬▬▬▬▬▬"); console.log(`\u001b[34;1m`, "▬▬▬▬▬▬▬ Commands ▬▬▬▬▬▬▬");
commands.forEach((cmd) => { commands.forEach((cmd) => {
@@ -40,6 +62,11 @@ class Client extends Discord.Client {
this.commands.set(cmd.name, cmd); this.commands.set(cmd.name, cmd);
}); });
console.log(`\u001b[34;1m`, "▬▬▬▬▬▬▬ Commands ▬▬▬▬▬▬▬");
// Addons
console.log(" ");
console.log(`\u001b[34;1m`, "▬▬▬▬▬▬▬ Addons ▬▬▬▬▬▬▬");
addons.forEach((addon) => { addons.forEach((addon) => {
console.log( console.log(
`\u001b[33m`, `\u001b[33m`,
@@ -49,57 +76,23 @@ class Client extends Discord.Client {
`\u001b[32;1m`, `\u001b[32;1m`,
"Loaded" "Loaded"
); );
this.commands.set(addon.name, addon); addon.commands.forEach((command) => {
this.commands.set(command.name, command);
});
addon.events.forEach((event) => {
this.on(event.event, (...args) => event.run(this, ...args));
});
}); });
console.log(`\u001b[34;1m`, "▬▬▬▬▬▬▬ Commands ▬▬▬▬▬▬▬"); console.log(`\u001b[34;1m`, "▬▬▬▬▬▬▬ Addons ▬▬▬▬▬▬▬");
// Slash Commands // Slash Commands
const slashCommands = commands.map((cmd) => ({ this.once("ready", async () => {
name: cmd.name.toLowerCase(), await this.application?.commands.set(this.commands, supportbot.Guild);
description: cmd.description, console.log(
permissions: [], `\u001b[32;1m`,
options: cmd.slashCommandOptions, `Slash Commands Registered for ${this.guilds.cache.first().name}`
defaultPermission: true,
}));
const slashCommands1 = addons.map((addon) => ({
name: addon.name.toLowerCase(),
description: addon.description,
permissions: [],
options: addon.slashCommandOptions,
defaultPermission: true,
}));
this.removeAllListeners();
this.on("ready", async () => {
const allCommands = slashCommands.concat(slashCommands1);
await this.application?.commands.set(allCommands);
console.log(" ");
console.log(`\u001b[34;1m`, "▬▬▬▬▬▬▬ Slash Command ▬▬▬▬▬▬▬"),
console.log(" ");
slashCommands.forEach((cmd) =>
console.log(
`\u001b[31;1m`,
`${cmd.name}`,
`\u001b[32;1m`,
`| Slash Command Registered`
)
);
slashCommands1.forEach((addon) =>
console.log(
`\u001b[33m`,
`[ADDON]`,
`\u001b[31;1m`,
`${addon.name}`,
`\u001b[32;1m`,
`| Slash Command Registered`
)
); );
}); });
@@ -111,14 +104,18 @@ class Client extends Discord.Client {
.forEach((file) => { .forEach((file) => {
const event = require(`../Events/${file}`); const event = require(`../Events/${file}`);
console.log(`\u001b[31;1m`, `${event.event}`, `\u001b[32;1m`, "Loaded"); console.log(`\u001b[31;1m`, `${event.event}`, `\u001b[32;1m`, "Loaded");
this.on(event.event, (...args) => event.run(this, ...args));
this.on(event.event, event.run.bind(null, this));
}); });
console.log(`\u001b[34;1m`, "▬▬▬▬▬▬▬ Events ▬▬▬▬▬▬▬"); console.log(`\u001b[34;1m`, "▬▬▬▬▬▬▬ Events ▬▬▬▬▬▬▬");
console.log(" "); if (process.argv[2] != "test") {
this.login(token);
this.login(token); } else {
console.log(
`\u001b[31;1m`,
"RUNNING IN TEST MODE, IF NOT INTENDED, PLEASE USE npm start"
);
}
} }
} }
+3 -9
View File
@@ -3,22 +3,16 @@
const fs = require("fs"); const fs = require("fs");
const Discord = require("discord.js");
const yaml = require("js-yaml"); const yaml = require("js-yaml");
const supportbot = yaml.load(
fs.readFileSync("./Configs/supportbot.yml", "utf8")
);
function RunFunction(interaction) {}
class Command { class Command {
constructor(options) { constructor(options) {
this.name = options.name; this.name = options.name;
this.description = options.description; this.description = options.description;
this.permission = options.permission; this.permissions = options.permissions;
this.slashCommandOptions = options.slashCommandOptions || []; this.options = options.options || [];
this.run = options.run; this.run = options.run;
this.defaultPermission = true;
} }
} }
+2 -14
View File
@@ -1,21 +1,9 @@
// SupportBot | Emerald Services // SupportBot | Emerald Services
// Event Structure // Event Structure
const fs = require("fs");
const Discord = require("discord.js");
const yaml = require("js-yaml");
const supportbot = yaml.load(
fs.readFileSync("./Configs/supportbot.yml", "utf8")
);
function RunFunction(client, ...eventArgs) {}
class Event { class Event {
constructor(event, runFunction) { constructor(event, run) {
this.event = event; this.event = event;
this.run = runFunction; this.run = run;
} }
} }
+14 -32
View File
@@ -3,85 +3,67 @@
const fs = require("fs"); const fs = require("fs");
const Discord = require("discord.js");
const Command = require("./Command.js");
const Client = require("./Client.js");
const Event = require("./Event.js");
const yaml = require("js-yaml");
const supportbot = yaml.load(
fs.readFileSync("./Configs/supportbot.yml", "utf8")
);
class TicketNumberID { class TicketNumberID {
static pad(guildId) { static async pad() {
let n = this.get(guildId) + ""; let n = this.get() + "";
let z = "0"; let z = "0";
let width = 4; let width = 4;
setTimeout(() => { await this.set(this.get() + 1);
this.set(guildId, this.get(guildId) + 1);
}, 50);
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
} }
static get(guildId) { static get() {
let ticketnumberID = JSON.parse( let ticketnumberID = JSON.parse(
fs.readFileSync("./Data/TicketData.json", "utf8") fs.readFileSync("./Data/TicketData.json", "utf8")
); );
if (!ticketnumberID[guildId]) { if (!ticketnumberID.id) {
ticketnumberID[guildId] = { ticketnumberID.id = 0;
id: 0,
};
fs.writeFileSync( fs.writeFileSync(
"./Data/TicketData.json", "./Data/TicketData.json",
JSON.stringify(ticketnumberID, null, 4), JSON.stringify(ticketnumberID, null, 4),
(err) => { (err) => {
if (err) console.log(err); if (err) console.error(err);
} }
); );
return 0; return 0;
} else { } else {
return ticketnumberID[guildId].id; return ticketnumberID.id;
} }
} }
static set(guildId, value) { static set(value) {
let ticketnumberID = JSON.parse( let ticketnumberID = JSON.parse(
fs.readFileSync("./Data/TicketData.json", "utf8") fs.readFileSync("./Data/TicketData.json", "utf8")
); );
ticketnumberID[guildId] = { ticketnumberID.id = value;
id: value,
};
fs.writeFileSync( fs.writeFileSync(
"./Data/TicketData.json", "./Data/TicketData.json",
JSON.stringify(ticketnumberID, null, 4), JSON.stringify(ticketnumberID, null, 4),
(err) => { (err) => {
if (err) console.log(err); if (err) console.error(err);
} }
); );
return value; return value;
} }
static reset(guildId) { static reset() {
let ticketnumberID = JSON.parse( let ticketnumberID = JSON.parse(
fs.readFileSync("./Data/TicketData.json", "utf8") fs.readFileSync("./Data/TicketData.json", "utf8")
); );
ticketnumberID[guildId] = { ticketnumberID.id = 0;
id: 0,
};
fs.writeFileSync( fs.writeFileSync(
"./Data/TicketData.json", "./Data/TicketData.json",
JSON.stringify(ticketnumberID, null, 4), JSON.stringify(ticketnumberID, null, 4),
(err) => { (err) => {
if (err) console.log(err); if (err) console.error(err);
} }
); );
+129 -100
View File
@@ -1,48 +1,41 @@
{ {
"name": "supportbot", "name": "supportbot",
"version": "7.3.0", "version": "7.4.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "supportbot", "name": "supportbot",
"version": "7.3.0", "version": "7.4.0",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"discord.js": "^13.2.0", "discord.js": "^13.3.1",
"js-yaml": "^4.1.0" "js-yaml": "^4.1.0"
} }
}, },
"node_modules/@discordjs/builders": { "node_modules/@discordjs/builders": {
"version": "0.6.0", "version": "0.8.2",
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.6.0.tgz", "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.8.2.tgz",
"integrity": "sha512-mH3Gx61LKk2CD05laCI9K5wp+a3NyASHDUGx83DGJFkqJlRlSV5WMJNY6RS37A5SjqDtGMF4wVR9jzFaqShe6Q==", "integrity": "sha512-/YRd11SrcluqXkKppq/FAVzLIPRVlIVmc6X8ZklspzMIHDtJ+A4W37D43SHvLdH//+NnK+SHW/WeOF4Ts54PeQ==",
"dependencies": { "dependencies": {
"@sindresorhus/is": "^4.0.1", "@sindresorhus/is": "^4.2.0",
"discord-api-types": "^0.22.0", "discord-api-types": "^0.24.0",
"ow": "^0.27.0", "ow": "^0.27.0",
"ts-mixer": "^6.0.0", "ts-mixer": "^6.0.0",
"tslib": "^2.3.1" "tslib": "^2.3.1"
}, },
"engines": { "engines": {
"node": ">=14.0.0", "node": ">=16.0.0",
"npm": ">=7.0.0" "npm": ">=7.0.0"
} }
}, },
"node_modules/@discordjs/builders/node_modules/discord-api-types": {
"version": "0.22.0",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.22.0.tgz",
"integrity": "sha512-l8yD/2zRbZItUQpy7ZxBJwaLX/Bs2TGaCthRppk8Sw24LOIWg12t9JEreezPoYD0SQcC2htNNo27kYEpYW/Srg==",
"engines": {
"node": ">=12"
}
},
"node_modules/@discordjs/collection": { "node_modules/@discordjs/collection": {
"version": "0.2.1", "version": "0.3.2",
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.2.1.tgz", "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.3.2.tgz",
"integrity": "sha512-vhxqzzM8gkomw0TYRF3tgx7SwElzUlXT/Aa41O7mOcyN6wIJfj5JmDWaO5XGKsGSsNx7F3i5oIlrucCCWV1Nog==", "integrity": "sha512-dMjLl60b2DMqObbH1MQZKePgWhsNe49XkKBZ0W5Acl5uVV43SN414i2QfZwRI7dXAqIn8pEWD2+XXQFn9KWxqg==",
"engines": { "engines": {
"node": ">=14.0.0" "node": ">=16.0.0",
"npm": ">=7.0.0"
} }
}, },
"node_modules/@discordjs/form-data": { "node_modules/@discordjs/form-data": {
@@ -59,9 +52,9 @@
} }
}, },
"node_modules/@sapphire/async-queue": { "node_modules/@sapphire/async-queue": {
"version": "1.1.7", "version": "1.1.9",
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.7.tgz", "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.9.tgz",
"integrity": "sha512-EBRERa9NqK/EV6DIPBVtjjdHBsu/DSdMuYAydmoIyIPONzp0UAxf2G6JGJ52WkiONtPRx6KNuqB5Q8dm14fwyw==", "integrity": "sha512-CbXaGwwlEMq+l1TRu01FJCvySJ1CEFKFclHT48nIfNeZXaAAmmwwy7scUKmYHPUa3GhoMp6Qr1B3eAJux6XgOQ==",
"engines": { "engines": {
"node": ">=v14.0.0", "node": ">=v14.0.0",
"npm": ">=7.0.0" "npm": ">=7.0.0"
@@ -79,14 +72,23 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "16.11.4", "version": "17.0.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.4.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.0.tgz",
"integrity": "sha512-TMgXmy0v2xWyuCSCJM6NCna2snndD8yvQF67J29ipdzMcsPa9u+o0tjF5+EQNdhcuZplYuouYqpc4zcd5I6amQ==" "integrity": "sha512-eMhwJXc931Ihh4tkU+Y7GiLzT/y/DBNpNtr4yU9O2w3SYBsr9NaOPhQlLKRmoWtI54uNwuo0IOUFQjVOTZYRvw=="
},
"node_modules/@types/node-fetch": {
"version": "2.5.12",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz",
"integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==",
"dependencies": {
"@types/node": "*",
"form-data": "^3.0.0"
}
}, },
"node_modules/@types/ws": { "node_modules/@types/ws": {
"version": "8.2.0", "version": "8.2.2",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.2.0.tgz", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.2.2.tgz",
"integrity": "sha512-cyeefcUCgJlEk+hk2h3N+MqKKsPViQgF5boi9TTHSK+PoR9KWBb/C5ccPcDyAqgsbAYHTwulch725DV84+pSpg==", "integrity": "sha512-NOn5eIcgWLOo6qW8AcuLZ7G8PycXu0xTxxkS6Q18VWFxgPUSOwV0pBj2a/4viNZVu25i7RIB7GttdkAIUUXOOg==",
"dependencies": { "dependencies": {
"@types/node": "*" "@types/node": "*"
} }
@@ -129,24 +131,25 @@
} }
}, },
"node_modules/discord-api-types": { "node_modules/discord-api-types": {
"version": "0.23.1", "version": "0.24.0",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.23.1.tgz", "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.24.0.tgz",
"integrity": "sha512-igWmn+45mzXRWNEPU25I/pr8MwxHb767wAr51oy3VRLRcTlp5ADBbrBR0lq3SA1Rfw3MtM4TQu1xo3kxscfVdQ==", "integrity": "sha512-X0uA2a92cRjowUEXpLZIHWl4jiX1NsUpDhcEOpa1/hpO1vkaokgZ8kkPtPih9hHth5UVQ3mHBu/PpB4qjyfJ4A==",
"engines": { "engines": {
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/discord.js": { "node_modules/discord.js": {
"version": "13.2.0", "version": "13.3.1",
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.2.0.tgz", "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.3.1.tgz",
"integrity": "sha512-nyxUvL8wuQG38zx13wUMkpcA8koFszyiXdkSLwwM9opKW2LC2H5gD0cTZxImeJ6GtEnKPWT8xBiE8lLBmbNIhw==", "integrity": "sha512-zn4G8tL5+tMV00+0aSsVYNYcIfMSdT2g0nudKny+Ikd+XKv7m6bqI7n3Vji0GIRqXDr5ArPaw+iYFM2I1Iw3vg==",
"dependencies": { "dependencies": {
"@discordjs/builders": "^0.6.0", "@discordjs/builders": "^0.8.1",
"@discordjs/collection": "^0.2.1", "@discordjs/collection": "^0.3.2",
"@discordjs/form-data": "^3.0.1", "@discordjs/form-data": "^3.0.1",
"@sapphire/async-queue": "^1.1.5", "@sapphire/async-queue": "^1.1.8",
"@types/node-fetch": "^2.5.12",
"@types/ws": "^8.2.0", "@types/ws": "^8.2.0",
"discord-api-types": "^0.23.1", "discord-api-types": "^0.24.0",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"ws": "^8.2.3" "ws": "^8.2.3"
}, },
@@ -169,6 +172,19 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/form-data": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
"integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/is-obj": { "node_modules/is-obj": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
@@ -194,28 +210,28 @@
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
}, },
"node_modules/mime-db": { "node_modules/mime-db": {
"version": "1.50.0", "version": "1.51.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
"integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==",
"engines": { "engines": {
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/mime-types": { "node_modules/mime-types": {
"version": "2.1.33", "version": "2.1.34",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
"integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
"dependencies": { "dependencies": {
"mime-db": "1.50.0" "mime-db": "1.51.0"
}, },
"engines": { "engines": {
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/node-fetch": { "node_modules/node-fetch": {
"version": "2.6.5", "version": "2.6.6",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz",
"integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==",
"dependencies": { "dependencies": {
"whatwg-url": "^5.0.0" "whatwg-url": "^5.0.0"
}, },
@@ -291,9 +307,9 @@
} }
}, },
"node_modules/ws": { "node_modules/ws": {
"version": "8.2.3", "version": "8.3.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-8.3.0.tgz",
"integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", "integrity": "sha512-Gs5EZtpqZzLvmIM59w4igITU57lrtYVFneaa434VROv4thzJyV6UjIL3D42lslWlI+D4KzLYnxSwtfuiO79sNw==",
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=10.0.0"
}, },
@@ -313,28 +329,21 @@
}, },
"dependencies": { "dependencies": {
"@discordjs/builders": { "@discordjs/builders": {
"version": "0.6.0", "version": "0.8.2",
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.6.0.tgz", "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.8.2.tgz",
"integrity": "sha512-mH3Gx61LKk2CD05laCI9K5wp+a3NyASHDUGx83DGJFkqJlRlSV5WMJNY6RS37A5SjqDtGMF4wVR9jzFaqShe6Q==", "integrity": "sha512-/YRd11SrcluqXkKppq/FAVzLIPRVlIVmc6X8ZklspzMIHDtJ+A4W37D43SHvLdH//+NnK+SHW/WeOF4Ts54PeQ==",
"requires": { "requires": {
"@sindresorhus/is": "^4.0.1", "@sindresorhus/is": "^4.2.0",
"discord-api-types": "^0.22.0", "discord-api-types": "^0.24.0",
"ow": "^0.27.0", "ow": "^0.27.0",
"ts-mixer": "^6.0.0", "ts-mixer": "^6.0.0",
"tslib": "^2.3.1" "tslib": "^2.3.1"
},
"dependencies": {
"discord-api-types": {
"version": "0.22.0",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.22.0.tgz",
"integrity": "sha512-l8yD/2zRbZItUQpy7ZxBJwaLX/Bs2TGaCthRppk8Sw24LOIWg12t9JEreezPoYD0SQcC2htNNo27kYEpYW/Srg=="
}
} }
}, },
"@discordjs/collection": { "@discordjs/collection": {
"version": "0.2.1", "version": "0.3.2",
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.2.1.tgz", "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.3.2.tgz",
"integrity": "sha512-vhxqzzM8gkomw0TYRF3tgx7SwElzUlXT/Aa41O7mOcyN6wIJfj5JmDWaO5XGKsGSsNx7F3i5oIlrucCCWV1Nog==" "integrity": "sha512-dMjLl60b2DMqObbH1MQZKePgWhsNe49XkKBZ0W5Acl5uVV43SN414i2QfZwRI7dXAqIn8pEWD2+XXQFn9KWxqg=="
}, },
"@discordjs/form-data": { "@discordjs/form-data": {
"version": "3.0.1", "version": "3.0.1",
@@ -347,9 +356,9 @@
} }
}, },
"@sapphire/async-queue": { "@sapphire/async-queue": {
"version": "1.1.7", "version": "1.1.9",
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.7.tgz", "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.9.tgz",
"integrity": "sha512-EBRERa9NqK/EV6DIPBVtjjdHBsu/DSdMuYAydmoIyIPONzp0UAxf2G6JGJ52WkiONtPRx6KNuqB5Q8dm14fwyw==" "integrity": "sha512-CbXaGwwlEMq+l1TRu01FJCvySJ1CEFKFclHT48nIfNeZXaAAmmwwy7scUKmYHPUa3GhoMp6Qr1B3eAJux6XgOQ=="
}, },
"@sindresorhus/is": { "@sindresorhus/is": {
"version": "4.2.0", "version": "4.2.0",
@@ -357,14 +366,23 @@
"integrity": "sha512-VkE3KLBmJwcCaVARtQpfuKcKv8gcBmUubrfHGF84dXuuW6jgsRYxPtzcIhPyK9WAPpRt2/xY6zkD9MnRaJzSyw==" "integrity": "sha512-VkE3KLBmJwcCaVARtQpfuKcKv8gcBmUubrfHGF84dXuuW6jgsRYxPtzcIhPyK9WAPpRt2/xY6zkD9MnRaJzSyw=="
}, },
"@types/node": { "@types/node": {
"version": "16.11.4", "version": "17.0.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.4.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.0.tgz",
"integrity": "sha512-TMgXmy0v2xWyuCSCJM6NCna2snndD8yvQF67J29ipdzMcsPa9u+o0tjF5+EQNdhcuZplYuouYqpc4zcd5I6amQ==" "integrity": "sha512-eMhwJXc931Ihh4tkU+Y7GiLzT/y/DBNpNtr4yU9O2w3SYBsr9NaOPhQlLKRmoWtI54uNwuo0IOUFQjVOTZYRvw=="
},
"@types/node-fetch": {
"version": "2.5.12",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz",
"integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==",
"requires": {
"@types/node": "*",
"form-data": "^3.0.0"
}
}, },
"@types/ws": { "@types/ws": {
"version": "8.2.0", "version": "8.2.2",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.2.0.tgz", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.2.2.tgz",
"integrity": "sha512-cyeefcUCgJlEk+hk2h3N+MqKKsPViQgF5boi9TTHSK+PoR9KWBb/C5ccPcDyAqgsbAYHTwulch725DV84+pSpg==", "integrity": "sha512-NOn5eIcgWLOo6qW8AcuLZ7G8PycXu0xTxxkS6Q18VWFxgPUSOwV0pBj2a/4viNZVu25i7RIB7GttdkAIUUXOOg==",
"requires": { "requires": {
"@types/node": "*" "@types/node": "*"
} }
@@ -398,21 +416,22 @@
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
}, },
"discord-api-types": { "discord-api-types": {
"version": "0.23.1", "version": "0.24.0",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.23.1.tgz", "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.24.0.tgz",
"integrity": "sha512-igWmn+45mzXRWNEPU25I/pr8MwxHb767wAr51oy3VRLRcTlp5ADBbrBR0lq3SA1Rfw3MtM4TQu1xo3kxscfVdQ==" "integrity": "sha512-X0uA2a92cRjowUEXpLZIHWl4jiX1NsUpDhcEOpa1/hpO1vkaokgZ8kkPtPih9hHth5UVQ3mHBu/PpB4qjyfJ4A=="
}, },
"discord.js": { "discord.js": {
"version": "13.2.0", "version": "13.3.1",
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.2.0.tgz", "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.3.1.tgz",
"integrity": "sha512-nyxUvL8wuQG38zx13wUMkpcA8koFszyiXdkSLwwM9opKW2LC2H5gD0cTZxImeJ6GtEnKPWT8xBiE8lLBmbNIhw==", "integrity": "sha512-zn4G8tL5+tMV00+0aSsVYNYcIfMSdT2g0nudKny+Ikd+XKv7m6bqI7n3Vji0GIRqXDr5ArPaw+iYFM2I1Iw3vg==",
"requires": { "requires": {
"@discordjs/builders": "^0.6.0", "@discordjs/builders": "^0.8.1",
"@discordjs/collection": "^0.2.1", "@discordjs/collection": "^0.3.2",
"@discordjs/form-data": "^3.0.1", "@discordjs/form-data": "^3.0.1",
"@sapphire/async-queue": "^1.1.5", "@sapphire/async-queue": "^1.1.8",
"@types/node-fetch": "^2.5.12",
"@types/ws": "^8.2.0", "@types/ws": "^8.2.0",
"discord-api-types": "^0.23.1", "discord-api-types": "^0.24.0",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"ws": "^8.2.3" "ws": "^8.2.3"
} }
@@ -425,6 +444,16 @@
"is-obj": "^2.0.0" "is-obj": "^2.0.0"
} }
}, },
"form-data": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
"integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
}
},
"is-obj": { "is-obj": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
@@ -444,22 +473,22 @@
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
}, },
"mime-db": { "mime-db": {
"version": "1.50.0", "version": "1.51.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
"integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==" "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g=="
}, },
"mime-types": { "mime-types": {
"version": "2.1.33", "version": "2.1.34",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
"integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
"requires": { "requires": {
"mime-db": "1.50.0" "mime-db": "1.51.0"
} }
}, },
"node-fetch": { "node-fetch": {
"version": "2.6.5", "version": "2.6.6",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz",
"integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==",
"requires": { "requires": {
"whatwg-url": "^5.0.0" "whatwg-url": "^5.0.0"
} }
@@ -517,9 +546,9 @@
} }
}, },
"ws": { "ws": {
"version": "8.2.3", "version": "8.3.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-8.3.0.tgz",
"integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", "integrity": "sha512-Gs5EZtpqZzLvmIM59w4igITU57lrtYVFneaa434VROv4thzJyV6UjIL3D42lslWlI+D4KzLYnxSwtfuiO79sNw==",
"requires": {} "requires": {}
} }
} }
+4 -3
View File
@@ -1,10 +1,11 @@
{ {
"name": "supportbot", "name": "supportbot",
"version": "7.3.0", "version": "7.4.0",
"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": {
"start": "npm i && node index.js" "start": "npm i && node index.js",
"test": "node index.js test"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@@ -17,7 +18,7 @@
}, },
"homepage": "https://github.com/Emerald-Services/SupportBot#readme", "homepage": "https://github.com/Emerald-Services/SupportBot#readme",
"dependencies": { "dependencies": {
"discord.js": "^13.2.0", "discord.js": "^13.3.1",
"js-yaml": "^4.1.0" "js-yaml": "^4.1.0"
} }
} }