446 lines
14 KiB
JavaScript
446 lines
14 KiB
JavaScript
const config = require("./config.json");
|
|
const Discord = require("discord.js");
|
|
const client = new Discord.Client({ intents: ["Guilds", "GuildMembers", "GuildMessages", "MessageContent", "GuildMessageReactions", "DirectMessageReactions"] })
|
|
const colors = require("colors")
|
|
var staffChannel;
|
|
client.on("ready", () => {
|
|
console.log(`${colors.cyan("[Info]")} Logged in as ${client.user.username}`)
|
|
staffChannel = client.channels.cache.get(config.staff_channel);
|
|
})
|
|
|
|
var activeTickets = {};
|
|
|
|
client.on("messageCreate", async (msg) => {
|
|
if (!msg.author.id === config.ticket_bot) return;
|
|
if (!msg.content.includes(config.ticket_detect_phrase)) return;
|
|
if (!msg.channel.name.startsWith(config.ticket_channel_prefix)) return;
|
|
let user = msg.mentions.users.first();
|
|
if (!user) return;
|
|
staffChannel.send({
|
|
content: `${config.staff_ping ? config.staff_ping : ""} Ticket ${msg.channel} created by ${user} (${user.tag})`,
|
|
components: [
|
|
{
|
|
type: 1,
|
|
components: [
|
|
{
|
|
type: 2,
|
|
label: "Accept (0)",
|
|
style: 3,
|
|
custom_id: "accept",
|
|
emoji: {
|
|
name: "✅"
|
|
}
|
|
},
|
|
{
|
|
type: 2,
|
|
label: "Deny (0)",
|
|
style: 4,
|
|
custom_id: "deny",
|
|
emoji: {
|
|
name: "❌"
|
|
}
|
|
},
|
|
{
|
|
type: 2,
|
|
label: "Question (0)",
|
|
style: 1,
|
|
custom_id: "question",
|
|
emoji: {
|
|
name: "❓"
|
|
}
|
|
},
|
|
{
|
|
type: 2,
|
|
label: "Coven (0)",
|
|
style: 2,
|
|
custom_id: "coven",
|
|
emoji: {
|
|
name: "🔮"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}).then((m) => {
|
|
activeTickets[m.id] = {
|
|
user: user,
|
|
adminMessage: m,
|
|
counts: {
|
|
accept: [],
|
|
deny: [],
|
|
question: [],
|
|
coven: []
|
|
},
|
|
}
|
|
});
|
|
})
|
|
|
|
client.on("interactionCreate", async (interaction) => {
|
|
// Check if its a button event
|
|
if (!interaction.isButton()) return;
|
|
// Check if the button is on an active ticket (if not, just ignore it, it should never happen)
|
|
if (!activeTickets[interaction.message.id]) return interaction.reply({
|
|
content: "Something went wrong, this ticket is not seen as active/monitored. Please revert to using reactions.",
|
|
ephemeral: true
|
|
});
|
|
msg = activeTickets[interaction.message.id].adminMessage;
|
|
switch (interaction.customId) {
|
|
case "accept":
|
|
// If the user is already in the array, tell them with ephemeral message
|
|
if (activeTickets[interaction.message.id].counts.accept.includes(interaction.user.id)) {
|
|
return await interaction.reply({
|
|
content: "You already accepted this ticket!",
|
|
ephemeral: true
|
|
});
|
|
}
|
|
// Remove the other counts if the user is in them
|
|
if (activeTickets[interaction.message.id].counts.deny.includes(interaction.user.id)) {
|
|
activeTickets[interaction.message.id].counts.deny = activeTickets[interaction.message.id].counts.deny.filter((id) => id !== interaction.user.id);
|
|
}
|
|
if (activeTickets[interaction.message.id].counts.question.includes(interaction.user.id)) {
|
|
activeTickets[interaction.message.id].counts.question = activeTickets[interaction.message.id].counts.question.filter((id) => id !== interaction.user.id);
|
|
}
|
|
if (activeTickets[interaction.message.id].counts.coven.includes(interaction.user.id)) {
|
|
activeTickets[interaction.message.id].counts.coven = activeTickets[interaction.message.id].counts.coven.filter((id) => id !== interaction.user.id);
|
|
}
|
|
// Add the interaction user to the accepts array
|
|
activeTickets[interaction.message.id].counts.accept.push(interaction.user.id);
|
|
// if statement, check if that makes the accepts go over the threshold for auto accept
|
|
if (activeTickets[interaction.message.id].counts.accept.length >= config.auto_accept.threshold) {
|
|
// Remove roles from config.auto_accept.remove_roles array
|
|
config.auto_accept.remove_roles.forEach((role) => {
|
|
interaction.guild.members.cache.get(activeTickets[interaction.message.id].user.id).roles.remove(role);
|
|
});
|
|
// Add roles from config.auto_accept.add_roles array
|
|
config.auto_accept.add_roles.forEach((role) => {
|
|
interaction.guild.members.cache.get(activeTickets[interaction.message.id].user.id).roles.add(role);
|
|
});
|
|
|
|
// Send the welcome message to the welcome channel, replace %user% with the user
|
|
interaction.guild.channels.cache.get(config.auto_accept.welcome_channel).send({
|
|
content: config.auto_accept.welcome_message.replace("%user%", activeTickets[interaction.message.id].user)
|
|
});
|
|
|
|
return await msg.edit({
|
|
content: `${activeTickets[interaction.message.id].user} has been auto accepted, roles given, message sent!\nDont forget to close the ticket!`,
|
|
components: []
|
|
}).then(() => {
|
|
interaction.reply({
|
|
content: "You have accepted the ticket",
|
|
ephemeral: true
|
|
});
|
|
});
|
|
}
|
|
|
|
// Update the message
|
|
msg.edit({
|
|
content: msg.content,
|
|
components: [
|
|
{
|
|
type: 1,
|
|
components: [
|
|
{
|
|
type: 2,
|
|
label: `Accept (${activeTickets[interaction.message.id].counts.accept.length})`,
|
|
style: 3,
|
|
custom_id: "accept",
|
|
emoji: {
|
|
name: "✅"
|
|
}
|
|
},
|
|
{
|
|
type: 2,
|
|
label: `Deny (${activeTickets[interaction.message.id].counts.deny.length})`,
|
|
style: 4,
|
|
custom_id: "deny",
|
|
emoji: {
|
|
name: "❌"
|
|
}
|
|
},
|
|
{
|
|
type: 2,
|
|
label: `Question (${activeTickets[interaction.message.id].counts.question.length})`,
|
|
style: 1,
|
|
custom_id: "question",
|
|
emoji: {
|
|
name: "❓"
|
|
}
|
|
},
|
|
{
|
|
type: 2,
|
|
label: `Coven (${activeTickets[interaction.message.id].counts.coven.length})`,
|
|
style: 2,
|
|
custom_id: "coven",
|
|
emoji: {
|
|
name: "🔮"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}).then(() => {
|
|
interaction.reply({
|
|
content: "You have accepted the ticket",
|
|
ephemeral: true
|
|
})
|
|
});
|
|
|
|
break;
|
|
|
|
case "deny": // This one doesnt automatically do anything, its just a counter
|
|
// If the user is already in the array, tell them with ephemeral message
|
|
if (activeTickets[interaction.message.id].counts.deny.includes(interaction.user.id)) {
|
|
return await interaction.reply({
|
|
content: "You already denied this ticket!",
|
|
ephemeral: true
|
|
});
|
|
}
|
|
// Remove the other counts if the user is in them
|
|
if (activeTickets[interaction.message.id].counts.accept.includes(interaction.user.id)) {
|
|
activeTickets[interaction.message.id].counts.accept = activeTickets[interaction.message.id].counts.accept.filter((id) => id !== interaction.user.id);
|
|
}
|
|
if (activeTickets[interaction.message.id].counts.question.includes(interaction.user.id)) {
|
|
activeTickets[interaction.message.id].counts.question = activeTickets[interaction.message.id].counts.question.filter((id) => id !== interaction.user.id);
|
|
}
|
|
if (activeTickets[interaction.message.id].counts.coven.includes(interaction.user.id)) {
|
|
activeTickets[interaction.message.id].counts.coven = activeTickets[interaction.message.id].counts.coven.filter((id) => id !== interaction.user.id);
|
|
}
|
|
|
|
// Add the interaction user to the denies array
|
|
activeTickets[interaction.message.id].counts.deny.push(interaction.user.id);
|
|
// Update the message
|
|
msg.edit({
|
|
content: msg.content,
|
|
components: [
|
|
{
|
|
type: 1,
|
|
components: [
|
|
{
|
|
type: 2,
|
|
label: `Accept (${activeTickets[interaction.message.id].counts.accept.length})`,
|
|
style: 3,
|
|
custom_id: "accept",
|
|
emoji: {
|
|
name: "✅"
|
|
}
|
|
},
|
|
{
|
|
type: 2,
|
|
label: `Deny (${activeTickets[interaction.message.id].counts.deny.length})`,
|
|
style: 4,
|
|
custom_id: "deny",
|
|
emoji: {
|
|
name: "❌"
|
|
}
|
|
},
|
|
{
|
|
type: 2,
|
|
label: `Question (${activeTickets[interaction.message.id].counts.question.length})`,
|
|
style: 1,
|
|
custom_id: "question",
|
|
emoji: {
|
|
name: "❓"
|
|
}
|
|
},
|
|
{
|
|
type: 2,
|
|
label: `Coven (${activeTickets[interaction.message.id].counts.coven.length})`,
|
|
style: 2,
|
|
custom_id: "coven",
|
|
emoji: {
|
|
name: "🔮"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}).then(() => {
|
|
interaction.reply({
|
|
content: "You have denied the ticket",
|
|
ephemeral: true
|
|
})
|
|
});
|
|
break;
|
|
case "question": // This one doesnt automatically do anything, its just a counter
|
|
// If the user is already in the array, tell them with ephemeral message
|
|
if (activeTickets[interaction.message.id].counts.question.includes(interaction.user.id)) {
|
|
return await interaction.reply({
|
|
content: "You already questioned this ticket!",
|
|
ephemeral: true
|
|
});
|
|
}
|
|
// Remove the other counts if the user is in them
|
|
if (activeTickets[interaction.message.id].counts.accept.includes(interaction.user.id)) {
|
|
activeTickets[interaction.message.id].counts.accept = activeTickets[interaction.message.id].counts.accept.filter((id) => id !== interaction.user.id);
|
|
}
|
|
if (activeTickets[interaction.message.id].counts.deny.includes(interaction.user.id)) {
|
|
activeTickets[interaction.message.id].counts.deny = activeTickets[interaction.message.id].counts.deny.filter((id) => id !== interaction.user.id);
|
|
}
|
|
if (activeTickets[interaction.message.id].counts.coven.includes(interaction.user.id)) {
|
|
activeTickets[interaction.message.id].counts.coven = activeTickets[interaction.message.id].counts.coven.filter((id) => id !== interaction.user.id);
|
|
}
|
|
|
|
// Add the interaction user to the questions array
|
|
activeTickets[interaction.message.id].counts.question.push(interaction.user.id);
|
|
// Update the message
|
|
msg.edit({
|
|
content: msg.content,
|
|
components: [
|
|
{
|
|
type: 1,
|
|
components: [
|
|
{
|
|
type: 2,
|
|
label: `Accept (${activeTickets[interaction.message.id].counts.accept.length})`,
|
|
style: 3,
|
|
custom_id: "accept",
|
|
emoji: {
|
|
name: "✅"
|
|
}
|
|
},
|
|
{
|
|
type: 2,
|
|
label: `Deny (${activeTickets[interaction.message.id].counts.deny.length})`,
|
|
style: 4,
|
|
custom_id: "deny",
|
|
emoji: {
|
|
name: "❌"
|
|
}
|
|
},
|
|
{
|
|
type: 2,
|
|
label: `Question (${activeTickets[interaction.message.id].counts.question.length})`,
|
|
style: 1,
|
|
custom_id: "question",
|
|
emoji: {
|
|
name: "❓"
|
|
}
|
|
},
|
|
{
|
|
type: 2,
|
|
label: `Coven (${activeTickets[interaction.message.id].counts.coven.length})`,
|
|
style: 2,
|
|
custom_id: "coven",
|
|
emoji: {
|
|
name: "🔮"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}).then(() => {
|
|
interaction.reply({
|
|
content: "You have questioned the ticket",
|
|
ephemeral: true
|
|
})
|
|
});
|
|
break;
|
|
case "coven": // This one doesnt automatically do anything, its just a counter
|
|
// If the user is already in the array, tell them with ephemeral message
|
|
if (activeTickets[interaction.message.id].counts.coven.includes(interaction.user.id)) {
|
|
return await interaction.reply({
|
|
content: "You already coven'd this ticket!",
|
|
ephemeral: true
|
|
});
|
|
}
|
|
// Remove the other counts if the user is in them
|
|
if (activeTickets[interaction.message.id].counts.accept.includes(interaction.user.id)) {
|
|
activeTickets[interaction.message.id].counts.accept = activeTickets[interaction.message.id].counts.accept.filter((id) => id !== interaction.user.id);
|
|
}
|
|
if (activeTickets[interaction.message.id].counts.deny.includes(interaction.user.id)) {
|
|
activeTickets[interaction.message.id].counts.deny = activeTickets[interaction.message.id].counts.deny.filter((id) => id !== interaction.user.id);
|
|
}
|
|
if (activeTickets[interaction.message.id].counts.question.includes(interaction.user.id)) {
|
|
activeTickets[interaction.message.id].counts.question = activeTickets[interaction.message.id].counts.question.filter((id) => id !== interaction.user.id);
|
|
}
|
|
// Add the interaction user to the covens array
|
|
activeTickets[interaction.message.id].counts.coven.push(interaction.user.id);
|
|
// Update the message
|
|
msg.edit({
|
|
content: msg.content,
|
|
components: [
|
|
{
|
|
type: 1,
|
|
components: [
|
|
{
|
|
type: 2,
|
|
label: `Accept (${activeTickets[interaction.message.id].counts.accept.length})`,
|
|
style: 3,
|
|
custom_id: "accept",
|
|
emoji: {
|
|
name: "✅"
|
|
}
|
|
},
|
|
{
|
|
type: 2,
|
|
label: `Deny (${activeTickets[interaction.message.id].counts.deny.length})`,
|
|
style: 4,
|
|
custom_id: "deny",
|
|
emoji: {
|
|
name: "❌"
|
|
}
|
|
},
|
|
{
|
|
type: 2,
|
|
label: `Question (${activeTickets[interaction.message.id].counts.question.length})`,
|
|
style: 1,
|
|
custom_id: "question",
|
|
emoji: {
|
|
name: "❓"
|
|
}
|
|
},
|
|
{
|
|
type: 2,
|
|
label: `Coven (${activeTickets[interaction.message.id].counts.coven.length})`,
|
|
style: 2,
|
|
custom_id: "coven",
|
|
emoji: {
|
|
name: "🔮"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
});
|
|
interaction.reply({
|
|
content: "You suggested to send this ticket to the coven",
|
|
ephemeral: true
|
|
});
|
|
break;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// Lets actually handle exceptions now
|
|
process.on('unhandledRejection', (error) => {
|
|
// Log a full error with line number
|
|
console.log(`${colors.red("[ERROR]")} ${error}`);
|
|
// If config.ntfyUrl is set, Send the exception to ntfy
|
|
if (config.ntfyUrl) fetch(config.ntfyUrl, {
|
|
method: 'POST', // PUT works too
|
|
body: error,
|
|
headers: {
|
|
'Title': 'TicketTool Watcher Bot Rejection',
|
|
'Priority': 5,
|
|
'Tags': 'warning,inbox_tray,TicketTool Watcher'
|
|
}
|
|
});
|
|
});
|
|
|
|
process.on('uncaughtException', (error) => {
|
|
// Log a full error with line number
|
|
console.log(`${colors.red("[ERROR]")} ${error}`);
|
|
// If config.ntfyUrl is set, Send the exception to ntfy
|
|
if (config.ntfyUrl) fetch(config.ntfyUrl, {
|
|
method: 'POST', // PUT works too
|
|
body: error,
|
|
headers: {
|
|
'Title': 'TicketTool Watcher Bot Exception',
|
|
'Priority': 5,
|
|
'Tags': 'warning,inbox_tray,TicketTool Watcher'
|
|
}
|
|
});
|
|
});
|
|
|
|
client.login(config.token) |