Compare commits

...
27 Commits
Author SHA1 Message Date
Jasper ad10a98f33 Merge pull request #24 from DJj123dj/dev
v2.4.0 pre release
2022-08-02 14:15:24 +02:00
DJj123dj 8aee358081 last push 2022-08-01 18:23:01 +02:00
DJj123dj e2f237e7b6 api events ready, now only the actions 2022-08-01 18:00:54 +02:00
DJj123dj 210923d29e v2.4.0 push 5 (almost the last one) 2022-07-29 19:41:25 +02:00
DJj123dj a69f2ee5a1 v2.4.0 push 4 2022-07-29 18:17:26 +02:00
DJj123dj ffa075d177 v2.4.0 push 3 2022-07-26 16:33:56 +02:00
DJj123dj e7a331b969 v2.4.0 push 2 (first working api) 2022-07-26 14:51:51 +02:00
DJj123dj 6b32fc9d5d v2.4.0 push 1 2022-07-26 12:25:33 +02:00
Jasper 7603dbcc47 Merge pull request #23 from DJj123dj/dev
fixed ANOTHER bug
2022-07-25 21:01:58 +02:00
DJj123dj 512e564c60 fixed ANOTHER bug 2022-07-25 21:01:36 +02:00
Jasper 5a731e6336 Merge pull request #22 from DJj123dj/dev
small bug fix
2022-07-25 20:54:50 +02:00
DJj123dj d02bf2b826 small bug fix 2022-07-25 20:54:21 +02:00
Jasper 2603a7bdd0 Merge pull request #21 from DJj123dj/dev
v2.3.3
2022-07-25 20:10:15 +02:00
DJj123dj c1ba677b82 v2.3.3 2022-07-25 20:09:52 +02:00
Jasper 7e6ac6a4b9 Merge pull request #20 from DJj123dj/dev
v2.3.2
2022-07-23 14:41:27 +02:00
DJj123dj 0ee9a312eb v2.3.2 2022-07-23 14:39:55 +02:00
Jasper d282a516e6 Merge pull request #19 from DJj123dj/dev
v2.3.1
2022-07-21 11:57:04 +02:00
DJj123dj 9638179d45 v2.3.1 push 1 2022-07-21 10:32:36 +02:00
Jasper 30d45ddc39 Merge pull request #18 from DJj123dj/dev
little change i forgot
2022-07-19 16:44:23 +02:00
DJj123dj 2c08ca7245 little change i forgot 2022-07-19 16:43:44 +02:00
Jasper 3d5b1f6e8d Merge pull request #17 from DJj123dj/dev
Update 2.3.0
2022-07-19 16:41:42 +02:00
DJj123dj edc8d4bc44 almost ready for discord.js 14! 2022-07-19 16:40:18 +02:00
DJj123dj c57507cea9 open ticket v2.3 push 1 (doesn't work yet) 2022-07-19 11:57:14 +02:00
Jasper ace46deb52 Merge pull request #16 from DJj123dj/dev
2.2.0 update
2022-07-18 09:37:22 +02:00
DJj123dj fc09858f92 2.2.0 update
bug fixes & 2 new languages
2022-07-18 09:14:25 +02:00
Jasper 1b7767641e Merge pull request #14 from DJj123dj/dev
important bug fix update v2.1.2
2022-07-01 08:20:20 +02:00
DJj123dj 76d491d27c important bug fix update v2.1.2 2022-07-01 08:19:35 +02:00
44 changed files with 1915 additions and 628 deletions
+42 -20
View File
@@ -1,52 +1,74 @@
### large announcement: ## We need translators!
[![open moderation](./openmod.png)](https://www.dj-dj.be/projects/open-moderation) If you know a language that isn't already in open ticket and you can write json,
then is this the job for you!
make a ticket in our server to start!
*if you translate, you will come in the credits*
# open-ticket # open-ticket
[![discord](https://img.shields.io/badge/discord-join%20our%20server-5865F2.svg?style=flat-square&logo=discord)](https://discord.com/invite/26vT9wt3n3) [![version](https://img.shields.io/badge/version-2.1.1%20stable-brightgreen.svg?style=flat-square)](https://github.com/DJj123dj/open-ticket/releases/tag/v2.1.1) [![npm](https://img.shields.io/badge/npm-external%20libraries%20needed-CB3837.svg?style=flat-square&logo=npm)](#packages) [![license](https://img.shields.io/badge/license-GPL%203.0-important.svg?style=flat-square)](https://github.com/DJj123dj/open-ticket/blob/main/LICENSE) [![discord](https://img.shields.io/badge/discord-join%20our%20server-5865F2.svg?style=flat-square&logo=discord)](https://discord.com/invite/26vT9wt3n3) [![version](https://img.shields.io/badge/version-2.4.0%20stable-brightgreen.svg?style=flat-square)](https://github.com/DJj123dj/open-ticket/releases/tag/v2.4.0) [![npm](https://img.shields.io/badge/npm-external%20libraries%20needed-CB3837.svg?style=flat-square&logo=npm)](#packages) [![license](https://img.shields.io/badge/license-GPL%203.0-important.svg?style=flat-square)](https://github.com/DJj123dj/open-ticket/blob/main/LICENSE)
This is an open-source discord ticket bot, you can configure it and it comes with cool features like transcripts & custom options! This is an open-source discord ticket bot, you can configure it and it comes with cool features like transcripts & custom options!
<img src="logo.png" alt="Open Ticket logo" style="height: 200px; width:200px;"/> <img src="logo.png" alt="Open Ticket logo" style="height: 200px; width:200px;"/>
[![q&a](https://img.shields.io/badge/Q&A-click%20here-blue.svg?style=flat-square)](https://www.github.com/DJj123dj/open-ticket/wiki/q&a) [![wiki](https://img.shields.io/badge/documentation-click%20here-blue.svg?style=flat-square)](https://www.github.com/DJj123dj/open-ticket/wiki)
### Thanks to these people:
- DJ-Lite: for doing the administration
- Sanke: for translation & new ideas
- Everyone that reported a bug
#### And our translators!
- ExothDE: for translation
- 1x1: for translation
- R0JO: for translation
- t0miiis for translation
## features ## features
- discord buttons - discord interaction buttons
- slash & text commands - slash & text commands
- close, delete & re-open tickets - close, delete & re-open tickets
- translation (we are searching for translators!) - translation in 8 different languages
- dynamic database system - dynamic database system
- advanced transcripts - transcripts
- add/remove users from a ticket - add/remove users from a ticket
- large embed customisation - custom colors & name for embeds
- create custom ticket names, icons & colors - customise your ticket
- create url's & reaction roles! - create url buttons for websites
- uses discord.js v13 - create reaction roles
- configure your own ticket options - build with discord.js v14
- remove credits if you want (don't do it please 😉) - configure everything per ticket
- unlimited tickets at the same time - remove credits if you want :(
- unlimited tickets spread over multiple messages
*comming soon:*
- dashboard
- view transcripts in dashboard
- share transcripts
- close with reason
- more translation
## installation ## installation
**You need `node.js 16` to run this project!** **You need `node.js 16` to run this project!**
You can clone or download this project.
### packages ### packages
- chalk => version `latest` - chalk => version `latest`
- discord.js => version `latest` - discord.js => version `latest`
- express => version `latest` - express => version `latest`
- node-localstorage => version `latest` - node-localstorage => version `latest`
- axios => version `latest`
You can install all of them by running `npm install` You can install all of them by running `npm install`
## running ## running
you can run `node index.js` but i would recommend you to use `npm start` you can run `node index.js` but i would recommend you to use `npm start`
if there are any errors, you can open an **issue on github** or **contact me in the discord server**. if there are any errors, you can open an **issue on github** or **contact me in our discord server**.
### config ### config
Our config documentation is moved to another file: Our config documentation is moved to another file:
[click here to view](https://www.github.com/DJj123dj/open-ticket/wiki/config-v2.1.1) [click here to view](https://www.github.com/DJj123dj/open-ticket/wiki/config-v2.4.0)
### intents & permissions ### intents & permissions
In the discord developer portal in the "bot" panel you will find 3 switches under the title "Gateaway Intents". The following switches should always be turned on In the discord developer portal in the "bot" panel you will find 3 switches under the title "Gateaway Intents". The following switches should always be turned on
@@ -58,8 +80,8 @@ You can also configure your own permissions
## information ## information
_v2.1.1 stable_ _v2.4.0 stable_
changelog: [click here](https://www.github.com/DJj123dj/open-ticket/wiki/Changelog) changelog: [click here](https://www.github.com/DJj123dj/open-ticket/wiki/Changelog)
© 2022 - DJdj Development | [website](https://www.dj-dj.be) | [discord](https://discord.com/invite/26vT9wt3n3) © 2022 - DJdj Development | [website](https://www.dj-dj.be) | [discord](https://discord.dj-dj.be) | [terms of service](https://www.dj-dj.be/terms)
+26 -8
View File
@@ -4,6 +4,9 @@ const client = bot.client
const config = bot.config const config = bot.config
const log = bot.errorLog.log const log = bot.errorLog.log
const l = bot.language const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events")
module.exports = () => { module.exports = () => {
client.on("messageCreate",msg => { client.on("messageCreate",msg => {
@@ -11,8 +14,10 @@ module.exports = () => {
var user = msg.mentions.users.first() var user = msg.mentions.users.first()
if (!user) return msg.channel.send({embeds:[bot.errorLog.invalidArgsMessage(l.errors.missingArgsDescription+" `<user>`:\n`"+config.prefix+"add <user>`")]}) if (!user) return msg.channel.send({embeds:[bot.errorLog.invalidArgsMessage(l.errors.missingArgsDescription+" `<user>`:\n`"+config.prefix+"add <user>`")]})
if (!msg.member.permissions.has("MANAGE_CHANNELS") && !msg.member.permissions.has("ADMINISTRATOR") && config.main_adminroles.some((item)=>{return msg.member.roles.cache.has(item)}) == false){ if (!msg.guild) return
return msg.channel.send({embeds:[bot.errorLog.noPermsMessage]}) if (!permsChecker.command(msg.author.id,msg.guild.id)){
permsChecker.sendUserNoPerms(msg.author)
return
} }
msg.channel.messages.fetchPinned().then(msglist => { msg.channel.messages.fetchPinned().then(msglist => {
@@ -26,21 +31,28 @@ module.exports = () => {
var loguser = msg.mentions.users.first() var loguser = msg.mentions.users.first()
log("command","someone used the 'add' command",[{key:"user",value:msg.author.tag}]) log("command","someone used the 'add' command",[{key:"user",value:msg.author.tag}])
log("system","user added to ticket",[{key:"user",value:msg.author.tag},{key:"ticket",value:msg.channel.name},{key:"added_user",value:loguser.tag}]) log("system","user added to ticket",[{key:"user",value:msg.author.tag},{key:"ticket",value:msg.channel.name},{key:"added_user",value:loguser.tag}])
const ticketId = firstmsg.embeds[0].footer.text.split("Ticket Type: ")[1]
const ticketData = require("../core/getoptions").getOptionsById("newT"+ticketId)
APIEvents.onTicketAdd(msg.author,loguser,msg.channel,msg.guild,new Date(),{status:"open",name:msg.channel.name,ticketOptions:ticketData})
APIEvents.onCommand("add",permsChecker.command(msg.author.id,msg.guild.id),msg.author,msg.channel,msg.guild,new Date())
}) })
}) })
client.on("interactionCreate",(interaction) => { client.on("interactionCreate",(interaction) => {
if (!interaction.isCommand()) return if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "add") return if (interaction.commandName != "add") return
const user = interaction.options.getUser("user") const user = interaction.options.getUser("user")
const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id) if (!interaction.guild) return
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("ADMINISTRATOR") && !permsmember.permissions.has("MANAGE_GUILD")){ if (!permsChecker.command(interaction.user.id,interaction.guild.id)){
interaction.reply({embeds:[bot.errorLog.noPermsMessage],ephemeral:true}) permsChecker.sendUserNoPerms(interaction.user)
return return
} }
interaction.deferReply()
interaction.channel.messages.fetchPinned().then(msglist => { interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last() var firstmsg = msglist.last()
@@ -53,6 +65,12 @@ module.exports = () => {
var loguser = user var loguser = user
log("command","someone used the 'add' command",[{key:"user",value:interaction.user.tag}]) log("command","someone used the 'add' command",[{key:"user",value:interaction.user.tag}])
log("system","user added to ticket",[{key:"user",value:interaction.user.tag},{key:"ticket",value:interaction.channel.name},{key:"added_user",value:loguser.tag}]) log("system","user added to ticket",[{key:"user",value:interaction.user.tag},{key:"ticket",value:interaction.channel.name},{key:"added_user",value:loguser.tag}])
const ticketId = firstmsg.embeds[0].footer.text.split("Ticket Type: ")[1]
const ticketData = require("../core/getoptions").getOptionsById("newT"+ticketId)
APIEvents.onTicketAdd(interaction.user,loguser,interaction.channel,interaction.guild,new Date(),{status:"open",name:interaction.channel.name,ticketOptions:ticketData})
APIEvents.onCommand("add",permsChecker.command(interaction.user.id,interaction.guild.id),interaction.user,interaction.channel,interaction.guild,new Date())
}) })
+14 -7
View File
@@ -4,6 +4,9 @@ const client = bot.client
const config = bot.config const config = bot.config
const log = bot.errorLog.log const log = bot.errorLog.log
const l = bot.language const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events")
module.exports = () => { module.exports = () => {
client.on("messageCreate",msg => { client.on("messageCreate",msg => {
@@ -15,18 +18,19 @@ module.exports = () => {
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]}) if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const closebutton = new discord.MessageActionRow() const closebutton = new discord.ActionRowBuilder()
.addComponents([ .addComponents([
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("closeTicketTrue1") .setCustomId("closeTicketTrue1")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setEmoji("🔒") .setEmoji("🔒")
]) ])
msg.channel.send({embeds:[bot.errorLog.success(l.commands.closeTitle,l.commands.closeDescription)],components:[closebutton]}) msg.channel.send({embeds:[bot.errorLog.success(l.commands.closeTitle,l.commands.closeDescription)],components:[closebutton]})
log("command","someone used the 'close' command",[{key:"user",value:msg.author.tag}]) log("command","someone used the 'close' command",[{key:"user",value:msg.author.tag}])
APIEvents.onCommand("close",true,msg.author,msg.channel,msg.guild,new Date())
}) })
@@ -34,26 +38,29 @@ module.exports = () => {
}) })
client.on("interactionCreate",(interaction) => { client.on("interactionCreate",(interaction) => {
if (!interaction.isCommand()) return if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "close") return if (interaction.commandName != "close") return
interaction.deferReply()
interaction.channel.messages.fetchPinned().then(msglist => { interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last() var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]}) if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const closebutton = new discord.MessageActionRow() const closebutton = new discord.ActionRowBuilder()
.addComponents([ .addComponents([
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("closeTicketTrue1") .setCustomId("closeTicketTrue1")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setEmoji("🔒") .setEmoji("🔒")
]) ])
interaction.reply({embeds:[bot.errorLog.success(l.commands.closeTitle,l.commands.closeDescription)],components:[closebutton]}) interaction.reply({embeds:[bot.errorLog.success(l.commands.closeTitle,l.commands.closeDescription)],components:[closebutton]})
log("command","someone used the 'close' command",[{key:"user",value:interaction.user.tag}]) log("command","someone used the 'close' command",[{key:"user",value:interaction.user.tag}])
APIEvents.onCommand("close",true,interaction.user,interaction.channel,interaction.guild,new Date())
}) })
}) })
+23 -15
View File
@@ -4,13 +4,18 @@ const client = bot.client
const config = bot.config const config = bot.config
const log = bot.errorLog.log const log = bot.errorLog.log
const l = bot.language const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events")
module.exports = () => { module.exports = () => {
client.on("messageCreate",msg => { client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix+"delete")) return if (!msg.content.startsWith(config.prefix+"delete")) return
if (!msg.member.permissions.has("MANAGE_CHANNELS") && !msg.member.permissions.has("ADMINISTRATOR") && config.main_adminroles.some((item)=>{return msg.member.roles.cache.has(item)}) == false){ if (!msg.guild) return
return msg.channel.send({embeds:[bot.errorLog.noPermsMessage]}) if (!permsChecker.command(msg.author.id,msg.guild.id)){
permsChecker.sendUserNoPerms(msg.author)
return
} }
msg.channel.messages.fetchPinned().then(msglist => { msg.channel.messages.fetchPinned().then(msglist => {
@@ -18,51 +23,54 @@ module.exports = () => {
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]}) if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const closebutton = new discord.MessageActionRow() const closebutton = new discord.ActionRowBuilder()
.addComponents([ .addComponents([
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("deleteTicketTrue") .setCustomId("deleteTicketTrue")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setEmoji("❌") .setEmoji("❌")
]) ])
msg.channel.send({embeds:[bot.errorLog.success(l.commands.deleteTitle,l.commands.deleteDescription)],components:[closebutton]}) msg.channel.send({embeds:[bot.errorLog.success(l.commands.deleteTitle,l.commands.deleteDescription)],components:[closebutton]})
log("command","someone used the 'delete' command",[{key:"user",value:msg.author.tag}]) log("command","someone used the 'delete' command",[{key:"user",value:msg.author.tag}])
APIEvents.onCommand("delete",permsChecker.command(msg.author.id,msg.guild.id),msg.author,msg.channel,msg.guild,new Date())
}) })
}) })
client.on("interactionCreate",(interaction) => { client.on("interactionCreate",(interaction) => {
if (!interaction.isCommand()) return if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "delete") return if (interaction.commandName != "delete") return
const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id) interaction.deferReply()
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("ADMINISTRATOR") && !permsmember.permissions.has("MANAGE_GUILD")){
interaction.reply({embeds:[bot.errorLog.noPermsMessage],ephemeral:true}) if (!interaction.guild) return
return if (!permsChecker.command(interaction.user.id,interaction.guild.id)){
} permsChecker.sendUserNoPerms(interaction.user)
return
}
interaction.channel.messages.fetchPinned().then(msglist => { interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last() var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]}) if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const closebutton = new discord.MessageActionRow() const closebutton = new discord.ActionRowBuilder()
.addComponents([ .addComponents([
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("deleteTicketTrue") .setCustomId("deleteTicketTrue")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setEmoji("❌") .setEmoji("❌")
]) ])
interaction.reply({embeds:[bot.errorLog.success(l.commands.deleteTitle,l.commands.deleteDescription)],components:[closebutton]}) interaction.reply({embeds:[bot.errorLog.success(l.commands.deleteTitle,l.commands.deleteDescription)],components:[closebutton]})
log("command","someone used the 'close' command",[{key:"user",value:interaction.user.tag}]) log("command","someone used the 'close' command",[{key:"user",value:interaction.user.tag}])
APIEvents.onCommand("delete",permsChecker.command(interaction.user.id,interaction.guild.id),interaction.user,interaction.channel,interaction.guild,new Date())
}) })
}) })
+13 -2
View File
@@ -5,8 +5,10 @@ const config = bot.config
const log = bot.errorLog.log const log = bot.errorLog.log
const l = bot.language const l = bot.language
const APIEvents = require("../core/api/modules/events")
module.exports = () => { module.exports = () => {
const helpEmbed = new discord.MessageEmbed() const helpEmbed = new discord.EmbedBuilder()
.setColor(config.main_color) .setColor(config.main_color)
.setTitle(l.helpMenu.title) .setTitle(l.helpMenu.title)
@@ -20,19 +22,28 @@ module.exports = () => {
client.on("messageCreate",msg => { client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix)) return if (!msg.content.startsWith(config.prefix)) return
var args = msg.content.split(config.prefix) var args = msg.content.split(config.prefix)
if (!args[1]){
msg.channel.send({embeds:[helpEmbed]})
log("command","someone used the 'help' command",[{key:"user",value:msg.author.tag}])
APIEvents.onCommand("help",true,msg.author,msg.channel,msg.guild,new Date())
return
}
if (!args[1].startsWith("close") && !args[1].startsWith("delete") && !args[1].startsWith("remove") && !args[1].startsWith("add") && !args[1].startsWith("msg") && !args[1].startsWith("remove") && !args[1].startsWith("rename") && !args[1].startsWith("reopen")){ if (!args[1].startsWith("close") && !args[1].startsWith("delete") && !args[1].startsWith("remove") && !args[1].startsWith("add") && !args[1].startsWith("msg") && !args[1].startsWith("remove") && !args[1].startsWith("rename") && !args[1].startsWith("reopen")){
msg.channel.send({embeds:[helpEmbed]}) msg.channel.send({embeds:[helpEmbed]})
log("command","someone used the 'help' command",[{key:"user",value:msg.author.tag}]) log("command","someone used the 'help' command",[{key:"user",value:msg.author.tag}])
APIEvents.onCommand("help",true,msg.author,msg.channel,msg.guild,new Date())
} }
}) })
client.on("interactionCreate",(interaction) => { client.on("interactionCreate",(interaction) => {
if (!interaction.isCommand()) return if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "help") return if (interaction.commandName != "help") return
interaction.reply({embeds:[helpEmbed]}) interaction.reply({embeds:[helpEmbed]})
log("command","someone used the 'help' command",[{key:"user",value:interaction.user.tag}]) log("command","someone used the 'help' command",[{key:"user",value:interaction.user.tag}])
APIEvents.onCommand("help",true,interaction.user,interaction.channel,interaction.guild,new Date())
}) })
} }
+25 -8
View File
@@ -4,6 +4,9 @@ const client = bot.client
const config = bot.config const config = bot.config
const log = bot.errorLog.log const log = bot.errorLog.log
const l = bot.language const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events")
module.exports = () => { module.exports = () => {
client.on("messageCreate",msg => { client.on("messageCreate",msg => {
@@ -11,10 +14,14 @@ module.exports = () => {
var user = msg.mentions.users.first() var user = msg.mentions.users.first()
if (!user) return msg.channel.send({embeds:[bot.errorLog.invalidArgsMessage(l.errors.missingArgsDescription+" `<user>`:\n`"+config.prefix+"remove <user>`")]}) if (!user) return msg.channel.send({embeds:[bot.errorLog.invalidArgsMessage(l.errors.missingArgsDescription+" `<user>`:\n`"+config.prefix+"remove <user>`")]})
if (!msg.member.permissions.has("MANAGE_CHANNELS") && !msg.member.permissions.has("ADMINISTRATOR") && config.main_adminroles.some((item)=>{return msg.member.roles.cache.has(item)}) == false){ if (!msg.guild) return
return msg.channel.send({embeds:[bot.errorLog.noPermsMessage]}) if (!permsChecker.command(msg.author.id,msg.guild.id)){
permsChecker.sendUserNoPerms(msg.author)
return
} }
interaction.deferReply()
msg.channel.messages.fetchPinned().then(msglist => { msg.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last() var firstmsg = msglist.last()
@@ -27,20 +34,25 @@ module.exports = () => {
log("command","someone used the 'remove' command",[{key:"user",value:msg.author.tag}]) log("command","someone used the 'remove' command",[{key:"user",value:msg.author.tag}])
log("system","user removed from ticket",[{key:"user",value:msg.author.tag},{key:"ticket",value:msg.channel.name},{key:"removed_user",value:loguser.tag}]) log("system","user removed from ticket",[{key:"user",value:msg.author.tag},{key:"ticket",value:msg.channel.name},{key:"removed_user",value:loguser.tag}])
const ticketId = firstmsg.embeds[0].footer.text.split("Ticket Type: ")[1]
const ticketData = require("../core/getoptions").getOptionsById("newT"+ticketId)
APIEvents.onTicketRemove(msg.author,loguser,msg.channel,msg.guild,new Date(),{status:"open",name:msg.channel.name,ticketOptions:ticketData})
APIEvents.onCommand("remove",permsChecker.command(msg.author.id,msg.guild.id),msg.author,msg.channel,msg.guild,new Date())
}) })
}) })
client.on("interactionCreate",(interaction) => { client.on("interactionCreate",(interaction) => {
if (!interaction.isCommand()) return if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "remove") return if (interaction.commandName != "remove") return
const user = interaction.options.getUser("user") const user = interaction.options.getUser("user")
const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id) if (!interaction.guild) return
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("ADMINISTRATOR") && !permsmember.permissions.has("MANAGE_GUILD")){ if (!permsChecker.command(interaction.user.id,interaction.guild.id)){
interaction.reply({embeds:[bot.errorLog.noPermsMessage],ephemeral:true}) permsChecker.sendUserNoPerms(interaction.user)
return return
} }
@@ -56,6 +68,11 @@ module.exports = () => {
log("command","someone used the 'remove' command",[{key:"user",value:interaction.user.tag}]) log("command","someone used the 'remove' command",[{key:"user",value:interaction.user.tag}])
log("system","user removed from ticket",[{key:"user",value:interaction.user.tag},{key:"ticket",value:interaction.channel.name},{key:"removed_user",value:loguser.tag}]) log("system","user removed from ticket",[{key:"user",value:interaction.user.tag},{key:"ticket",value:interaction.channel.name},{key:"removed_user",value:loguser.tag}])
const ticketId = firstmsg.embeds[0].footer.text.split("Ticket Type: ")[1]
const ticketData = require("../core/getoptions").getOptionsById("newT"+ticketId)
APIEvents.onTicketRemove(interaction.user,loguser,interaction.channel,interaction.guild,new Date(),{status:"open",name:interaction.channel.name,ticketOptions:ticketData})
APIEvents.onCommand("remove",permsChecker.command(interaction.user.id,interaction.guild.id),interaction.user,interaction.channel,interaction.guild,new Date())
}) })
+16 -8
View File
@@ -4,6 +4,9 @@ const client = bot.client
const config = bot.config const config = bot.config
const log = bot.errorLog.log const log = bot.errorLog.log
const l = bot.language const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events")
module.exports = () => { module.exports = () => {
client.on("messageCreate",msg => { client.on("messageCreate",msg => {
@@ -14,8 +17,10 @@ module.exports = () => {
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]}) if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
if (!msg.member.permissions.has("MANAGE_CHANNELS") && !msg.member.permissions.has("ADMINISTRATOR") && config.main_adminroles.some((item)=>{return msg.member.roles.cache.has(item)}) == false){ if (!msg.guild) return
return msg.channel.send({embeds:[bot.errorLog.noPermsMessage]}) if (!permsChecker.command(msg.author.id,msg.guild.id)){
permsChecker.sendUserNoPerms(msg.author)
return
} }
var newname = msg.content.split(config.prefix+"rename")[1].substring(1) var newname = msg.content.split(config.prefix+"rename")[1].substring(1)
@@ -38,24 +43,26 @@ module.exports = () => {
log("command","someone used the 'rename' command",[{key:"user",value:msg.author.tag}]) log("command","someone used the 'rename' command",[{key:"user",value:msg.author.tag}])
log("system","ticket renamed",[{key:"user",value:msg.author.tag},{key:"ticket",value:name},{key:"newname",value:newname}]) log("system","ticket renamed",[{key:"user",value:msg.author.tag},{key:"ticket",value:name},{key:"newname",value:newname}])
APIEvents.onCommand("rename",permsChecker.command(msg.author.id,msg.guild.id),msg.author,msg.channel,msg.guild,new Date())
}) })
}) })
client.on("interactionCreate",(interaction) => { client.on("interactionCreate",(interaction) => {
if (!interaction.isCommand()) return if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "rename") return if (interaction.commandName != "rename") return
interaction.deferReply()
interaction.channel.messages.fetchPinned().then(msglist => { interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last() var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id)return interaction.reply({embeds:[bot.errorLog.notInATicket]}) if (firstmsg == undefined || firstmsg.author.id != client.user.id)return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id) if (!interaction.guild) return
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("ADMINISTRATOR") && !permsmember.permissions.has("MANAGE_GUILD")){ if (!permsChecker.command(interaction.user.id,interaction.guild.id)){
interaction.reply({embeds:[bot.errorLog.noPermsMessage],ephemeral:true}) permsChecker.sendUserNoPerms(interaction.user)
return return
} }
@@ -76,7 +83,8 @@ module.exports = () => {
log("command","someone used the 'rename' command",[{key:"user",value:interaction.user.tag}]) log("command","someone used the 'rename' command",[{key:"user",value:interaction.user.tag}])
log("system","ticket renamed",[{key:"user",value:interaction.user.tag},{key:"ticket",value:name},{key:"newname",value:newname}]) log("system","ticket renamed",[{key:"user",value:interaction.user.tag},{key:"ticket",value:name},{key:"newname",value:newname}])
APIEvents.onCommand("rename",permsChecker.command(interaction.user.id,interaction.guild.id),interaction.user,interaction.channel,interaction.guild,new Date())
}) })
}) })
} }
+18 -7
View File
@@ -4,14 +4,17 @@ const client = bot.client
const config = bot.config const config = bot.config
const log = bot.errorLog.log const log = bot.errorLog.log
const l = bot.language const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events")
module.exports = () => { module.exports = () => {
var reopenCommandBar = new discord.MessageActionRow() var reopenCommandBar = new discord.ActionRowBuilder()
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("reopenTicket1") .setCustomId("reopenTicket1")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setEmoji("🔓") .setEmoji("🔓")
) )
@@ -27,23 +30,31 @@ module.exports = () => {
log("command","someone used the 'reopen' command",[{key:"user",value:msg.author.tag}]) log("command","someone used the 'reopen' command",[{key:"user",value:msg.author.tag}])
APIEvents.onCommand("reopen",true,msg.author,msg.channel,msg.guild,new Date())
}) })
}) })
client.on("interactionCreate",(interaction) => { client.on("interactionCreate",async (interaction) => {
if (!interaction.isCommand()) return if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "reopen") return if (interaction.commandName != "reopen") return
interaction.channel.messages.fetchPinned().then(msglist => { await interaction.deferReply()
interaction.channel.messages.fetchPinned().then(async msglist => {
var firstmsg = msglist.last() var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]}) if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
interaction.reply({embeds:[bot.errorLog.success(l.commands.reopenTitle,l.commands.reopenDescription)],components:[reopenCommandBar]}) try {
await interaction.reply({embeds:[bot.errorLog.success(l.commands.reopenTitle,l.commands.reopenDescription)],components:[reopenCommandBar]})
}catch{
await interaction.editReply({embeds:[bot.errorLog.success(l.commands.reopenTitle,l.commands.reopenDescription)],components:[reopenCommandBar]})
}
log("command","someone used the 'reopen' command",[{key:"user",value:interaction.user.tag}]) log("command","someone used the 'reopen' command",[{key:"user",value:interaction.user.tag}])
APIEvents.onCommand("reopen",true,interaction.user,interaction.channel,interaction.guild,new Date())
}) })
+18 -10
View File
@@ -4,6 +4,9 @@ const client = bot.client
const config = bot.config const config = bot.config
const log = bot.errorLog.log const log = bot.errorLog.log
const l = bot.language const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events")
module.exports = () => { module.exports = () => {
/**@type {String[]} */ /**@type {String[]} */
@@ -16,8 +19,10 @@ module.exports = () => {
client.on("messageCreate", msg => { client.on("messageCreate", msg => {
if (msg.content.startsWith(config.prefix+"msg"||config.prefix+"message")){ if (msg.content.startsWith(config.prefix+"msg"||config.prefix+"message")){
if (!msg.member.permissions.has("MANAGE_CHANNELS") && !msg.member.permissions.has("ADMINISTRATOR") && config.main_adminroles.some((item)=>{return msg.member.roles.cache.has(item)}) == false){ if (!msg.guild) return
return msg.channel.send({embeds:[bot.errorLog.noPermsMessage]}) if (!permsChecker.command(msg.author.id,msg.guild.id)){
permsChecker.sendUserNoPerms(msg.author)
return
} }
const id = msg.content.split(config.prefix+"msg")[1].substring(1) ? msg.content.split(config.prefix+"msg")[1].substring(1) : false const id = msg.content.split(config.prefix+"msg")[1].substring(1) ? msg.content.split(config.prefix+"msg")[1].substring(1) : false
@@ -30,19 +35,20 @@ module.exports = () => {
msg.channel.send({embeds:[embed],components:componentRows}) msg.channel.send({embeds:[embed],components:componentRows})
log("command","someone used the 'msg' command",[{key:"user",value:msg.author.tag},{key:"id",value:id}]) log("command","someone used the 'message' command",[{key:"user",value:msg.author.tag},{key:"id",value:id}])
APIEvents.onCommand("message",permsChecker.command(msg.author.id,msg.guild.id),msg.author,msg.channel,msg.guild,new Date())
} }
}) })
client.on("interactionCreate", (interaction) => { client.on("interactionCreate", (interaction) => {
if (!interaction.isCommand()) return if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "message") return if (interaction.commandName != "message") return
const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id) if (!interaction.guild) return
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("ADMINISTRATOR") && !permsmember.permissions.has("MANAGE_GUILD")){ if (!permsChecker.command(interaction.user.id,interaction.guild.id)){
interaction.reply({embeds:[bot.errorLog.noPermsMessage],ephemeral:true}) permsChecker.sendUserNoPerms(interaction.user)
return return
} }
const id = interaction.options.getString("id") const id = interaction.options.getString("id")
@@ -53,7 +59,9 @@ module.exports = () => {
interaction.reply({content:l.commands.ticketWarning}) interaction.reply({content:l.commands.ticketWarning})
interaction.channel.send({embeds:[embed],components:componentRows}) interaction.channel.send({embeds:[embed],components:componentRows})
log("command","someone used the 'msg' command",[{key:"user",value:interaction.user.tag},{key:"id",value:id}]) log("command","someone used the 'message' command",[{key:"user",value:interaction.user.tag},{key:"id",value:id}])
APIEvents.onCommand("message",permsChecker.command(interaction.user.id,interaction.guild.id),interaction.user,interaction.channel,interaction.guild,new Date())
}) })
} }
+9 -5
View File
@@ -1,5 +1,4 @@
{ {
"bot_name":"Wumpus",
"main_color":"#ffffff", "main_color":"#ffffff",
"server_id":"server id (for slash cmds)", "server_id":"server id (for slash cmds)",
"auth_token":"auth token", "auth_token":"auth token",
@@ -11,7 +10,7 @@
"status":{ "status":{
"enabled":true, "enabled":true,
"type":"PLAYING", "type":"PLAYING",
"text":"!ticket" "text":"!ticket help"
}, },
"system":{ "system":{
@@ -77,12 +76,17 @@
{ {
"id":"1", "id":"1",
"name":"Choose Your Ticket", "name":"Choose Your Ticket",
"description":"You can click one of the buttons below!\nYou can also customize all the embeds now!", "description":"You can click one of the buttons below!",
"enableFooter":true,
"footer":"Open Ticket v2.1.1 - I'm a footer!", "enableFooter":false,
"footer":"Open Ticket v2.4.0 - I'm a footer!",
"enableThumbnail":false, "enableThumbnail":false,
"thumbnail":"https://www.example.com/catmemes/cat.png", "thumbnail":"https://www.example.com/catmemes/cat.png",
"enableCustomColor":false,
"color":"#ffffff", "color":"#ffffff",
"options":["general","apply"], "options":["general","apply"],
"enableTicketExplaination":true, "enableTicketExplaination":true,
"enableMaxTicketsWarning":true "enableMaxTicketsWarning":true
+18
View File
@@ -0,0 +1,18 @@
//base
const bot = require("../../index")
exports.client = bot.client
exports.config = bot.config
exports.utils = {
log:bot.errorLog.log(),
storage:bot.storage
}
//events
const events = require("./modules/events").events
exports.events = events
//actions
const actions = require("./modules/actions").actions
//comming soon
//exports.actions = actions
+46
View File
@@ -0,0 +1,46 @@
{
"version":"1.0.0",
"disclaimer":"DISABLE doesn't work yet! Below this message!",
"disable":{
"messages":{
"ticketCreated":false,
"ticketClosed":false,
"ticketDeleted":false,
"ticketReopened":false
},
"transcripts":{
"server":false,
"dm":false
},
"commands":{
"text":{
"help":false,
"msg":false,
"close":false,
"delete":false,
"reopen":false,
"new":false,
"add":false,
"remove":false,
"rename":false
},
"slash":{
"help":false,
"msg":false,
"close":false,
"delete":false,
"reopen":false,
"new":false,
"add":false,
"remove":false,
"rename":false
}
},
"checkerjs":{
"token":false,
"all":false
}
}
}
+7
View File
@@ -0,0 +1,7 @@
//ACTIONS:
//EXPORT ACTIONS:
exports.actions = {
}
+28
View File
@@ -0,0 +1,28 @@
const discord = require('discord.js')
const bot = require("../../../index")
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const l = bot.language
const storage = bot.storage
/** FOR DEVELOPERS ONLY!!
* Don't change anything in this file, read the api documentation first!
* look into "api docs.md" for the docs!
*/
//used when creating plugins!
exports.enableApiLogs = false
//DOESN'T WORK YET
//this is used when embedding open ticket into another bot
exports.embeddedMode = false
exports.clientLocation = require("../../../index").client
/** !! WARNING !!
* Only edit or extend the code when you know what you are doing!
* If open ticket crashes while you change the code, then we can't help you!
*
* DO IT ON YOUR OWN RISK!
*/
+349
View File
@@ -0,0 +1,349 @@
const discord = require('discord.js')
const bot = require('../../../index')
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const l = bot.language
const storage = bot.storage
//EVENT API:
const ticketOpenListeners = []
const ticketCloseListeners = []
const ticketDeleteListeners = []
const ticketReopenListeners = []
const ticketAddListeners = []
const ticketRemoveListeners = []
const transcriptCreationListeners = []
const commandListeners = []
const reactionRoleListeners = []
const errorListeners = []
/**
*
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata
*/
exports.onTicketOpen = (user,channel,guild,date,ticketdata) => {
//system
bot.errorLog.log("api","new ticket created",[{key:"userid",value:user.id},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id},{key:"ticketdata",value:JSON.stringify(ticketdata)}])
ticketOpenListeners.forEach((func) => {
try {
func(user,channel,guild,date,ticketdata)
}catch{}
})
}
/**
*
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata
*/
exports.onTicketClose = (user,channel,guild,date,ticketdata) => {
//system
bot.errorLog.log("api","ticket closed",[{key:"userid",value:user.id},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id},{key:"ticketdata",value:JSON.stringify(ticketdata)}])
ticketCloseListeners.forEach((func) => {
try {
func(user,channel,guild,date,ticketdata)
}catch{}
})
}
/**
*
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata
*/
exports.onTicketDelete = (user,channel,guild,date,ticketdata) => {
//system
bot.errorLog.log("api","ticket deleted",[{key:"userid",value:user.id},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id},{key:"ticketdata",value:JSON.stringify(ticketdata)}])
ticketDeleteListeners.forEach((func) => {
try {
func(user,channel,guild,date,ticketdata)
}catch{}
})
}
/**
*
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata
*/
exports.onTicketReopen = (user,channel,guild,date,ticketdata) => {
//system
bot.errorLog.log("api","ticket reopened",[{key:"userid",value:user.id},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id},{key:"ticketdata",value:JSON.stringify(ticketdata)}])
ticketReopenListeners.forEach((func) => {
try {
func(user,channel,guild,date,ticketdata)
}catch{}
})
}
/**
*
* @param {discord.User} user
* @param {discord.User} editeduser
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata
*/
exports.onTicketAdd = (user,editeduser,channel,guild,date,ticketdata) => {
//system
bot.errorLog.log("api","user added to ticket",[{key:"userid",value:user.id},{key:"editeduser",value:editeduser.id},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id},{key:"ticketdata",value:JSON.stringify(ticketdata)}])
ticketAddListeners.forEach((func) => {
try {
func(user,editeduser,channel,guild,date,ticketdata)
}catch{}
})
}
/**
*
* @param {discord.User} user
* @param {discord.User} editeduser
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata
*/
exports.onTicketRemove = (user,editeduser,channel,guild,date,ticketdata) => {
//system
bot.errorLog.log("api","user removed from ticket",[{key:"userid",value:user.id},{key:"editeduser",value:editeduser.id},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id},{key:"ticketdata",value:JSON.stringify(ticketdata)}])
ticketRemoveListeners.forEach((func) => {
try {
func(user,editeduser,channel,guild,date,ticketdata)
}catch{}
})
}
/**
*
* @param {discord.Message[]} messages
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
*/
exports.onTranscriptCreation = (messages,channel,guild,date) => {
//system
bot.errorLog.log("api","transcript created",[{key:"messages",value:JSON.stringify(messages)},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id}])
transcriptCreationListeners.forEach((func) => {
try {
func(messages,channel,guild,date)
}catch{}
})
}
/**@typedef {"help"|"message"|"close"|"delete"|"reopen"|"rename"|"add"|"remove"} OTCommandType */
/**
*
* @param {OTCommandType} type
* @param {Boolean} hasPerms
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
*/
exports.onCommand = (type,hasPerms,user,channel,guild,date) => {
//system
bot.errorLog.log("api","someone used a command",[{key:"type",value:type},{key:"hasPerms",value:hasPerms},{key:"userid",value:user},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id}])
commandListeners.forEach((func) => {
try {
func(type,hasPerms,user,channel,guild,date)
}catch{}
})
}
/**@typedef {"add"|"remove"|"add&remove"} OTReactionRoleType */
/**@typedef {"add"|"remove"} OTReactionRoleMode */
/**
* @param {OTReactionRoleMode} mode
* @param {OTReactionRoleType} type
* @param {discord.Role} role
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
*/
exports.onReactionRole = (mode,type,role,user,channel,guild,date) => {
//system
bot.errorLog.log("api","someone used a reaction role",[{key:"mode",value:mode},{key:"type",value:type},{key:"roleid",value:role.id},{key:"userid",value:user},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id}])
reactionRoleListeners.forEach((func) => {
try {
func(mode,type,role,user,channel,guild,date)
}catch{}
})
}
/**
* @param {String} err
* @param {Date} date
*/
exports.onError = (err,date) => {
//system
bot.errorLog.log("api","there is an error",[{key:"error",value:err}])
errorListeners.forEach((func) => {
try {
func(err,date)
}catch{}
})
}
//EVENT CALLBACKS:
/**
* @callback TicketActionEvent
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata
*/
/**
* @callback TranscriptCreationEvent
* @param {discord.Message[]} messages
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
*/
/**
* @callback TicketUserChangeEvent
* @param {discord.User} user
* @param {discord.User} editeduser
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata
*/
/**
* @callback CommandEvent
* @param {OTCommandType} type
* @param {Boolean} hasPerms
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
*/
/**
* @callback ReactionRoleEvent
* @param {OTReactionRoleMode} mode
* @param {OTReactionRoleType} type
* @param {discord.Role} role
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
*/
/**
* @callback ErrorEvent
* @param {String} error
* @param {Date} date
*/
//EVENT EXPORT:
/**@param {TicketActionEvent} callback */
const onTicketOpen = (callback) => {
ticketOpenListeners.push(callback)
}
/**@param {TicketActionEvent} callback */
const onTicketClose = (callback) => {
ticketCloseListeners.push(callback)
}
/**@param {TicketActionEvent} callback */
const onTicketDelete = (callback) => {
ticketDeleteListeners.push(callback)
}
/**@param {TicketActionEvent} callback */
const onTicketReopen = (callback) => {
ticketReopenListeners.push(callback)
}
/**@param {TicketUserChangeEvent} callback */
const onTicketAdd = (callback) => {
ticketAddListeners.push(callback)
}
/**@param {TicketUserChangeEvent} callback */
const onTicketRemove = (callback) => {
ticketRemoveListeners.push(callback)
}
/**@param {TranscriptCreationEvent} callback */
const onTranscriptCreation = (callback) => {
transcriptCreationListeners.push(callback)
}
/**@param {CommandEvent} callback */
const onCommand = (callback) => {
commandListeners.push(callback)
}
/**@param {ReactionRoleEvent} callback */
const onReactionRole = (callback) => {
commandListeners.push(callback)
}
/**@param {ErrorEvent} callback */
const onError = (callback) => {
errorListeners.push(callback)
}
exports.events = {
onTicketOpen,
onTicketClose,
onTicketDelete,
onTicketReopen,
onTicketAdd,
onTicketRemove,
onTranscriptCreation,
onCommand,
onReactionRole,
onError
}
+26
View File
@@ -0,0 +1,26 @@
const fs = require("fs")
const bot = require("../../index")
const log = bot.errorLog.log
module.exports = () => {
const files = fs.readdirSync("./plugins")
var totalcount = 0
var successcount = 0
var failcount = 0
files.forEach((file) => {
if (file.endsWith(".plugin.js")){
try {
require("../../plugins/"+file)()
successcount++
totalcount++
}catch{
failcount++
totalcount++
}
}
})
log("info","loaded plugins",[{key:"success",value:successcount},{key:"error",value:failcount},{key:"total",value:totalcount}])
}
+31 -16
View File
@@ -25,7 +25,7 @@ exports.checker = async () => {
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){ if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+"' | this channel id is invalid") createError("'"+path+"' | this channel id is invalid")
} }
}else if (mode == "roleid"){ }else if (mode == "roleid"){
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){ if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+"' | this role id is invalid") createError("'"+path+"' | this role id is invalid")
} }
@@ -41,7 +41,7 @@ exports.checker = async () => {
} }
/**@param {String} value */ /**@param {String} value */
const checkToken = (value) => { const checkToken = (value) => {
if (value.includes(" ") || value.length < 40 || value.length > 70){ if (value.includes(" ") || value.length < 40 || value.length > 90){
createError("'auth_token' | your token is invalid") createError("'auth_token' | your token is invalid")
} }
} }
@@ -245,21 +245,14 @@ exports.checker = async () => {
//--------------------------| //--------------------------|
//--------------------------| //--------------------------|
var configArray = ["bot_name","main_color","server_id","auth_token","main_adminroles","prefix","languagefile","credits","status","system","options","messages"] var configArray = ["main_color","server_id","auth_token","main_adminroles","prefix","languagefile","credits","status","system","options","messages"]
configArray.forEach((item) => { configArray.forEach((item) => {
if (config[item] == undefined){ if (config[item] == undefined){
throw new Error("\n\nMAIN ERROR: the item '"+item+"' doesn't exist in config.json") throw new Error("\n\nMAIN ERROR: the item '"+item+"' doesn't exist in config.json")
} }
}) })
checkHexColor(config.main_color,"main_color")
checkType(config.bot_name,"string","bot_name")
if (config.main_color.startsWith("#")){
checkHexColor(config.main_color,"main_color")
}else{
checkEmbedColor(config.main_color,"main_color")
}
checkDiscord("serverid",config.server_id,"server_id") checkDiscord("serverid",config.server_id,"server_id")
checkToken(config.auth_token) checkToken(config.auth_token)
checkDiscordArray("roleid",config.main_adminroles,"main_adminroles") checkDiscordArray("roleid",config.main_adminroles,"main_adminroles")
@@ -267,7 +260,7 @@ exports.checker = async () => {
//languagefile //languagefile
checkType(config.languagefile,"string","languagefile") checkType(config.languagefile,"string","languagefile")
const lf = config.languagefile const lf = config.languagefile
if (!lf.startsWith("custom") && !lf.startsWith("english") && !lf.startsWith("dutch") && !lf.startsWith("romanian")){ if (!lf.startsWith("custom") && !lf.startsWith("english") && !lf.startsWith("dutch") && !lf.startsWith("romanian") && !lf.startsWith("german") && !lf.startsWith("arabic") && !lf.startsWith("spanish")){
createError("'languagefile' | invalid language, more info in the wiki") createError("'languagefile' | invalid language, more info in the wiki")
} }
@@ -296,6 +289,8 @@ exports.checker = async () => {
checkType(config.system["has@everyoneaccess"],"boolean","system/has@everyoneaccess") checkType(config.system["has@everyoneaccess"],"boolean","system/has@everyoneaccess")
if (config.system.member_role != "" && config.system.member_role != " " && config.system.member_role != "false" && config.system.member_role != "null" && config.system.member_role != "0"){ if (config.system.member_role != "" && config.system.member_role != " " && config.system.member_role != "false" && config.system.member_role != "null" && config.system.member_role != "0"){
checkDiscord("roleid",config.system.member_role,"system/member_role") checkDiscord("roleid",config.system.member_role,"system/member_role")
}else{
createWarn("'system/member_role' | You don't have a member role, but it's recommended!")
} }
checkType(config.system.closeMode,"string","system/closeMode") checkType(config.system.closeMode,"string","system/closeMode")
if (!["normal","adminonly"].includes(config.system.closeMode)){ if (!["normal","adminonly"].includes(config.system.closeMode)){
@@ -314,6 +309,28 @@ exports.checker = async () => {
checkOption(option,"options/"+index) checkOption(option,"options/"+index)
}) })
//discord check
/**
const discord = require("discord.js")
const {GatewayIntentBits,Partials} = discord
const client = new discord.Client({
intents:[
GatewayIntentBits.DirectMessages,
GatewayIntentBits.GuildInvites,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.Guilds,
GatewayIntentBits.MessageContent
],
partials:[Partials.Channel,Partials.Message]
})
await client.guilds.fetch()
if (!client.guilds.cache.find(g => g.id == config.server_id)){
createError("'server_id' | i'm not in a server with this id!")
}
*/
//the end //the end
@@ -346,6 +363,4 @@ exports.checker = async () => {
console.log("=> "+chalk.bgYellow("if you ignore warns, some things may work differently than expected!")) console.log("=> "+chalk.bgYellow("if you ignore warns, some things may work differently than expected!"))
} }
} }
this.checker()
+89 -55
View File
@@ -7,109 +7,109 @@ const l = bot.language
module.exports = () => { module.exports = () => {
//closebar //closebar
var closeBar = new discord.MessageActionRow() var closeBar = new discord.ActionRowBuilder()
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("closeTicketTrue") .setCustomId("closeTicketTrue")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setEmoji("✅") .setEmoji("✅")
) )
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("closeTicketFalse") .setCustomId("closeTicketFalse")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setEmoji("❌") .setEmoji("❌")
) )
var deleteBar = new discord.MessageActionRow() var deleteBar = new discord.ActionRowBuilder()
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("deleteTicketTrue") .setCustomId("deleteTicketTrue")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setEmoji("✅") .setEmoji("✅")
) )
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("deleteTicketFalse") .setCustomId("deleteTicketFalse")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setEmoji("❌") .setEmoji("❌")
) )
var deleteBar1 = new discord.MessageActionRow() var deleteBar1 = new discord.ActionRowBuilder()
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("deleteTicketTrue1") .setCustomId("deleteTicketTrue1")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setEmoji("✅") .setEmoji("✅")
) )
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("deleteTicketFalse1") .setCustomId("deleteTicketFalse1")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setEmoji("❌") .setEmoji("❌")
) )
//closebutton //closebutton
var closeRowNormal = new discord.MessageActionRow() var closeRowNormal = new discord.ActionRowBuilder()
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("closeTicket") .setCustomId("closeTicket")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setLabel(l.buttons.close) .setLabel(l.buttons.close)
.setEmoji("🔒") .setEmoji("🔒")
) )
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("deleteTicket") .setCustomId("deleteTicket")
.setDisabled(false) .setDisabled(false)
.setStyle("DANGER") .setStyle(discord.ButtonStyle.Danger)
.setLabel(l.buttons.delete) .setLabel(l.buttons.delete)
.setEmoji("✖️") .setEmoji("✖️")
) )
var closeRowClosed = new discord.MessageActionRow() var closeRowClosed = new discord.ActionRowBuilder()
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("deleteTicket1") .setCustomId("deleteTicket1")
.setDisabled(false) .setDisabled(false)
.setStyle("DANGER") .setStyle(discord.ButtonStyle.Danger)
.setLabel(l.buttons.delete) .setLabel(l.buttons.delete)
.setEmoji("✖️") .setEmoji("✖️")
) )
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("sendTranscript") .setCustomId("sendTranscript")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setLabel(l.buttons.sendTranscript) .setLabel(l.buttons.sendTranscript)
.setEmoji("📄") .setEmoji("📄")
) )
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("reopenTicket") .setCustomId("reopenTicket")
.setDisabled(false) .setDisabled(false)
.setStyle("SUCCESS") .setStyle(discord.ButtonStyle.Success)
.setLabel(l.buttons.reopen) .setLabel(l.buttons.reopen)
.setEmoji("✔") .setEmoji("✔")
) )
var closeRowDisabled = new discord.MessageActionRow() var closeRowDisabled = new discord.ActionRowBuilder()
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("closeTicket") .setCustomId("closeTicket")
.setDisabled(true) .setDisabled(true)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setLabel(l.buttons.close) .setLabel(l.buttons.close)
.setEmoji("🔒") .setEmoji("🔒")
) )
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("deleteTicket") .setCustomId("deleteTicket")
.setDisabled(true) .setDisabled(true)
.setStyle("DANGER") .setStyle(discord.ButtonStyle.Danger)
.setLabel(l.buttons.delete) .setLabel(l.buttons.delete)
.setEmoji("✖️") .setEmoji("✖️")
) )
@@ -131,17 +131,25 @@ module.exports = () => {
interaction.deferUpdate() interaction.deferUpdate()
interaction.message.edit({components:[closeRowNormal]}) interaction.message.edit({components:[closeRowNormal]})
}) })
client.on("interactionCreate",interaction => {
var closeTicketButtonChecker = false
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return if (!interaction.isButton()) return
if (interaction.customId != "closeTicketTrue") return if (interaction.customId != "closeTicketTrue") return
interaction.deferUpdate() interaction.deferUpdate()
if (closeTicketButtonChecker == true) return
closeTicketButtonChecker = true
if (config.system.closeMode == "adminonly"){ if (config.system.closeMode == "adminonly"){
const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id) const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id)
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("ADMINISTRATOR") && !permsmember.permissions.has("MANAGE_GUILD")){ if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("Administrator") && !permsmember.permissions.has("ManageGuild")){
interaction.channel.send({embeds:[bot.errorLog.noPermsMessage]}) try {
return return msg.member.send({embeds:[bot.errorLog.noPermsMessage]})
}catch{
return msg.channel.send({embeds:[bot.errorLog.noPermsMessage]})
}
} }
} }
@@ -159,29 +167,37 @@ module.exports = () => {
} }
}) })
require("./ticketCloser").closeTicket(interaction,prefix,"close") await require("./ticketCloser").NEWcloseTicket(interaction.member,interaction.channel,prefix,"close")
closeTicketButtonChecker = false
}) })
client.on("interactionCreate",interaction => { var closeTicket1ButtonChecker = false
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return if (!interaction.isButton()) return
if (interaction.customId != "closeTicketTrue1") return if (interaction.customId != "closeTicketTrue1") return
interaction.deferUpdate() interaction.deferUpdate()
if (closeTicket1ButtonChecker == true) return
closeTicket1ButtonChecker = true
if (config.system.closeMode == "adminonly"){ if (config.system.closeMode == "adminonly"){
const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id) const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id)
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("ADMINISTRATOR") && !permsmember.permissions.has("MANAGE_GUILD")){ if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("Administrator") && !permsmember.permissions.has("ManageGuild")){
interaction.channel.send({embeds:[bot.errorLog.noPermsMessage]}) try {
return return interaction.member.send({embeds:[bot.errorLog.noPermsMessage]})
}catch{
return interaction.channel.send({embeds:[bot.errorLog.noPermsMessage]})
}
} }
} }
const closedButtonDisabled = new discord.MessageActionRow() const closedButtonDisabled = new discord.ActionRowBuilder()
.addComponents([ .addComponents([
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("closeTicketTrue1") .setCustomId("closeTicketTrue1")
.setDisabled(true) .setDisabled(true)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setEmoji("🔒") .setEmoji("🔒")
]) ])
interaction.message.edit({components:[closedButtonDisabled]}) interaction.message.edit({components:[closedButtonDisabled]})
@@ -202,7 +218,8 @@ module.exports = () => {
} }
}) })
require("./ticketCloser").closeTicket(interaction,prefix,"close") await require("./ticketCloser").NEWcloseTicket(interaction.member,interaction.channel,prefix,"close")
closeTicket1ButtonChecker = false
}) })
@@ -222,16 +239,23 @@ module.exports = () => {
interaction.deferUpdate() interaction.deferUpdate()
interaction.message.edit({components:[closeRowNormal]}) interaction.message.edit({components:[closeRowNormal]})
}) })
client.on("interactionCreate",interaction => { var deleteTicketButtonChecker = false
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return if (!interaction.isButton()) return
if (interaction.customId != "deleteTicketTrue") return if (interaction.customId != "deleteTicketTrue") return
interaction.deferUpdate() interaction.deferUpdate()
if (deleteTicketButtonChecker == true) return
deleteTicketButtonChecker = true
const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id) const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id)
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("ADMINISTRATOR") && !permsmember.permissions.has("MANAGE_GUILD")){ if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("Administrator") && !permsmember.permissions.has("ManageGuild")){
interaction.channel.send({embeds:[bot.errorLog.noPermsMessage]}) try {
return return interaction.member.send({embeds:[bot.errorLog.noPermsMessage]})
}catch{
return interaction.channel.send({embeds:[bot.errorLog.noPermsMessage]})
}
} }
/** /**
@@ -246,7 +270,8 @@ module.exports = () => {
} }
}) })
require("./ticketCloser").closeTicket(interaction,prefix,"delete") await require("./ticketCloser").NEWcloseTicket(interaction.member,interaction.channel,prefix,"delete")
deleteTicketButtonChecker = false
}) })
@@ -268,16 +293,24 @@ module.exports = () => {
interaction.deferUpdate() interaction.deferUpdate()
interaction.message.edit({components:[closeRowClosed]}) interaction.message.edit({components:[closeRowClosed]})
}) })
client.on("interactionCreate",interaction => {
var deleteTicket1ButtonChecker = false
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return if (!interaction.isButton()) return
if (interaction.customId != "deleteTicketTrue1") return if (interaction.customId != "deleteTicketTrue1") return
interaction.deferUpdate() interaction.deferUpdate()
if (deleteTicket1ButtonChecker == true) return
deleteTicket1ButtonChecker = true
const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id) const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id)
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("ADMINISTRATOR") && !permsmember.permissions.has("MANAGE_GUILD")){ if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("Administrator") && !permsmember.permissions.has("ManageGuild")){
interaction.channel.send({embeds:[bot.errorLog.noPermsMessage]}) try {
return return interaction.member.send({embeds:[bot.errorLog.noPermsMessage]})
}catch{
return interaction.channel.send({embeds:[bot.errorLog.noPermsMessage]})
}
} }
/** /**
@@ -292,6 +325,7 @@ module.exports = () => {
} }
}) })
require("./ticketCloser").closeTicket(interaction,prefix,"deletenotranscript") await require("./ticketCloser").NEWcloseTicket(interaction.member,interaction.channel,prefix,"deletenotranscript")
deleteTicket1ButtonChecker = false
}) })
} }
+19 -12
View File
@@ -7,17 +7,18 @@ const l = bot.language
const loadChalk = async () => { const loadChalk = async () => {
return await (await import("chalk")).default return await (await import("chalk")).default
} }
const embed = discord.MessageEmbed const embed = discord.EmbedBuilder
const c = discord.Colors
exports.noPermsMessage = new embed() exports.noPermsMessage = new embed()
.setColor("RED") .setColor(c.Red)
.setTitle(":x: "+l.errors.noPermsTitle+" :x:") .setTitle(":x: "+l.errors.noPermsTitle+" :x:")
.setDescription(l.errors.noPermsDescription) .setDescription(l.errors.noPermsDescription)
/**@param {String} message */ /**@param {String} message */
exports.invalidArgsMessage = (message) => { exports.invalidArgsMessage = (message) => {
var x = new embed() var x = new embed()
.setColor("RED") .setColor(c.Red)
.setTitle(":x: "+l.errors.missingArgsTitle+" :x:") .setTitle(":x: "+l.errors.missingArgsTitle+" :x:")
.setDescription(message) .setDescription(message)
@@ -27,7 +28,7 @@ exports.invalidArgsMessage = (message) => {
/**@param {String} message */ /**@param {String} message */
exports.serverError = (message) => { exports.serverError = (message) => {
var x = new embed() var x = new embed()
.setColor("ORANGE") .setColor(c.Orange)
.setTitle(":warning: "+l.errors.boterror+" :warning:") .setTitle(":warning: "+l.errors.boterror+" :warning:")
.setDescription(message) .setDescription(message)
@@ -37,14 +38,14 @@ exports.serverError = (message) => {
/**@param {String[]} list */ /**@param {String[]} list */
exports.invalidIdChooseFromList = (list) => { exports.invalidIdChooseFromList = (list) => {
var x = new embed() var x = new embed()
.setColor("RED") .setColor(c.Red)
.setTitle(":x: "+l.errors.chooseFromListTitle+" :x:") .setTitle(":x: "+l.errors.chooseFromListTitle+" :x:")
.setDescription(l.errors.chooseFromListDescription+"\n`"+list.join("`\n`")+"`") .setDescription(l.errors.chooseFromListDescription+"\n`"+list.join("`\n`")+"`")
return x return x
} }
exports.notInATicket = new embed() exports.notInATicket = new embed()
.setColor("RED") .setColor(c.Red)
.setTitle(":x: "+l.errors.notInTicketTitle+" :x:") .setTitle(":x: "+l.errors.notInTicketTitle+" :x:")
.setDescription(l.errors.notInTicketDescription) .setDescription(l.errors.notInTicketDescription)
@@ -62,7 +63,7 @@ exports.success = (title,message) => {
/**@param {String} message @param {String} title */ /**@param {String} message @param {String} title */
exports.warning = (title,message) => { exports.warning = (title,message) => {
var x = new embed() var x = new embed()
.setColor("ORANGE") .setColor(c.Orange)
.setTitle(":warning: "+title+" :warning:") .setTitle(":warning: "+title+" :warning:")
.setDescription(message) .setDescription(message)
@@ -87,11 +88,12 @@ const normalLog = (debugString) => {
/** /**
* *
* @param {"system"|"command"|"info"} type * @param {"system"|"command"|"info"|"api"} type
* @param {String} message * @param {String} message
* @param {[{key:String,value:String}]} params * @param {[{key:String,value:String}]} params
*/ */
exports.log = async (type,message,params) => { exports.log = async (type,message,params) => {
var ptype = type
const chalk = await loadChalk() const chalk = await loadChalk()
var paramstring = "" var paramstring = ""
if (params){ if (params){
@@ -103,15 +105,20 @@ exports.log = async (type,message,params) => {
} }
const parameters = params ? "("+paramstring+")" : " " const parameters = params ? "("+paramstring+")" : " "
if (type == "command"){ if (ptype == "command"){
console.log(chalk.green("[command] ")+message+" "+chalk.yellow(parameters)) console.log(chalk.green("[command] ")+message+" "+chalk.yellow(parameters))
}else if (type == "info"){ }else if (ptype == "info"){
console.log(chalk.blue("[info] ")+message+" "+chalk.yellow(parameters)) console.log(chalk.blue("[info] ")+message+" "+chalk.yellow(parameters))
}else if (type == "system"){ }else if (ptype == "system"){
console.log(chalk.green("[system] ")+message+" "+chalk.yellow(parameters)) console.log(chalk.green("[system] ")+message+" "+chalk.yellow(parameters))
}else if (ptype == "api"){
if (require("./api/modules/base").enableApiLogs == true){
console.log(chalk.red("[api v"+require("./api/api.json").version+"] ")+message+" "+chalk.yellow(parameters))
}
ptype = "api v"+require("./api/api.json").version
} }
const cd = new Date() const cd = new Date()
const months = ["January","February","March","April","May","June","July","August","September","October","November","December"] const months = ["January","February","March","April","May","June","July","August","September","October","November","December"]
normalLog("["+cd.getDate()+" "+months[cd.getMonth()-1]+" "+cd.getFullYear()+" - "+cd.getSeconds()+":"+cd.getMinutes()+":"+cd.getHours()+"] ["+type+"] "+message+" "+parameters) normalLog("["+cd.getDate()+" "+months[cd.getMonth()-1]+" "+cd.getFullYear()+" - "+cd.getSeconds()+":"+cd.getMinutes()+":"+cd.getHours()+"] ["+ptype+"] "+message+" "+parameters)
} }
+3 -1
View File
@@ -9,9 +9,11 @@ var localLanguage = require("../language/english.json")
if (config.languagefile.startsWith("custom")) localLanguage = require("../language/custom.json") if (config.languagefile.startsWith("custom")) localLanguage = require("../language/custom.json")
else if (config.languagefile.startsWith("dutch")) localLanguage = require("../language/dutch.json") else if (config.languagefile.startsWith("dutch")) localLanguage = require("../language/dutch.json")
else if (config.languagefile.startsWith("english")) localLanguage = require("../language/english.json") else if (config.languagefile.startsWith("english")) localLanguage = require("../language/english.json")
else if (config.languagefile.startsWith("deutsch")) localLanguage = require("../language/deutsch.json") else if (config.languagefile.startsWith("german")) localLanguage = require("../language/german.json")
else if (config.languagefile.startsWith("french")) localLanguage = require("../language/french.json") else if (config.languagefile.startsWith("french")) localLanguage = require("../language/french.json")
else if (config.languagefile.startsWith("romanian")) localLanguage = require("../language/romanian.json") else if (config.languagefile.startsWith("romanian")) localLanguage = require("../language/romanian.json")
else if (config.languagefile.startsWith("arabic")) localLanguage = require("../language/arabic.json")
else if (config.languagefile.startsWith("spanish")) localLanguage = require("../language/spanish.json")
const errorLog = async () => { const errorLog = async () => {
const chalk = await (await import("chalk")).default const chalk = await (await import("chalk")).default
+44 -31
View File
@@ -6,6 +6,8 @@ const log = bot.errorLog.log
const l = bot.language const l = bot.language
const storage = bot.storage const storage = bot.storage
const APIEvents = require("./api/modules/events")
module.exports = async () => { module.exports = async () => {
const chalk = await (await import("chalk")).default const chalk = await (await import("chalk")).default
@@ -21,42 +23,53 @@ module.exports = async () => {
interaction.reply({embeds:[bot.errorLog.serverError(l.errors.roleDoesntExist)]}) interaction.reply({embeds:[bot.errorLog.serverError(l.errors.roleDoesntExist)]})
return return
} }
}
try {
const option = require("./utils/getButton").getOption(optionid) try {
/**@type {"add"|"remove"|"add&remove"} */
const mode = option.mode
const user = interaction.member
if (mode == "add"){
option.roles.forEach((role) => {
interaction.guild.members.cache.find(u => u.id == user.id).roles.add(role)
log("system","added role (reaction roles)",[{key:"user",value:interaction.user.tag},{key:"role",value:role}]) const option = require("./utils/getButton").getOption(optionid)
}) /**@type {"add"|"remove"|"add&remove"} */
}else if (mode == "remove"){ const mode = option.mode
option.roles.forEach((role) => { const user = interaction.member
interaction.guild.members.cache.find(u => u.id == user.id).roles.remove(role)
log("system","removed role (reaction roles)",[{key:"user",value:interaction.user.tag},{key:"role",value:role}]) if (mode == "add"){
}) option.roles.forEach((role) => {
}else if (mode == "add&remove"){ interaction.guild.members.cache.find(u => u.id == user.id).roles.add(role)
option.roles.forEach((role) => {
if (interaction.guild.members.cache.find(u => u.id == user.id).roles.cache.has(role)){ log("system","added role (reaction roles)",[{key:"user",value:interaction.user.tag},{key:"role",value:role}])
interaction.guild.members.cache.find(u => u.id == user.id).roles.remove(role) const apirole = interaction.guild.roles.cache.find(r => r.id == role)
APIEvents.onReactionRole("add","add",apirole,interaction.user,interaction.channel,interaction.guild,new Date())
})
}else if (mode == "remove"){
option.roles.forEach((role) => {
interaction.guild.members.cache.find(u => u.id == user.id).roles.remove(role)
log("system","removed role (reaction roles)",[{key:"user",value:interaction.user.tag},{key:"role",value:role}])
const apirole = interaction.guild.roles.cache.find(r => r.id == role)
APIEvents.onReactionRole("remove","remove",apirole,interaction.user,interaction.channel,interaction.guild,new Date())
})
log("system","added role (reaction roles)",[{key:"user",value:interaction.user.tag},{key:"role",value:role}]) }else if (mode == "add&remove"){
}else { option.roles.forEach((role) => {
interaction.guild.members.cache.find(u => u.id == user.id).roles.add(role) if (interaction.guild.members.cache.find(u => u.id == user.id).roles.cache.has(role)){
interaction.guild.members.cache.find(u => u.id == user.id).roles.remove(role)
log("system","removed role (reaction roles)",[{key:"user",value:interaction.user.tag},{key:"role",value:role}])
log("system","added role (reaction roles)",[{key:"user",value:interaction.user.tag},{key:"role",value:role}])
const apirole = interaction.guild.roles.cache.find(r => r.id == role)
APIEvents.onReactionRole("add","add&remove",apirole,interaction.user,interaction.channel,interaction.guild,new Date())
}else {
interaction.guild.members.cache.find(u => u.id == user.id).roles.add(role)
log("system","removed role (reaction roles)",[{key:"user",value:interaction.user.tag},{key:"role",value:role}])
const apirole = interaction.guild.roles.cache.find(r => r.id == role)
APIEvents.onReactionRole("remove","add&remove",apirole,interaction.user,interaction.channel,interaction.guild,new Date())
}
})
} }
})
} }catch{
interaction.channel.send({embeds:[bot.errorLog.serverError(l.errors.somethingWentWrong)]})
}catch{ }
interaction.replyinteraction.channel.send({embeds:[bot.errorLog.serverError(l.errors.somethingWentWrong)]})
} }
}) })
} }
+1 -1
View File
@@ -9,7 +9,7 @@ module.exports = async () => {
console.log(chalk.red("\nINSTRUCTIONS:\n\n1: Run the command you want to delete in discord.\n2: You get the message 'This command is now deleted!'\n3: There is also a message in the console that says the command is deleted.\n4: reload your discord.")) console.log(chalk.red("\nINSTRUCTIONS:\n\n1: Run the command you want to delete in discord.\n2: You get the message 'This command is now deleted!'\n3: There is also a message in the console that says the command is deleted.\n4: reload your discord."))
client.on("interactionCreate",(interaction) => { client.on("interactionCreate",(interaction) => {
if (!interaction.isCommand()) return console.log("this isn't a command!") if (!interaction.isChatInputCommand()) return console.log("this isn't a command!")
interaction.reply({content:"This command is now deleted!"}) interaction.reply({content:"This command is now deleted!"})
+21 -17
View File
@@ -4,6 +4,9 @@ const client = require("../../index").client
const config = bot.config const config = bot.config
const getoptions = require("../getoptions") const getoptions = require("../getoptions")
const act = discord.ApplicationCommandType
const acot = discord.ApplicationCommandOptionType
module.exports = async () => { module.exports = async () => {
const chalk = (await import("chalk")).default const chalk = (await import("chalk")).default
const sid = config.server_id const sid = config.server_id
@@ -42,10 +45,10 @@ module.exports = async () => {
name:"ticket", name:"ticket",
description:"Create a ticket!", description:"Create a ticket!",
defaultPermission:true, defaultPermission:true,
type:"CHAT_INPUT", type:act.ChatInput,
options:[ options:[
{ {
type:"STRING", type:acot.String,
name:"type", name:"type",
description:"The type of ticket.", description:"The type of ticket.",
required:true, required:true,
@@ -61,10 +64,10 @@ module.exports = async () => {
name:"new", name:"new",
description:"Create a ticket!", description:"Create a ticket!",
defaultPermission:true, defaultPermission:true,
type:"CHAT_INPUT", type:act.ChatInput,
options:[ options:[
{ {
type:"STRING", type:acot.String,
name:"type", name:"type",
description:"The type of ticket.", description:"The type of ticket.",
required:true, required:true,
@@ -81,7 +84,7 @@ module.exports = async () => {
name:"help", name:"help",
description:"The help menu", description:"The help menu",
defaultPermission:true, defaultPermission:true,
type:"CHAT_INPUT" type:act.ChatInput
},sid).then(() => { },sid).then(() => {
readystats++ readystats++
@@ -92,7 +95,7 @@ module.exports = async () => {
name:"close", name:"close",
description:"Close the current ticket.", description:"Close the current ticket.",
defaultPermission:true, defaultPermission:true,
type:"CHAT_INPUT" type:act.ChatInput
},sid).then(() => { },sid).then(() => {
readystats++ readystats++
}) })
@@ -102,7 +105,7 @@ module.exports = async () => {
name:"delete", name:"delete",
description:"Delete the current ticket.", description:"Delete the current ticket.",
defaultPermission:true, defaultPermission:true,
type:"CHAT_INPUT" type:act.ChatInput
},sid).then(() => { },sid).then(() => {
readystats++ readystats++
}) })
@@ -112,14 +115,15 @@ module.exports = async () => {
name:"message", name:"message",
description:"Create a ticket message.", description:"Create a ticket message.",
defaultPermission:true, defaultPermission:true,
type:"CHAT_INPUT", type:act.ChatInput,
options:[ options:[
{ {
type:"STRING", type:acot.String,
name:"id", name:"id",
description:"The message id.", description:"The message id.",
required:true, required:true,
choices:msgchoices choices:msgchoices,
max_length:30
} }
] ]
@@ -132,10 +136,10 @@ module.exports = async () => {
name:"add", name:"add",
description:"Add people to this ticket.", description:"Add people to this ticket.",
defaultPermission:true, defaultPermission:true,
type:"CHAT_INPUT", type:act.ChatInput,
options:[ options:[
{ {
type:"USER", type:acot.User,
name:"user", name:"user",
description:"The user to add.", description:"The user to add.",
required:true required:true
@@ -150,10 +154,10 @@ module.exports = async () => {
name:"remove", name:"remove",
description:"Remove people from this ticket.", description:"Remove people from this ticket.",
defaultPermission:true, defaultPermission:true,
type:"CHAT_INPUT", type:act.ChatInput,
options:[ options:[
{ {
type:"USER", type:acot.User,
name:"user", name:"user",
description:"The user to remove.", description:"The user to remove.",
required:true required:true
@@ -168,10 +172,10 @@ module.exports = async () => {
name:"rename", name:"rename",
description:"Rename this ticket.", description:"Rename this ticket.",
defaultPermission:true, defaultPermission:true,
type:"CHAT_INPUT", type:act.ChatInput,
options:[ options:[
{ {
type:"STRING", type:acot.String,
name:"name", name:"name",
description:"The new name (without prefix).", description:"The new name (without prefix).",
required:true required:true
@@ -186,7 +190,7 @@ module.exports = async () => {
name:"reopen", name:"reopen",
description:"Reopen this ticket.", description:"Reopen this ticket.",
defaultPermission:true, defaultPermission:true,
type:"CHAT_INPUT" type:act.ChatInput
},sid).then(() => { },sid).then(() => {
readystats++ readystats++
}) })
Regular → Executable
+303 -217
View File
@@ -5,223 +5,7 @@ const config = bot.config
const log = bot.errorLog.log const log = bot.errorLog.log
const l = bot.language const l = bot.language
const storage = bot.storage const storage = bot.storage
const permsChecker = require("./utils/permisssionChecker")
/**
*
* @param {discord.Interaction} interaction
* @param {String} prefix
* @param {"delete"|"close"|"deletenotranscript"} mode
*/
exports.closeTicket = async (interaction,prefix,mode) => {
const chalk = await (await import("chalk")).default
const channelmessages = await interaction.channel.messages.fetch()
const channel = interaction.channel
channelmessages.sweep((msgSweep) => {
return msgSweep.author.id == client.user.id
})
/**
* @type {String} ticketuserarray
*/
const ticketuserarray = interaction.channel.name
const ticketusername = ticketuserarray.split(prefix)[1]
var getuserID = storage.get("userTicketStorage",interaction.channel.id)
try {
var getusernameStep1 = client.users.cache.find(u => u.id === getuserID)
var isDatabaseError = false
}catch{
var isDatabaseError = true
}
if (!getusernameStep1){
console.log(chalk.red("[database error]"),"something went wrong when getting the data in the database.\nNo panic, this error fixes itself!")
var isDatabaseError = true
}
var enableTranscript = true
if (mode == "delete"){
const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id)
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("ADMINISTRATOR") && !permsmember.permissions.has("MANAGE_GUILD")){
interaction.channel.send({embeds:[bot.errorLog.noPermsMessage]})
return
}
interaction.channel.delete()
log("system","deleted a ticket",[{key:"user",value:interaction.user.tag},{key:"ticket",value:interaction.channel.name}])
if (!isDatabaseError) storage.set("ticketStorage",getuserID,Number(storage.get("ticketStorage",getuserID)) - 1)
//getID & send DM
interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return false
if (!firstmsg.embeds[0].author) return false
const id = firstmsg.embeds[0].author.name
if (!id) return false
try{
if (config.system.enable_DM_Messages){
interaction.member.send({embeds:[bot.errorLog.custom(l.messages.deletedTicketDmTitle,l.messages.deletedTicketDmDescription,":ticket:",config.main_color)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
})
}else if (mode == "close"){
if (config.system.closeMode == "adminonly"){
const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id)
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("ADMINISTRATOR") && !permsmember.permissions.has("MANAGE_GUILD")){
interaction.channel.send({embeds:[bot.errorLog.noPermsMessage]})
return
}
}
var permissionArray = []
if (!isDatabaseError) permissionArray.push({
id:getusernameStep1.id,
type:"member",
allow:["VIEW_CHANNEL"],
deny:["ADD_REACTIONS","ATTACH_FILES","EMBED_LINKS","SEND_MESSAGES"]
})
permissionArray.push({
id:interaction.guild.id,
type:"role",
deny:["ADD_REACTIONS","ATTACH_FILES","EMBED_LINKS","SEND_MESSAGES","VIEW_CHANNEL"]
})
interaction.channel.permissionOverwrites.set(permissionArray)
//message
var closeButtonRow = new discord.MessageActionRow()
.addComponents(
new discord.MessageButton()
.setCustomId("deleteTicket1")
.setDisabled(false)
.setStyle("DANGER")
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
.addComponents(
new discord.MessageButton()
.setCustomId("sendTranscript")
.setDisabled(false)
.setStyle("SECONDARY")
.setLabel(l.buttons.sendTranscript)
.setEmoji("📄")
)
.addComponents(
new discord.MessageButton()
.setCustomId("reopenTicket")
.setDisabled(false)
.setStyle("SUCCESS")
.setLabel(l.buttons.reopen)
.setEmoji("✔")
)
const embed = new discord.MessageEmbed()
.setColor(config.main_color)
.setTitle(":lock: "+l.messages.closedTitle+" :lock:")
.setDescription(l.messages.closedDescription)
interaction.channel.send({embeds:[embed],components:[closeButtonRow]})
log("system","closed a ticket",[{key:"user",value:interaction.user.tag},{key:"ticket",value:interaction.channel.name}])
//getID & send DM
interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return false
const id = firstmsg.embeds[0].author.name
if (!id) return false
try{
if (config.system.enable_DM_Messages){
interaction.member.send({embeds:[bot.errorLog.custom(l.messages.closedTicketDmTitle,l.messages.closedTicketDmDescription,":ticket:",config.main_color)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
})
}else if (mode == "deletenotranscript"){
const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id)
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("ADMINISTRATOR") && !permsmember.permissions.has("MANAGE_GUILD")){
interaction.channel.send({embeds:[bot.errorLog.noPermsMessage]})
return
}
enableTranscript = false
interaction.channel.delete()
log("system","deleted a ticket",[{key:"user",value:interaction.user.tag},{key:"ticket",value:interaction.channel.name}])
if (!isDatabaseError) storage.set("ticketStorage",getuserID,Number(storage.get("ticketStorage",getuserID)) - 1)
//getID & send DM
interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return false
const id = firstmsg.embeds[0].author.name
if (!id) return false
try{
if (config.system.enable_DM_Messages){
interaction.member.send({embeds:[bot.errorLog.custom(l.messages.deletedTicketDmTitle,l.messages.deletedTicketDmDescription,":ticket:",config.main_color)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
})
}
if (enableTranscript == true && mode != "deletenotranscript"){
if (config.system.enable_transcript || config.system.enable_DM_transcript){
var fileattachment = await require("./transcript").createTranscript(channelmessages,channel)
if (fileattachment == false){log("system","internal error: transcript is not created!");return}
}
if (config.system.enable_transcript){
const transcriptEmbed = new discord.MessageEmbed()
.setColor(config.main_color)
.setTitle(l.messages.newTranscriptTitle)
.setAuthor({name:interaction.user.username,iconURL:interaction.user.displayAvatarURL({format:"png"})})
.setDescription(l.messages.newTranscriptDescription)
.setFooter({text:"ticket: "+ticketuserarray})
interaction.guild.channels.cache.find(c => c.id == config.system.transcript_channel).send({
embeds:[transcriptEmbed],
files:[fileattachment]
})
}
if (config.system.enable_DM_transcript){
const transcriptEmbed = new discord.MessageEmbed()
.setColor(config.main_color)
.setTitle(l.messages.newTranscriptTitle)
.setDescription(l.messages.newTranscriptDescription)
.setFooter({text:"ticket: "+ticketuserarray})
if (!isDatabaseError) getusernameStep1.send({
embeds:[transcriptEmbed],
files:[fileattachment]
})
}
}
}
exports.runThis = () => { exports.runThis = () => {
client.on("interactionCreate",async (interaction) => { client.on("interactionCreate",async (interaction) => {
@@ -246,4 +30,306 @@ exports.runThis = () => {
interaction.channel.send({content:"**"+l.messages.hereIsTheTranscript+"**",files:[fileattachment]}) interaction.channel.send({content:"**"+l.messages.hereIsTheTranscript+"**",files:[fileattachment]})
}) })
}
/**
*
* @param {discord.GuildMember} member
* @param {discord.TextChannel} channel
* @param {String} prefix
* @param {"delete"|"close"|"deletenotranscript"} mode
*/
exports.NEWcloseTicket = async (member,channel,prefix,mode) => {
const guild = channel.guild
const user = member.user
const chalk = await (await import("chalk")).default
const channelmessages = await channel.messages.fetch()
//start code
//remove ot bot from transcript
channelmessages.sweep((msgSweep) => {return msgSweep.author.id == client.user.id})
/**@type {String}*/
const channelname = channel.name
const ticketOpenerChannelName = channelname.split(prefix)[1]
//get user that opened the ticket
var getuserID = storage.get("userTicketStorage",channel.id)
try {
var ticketOpener = client.users.cache.find(u => u.id === getuserID)
var isDatabaseError = false
}catch{var isDatabaseError = true}
if (!ticketOpener){
console.log(chalk.red("[database error]"),"something went wrong when getting the data in the database.\nNo panic, this error fixes itself!")
var isDatabaseError = true
}
var enableTranscript = true
var deleteRequired = false
if (mode == "delete"){
//delete
//check perms
if (!guild) return
if (!permsChecker.command(user.id,guild.id)){
permsChecker.sendUserNoPerms(user)
return
}
//start delete proccess
deleteRequired = true
await channel.send({content:"**"+l.messages.gettingdeleted+"**"})
log("system","deleted a ticket",[{key:"user",value:user.tag},{key:"ticket",value:channel.name}])
if (!isDatabaseError) storage.set("ticketStorage",getuserID,Number(storage.get("ticketStorage",getuserID)) - 1)
//getID & send DM & send api event
await channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return false
const ticketId = firstmsg.embeds[0].footer.text.split("Ticket Type: ")[1]
const ticketData = require("./getoptions").getOptionsById("newT"+ticketId)
require("./api/modules/events").onTicketDelete(user,channel,guild,new Date(),{name:channel.name,status:"deleted",ticketOptions:ticketData})
if (!firstmsg.embeds[0].author) return false
const id = firstmsg.embeds[0].author.name
if (!id) return false
try{
if (config.system.enable_DM_Messages){
member.send({embeds:[bot.errorLog.custom(l.messages.deletedTicketDmTitle,l.messages.deletedTicketDmDescription,":ticket:",config.main_color)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
})
}else if (mode == "close"){
//close
//check perms
if (config.system.closeMode == "adminonly"){
if (!guild) return
if (!permsChecker.command(user.id,guild.id)){
permsChecker.sendUserNoPerms(user)
return
}
}
//set new permissions
var permissionArray = []
const pfb = discord.PermissionFlagsBits
if (!isDatabaseError) permissionArray.push({
id:ticketOpener,
type:"member",
allow:[pfb.ViewChannel],
deny:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages]
})
permissionArray.push({
id:guild.roles.everyone,
type:"role",
deny:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
})
//add main adminroles
config.main_adminroles.forEach((role,index) => {
try {
const adminrole = guild.roles.cache.find(r => r.id == role)
if (!adminrole) return
permissionArray.push({
id:adminrole,
type:"role",
allow:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
})
}catch{
log("system","invalid role! At 'config.json => main_adminroles:"+index)
}
})
//add ticket adminroles
await channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return false
const ticketId = firstmsg.embeds[0].footer.text.split("Ticket Type: ")[1]
const ticketData = require("./getoptions").getOptionsById("newT"+ticketId)
if (!ticketData) return
/**
* @type {String[]}
*/
const ticketadmin = ticketData.adminroles
ticketadmin.forEach((role,index) => {
if (!config.main_adminroles.includes(role)){
try {
const adminrole = guild.roles.cache.find(r => r.id == role)
if (!adminrole) return
permissionArray.push({
id:adminrole,
type:"role",
allow:[pfb.AddReactions,pfb.ViewChannel],
deny:[pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages]
})
}catch{
log("system","invalid role! At 'config.json => options/ticket/...:"+index)
}
}
})
})
channel.permissionOverwrites.set(permissionArray)
//message
var closeButtonRow = new discord.ActionRowBuilder()
.addComponents(
new discord.ButtonBuilder()
.setCustomId("deleteTicket1")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Danger)
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("sendTranscript")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setLabel(l.buttons.sendTranscript)
.setEmoji("📄")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("reopenTicket")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Success)
.setLabel(l.buttons.reopen)
.setEmoji("✔")
)
const embed = new discord.EmbedBuilder()
.setColor(config.main_color)
.setTitle(":lock: "+l.messages.closedTitle+" :lock:")
.setDescription(l.messages.closedDescription)
channel.send({embeds:[embed],components:[closeButtonRow]})
log("system","closed a ticket",[{key:"user",value:user.tag},{key:"ticket",value:channel.name}])
//getID & send DM & send api event
await channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return false
const ticketId = firstmsg.embeds[0].footer.text.split("Ticket Type: ")[1]
const ticketData = require("./getoptions").getOptionsById("newT"+ticketId)
require("./api/modules/events").onTicketClose(user,channel,guild,new Date(),{name:channel.name,status:"closed",ticketOptions:ticketData})
const id = firstmsg.embeds[0].author.name
if (!id) return false
try{
if (config.system.enable_DM_Messages){
member.send({embeds:[bot.errorLog.custom(l.messages.closedTicketDmTitle,l.messages.closedTicketDmDescription,":ticket:",config.main_color)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
})
}else if (mode == "deletenotranscript"){
//delete with no transcript
//check perms
if (!guild) return
if (!permsChecker.command(user.id,guild.id)){
permsChecker.sendUserNoPerms(user)
return
}
//start delete proccess
enableTranscript = false
deleteRequired = true
channel.send({content:"**"+l.messages.gettingdeleted+"**"})
log("system","deleted a ticket",[{key:"user",value:user.tag},{key:"ticket",value:channel.name}])
if (!isDatabaseError) storage.set("ticketStorage",getuserID,Number(storage.get("ticketStorage",getuserID)) - 1)
//getID & send DM & send api event
await channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return false
const ticketId = firstmsg.embeds[0].footer.text.split("Ticket Type: ")[1]
const ticketData = require("./getoptions").getOptionsById("newT"+ticketId)
require("./api/modules/events").onTicketDelete(user,channel,guild,new Date(),{name:channel.name,status:"deleted",ticketOptions:ticketData})
const id = firstmsg.embeds[0].author.name
if (!id) return false
try{
if (config.system.enable_DM_Messages){
member.send({embeds:[bot.errorLog.custom(l.messages.deletedTicketDmTitle,l.messages.deletedTicketDmDescription,":ticket:",config.main_color)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
})
}
if (enableTranscript == true && mode != "deletenotranscript"){
if (config.system.enable_transcript || config.system.enable_DM_transcript){
var fileattachment = await require("./transcript").createTranscript(channelmessages,channel)
if (fileattachment == false){log("system","internal error: transcript is not created!");return}
}
if (config.system.enable_transcript){
const transcriptEmbed = new discord.EmbedBuilder()
.setColor(config.main_color)
.setTitle(l.messages.newTranscriptTitle)
.setAuthor({name:user.username,iconURL:user.displayAvatarURL({format:"png"})})
.setDescription(l.messages.newTranscriptDescription)
.setFooter({text:"ticket: "+channelname})
guild.channels.cache.find(c => c.id == config.system.transcript_channel).send({
embeds:[transcriptEmbed],
files:[fileattachment]
})
}
if (config.system.enable_DM_transcript){
const transcriptEmbed = new discord.EmbedBuilder()
.setColor(config.main_color)
.setTitle(l.messages.newTranscriptTitle)
.setDescription(l.messages.newTranscriptDescription)
.setFooter({text:"ticket: "+channelname})
if (!isDatabaseError) ticketOpener.send({
embeds:[transcriptEmbed],
files:[fileattachment]
})
}
}
if (deleteRequired){
const timer = () => {return new Promise((resolve,reject) => {
setTimeout(() => {resolve(true)},7000)
})}
await timer()
await channel.delete()
}
} }
+12 -10
View File
@@ -8,7 +8,7 @@ const l = bot.language
/** /**
* *
* @param {String} id the id from an open-ticket embed * @param {String} id the id from an open-ticket embed
* @returns {{embed:discord.MessageEmbed,componentRows:discord.MessageActionRow[]}} discord embed * @returns {{embed:discord.EmbedBuilder,componentRows:discord.MessageActionRow[]}} discord embed
*/ */
@@ -17,7 +17,7 @@ exports.createEmbed = (id) => {
//----------------------------------- //-----------------------------------
//general importing //general importing
const data = require("./utils/getTicketMessages").getTicketMessage(id) const data = require("./utils/getTicketMessages").getTicketMessage(id)
/**@type {discord.MessageButton[]}*/ /**@type {discord.ButtonBuilder[]}*/
var buttons = [] var buttons = []
/**@type {getButton.rawButtonData[]} */ /**@type {getButton.rawButtonData[]} */
var buttonData = [] var buttonData = []
@@ -32,12 +32,17 @@ exports.createEmbed = (id) => {
//----------------------------------- //-----------------------------------
//create the embed //create the embed
const embed = new discord.MessageEmbed() const embed = new discord.EmbedBuilder()
.setColor(data.color)
.setTitle(data.name) .setTitle(data.name)
if (data.enableFooter) embed.setFooter({text:data.footer}) if (data.enableFooter) embed.setFooter({text:data.footer})
if (data.enableThumbnail) embed.setThumbnail(data.thumbnail) if (data.enableThumbnail) embed.setThumbnail(data.thumbnail)
if (data.enableCustomColor){
embed.setColor(data.color)
}else{
embed.setColor(config.main_color)
}
var description = data.description var description = data.description
if (data.enableTicketExplaination){ if (data.enableTicketExplaination){
description = description+"\n\n__"+l.messages.chooseCategory+"__\n" description = description+"\n\n__"+l.messages.chooseCategory+"__\n"
@@ -70,7 +75,7 @@ exports.createEmbed = (id) => {
for (let i = AmountOfRows; i > 0; i--){ for (let i = AmountOfRows; i > 0; i--){
componentRows.push(new discord.MessageActionRow()) componentRows.push(new discord.ActionRowBuilder())
} }
buttons.forEach((button,index) => { buttons.forEach((button,index) => {
@@ -86,11 +91,8 @@ exports.createEmbed = (id) => {
//return everything //return everything
/** /**
* @type {{embed:discord.MessageEmbed,componentRows:discord.MessageActionRow[]}} * @type {{embed:discord.EmbedBuilder,componentRows:discord.MessageActionRow[]}}
*/ */
const returnedData = {embed:embed,componentRows:componentRows} const returnedData = {embed:embed,componentRows:componentRows}
return returnedData return returnedData
} }
this.createEmbed()
Regular → Executable
+65 -39
View File
@@ -9,39 +9,42 @@ const getconfigoptions = require("./getoptions")
const storage = bot.storage const storage = bot.storage
module.exports = () => { module.exports = () => {
var closeButton = new discord.MessageActionRow() var closeButton = new discord.ActionRowBuilder()
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("closeTicket") .setCustomId("closeTicket")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setLabel(l.buttons.close) .setLabel(l.buttons.close)
.setEmoji("🔒") .setEmoji("🔒")
) )
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("deleteTicket") .setCustomId("deleteTicket")
.setDisabled(false) .setDisabled(false)
.setStyle("DANGER") .setStyle(discord.ButtonStyle.Danger)
.setLabel(l.buttons.delete) .setLabel(l.buttons.delete)
.setEmoji("✖️") .setEmoji("✖️")
) )
//ticket button click / create ticket //ticket button click / create ticket
client.on("interactionCreate",(interaction) => { client.on("interactionCreate",(interaction) => {
if (interaction.isCommand() && (interaction.commandName == "new" || interaction.commandName == "ticket")){ if (interaction.isChatInputCommand() && (interaction.commandName == "new" || interaction.commandName == "ticket")){
var customId = "newT"+interaction.options.getString("type") var customId = "newT"+interaction.options.getString("type")
}else if (interaction.isButton()){ }else if (interaction.isButton()){
var customId = interaction.customId var customId = interaction.customId
}else return }else return
if (interaction.customId.startsWith("newT")){ if (interaction.isButton()){
const optionid = interaction.customId.split("newT")[1] if (interaction.customId.startsWith("newT")){
if (!optionid){ const optionid = interaction.customId.split("newT")[1]
interaction.reply({embeds:[bot.errorLog.serverError(l.errors.ticketDoesntExist)]}) if (!optionid){
return interaction.reply({embeds:[bot.errorLog.serverError(l.errors.ticketDoesntExist)]})
return
}
} }
} }
if (getconfigoptions.getTicketValues("id").includes(customId)){ if (getconfigoptions.getTicketValues("id").includes(customId)){
@@ -52,7 +55,7 @@ module.exports = () => {
if (interaction.isButton()){ if (interaction.isButton()){
interaction.deferUpdate() interaction.deferUpdate()
}else if (interaction.isCommand()){ }else if (interaction.isChatInputCommand()){
interaction.reply({embeds:[bot.errorLog.success(l.messages.createdTitle,l.messages.createdDescription)]}) interaction.reply({embeds:[bot.errorLog.success(l.messages.createdTitle,l.messages.createdDescription)]})
} }
@@ -65,7 +68,6 @@ module.exports = () => {
} }
catch{log("system","can't send DM to member, member doesn't allow dm's")} catch{log("system","can't send DM to member, member doesn't allow dm's")}
//update storage //update storage
storage.set("ticketStorage",interaction.member.id,Number(storage.get("ticketStorage",interaction.member.id))+1) storage.set("ticketStorage",interaction.member.id,Number(storage.get("ticketStorage",interaction.member.id))+1)
@@ -83,17 +85,19 @@ module.exports = () => {
} }
var permissionsArray = [] var permissionsArray = []
const pfb = discord.PermissionFlagsBits
const guild = client.guilds.cache.find(g => g.id == interaction.guild.id)
//set everyone allowed //set everyone allowed
if (config.system['has@everyoneaccess']){ if (config.system['has@everyoneaccess']){
var everyoneAllowPerms = ["ADD_REACTIONS","ATTACH_FILES","EMBED_LINKS","SEND_MESSAGES","VIEW_CHANNEL"] var everyoneAllowPerms = [pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
var everyoneDenyPerms = [] var everyoneDenyPerms = []
}else{ }else{
var everyoneAllowPerms = [] var everyoneAllowPerms = []
var everyoneDenyPerms = ["VIEW_CHANNEL"] var everyoneDenyPerms = [pfb.ViewChannel]
} }
permissionsArray.push({ permissionsArray.push({
id:interaction.guild.id, id:interaction.guild.roles.everyone,
type:"role", type:"role",
allow:everyoneAllowPerms, allow:everyoneAllowPerms,
deny:everyoneDenyPerms deny:everyoneDenyPerms
@@ -101,18 +105,25 @@ module.exports = () => {
//add the user that created the ticket //add the user that created the ticket
permissionsArray.push({ permissionsArray.push({
id:interaction.member.id, id:interaction.member.user,
type:"member", type:"member",
allow:["ADD_REACTIONS","ATTACH_FILES","EMBED_LINKS","SEND_MESSAGES","VIEW_CHANNEL"] allow:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
}) })
//add main adminroles //add main adminroles
config.main_adminroles.forEach((role) => { config.main_adminroles.forEach((role,index) => {
permissionsArray.push({ try {
id:role, const adminrole = guild.roles.cache.find(r => r.id == role)
type:"role", if (!adminrole) return
allow:["ADD_REACTIONS","ATTACH_FILES","EMBED_LINKS","SEND_MESSAGES","VIEW_CHANNEL"]
}) permissionsArray.push({
id:adminrole,
type:"role",
allow:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
})
}catch{
log("system","invalid role! At 'config.json => main_adminroles:"+index)
}
}) })
//add ticket adminroles //add ticket adminroles
@@ -120,29 +131,42 @@ module.exports = () => {
* @type {String[]} * @type {String[]}
*/ */
const ticketadmin = currentTicketOptions.adminroles const ticketadmin = currentTicketOptions.adminroles
ticketadmin.forEach((role) => { ticketadmin.forEach((role,index) => {
if (!config.main_adminroles.includes(role)){ if (!config.main_adminroles.includes(role)){
permissionsArray.push({ try {
id:role, const adminrole = guild.roles.cache.find(r => r.id == role)
type:"role", if (!adminrole) return
allow:["ADD_REACTIONS","ATTACH_FILES","EMBED_LINKS","SEND_MESSAGES","VIEW_CHANNEL"]
}) permissionsArray.push({
id:adminrole,
type:"role",
allow:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
})
}catch{
log("system","invalid role! At 'config.json => options/ticket/...:"+index)
}
} }
}) })
//add member role //add member role
if (config.system.member_role != "" && config.system.member_role != " " && config.system.member_role != "false" && config.system.member_role != "null" && config.system.member_role != "0"){ if (config.system.member_role != "" && config.system.member_role != " " && config.system.member_role != "false" && config.system.member_role != "null" && config.system.member_role != "0"){
permissionsArray.push({ try {
id:config.system.member_role, const userrole = guild.roles.cache.find(r => r.id == config.system.member_role)
type:"role", if (!userrole) return
deny:["VIEW_CHANNEL"] permissionsArray.push({
}) id:userrole,
type:"role",
deny:[pfb.ViewChannel]
})
}catch{
log("system","invalid role! At 'config.json => system/member_role")
}
} }
//create the channel //create the channel
interaction.guild.channels.create(ticketName,{ interaction.guild.channels.create({
type:"GUILD_TEXT", name:ticketName,
type:discord.ChannelType.GuildText,
parent:newTicketCategory, parent:newTicketCategory,
reason:"A new ticket is created", reason:"A new ticket is created",
permissionOverwrites:permissionsArray permissionOverwrites:permissionsArray
@@ -150,10 +174,11 @@ module.exports = () => {
}).then((ticketChannel) => { }).then((ticketChannel) => {
storage.set("userTicketStorage",ticketChannel.id,interaction.member.id) storage.set("userTicketStorage",ticketChannel.id,interaction.member.id)
var ticketEmbed = new discord.MessageEmbed() var ticketEmbed = new discord.EmbedBuilder()
.setAuthor({name:interaction.user.id}) .setAuthor({name:interaction.user.id})
.setColor(config.main_color) .setColor(config.main_color)
.setTitle(currentTicketOptions.name) .setTitle(currentTicketOptions.name)
.setFooter({text:"Ticket Type: "+currentTicketOptions.id})
if (currentTicketOptions.ticketmessage.length > 0) ticketEmbed.setDescription(currentTicketOptions.ticketmessage) if (currentTicketOptions.ticketmessage.length > 0) ticketEmbed.setDescription(currentTicketOptions.ticketmessage)
ticketChannel.send({ ticketChannel.send({
@@ -166,6 +191,7 @@ module.exports = () => {
}) })
log("system","created new ticket",[{key:"ticket",value:ticketName},{key:"user",value:interaction.user.tag}]) log("system","created new ticket",[{key:"ticket",value:ticketName},{key:"user",value:interaction.user.tag}])
require("./api/modules/events").onTicketOpen(interaction.user,ticketChannel,interaction.guild,new Date(),{name:ticketName,status:"open",ticketOptions:currentTicketOptions})
}) })
}else{ }else{
try { try {
Regular → Executable
+76 -109
View File
@@ -7,91 +7,136 @@ const l = bot.language
const storage = bot.storage const storage = bot.storage
module.exports = () => { module.exports = () => {
var closeRowNormal = new discord.MessageActionRow() var closeRowNormal = new discord.ActionRowBuilder()
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("closeTicket") .setCustomId("closeTicket")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setLabel(l.buttons.close) .setLabel(l.buttons.close)
.setEmoji("🔒") .setEmoji("🔒")
) )
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("deleteTicket") .setCustomId("deleteTicket")
.setDisabled(false) .setDisabled(false)
.setStyle("DANGER") .setStyle(discord.ButtonStyle.Danger)
.setLabel(l.buttons.delete) .setLabel(l.buttons.delete)
.setEmoji("✖️") .setEmoji("✖️")
) )
var closeRowClosed = new discord.MessageActionRow() var closeRowClosed = new discord.ActionRowBuilder()
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("deleteTicket1") .setCustomId("deleteTicket1")
.setDisabled(false) .setDisabled(false)
.setStyle("DANGER") .setStyle(discord.ButtonStyle.Danger)
.setLabel(l.buttons.delete) .setLabel(l.buttons.delete)
.setEmoji("✖️") .setEmoji("✖️")
) )
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("sendTranscript") .setCustomId("sendTranscript")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setLabel(l.buttons.sendTranscript) .setLabel(l.buttons.sendTranscript)
.setEmoji("📄") .setEmoji("📄")
) )
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("reopenTicket") .setCustomId("reopenTicket")
.setDisabled(false) .setDisabled(false)
.setStyle("SUCCESS") .setStyle(discord.ButtonStyle.Success)
.setLabel(l.buttons.reopen) .setLabel(l.buttons.reopen)
.setEmoji("✔") .setEmoji("✔")
) )
var reopenBar = new discord.MessageActionRow() var reopenBar = new discord.ActionRowBuilder()
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("reopenTicketTrue") .setCustomId("reopenTicketTrue")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setEmoji("✅") .setEmoji("✅")
) )
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("reopenTicketFalse") .setCustomId("reopenTicketFalse")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setEmoji("❌") .setEmoji("❌")
) )
var reopenBar1 = new discord.MessageActionRow() var reopenBar1 = new discord.ActionRowBuilder()
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("reopenTicketTrue1") .setCustomId("reopenTicketTrue1")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setEmoji("✅") .setEmoji("✅")
) )
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("reopenTicketFalse1") .setCustomId("reopenTicketFalse1")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setEmoji("❌") .setEmoji("❌")
) )
var reopenCommandBar = new discord.MessageActionRow() var reopenCommandBar = new discord.ActionRowBuilder()
.addComponents( .addComponents(
new discord.MessageButton() new discord.ButtonBuilder()
.setCustomId("reopenTicket1") .setCustomId("reopenTicket1")
.setDisabled(false) .setDisabled(false)
.setStyle("SECONDARY") .setStyle(discord.ButtonStyle.Secondary)
.setEmoji("🔓") .setEmoji("🔓")
) )
/**
*
* @param {discord.Guild} guild
* @param {discord.TextBasedChannel} channel
* @param {discord.User} user
* @returns
*/
const reopenTicket = (guild,channel,user) => {
log("system","re-opened a ticket",[{key:"ticket",value:channel.name},{key:"user",value:user.tag}])
var permissionsArray = []
//set everyone allowed
if (config.system['has@everyoneaccess']){
var everyoneAllowPerms = [pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
var everyoneDenyPerms = []
}else{
var everyoneAllowPerms = []
var everyoneDenyPerms = [pfb.ViewChannel]
}
permissionsArray.push({
id:guild.roles.everyone,
type:"role",
allow:everyoneAllowPerms,
deny:everyoneDenyPerms
})
channel.permissionOverwrites.cache.forEach((p) => {
if (p.type == "member"){
permissionsArray.push({
id:p.id,
type:"member",
allow:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel],
deny:[]
})
}
})
channel.permissionOverwrites.set(permissionsArray)
require("./api/modules/events").onTicketReopen(user,channel,guild,new Date(),{name:channel.name,status:"reopened",ticketOptions:false})
}
//NORMAL WAY //NORMAL WAY
client.on("interactionCreate",(interaction) => { client.on("interactionCreate",(interaction) => {
if (!interaction.isButton()) return if (!interaction.isButton()) return
@@ -111,51 +156,22 @@ module.exports = () => {
}) })
const pfb = discord.PermissionFlagsBits
client.on("interactionCreate",(interaction) => { client.on("interactionCreate",(interaction) => {
if (!interaction.isButton()) return if (!interaction.isButton()) return
if (interaction.customId != "reopenTicketTrue") return if (interaction.customId != "reopenTicketTrue") return
interaction.deferUpdate() interaction.deferUpdate()
const embed = new discord.MessageEmbed() const embed = new discord.EmbedBuilder()
.setColor(config.main_color) .setColor(config.main_color)
.setTitle(":unlock: "+l.messages.reopenTitle+" :unlock:") .setTitle(":unlock: "+l.messages.reopenTitle+" :unlock:")
.setDescription(l.messages.reopenDescription) .setDescription(l.messages.reopenDescription)
interaction.message.edit({embeds:[embed],components:[closeRowNormal]}) interaction.message.edit({embeds:[embed],components:[closeRowNormal]})
log("system","re-opened a ticket",[{key:"ticket",value:interaction.channel.name},{key:"user",value:interaction.user.tag}]) reopenTicket(interaction.guild,interaction.channel,interaction.user)
var permissionsArray = []
//set everyone allowed
if (config.system['has@everyoneaccess']){
var everyoneAllowPerms = ["ADD_REACTIONS","ATTACH_FILES","EMBED_LINKS","SEND_MESSAGES","VIEW_CHANNEL"]
var everyoneDenyPerms = []
}else{
var everyoneAllowPerms = []
var everyoneDenyPerms = ["VIEW_CHANNEL"]
}
permissionsArray.push({
id:interaction.guild.id,
type:"role",
allow:everyoneAllowPerms,
deny:everyoneDenyPerms
})
interaction.channel.permissionOverwrites.cache.forEach((p) => {
if (p.type == "member"){
permissionsArray.push({
id:p.id,
type:"member",
allow:["ADD_REACTIONS","ATTACH_FILES","EMBED_LINKS","SEND_MESSAGES","VIEW_CHANNEL"],
deny:[]
})
}
})
interaction.channel.permissionOverwrites.set(permissionsArray)
}) })
@@ -184,62 +200,13 @@ module.exports = () => {
interaction.deferUpdate() interaction.deferUpdate()
const embed = new discord.MessageEmbed() const embed = new discord.EmbedBuilder()
.setColor(config.main_color) .setColor(config.main_color)
.setTitle(":unlock: "+l.messages.reopenTitle+" :unlock:") .setTitle(":unlock: "+l.messages.reopenTitle+" :unlock:")
.setDescription(l.messages.reopenDescription) .setDescription(l.messages.reopenDescription)
interaction.message.edit({content:null,embeds:[embed],components:[closeRowNormal]}) interaction.message.edit({content:null,embeds:[embed],components:[closeRowNormal]})
log("system","re-opened a ticket",[{key:"ticket",value:interaction.channel.name},{key:"user",value:interaction.user.tag}]) reopenTicket(interaction.guild,interaction.channel,interaction.user)
var permissionsArray = []
//set everyone allowed
if (config.system['has@everyoneaccess']){
var everyoneAllowPerms = ["ADD_REACTIONS","ATTACH_FILES","EMBED_LINKS","SEND_MESSAGES","VIEW_CHANNEL"]
var everyoneDenyPerms = []
}else{
var everyoneAllowPerms = []
var everyoneDenyPerms = ["VIEW_CHANNEL"]
}
permissionsArray.push({
id:interaction.guild.id,
type:"role",
allow:everyoneAllowPerms,
deny:everyoneDenyPerms
})
interaction.channel.permissionOverwrites.cache.forEach((p) => {
if (p.type == "member"){
permissionsArray.push({
id:p.id,
type:"member",
allow:["ADD_REACTIONS","ATTACH_FILES","EMBED_LINKS","SEND_MESSAGES","VIEW_CHANNEL"],
deny:[]
})
}
})
interaction.channel.permissionOverwrites.set(permissionsArray)
//getID & send DM
interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return false
const id = firstmsg.embeds[0].author.name
if (!id) return false
try{
if (config.system.enable_DM_Messages){
interaction.member.send({embeds:[bot.errorLog.custom(l.messages.reopenTicketDmTitle,l.messages.reopenTicketDmDescription,":ticket:",config.main_color)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
})
}) })
} }
Regular → Executable
+6 -4
View File
@@ -39,11 +39,13 @@ const getUserInfo = (channel) => {
* *
* @param {discord.Message[]} messagecollection * @param {discord.Message[]} messagecollection
* @param {discord.Channel} channel * @param {discord.Channel} channel
* @returns new `discord.messageAttachment` * @returns new `discord.attachmentBuilder`
*/ */
exports.createTranscript = async (messagecollection,channel) => { exports.createTranscript = async (messagecollection,channel) => {
const ticketuserdata = await getUserInfo(channel) const ticketuserdata = await getUserInfo(channel)
require("./api/modules/events").onTranscriptCreation(messagecollection,channel,channel.guild,new Date())
try { try {
const cd = new Date() const cd = new Date()
const months = ["January","February","March","April","May","June","July","August","September","October","November","December"] const months = ["January","February","March","April","May","June","July","August","September","October","November","December"]
@@ -57,14 +59,14 @@ exports.createTranscript = async (messagecollection,channel) => {
if (msg.content){var content = msg.content}else{var content = "*empty message*"} if (msg.content){var content = msg.content}else{var content = "*empty message*"}
const msgstats = "files: "+msg.attachments.size+" | embeds: "+msg.embeds.length+" | isbot: "+msg.author.bot const msgstats = "files: "+msg.attachments.size+", embeds: "+msg.embeds.length
filearray.push("["+timestamp.getDate()+"/"+timestamp.getMonth()+"/"+timestamp.getFullYear()+" | "+timestamp.getHours()+":"+timestamp.getMinutes()+":"+timestamp.getSeconds()+" | "+msg.author.tag+" ] ["+msgstats+"]\n"+content+"\n") filearray.push("["+timestamp.getDate()+"/"+timestamp.getMonth()+"/"+timestamp.getFullYear()+", "+timestamp.getHours()+":"+timestamp.getMinutes()+":"+timestamp.getSeconds()+"|"+msg.author.tag+"] ["+msgstats+"]\n"+content+"\n")
}) })
if (filearray.length < 2) filearray.push("transcript is empty") if (filearray.length < 2) filearray.push("transcript is empty")
const filestring = filearray.join("\n") const filestring = filearray.join("\n")
const filebuff = Buffer.from(filestring,"utf-8") const filebuff = Buffer.from(filestring,"utf-8")
return new discord.MessageAttachment(filebuff,"transcript_"+ticketuserdata.ticketname+".txt") return new discord.AttachmentBuilder(filebuff,{name:"transcript_"+ticketuserdata.ticketname+".txt",description:"An Open Ticket transcript"})
}catch(err){ }catch(err){
console.log("[error] "+err) console.log("[error] "+err)
return false return false
+3
View File
@@ -0,0 +1,3 @@
/**
* @typedef {String|Boolean} OTErrorType
*/
+12 -11
View File
@@ -6,19 +6,20 @@ const l = bot.language
/**@returns {"DANGER"|"SUCCESS"|"PRIMARY"|"SECONDARY"} */ /**@returns {"DANGER"|"SUCCESS"|"PRIMARY"|"SECONDARY"} */
const getColor = (color) => { const getColor = (color) => {
const b = discord.ButtonStyle
if (color.toLowerCase() == "red"){ if (color.toLowerCase() == "red"){
return "DANGER" return b.Danger
}else if (color.toLowerCase() == "green"){ }else if (color.toLowerCase() == "green"){
return "SUCCESS" return b.Success
}else if (color.toLowerCase() == "blue" || color.toLowerCase() == "blurple"){ }else if (color.toLowerCase() == "blue" || color.toLowerCase() == "blurple"){
return "PRIMARY" return b.Primary
}else if (color.toLowerCase() == "black" || color.toLowerCase() == "gray" || color.toLowerCase() == "grey"){ }else if (color.toLowerCase() == "black" || color.toLowerCase() == "gray" || color.toLowerCase() == "grey"){
return "SECONDARY" return b.Secondary
}else if (color == "DANGER" || color == "SECONDARY" || color == "SUCCESS" || color == "PRIMARY"){ }else if (color == "DANGER" || color == "SECONDARY" || color == "SUCCESS" || color == "PRIMARY"){
return color return color
}else if (color.toLowerCase() == "none" || color.toLowerCase() == "false" || color.toLowerCase() == ""){ }else if (color.toLowerCase() == "none" || color.toLowerCase() == "false" || color.toLowerCase() == ""){
return "SECONDARY" return b.Secondary
}else return "SECONDARY" }else return b.Secondary
} }
const getOption = (id) => { const getOption = (id) => {
@@ -29,13 +30,13 @@ exports.getOption = getOption
/** /**
* *
* @param {String} id * @param {String} id
* @returns {discord.MessageButton|false} * @returns {discord.ButtonBuilder|false}
*/ */
exports.getButton = (id) => { exports.getButton = (id) => {
const option = getOption(id) const option = getOption(id)
if (!option) return false if (!option) return false
if (option.type == "ticket"){ if (option.type == "ticket"){
var button = new discord.MessageButton() var button = new discord.ButtonBuilder()
.setCustomId("newT"+option.id) .setCustomId("newT"+option.id)
.setDisabled(false) .setDisabled(false)
.setStyle(getColor(option.color)) .setStyle(getColor(option.color))
@@ -45,9 +46,9 @@ exports.getButton = (id) => {
if (!option.label && !option.icon){button.setLabel("no label or emoji")} if (!option.label && !option.icon){button.setLabel("no label or emoji")}
}else if (option.type == "website"){ }else if (option.type == "website"){
var button = new discord.MessageButton() var button = new discord.ButtonBuilder()
.setDisabled(false) .setDisabled(false)
.setStyle("LINK") .setStyle(discord.ButtonStyle.Link)
.setURL(option.url) .setURL(option.url)
if (option.label){button.setLabel(option.label)} if (option.label){button.setLabel(option.label)}
@@ -55,7 +56,7 @@ exports.getButton = (id) => {
if (!option.label && !option.icon){button.setLabel("no label or emoji")} if (!option.label && !option.icon){button.setLabel("no label or emoji")}
}else if (option.type == "role"){ }else if (option.type == "role"){
var button = new discord.MessageButton() var button = new discord.ButtonBuilder()
.setCustomId("newR"+option.id) .setCustomId("newR"+option.id)
.setDisabled(false) .setDisabled(false)
.setStyle(getColor(option.color)) .setStyle(getColor(option.color))
+76
View File
@@ -0,0 +1,76 @@
const discord = require('discord.js')
const bot = require('../../index')
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const l = bot.language
const storage = bot.storage
/**
*
* @param {String} memberid
* @param {String} guildid
* @returns {Boolean} has permissions?
*/
exports.command = (memberid,guildid) => {
const permsmember = client.guilds.cache.find(g => g.id == guildid).members.cache.find(m => m.id == memberid)
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("Administrator") && !permsmember.permissions.has("ManageGuild")){
return false
}else {return true}
}
/**
*
* @param {discord.User} user
* @returns {Boolean}
*/
exports.sendUserNoPerms = (user) => {
try {
user.send({embeds:[bot.errorLog.noPermsMessage]})
return true
}catch{
return false
}
}
/**
*
* @param {discord.User} user
* @returns {Boolean}
*/
exports.sendUserNoTicket = (user) => {
try {
user.send({embeds:[bot.errorLog.notInATicket]})
return true
}catch{
return false
}
}
/**
*
* @param {discord.TextChannel} channel
* @returns {Boolean}
*/
exports.sendChannelNoPerms = (channel) => {
try {
channel.send({embeds:[bot.errorLog.noPermsMessage]})
return true
}catch{
return false
}
}
/**
*
* @param {discord.TextChannel} channel
* @returns {Boolean}
*/
exports.sendChannelNoTicket = (channel) => {
try {
channel.send({embeds:[bot.errorLog.notInATicket]})
return true
}catch{
return false
}
}
+44 -5
View File
@@ -12,8 +12,18 @@
const discord = require('discord.js') const discord = require('discord.js')
const fs = require('fs') const fs = require('fs')
const intents = discord.Intents const {GatewayIntentBits,Partials} = discord
const client = new discord.Client({intents:[intents.FLAGS.GUILDS,intents.FLAGS.GUILD_MESSAGES,intents.FLAGS.GUILD_MEMBERS],partials:["CHANNEL"]}) const client = new discord.Client({
intents:[
GatewayIntentBits.DirectMessages,
GatewayIntentBits.GuildInvites,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.Guilds,
GatewayIntentBits.MessageContent
],
partials:[Partials.Channel,Partials.Message]
})
exports.client = client exports.client = client
client.setMaxListeners(30) client.setMaxListeners(30)
@@ -42,6 +52,20 @@ exports.errorLog = require("./core/errorLogSystem")
const log = this.errorLog.log const log = this.errorLog.log
client.on('ready',async () => { client.on('ready',async () => {
var statusSet = false
const setStatus = (type,text) => {
if (statusSet == true) return
const getTypeEnum = (text) => {
if (text.toLowerCase() == "playing") return discord.ActivityType.Playing
else if (text.toLowerCase() == "listening") return discord.ActivityType.Listening
else if (text.toLowerCase() == "watching") return discord.ActivityType.Watching
else return discord.ActivityType.Listening
}
client.user.setActivity(text,{type:getTypeEnum(type)})
statusSet = true
log("system","loaded status",[{key:"type",value:type},{key:"text",value:text}])
}
const chalk = await (await import("chalk")).default const chalk = await (await import("chalk")).default
if (!process.argv[2]){ if (!process.argv[2]){
@@ -50,7 +74,7 @@ client.on('ready',async () => {
console.log(chalk.blue("\n\nlogs:")+"\n============") console.log(chalk.blue("\n\nlogs:")+"\n============")
if (config.status.enabled){ if (config.status.enabled){
client.user.setActivity(config.status.text,{type:config.status.type}) setStatus(config.status.type,config.status.text)
} }
log("system","bot logged in!") log("system","bot logged in!")
@@ -59,13 +83,19 @@ client.on('ready',async () => {
return return
} }
if (process.argv[2] == "d"){
if (config.status.enabled){
setStatus(config.status.type,config.status.text)
}
}
if (!process.argv[2].startsWith("slash")){ if (!process.argv[2].startsWith("slash")){
console.log(chalk.red("WELCOME TO OPEN TICKET!")) console.log(chalk.red("WELCOME TO OPEN TICKET!"))
log("info","open ticket ready",[{key:"version",value:require("./package.json").version},{key:"language",value:config.languagefile}]) log("info","open ticket ready",[{key:"version",value:require("./package.json").version},{key:"language",value:config.languagefile}])
console.log(chalk.blue("\n\nlogs:")+"\n============") console.log(chalk.blue("\n\nlogs:")+"\n============")
if (config.status.enabled){ if (config.status.enabled){
client.user.setActivity(config.status.text,{type:config.status.type}) setStatus(config.status.type,config.status.text)
} }
log("system","bot logged in!") log("system","bot logged in!")
@@ -87,13 +117,18 @@ client.on('ready',async () => {
process.exit(1) process.exit(1)
} }
} }
//load plugins
require("./core/api/pluginlauncher")()
}) })
if (!isDev){ if (!isDev){
require("./core/checker").checker() require("./core/checker").checker()
} }
if (process.argv[2] && !process.argv[2].startsWith("slash")){ if (process.argv[2] && process.argv[2].startsWith("slash")){
//do nothing
}else{
var storage = require('./core/dynamicdatabase/storage') var storage = require('./core/dynamicdatabase/storage')
exports.storage = storage exports.storage = storage
@@ -116,6 +151,8 @@ if (process.argv[2] && !process.argv[2].startsWith("slash")){
} }
const APIEvents = require("./core/api/modules/events")
const debugLog = (debugString) => { const debugLog = (debugString) => {
const content = fs.existsSync("./openticketdebug.txt") ? fs.readFileSync("./openticketdebug.txt").toString() : "==========================\n<OPEN TICKET DEBUG FILE:>\n==========================" const content = fs.existsSync("./openticketdebug.txt") ? fs.readFileSync("./openticketdebug.txt").toString() : "==========================\n<OPEN TICKET DEBUG FILE:>\n=========================="
fs.writeFileSync("./openticketdebug.txt",content+"\nDEBUG: "+debugString) fs.writeFileSync("./openticketdebug.txt",content+"\nDEBUG: "+debugString)
@@ -137,6 +174,8 @@ process.on("uncaughtException",async (error,origin) => {
const chalk = await (await import("chalk")).default const chalk = await (await import("chalk")).default
console.log(chalk.red("\nOPEN TICKET ERROR: ")+error+"\n"+chalk.green("\nCreate a ticket in our support server for more information!\nIf you do this, you might help us to avoid a future bug!\n")) console.log(chalk.red("\nOPEN TICKET ERROR: ")+error+"\n"+chalk.green("\nCreate a ticket in our support server for more information!\nIf you do this, you might help us to avoid a future bug!\n"))
errorLog(error.name+": "+error.message+" | origin: "+origin,error.stack) errorLog(error.name+": "+error.message+" | origin: "+origin,error.stack)
APIEvents.onError(error.name+": "+error.message,new Date())
}) })
client.login(config.auth_token) client.login(config.auth_token)
+80
View File
@@ -0,0 +1,80 @@
{
"errors":{
"missingArgsTitle":"حجج باطلة",
"missingArgsDescription":"حجة مفقودة",
"noPermsTitle":"ليس لديك إذن",
"noPermsDescription":"ليس لديك إذن لاستخدام هذا\nأنت بحاجة إلى إذن 'ADMINISTRATOR' أو أن تكون في قائمة الأدوار المسموح بها!",
"chooseFromListTitle":"بطاقة التعريف غير صالحة",
"chooseFromListDescription":"اختر أحد المعرفات أدناه:",
"boterror":"مشكلة في الروبوت",
"notInTicketTitle":"أنت لست في تذكرة!",
"notInTicketDescription":"هذا الأمر لا يعمل خارج التذاكر!",
"ticketDoesntExist":"هذه التذكرة لم تعد موجودة!",
"roleDoesntExist":"هذا الدور لم يعد موجودًا!",
"anotherOption":"هذا الخيار ليس تذكرة بل نوع آخر!",
"maxAmountTitle":"بلغ الحد الأقصى!",
"maxAmountDescription":"لقد وصلت إلى الحد الأقصى لعدد التذاكر المسموح بها!\nلذلك لا يمكنك إنشاء واحدة جديدة!",
"somethingWentWrong":"**هناك خطأ ما!**\nالرجاء المحاولة مرة أخرى!",
"somethingWentWrongTranscript":"**حدث خطأ ما أثناء كتابة النص!**\nالرجاء المحاولة مرة أخرى!"
},
"commands":{
"userAddedTitle":"تمت إضافة المستخدم!",
"userAddedDescription":"{0} يضاف إلى هذه التذكرة!",
"userRemovedTitle":"تمت إزالة المستخدم!",
"userRemovedDescription":"{0} تمت إزالته من هذه التذكرة!",
"renameTitle":"تم تغيير الاسم!",
"renameWarning":"تحذير: يمكنك فقط تغيير اسم القناة مرتين في الدقيقة!\n(هذا يرجع إلى حدود معدل الخلاف)",
"closeTitle":"أغلق هذه التذكرة!",
"closeDescription":"يمكنك إغلاق هذه التذكرة بالضغط على الزر أدناه!",
"deleteTitle":"احذف هذه التذكرة!",
"deleteDescription":"يمكنك حذف هذه التذكرة بالضغط على الزر أدناه!",
"reopenTitle":"أعد فتح هذه التذكرة!",
"reopenDescription":"يمكنك إعادة فتح هذه التذكرة بالضغط على الزر أدناه!",
"ticketWarning":"التضمين في الرسالة أدناه!",
"maxTicketWarning":"**تحذير:** _يمكنك فقط إنشاء ملفات {0} تذكرة في كل مرة!_"
},
"helpMenu":{
"title":"قائمة التعليمات:",
"header1":"**اذهب إلى {0} لإنشاء تذكرة!**\n\n",
"header2":"**قم بتشغيل الأمر `/new` أو `/ticket` لإنشاء تذكرة!**\n\n",
"msgCmd":"تفرخ تضمين مع الأزرار. (المسؤولون فقط)",
"renameCmd":"إعادة تسمية تذكرة. (بدون مسافات)",
"closeCmd":"أغلق التذكرة.",
"deleteCmd":"حذف التذكرة.",
"addCmd":"أضف مستخدمًا إلى التذكرة.",
"removeCmd":"إزالة مستخدم من التذكرة.",
"reopenCmd":"أعد فتح التذكرة بعد إغلاقه."
},
"buttons":{
"close":"إغلاق التذكرة",
"delete":"حذف التذكرة",
"reopen":"إعادة فتح التذكرة",
"sendTranscript":"إرسال ملف النص"
},
"messages":{
"reopenTitle":"أعيد فتح هذه التذكرة!",
"reopenDescription":"لا تتردد في التحدث مرة أخرى!",
"closedTitle":"أغلقت هذه التذكرة!",
"closedDescription":"يمكن للمسؤولين فقط التحدث في هذه التذكرة الآن!\n\n*انقر فوق الزر أدناه لحذف هذه التذكرة أو إعادة فتحها!*",
"createdTitle":"تم إنشاء التذكرة!",
"createdDescription":"تم إنشاء تذكرتك ، يمكنك اكتشافها عن طريق ping",
"newTicketDmTitle":"تذكرة جديدة!",
"closedTicketDmTitle":"تم إغلاق التذكرة!",
"deletedTicketDmTitle":"تم حذف التذكرة!",
"closedTicketDmDescription":"تم إغلاق تذكرتك!",
"deletedTicketDmDescription":"تم حذف تذكرتك!",
"reopenTicketDmTitle":"أعيد فتح التذكرة!",
"reopenTicketDmDescription":"تم إعادة فتح تذكرتك!",
"newTranscriptTitle":"نسخة جديدة هنا!",
"newTranscriptDescription":"يمكنك العثور على النص في الملف النصي أعلاه!",
"hereIsTheTranscript":"هذا هو النص:",
"chooseCategory":"اختر فئة:",
"gettingdeleted":"...يتم حذف التذكرة"
}
}
+5 -2
View File
@@ -14,7 +14,7 @@
"anotherOption":"This option is not a ticket but another type!", "anotherOption":"This option is not a ticket but another type!",
"maxAmountTitle":"Max amount reached!", "maxAmountTitle":"Max amount reached!",
"maxAmountDescription":"You reached the maximum number of tickets allowed!\nSo you can't create a new one!", "maxAmountDescription":"You reached the maximum number of tickets allowed!\nSo you can't create a new one!",
"somethingWentWrong":"Something went wrong!**\nPlease try again another time!", "somethingWentWrong":"**Something went wrong!**\nPlease try again another time!",
"somethingWentWrongTranscript":"Something went wrong while making the transcript!**\nPlease try again another time!" "somethingWentWrongTranscript":"Something went wrong while making the transcript!**\nPlease try again another time!"
}, },
"commands":{ "commands":{
@@ -68,10 +68,13 @@
"deletedTicketDmTitle":"Ticket Deleted!", "deletedTicketDmTitle":"Ticket Deleted!",
"closedTicketDmDescription":"Your ticket is closed!", "closedTicketDmDescription":"Your ticket is closed!",
"deletedTicketDmDescription":"Your ticket is deleted!", "deletedTicketDmDescription":"Your ticket is deleted!",
"reopenTicketDmTitle":"Ticket Re-opened!",
"reopenTicketDmDescription":"Your ticket is re-opened!",
"newTranscriptTitle":"A new transcript is here!", "newTranscriptTitle":"A new transcript is here!",
"newTranscriptDescription":"You can find the transcript in the text file above!", "newTranscriptDescription":"You can find the transcript in the text file above!",
"hereIsTheTranscript":"Here is the transcript:", "hereIsTheTranscript":"Here is the transcript:",
"chooseCategory":"choose a category:" "chooseCategory":"choose a category:",
"gettingdeleted":"Ticket is getting deleted..."
} }
} }
+79
View File
@@ -0,0 +1,79 @@
{
"errors":{
"missingArgsTitle":"Neplatné argumenty",
"missingArgsDescription":"Chybí argumenty",
"noPermsTitle":"Nemáš práva!",
"noPermsDescription":"Nemáš dostatečné práva na tento příkaz!\n Potřebuješ ADMINISTRATOR aby jsi mohl provést příkaz!",
"chooseFromListTitle":"Neplatné ID",
"chooseFromListDescription":"Vyber si z těchto ID:",
"boterror":"Error!",
"notInTicketTitle":"Nejsi v ticketu!",
"notInTicketDescription":"Tento příkaz nefunguje mimo tickety!",
"ticketDoesntExist":"Tento ticket už bohužel neexistuje!",
"roleDoesntExist":"Tato role bohužel neexistuje!",
"anotherOption":"Tato možnost není ticket ale něco jiného!",
"maxAmountTitle":"Maximální počet ticketů dosažen!",
"maxAmountDescription":"Dosáhl jsi maximálního povoleného počtu ticketů!\n Nemůžeš si vytvořit nový!",
"somethingWentWrong":"**Něco je špatně**\nProsím zkus to příště znovu!",
"somethingWentWrongTranscript":"Něco je špatně s transcriptem!**\nProsím zkus to příště znovu!"
},
"commands":{
"userAddedTitle":"Uživatel přidán!",
"userAddedDescription":"{0} je přidán do ticketu!",
"userRemovedTitle":"Uživatel odebrán!",
"userRemovedDescription":"{0} je odstraněn z ticketu!",
"renameTitle":"Jméno bylo změněno!",
"renameWarning":"Varování: jméno kanálu můžeš změnit pouze 2x za minutu!",
"closeTitle":"Zavři tento ticket!",
"closeDescription":"Můžeš zavřít ticket kliknutím na tlačítko níže!",
"deleteTitle":"Smaž tento ticket!",
"deleteDescription":"Můžeš smazat ticket kliknutím na tlačítko níže!",
"reopenTitle":"Znovu otevři ticket!",
"reopenDescription":"Můžeš znovu otevřít tento ticket kliknutínm na tlačítko níže!",
"ticketWarning":"The embed is in the message below!",
"maxTicketWarning":"**Varovaní:** _Můžeš si vytvořit použe {0} ticket(s) v jednu chvíli!_"
},
"helpMenu":{
"title":"Příkazy:",
"header1":"**Běž {0} vytvořit si ticket!**\n\n",
"header2":"**Použij příkaz `/new` nebo `/ticket` k vytvoření ticketu!**\n\n",
"msgCmd":"Vytvoř možnost otevírat tickety přes tlačítko. (ADMIN)",
"renameCmd":"Přejmenovat ticket. (Žádné mezery)",
"closeCmd":"Zavři ticket.",
"deleteCmd":"Smaž ticket.",
"addCmd":"Přidej člena do ticketu.",
"removeCmd":"Odebere člena z ticketu.",
"reopenCmd":"Znovu otevři ticket po uzavření."
},
"buttons":{
"close":"Zavři ticket",
"delete":"Smaž ticket",
"reopen":"Znovu otevři ticket",
"sendTranscript":"Odešli log ticketu"
},
"messages":{
"reopenTitle":"Ticket znovu otevřen!",
"reopenDescription":"Cítím se skvěle že si můžeme zase povídat!",
"closedTitle":"Zavřený ticket!",
"closedDescription":"Pouze admin team zde může nyní komunikovat!\n\n*Klikni na tlačítko níže pro smazání nebo znovu otevření ticketu!*",
"createdTitle":"Ticket vytvořen!",
"createdDescription":"Váš tiket je vytvořen, můžete ho zjistit pomocí pingu!",
"newTicketDmTitle":"Nový ticket!",
"closedTicketDmTitle":"Ticket uzavřen!",
"deletedTicketDmTitle":"Ticket smazán!",
"closedTicketDmDescription":"Tvůj ticket byl uzavřen!",
"deletedTicketDmDescription":"Tvůj ticket byl smazán!",
"reopenTicketDmTitle":"Ticket znovu otevřen!",
"reopenTicketDmDescription":"Tvůj ticket byl znovu otevřen!",
"newTranscriptTitle":"Nový log ticketu je zde!",
"newTranscriptDescription":"Zde najdeš log svého ticketu!",
"hereIsTheTranscript":"Zde je log:",
"chooseCategory":"Vyber kategorii:"
}
}
+3 -2
View File
@@ -14,7 +14,7 @@
"anotherOption":"Deze optie is geen ticket maar een ander type!", "anotherOption":"Deze optie is geen ticket maar een ander type!",
"maxAmountTitle":"Max aantal bereikt!", "maxAmountTitle":"Max aantal bereikt!",
"maxAmountDescription":"Je hebt het maximum aantal openstaande ticket bereikt!\nDus je kan er geen nieuwe maken!", "maxAmountDescription":"Je hebt het maximum aantal openstaande ticket bereikt!\nDus je kan er geen nieuwe maken!",
"somethingWentWrong":"Iets ging fout!**\nProbeer een andere keer opnieuw!", "somethingWentWrong":"**Iets ging fout!**\nProbeer een andere keer opnieuw!",
"somethingWentWrongTranscript":"Iets ging fout bij het maken van het transcript!**\nProbeer een andere keer opnieuw!" "somethingWentWrongTranscript":"Iets ging fout bij het maken van het transcript!**\nProbeer een andere keer opnieuw!"
}, },
"commands":{ "commands":{
@@ -74,6 +74,7 @@
"newTranscriptDescription":"Je kan het transcript vinden in het bestand hierboven!", "newTranscriptDescription":"Je kan het transcript vinden in het bestand hierboven!",
"hereIsTheTranscript":"Hier is het transcript:", "hereIsTheTranscript":"Hier is het transcript:",
"chooseCategory":"kies een categorie:" "chooseCategory":"kies een categorie:",
"gettingdeleted":"Ticket wordt verwijderd..."
} }
} }
+3 -2
View File
@@ -14,7 +14,7 @@
"anotherOption":"This option is not a ticket but another type!", "anotherOption":"This option is not a ticket but another type!",
"maxAmountTitle":"Max amount reached!", "maxAmountTitle":"Max amount reached!",
"maxAmountDescription":"You reached the maximum number of tickets allowed!\nSo you can't create a new one!", "maxAmountDescription":"You reached the maximum number of tickets allowed!\nSo you can't create a new one!",
"somethingWentWrong":"Something went wrong!**\nPlease try again another time!", "somethingWentWrong":"**Something went wrong!**\nPlease try again another time!",
"somethingWentWrongTranscript":"Something went wrong while making the transcript!**\nPlease try again another time!" "somethingWentWrongTranscript":"Something went wrong while making the transcript!**\nPlease try again another time!"
}, },
"commands":{ "commands":{
@@ -74,6 +74,7 @@
"newTranscriptDescription":"You can find the transcript in the text file above!", "newTranscriptDescription":"You can find the transcript in the text file above!",
"hereIsTheTranscript":"Here is the transcript:", "hereIsTheTranscript":"Here is the transcript:",
"chooseCategory":"choose a category:" "chooseCategory":"choose a category:",
"gettingdeleted":"Ticket is getting deleted..."
} }
} }
+74
View File
@@ -0,0 +1,74 @@
{
"errors":{
"missingArgsTitle":"Arguments invalides !",
"missingArgsDescription":"Argument manquant",
"noPermsTitle":"Pas de permissions!",
"noPermsDescription":"Vous n'avez pas les bons rôles pour exécuter cette commande !\nVous avez besoin de la permission `ADMINISTRATOR` ou d'être dans la liste des rôles autorisés !",
"chooseFromListTitle":"Invalid ID",
"chooseFromListDescription":"Choisissez l'un des identifiants ci-dessous:",
"boterror":"Bot Error!",
"notInTicketTitle":"Vous n'êtes pas dans un ticket !",
"notInTicketDescription":"Cette commande ne fonctionne pas en dehors des tickets !",
"ticketDoesntExist":"Ce billet n'existe plus !",
"roleDoesntExist":"Ce rôle n'existe plus !",
"anotherOption":"Cette option n'est pas un ticket mais un autre type !",
"maxAmountTitle":"Montant max atteint !",
"maxAmountDescription":"Vous avez atteint le nombre maximum de tickets autorisés !\nVous ne pouvez donc pas en créer un nouveau !",
"somethingWentWrong":"**Une erreur s'est produite !**\nVeuillez réessayer une autre fois !",
"somethingWentWrongTranscript":"Une erreur s'est produite lors de la création de la transcription !**\nVeuillez réessayer une autre fois !"
},
"commands":{
"userAddedTitle":"Utilisateur ajouté !",
"userAddedDescription":"{0} est ajouté à ce billet !",
"userRemovedTitle":"Utilisateur supprimé!",
"userRemovedDescription":"{0} est supprimé de ce ticket!",
"renameTitle":"Le nom est changé !",
"renameWarning":"Attention : vous ne pouvez modifier le nom de la chaîne que 2 fois par minute !\n(ceci est dû aux limites du taux de discorde)",
"closeTitle":"Fermez ce ticket !",
"closeDescription":"Vous pouvez fermer ce ticket en cliquant sur le bouton ci-dessous !",
"deleteTitle":"Supprimez ce billet !",
"deleteDescription":"Vous pouvez supprimer ce ticket en cliquant sur le bouton ci-dessous !",
"reopenTitle":"Ré-ouvrez ce ticket !",
"reopenDescription":"Vous pouvez rouvrir ce ticket en cliquant sur le bouton ci-dessous !",
"ticketWarning":"L'intégration est dans le message ci-dessous !",
"maxTicketWarning":"**Attention :** _Vous ne pouvez créer que {0} billet(s) à la fois !_"
},
"helpMenu":{
"title":"Menu d'aide:",
"header1":"**Allez à {0} pour créer un ticket !**\n\n",
"header2":"**Exécutez la commande `/new` ou `/ticket` pour créer un ticket!**\n\n",
"msgCmd":"Créez une intégration avec des boutons. (administrateurs uniquement)",
"renameCmd":"Renommer un ticket. (sans espaces)",
"closeCmd":"Fermer un ticket.",
"deleteCmd":"Supprimer un billet.",
"addCmd":"Ajouter un utilisateur au ticket.",
"removeCmd":"Supprimer un utilisateur du ticket.",
"reopenCmd":"Re-Open a ticket after it was closed."
},
"buttons":{
"close":"Fermer le ticket",
"delete":"Supprimer le billet",
"reopen":"Billet de réouverture",
"sendTranscript":"Envoyer le fichier de transcription"
},
"messages":{
"reopenTitle":"A rouvert ce ticket!",
"reopenDescription":"N'hésitez pas à reparler!",
"closedTitle":"Fermé ce ticket",
"closedDescription":"Seuls les administrateurs peuvent parler dans ce ticket maintenant !\n\n*Cliquez sur le bouton ci-dessous pour supprimer ou rouvrir ce ticket !*",
"createdTitle":"Ticket créé !",
"createdDescription":"Votre ticket est créé, vous pouvez le détecter par un ping !",
"newTicketDmTitle":"Nouveau ticket!",
"newTranscriptTitle":"Une nouvelle transcription est ici!",
"newTranscriptDescription":"Vous pouvez trouver la transcription dans le fichier texte ci-dessus !",
"hereIsTheTranscript":"Voici la transcription :",
"chooseCategory":"choisissez une catégorie:",
"gettingdeleted":"Le ticket est en cours de suppression..."
}
}
+80
View File
@@ -0,0 +1,80 @@
{
"errors":{
"missingArgsTitle":"Ungültiges Argument!",
"missingArgsDescription":"Fehlendes Argument!",
"noPermsTitle":"Du hast keine Rechte!",
"noPermsDescription":"Sie haben nicht die richtigen Rollen, um diesen Befehl auszuführen!\nSie benötigen die `ADMINISTRATOR` Erlaubnis oder in der Liste der erlaubten Rollen sein!",
"chooseFromListTitle":"Ungültige ID",
"chooseFromListDescription":"Wählen Sie eine der folgenden ID:",
"boterror":"Bot Fehler!",
"notInTicketTitle":"Du bist ein kein Ticket!",
"notInTicketDescription":"Der Befehl funktioniert nicht außerhalb eines Tickets!",
"ticketDoesntExist":"Das Ticket Exisitert nicht mehr!",
"roleDoesntExist":"Die Rolle Exisitiert nicht mehr!",
"anotherOption":"Diese Option ist kein Ticket, sondern eine andere Art!",
"maxAmountTitle":"Das Limit wurde erreicht!",
"maxAmountDescription":"Sie haben die maximal zulässige Anzahl von Tickets erreicht!\nSie können also keine neue erstellen.!",
"somethingWentWrong":"**Etwas ist schief gelaufen!**\nBitte versuchen Sie es ein anderes Mal!",
"somethingWentWrongTranscript":"Bei der Erstellung der Transcript ist etwas schief gelaufen!**\nBitte versuchen Sie es ein anderes Mal!"
},
"commands":{
"userAddedTitle":"User geaddet!",
"userAddedDescription":"{0} wird zu diesem Ticket hinzugefügt!",
"userRemovedTitle":"User entfernt!",
"userRemovedDescription":"{0} wird aus diesem Ticket entfernt!",
"renameTitle":"Der Name wurde geändert!",
"renameWarning":"Achtung: Sie können den Kanalnamen nur 2 Mal pro Minute ändern!\n(dies ist auf die Begrenzung der Diskordrate zurückzuführen)",
"closeTitle":"Dieses Ticket schließen!",
"closeDescription":"Sie können dieses Ticket schließen, indem Sie auf die Schaltfläche unten klicken!",
"deleteTitle":"Löschen Sie dieses Ticket!",
"deleteDescription":"Sie können dieses Ticket löschen, indem Sie auf die Schaltfläche unten klicken!",
"reopenTitle":"Öffne dieses Ticket erneut!",
"reopenDescription":"Sie können dieses Ticket erneut öffnen, indem Sie auf die Schaltfläche unten klicken!",
"ticketWarning":"Die Einbettung befindet sich in der Nachricht unten!",
"maxTicketWarning":"**Warnung:** _Sie können nur {0} ticket(s) erstellen zu einer Zeit!_"
},
"helpMenu":{
"title":"Hilfe Menu:",
"header1":"**Gehe zu {0} um ein Ticket zu erstellen!**\n\n",
"header2":"**Führen Sie den Befehl `/new` oder `/ticket` um ein Ticket zu erstellen!**\n\n",
"msgCmd":"Eine Einbettung mit Schaltflächen erzeugen. (nur admins)",
"renameCmd":"Ein Ticket umbenennen. (keine Leerzeichen)",
"closeCmd":"Schließen Sie ein Ticket.",
"deleteCmd":"Ein Ticket löschen.",
"addCmd":"Fügen Sie dem Ticket einen Benutzer hinzu.",
"removeCmd":"Entfernen eines Benutzers aus dem Ticket.",
"reopenCmd":"Öffnen Sie ein Ticket erneut, nachdem es geschlossen wurde."
},
"buttons":{
"close":"Ticket schließen",
"delete":"Ticket löschen",
"reopen":"Ticket wieder öffnen",
"sendTranscript":"Transcript-Datei senden"
},
"messages":{
"reopenTitle":"Dieses Ticket wiedereröffnet!",
"reopenDescription":"Sie können gerne weiterreden!",
"closedTitle":"Dieses Ticket geschlossen!",
"closedDescription":"Nur Admins können jetzt in diesem Ticket sprechen!\n\n*Klicken Sie auf die Schaltfläche unten, um dieses Ticket zu löschen oder erneut zu öffnen!*",
"createdTitle":"Ticket erstellt!",
"createdDescription":"Ihr Ticket ist erstellt, Sie können es durch einen Ping erkennen!",
"newTicketDmTitle":"Neues Ticket!",
"closedTicketDmTitle":"Ticket schließen!",
"deletedTicketDmTitle":"Ticket löschen!",
"closedTicketDmDescription":"Ihr Ticket ist geschlossen!",
"deletedTicketDmDescription":"Ihr Ticket ist gelöscht!",
"reopenTicketDmTitle":"Ticket neu Eröffnen!",
"reopenTicketDmDescription":"Dein Ticket ist Neu eröffnet!",
"newTranscriptTitle":"Eine neue Transscript finden Sie hier!",
"newTranscriptDescription":"Die Abschrift finden Sie in der obigen Textdatei!",
"hereIsTheTranscript":"Hier ist das Transscript:",
"chooseCategory":"Wähle eine Kategorie:",
"gettingdeleted":"Ticket wird gelöscht..."
}
}
+2 -1
View File
@@ -74,6 +74,7 @@
"newTranscriptDescription":"Poti vedea copia ticket-ului in fisierul .txt de mai sus!", "newTranscriptDescription":"Poti vedea copia ticket-ului in fisierul .txt de mai sus!",
"hereIsTheTranscript":"Aceasta este copia ticket-ului:", "hereIsTheTranscript":"Aceasta este copia ticket-ului:",
"chooseCategory":"Alege o categorie:" "chooseCategory":"Alege o categorie:",
"gettingdeleted":"Ticket-ul se sterge..."
} }
} }
+80
View File
@@ -0,0 +1,80 @@
{
"errors":{
"missingArgsTitle":"¡Argumentos inválidos!",
"missingArgsDescription":"Argumento faltante.",
"noPermsTitle":"¡Sin permisos!",
"noPermsDescription":"¡No tienes permiso para usar este comando.!\n¡Necesitas el permiso `ADMINISTRATOR` permiso o tener uno de los roles permitidos!",
"chooseFromListTitle":"ID Invalida",
"chooseFromListDescription":"Elije una de las ID de abajo:",
"boterror":"¡Error del bot!",
"notInTicketTitle":"¡No te encuentras en un ticket!",
"notInTicketDescription":"¡Este comando no funciona fuera de los tickets!",
"ticketDoesntExist":"¡Este ticket no existe!",
"roleDoesntExist":"¡Este rol no existe!",
"anotherOption":"¡Esta opción no es un ticket, si no otra cosa!",
"maxAmountTitle":"¡Máxima cantidad alcanzada!",
"maxAmountDescription":"¡Has alcanzado la máxima cantidad de tickets permitida!\n¡Por lo que no puedes crear otro!",
"somethingWentWrong":"**¡Algo salió mal!**\n¡Prueba dentro de un rato!",
"somethingWentWrongTranscript":"**¡Algo salió mal al hacer el transcript!**\n¡Prueba en otro momento!"
},
"commands":{
"userAddedTitle":"¡Usuario agregado!",
"userAddedDescription":"¡{0} fué agregado al ticket!",
"userRemovedTitle":"¡Usuario eliminado!",
"userRemovedDescription":"¡{0} fué eliminado del ticket!",
"renameTitle":"¡El nombre fué cambiado!",
"renameWarning":"Aviso: Solo puedes cambiar el nombre 2 veces por minuto.\n(Esto es por limitaciones de Discord)",
"closeTitle":"¡Cierra el ticket!",
"closeDescription":"¡Puedes cerrar el ticket con el botón de abajo!",
"deleteTitle":"¡Elimina el ticket!",
"deleteDescription":"¡Puedes eliminar el ticket con el botón de abajo!",
"reopenTitle":"¡Re-Abre el ticket!",
"reopenDescription":"¡Puedes re-abrir el ticket con el botón de abajo!",
"ticketWarning":"¡El emblema está en el mensaje de abajo!",
"maxTicketWarning":"**Aviso:** _Solo puedes poseer {0} ticket(s) al mismo tiempo!_"
},
"helpMenu":{
"title":"Menú de ayuda:",
"header1":"**¡Dirígete a {0} para crear un nuevo ticket!**\n\n",
"header2":"**¡Ejecuta el comando `/new` o `/ticket` para crear un ticket!**\n\n",
"msgCmd":"Generar un embed con botones. (Solo admins)",
"renameCmd":"Renombrar un ticket. (Sin espacios)",
"closeCmd":"Cerrar un ticket.",
"deleteCmd":"Eliminar un ticket.",
"addCmd":"Agregar un usuario al ticket.",
"removeCmd":"Eliminar un usuario del ticket.",
"reopenCmd":"Re-Abre un ticket después de que este se vea cerrado."
},
"buttons":{
"close":"Cerrar ticket.",
"delete":"Eliminar ticket",
"reopen":"Re-Abrir ticket",
"sendTranscript":"Obtener transcript."
},
"messages":{
"reopenTitle":"¡Ticket Re-Abierto!",
"reopenDescription":"¡Siéntete libre de hablar de nuevo!",
"closedTitle":"¡Ticket cerrado!",
"closedDescription":"¡Solo admins pueden hablar ahora en este ticket!\n\n*¡Presiona en el botón de abajo para eliminar o re-abrir el ticket!*",
"createdTitle":"¡Ticket creado!",
"createdDescription":"¡Ticket creado, también te he mencionado en él!",
"newTicketDmTitle":"¡Nuevo ticket!",
"closedTicketDmTitle":"¡Ticket cerrado!",
"deletedTicketDmTitle":"¡Ticket eliminado!",
"closedTicketDmDescription":"¡Tu ticket fué cerrado!",
"deletedTicketDmDescription":"¡Tu ticket fué eliminado!",
"reopenTicketDmTitle":"¡Ticket re-abierto!",
"reopenTicketDmDescription":"¡Tu ticket se vió abierto de nuevo!",
"newTranscriptTitle":"¡Un nuevo transcript está aquí!",
"newTranscriptDescription":"¡Puedes encontrar el transcript en el archivo de texto que se muestra arriba!",
"hereIsTheTranscript":"Aquí está el transcript:",
"chooseCategory":"elije una categoría:",
"gettingdeleted":"El ticket se está viendo eliminado..."
}
}
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 KiB

+4 -3
View File
@@ -1,11 +1,11 @@
{ {
"name": "open-ticket", "name": "open-ticket",
"version": "2.1.1", "version": "2.4.0",
"description": "This is an open-source discord ticket bot, you can configure it and it comes with cool features like a transcript.", "description": "This is an open-source discord ticket bot, you can configure it and it comes with cool features like a transcript.",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"start": "node index.js", "start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1", "test": "node index.js d",
"slashEnable": "node index.js slash enable", "slashEnable": "node index.js slash enable",
"slashDisable": "node index.js slash disable", "slashDisable": "node index.js slash disable",
"cleardata": "node ./core/dynamicdatabase/cleardata.js" "cleardata": "node ./core/dynamicdatabase/cleardata.js"
@@ -13,8 +13,9 @@
"author": "DJdj Development", "author": "DJdj Development",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"axios": "^0.27.2",
"chalk": "^5.0.1", "chalk": "^5.0.1",
"discord.js": "^13.8.0", "discord.js": "^14.0.2",
"express": "^4.17.1", "express": "^4.17.1",
"node": "^16.10.0", "node": "^16.10.0",
"node-localstorage": "^2.2.1" "node-localstorage": "^2.2.1"
+22
View File
@@ -0,0 +1,22 @@
const discord = require("discord.js")
const api = require("../core/api/api.js")
module.exports = () => {
const {client,config,events,utils,actions} = api
//this code will run when the bot starts!
//in this example, we will say "hello" in the console when someone opens a ticket!
/**
events.onTicketOpen((user,channel,guild,date,ticketdata) => {
console.log("hello, someone opened a ticket!")
})
*/
}