Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
753f432c95 | ||
|
|
c824bc51b2 | ||
|
|
39ee540b55 | ||
|
|
903b214051 | ||
|
|
ac0daf5fe7 | ||
|
|
80e38a07e9 | ||
|
|
d2598e09f7 | ||
|
|
28aab47150 |
No files matched your search
@@ -1,128 +0,0 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
our discord.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
@@ -1,92 +0,0 @@
|
||||
# Contributing
|
||||
|
||||
When contributing to this repository, please first discuss the change you wish to make via issue,
|
||||
email, or any other method with the owners of this repository before making a change.
|
||||
|
||||
Please note we have a code of conduct, please follow it in all your interactions with the project.
|
||||
|
||||
## Pull Request Process
|
||||
|
||||
1. Ensure any install or build dependencies are removed before the end of the layer when doing a
|
||||
build.
|
||||
2. Update the README.md with details of changes to the interface, this includes new environment
|
||||
variables, exposed ports, useful file locations and container parameters.
|
||||
3. Increase the version numbers in any examples files and the README.md to the new version that this
|
||||
Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/).
|
||||
4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you
|
||||
do not have permission to do that, you may request the second reviewer to merge it for you.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
### Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||
nationality, personal appearance, race, religion, or sexual identity and
|
||||
orientation.
|
||||
|
||||
### Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
### Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
### Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
### Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at [INSERT EMAIL ADDRESS]. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
### Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
+27
-3
@@ -6,6 +6,7 @@ const {
|
||||
ActionRowBuilder,
|
||||
ButtonBuilder,
|
||||
ButtonStyle,
|
||||
ChannelType,
|
||||
} = require("discord.js");
|
||||
const yaml = require("js-yaml");
|
||||
|
||||
@@ -34,8 +35,10 @@ module.exports = new Command({
|
||||
const ticketChannel = interaction.channel;
|
||||
const ticketDataPath = "./Data/TicketData.json";
|
||||
|
||||
// Check if the channel is a ticket thread
|
||||
if (!ticketChannel.isThread()) {
|
||||
if (
|
||||
(supportbot.Ticket.TicketType === "threads" && !ticketChannel.isThread()) ||
|
||||
(supportbot.Ticket.TicketType === "channels" && ticketChannel.type !== ChannelType.GuildText)
|
||||
) {
|
||||
const onlyInTicket = new EmbedBuilder()
|
||||
.setTitle(msgconfig.AddUser.NotInTicket_Title)
|
||||
.setDescription(msgconfig.AddUser.NotInTicket_Description)
|
||||
@@ -91,7 +94,16 @@ module.exports = new Command({
|
||||
collector.on("collect", async (i) => {
|
||||
if (i.customId === "accept_invite") {
|
||||
try {
|
||||
await ticketChannel.members.add(userToAdd.id);
|
||||
// Add user to thread or channel based on TicketType
|
||||
if (supportbot.Ticket.TicketType === "threads") {
|
||||
await ticketChannel.members.add(userToAdd.id); // For threads
|
||||
} else if (supportbot.Ticket.TicketType === "channels") {
|
||||
await ticketChannel.permissionOverwrites.create(userToAdd.id, {
|
||||
ViewChannel: true,
|
||||
SendMessages: true,
|
||||
ReadMessageHistory: true,
|
||||
}); // For channels
|
||||
}
|
||||
|
||||
const ticketData = JSON.parse(fs.readFileSync(ticketDataPath, "utf8"));
|
||||
const ticketIndex = ticketData.tickets.findIndex((t) => t.id === ticketChannel.id);
|
||||
@@ -110,6 +122,18 @@ module.exports = new Command({
|
||||
components: [],
|
||||
});
|
||||
|
||||
// Send the added user ticket message in the ticket channel
|
||||
|
||||
const addeduserTicket = new EmbedBuilder()
|
||||
.setTitle(msgconfig.AddUser.Added_Title)
|
||||
.setDescription(msgconfig.AddUser.Added_Description.replace('%username%', userToAdd.username))
|
||||
.setColor(supportbot.Embed.Colours.General);
|
||||
|
||||
await ticketChannel.send({
|
||||
embeds: [addeduserTicket],
|
||||
});
|
||||
|
||||
|
||||
const addedToTicketEmbed = new EmbedBuilder()
|
||||
.setTitle(msgconfig.AddUser.AddedToTicket_Title)
|
||||
.setDescription(msgconfig.AddUser.AddedToTicket_Description.replace(
|
||||
|
||||
+17
-49
@@ -2,15 +2,9 @@ const fs = require("fs");
|
||||
const Discord = require("discord.js");
|
||||
const yaml = require("js-yaml");
|
||||
|
||||
const supportbot = yaml.load(
|
||||
fs.readFileSync("./Configs/supportbot.yml", "utf8")
|
||||
);
|
||||
const cmdconfig = yaml.load(
|
||||
fs.readFileSync("./Configs/commands.yml", "utf8")
|
||||
);
|
||||
const msgconfig = yaml.load(
|
||||
fs.readFileSync("./Configs/messages.yml", "utf8")
|
||||
);
|
||||
const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8"));
|
||||
const cmdconfig = yaml.load(fs.readFileSync("./Configs/commands.yml", "utf8"));
|
||||
const msgconfig = yaml.load(fs.readFileSync("./Configs/messages.yml", "utf8"));
|
||||
|
||||
const Command = require("../Structures/Command.js");
|
||||
|
||||
@@ -35,28 +29,25 @@ module.exports = new Command({
|
||||
let Admin = await getRole(supportbot.Roles.StaffMember.Admin, interaction.guild);
|
||||
|
||||
if (!SupportStaff || !Admin)
|
||||
return interaction.reply(
|
||||
"Some roles seem to be missing!\nPlease check for errors when starting the bot."
|
||||
);
|
||||
return interaction.reply("Some roles seem to be missing!\nPlease check for errors when starting the bot.");
|
||||
|
||||
const NoPerms = new Discord.EmbedBuilder()
|
||||
.setTitle("Invalid Permissions!")
|
||||
.setDescription(
|
||||
`${msgconfig.Error.IncorrectPerms}\n\nRole Required: \`${supportbot.Roles.StaffMember.Staff}\` or \`${supportbot.Roles.StaffMember.Admin}\``
|
||||
)
|
||||
.setDescription(`${msgconfig.Error.IncorrectPerms}\n\nRole Required: \`${supportbot.Roles.StaffMember.Staff}\` or \`${supportbot.Roles.StaffMember.Admin}\``)
|
||||
.setColor(supportbot.Embed.Colours.Warn);
|
||||
|
||||
if (
|
||||
!interaction.member.roles.cache.has(SupportStaff.id) &&
|
||||
!interaction.member.roles.cache.has(Admin.id)
|
||||
)
|
||||
if (!interaction.member.roles.cache.has(SupportStaff.id) && !interaction.member.roles.cache.has(Admin.id))
|
||||
return interaction.reply({ embeds: [NoPerms] });
|
||||
}
|
||||
|
||||
if (interaction.channel.type !== Discord.ChannelType.PrivateThread) {
|
||||
// Check if it's a thread or channel based on config
|
||||
if (
|
||||
(supportbot.Ticket.TicketType === "threads" && interaction.channel.type !== Discord.ChannelType.PrivateThread) ||
|
||||
(supportbot.Ticket.TicketType === "channels" && interaction.channel.type !== Discord.ChannelType.GuildText)
|
||||
) {
|
||||
const NotTicketChannel = new Discord.EmbedBuilder()
|
||||
.setTitle("Invalid Channel!")
|
||||
.setDescription("This command can only be used in a ticket thread.")
|
||||
.setDescription(`This command can only be used in a ${supportbot.Ticket.TicketType === "threads" ? "ticket thread" : "ticket channel"}.`)
|
||||
.setColor(supportbot.Embed.Colours.Warn);
|
||||
|
||||
return interaction.reply({ embeds: [NotTicketChannel], ephemeral: true });
|
||||
@@ -88,9 +79,7 @@ module.exports = new Command({
|
||||
|
||||
const CloseTicketRequest = new Discord.EmbedBuilder()
|
||||
.setTitle(`**${supportbot.Ticket.Close.Title}**`)
|
||||
.setDescription(
|
||||
`${msgconfig.Ticket.ConfirmClose}`
|
||||
)
|
||||
.setDescription(`${msgconfig.Ticket.ConfirmClose}`)
|
||||
.setColor(supportbot.Embed.Colours.General);
|
||||
|
||||
await interaction.followUp({
|
||||
@@ -117,10 +106,9 @@ async function handleCloseTicket(interaction, reason, ticket, TicketData) {
|
||||
|
||||
let tickets = JSON.parse(fs.readFileSync("./Data/TicketData.json", "utf8"));
|
||||
let tUser = interaction.client.users.cache.get(ticket.user);
|
||||
let transcriptChannel = await getChannel(supportbot.Ticket.Log.TranscriptLog, interaction.guild);
|
||||
let logChannel = await getChannel(supportbot.Ticket.Log.TicketLog, interaction.guild);
|
||||
let transcriptChannel = await getChannel(supportbot.Ticket.Log.TicketDataLog, interaction.guild);
|
||||
|
||||
if (!transcriptChannel || !logChannel)
|
||||
if (!transcriptChannel)
|
||||
return interaction.followUp("Some Channels seem to be missing!");
|
||||
|
||||
try {
|
||||
@@ -134,22 +122,8 @@ async function handleCloseTicket(interaction, reason, ticket, TicketData) {
|
||||
);
|
||||
|
||||
const transcriptEmbed = new Discord.EmbedBuilder()
|
||||
.setTitle(supportbot.Ticket.Log.TranscriptTitle)
|
||||
.setColor(supportbot.Embed.Colours.General)
|
||||
.setFooter({
|
||||
text: supportbot.Embed.Footer,
|
||||
iconURL: interaction.user.displayAvatarURL(),
|
||||
})
|
||||
.addFields(
|
||||
{ name: "Ticket", value: `${interaction.channel.name} (${interaction.channel.id})` },
|
||||
{ name: "User", value: `${tUser?.username || "N/A"}#${tUser?.discriminator || "N/A"} (${tUser?.id || ticket.user})` },
|
||||
{ name: "Closed By", value: interaction.user.tag },
|
||||
{ name: "Reason", value: reason }
|
||||
);
|
||||
|
||||
const logEmbed = new Discord.EmbedBuilder()
|
||||
.setTitle(supportbot.Ticket.Log.TicketLog_Title)
|
||||
.setColor(supportbot.Embed.Colours.General)
|
||||
.setTitle(msgconfig.TicketLog.Title)
|
||||
.setColor(msgconfig.TicketLog.Colour)
|
||||
.setFooter({
|
||||
text: supportbot.Embed.Footer,
|
||||
iconURL: interaction.user.displayAvatarURL(),
|
||||
@@ -263,12 +237,6 @@ async function handleCloseTicket(interaction, reason, ticket, TicketData) {
|
||||
</html>
|
||||
`;
|
||||
|
||||
if (!supportbot.Ticket.Log.DisableTicketLogChannel) {
|
||||
await logChannel.send({ embeds: [logEmbed] }).catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
let file = new Discord.AttachmentBuilder(
|
||||
Buffer.from(html),
|
||||
{ name: fileName }
|
||||
|
||||
+51
-36
@@ -1,9 +1,9 @@
|
||||
// File: Commands/ForceAddUser.js
|
||||
const fs = require("fs");
|
||||
const {
|
||||
EmbedBuilder,
|
||||
ApplicationCommandOptionType,
|
||||
ApplicationCommandType,
|
||||
ChannelType,
|
||||
} = require("discord.js");
|
||||
const yaml = require("js-yaml");
|
||||
|
||||
@@ -20,7 +20,7 @@ module.exports = new Command({
|
||||
options: [
|
||||
{
|
||||
name: "user",
|
||||
description: "The user to add",
|
||||
description: "The user to forcefully add",
|
||||
type: ApplicationCommandOptionType.User,
|
||||
required: true,
|
||||
},
|
||||
@@ -28,34 +28,14 @@ module.exports = new Command({
|
||||
permissions: cmdconfig.ForceAddUser.Permission,
|
||||
|
||||
async run(interaction) {
|
||||
|
||||
const { getRole } = interaction.client;
|
||||
let SupportStaff = await getRole(supportbot.Roles.StaffMember.Staff, interaction.guild);
|
||||
let Admin = await getRole(supportbot.Roles.StaffMember.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 EmbedBuilder()
|
||||
.setTitle("Invalid Permissions!")
|
||||
.setDescription(
|
||||
`${msgconfig.Error.IncorrectPerms}\n\nRole Required: \`${supportbot.Roles.StaffMember.Staff}\` or \`${supportbot.Roles.StaffMember.Admin}\``
|
||||
)
|
||||
.setColor(supportbot.Embed.Colours.Warn);
|
||||
|
||||
if (
|
||||
!interaction.member.roles.cache.has(SupportStaff.id) &&
|
||||
!interaction.member.roles.cache.has(Admin.id)
|
||||
)
|
||||
return interaction.reply({ embeds: [NoPerms] });
|
||||
|
||||
const userToAdd = interaction.options.getUser("user");
|
||||
const ticketChannel = interaction.channel;
|
||||
const ticketDataPath = "./Data/TicketData.json";
|
||||
|
||||
if (!ticketChannel.isThread()) {
|
||||
if (
|
||||
(supportbot.Ticket.TicketType === "threads" && !ticketChannel.isThread()) ||
|
||||
(supportbot.Ticket.TicketType === "channels" && ticketChannel.type !== ChannelType.GuildText)
|
||||
) {
|
||||
const onlyInTicket = new EmbedBuilder()
|
||||
.setTitle(msgconfig.ForceAddUser.NotInTicket_Title)
|
||||
.setDescription(msgconfig.ForceAddUser.NotInTicket_Description)
|
||||
@@ -68,7 +48,42 @@ module.exports = new Command({
|
||||
}
|
||||
|
||||
try {
|
||||
await ticketChannel.members.add(userToAdd.id);
|
||||
|
||||
if (supportbot.Ticket.TicketType === "threads") {
|
||||
try {
|
||||
// Explicitly ensure the bot is in the thread
|
||||
const botMember = await ticketChannel.members.fetch(interaction.client.user.id).catch(() => null);
|
||||
if (!botMember) {
|
||||
await ticketChannel.join();
|
||||
}
|
||||
|
||||
// Delay to ensure API has processed the bot's membership
|
||||
await new Promise(res => setTimeout(res, 1000));
|
||||
|
||||
// Attempt to add the user to the thread
|
||||
await ticketChannel.members.add(userToAdd.id);
|
||||
|
||||
console.log("User successfully added to the thread.");
|
||||
} catch (err) {
|
||||
console.error("Error adding user to the thread:", err.message);
|
||||
const errorEmbed = new EmbedBuilder()
|
||||
.setTitle(msgconfig.ForceAddUser.Error_Title)
|
||||
.setDescription(`An error occurred: ${err.message}`)
|
||||
.setColor(supportbot.Embed.Colours.Error);
|
||||
|
||||
return interaction.reply({
|
||||
embeds: [errorEmbed],
|
||||
ephemeral: true,
|
||||
});
|
||||
}
|
||||
|
||||
} else if (supportbot.Ticket.TicketType === "channels") {
|
||||
await ticketChannel.permissionOverwrites.create(userToAdd.id, {
|
||||
ViewChannel: true,
|
||||
SendMessages: true,
|
||||
ReadMessageHistory: true,
|
||||
});
|
||||
}
|
||||
|
||||
const ticketData = JSON.parse(fs.readFileSync(ticketDataPath, "utf8"));
|
||||
const ticketIndex = ticketData.tickets.findIndex((t) => t.id === ticketChannel.id);
|
||||
@@ -79,10 +94,9 @@ module.exports = new Command({
|
||||
|
||||
const addedEmbed = new EmbedBuilder()
|
||||
.setTitle(msgconfig.ForceAddUser.Added_Title)
|
||||
.setDescription(msgconfig.ForceAddUser.Added_Description.replace(
|
||||
"%username%",
|
||||
userToAdd.username
|
||||
))
|
||||
.setDescription(
|
||||
msgconfig.ForceAddUser.Added_Description.replace("%username%", userToAdd.username)
|
||||
)
|
||||
.setColor(supportbot.Embed.Colours.Success);
|
||||
|
||||
await interaction.reply({
|
||||
@@ -92,16 +106,17 @@ module.exports = new Command({
|
||||
|
||||
const addedToTicketEmbed = new EmbedBuilder()
|
||||
.setTitle(msgconfig.ForceAddUser.AddedToTicket_Title)
|
||||
.setDescription(msgconfig.ForceAddUser.AddedToTicket_Description.replace(
|
||||
"%channel_link%",
|
||||
`[${ticketChannel.name}](https://discord.com/channels/${ticketChannel.guild.id}/${ticketChannel.id})`
|
||||
))
|
||||
.setDescription(
|
||||
msgconfig.ForceAddUser.AddedToTicket_Description.replace(
|
||||
"%channel_link%",
|
||||
`[${ticketChannel.name}](https://discord.com/channels/${ticketChannel.guild.id}/${ticketChannel.id})`
|
||||
)
|
||||
)
|
||||
.setColor(supportbot.Embed.Colours.General);
|
||||
|
||||
await userToAdd.send({
|
||||
embeds: [addedToTicketEmbed],
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
console.error("Error adding user to the ticket:", err);
|
||||
|
||||
|
||||
+4
-3
@@ -10,9 +10,9 @@ const Command = require("../Structures/Command.js");
|
||||
|
||||
const clockedInUsers = new Set();
|
||||
|
||||
async function getRole(roleName, guild) {
|
||||
return guild.roles.cache.find(role => role.name === roleName);
|
||||
}
|
||||
// async function getRole(roleName, guild) {
|
||||
// return guild.roles.cache.find(role => role.name === roleName);
|
||||
// }
|
||||
|
||||
function updateClockedInStatus(profileEmbed, clockedIn) {
|
||||
profileEmbed.data.fields = profileEmbed.data.fields.map(field => {
|
||||
@@ -47,6 +47,7 @@ module.exports = new Command({
|
||||
const interactionUserId = interaction.user.id;
|
||||
|
||||
const user = interaction.guild.members.cache.get(viewingUserId);
|
||||
const { getRole, getChannel } = interaction.client;
|
||||
|
||||
const Staff = await getRole(supportbot.Roles.StaffMember.Staff, interaction.guild);
|
||||
const Admin = await getRole(supportbot.Roles.StaffMember.Admin, interaction.guild);
|
||||
|
||||
+20
-11
@@ -1,10 +1,9 @@
|
||||
// File path: Commands/RemoveUser.js
|
||||
|
||||
const fs = require("fs");
|
||||
const {
|
||||
EmbedBuilder,
|
||||
ApplicationCommandOptionType,
|
||||
ApplicationCommandType,
|
||||
ChannelType,
|
||||
ActionRowBuilder,
|
||||
ButtonBuilder,
|
||||
ButtonStyle,
|
||||
@@ -36,13 +35,13 @@ module.exports = new Command({
|
||||
const { getRole } = interaction.client;
|
||||
let SupportStaff = await getRole(supportbot.Roles.StaffMember.Staff, interaction.guild);
|
||||
let Admin = await getRole(supportbot.Roles.StaffMember.Admin, interaction.guild);
|
||||
if (!SupportStaff || !Admin)
|
||||
|
||||
if (!SupportStaff || !Admin) {
|
||||
return interaction.reply(
|
||||
"Some roles seem to be missing!\nPlease check for errors when starting the bot."
|
||||
);
|
||||
}
|
||||
|
||||
const NoPerms = new EmbedBuilder()
|
||||
const NoPerms = new EmbedBuilder()
|
||||
.setTitle("Invalid Permissions!")
|
||||
.setDescription(
|
||||
`${msgconfig.Error.IncorrectPerms}\n\nRole Required: \`${supportbot.Roles.StaffMember.Staff}\` or \`${supportbot.Roles.StaffMember.Admin}\``
|
||||
@@ -50,17 +49,21 @@ module.exports = new Command({
|
||||
.setColor(supportbot.Embed.Colours.Warn);
|
||||
|
||||
if (
|
||||
!interaction.member.roles.cache.has(SupportStaff.id) &&
|
||||
!interaction.member.roles.cache.has(Admin.id)
|
||||
)
|
||||
!interaction.member.roles.cache.has(SupportStaff.id) &&
|
||||
!interaction.member.roles.cache.has(Admin.id)
|
||||
) {
|
||||
return interaction.reply({ embeds: [NoPerms] });
|
||||
}
|
||||
|
||||
const userToRemove = interaction.options.getUser("user");
|
||||
const ticketChannel = interaction.channel;
|
||||
const ticketDataPath = "./Data/TicketData.json";
|
||||
|
||||
// Check if the channel is a ticket thread
|
||||
if (!ticketChannel.isThread()) {
|
||||
// Check if the channel is a ticket thread or text channel based on TicketType
|
||||
if (
|
||||
(supportbot.Ticket.TicketType === "threads" && !ticketChannel.isThread()) ||
|
||||
(supportbot.Ticket.TicketType === "channels" && ticketChannel.type !== ChannelType.GuildText)
|
||||
) {
|
||||
const onlyInTicket = new EmbedBuilder()
|
||||
.setTitle(msgconfig.RemoveUser.NotInTicket_Title)
|
||||
.setDescription(msgconfig.RemoveUser.NotInTicket_Description)
|
||||
@@ -73,8 +76,14 @@ module.exports = new Command({
|
||||
}
|
||||
|
||||
try {
|
||||
await ticketChannel.members.remove(userToRemove.id);
|
||||
// Remove user from thread or channel based on TicketType
|
||||
if (supportbot.Ticket.TicketType === "threads") {
|
||||
await ticketChannel.members.remove(userToRemove.id); // For threads
|
||||
} else if (supportbot.Ticket.TicketType === "channels") {
|
||||
await ticketChannel.permissionOverwrites.delete(userToRemove.id); // For channels
|
||||
}
|
||||
|
||||
// Update the ticket data
|
||||
const ticketData = JSON.parse(fs.readFileSync(ticketDataPath, "utf8"));
|
||||
const ticketIndex = ticketData.tickets.findIndex((t) => t.id === ticketChannel.id);
|
||||
if (ticketIndex !== -1) {
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
const { Command } = require('../Structures/Addon.js');
|
||||
const Discord = require("discord.js");
|
||||
const fs = require("fs");
|
||||
const yaml = require("js-yaml");
|
||||
const path = require("path");
|
||||
|
||||
const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8"));
|
||||
const cmdconfig = yaml.load(fs.readFileSync("./Configs/commands.yml", "utf8"));
|
||||
const settingsFilePath = path.resolve(__dirname, '../Data/settings.json');
|
||||
|
||||
function loadSettings() {
|
||||
try {
|
||||
if (fs.existsSync(settingsFilePath)) {
|
||||
const data = fs.readFileSync(settingsFilePath, 'utf8');
|
||||
return JSON.parse(data);
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error reading settings file:", error);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
function saveSettings(settings) {
|
||||
try {
|
||||
fs.writeFileSync(settingsFilePath, JSON.stringify(settings, null, 2), 'utf8');
|
||||
} catch (error) {
|
||||
console.error("Error writing settings file:", error);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new Command({
|
||||
name: cmdconfig.Settings.Command,
|
||||
description: cmdconfig.Settings.Description,
|
||||
permissions: cmdconfig.Settings.Permission,
|
||||
options: [
|
||||
{
|
||||
name: 'setstatus',
|
||||
type: Discord.ApplicationCommandOptionType.Subcommand,
|
||||
description: 'Set the bot status',
|
||||
options: [
|
||||
{
|
||||
name: 'status',
|
||||
type: Discord.ApplicationCommandOptionType.String,
|
||||
description: 'Choose the bot status',
|
||||
required: true,
|
||||
choices: [
|
||||
{ name: 'Online 🟢', value: 'online' },
|
||||
{ name: 'Idle 🌙', value: 'idle' },
|
||||
{ name: 'Do Not Disturb ⛔', value: 'dnd' },
|
||||
{ name: 'Invisible 👻', value: 'invisible' }
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'setactivity',
|
||||
type: Discord.ApplicationCommandOptionType.Subcommand,
|
||||
description: 'Set the bot activity',
|
||||
options: [
|
||||
{
|
||||
name: 'type',
|
||||
type: Discord.ApplicationCommandOptionType.String,
|
||||
description: 'Choose the activity type',
|
||||
required: true,
|
||||
choices: [
|
||||
{ name: 'Playing 🎮', value: 'PLAYING' },
|
||||
{ name: 'Watching 👀', value: 'WATCHING' },
|
||||
{ name: 'Listening 🎧', value: 'LISTENING' },
|
||||
{ name: 'Competing 🏆', value: 'COMPETING' }
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'message',
|
||||
type: Discord.ApplicationCommandOptionType.String,
|
||||
description: 'The activity message',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'streammode',
|
||||
type: Discord.ApplicationCommandOptionType.Subcommand,
|
||||
description: 'Set the bot streaming status',
|
||||
options: [
|
||||
{
|
||||
name: 'toggle',
|
||||
type: Discord.ApplicationCommandOptionType.String,
|
||||
description: 'Turn streaming mode on or off',
|
||||
required: true,
|
||||
choices: [
|
||||
{ name: 'On', value: 'on' },
|
||||
{ name: 'Off', value: 'off' }
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'twitchurl',
|
||||
type: Discord.ApplicationCommandOptionType.String,
|
||||
description: 'Twitch stream URL (Required if turning on)',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'setnickname',
|
||||
type: Discord.ApplicationCommandOptionType.Subcommand,
|
||||
description: 'Set the bot nickname',
|
||||
options: [
|
||||
{
|
||||
name: 'nickname',
|
||||
type: Discord.ApplicationCommandOptionType.String,
|
||||
description: 'The new nickname for the bot',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
async run(interaction) {
|
||||
const subcommand = interaction.options.getSubcommand();
|
||||
const settings = loadSettings();
|
||||
|
||||
if (subcommand === 'setstatus') {
|
||||
const status = interaction.options.getString('status');
|
||||
|
||||
try {
|
||||
interaction.client.user.setPresence({
|
||||
status: status,
|
||||
activities: interaction.client.user.presence.activities || [],
|
||||
});
|
||||
|
||||
settings.status = status;
|
||||
saveSettings(settings);
|
||||
|
||||
const embed = new Discord.EmbedBuilder()
|
||||
.setDescription(`Status set to **${status.charAt(0).toUpperCase() + status.slice(1)}**`)
|
||||
.setColor(supportbot.Embed.Colours.General);
|
||||
|
||||
return interaction.reply({ embeds: [embed], ephemeral: true });
|
||||
} catch (error) {
|
||||
return interaction.reply({ content: `Failed to set status: ${error.message}`, ephemeral: true });
|
||||
}
|
||||
}
|
||||
|
||||
if (subcommand === 'setactivity') {
|
||||
const activityType = interaction.options.getString('type');
|
||||
const activityMessage = interaction.options.getString('message');
|
||||
|
||||
try {
|
||||
interaction.client.user.setPresence({
|
||||
activities: [{ name: activityMessage, type: Discord.ActivityType[activityType] }],
|
||||
status: interaction.client.user.presence.status || 'online',
|
||||
});
|
||||
|
||||
settings.activity = { type: activityType, message: activityMessage };
|
||||
saveSettings(settings);
|
||||
|
||||
const embed = new Discord.EmbedBuilder()
|
||||
.setDescription(`Activity set to **${activityType.toLowerCase()} ${activityMessage}**`)
|
||||
.setColor(supportbot.Embed.Colours.General);
|
||||
|
||||
return interaction.reply({ embeds: [embed], ephemeral: true });
|
||||
} catch (error) {
|
||||
return interaction.reply({ content: `Failed to set activity: ${error.message}`, ephemeral: true });
|
||||
}
|
||||
} else if (subcommand === 'streammode') {
|
||||
const toggle = interaction.options.getString('toggle');
|
||||
const twitchUrl = interaction.options.getString('twitchurl');
|
||||
|
||||
if (toggle === 'on') {
|
||||
if (!twitchUrl) {
|
||||
return interaction.reply({ content: 'Please provide a Twitch URL to stream.', ephemeral: true });
|
||||
}
|
||||
|
||||
try {
|
||||
interaction.client.user.setPresence({
|
||||
activities: [{ name: 'Streaming', type: Discord.ActivityType.Streaming, url: twitchUrl }],
|
||||
status: 'online',
|
||||
});
|
||||
|
||||
settings.streaming = { active: true, url: twitchUrl };
|
||||
saveSettings(settings);
|
||||
|
||||
const embed = new Discord.EmbedBuilder()
|
||||
.setDescription(`**Streaming mode enabled!**\nStreaming: [Twitch](${twitchUrl})`)
|
||||
.setColor(supportbot.Embed.Colours.General);
|
||||
|
||||
return interaction.reply({ embeds: [embed], ephemeral: true });
|
||||
} catch (error) {
|
||||
return interaction.reply({ content: `Failed to enable streaming mode: ${error.message}`, ephemeral: true });
|
||||
}
|
||||
} else if (toggle === 'off') {
|
||||
try {
|
||||
interaction.client.user.setPresence({
|
||||
activities: interaction.client.user.presence.activities.filter(a => a.type !== Discord.ActivityType.Streaming),
|
||||
status: settings.status || 'online',
|
||||
});
|
||||
|
||||
settings.streaming = { active: false };
|
||||
saveSettings(settings);
|
||||
|
||||
const embed = new Discord.EmbedBuilder()
|
||||
.setDescription(`**Streaming mode disabled!**`)
|
||||
.setColor(supportbot.Embed.Colours.General);
|
||||
|
||||
return interaction.reply({ embeds: [embed], ephemeral: true });
|
||||
} catch (error) {
|
||||
return interaction.reply({ content: `Failed to disable streaming mode: ${error.message}`, ephemeral: true });
|
||||
}
|
||||
}
|
||||
} else if (subcommand === 'setnickname') {
|
||||
const nickname = interaction.options.getString('nickname');
|
||||
|
||||
try {
|
||||
const guild = interaction.guild;
|
||||
const botMember = guild.members.cache.get(interaction.client.user.id);
|
||||
await botMember.setNickname(nickname);
|
||||
|
||||
settings.nickname = nickname;
|
||||
saveSettings(settings);
|
||||
|
||||
const embed = new Discord.EmbedBuilder()
|
||||
.setDescription(`Bot nickname set to **${nickname}**`)
|
||||
.setColor(supportbot.Embed.Colours.General);
|
||||
|
||||
return interaction.reply({ embeds: [embed], ephemeral: true });
|
||||
} catch (error) {
|
||||
return interaction.reply({ content: `Failed to set nickname: ${error.message}`, ephemeral: true });
|
||||
}
|
||||
} else {
|
||||
return interaction.reply({ content: 'Invalid command usage.', ephemeral: true });
|
||||
}
|
||||
},
|
||||
});
|
||||
+113
-104
@@ -38,19 +38,16 @@ async function getClockedInUsers(guild) {
|
||||
}
|
||||
|
||||
async function assignTicketToUser(ticketChannel, Staff, Admin, interaction, attempts = 0) {
|
||||
console.log(`Assigning ticket attempt ${attempts}`);
|
||||
|
||||
try {
|
||||
const clockedInUsers = await getClockedInUsers(interaction.guild);
|
||||
console.log(`Clocked in users: ${Array.from(clockedInUsers).join(', ')}`);
|
||||
|
||||
if (clockedInUsers.size === 0 || attempts >= 2) {
|
||||
console.log("No clocked in users or max attempts reached");
|
||||
const claimChannel = await interaction.guild.channels.cache.get(supportbot.Ticket.ClaimTickets.Channel);
|
||||
if (claimChannel) {
|
||||
const claimEmbed = new EmbedBuilder()
|
||||
.setTitle(msgconfig.Ticket.ClaimTickets.ClaimTitle || 'Default Claim Title')
|
||||
.setDescription(msgconfig.Ticket.ClaimTickets.ClaimMessage || 'Default Claim Message')
|
||||
.setTitle(msgconfig.Ticket.ClaimTickets.ClaimTitle)
|
||||
.setDescription(msgconfig.Ticket.ClaimTickets.ClaimMessage)
|
||||
.setColor(supportbot.Embed.Colours.General);
|
||||
|
||||
const claimButton = new ButtonBuilder()
|
||||
@@ -70,17 +67,15 @@ async function assignTicketToUser(ticketChannel, Staff, Admin, interaction, atte
|
||||
const collector = claimMessage.createMessageComponentCollector({ filter, time: 120000 });
|
||||
|
||||
collector.on('collect', async i => {
|
||||
console.log(`Ticket claimed by user ${i.user.id}`);
|
||||
await ticketChannel.send({ content: `<@${i.user.id}> has claimed the ticket.` });
|
||||
});
|
||||
|
||||
collector.on('end', async collected => {
|
||||
if (collected.size === 0) {
|
||||
console.log("No one claimed the ticket, notifying admins");
|
||||
await claimMessage.delete();
|
||||
|
||||
await claimChannel.send({
|
||||
content: `No one claimed the ticket. Tagging roles: <@&${Staff.id}> <@&${Admin.id}>`,
|
||||
content: `Ticket is still unclaimed. \nCC: [<@&${Staff.id}> <@&${Admin.id}]`,
|
||||
embeds: [new EmbedBuilder().setDescription(`Ticket is still unclaimed: <#${ticketChannel.id}>`).setColor(supportbot.Embed.Colours.Warn)],
|
||||
});
|
||||
}
|
||||
@@ -96,11 +91,10 @@ async function assignTicketToUser(ticketChannel, Staff, Admin, interaction, atte
|
||||
const clockedInArray = Array.from(clockedInUsers);
|
||||
const assignedUserId = clockedInArray[Math.floor(Math.random() * clockedInArray.length)];
|
||||
const assignedUser = await interaction.guild.members.fetch(assignedUserId);
|
||||
console.log(`Assigned user: ${assignedUserId}`);
|
||||
|
||||
const claimEmbed = new EmbedBuilder()
|
||||
.setTitle(msgconfig.Ticket.ClaimTickets.ClaimTitle || 'Default Claim Title')
|
||||
.setDescription(msgconfig.Ticket.ClaimTickets.ClaimMessage.replace('%user%', interaction.user.id) || 'Default Claim Message')
|
||||
.setTitle(msgconfig.Ticket.ClaimTickets.ClaimTitle)
|
||||
.setDescription(msgconfig.Ticket.ClaimTickets.ClaimMessage.replace('%user%', interaction.user.id))
|
||||
.setColor(supportbot.Embed.Colours.General);
|
||||
|
||||
const claimButton = new ButtonBuilder()
|
||||
@@ -126,13 +120,11 @@ async function assignTicketToUser(ticketChannel, Staff, Admin, interaction, atte
|
||||
const collector = claimMessage.createMessageComponentCollector({ filter, time: 120000 });
|
||||
|
||||
collector.on('collect', async i => {
|
||||
console.log(`Ticket claimed by user ${i.user.id}`);
|
||||
await ticketChannel.send({ content: `<@${assignedUserId}>` });
|
||||
await ticketChannel.send({ content: `<@${assignedUserId}>` }).then(msg => setTimeout(() => msg.delete(), 5000));
|
||||
});
|
||||
|
||||
collector.on('end', async collected => {
|
||||
if (collected.size === 0) {
|
||||
console.log("No one claimed the ticket, attempting reassignment");
|
||||
await claimMessage.delete();
|
||||
|
||||
if (attempts >= 1) {
|
||||
@@ -141,7 +133,6 @@ async function assignTicketToUser(ticketChannel, Staff, Admin, interaction, atte
|
||||
embeds: [new EmbedBuilder().setDescription(`Ticket is still unclaimed: <#${ticketChannel.id}>`).setColor(supportbot.Embed.Colours.Warn)],
|
||||
});
|
||||
|
||||
// Add a claim button for any staff member to click
|
||||
const claimEmbed = new EmbedBuilder()
|
||||
.setTitle(msgconfig.Ticket.ClaimTickets.ClaimTitle)
|
||||
.setDescription(msgconfig.Ticket.ClaimTickets.ClaimMessage)
|
||||
@@ -156,7 +147,6 @@ async function assignTicketToUser(ticketChannel, Staff, Admin, interaction, atte
|
||||
const row = new ActionRowBuilder().addComponents(claimButton);
|
||||
|
||||
const claimMessage = await claimChannel.send({
|
||||
content: `<@&${Staff.id}> <@&${Admin.id}>`,
|
||||
embeds: [claimEmbed],
|
||||
components: [row],
|
||||
});
|
||||
@@ -281,31 +271,87 @@ module.exports = new Command({
|
||||
ephemeral: true,
|
||||
});
|
||||
|
||||
const TicketCategory = interaction.guild.channels.cache.find(
|
||||
(c) => c.name === supportbot.Ticket.TicketCategory || c.id === supportbot.Ticket.TicketCategory
|
||||
);
|
||||
let ticketChannel;
|
||||
|
||||
const channel = await getChannel(supportbot.Ticket.TicketCategory, interaction.guild);
|
||||
const ticketChannel = await channel.threads.create({
|
||||
name: `${supportbot.Ticket.Channel}${ticketNumberID}`,
|
||||
type: ChannelType.PrivateThread,
|
||||
parent: TicketCategory,
|
||||
autoArchiveDuration: 60,
|
||||
reason: 'support ticket',
|
||||
});
|
||||
if (supportbot.Ticket.TicketType === "threads") {
|
||||
const TicketHome = interaction.guild.channels.cache.find(
|
||||
(c) => c.name === supportbot.Ticket.TicketHome || c.id === supportbot.Ticket.TicketHome
|
||||
);
|
||||
|
||||
const channel = await getChannel(supportbot.Ticket.TicketHome, interaction.guild);
|
||||
ticketChannel = await channel.threads.create({
|
||||
name: `${supportbot.Ticket.Channel}${ticketNumberID}`,
|
||||
type: ChannelType.PrivateThread,
|
||||
parent: TicketHome,
|
||||
autoArchiveDuration: 60,
|
||||
reason: 'support ticket',
|
||||
});
|
||||
} else if (supportbot.Ticket.TicketType === "channels") {
|
||||
const category = interaction.guild.channels.cache.find(
|
||||
(c) => c.name === supportbot.Ticket.TicketChannelsCategory || c.id === supportbot.Ticket.TicketChannelsCategory
|
||||
);
|
||||
|
||||
if (!category) {
|
||||
return interaction.reply({
|
||||
content: "The ticket category does not exist!",
|
||||
ephemeral: true,
|
||||
});
|
||||
}
|
||||
|
||||
ticketChannel = await interaction.guild.channels.create({
|
||||
name: `${supportbot.Ticket.Channel}${ticketNumberID}`,
|
||||
type: ChannelType.GuildText,
|
||||
parent: category.id,
|
||||
reason: 'support ticket',
|
||||
});
|
||||
|
||||
// Move to secondary category if the primary one is full
|
||||
if (category.children.size >= 50) {
|
||||
const secondaryCategory = interaction.guild.channels.cache.find(
|
||||
(c) => c.name === supportbot.Ticket.TicketChannelsCategory2 || c.id === supportbot.Ticket.TicketChannelsCategory2
|
||||
);
|
||||
|
||||
if (secondaryCategory) {
|
||||
await ticketChannel.setParent(secondaryCategory.id);
|
||||
} else {
|
||||
return interaction.reply({
|
||||
content: "The secondary ticket category does not exist!",
|
||||
ephemeral: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assign ticket to a user if claiming tickets is enabled
|
||||
if (supportbot.Ticket.ClaimTickets.Enabled) {
|
||||
const assignedUserId = await assignTicketToUser(ticketChannel, Staff, Admin, interaction);
|
||||
if (!assignedUserId) {
|
||||
const claimChannel = await interaction.guild.channels.cache.get(supportbot.Ticket.ClaimTickets.Channel);
|
||||
await claimChannel.send(`<@&${Staff.id}> <@&${Admin.id}>`);
|
||||
}
|
||||
}
|
||||
|
||||
// Add user to the ticket channel
|
||||
await ticketChannel.members.add(interaction.user.id);
|
||||
if (supportbot.Ticket.TicketType === "threads") {
|
||||
await ticketChannel.members.add(interaction.user.id);
|
||||
|
||||
} else if (supportbot.Ticket.TicketType === "channels") {
|
||||
|
||||
await ticketChannel.permissionOverwrites.create(interaction.user.id, {
|
||||
ViewChannel: true,
|
||||
SendMessages: true,
|
||||
ReadMessageHistory: true,
|
||||
});
|
||||
|
||||
await ticketChannel.permissionOverwrites.create(Admin, {
|
||||
ViewChannel: true,
|
||||
SendMessages: true,
|
||||
ReadMessageHistory: true,
|
||||
});
|
||||
|
||||
await ticketChannel.permissionOverwrites.create(interaction.guild.roles.everyone, {
|
||||
ViewChannel: false,
|
||||
});
|
||||
}
|
||||
|
||||
// Save ticket data
|
||||
TicketData.tickets.push({
|
||||
id: ticketChannel.id,
|
||||
@@ -368,92 +414,55 @@ module.exports = new Command({
|
||||
|
||||
// Create the control panel
|
||||
const SelectMenus = new StringSelectMenuBuilder()
|
||||
.setCustomId("ticketcontrolpanel")
|
||||
.setPlaceholder("Ticket Control Panel")
|
||||
.addOptions(
|
||||
new StringSelectMenuOptionBuilder()
|
||||
.setLabel("Close")
|
||||
.setDescription("Close the ticket.")
|
||||
.setEmoji(supportbot.SelectMenus.Tickets.CloseEmoji)
|
||||
.setValue("ticketclose"),
|
||||
new StringSelectMenuOptionBuilder()
|
||||
.setLabel("Archive")
|
||||
.setDescription("Acrhive the ticket.")
|
||||
.setEmoji(supportbot.SelectMenus.Tickets.ArchiveEmoji)
|
||||
.setValue("archiveticket"),
|
||||
.setCustomId("ticketcontrolpanel")
|
||||
.setPlaceholder("Ticket Control Panel")
|
||||
.addOptions(
|
||||
new StringSelectMenuOptionBuilder()
|
||||
.setLabel("Close")
|
||||
.setDescription("Close the ticket.")
|
||||
.setEmoji(supportbot.SelectMenus.Tickets.CloseEmoji)
|
||||
.setValue("ticketclose"),
|
||||
new StringSelectMenuOptionBuilder()
|
||||
.setLabel("Archive")
|
||||
.setDescription("Archive the ticket.")
|
||||
.setEmoji(supportbot.SelectMenus.Tickets.ArchiveEmoji)
|
||||
.setValue("archiveticket"),
|
||||
...(supportbot.Ticket.TicketType === "threads" ? [
|
||||
new StringSelectMenuOptionBuilder()
|
||||
.setLabel("Lock Ticket")
|
||||
.setDescription("Lock the ticket.")
|
||||
.setEmoji(supportbot.SelectMenus.Tickets.LockEmoji)
|
||||
.setValue("lockticket"),
|
||||
new StringSelectMenuOptionBuilder()
|
||||
.setLabel("Enable Invites")
|
||||
.setDescription("Enable invites.")
|
||||
.setEmoji(supportbot.SelectMenus.Tickets.EnableInvitesEmoji)
|
||||
.setValue("enableinvites"),
|
||||
new StringSelectMenuOptionBuilder()
|
||||
.setLabel("Disable Invites")
|
||||
.setDescription("Disable invites.")
|
||||
.setEmoji(supportbot.SelectMenus.Tickets.DisableInvitesEmoji)
|
||||
.setValue("disableinvites"),
|
||||
);
|
||||
.setValue("lockticket")
|
||||
] : []),
|
||||
new StringSelectMenuOptionBuilder()
|
||||
.setLabel("Rename Ticket")
|
||||
.setDescription("Rename the ticket.")
|
||||
.setEmoji(supportbot.SelectMenus.Tickets.RenameEmoji)
|
||||
.setValue("renameticket")
|
||||
);
|
||||
|
||||
if (supportbot.Ticket.TicketType === "threads") {
|
||||
SelectMenus.addOptions(
|
||||
new StringSelectMenuOptionBuilder()
|
||||
.setLabel("Enable Invites")
|
||||
.setDescription("Enable invites.")
|
||||
.setEmoji(supportbot.SelectMenus.Tickets.EnableInvitesEmoji)
|
||||
.setValue("enableinvites"),
|
||||
new StringSelectMenuOptionBuilder()
|
||||
.setLabel("Disable Invites")
|
||||
.setDescription("Disable invites.")
|
||||
.setEmoji(supportbot.SelectMenus.Tickets.DisableInvitesEmoji)
|
||||
.setValue("disableinvites"),
|
||||
);
|
||||
}
|
||||
|
||||
const row2 = new ActionRowBuilder().addComponents(SelectMenus);
|
||||
|
||||
// Send the ticket message and control panel
|
||||
await ticketChannel.send({
|
||||
embeds: [TicketMessage],
|
||||
components: [row2],
|
||||
});
|
||||
|
||||
// Handle department selection if not specified
|
||||
if (!department) {
|
||||
try {
|
||||
const buttons = supportbot.Departments.map((x, index) =>
|
||||
new ButtonBuilder()
|
||||
.setCustomId("Department" + index)
|
||||
.setLabel(x.title)
|
||||
.setStyle(x.color)
|
||||
.setEmoji(x.emoji)
|
||||
);
|
||||
|
||||
const row = new ActionRowBuilder().addComponents(buttons);
|
||||
|
||||
const message = await ticketChannel.send({
|
||||
content: "Please select a department:",
|
||||
components: [row],
|
||||
});
|
||||
|
||||
const filter = (i) => i.user.id === interaction.user.id;
|
||||
await message.awaitMessageComponent({
|
||||
filter,
|
||||
max: 1,
|
||||
componentType: "BUTTON",
|
||||
time: supportbot.Ticket.Timeout * 60000,
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
if (e.code === "COLLECTOR_ERROR") {
|
||||
try {
|
||||
const ticket = TicketData.tickets.findIndex((t) => t.id === ticketChannel.id);
|
||||
TicketData.tickets[ticket].open = false;
|
||||
fs.writeFileSync(
|
||||
"./Data/TicketData.json",
|
||||
JSON.stringify(TicketData, null, 4),
|
||||
(err) => {
|
||||
if (err) console.error(err);
|
||||
}
|
||||
);
|
||||
await interaction.user.send(
|
||||
"Your ticket has timed out. Please open a new one and select a department."
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("An error occurred while handling collector:", error);
|
||||
}
|
||||
await ticketChannel.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error in run method:", error);
|
||||
}
|
||||
|
||||
@@ -35,8 +35,13 @@ module.exports = new Command({
|
||||
});
|
||||
}
|
||||
|
||||
const channelName = panelconfig.Channel;
|
||||
const channel = interaction.guild.channels.cache.find(ch => ch.name === channelName);
|
||||
const { getChannel } = interaction.client;
|
||||
|
||||
const channel = await getChannel(
|
||||
supportbot.Ticket.TicketHome,
|
||||
interaction.guild
|
||||
);
|
||||
|
||||
if (!channel) {
|
||||
console.log(`[TICKET PANEL] ${channelName} channel not found. Please check your config file.`);
|
||||
return interaction.reply({
|
||||
|
||||
@@ -71,7 +71,7 @@ module.exports = new Command({
|
||||
let url = "https://www.science.co.il/language/Codes.php"; // URL to all available language codes
|
||||
let text = await interaction.options.getString("text"); // Grab the text to translate by the user
|
||||
let translatelog = await getChannel(
|
||||
supportbot.Translate.Log,
|
||||
supportbot.Translate.TranslateLog,
|
||||
interaction.guild
|
||||
); // Grab the set logging channel for translations
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#
|
||||
# Command Configuration
|
||||
|
||||
# If you don't want to mess with this configuration, You can manage commands via Discord Settings the Intregations.
|
||||
|
||||
Help:
|
||||
Command: "help"
|
||||
Description: "Get a list of all the commands."
|
||||
@@ -97,6 +99,16 @@ Ping:
|
||||
Permission: ["SendMessages"]
|
||||
Enabled: true
|
||||
|
||||
# ---------------------------------------
|
||||
# Bot Administrator Commands
|
||||
# ---------------------------------------
|
||||
|
||||
Settings:
|
||||
Command: "settings"
|
||||
Description: "Update bot settings."
|
||||
Permission: ["Administrator"]
|
||||
Enabled: true
|
||||
|
||||
# ---------------------------------------
|
||||
# Command Description Configuration
|
||||
# ---------------------------------------
|
||||
|
||||
+11
-6
@@ -17,7 +17,7 @@ Info:
|
||||
Title: "About Us"
|
||||
Description: "SupportBot is an open-sourced support system for discord. It's completely free to use with high amounts of customization to match your own brand."
|
||||
Button: "Visit Site"
|
||||
URL: "https://emeraldsrv.com"
|
||||
URL: "https://docs.emeraldsrv.com"
|
||||
Colour: "#f74343"
|
||||
|
||||
Welcome:
|
||||
@@ -77,14 +77,11 @@ Ticket:
|
||||
Muted: ":x: You are `Muted` and therefore not allowed to open any tickets"
|
||||
InvalidSubject: "No Reason Provided!"
|
||||
|
||||
TranscriptSavedMessage: "📝 **Transcript Saved!**"
|
||||
TicketLockMessage: "❌ **Ticket Locked!**"
|
||||
TicketDeleteMessage: "⚠ **Ticket Deleting!**"
|
||||
|
||||
ClosingTicket: ":warning: You have requested to close your support ticket."
|
||||
ConfirmClose: "Please confirm closing the ticket by clicking the button below."
|
||||
CloseTimeout: "Ticket close confirmation timed out."
|
||||
|
||||
RenamedSuccess: "🏷️ Ticket renamed successfully!"
|
||||
|
||||
ClaimTickets:
|
||||
ClaimTitle: "Incoming Support Request!"
|
||||
ClaimMessage: "A new ticket has been created by <@!%user%>. Click the button below to claim this ticket."
|
||||
@@ -105,6 +102,10 @@ TicketStats:
|
||||
|
||||
Title: "Your Ticket Stats"
|
||||
|
||||
TicketLog:
|
||||
Title: "Ticket Log"
|
||||
Colour: "#0cc559"
|
||||
|
||||
AddUser:
|
||||
NotInTicket_Title: "Ticket Invitation"
|
||||
NotInTicket_Description: "This command can only be used within a ticket thread."
|
||||
@@ -123,6 +124,10 @@ AddUser:
|
||||
Accepted_Message: "You have been added to the ticket."
|
||||
AddedToTicket_Title: "Added to Ticket"
|
||||
AddedToTicket_Description: "You have been added to the ticket %channel_link%."
|
||||
|
||||
# Added Message for inside the ticket, this informs everyone inside the ticket that the user has been added.
|
||||
Added_Title: "User Added"
|
||||
Added_Description: "Successfully added **%username%** to the ticket."
|
||||
|
||||
Declined_Title: "Invitation Declined"
|
||||
Declined_Message: "You have declined the invitation."
|
||||
|
||||
@@ -10,22 +10,22 @@ Enabled: true
|
||||
General:
|
||||
Name: "SupportBot AI"
|
||||
# What would you like to call your AI
|
||||
Model: "gpt-4o"
|
||||
Model: "gpt-4o-mini"
|
||||
# You can see a list of OpenAI Models here: https://platform.openai.com/docs/models
|
||||
|
||||
Tokens: 400
|
||||
# Max tokens you can set is 400
|
||||
# For more information about tokens, go to https://openai.com/api/pricing/
|
||||
OpenAI_Key: "OPEN_AI_KEY_HERE"
|
||||
OpenAI_Key: "OPEN_AI_API_KEY"
|
||||
# To create an OpenAI API key, go to https://platform.openai.com/api-keys
|
||||
|
||||
|
||||
PastebinAPI_Key: "PASTEBIN_API_KEY_HERE"
|
||||
PastebinAPI_Key: "PASTEBIN_API_KEY"
|
||||
# You can get your Pastebin API Key from https://pastebin.com
|
||||
PastebinAPI_URL: "https://pastebin.com/api/api_post.php"
|
||||
|
||||
Channels:
|
||||
AIChannel: "1250190338954498048"
|
||||
AIChannel: "AI_BOT_CHANNEL"
|
||||
# This is the channel where AI will respond in without needing to mention the bot.
|
||||
|
||||
Embed:
|
||||
|
||||
+41
-38
@@ -11,7 +11,7 @@
|
||||
# Official Documentation: https://github.com/Emerald-Services/SupportBot/wiki
|
||||
# Third-Party Documentation: COMING SOON
|
||||
|
||||
SupportBot_Version: "v8.0.1"
|
||||
SupportBot_Version: "v8.2"
|
||||
# Do not change the version number
|
||||
|
||||
# -------------------------
|
||||
@@ -37,6 +37,8 @@ Activity:
|
||||
StreamingURL: "https://www.twitch.tv/YOUR_TWITCH_NAME"
|
||||
# Set The Type to "Streaming" for a streaming status!
|
||||
|
||||
# You can update the activity via Discord using: /settings
|
||||
|
||||
# -------------------------
|
||||
# Embeds
|
||||
# -------------------------
|
||||
@@ -57,15 +59,15 @@ Embed:
|
||||
Roles:
|
||||
AutoRole:
|
||||
Enabled: true
|
||||
Role: "Member"
|
||||
Role: "ROLE_ID"
|
||||
|
||||
StaffMember:
|
||||
Staff: "Staff"
|
||||
Admin: "Admin"
|
||||
Staff: "STAFF_ROLE_ID"
|
||||
Admin: "ADMIN_ROLE_ID"
|
||||
|
||||
ModRoles:
|
||||
Muted: "Muted"
|
||||
Blacklisted: "Blacklisted"
|
||||
Muted: "MUTED_ROLE_ID"
|
||||
Blacklisted: "BLACKLISTED_ROLE_ID"
|
||||
|
||||
# ----------------------------
|
||||
# System Messages
|
||||
@@ -73,18 +75,18 @@ Roles:
|
||||
|
||||
Welcome:
|
||||
Enabled: true
|
||||
Channel: "🚨┃join-leave-logs"
|
||||
Channel: "WELCOME_CHANNEL_ID"
|
||||
|
||||
Leave:
|
||||
Enabled: true
|
||||
Channel: "🚨┃join-leave-logs"
|
||||
Channel: "LEAVE_CHANNEL_ID"
|
||||
|
||||
# ----------------------------
|
||||
# Suggestions
|
||||
# ----------------------------
|
||||
|
||||
Suggestions:
|
||||
Channel: "📗┃suggestions"
|
||||
Channel: "SUGGEST_CHANNEL_ID"
|
||||
UpvoteEmoji: "✅"
|
||||
DownvoteEmoji: "❌"
|
||||
|
||||
@@ -119,8 +121,23 @@ Suggestions:
|
||||
# -------------------------
|
||||
|
||||
Ticket:
|
||||
TicketCategory: "📗┃tickets" #Where tickets normally go with the /ticket command
|
||||
# This is the channel name for the ticket threads to be created, NOT A DISCORD CATEGORY!
|
||||
TicketType: "channels" # Choose how you want tickets to be created.
|
||||
# Options:
|
||||
# channels - Tickets will be created as channels in the
|
||||
# threads - Tickets will be created as threads through the "TicketHome"
|
||||
|
||||
# For TicketType "Threads"
|
||||
TicketHome: "TICKETHOME_CHANNEL_ID"
|
||||
# What is TicketHome?
|
||||
# - Channel where the Ticket creation panel is sent.
|
||||
# - Channel where ticket threads are made. (only if ticket threads is enabled above.)
|
||||
|
||||
# For TicketType "Channels"
|
||||
TicketChannelsCategory: "TICKET_CATEGORY_ID" # if Type is set to channels
|
||||
TicketChannelsCategory2: "BACKUP_TICKET_CATEGORY_ID" # This will be used if the first category has reached the max channel limit.
|
||||
TicketArchiveCategory: "ARCHIVE_TICKET_CATEGORY_ID"
|
||||
|
||||
# ---
|
||||
|
||||
Channel: "ticket-" # The prefix for ticket channel names
|
||||
TicketsPerUser: 100
|
||||
@@ -134,19 +151,17 @@ Ticket:
|
||||
# Set to true to allow all staff to access the ticket
|
||||
|
||||
Log:
|
||||
TicketLog: "🚨┃ticket-data"
|
||||
TicketLog_Title: "Ticket Closed"
|
||||
DisableTicketLogChannel: false
|
||||
|
||||
TranscriptLog: "🚨┃ticket-data"
|
||||
TranscriptTitle: "Ticket Transcript"
|
||||
TicketDataLog: "TICKET_LOG_ID"
|
||||
TickeDataTitle: "Ticket Data"
|
||||
|
||||
Close:
|
||||
StaffOnly: true
|
||||
# Set to false is anyone is able to close a ticket.
|
||||
|
||||
Confirmation_Button: "Confirm Close"
|
||||
Confirmation_Emoji: "🗑️"
|
||||
Confirmation_Style: "2"
|
||||
|
||||
Title: "Are you sure you want to close this ticket?"
|
||||
|
||||
# Available Button Styles
|
||||
@@ -158,16 +173,18 @@ Ticket:
|
||||
Invites:
|
||||
StaffOnly: true
|
||||
|
||||
LockedTickets:
|
||||
Channel: "1267856939275124809"
|
||||
|
||||
ClaimTickets:
|
||||
Enabled: true
|
||||
Channel: "1249723473757077624"
|
||||
Channel: "CLAIM_TICKETS_CHANNEL_ID"
|
||||
# Channel name or Channel ID
|
||||
|
||||
ClaimAcceptTime: 120000
|
||||
# How long the assigned user has to accept the ticket before it gets re-assigned to someone else.
|
||||
# 120000 = 2 Minutes
|
||||
# 180000 = 3 Minutes
|
||||
# 240000 = 4 Minutes
|
||||
# 300000 = 5 Minutes
|
||||
# Time in Mliseconds
|
||||
|
||||
ButtonTitle: "Claim Ticket"
|
||||
ButtonEmoji: "🎫"
|
||||
@@ -179,18 +196,6 @@ Ticket:
|
||||
# 3 - Green
|
||||
# 4 - Red
|
||||
|
||||
|
||||
# -------------------------
|
||||
# Departments - NOT IN THIS UPDATE
|
||||
# -------------------------
|
||||
|
||||
Departments:
|
||||
- title: "Create Ticket"
|
||||
role: "Staff"
|
||||
color: "2"
|
||||
emoji: "🎫"
|
||||
category: "TICKETS"
|
||||
|
||||
# -------------------------
|
||||
# Buttons
|
||||
# -------------------------
|
||||
@@ -207,14 +212,12 @@ Buttons:
|
||||
Unlock_Emoji: "🔓"
|
||||
Unlock_Style: "2"
|
||||
|
||||
|
||||
# Available Button Styles
|
||||
# 1 - Blurple
|
||||
# 2 - Grey
|
||||
# 3 - Green
|
||||
# 4 - Red
|
||||
|
||||
|
||||
# -------------------------
|
||||
# Select Menus
|
||||
# -------------------------
|
||||
@@ -222,18 +225,18 @@ Buttons:
|
||||
SelectMenus:
|
||||
Tickets:
|
||||
PanelEmoji: "⚙️"
|
||||
|
||||
|
||||
CloseEmoji: "🗑️"
|
||||
ArchiveEmoji: "♻️"
|
||||
LockEmoji: "🔐"
|
||||
RenameEmoji: "🏷️"
|
||||
|
||||
EnableInvitesEmoji: "📤"
|
||||
DisableInvitesEmoji: "📥"
|
||||
|
||||
|
||||
# -------------------------
|
||||
# Misc
|
||||
# -------------------------
|
||||
|
||||
Translate:
|
||||
Log: "🚨┃logs"
|
||||
TranslateLog: "TRANSLATE_LOG_ID"
|
||||
@@ -20,9 +20,6 @@ Panel: true
|
||||
# Ticket Panel Message Configuration #2b2d31
|
||||
# ----------------------------------------
|
||||
|
||||
Channel: "📗┃tickets"
|
||||
# The channel used to create the ticket panel, Use command /ticketpanel to generate it.
|
||||
|
||||
PanelTitle: "SupportBot"
|
||||
PanelColour: "#0cc559"
|
||||
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
{
|
||||
|
||||
}
|
||||
{}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"tickets": [
|
||||
{}
|
||||
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"id": 0,
|
||||
"TicketPanelID": "000000000000000000"
|
||||
}
|
||||
"TicketPanelID": "0000000000000000000"
|
||||
}
|
||||
+20
-19
@@ -19,7 +19,8 @@ const msgconfig = yaml.load(
|
||||
module.exports = new Event("guildMemberAdd", async (client, member, interaction, guild) => {
|
||||
|
||||
if (supportbot.Welcome.Enabled) {
|
||||
const WelcomeChannel = member.guild.channels.cache.find(channel => channel.name === supportbot.Welcome.Channel)
|
||||
const WelcomeChannel = member.guild.channels.cache.get(supportbot.Welcome.Channel) ||
|
||||
member.guild.channels.cache.find(channel => channel.name === supportbot.Welcome.Channel);
|
||||
|
||||
const WelcomeEmbed = new Discord.EmbedBuilder()
|
||||
.setColor(msgconfig.Welcome.Embed.Colour)
|
||||
@@ -27,29 +28,29 @@ module.exports = new Event("guildMemberAdd", async (client, member, interaction,
|
||||
.setDescription(msgconfig.Welcome.Embed.Message.replace(/%joined_user%/g, member.user))
|
||||
.setTimestamp();
|
||||
|
||||
if (msgconfig.Welcome.Embed.Thumbnail === "BOT") {
|
||||
WelcomeEmbed.setThumbnail(client.user.displayAvatarURL())
|
||||
}
|
||||
if (msgconfig.Welcome.Embed.Thumbnail === "BOT") {
|
||||
WelcomeEmbed.setThumbnail(client.user.displayAvatarURL())
|
||||
} else if (msgconfig.Welcome.Embed.Thumbnail === "USER") {
|
||||
WelcomeEmbed.setThumbnail(member.user.displayAvatarURL())
|
||||
}
|
||||
|
||||
if (msgconfig.Welcome.Embed.Thumbnail === "USER") {
|
||||
WelcomeEmbed.setThumbnail(member.user.displayAvatarURL())
|
||||
}
|
||||
if (msgconfig.Welcome.Embed.ImageEnabled) {
|
||||
WelcomeEmbed.setImage(msgconfig.Welcome.Embed.ImageURL)
|
||||
}
|
||||
|
||||
if (msgconfig.Welcome.Embed.ImageEnabled) {
|
||||
WelcomeEmbed.setImage(msgconfig.Welcome.Embed.ImageURL)
|
||||
}
|
||||
if (WelcomeChannel) {
|
||||
WelcomeChannel.send({ embeds: [WelcomeEmbed] });
|
||||
}
|
||||
|
||||
WelcomeChannel.send({
|
||||
embeds: [WelcomeEmbed]
|
||||
})
|
||||
|
||||
if (supportbot.Roles.AutoRole.Enabled) {
|
||||
var role = member.guild.roles.cache.find(role => role.name === supportbot.Roles.AutoRole.Role);
|
||||
if (supportbot.Roles.AutoRole.Enabled) {
|
||||
const role = member.guild.roles.cache.get(supportbot.Roles.AutoRole.Role) ||
|
||||
member.guild.roles.cache.find(role => role.name === supportbot.Roles.AutoRole.Role);
|
||||
if (role) {
|
||||
member.roles.add(role);
|
||||
}
|
||||
|
||||
console.log(`\u001b[32m`, `[+]`, `\u001b[33m`, `${member.user.username} joined the server!`)
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\u001b[32m`, `[+]`, `\u001b[33m`, `${member.user.username} joined the server!`);
|
||||
}
|
||||
|
||||
});
|
||||
+16
-16
@@ -19,32 +19,32 @@ const msgconfig = yaml.load(
|
||||
module.exports = new Event("guildMemberRemove", async (client, member, interaction, guild) => {
|
||||
|
||||
if (supportbot.Leave.Enabled) {
|
||||
const LeaveChannel = member.guild.channels.cache.find(channel => channel.name === supportbot.Leave.Channel)
|
||||
const LeaveChannel = member.guild.channels.cache.get(supportbot.Leave.Channel) ||
|
||||
member.guild.channels.cache.find(channel => channel.name === supportbot.Leave.Channel);
|
||||
|
||||
const LeaveEmbed = new Discord.EmbedBuilder()
|
||||
.setColor(msgconfig.Leave.Embed.Colour)
|
||||
.setTitle(msgconfig.Leave.Embed.Title)
|
||||
.setDescription(msgconfig.Leave.Embed.Message.replace(/%joined_user%/g, member.user))
|
||||
.setDescription(msgconfig.Leave.Embed.Message.replace(/%left_user%/g, member.user))
|
||||
.setTimestamp();
|
||||
|
||||
if (msgconfig.Leave.Embed.Thumbnail === "BOT") {
|
||||
LeaveEmbed.setThumbnail(client.user.displayAvatarURL())
|
||||
}
|
||||
if (msgconfig.Leave.Embed.Thumbnail === "BOT") {
|
||||
LeaveEmbed.setThumbnail(client.user.displayAvatarURL());
|
||||
} else if (msgconfig.Leave.Embed.Thumbnail === "USER") {
|
||||
LeaveEmbed.setThumbnail(member.user.displayAvatarURL());
|
||||
}
|
||||
|
||||
if (msgconfig.Leave.Embed.Thumbnail === "USER") {
|
||||
LeaveEmbed.setThumbnail(member.user.displayAvatarURL())
|
||||
}
|
||||
|
||||
if (msgconfig.Leave.Embed.ImageEnabled) {
|
||||
LeaveEmbed.setImage(msgconfig.Leave.Embed.ImageURL)
|
||||
}
|
||||
if (msgconfig.Leave.Embed.ImageEnabled) {
|
||||
LeaveEmbed.setImage(msgconfig.Leave.Embed.ImageURL);
|
||||
}
|
||||
|
||||
if (LeaveChannel) {
|
||||
LeaveChannel.send({
|
||||
embeds: [LeaveEmbed]
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`\u001b[31m`, `[-]`, `\u001b[33m`, `${member.user.username} left the server!`)
|
||||
console.log(`\u001b[31m`, `[-]`, `\u001b[33m`, `${member.user.username} left the server!`);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
+247
-21
@@ -91,6 +91,46 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (interaction.customId === "renameTicketModal") {
|
||||
const newTicketName = interaction.fields.getTextInputValue("renameTicket");
|
||||
|
||||
// Fixing the ticketChannelId extraction and lookup
|
||||
const ticketChannelId = interaction.channel.id;
|
||||
|
||||
let ticketChannel;
|
||||
if (supportbot.Ticket.TicketType === "threads") {
|
||||
ticketChannel = interaction.guild.channels.cache.get(ticketChannelId);
|
||||
} else if (supportbot.Ticket.TicketType === "channels") {
|
||||
ticketChannel = interaction.guild.channels.cache.get(ticketChannelId);
|
||||
}
|
||||
|
||||
if (!ticketChannel) {
|
||||
return interaction.reply({
|
||||
content: "Ticket channel not found.",
|
||||
ephemeral: true,
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await ticketChannel.setName(newTicketName);
|
||||
|
||||
const renamedsuccess = new Discord.EmbedBuilder()
|
||||
.setDescription(msgconfig.Ticket.RenamedSuccess)
|
||||
.setColor(supportbot.Embed.Colours.Success);
|
||||
|
||||
return interaction.reply({
|
||||
embeds: [renamedsuccess],
|
||||
ephemeral: true,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error renaming the ticket:", error);
|
||||
return interaction.reply({
|
||||
content: "There was an error renaming the ticket.",
|
||||
ephemeral: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (interaction.isStringSelectMenu()) {
|
||||
if (interaction.customId === "ticketcontrolpanel") {
|
||||
const selectedOption = interaction.values[0];
|
||||
@@ -131,25 +171,112 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
|
||||
components: [ArchivedOptions],
|
||||
});
|
||||
|
||||
await interaction.channel.setArchived(true);
|
||||
if (supportbot.Ticket.TicketType === "threads") {
|
||||
await interaction.channel.setArchived(true);
|
||||
}
|
||||
|
||||
if (supportbot.Ticket.TicketType === "channels") {
|
||||
const { getRole, getChannel } = interaction.client;
|
||||
await interaction.channel.setParent(supportbot.Ticket.TicketArchiveCategory);
|
||||
|
||||
break;
|
||||
const ticketData = JSON.parse(fs.readFileSync("./Data/TicketData.json", "utf8"));
|
||||
const ticketInfo = ticketData.tickets.find(t => t.id === interaction.channel.id);
|
||||
|
||||
if (ticketInfo) {
|
||||
const user = interaction.guild.members.cache.get(ticketInfo.user) || ticketInfo.user;
|
||||
const claimedBy = interaction.guild.members.cache.get(ticketInfo.claimedBy) || ticketInfo.claimedBy;
|
||||
const Admin = await interaction.guild.roles.fetch(supportbot.Roles.StaffMember.Admin);
|
||||
const Staff = await interaction.guild.roles.fetch(supportbot.Roles.StaffMember.Staff);
|
||||
|
||||
if (user && user.id) {
|
||||
await interaction.channel.permissionOverwrites.edit(user.id, {
|
||||
ViewChannel: false,
|
||||
SendMessages: false,
|
||||
});
|
||||
}
|
||||
|
||||
if (supportbot.ClaimTickets === true) {
|
||||
if (claimedBy && claimedBy.id) {
|
||||
await interaction.channel.permissionOverwrites.edit(claimedBy.id, {
|
||||
ViewChannel: true,
|
||||
SendMessages: true,
|
||||
ReadMessageHistory: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
case "lockticket":
|
||||
const lockembed = new Discord.EmbedBuilder()
|
||||
.setDescription(msgconfig.Ticket.TicketLocked)
|
||||
.setColor(supportbot.Embed.Colours.Success);
|
||||
|
||||
await interaction.channel.send({
|
||||
embeds: [lockembed],
|
||||
components: [],
|
||||
ephemeral: true,s
|
||||
});
|
||||
|
||||
await interaction.channel.setLocked(true);
|
||||
if (supportbot.ClaimTickets === false) {
|
||||
if (Staff && Staff.id) {
|
||||
await interaction.channel.permissionOverwrites.edit(claimedBy.id, {
|
||||
ViewChannel: true,
|
||||
SendMessages: true,
|
||||
ReadMessageHistory: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (Admin && Admin.id) {
|
||||
await interaction.channel.permissionOverwrites.edit(Admin.id, {
|
||||
ViewChannel: true,
|
||||
SendMessages: true,
|
||||
ReadMessageHistory: true,
|
||||
});
|
||||
}
|
||||
|
||||
await interaction.channel.permissionOverwrites.edit(interaction.guild.roles.everyone.id, {
|
||||
ViewChannel: false,
|
||||
SendMessages: false,
|
||||
ReadMessageHistory: false,
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "lockticket":
|
||||
const lockembed = new Discord.EmbedBuilder()
|
||||
.setDescription(msgconfig.Ticket.TicketLocked)
|
||||
.setColor(supportbot.Embed.Colours.Success);
|
||||
|
||||
const unlockButton = new Discord.ButtonBuilder()
|
||||
.setCustomId("unlockTicket")
|
||||
.setLabel(supportbot.Buttons.Tickets.Unlock)
|
||||
.setEmoji(supportbot.Buttons.Tickets.Unlock_Emoji)
|
||||
.setStyle(supportbot.Buttons.Tickets.Unlock_Style);
|
||||
|
||||
const LockedOptions = new Discord.ActionRowBuilder()
|
||||
.addComponents(unlockButton);
|
||||
|
||||
await interaction.channel.send({
|
||||
embeds: [lockembed],
|
||||
components: [LockedOptions],
|
||||
ephemeral: false,
|
||||
});
|
||||
|
||||
|
||||
if (supportbot.Ticket.TicketType === "threads") {
|
||||
await interaction.channel.setLocked(true);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "unlockTicket":
|
||||
const unlockEmbed = new Discord.EmbedBuilder()
|
||||
.setDescription(msgconfig.Ticket.TicketUnlocked)
|
||||
.setColor(supportbot.Embed.Colours.Success);
|
||||
|
||||
await interaction.channel.send({
|
||||
embeds: [unlockEmbed],
|
||||
ephemeral: false,
|
||||
});
|
||||
|
||||
if (supportbot.Ticket.TicketType === "threads") {
|
||||
await interaction.channel.setLocked(false);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "enableinvites":
|
||||
await handleInvites(interaction, true);
|
||||
break;
|
||||
@@ -157,23 +284,101 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
|
||||
case "disableinvites":
|
||||
await handleInvites(interaction, false);
|
||||
break;
|
||||
|
||||
case "renameticket":
|
||||
const modal = new Discord.ModalBuilder()
|
||||
.setCustomId("renameTicketModal")
|
||||
.setTitle("Rename Channel")
|
||||
.addComponents(
|
||||
new Discord.ActionRowBuilder()
|
||||
.addComponents(
|
||||
new Discord.TextInputBuilder()
|
||||
.setCustomId("renameTicket")
|
||||
.setLabel("New Channel Name")
|
||||
.setStyle(Discord.TextInputStyle.Short)
|
||||
.setRequired(true)
|
||||
)
|
||||
);
|
||||
await interaction.showModal(modal);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (interaction.isButton()) {
|
||||
if (interaction.customId === "unarchiveTicket") {
|
||||
await interaction.channel.setArchived(false);
|
||||
|
||||
if (supportbot.Ticket.TicketType === "threads") {
|
||||
await interaction.channel.setArchived(false);
|
||||
}
|
||||
|
||||
if (supportbot.Ticket.TicketType === "channels") {
|
||||
const { getRole, getChannel } = interaction.client;
|
||||
await interaction.channel.setParent(supportbot.Ticket.TicketChannelsCategory);
|
||||
|
||||
const ticketData = JSON.parse(fs.readFileSync("./Data/TicketData.json", "utf8"));
|
||||
const ticketInfo = ticketData.tickets.find(t => t.id === interaction.channel.id);
|
||||
|
||||
if (ticketInfo) {
|
||||
const user = interaction.guild.members.cache.get(ticketInfo.user) || ticketInfo.user;
|
||||
const claimedBy = interaction.guild.members.cache.get(ticketInfo.claimedBy) || ticketInfo.claimedBy;
|
||||
const Admin = await interaction.guild.roles.fetch(supportbot.Roles.StaffMember.Admin);
|
||||
const Staff = await interaction.guild.roles.fetch(supportbot.Roles.StaffMember.Staff);
|
||||
|
||||
if (user && user.id) {
|
||||
await interaction.channel.permissionOverwrites.edit(user.id, {
|
||||
ViewChannel: true,
|
||||
SendMessages: true,
|
||||
ReadMessageHistory: true,
|
||||
});
|
||||
}
|
||||
|
||||
if (supportbot.ClaimTickets === true) {
|
||||
if (claimedBy && claimedBy.id) {
|
||||
await interaction.channel.permissionOverwrites.edit(claimedBy.id, {
|
||||
ViewChannel: true,
|
||||
SendMessages: true,
|
||||
ReadMessageHistory: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (supportbot.ClaimTickets === false) {
|
||||
if (Staff && Staff.id) {
|
||||
await interaction.channel.permissionOverwrites.edit(claimedBy.id, {
|
||||
ViewChannel: true,
|
||||
SendMessages: true,
|
||||
ReadMessageHistory: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (Admin && Admin.id) {
|
||||
await interaction.channel.permissionOverwrites.edit(Admin.id, {
|
||||
ViewChannel: true,
|
||||
SendMessages: true,
|
||||
ReadMessageHistory: true,
|
||||
});
|
||||
}
|
||||
|
||||
await interaction.channel.permissionOverwrites.edit(interaction.guild.roles.everyone.id, {
|
||||
ViewChannel: false,
|
||||
SendMessages: false,
|
||||
ReadMessageHistory: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const unrcembed = new Discord.EmbedBuilder()
|
||||
.setDescription(msgconfig.Ticket.TicketUnarchived)
|
||||
.setColor(supportbot.Embed.Colours.Success);
|
||||
|
||||
.setDescription(msgconfig.Ticket.TicketUnarchived)
|
||||
.setColor(supportbot.Embed.Colours.Success);
|
||||
|
||||
await interaction.update({
|
||||
embeds: [unrcembed],
|
||||
components: [],
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (interaction.customId === "createticket") {
|
||||
@@ -276,7 +481,27 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
|
||||
});
|
||||
}
|
||||
|
||||
await ticketChannel.members.add(interaction.user.id);
|
||||
if (supportbot.Ticket.TicketType === "threads") {
|
||||
await ticketChannel.members.add(interaction.user.id);
|
||||
|
||||
} else if (supportbot.Ticket.TicketType === "channels") {
|
||||
await ticketChannel.permissionOverwrites.create(interaction.user.id, {
|
||||
ViewChannel: true,
|
||||
SendMessages: true,
|
||||
ReadMessageHistory: true,
|
||||
});
|
||||
|
||||
await ticketChannel.permissionOverwrites.create(Admin, {
|
||||
ViewChannel: true,
|
||||
SendMessages: true,
|
||||
ReadMessageHistory: true,
|
||||
});
|
||||
|
||||
await ticketChannel.permissionOverwrites.create(interaction.guild.roles.everyone, {
|
||||
ViewChannel: false,
|
||||
});
|
||||
}
|
||||
|
||||
const pingclaimedstaff = await ticketChannel.send(`<@${interaction.user.id}>`);
|
||||
|
||||
setTimeout(() => {
|
||||
@@ -371,6 +596,7 @@ module.exports = new Event("interactionCreate", async (client, interaction) => {
|
||||
|
||||
await interaction.update({ embeds: [updatedEmbed] });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function handleInvites(interaction, enable) {
|
||||
|
||||
+2
-4
@@ -26,7 +26,7 @@ const msgconfig = yaml.load(
|
||||
|
||||
const Event = require("../Structures/Event.js");
|
||||
|
||||
let chan1 = client.channels.cache.get(panelconfig.Channel);
|
||||
let chan1 = client.channels.cache.get(supportbot.Ticket.TicketHome);
|
||||
|
||||
module.exports = new Event("ready", async (client, interaction) => {
|
||||
const { getRole, getChannel, getCategory } = client;
|
||||
@@ -94,15 +94,13 @@ module.exports = new Event("ready", async (client, interaction) => {
|
||||
supportbot.Roles.ModRoles.Muted
|
||||
];
|
||||
|
||||
supportbot.Departments.forEach((department) => roles.push(department.role));
|
||||
|
||||
if (supportbot.Roles.AutoRole.Role) roles.push(supportbot.Roles.AutoRole.Role);
|
||||
|
||||
const channels = [
|
||||
supportbot.Suggestions.Channel,
|
||||
supportbot.Ticket.Log.TicketLog,
|
||||
supportbot.Ticket.Log.TranscriptLog,
|
||||
panelconfig.Channel,
|
||||
supportbot.Ticket.TicketHome,
|
||||
supportbot.Welcome.Channel,
|
||||
supportbot.Leave.Channel,
|
||||
supportbot.Translate.Log
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
</a>
|
||||
|
||||
<a href="https://github.com/discordjs">
|
||||
<img src="https://img.shields.io/badge/discord.js-v13.6.x-blue.svg?style=for-the-badge&logo=javascript.svg" alt="shield.png">
|
||||
<img src="https://img.shields.io/badge/DISCORD.JS%20-%20v14-blue?style=for-the-badge" alt="shield.png">
|
||||
</a>
|
||||
|
||||
<a href="https://github.com/nodejs/node">
|
||||
<img src="https://img.shields.io/badge/node.js-v16.14.x-green.svg?style=for-the-badge&logo=node" alt="shield.png">
|
||||
<img src="https://img.shields.io/badge/NODE.JS%20-%20v20.x-green?style=for-the-badge" alt="shield.png">
|
||||
</a>
|
||||
|
||||
<a href="https://github.com/Emerald-Services/SupportBot/releases">
|
||||
|
||||
+7
-1
@@ -1,6 +1,6 @@
|
||||
|
||||
// SupportBot | Emerald Services
|
||||
// Addon Structure
|
||||
|
||||
class Command {
|
||||
constructor(options) {
|
||||
this.name = options.name;
|
||||
@@ -10,7 +10,13 @@ class Command {
|
||||
this.run = options.run;
|
||||
this.defaultPermission = true;
|
||||
}
|
||||
|
||||
// Method to dynamically update options
|
||||
setOptions(options) {
|
||||
this.options = options;
|
||||
}
|
||||
}
|
||||
|
||||
class Event {
|
||||
constructor(event, run) {
|
||||
this.event = event;
|
||||
|
||||
@@ -98,7 +98,11 @@ class Client extends Discord.Client {
|
||||
}
|
||||
|
||||
if (cmdconfig.Profile.Enabled === false) {
|
||||
tempCommandFiles = tempCommandFiles.filter(item => item !== "Profile.js");
|
||||
tempCommandFiles = tempCommandFiles.filter(item => item !== "profile.js");
|
||||
}
|
||||
|
||||
if (cmdconfig.Settings.Enabled === false) {
|
||||
tempCommandFiles = tempCommandFiles.filter(item => item !== "settings.js");
|
||||
}
|
||||
|
||||
const commandFiles = tempCommandFiles;
|
||||
|
||||
Generated
+79
-1
@@ -9,13 +9,17 @@
|
||||
"version": "8.0.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@paypal/checkout-server-sdk": "^1.0.3",
|
||||
"@vitalets/google-translate-api": "^8.0.0",
|
||||
"axios": "^1.7.2",
|
||||
"chatgpt": "^5.2.5",
|
||||
"discord.js": "^14.13.0",
|
||||
"js": "^0.1.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"moment": "^2.29.3",
|
||||
"openai": "^4.50.0"
|
||||
"ms": "^2.1.3",
|
||||
"openai": "^4.50.0",
|
||||
"paypal-rest-sdk": "^1.8.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
@@ -171,6 +175,25 @@
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@paypal/checkout-server-sdk": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@paypal/checkout-server-sdk/-/checkout-server-sdk-1.0.3.tgz",
|
||||
"integrity": "sha512-UEdq8akEdMz0Vs4qoQFU2gMp8PpyE/HKyMwiZuK4vIWUKl8jfd1fWKjQN5cDFm9NkFUIp5U7h++rdMOVj9WMNA==",
|
||||
"dependencies": {
|
||||
"@paypal/paypalhttp": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@paypal/paypalhttp": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@paypal/paypalhttp/-/paypalhttp-1.0.1.tgz",
|
||||
"integrity": "sha512-DC7AHxTT7drF6dUi3YaFdPVuT15sIkpD5H2eHmdtFgxM4UanS1o1ZDfMhR9mpxd8o+X6pz2r+EZVRRq+n1cssQ==",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/async-queue": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.3.tgz",
|
||||
@@ -380,6 +403,14 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/buffer-crc32": {
|
||||
"version": "0.2.13",
|
||||
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
||||
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/cac": {
|
||||
"version": "6.7.14",
|
||||
"resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
|
||||
@@ -510,6 +541,17 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-1.1.1.tgz",
|
||||
"integrity": "sha512-71Rod2AhcH3JhkBikVpNd0pA+fWsmAaVoti6OR38T76chA7vE3pSerS0Jor4wDw+tOueD2zLVvFOw5H0Rcj7rA==",
|
||||
"dependencies": {
|
||||
"keypress": "0.1.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6.x"
|
||||
}
|
||||
},
|
||||
"node_modules/conf": {
|
||||
"version": "11.0.2",
|
||||
"resolved": "https://registry.npmjs.org/conf/-/conf-11.0.2.tgz",
|
||||
@@ -914,6 +956,17 @@
|
||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||
"integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
|
||||
},
|
||||
"node_modules/js": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js/-/js-0.1.0.tgz",
|
||||
"integrity": "sha512-ZBbGYOpact8QAH9RprFWL4RAESYwbDodxiuDjOnzwzzk9pBzKycoifGuUrHHcDixE/eLMKPHRaXenTgu1qXBqA==",
|
||||
"dependencies": {
|
||||
"commander": "~1.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"js": "bin/js"
|
||||
}
|
||||
},
|
||||
"node_modules/js-tiktoken": {
|
||||
"version": "1.0.12",
|
||||
"resolved": "https://registry.npmjs.org/js-tiktoken/-/js-tiktoken-1.0.12.tgz",
|
||||
@@ -958,6 +1011,11 @@
|
||||
"resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.1.tgz",
|
||||
"integrity": "sha512-XQmWYj2Sm4kn4WeTYvmpKEbyPsL7nBsb647c7pMe6l02/yx2+Jfc4dT6UZkEXnIUb5LhD55r2HPsJ1milQ4rDg=="
|
||||
},
|
||||
"node_modules/keypress": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz",
|
||||
"integrity": "sha512-x0yf9PL/nx9Nw9oLL8ZVErFAk85/lslwEP7Vz7s5SI1ODXZIgit3C5qyWjw4DxOuO/3Hb4866SQh28a1V1d+WA=="
|
||||
},
|
||||
"node_modules/keyv": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||
@@ -1257,6 +1315,26 @@
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/paypal-rest-sdk": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/paypal-rest-sdk/-/paypal-rest-sdk-1.8.1.tgz",
|
||||
"integrity": "sha512-Trj2GuPn10GqpICAxQh5wjxuDT7rq7DMOkvyatz05wI5xPGmqXN7UC0WfDSF9WSBs4YdcWZP0g+nY+sOdaFggw==",
|
||||
"dependencies": {
|
||||
"buffer-crc32": "^0.2.3",
|
||||
"semver": "^5.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= v0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/paypal-rest-sdk/node_modules/semver": {
|
||||
"version": "5.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||
"bin": {
|
||||
"semver": "bin/semver"
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
|
||||
|
||||
+4
-1
@@ -18,12 +18,15 @@
|
||||
},
|
||||
"homepage": "https://github.com/Emerald-Services/SupportBot#readme",
|
||||
"dependencies": {
|
||||
"@paypal/checkout-server-sdk": "^1.0.3",
|
||||
"@vitalets/google-translate-api": "^8.0.0",
|
||||
"axios": "^1.7.2",
|
||||
"chatgpt": "^5.2.5",
|
||||
"discord.js": "^14.13.0",
|
||||
"js": "^0.1.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"moment": "^2.29.3",
|
||||
"openai": "^4.50.0"
|
||||
"ms": "^2.1.3",
|
||||
"openai": "^4.50.0",
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user