Compare commits

...
59 Commits
Author SHA1 Message Date
Jasper 59e756210e Merge pull request #12 from DJj123dj/dev
Open Ticket v2.1.0 Pull Request
2022-06-27 09:32:27 +02:00
DJj123dj a8bb210eca added large text for the fun! 2022-06-27 09:23:16 +02:00
DJj123dj e3ee51d9fb last push 2022-06-26 20:42:21 +02:00
DJj123dj a6e107c12a almost the last push for v2.1.0 2022-06-26 20:25:33 +02:00
DJj123dj a49b53e2d6 added something sneaky 😉 2022-06-24 11:55:46 +02:00
DJj123dj 0bbde2018c every file now supports translation & the languages "custom & dutch" are added
v2.1.0 push 9
2022-06-23 19:59:35 +02:00
DJj123dj 15825d0da6 most of the files now support translation
v2.1.0 push 8
2022-06-23 16:07:49 +02:00
DJj123dj 9d19c7053b v2.1.0 push 7
Added LanguageManager.js (yep this is for language stuff in the future)
2022-06-21 12:11:09 +02:00
DJj123dj 09f9944cf7 v2.1.0 push 6
Added english.json
2022-06-15 18:29:50 +02:00
DJj123dj 6cd6799712 Update .DS_Store 2022-06-13 22:21:16 +02:00
DJj123dj 44515fc6b4 Update index.js 2022-06-13 21:06:53 +02:00
DJj123dj 4c947b138f v2.1.0 push 5 2022-06-09 21:36:33 +02:00
DJj123dj 428f4a9e92 Update ticketReopener.js 2022-06-09 20:45:08 +02:00
DJj123dj a274576589 v2.1.0 push 4
Added re-open mechanics
2022-06-09 20:43:41 +02:00
DJj123dj 2410743a46 Update .gitignore 2022-06-09 20:24:29 +02:00
DJj123dj 89a44f3f2f v2.1.0 push 3 2022-06-09 20:23:34 +02:00
DJj123dj 1728c3653a v2.1.0 push 2 2022-06-08 18:07:42 +02:00
DJj123dj 62a1f0f8c1 v2.1.0 push 1
changed some things
2022-06-08 17:13:53 +02:00
Jasper 8875c9ff01 Merge pull request #8 from DJj123dj/dev
Update README.md
2022-05-07 17:00:47 +02:00
DJj123dj 9b378caff5 Update README.md 2022-05-07 17:00:26 +02:00
Jasper 821a49cb0b Merge pull request #7 from DJj123dj/dev
Update README.md
2022-05-07 16:59:54 +02:00
DJj123dj ebacb92b99 Update README.md 2022-05-07 16:58:58 +02:00
Jasper e1eb3f252b Merge pull request #6 from DJj123dj/dev
Dev to Main (version 2.0)
2022-05-07 14:31:13 +02:00
Jasper 49405b848e Merge branch 'main' into dev 2022-05-07 14:30:53 +02:00
DJj123dj 5dcd36d290 the final push 2022-05-07 14:25:01 +02:00
DJj123dj d00a26a1e0 added reactionRoles & changed links to wiki
The reaction roles work now!
2022-05-06 17:27:04 +02:00
DJj123dj 8c9eddd4a1 added dynamic database & everything is now v2.0.0
Changed everything from v1.4.0 to v2.0.0 & added the dynamic database system
2022-05-05 17:52:42 +02:00
DJj123dj 046cef0088 updated the button system for new types of buttons
You can now also create "website" & "role" tickets. more on these types in the following updates
2022-05-04 20:02:51 +02:00
DJj123dj 0f143c7ebb deleted the old commands 2022-05-04 19:02:59 +02:00
Jasper 4cc12eb727 Delete .DS_Store 2022-05-04 19:02:20 +02:00
DJj123dj e3e5c04096 added the "add" & "remove" commands 2022-05-04 18:42:33 +02:00
DJj123dj eddbcf9acd Update TEMPDOCS.md 2022-05-04 18:11:11 +02:00
DJj123dj 3c2f39df9c Update README.md 2022-05-04 18:08:09 +02:00
Jasper ca4532931b Update README.md 2022-05-04 18:07:23 +02:00
DJj123dj 14ad1f48f3 test discord webhook 2022-05-04 18:03:35 +02:00
DJj123dj fa8741aef8 test discord webhook 2022-05-04 18:00:40 +02:00
DJj123dj 130fd98d0c bug fix
fixed not starting up because of a temporary config file
2022-05-04 15:26:40 +02:00
DJj123dj a9770ec66c Update slashEnable.js 2022-05-02 15:02:27 +02:00
DJj123dj f163769de4 updated cleardatabase with chalk 2022-05-02 14:54:52 +02:00
DJj123dj 07de112f32 added some new commands
- rename
- close
- delete
2022-05-02 12:41:15 +02:00
DJj123dj 8e7a98b810 created cleardatabase system 2022-05-02 11:35:41 +02:00
DJj123dj 92c1e8fce0 Update .gitignore 2022-05-02 11:21:45 +02:00
DJj123dj 4e73626072 created devConfig.json 2022-05-02 11:20:04 +02:00
DJj123dj 943e7b6fef removed token :) 2022-05-02 11:13:18 +02:00
DJj123dj af8d6351af 1.4.0 beta 2022-05-02 11:07:56 +02:00
DJj123dj 5fc3ba3279 Update checker.js 2022-04-02 17:03:13 +02:00
DJj123dj 6df23d84bc v1.3.2
This is the first stable version of open-ticket 1.3
2022-04-02 16:38:00 +02:00
DJj123dj 8cab4cc686 v1.3.1
Bug fixes
2022-03-31 18:38:49 +02:00
DJj123dj 21e3a88b87 v1.3.0
Changes in changelog
2022-03-30 17:09:55 +02:00
DJj123dj 1451769ebf Update README.md 2022-03-24 11:40:28 +01:00
DJj123dj da3017ff95 Update README.md 2022-03-24 11:40:01 +01:00
DJj123dj 43186c8a0e Update README.md 2022-03-24 11:37:44 +01:00
DJj123dj 63632e3a66 added new stuff to readme file 2022-03-23 20:45:33 +01:00
DJj123dj 8981c9e60e v1.2.2
some bugs fixed!
2022-03-04 10:20:47 +01:00
DJj123dj 4a90a2d19a v1.2.1
- added the option to remove credits
- fixed the bug where ticket_system crashes the bot
- in the help menu is now the correct prefix displayed
2022-02-20 09:20:26 +01:00
DJj123dj 49b71ecdc6 Merge branch 'main' of https://github.com/DJj123dj/open-ticket 2021-12-07 18:19:22 +01:00
DJj123dj af1c3288c0 Version 1.2.0
Many changes! :D
2021-12-07 18:19:07 +01:00
Jasper 7d89ac713b Delete .DS_Store 2021-12-01 15:31:31 +01:00
DJj123dj 1fb8ece6ff v1.1.2
Fixed: Status can be "playing highmt", this is now fixed. you can also choose status now
2021-11-20 13:32:50 +01:00
42 changed files with 3332 additions and 539 deletions
Vendored
BIN
View File
Binary file not shown.
+13
View File
@@ -0,0 +1,13 @@
node_modules/
package-lock.json
devConfig.json
devConfig1.json
devConfig2.json
devConfig3.json
devConfig4.json
devConfig5.json
.DS_Store
openticketdebug.txt
developerChangelog.md
storage/dynamicDB/
storage/.DS_Store
+42 -42
View File
@@ -1,65 +1,65 @@
# open-ticket ### large announcement:
This is an open-source discord ticket bot, you can configure it and it comes with cool features like a transcript. [![open moderation](./openmod.png)](https://www.dj-dj.be/projects/open-moderation)
(WARNING: the bot's language is Dutch, there will be an English version soon!) # 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.0%20stable-brightgreen.svg?style=flat-square)](https://github.com/DJj123dj/open-ticket/releases/tag/v2.1.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!
<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)
## features ## features
- discord interaction buttons - discord buttons
- transcripts - slash & text commands
- add/remove users from ticket - close, delete & re-open tickets
- custom colors & name - translation (we are searching for translators!)
- has tickets for questions, partners & job applications - dynamic database system
- advanced transcripts
- add/remove users from a ticket
- large embed customisation
- create custom ticket names, icons & colors
- create url's & reaction roles!
- uses discord.js v13
- configure your own ticket options
- remove credits if you want (don't do it please 😉)
- unlimited tickets at the same time
## installation ## installation
You need `node.js 16` to run this project, if you don't want to install `node.js 16` then there is a npm package that can help you. **You need `node.js 16` to run this project!**
You can clone this project for download. You can clone or download this project.
### packages ### packages
- canvas => version `^2.8.0` - chalk => version `latest`
- discord.js => version `^13.2.0` - discord.js => version `latest`
- express => version `^4.17.1` - express => version `latest`
- node-localstorage => version `^2.2.1` - node-localstorage => version `latest`
The packages are also in package.json! You can install all of them by running `npm install`
### node.js 16 package
if you don't want to install `node.js 16`, you can install this package too
- node => version ^16.10.0
_npm install node@16_
## 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. if there are any errors, you can open an **issue on github** or **contact me in the discord server**.
### config (required) ### config
- `server_name` => the name from your server. Our config documentation is moved to another file:
- `server_logo`=> the logo from your server. [click here to view](https://www.github.com/DJj123dj/open-ticket/wiki/config-v2.1.0)
- `bot_name`=> the bot's name.
- `main_color`=> the color used in all embeds.
- `auth_token`=> the bot's token (Discord Developer Portal)
- `botperms_role`=> the id from a role that can run admin commands with the bot.
- `prefix`=> the bot's prefix.
- `ticket_system/ticket_channel` => the channel where you are gonna put the !ticket msg.
- `ticket_system/ticket_category` => the category for tickets.
- `ticket_system/member_role` => this role doesn't have access to tickets
(WARNING: @everyone does have access to tickets, so make sure all members have a member role!).
- `ticket_system/transcript_channel` => the channel for transcripts.
- `ticket_system/enable_transcripts` => enable transcripts.
- `ticket_system/enable_category` => enable tickets in category.
### 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
- `SERVER MEMBERS INTENT` - `SERVER MEMBERS INTENT`
- `MESSAGE CONTENT INTENT` - `MESSAGE CONTENT INTENT`
The bot needs `ADMINISTRATOR` permissions to work the best. To work the best, the bot needs `ADMINISTRATOR` permissions.
You can also configure your own permissions
## credits ## information
the package contains a license, there are also credits in the bot. It is forbidden to extract these licenses and credits from it!
_v1.1.1_ _v2.1.0 unstable_
© 2021 - DJdj Development | [website](https://www.dj-dj.be) | [discord](https://discord.com/invite/26vT9wt3n3) 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)
+60
View File
@@ -0,0 +1,60 @@
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
module.exports = () => {
client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix+"add")) return
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 (!msg.member.permissions.has("MANAGE_CHANNELS") && !msg.member.permissions.has("ADMINISTRATOR") && config.main_adminroles.some((item)=>{return msg.member.roles.cache.has(item)}) == false){
return msg.channel.send({embeds:[bot.errorLog.noPermsMessage]})
}
msg.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
msg.channel.permissionOverwrites.create(user.id, { VIEW_CHANNEL:true, ADD_REACTIONS:true,ATTACH_FILES:true, EMBED_LINKS:true, SEND_MESSAGES:true})
msg.channel.send({embeds:[bot.errorLog.success(l.commands.userAddedTitle,l.commands.userAddedDescription.replace("{0}",user.tag))]})
var loguser = msg.mentions.users.first()
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}])
})
})
client.on("interactionCreate",(interaction) => {
if (!interaction.isCommand()) return
if (interaction.commandName != "add") return
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 (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})
return
}
interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
interaction.channel.permissionOverwrites.create(user.id, { VIEW_CHANNEL:true, ADD_REACTIONS:true,ATTACH_FILES:true, EMBED_LINKS:true, SEND_MESSAGES:true})
interaction.reply({embeds:[bot.errorLog.success(l.commands.userAddedTitle,l.commands.userAddedDescription.replace("{0}",user.tag))]})
var loguser = user
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}])
})
})
}
+60
View File
@@ -0,0 +1,60 @@
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
module.exports = () => {
client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix+"close")) return
msg.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const closebutton = new discord.MessageActionRow()
.addComponents([
new discord.MessageButton()
.setCustomId("closeTicketTrue1")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("🔒")
])
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}])
})
})
client.on("interactionCreate",(interaction) => {
if (!interaction.isCommand()) return
if (interaction.commandName != "close") return
interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const closebutton = new discord.MessageActionRow()
.addComponents([
new discord.MessageButton()
.setCustomId("closeTicketTrue1")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("🔒")
])
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}])
})
})
}
+69
View File
@@ -0,0 +1,69 @@
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
module.exports = () => {
client.on("messageCreate",msg => {
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){
return msg.channel.send({embeds:[bot.errorLog.noPermsMessage]})
}
msg.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const closebutton = new discord.MessageActionRow()
.addComponents([
new discord.MessageButton()
.setCustomId("deleteTicketTrue")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("❌")
])
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}])
})
})
client.on("interactionCreate",(interaction) => {
if (!interaction.isCommand()) 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)
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})
return
}
interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const closebutton = new discord.MessageActionRow()
.addComponents([
new discord.MessageButton()
.setCustomId("deleteTicketTrue")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("❌")
])
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}])
})
})
}
+38
View File
@@ -0,0 +1,38 @@
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
module.exports = () => {
const helpEmbed = new discord.MessageEmbed()
.setColor(config.main_color)
.setTitle(l.helpMenu.title)
const prefix = config.prefix
const header = config.system.ticket_channel ? l.helpMenu.header1.replace("{0}","<#"+config.system.ticket_channel+">") : l.helpMenu.header2
helpEmbed.setDescription(header+"`"+prefix+"msg <id>` ➜ _"+l.helpMenu.msgCmd+"_\n\n`"+prefix+"rename <name>` ➜ _"+l.helpMenu.renameCmd+"_\n`"+prefix+"close` ➜ _"+l.helpMenu.closeCmd+"_\n`"+prefix+"delete` ➜ _"+l.helpMenu.deleteCmd+"_\n`"+prefix+"reopen` ➜ _"+l.helpMenu.reopenCmd+"_\n\n`"+prefix+"add <user>` ➜ _"+l.helpMenu.addCmd+"_\n`"+prefix+"remove <user>` ➜ _"+l.helpMenu.removeCmd+"_`")
if (config.credits) helpEmbed.setFooter({text:"Open-Ticket by DJdj Development | view on github for source code",iconURL:"https://raw.githubusercontent.com/DJj123dj/open-ticket/main/logo.png"})
client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix)) return
var args = msg.content.split(config.prefix)
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]})
log("command","someone used the 'help' command",[{key:"user",value:msg.author.tag}])
}
})
client.on("interactionCreate",(interaction) => {
if (!interaction.isCommand()) return
if (interaction.commandName != "help") return
interaction.reply({embeds:[helpEmbed]})
log("command","someone used the 'help' command",[{key:"user",value:interaction.user.tag}])
})
}
+63
View File
@@ -0,0 +1,63 @@
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
module.exports = () => {
client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix+"remove")) return
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 (!msg.member.permissions.has("MANAGE_CHANNELS") && !msg.member.permissions.has("ADMINISTRATOR") && config.main_adminroles.some((item)=>{return msg.member.roles.cache.has(item)}) == false){
return msg.channel.send({embeds:[bot.errorLog.noPermsMessage]})
}
msg.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
msg.channel.permissionOverwrites.delete(user.id)
msg.channel.send({embeds:[bot.errorLog.success(l.commands.userRemovedTitle,l.commands.userRemovedDescription.replace("{0}",user.tag))]})
var loguser = msg.mentions.users.first()
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}])
})
})
client.on("interactionCreate",(interaction) => {
if (!interaction.isCommand()) return
if (interaction.commandName != "remove") return
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 (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})
return
}
interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
interaction.channel.permissionOverwrites.delete(user.id)
interaction.reply({embeds:[bot.errorLog.success(l.commands.userRemovedTitle,l.commands.userRemovedDescription.replace("{0}",user.tag))]})
var loguser = user
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}])
})
})
}
+82
View File
@@ -0,0 +1,82 @@
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
module.exports = () => {
client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix+"rename")) return
msg.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
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){
return msg.channel.send({embeds:[bot.errorLog.noPermsMessage]})
}
var newname = msg.content.split(config.prefix+"rename")[1].substring(1)
if (!newname) return msg.channel.send({embeds:[bot.errorLog.invalidArgsMessage(l.errors.missingArgsDescription+" `<name>`:\n`"+config.prefix+"rename <name>`")]})
var name = msg.channel.name
var prefix = ""
const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
}
})
if (!prefix) prefix = "noprefix-"
msg.channel.setName(prefix+newname)
msg.channel.send({embeds:[bot.errorLog.success(l.commands.renameTitle,l.commands.renameWarning)]})
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}])
})
})
client.on("interactionCreate",(interaction) => {
if (!interaction.isCommand()) return
if (interaction.commandName != "rename") return
interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
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 (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})
return
}
var newname = interaction.options.getString("name")
var name = interaction.channel.name
var prefix = ""
const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
}
})
if (!prefix) prefix = "noprefix-"
interaction.channel.setName(prefix+newname)
interaction.reply({embeds:[bot.errorLog.success(l.commands.renameTitle,l.commands.renameWarning)]})
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}])
})
})
}
+51
View File
@@ -0,0 +1,51 @@
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
module.exports = () => {
var reopenCommandBar = new discord.MessageActionRow()
.addComponents(
new discord.MessageButton()
.setCustomId("reopenTicket1")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("🔓")
)
client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix+"reopen")) return
msg.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
msg.channel.send({embeds:[bot.errorLog.success(l.commands.reopenTitle,l.commands.reopenDescription)],components:[reopenCommandBar]})
log("command","someone used the 'reopen' command",[{key:"user",value:msg.author.tag}])
})
})
client.on("interactionCreate",(interaction) => {
if (!interaction.isCommand()) return
if (interaction.commandName != "reopen") return
interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
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]})
log("command","someone used the 'reopen' command",[{key:"user",value:interaction.user.tag}])
})
})
}
+43 -36
View File
@@ -1,52 +1,59 @@
const discord = require('discord.js') const discord = require('discord.js')
const bot = require('../index') const bot = require('../index')
const client = bot.client const client = bot.client
const config = require("../config.json") const config = bot.config
const log = bot.errorLog.log
var name = require('./ticketExtra').name const l = bot.language
var stringDecoder = require('./ticketSystem').stringDecoder
module.exports = () => { module.exports = () => {
/**@type {String[]} */
var msgIds = []
config.messages.forEach((msg) => {
msgIds.push(msg.id)
})
client.on("messageCreate", msg => { client.on("messageCreate", msg => {
if (msg.content == config.prefix+"ticket msg"){ if (msg.content.startsWith(config.prefix+"msg"||config.prefix+"message")){
if (msg.member.roles.cache.has(config.botperms_role) == false && msg.author.id != "779742674932072469"){
msg.channel.send({content:"Je hebt geen permissions voor deze command!"}) 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){
return msg.channel.send({embeds:[bot.errorLog.noPermsMessage]})
}
const id = msg.content.split(config.prefix+"msg")[1].substring(1) ? msg.content.split(config.prefix+"msg")[1].substring(1) : false
if (!id) return msg.channel.send({embeds:[bot.errorLog.invalidArgsMessage(l.errors.missingArgsDescription+" `<id>`:\n`"+config.prefix+"msg <id>`")]})
if (!msgIds.includes(id)) return msg.channel.send({embeds:[bot.errorLog.invalidIdChooseFromList(msgIds)]})
const {embed,componentRows} = require("../core/ticketMessageEmbed").createEmbed(id)
msg.channel.send({embeds:[embed],components:componentRows})
log("command","someone used the 'msg' command",[{key:"user",value:msg.author.tag},{key:"id",value:id}])
}
})
client.on("interactionCreate", (interaction) => {
if (!interaction.isCommand()) 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 (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})
return return
} }
var ticketButton = new discord.MessageActionRow() const id = interaction.options.getString("id")
.addComponents(
new discord.MessageButton()
.setCustomId("newTicketVraag")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("❓")
)
.addComponents(
new discord.MessageButton()
.setCustomId("newTicketSolli")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("📝")
)
.addComponents(
new discord.MessageButton()
.setCustomId("newTicketPartner")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("💼")
)
var ticketEmbed = new discord.MessageEmbed() if (!msgIds.includes(id)) return interaction.reply({embeds:[bot.errorLog.invalidIdChooseFromList(msgIds)]})
.setColor(config.main_color)
.setDescription("**Maak een ticket:**\nKlik op een van de onderstaande knoppen om een ticket aan te maken.\n\n__kies een categorie:__\n\n❓: **Vragen**\nOverige vragen.\n\n📝: **Sollicitatie**\nDoe een sollicitatie.\n\n💼: **Partner**\nWord partner met ons.\n\n**opgepast: **_u kan maar één ticket tegelijkertijd aanmaken!_")
const {embed,componentRows} = require("../core/ticketMessageEmbed").createEmbed(id)
interaction.reply({content:l.commands.ticketWarning})
interaction.channel.send({embeds:[embed],components:componentRows})
msg.channel.send({embeds:[ticketEmbed],components:[ticketButton]}) log("command","someone used the 'msg' command",[{key:"user",value:interaction.user.tag},{key:"id",value:id}])
}
}) })
} }
-156
View File
@@ -1,156 +0,0 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = require("../config.json")
var name = "DJdj Development"
exports.name = name
var stringDecoder = require('./ticketSystem').stringDecoder
module.exports = () => {
client.on("messageCreate",msg => {
var args = msg.content.split(" ")
if (args[0] == config.prefix+"solli"){
var SolliMsg = new discord.MessageEmbed()
.setColor(config.main_color)
.setDescription("**Hier is de informatie die wij nodig hebben voor een sollicitatie**\n\n**naam:** Je echte naam.\n**leeftijd:** Je leeftijd.\n**discord naam:** Je discord naam + tag (bv:Wumpus#0001).\n**minecraft naam:** Je minecraft naam.\n**waarom wil je staff worden:** De reden waarom je staff wilt worden.\n**+ punten:** Je plus punten.\n**- punten:** Je min punten.\n**Jou of iemand anders:** Waarom zouden we jou aan moeten nemen en niet een andere sollicitant?\n**ervaring:** Wat is je ervaring met MT servers?\n**andere server:** Ben je op dit moment staff op een andere server?\n**online:** Hoeveel uur per dag/week kan je online zijn?\n**functie:** Voor welke functie solliciteert u?")
.setTitle("Sollicitatie")
msg.channel.send({embeds:[SolliMsg]})
}
})
client.on("messageCreate",msg => {
var args = msg.content.split(" ")
if (args[0] == config.prefix+"ticket" && (args[1] == undefined ||args[1] == "" ||args[1] == null)){
var TicketHelpMsg = new discord.MessageEmbed()
.setColor(config.main_color)
.setDescription("**Ga naar <#"+config.ticket_system.ticket_channel+"> om een ticket te maken!**\n\n`!ticket msg` ➜ _Maak een ticket reageer bericht (staff only)._\n`!ticket rename` ➜ _Rename een ticket (geen spaties)._\n`!ticket close` ➜ _Close een ticket._\n`!ticket add <user>` ➜ _Voeg een speler toe aan het ticket._\n`!ticket remove <user>` ➜ _Verwijder een speler van het ticket._\n`!partner` ➜ _De informatie voor partners._\n`!solli` ➜ _De informatie voor solliciteren._")
.setTitle("Ticket commands")
.setFooter(stringDecoder+name)
msg.channel.send({embeds:[TicketHelpMsg]})
}
})
client.on("messageCreate",msg => {
var args = msg.content.split(" ")
if (args[0] == config.prefix+"partner"){
var PartnerMsg = new discord.MessageEmbed()
.setColor(config.main_color)
.setDescription("**Hier zijn de doelen die je moet hebben voor een partnership**\n\n**server:** De naam van je server.\n**beschrijving:** Waar gaat je server over?\n**members:** Het aantal members in je server.\n**invite:** Een oneindige invite.\n\n_als wij dit goedkeuren, kan je je 'invite bericht' plaatsen._")
.setTitle("Partnership")
msg.channel.send({embeds:[PartnerMsg]})
}
})
client.on("messageCreate",msg => {
var args = msg.content.split(" ")
if (args[0] == config.prefix+"ticket" && args[1] == "close"){
msg.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined){
msg.channel.send({content:"Ik heb de sluit knop niet gevonden!"})
}
if (firstmsg.author.id != client.user.id){
msg.channel.send({content:"Je bent niet in een ticket!"})
return
}
var CloseMsg = new discord.MessageEmbed()
.setColor(config.main_color)
.setDescription("klik [hier]("+firstmsg.url+") om het ticket te sluiten.")
.setTitle("Sluit dit ticket:")
msg.channel.send({embeds:[CloseMsg]})
})
}
})
client.on("messageCreate",msg => {
var args = msg.content.split(" ")
if (args[0] == config.prefix+"ticket" && args[1] == "rename"){
if (msg.member.roles.cache.has(config.botperms_role) == false && msg.author.id != "779742674932072469"){
msg.channel.send({content:"Je hebt geen permissions voor deze command!"})
return
}
var name = args[2]
msg.channel.messages.fetchPinned().then(msglist => {
if (msglist.last().author.id == client.user.id){
msg.channel.send({content:"De naam is veranderd!"}).then(rmsg => {
rmsg.channel.setName(name)
})
}else{
msg.channel.send({content:"Je bent niet in een ticket!"})
}
})
}
})
client.on("messageCreate",msg => {
var args = msg.content.split(" ")
if (args[0] == config.prefix+"ticket" && args[1] == "add"){
if (msg.member.roles.cache.has(config.botperms_role) == false && msg.author.id != "779742674932072469"){
msg.channel.send({content:"Je hebt geen permissions voor deze command!"})
return
}
msg.channel.messages.fetch().then(msglist => {
if (msglist.last().author.id != client.user.id){
msg.channel.send({content:"Je bent niet in een ticket!"})
return
}
if (args[2] == null || args[2] == undefined || args[2] == "" || args[2] == false){
msg.channel.send({content:"Niet genoeg parameters!"})
return
}
var user = msg.mentions.users.first()
if (!user){
return
}
msg.channel.permissionOverwrites.create(user.id, { VIEW_CHANNEL:true, ADD_REACTIONS:true,ATTACH_FILES:true, EMBED_LINKS:true, SEND_MESSAGES:true})
})
}
})
client.on("messageCreate",msg => {
var args = msg.content.split(" ")
if (args[0] == config.prefix+"ticket" && args[1] == "remove"){
if (msg.member.roles.cache.has(config.botperms_role) == false && msg.author.id != "779742674932072469"){
msg.channel.send({content:"Je hebt geen permissions voor deze command!"})
return
}
msg.channel.messages.fetchPinned().then(msglist => {
if (msglist.last().author.id != client.user.id){
msg.channel.send({content:"Je bent niet in een ticket!"})
return
}
if (args[2] == null || args[2] == undefined || args[2] == "" || args[2] == false){
msg.channel.send({content:"Niet genoeg parameters!"})
return
}
var user = msg.mentions.users.first()
if (!user){
return
}
msg.channel.permissionOverwrites.delete(user.id)
})
}
})
}
-252
View File
@@ -1,252 +0,0 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = require("../config.json")
const ticketStorage = bot.TicketStorage
const userTicketStorage = bot.userTicketStorage
const transcriptStorage = bot.transcriptStorage
var stringDecoder = "Created By "
exports.stringDecoder = stringDecoder
module.exports = () => {
var closeButton = new discord.MessageActionRow()
.addComponents(
new discord.MessageButton()
.setCustomId("closeTicket")
.setDisabled(false)
.setStyle("SECONDARY")
.setLabel("Sluit Ticket")
.setEmoji("❌")
)
client.on("interactionCreate",interaction => {
if (interaction.isButton() == false){
return
}
if (interaction.customId == "newTicketVraag"||interaction.customId == "newTicketSolli"||interaction.customId == "newTicketPartner"){
interaction.deferUpdate()
if (ticketStorage.getItem(interaction.member.id) == null ||ticketStorage.getItem(interaction.member.id) == "false"){
try{
interaction.member.send("**Je ticket is aangemaakt!**")
}
catch{console.log("cant send DM to member")}
ticketStorage.setItem(interaction.member.id,"true")
var ticketNumber = interaction.member.user.username
if (interaction.customId == "newTicketVraag"){
var ticketName = "vraag-"+ticketNumber
}else if (interaction.customId == "newTicketSolli"){
var ticketName = "solli-"+ticketNumber
}else if (interaction.customId == "newTicketPartner"){
var ticketName = "partner-"+ticketNumber
}
if (config.ticket_system.enable_category){
var Category = config.ticket_system.ticket_category
}else{var Category = null}
interaction.guild.channels.create(ticketName,{
type:"GUILD_TEXT",
parent:Category,
permissionOverwrites:[
{
id:interaction.member.id,
type:"member",
allow:["ADD_REACTIONS","ATTACH_FILES","EMBED_LINKS","SEND_MESSAGES","VIEW_CHANNEL"]
},
{
id:config.botperms_role,
type:"role",
allow:["ADD_REACTIONS","ATTACH_FILES","EMBED_LINKS","SEND_MESSAGES","VIEW_CHANNEL"]
},
{
id:config.ticket_system.member_role,
type:"role",
deny:["VIEW_CHANNEL"]
}
]
}).then(tChannel => {
userTicketStorage.setItem(tChannel.id,interaction.member.id)
var ticketEmbed = new discord.MessageEmbed()
.setColor(config.main_color)
if (interaction.customId == "newTicketVraag"){
ticketEmbed.setDescription("**Ticket gemaakt:**\nJe hebt gekozen voor **overige vragen**, zeg alvast maar je vraag, onze staffleden komen u zo helpen.\n\n_Klik op knop hieronder om dit ticket te sluiten_")
}else if (interaction.customId == "newTicketSolli"){
ticketEmbed.setDescription("**Ticket gemaakt:**\nJe hebt gekozen voor **sollicitatie**, neem maar tijd om u sollicitatie brief voor te bereiden. Met de `!solli` command kan je zien wat je allemaal moet zeggen.\n\n_Klik op knop hieronder om dit ticket te sluiten_")
}else if (interaction.customId == "newTicketPartner"){
ticketEmbed.setDescription("**Ticket gemaakt:**\nJe hebt gekozen voor **partner**, neem maar tijd om u partner brief voor te bereiden. Met de `!partner` command kan je zien wat de vereisen zijn.\n\n_Klik op knop hieronder om dit ticket te sluiten_")
}
tChannel.send({content:"<@"+interaction.member.id+"> <@&"+config.botperms_role+">",embeds:[ticketEmbed],components:[closeButton]}).then(firstmsg => {
firstmsg.pin()
})
})
}else{
try {
interaction.member.send("**Je hebt al een ticket open!**")
}
catch{console.log("cant send DM to member")}
}
}
})
var closeBar = new discord.MessageActionRow()
.addComponents(
new discord.MessageButton()
.setCustomId("closeTicketTrue")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("✅")
)
.addComponents(
new discord.MessageButton()
.setCustomId("closeTicketFalse")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("❌")
)
client.on("interactionCreate",interaction => {
if (interaction.isButton() == false){
return
}
if (interaction.customId == "closeTicket"){
interaction.deferUpdate()
interaction.message.edit({components:[closeBar]})
}
})
client.on("interactionCreate",interaction => {
if (interaction.isButton() == false){
return
}
if (interaction.customId == "closeTicketFalse"){
interaction.deferUpdate()
interaction.message.edit({components:[closeButton]})
}
})
client.on("interactionCreate",interaction => {
if (interaction.isButton() == false){
return
}
if (interaction.customId == "closeTicketTrue"){
interaction.deferUpdate()
interaction.channel.messages.fetch().then(messages => {
var transcriptArray = []
messages.forEach(msg => {
if (msg.author.id != client.user.id){
transcriptArray.push("["+msg.author.username+"]: "+msg.content)
}
})
var getuserID = userTicketStorage.getItem(interaction.channel.id)
var getusernameStep1 = client.users.cache.find(u => u.id === getuserID)
if (getusernameStep1 == null || getusernameStep1 == undefined || getusernameStep1 == false || getusernameStep1 == ""){
var getuserNAME = ":user niet in database:"
}else {
var getuserNAME = getusernameStep1.username
}
if (config.ticket_system.enable_transcript){
var transcript = transcriptArray.reverse().join("\n")
transcriptStorage.setItem(interaction.channel.id,transcript)
var splittedTranscript = [transcript.slice(0,2000)]
if (transcript.length > 4000){
splittedTranscript.push(transcript.slice(2000,4000))
splittedTranscript.push(transcript.slice(4000))
}else if (transcript.length > 2000){
splittedTranscript.push(transcript.slice(2000))
}
var transcriptEmbed = new discord.MessageEmbed()
.setColor(config.main_color)
.setAuthor(interaction.channel.name + " - ticket gemaakt door "+getuserNAME)
.setTitle("Er is een nieuw transcript!")
.setDescription(splittedTranscript[0])
.setFooter("ticket gesloten door "+interaction.member.user.username)
if (transcript.length > 4000){
var transcriptEmbed2 = new discord.MessageEmbed()
.setColor(config.main_color)
.setAuthor(interaction.channel.name + " - ticket gemaakt door "+getuserNAME)
.setTitle("Deel 2 van het transcript")
.setDescription(splittedTranscript[1])
.setFooter("ticket gesloten door "+interaction.member.user.username)
var transcriptEmbed3 = new discord.MessageEmbed()
.setColor(config.main_color)
.setAuthor(interaction.channel.name + " - ticket gemaakt door "+getuserNAME)
.setTitle("Deel 3 van het transcript")
.setDescription(splittedTranscript[1])
.setFooter("ticket gesloten door "+interaction.member.user.username)
client.channels.cache.find(ch => ch.id == config.ticket_system.transcript_channel).send({embeds:[transcriptEmbed,transcriptEmbed2,transcriptEmbed3]})
}else if (transcript.length > 2000){
var transcriptEmbed2 = new discord.MessageEmbed()
.setColor(config.main_color)
.setAuthor(interaction.channel.name + " - ticket gemaakt door "+getuserNAME)
.setTitle("Deel 2 van het transcript")
.setDescription(splittedTranscript[1])
.setFooter("ticket gesloten door "+interaction.member.user.username)
client.channels.cache.find(ch => ch.id == config.ticket_system.transcript_channel).send({embeds:[transcriptEmbed,transcriptEmbed2]})
}else{
client.channels.cache.find(ch => ch.id == config.ticket_system.transcript_channel).send({embeds:[transcriptEmbed]})
}
}
interaction.channel.delete()
ticketStorage.setItem(getuserID,"false")
try {
interaction.member.send("**Je ticket is gesloten door "+interaction.member.user.username+"!**")
}
catch{console.log("cant send DM to member")}
})
}
})
process.on('unhandledRejection',error => {
console.log("ERROR: "+error)
})
}
+82 -12
View File
@@ -1,21 +1,91 @@
{ {
"server_name":"Ticket Bot Land",
"server_logo":"https://www.example.com/another-example/yourlogo.png",
"bot_name":"Wumpus", "bot_name":"Wumpus",
"main_color":"#fffff", "main_color":"#ffffff",
"auth_token":"the bot's auth token", "server_id":"server id (for slash cmds)",
"botperms_role":"the id from a role that can do anything with the bot", "auth_token":"auth token",
"prefix":"!", "main_adminroles":["discord role id"],
"prefix":"!ticket ",
"languagefile":"english",
"ticket_system":{ "credits":true,
"ticket_channel":"id of the channel with the !ticket msg", "status":{
"enabled":true,
"type":"PLAYING",
"text":"!ticket"
},
"enable_category":false, "system":{
"ticket_category":"the id of a category for the tickets", "ticket_channel":"channel id",
"max_allowed_tickets":3,
"enable_DM_Messages":true,
"member_role":"this role doesn't have access to tickets (WARNING: @everyone does have access to tickets, so make sure all members have a member role!)", "has@everyoneaccess":false,
"member_role":"member role (doesn't have access to tickets)",
"closeMode":"adminonly|normal",
"enable_transcript":false, "enable_transcript":false,
"transcript_channel":"the channel for transcripts" "enable_DM_transcript":false,
"transcript_channel":"channel id"
},
"options":[
{
"id":"general",
"name":"Question",
"description":"Create this ticket if you have a question.",
"icon":"🎫",
"label":"question",
"type":"ticket",
"color":"gray",
"adminroles":["role id"],
"channelprefix":"question-",
"category":"category id",
"message":"You created a ticket!",
"enableDMMessage":true,
"ticketmessage":"The staff will help you soon!\n\n*Click on the button below to close the ticket!*"
},
{
"id":"website",
"name":"Website",
"description":"Go to our website.",
"icon":"✅",
"label":"click here",
"type":"website",
"url":"https://www.dj-dj.be"
},
{
"id":"role",
"name":"Verify",
"description":"Click here to get the verify role.",
"icon":"👮🏼",
"label":"get a role",
"type":"role",
"color":"red",
"roles":["discord role id"],
"mode":"add&remove|remove|add",
"enableDMMessage":true
} }
],
"messages":[
{
"id":"1",
"name":"Choose Your Ticket",
"description":"You can click one of the buttons below!\nYou can also customize all the embeds now!",
"enableFooter":true,
"footer":"Open Ticket v2.1.0 - I'm a footer!",
"enableThumbnail":false,
"thumbnail":"https://www.example.com/catmemes/cat.png",
"color":"#ffffff",
"options":["general","apply"],
"enableTicketExplaination":true,
"enableMaxTicketsWarning":true
}
]
} }
+352
View File
@@ -0,0 +1,352 @@
exports.checker = async () => {
const chalk = await (await import("chalk")).default
const config = require("../config.json")
var errorList = []
var isError = false
var warnList = []
var isWarn = false
const createError = (message) => {
isError = true
errorList.push("open-ticket CONFIG ERROR: "+message)
}
const createWarn = (message) => {
isWarn = true
warnList.push("open-ticket CONFIG WARNING: "+message)
}
//validators
/**@param {"userid"|"roleid"|"channelid"|"serverid"|"categoryid"} mode @param {String} value @param {String} path */
const checkDiscord = (mode,value,path) => {
if (mode == "userid"){
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+"' | this user id is invalid")
}
}else if (mode == "channelid"){
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+"' | this channel id is invalid")
}
}else if (mode == "roleid"){
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+"' | this role id is invalid")
}
}else if (mode == "serverid"){
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+"' | this server id is invalid")
}
}else if (mode == "categoryid"){
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+"' | this category id is invalid")
}
}
}
/**@param {String} value */
const checkToken = (value) => {
if (value.includes(" ") || value.length < 40 || value.length > 70){
createError("'auth_token' | your token is invalid")
}
}
/**@param {String} value @param {String} path */
const checkHexColor = (value,path) => {
if (!/^#[a-fA-F0-9]{3,6}$/.test(value)){
if (value.length < 4) return createError("'"+path+"' | hex color too short! (example: #123abc)")
if (value.length > 7) return createError("'"+path+"' | hex color too long! (example: #123abc)")
createError("'"+path+"' | invalid color! (example: #123abc)")
}
}
/**@param {String} value @param {String} path */
const checkEmbedColor = (value,path) => {
if (!['DEFAULT','WHITE','AQUA','GREEN','BLUE','YELLOW','PURPLE','LUMINOUS_VIVID_PINK','FUCHSIA','GOLD','ORANGE','RED','GREY','DARKER_GREY','NAVY','DARK_AQUA','DARK_GREEN','DARK_BLUE','DARK_PURPLE','DARK_VIVID_PINK','DARK_GOLD','DARK_ORANGE','DARK_RED','DARK_GREY','LIGHT_GREY','DARK_NAVY','BLURPLE','GREYPLE','DARK_BUT_NOT_BLACK','NOT_QUITE_BLACK','RANDOM'].includes(value)){
return createError("'"+path+"' | invalid color, must be a hex code or default color (more info in the wiki)")
}
}
/**@param {String} value @param {String} path @param {Number} minLength @param {Number} maxLength @param {String} name */
const checkString = (value,minLength,maxLength,path,name) => {
if (value.length < minLength){
createError("'"+path+"' | "+name+" is too short!")
}else if (value.length > maxLength){
createError("'"+path+"' | "+name+" is too long!")
}
}
/**@param {"userid"|"roleid"|"channelid"|"serverid"} mode @param {String[]} arrayValue @param {String} path */
const checkDiscordArray = (mode,arrayValue,path) => {
if (mode == "userid"){
arrayValue.forEach((value,index) => {
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+":"+index+"' | this user id is invalid")
}
})
}else if (mode == "channelid"){
arrayValue.forEach((value,index) => {
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+":"+index+"' | this channel id is invalid")
}
})
}else if (mode == "roleid"){
arrayValue.forEach((value,index) => {
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+":"+index+"' | this role id is invalid")
}
})
}else if (mode == "serverid"){
arrayValue.forEach((value,index) => {
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+":"+index+"' | this server id is invalid")
}
})
}
}
/**@param {String} value @param {"string"|"boolean"|"number"} type */
const checkType = (value,type,path) => {
if (type == "boolean"){
if (typeof value != "boolean"){
createError("'"+path+"' | invalid type, this must be a boolean!")
}
}else if (type == "number"){
if (typeof value != "number"){
createError("'"+path+"' | invalid type, this must be a number!")
}
}else if (type == "string"){
if (typeof value != "string"){
createError("'"+path+"' | invalid type, this must be a string!")
}
}
}
const checkButtonColor = (value,path) => {
if (value != "none" && value != "grey" && value != "gray" && value != "black" && value != "red" && value != "green" && value != "blue" && value != "blurple"){
createError("'"+path+"' | invalid color, it must be one of these: none, gray, red, green, blue!")
}
}
const getButtonClass = require("./utils/getButton").rawButtonData
/**@param {getButtonClass} option */
const checkOption = (option,path) => {
//id
checkType(option.id,"string",path+"/id")
if (option.id.includes(" ")){
createError("'"+path+"/id' | option id can't contain space characters!")
}
if (option.id.length > 20){
createError("'"+path+"/id' | option id max lenght is 20!")
}
//name
checkType(option.name,"string",path+"/name")
if (option.name.length > 100){
createWarn("'"+path+"/name' | if your name is too long it maybe doesn't look so good!")
}else if (option.name.length < 1){
createError("'"+path+"/name' | there is no name!")
}
//description
checkType(option.description,"string",path+"/description")
//icon
const emojiRegex = /(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])/gi;
if (option.icon.length > 0){
const isEmoji = emojiRegex.test(option.icon)
if (isEmoji == false){
createError("'"+path+"/icon' | invalid emoji or custom discord emoji")
}
}
checkType(option.icon,"string",path+"/icon")
//label
checkType(option.label,"string",path+"/label")
if (option.label.length < 1 && option.icon.length < 1){
createError("'"+path+"' | you need at least one of these: label, icon!")
}
//type
checkType(option.type,"string",path+"/type")
if (option.type != "ticket" && option.type != "website" && option.type != "role"){
createError("'"+path+"/type' | the type must be one of these: ticket, website, role!")
}
/**@type {"ticket"|"website"|"role"} */
const type = option.type
if (type == "ticket"){
//color
checkType(option.color,"string",path+"/color")
checkButtonColor(option.color,path+"/color")
//adminroles
checkDiscordArray("roleid",option.adminroles,path+"/adminroles")
//channelprefix
checkType(option.channelprefix,"string",path+"/channelprefix")
if (option.channelprefix.includes(" ")){
createWarn("'"+path+"/channelprefix' | this prefix can't contain spaces!")
}
//category
checkType(option.category,"string",path+"/category")
if (option.category.length > 0){
checkDiscord("categoryid",option.category,path+"/category")
}
//message
checkType(option.message,"string",path+"/message")
//enableDMmessage
checkType(option.enableDMMessage,"boolean",path+"/enableDMMessage")
//ticketmessage
checkType(option.ticketmessage,"string",path+"/ticketmessage")
}else if (type == "website"){
//url
checkType(option.url,"string",path+"/url")
if (option.url.includes(" ")){
createWarn("'"+path+"/url' | a url can't contain spaces")
}
if (option.url.length < 1){
createError("'"+path+"/url' | you have no url in this button")
}
if (!option.url.startsWith("https://") && !option.url.startsWith("http://") && !option.url.startsWith("discord://")){
createWarn("'"+path+"/url' | your url doesn't start with https or http!")
}
if (option.url.startsWith("http://")){
createWarn("'"+path+"/url' | your url is not a HTTPS link! discord maybe blocks this url!")
}
}else if (type == "role"){
//color
checkType(option.color,"string",path+"/color")
checkButtonColor(option.color,path+"/color")
//roles
checkDiscordArray("roleid",option.roles,path+"/roles")
//mode
checkType(option.mode,"string",path+"/mode")
if (option.mode != "add&remove" && option.mode != "add" && option.mode != "remove"){
createError("'"+path+"/mode' | mode must be one of these: add, remove, add&remove")
}
//enableDMmessage
checkType(option.enableDMMessage,"boolean",path+"/enableDMMessage")
}
}
const checkMessage = (input,path) => {
}
//--------------------------|
//--------------------------|
//checker => START HERE |
//--------------------------|
//--------------------------|
var configArray = ["bot_name","main_color","server_id","auth_token","main_adminroles","prefix","languagefile","credits","status","system","options","messages"]
configArray.forEach((item) => {
if (config[item] == undefined){
throw new Error("\n\nMAIN ERROR: the item '"+item+"' doesn't exist in config.json")
}
})
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")
checkToken(config.auth_token)
checkDiscordArray("roleid",config.main_adminroles,"main_adminroles")
checkString(config.prefix,1,15,"prefix","prefix")
//languagefile
checkType(config.languagefile,"string","languagefile")
const lf = config.languagefile
if (!lf.startsWith("custom") && !lf.startsWith("english") && !lf.startsWith("dutch") && !lf.startsWith("romanian")){
createError("'languagefile' | invalid language, more info in the wiki")
}
checkType(config.credits,"boolean","credits")
//status:
checkType(config.status.enabled,"boolean","status/enabled")
if (config.status.enabled){
if (config.status.type != "PLAYING" && config.status.type != "LISTENING" && config.status.type != "WATCHING"){
createError("'status/type' | not a valid status type!")
}
if (config.status.text.length < 1 || config.status.text.length > 40){
createError("'status/text' | text too long or short!")
}
}
//system:
if (config.system.ticket_channel){
if (config.system.ticket_channel.length < 16 || config.system.ticket_channel.length > 20 || !/^\d+$/.test(config.system.ticket_channel)){
createError("'system/ticket_channel' | this channel id is invalid")
}
}else createWarn("'"+path+"' | you have no ticket channel selected!")
checkType(config.system.max_allowed_tickets,"number","system/max_allowed_tickets")
checkType(config.system.enable_DM_Messages,"boolean","system/enable_DM_Messages")
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"){
checkDiscord("roleid",config.system.member_role,"system/member_role")
}
checkType(config.system.closeMode,"string","system/closeMode")
if (!["normal","adminonly"].includes(config.system.closeMode)){
createError("'system/closeMode' | the close mode must be adminonly or normal")
}
console.log("hoi")
checkType(config.system.enable_transcript,"boolean","system/enable_transcript")
checkType(config.system.enable_DM_transcript,"boolean","system/enable_DM_transcript")
if (config.system.enable_transcript){
checkDiscord("channelid",config.system.transcript_channel,"system/transcript_channel")
}
//options
config.options.forEach((option,index) => {
checkOption(option,"options/"+index)
})
//the end
if (errorList.length > 0 || warnList.length > 0){
console.log("REPORT:\n===========================")
}
warnList.forEach((w) => {
const splitw = w.split("'")
if (splitw.length > 1){
var splitstring = chalk.yellow(splitw[0])+chalk.blue("'"+splitw[1]+"'")+chalk.yellow(splitw[2])
}else {var splitstring = chalk.yellow(splitw[0])}
console.log(splitstring)
})
errorList.forEach((e) => {
const splite = e.split("'")
if (splite.length > 1){
var splitstring = chalk.red(splite[0])+chalk.blue("'"+splite[1]+"'")+chalk.red(splite[2])
}else {var splitstring = chalk.red(splite[0])}
console.log(splitstring)
})
if (isError){
console.log("===========================")
console.log("=> "+chalk.bgRed("your bot doesn't work if you don't fix the above errors!"))
if (isWarn){
console.log("\n=> "+chalk.bgYellow("if you ignore warns, some things may work differently than expected!"))
}
process.exit(0)
}else if (isWarn == true && isError == false){
console.log("===========================")
console.log("=> "+chalk.bgYellow("if you ignore warns, some things may work differently than expected!"))
}
}
this.checker()
+297
View File
@@ -0,0 +1,297 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const l = bot.language
module.exports = () => {
//closebar
var closeBar = new discord.MessageActionRow()
.addComponents(
new discord.MessageButton()
.setCustomId("closeTicketTrue")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("✅")
)
.addComponents(
new discord.MessageButton()
.setCustomId("closeTicketFalse")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("❌")
)
var deleteBar = new discord.MessageActionRow()
.addComponents(
new discord.MessageButton()
.setCustomId("deleteTicketTrue")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("✅")
)
.addComponents(
new discord.MessageButton()
.setCustomId("deleteTicketFalse")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("❌")
)
var deleteBar1 = new discord.MessageActionRow()
.addComponents(
new discord.MessageButton()
.setCustomId("deleteTicketTrue1")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("✅")
)
.addComponents(
new discord.MessageButton()
.setCustomId("deleteTicketFalse1")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("❌")
)
//closebutton
var closeRowNormal = new discord.MessageActionRow()
.addComponents(
new discord.MessageButton()
.setCustomId("closeTicket")
.setDisabled(false)
.setStyle("SECONDARY")
.setLabel(l.buttons.close)
.setEmoji("🔒")
)
.addComponents(
new discord.MessageButton()
.setCustomId("deleteTicket")
.setDisabled(false)
.setStyle("DANGER")
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
var closeRowClosed = 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("✔")
)
var closeRowDisabled = new discord.MessageActionRow()
.addComponents(
new discord.MessageButton()
.setCustomId("closeTicket")
.setDisabled(true)
.setStyle("SECONDARY")
.setLabel(l.buttons.close)
.setEmoji("🔒")
)
.addComponents(
new discord.MessageButton()
.setCustomId("deleteTicket")
.setDisabled(true)
.setStyle("DANGER")
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
//NORMAL CLOSE
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "closeTicket") return
interaction.deferUpdate()
interaction.message.edit({components:[closeBar]})
})
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "closeTicketFalse") return
interaction.deferUpdate()
interaction.message.edit({components:[closeRowNormal]})
})
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "closeTicketTrue") return
interaction.deferUpdate()
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
}
}
interaction.message.edit({components:[closeRowDisabled]})
/**
* @type {String}
*/
const name = interaction.channel.name
var prefix = ""
const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
}
})
require("./ticketCloser").closeTicket(interaction,prefix,"close")
})
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "closeTicketTrue1") return
interaction.deferUpdate()
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
}
}
const closedButtonDisabled = new discord.MessageActionRow()
.addComponents([
new discord.MessageButton()
.setCustomId("closeTicketTrue1")
.setDisabled(true)
.setStyle("SECONDARY")
.setEmoji("🔒")
])
interaction.message.edit({components:[closedButtonDisabled]})
interaction.channel.messages.fetchPinned().then((messages) => {
messages.first().edit({components:[closeRowDisabled]})
})
/**
* @type {String}
*/
const name = interaction.channel.name
var prefix = ""
const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
}
})
require("./ticketCloser").closeTicket(interaction,prefix,"close")
})
//NORMAL DELETE
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "deleteTicket") return
interaction.deferUpdate()
interaction.message.edit({components:[deleteBar]})
})
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "deleteTicketFalse") return
interaction.deferUpdate()
interaction.message.edit({components:[closeRowNormal]})
})
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "deleteTicketTrue") return
interaction.deferUpdate()
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
}
/**
* @type {String}
*/
const name = interaction.channel.name
var prefix = ""
const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
}
})
require("./ticketCloser").closeTicket(interaction,prefix,"delete")
})
//CLOSED DELETE
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "deleteTicket1") return
interaction.deferUpdate()
interaction.message.edit({components:[deleteBar1]})
})
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "deleteTicketFalse1") return
interaction.deferUpdate()
interaction.message.edit({components:[closeRowClosed]})
})
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "deleteTicketTrue1") return
interaction.deferUpdate()
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
}
/**
* @type {String}
*/
const name = interaction.channel.name
var prefix = ""
const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
}
})
require("./ticketCloser").closeTicket(interaction,prefix,"deletenotranscript")
})
}
+53
View File
@@ -0,0 +1,53 @@
const fs = require('fs')
const readline = require("readline")
const rl = readline.createInterface({
input:process.stdin,
output:process.stdout,
terminal:true
})
const ask = async () => {
const chalk = await (await import("chalk")).default
rl.question(chalk.yellow("WARNING: are you sure that there are",chalk.red("no tickets open"),"at the moment? ")+chalk.green("(yes/no)")+"\n",(answer) => {
if (answer != "1" && !answer.toLowerCase().startsWith("yes")){
console.log(chalk.red("invalid answer"))
ask()
return
}
console.log(chalk.green("clearing data..."))
runClear()
rl.close()
})
}
ask()
const runClear = async () => {
const chalk = await (await import("chalk")).default
//console.log(chalk.blue("You can get a node.js warning below, just ignore that, it's not important!"))
const dataPaths = ["./storage/dynamicDB"]
var index = 0
dataPaths.forEach((path) => {
try {
fs.rmSync(path,{recursive:true,force:true})
}catch{
//console.log(path,"doesn't exist")
}
setTimeout(() => {
try{
fs.mkdirSync(path)
}catch{
//console.log(path,"already exists")
}
index++
},500)
})
setInterval(() => {
if (index >= 1){
console.log(chalk.bgGreen("All local data is cleared!"))
process.exit(1)
}
},500)
}
@@ -0,0 +1,39 @@
const localstorage = require("node-localstorage")
const ls = new localstorage.LocalStorage("./storage/dynamicDB")
/**
*
* @param {String} category
* @param {String} id
* @param {String} value
* @returns {Boolean}
*/
exports.set = (category,id,value) => {
ls.setItem(category+"--"+id,value.toString())
return true
}
/**
*
* @param {String} category
* @param {String} id
* @returns {String|false}
*/
exports.get = (category,id) => {
const result = ls.getItem(category+"--"+id)
if (!result) return false
return result
}
/**
*
* @param {String} category
* @param {String} id
* @returns {Boolean}
*/
exports.delete = (category,id) => {
ls.removeItem(category+"--"+id)
return true
}
+33
View File
@@ -0,0 +1,33 @@
//Do not change this without knowing what you are doing!!
const databaseFile = "local"
//Do not change this without knowing what you are doing!!
try {
var db = require("./dynamicfiles/local")
}catch{
console.log("I couldn't find the database file! (location: ./core/dynamicdatabase/storage.js:2)")
process.exit(1)
}
module.exports = db
/** =============================
** NOT READY YET
** must be dynamic
** =============================*/
//const LocalStorage = require("node-localstorage")
//
//const ticketStorage = new LocalStorage.LocalStorage("./storage/tickets")
//exports.ticketStorage = ticketStorage
//
//const userTicketStorage = new LocalStorage.LocalStorage("./storage/userTickets")
//exports.userTicketStorage = userTicketStorage
//
//const transcriptStorage = new LocalStorage.LocalStorage("./storage/transcripts")
//exports.transcriptStorage = transcriptStorage
//const ticketNumberStorage = new LocalStorage.LocalStorage("./storage/ticketNumbers")
//exports.ticketNumberStorage = ticketNumberStorage
+117
View File
@@ -0,0 +1,117 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const l = bot.language
const loadChalk = async () => {
return await (await import("chalk")).default
}
const embed = discord.MessageEmbed
exports.noPermsMessage = new embed()
.setColor("RED")
.setTitle(":x: "+l.errors.noPermsTitle+" :x:")
.setDescription(l.errors.noPermsDescription)
/**@param {String} message */
exports.invalidArgsMessage = (message) => {
var x = new embed()
.setColor("RED")
.setTitle(":x: "+l.errors.missingArgsTitle+" :x:")
.setDescription(message)
return x
}
/**@param {String} message */
exports.serverError = (message) => {
var x = new embed()
.setColor("ORANGE")
.setTitle(":warning: "+l.errors.boterror+" :warning:")
.setDescription(message)
return x
}
/**@param {String[]} list */
exports.invalidIdChooseFromList = (list) => {
var x = new embed()
.setColor("RED")
.setTitle(":x: "+l.errors.chooseFromListTitle+" :x:")
.setDescription(l.errors.chooseFromListDescription+"\n`"+list.join("`\n`")+"`")
return x
}
exports.notInATicket = new embed()
.setColor("RED")
.setTitle(":x: "+l.errors.notInTicketTitle+" :x:")
.setDescription(l.errors.notInTicketDescription)
/**@param {String} message @param {String} title */
exports.success = (title,message) => {
var x = new embed()
.setColor(config.main_color)
.setTitle(":white_check_mark: "+title+" :white_check_mark:")
.setDescription(message)
return x
}
/**@param {String} message @param {String} title */
exports.warning = (title,message) => {
var x = new embed()
.setColor("ORANGE")
.setTitle(":warning: "+title+" :warning:")
.setDescription(message)
return x
}
/**@param {String} message the message @param {String} title the title @param {String} emoji an discord emoji @param {discord.ColorResolvable} color the embed color*/
exports.custom = (title,message,emoji,color) => {
var x = new embed()
.setColor(color)
.setTitle(emoji+" "+title+" "+emoji)
.setDescription(message)
return x
}
const normalLog = (debugString) => {
const fs = require("fs")
const content = fs.existsSync("./openticketdebug.txt") ? fs.readFileSync("./openticketdebug.txt").toString() : "==========================\n<OPEN TICKET DEBUG FILE:>\n=========================="
fs.writeFileSync("./openticketdebug.txt",content+"\nSYSTEM: "+debugString)
}
/**
*
* @param {"system"|"command"|"info"} type
* @param {String} message
* @param {[{key:String,value:String}]} params
*/
exports.log = async (type,message,params) => {
const chalk = await loadChalk()
var paramstring = ""
if (params){
if (params.length > 0){
params.forEach((p) => {
paramstring = paramstring+p.key+": "+p.value+" "
})
}
}
const parameters = params ? "("+paramstring+")" : " "
if (type == "command"){
console.log(chalk.green("[command] ")+message+" "+chalk.yellow(parameters))
}else if (type == "info"){
console.log(chalk.blue("[info] ")+message+" "+chalk.yellow(parameters))
}else if (type == "system"){
console.log(chalk.green("[system] ")+message+" "+chalk.yellow(parameters))
}
const cd = new Date()
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)
}
+116
View File
@@ -0,0 +1,116 @@
const bot = require("../index")
const config = bot.config
/**
* @param {Number} index
* @param {"id"|"name"|"description"|"icon"|"label"|"type"|"color"|"adminroles"|"channelprefix"|"category"|"message"|"enableDMMessage"|"ticketmessage"} value
*/
exports.getTicketValue = (index,value) => {
if (value == "id"){
return "newT"+config.options[index][value]
}
return config.options[index][value]
}
/**
* @param {Number} index
* @param {"id"|"name"|"description"|"icon"|"label"|"type"|"url"} value
*/
exports.getWebsiteValue = (index,value) => {
return config.options[index][value]
}
/**
* @param {Number} index
* @param {"id"|"name"|"description"|"icon"|"label"|"type"|"color"|"roles"|"mode"|"enableDMMessage"} value
*/
exports.getRoleValue = (index,value) => {
return config.options[index][value]
}
/**
* @param {"id"|"name"|"description"|"icon"|"label"|"type"|"color"|"adminroles"|"channelprefix"|"category"|"message"|"enableDMMessage"|"ticketmessage"} value
*/
exports.getTicketValues = (value) => {
var result = []
config.options.forEach((o) => {
if (value == "id"){
result.push("newT"+o[value])
}else{
result.push(o[value])
}
})
return result
}
/**
* @param {"id"|"name"|"description"|"icon"|"label"|"type"|"url"} value
*/
exports.getWebsiteValues = (value) => {
var result = []
config.options.forEach((o) => {
result.push(o[value])
})
return result
}
/**
* @param {"id"|"name"|"description"|"icon"|"label"|"type"|"color"|"roles"|"mode"|"enableDMMessage""} value
*/
exports.getRoleValues = (value) => {
var result = []
config.options.forEach((o) => {
result.push(o[value])
})
return result
}
class TicketOptions {
constructor() {
this.id = ""
this.name = ""
this.description = ""
this.icon = ""
this.label = ""
this.type = ""
this.color = ""
this.adminroles = ["",""]
this.channelprefix = ""
this.category = ""
this.message = ""
this.enableDMMessage = true
this.ticketmessage = ""
}
}
/**
*
* @param {String} id
* @returns {TicketOptions|false}
*/
exports.getOptionsById = (id) => {
var result = false
config.options.forEach((option) => {
if ("newT"+option.id == id){
result = option
}
})
return result
}
exports.exportedOptionClass = class {
constructor() {
this.id = ""
this.name = ""
this.description = ""
this.icon = ""
this.label = ""
this.type = ""
this.color = ""
this.adminroles = ["",""]
this.channelprefix = ""
this.category = ""
this.message = ""
this.enableDMMessage = true
this.ticketmessage = ""
}
}
+37
View File
@@ -0,0 +1,37 @@
const index = require("../index")
if (index.developerMode){
var config = require("../devConfig.json")
}else{var config = require("../config.json")}
var localLanguage = require("../language/english.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("english")) localLanguage = require("../language/english.json")
else if (config.languagefile.startsWith("deutsch")) localLanguage = require("../language/deutsch.json")
else if (config.languagefile.startsWith("french")) localLanguage = require("../language/french.json")
else if (config.languagefile.startsWith("romanian")) localLanguage = require("../language/romanian.json")
const errorLog = async () => {
const chalk = await (await import("chalk")).default
console.log(chalk.red("Something went wrong when loading the language!")+"\nCheck the config file or create a ticket in our server!")
}
const successLog = async (language) => {
const chalk = await (await import("chalk")).default
console.log(chalk.green("loaded language "+language+"..."))
}
if (!localLanguage){
const runError = async () => {
await errorLog()
process.exit(1)
}
runError()
}else{
exports.language = localLanguage
successLog(config.languagefile)
}
+62
View File
@@ -0,0 +1,62 @@
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
module.exports = async () => {
const chalk = await (await import("chalk")).default
client.on("interactionCreate",(interaction) => {
if (!interaction.isButton()) return
if (!interaction.customId.startsWith("newR")) return
interaction.deferUpdate()
if (interaction.customId.startsWith("newR")){
const optionid = interaction.customId.split("newR")[1]
if (!optionid){
interaction.reply({embeds:[bot.errorLog.serverError(l.errors.roleDoesntExist)]})
return
}
}
try {
const option = require("./utils/getButton").getOption(optionid)
/**@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}])
})
}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}])
})
}else if (mode == "add&remove"){
option.roles.forEach((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","added role (reaction roles)",[{key:"user",value:interaction.user.tag},{key:"role",value:role}])
}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}])
}
})
}
}catch{
interaction.replyinteraction.channel.send({embeds:[bot.errorLog.serverError(l.errors.somethingWentWrong)]})
}
})
}
+24
View File
@@ -0,0 +1,24 @@
const discord = require("discord.js")
const bot = require("../../index")
const client = require("../../index").client
const config = bot.config
const getoptions = require("../getoptions")
module.exports = async () => {
const chalk = (await import("chalk")).default
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) => {
if (!interaction.isCommand()) return console.log("this isn't a command!")
interaction.reply({content:"This command is now deleted!"})
try {
client.application.commands.delete(interaction.commandId,interaction.guild.id).then(() => {
console.log("deleted the command",chalk.blue(interaction.commandName),"(id:",interaction.commandId+")")
})
}catch{
console.log(chalk.red("something went wrong by the deleting of this command!"))
}
})
}
+194
View File
@@ -0,0 +1,194 @@
const discord = require("discord.js")
const bot = require("../../index")
const client = require("../../index").client
const config = bot.config
const getoptions = require("../getoptions")
module.exports = async () => {
const chalk = (await import("chalk")).default
const sid = config.server_id
const ids = getoptions.getTicketValues("id")
/**@type {[{name:String,value:String}]} */
var choices = []
ids.forEach((id) => {
const option = getoptions.getOptionsById(id)
if (option.type == "ticket"){
choices.push({name:option.name,value:option.id})
}
})
/**@type {[{name:String,value:String}]} */
var msgchoices = []
config.messages.forEach((msg) => {
msgchoices.push({name:msg.id,value:msg.id})
})
var readystats = 0
process.stdout.write("[status] there are "+chalk.blue("0 out of 10")+" commands ready! (this can take up to 40 seconds)")
setInterval(() => {
process.stdout.cursorTo(0)
process.stdout.write("[status] there are "+chalk.blue(readystats+" out of 9")+" commands ready! (this can take up to 40 seconds)")
if (readystats >= 10){
console.log(chalk.green("\nready!"))
console.log(chalk.bgBlue("you can now start the bot with 'npm start'!"))
process.exit(1)
}
},100)
//create a ticket (/new or /ticket)
client.application.commands.create({
name:"ticket",
description:"Create a ticket!",
defaultPermission:true,
type:"CHAT_INPUT",
options:[
{
type:"STRING",
name:"type",
description:"The type of ticket.",
required:true,
choices:choices
}
]
},sid).then(() => {
readystats++
})
client.application.commands.create({
name:"new",
description:"Create a ticket!",
defaultPermission:true,
type:"CHAT_INPUT",
options:[
{
type:"STRING",
name:"type",
description:"The type of ticket.",
required:true,
choices:choices
}
]
},sid).then(() => {
readystats++
})
//help
client.application.commands.create({
name:"help",
description:"The help menu",
defaultPermission:true,
type:"CHAT_INPUT"
},sid).then(() => {
readystats++
})
//close
client.application.commands.create({
name:"close",
description:"Close the current ticket.",
defaultPermission:true,
type:"CHAT_INPUT"
},sid).then(() => {
readystats++
})
//delete
client.application.commands.create({
name:"delete",
description:"Delete the current ticket.",
defaultPermission:true,
type:"CHAT_INPUT"
},sid).then(() => {
readystats++
})
//msg
client.application.commands.create({
name:"message",
description:"Create a ticket message.",
defaultPermission:true,
type:"CHAT_INPUT",
options:[
{
type:"STRING",
name:"id",
description:"The message id.",
required:true,
choices:msgchoices
}
]
},sid).then(() => {
readystats++
})
//add
client.application.commands.create({
name:"add",
description:"Add people to this ticket.",
defaultPermission:true,
type:"CHAT_INPUT",
options:[
{
type:"USER",
name:"user",
description:"The user to add.",
required:true
}
]
},sid).then(() => {
readystats++
})
//remove
client.application.commands.create({
name:"remove",
description:"Remove people from this ticket.",
defaultPermission:true,
type:"CHAT_INPUT",
options:[
{
type:"USER",
name:"user",
description:"The user to remove.",
required:true
}
]
},sid).then(() => {
readystats++
})
//rename
client.application.commands.create({
name:"rename",
description:"Rename this ticket.",
defaultPermission:true,
type:"CHAT_INPUT",
options:[
{
type:"STRING",
name:"name",
description:"The new name (without prefix).",
required:true
}
]
},sid).then(() => {
readystats++
})
//reopen
client.application.commands.create({
name:"reopen",
description:"Reopen this ticket.",
defaultPermission:true,
type:"CHAT_INPUT"
},sid).then(() => {
readystats++
})
}
+249
View File
@@ -0,0 +1,249 @@
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 {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 = () => {
client.on("interactionCreate",async (interaction) => {
if (!interaction.isButton()) return
if (interaction.customId != "sendTranscript") return
interaction.deferUpdate()
const channelmessages = await interaction.channel.messages.fetch()
channelmessages.sweep((msgSweep) => {
return msgSweep.author.id == client.user.id
})
var fileattachment = await require("./transcript").createTranscript(channelmessages,interaction.channel)
if (fileattachment == false){
log("system","internal error: transcript is not created!")
interaction.channel.send({embeds:[bot.errorLog.serverError(l.errors.somethingWentWrongTranscript)]})
return
}
interaction.channel.send({content:"**"+l.messages.hereIsTheTranscript+"**",files:[fileattachment]})
})
}
+96
View File
@@ -0,0 +1,96 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const getButton = require("./utils/getButton")
const l = bot.language
/**
*
* @param {String} id the id from an open-ticket embed
* @returns {{embed:discord.MessageEmbed,componentRows:discord.MessageActionRow[]}} discord embed
*/
exports.createEmbed = (id) => {
//-----------------------------------
//general importing
const data = require("./utils/getTicketMessages").getTicketMessage(id)
/**@type {discord.MessageButton[]}*/
var buttons = []
/**@type {getButton.rawButtonData[]} */
var buttonData = []
data.options.forEach((option) => {
var button = getButton.getButton(option)
var localButtonData = getButton.getOption(option)
if (button) buttons.push(button)
if (localButtonData) buttonData.push(localButtonData)
})
//-----------------------------------
//-----------------------------------
//create the embed
const embed = new discord.MessageEmbed()
.setColor(data.color)
.setTitle(data.name)
if (data.enableFooter) embed.setFooter({text:data.footer})
if (data.enableThumbnail) embed.setThumbnail(data.thumbnail)
var description = data.description
if (data.enableTicketExplaination){
description = description+"\n\n__"+l.messages.chooseCategory+"__\n"
var ticketExplainations = []
buttonData.forEach((button) => {
var explaination = button.icon+" **"+button.name+":**\n"+button.description
ticketExplainations.push(explaination)
})
description = description+ticketExplainations.join("\n\n")
}
if (data.enableMaxTicketsWarning){
description = description+"\n\n"+l.commands.maxTicketWarning.replace("{0}",config.system.max_allowed_tickets)
}
embed.setDescription(description)
//-----------------------------------
//-----------------------------------
//create the components
var AmountOfRows = Math.ceil(buttons.length / 4)
var currentRow = 0
/**
* @type {discord.MessageActionRow[]}
*/
var componentRows = []
for (let i = AmountOfRows; i > 0; i--){
componentRows.push(new discord.MessageActionRow())
}
buttons.forEach((button,index) => {
componentRows[currentRow].addComponents([button])
if (index == 3 || index == 7 || index == 11 || index == 15 || index == 19 || index == 23 || index == 27 || index == 31 || index == 35 || index == 39){
currentRow = currentRow + 1
}
})
//-----------------------------------
//return everything
/**
* @type {{embed:discord.MessageEmbed,componentRows:discord.MessageActionRow[]}}
*/
const returnedData = {embed:embed,componentRows:componentRows}
return returnedData
}
this.createEmbed()
+182
View File
@@ -0,0 +1,182 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const l = bot.language
const log = bot.errorLog.log
const getconfigoptions = require("./getoptions")
const storage = bot.storage
module.exports = () => {
var closeButton = new discord.MessageActionRow()
.addComponents(
new discord.MessageButton()
.setCustomId("closeTicket")
.setDisabled(false)
.setStyle("SECONDARY")
.setLabel(l.buttons.close)
.setEmoji("🔒")
)
.addComponents(
new discord.MessageButton()
.setCustomId("deleteTicket")
.setDisabled(false)
.setStyle("DANGER")
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
//ticket button click / create ticket
client.on("interactionCreate",(interaction) => {
if (interaction.isCommand() && (interaction.commandName == "new" || interaction.commandName == "ticket")){
var customId = "newT"+interaction.options.getString("type")
}else if (interaction.isButton()){
var customId = interaction.customId
}else return
if (interaction.customId.startsWith("newT")){
const optionid = interaction.customId.split("newT")[1]
if (!optionid){
interaction.reply({embeds:[bot.errorLog.serverError(l.errors.ticketDoesntExist)]})
return
}
}
if (getconfigoptions.getTicketValues("id").includes(customId)){
//ticketoptions from config
const currentTicketOptions = getconfigoptions.getOptionsById(customId)
if (currentTicketOptions == false || currentTicketOptions.type != "ticket") return interaction.reply({embeds:[bot.errorLog.serverError(l.errors.anotherOption)]})
if (interaction.isButton()){
interaction.deferUpdate()
}else if (interaction.isCommand()){
interaction.reply({embeds:[bot.errorLog.success(l.messages.createdTitle,l.messages.createdDescription)]})
}
if (storage.get("ticketStorage",interaction.member.id) == null || storage.get("ticketStorage",interaction.member.id) == "false"|| Number(storage.get("ticketStorage",interaction.member.id)) < config.system.max_allowed_tickets){
try{
if (config.system.enable_DM_Messages){
interaction.member.send({embeds:[bot.errorLog.custom(l.messages.newTicketDmTitle,currentTicketOptions.message,":ticket:",config.main_color)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
//update storage
storage.set("ticketStorage",interaction.member.id,Number(storage.get("ticketStorage",interaction.member.id))+1)
var ticketNumber = interaction.member.user.username
//set ticketName
var ticketName = currentTicketOptions.channelprefix+ticketNumber
var logsname = currentTicketOptions.name
//category
if (currentTicketOptions.category.length < 16 || currentTicketOptions.category.length > 20){
var newTicketCategory = null
}else{
var newTicketCategory = currentTicketOptions.category
}
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
})
//add the user that created the ticket
permissionsArray.push({
id:interaction.member.id,
type:"member",
allow:["ADD_REACTIONS","ATTACH_FILES","EMBED_LINKS","SEND_MESSAGES","VIEW_CHANNEL"]
})
//add main adminroles
config.main_adminroles.forEach((role) => {
permissionsArray.push({
id:role,
type:"role",
allow:["ADD_REACTIONS","ATTACH_FILES","EMBED_LINKS","SEND_MESSAGES","VIEW_CHANNEL"]
})
})
//add ticket adminroles
/**
* @type {String[]}
*/
const ticketadmin = currentTicketOptions.adminroles
ticketadmin.forEach((role) => {
if (!config.main_adminroles.includes(role)){
permissionsArray.push({
id:role,
type:"role",
allow:["ADD_REACTIONS","ATTACH_FILES","EMBED_LINKS","SEND_MESSAGES","VIEW_CHANNEL"]
})
}
})
//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"){
permissionsArray.push({
id:config.system.member_role,
type:"role",
deny:["VIEW_CHANNEL"]
})
}
//create the channel
interaction.guild.channels.create(ticketName,{
type:"GUILD_TEXT",
parent:newTicketCategory,
reason:"A new ticket is created",
permissionOverwrites:permissionsArray
}).then((ticketChannel) => {
storage.set("userTicketStorage",ticketChannel.id,interaction.member.id)
var ticketEmbed = new discord.MessageEmbed()
.setAuthor({name:interaction.user.id})
.setColor(config.main_color)
.setTitle(currentTicketOptions.name)
if (currentTicketOptions.ticketmessage.length > 0) ticketEmbed.setDescription(currentTicketOptions.ticketmessage)
ticketChannel.send({
content:"<@"+interaction.member.id+"> @here",
embeds:[ticketEmbed],
components:[closeButton]
}).then(firstmsg => {
firstmsg.pin()
})
log("system","created new ticket",[{key:"ticket",value:ticketName},{key:"user",value:interaction.user.tag}])
})
}else{
try {
if (config.system.enable_DM_Messages){
interaction.member.send({embeds:[bot.errorLog.warning(l.errors.maxAmountTitle,l.errors.maxAmountDescription)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
}
}
})
}
+245
View File
@@ -0,0 +1,245 @@
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
module.exports = () => {
var closeRowNormal = new discord.MessageActionRow()
.addComponents(
new discord.MessageButton()
.setCustomId("closeTicket")
.setDisabled(false)
.setStyle("SECONDARY")
.setLabel(l.buttons.close)
.setEmoji("🔒")
)
.addComponents(
new discord.MessageButton()
.setCustomId("deleteTicket")
.setDisabled(false)
.setStyle("DANGER")
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
var closeRowClosed = 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("✔")
)
var reopenBar = new discord.MessageActionRow()
.addComponents(
new discord.MessageButton()
.setCustomId("reopenTicketTrue")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("✅")
)
.addComponents(
new discord.MessageButton()
.setCustomId("reopenTicketFalse")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("❌")
)
var reopenBar1 = new discord.MessageActionRow()
.addComponents(
new discord.MessageButton()
.setCustomId("reopenTicketTrue1")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("✅")
)
.addComponents(
new discord.MessageButton()
.setCustomId("reopenTicketFalse1")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("❌")
)
var reopenCommandBar = new discord.MessageActionRow()
.addComponents(
new discord.MessageButton()
.setCustomId("reopenTicket1")
.setDisabled(false)
.setStyle("SECONDARY")
.setEmoji("🔓")
)
//NORMAL WAY
client.on("interactionCreate",(interaction) => {
if (!interaction.isButton()) return
if (interaction.customId != "reopenTicket") return
interaction.deferUpdate()
interaction.message.edit({components:[reopenBar]})
})
client.on("interactionCreate",(interaction) => {
if (!interaction.isButton()) return
if (interaction.customId != "reopenTicketFalse") return
interaction.deferUpdate()
interaction.message.edit({components:[closeRowClosed]})
})
client.on("interactionCreate",(interaction) => {
if (!interaction.isButton()) return
if (interaction.customId != "reopenTicketTrue") return
interaction.deferUpdate()
const embed = new discord.MessageEmbed()
.setColor(config.main_color)
.setTitle(":unlock: "+l.messages.reopenTitle+" :unlock:")
.setDescription(l.messages.reopenDescription)
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}])
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)
})
//COMMAND WAY
client.on("interactionCreate",(interaction) => {
if (!interaction.isButton()) return
if (interaction.customId != "reopenTicket1") return
interaction.deferUpdate()
interaction.message.edit({components:[reopenBar1]})
})
client.on("interactionCreate",(interaction) => {
if (!interaction.isButton()) return
if (interaction.customId != "reopenTicketFalse1") return
interaction.deferUpdate()
interaction.message.edit({components:[reopenCommandBar]})
})
client.on("interactionCreate",(interaction) => {
if (!interaction.isButton()) return
if (interaction.customId != "reopenTicketTrue1") return
interaction.deferUpdate()
const embed = new discord.MessageEmbed()
.setColor(config.main_color)
.setTitle(":unlock: "+l.messages.reopenTitle+" :unlock:")
.setDescription(l.messages.reopenDescription)
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}])
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")}
})
})
}
+72
View File
@@ -0,0 +1,72 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const l = bot.language
/** @param {discord.TextBasedChannel} channel @returns {Promise<{ticketname:String,ticketopener:{discordjsuser:discord.User,name:String,id:String}>} */
const getUserInfo = (channel) => {
return new Promise((promiseresolve,reject) => {
//getID
var result = {
ticketopener:{
discordjsuser:"",
id:"/",
name:"/"
},
ticketname:"/"
}
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 ? firstmsg.embeds[0].author.name : false
result.ticketopener.id = id
const ticketopener = client.users.cache.find(u => u.id == id)
const name = ticketopener.tag
const channelname = channel.name
promiseresolve({ticketname:channelname,ticketopener:{discordjsuser:ticketopener,name:name,id:id}})
})
})
}
/**
*
* @param {discord.Message[]} messagecollection
* @param {discord.Channel} channel
* @returns new `discord.messageAttachment`
*/
exports.createTranscript = async (messagecollection,channel) => {
const ticketuserdata = await getUserInfo(channel)
try {
const cd = new Date()
const months = ["January","February","March","April","May","June","July","August","September","October","November","December"]
const dateString = cd.getDate()+" "+months[cd.getMonth()-1]+" "+cd.getFullYear()+" - "+cd.getSeconds()+":"+cd.getMinutes()+":"+cd.getHours()
const filearray = ["open ticket transcript:\ntranscript creation: "+dateString+"\nticket name: "+ticketuserdata.ticketname+"\nticket opener: "+ticketuserdata.ticketopener.name,"\nTRANSCRIPT START:"]
messagecollection.reverse()
messagecollection.forEach((msg) => {
const timestamp = new Date(msg.createdTimestamp)
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
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")
const filestring = filearray.join("\n")
const filebuff = Buffer.from(filestring,"utf-8")
return new discord.MessageAttachment(filebuff,"transcript_"+ticketuserdata.ticketname+".txt")
}catch(err){
console.log("[error] "+err)
return false
}
}
+94
View File
@@ -0,0 +1,94 @@
const discord = require("discord.js")
const bot = require("../../index")
const config = bot.config
const getoptions = require("../getoptions")
const l = bot.language
/**@returns {"DANGER"|"SUCCESS"|"PRIMARY"|"SECONDARY"} */
const getColor = (color) => {
if (color.toLowerCase() == "red"){
return "DANGER"
}else if (color.toLowerCase() == "green"){
return "SUCCESS"
}else if (color.toLowerCase() == "blue" || color.toLowerCase() == "blurple"){
return "PRIMARY"
}else if (color.toLowerCase() == "black" || color.toLowerCase() == "gray" || color.toLowerCase() == "grey"){
return "SECONDARY"
}else if (color == "DANGER" || color == "SECONDARY" || color == "SUCCESS" || color == "PRIMARY"){
return color
}else if (color.toLowerCase() == "none" || color.toLowerCase() == "false" || color.toLowerCase() == ""){
return "SECONDARY"
}else return "SECONDARY"
}
const getOption = (id) => {
const result = config.options.find((option) => option.id == id)
if (!result){return false}else return result
}
exports.getOption = getOption
/**
*
* @param {String} id
* @returns {discord.MessageButton|false}
*/
exports.getButton = (id) => {
const option = getOption(id)
if (!option) return false
if (option.type == "ticket"){
var button = new discord.MessageButton()
.setCustomId("newT"+option.id)
.setDisabled(false)
.setStyle(getColor(option.color))
if (option.label){button.setLabel(option.label)}
if (option.icon){button.setEmoji(option.icon)}
if (!option.label && !option.icon){button.setLabel("no label or emoji")}
}else if (option.type == "website"){
var button = new discord.MessageButton()
.setDisabled(false)
.setStyle("LINK")
.setURL(option.url)
if (option.label){button.setLabel(option.label)}
if (option.icon){button.setEmoji(option.icon)}
if (!option.label && !option.icon){button.setLabel("no label or emoji")}
}else if (option.type == "role"){
var button = new discord.MessageButton()
.setCustomId("newR"+option.id)
.setDisabled(false)
.setStyle(getColor(option.color))
if (option.label){button.setLabel(option.label)}
if (option.icon){button.setEmoji(option.icon)}
if (!option.label && !option.icon){button.setLabel("no label or emoji")}
}
return button
}
exports.rawButtonData = class {
constructor() {
this.id = ""
this.name = ""
this.description = ""
this.icon = ""
this.label = ""
this.type = ""
this.color = ""
this.enableDMMessage = true
this.url = ""
this.roles = ["",""]
this.mode = ""
this.adminroles = ["",""]
this.channelprefix = ""
this.category = ""
this.message = ""
this.ticketmessage = ""
}
}
+16
View File
@@ -0,0 +1,16 @@
const bot = require("../../index")
const config = bot.config
const l = bot.language
exports.getTicketMessage = (input) => {
var returned = config.messages.find(a => a.id == input)
if (returned){
return returned
}
var result = config.messages[0]
if (!result){
throw new Error("'messages' object in config.json is empty")
return
}
return result
}
+115 -16
View File
@@ -1,28 +1,127 @@
// __________ __________ ___________ ____ ____
// / ____ \ / ______ \ / | | \ | |
// | / \ | | | | | | |_______| | \ | |
// | | | | | |____| | | | | |\ \ | |
// | | | | | ________/ | |______ | | \ \ | |
// | | | | | | | _____| | | \ \ | |
// | | | | | | | | | | \ \ | |
// | | | | | | | |________ | | \ \| |
// | \____/ | | | | | | | \ |
// \__________/ |__| \__________| |__| \___|
const discord = require('discord.js') const discord = require('discord.js')
const config = require('./config.json') const fs = require('fs')
const intents = discord.Intents const intents = discord.Intents
const client = new discord.Client({intents:[intents.FLAGS.GUILDS,intents.FLAGS.GUILD_MESSAGES,intents.FLAGS.GUILD_MEMBERS]}) const client = new discord.Client({intents:[intents.FLAGS.GUILDS,intents.FLAGS.GUILD_MESSAGES,intents.FLAGS.GUILD_MEMBERS],partials:["CHANNEL"]})
exports.client = client exports.client = client
client.on('ready',() => { client.setMaxListeners(30)
console.log('ready')
client.user.setActivity("HighMT",{type:"PLAYING"}) if (process.argv[2]){
if (process.argv[2].endsWith("d")){
var isDev = true
console.log("starting in dev mode...")
}else{var isDev = false}
}else{var isDev = false}
exports.developerMode = isDev
const language = require("./core/languageManager").language
exports.language = language
if (isDev){
try {
var config = require('./devConfig.json')
}catch{
console.log("devConfig.json not found! Trying the normal config...")
var config = require("./config.json")
}
}else{var config = require('./config.json')}
exports.config = config
exports.errorLog = require("./core/errorLogSystem")
const log = this.errorLog.log
client.on('ready',async () => {
const chalk = await (await import("chalk")).default
if (!process.argv[2].startsWith("slash")){
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}])
console.log(chalk.blue("\n\nlogs:")+"\n============")
if (config.status.enabled){
client.user.setActivity(config.status.text,{type:config.status.type})
}
log("system","bot logged in!")
await client.guilds.cache.find((g) => g.id == config.server_id).members.fetch()
}else{
console.log(chalk.red("STARTING IN ")+chalk.blue("SLASH MODE")+chalk.red("..."))
console.log("logs:\n================")
console.log("client logged in...")
console.log("loading files...")
if (process.argv[3] == "enable"){
console.log(chalk.green("switching to slashEnable.js"))
require("./core/slashSystem/slashEnable")()
}else if (process.argv[3] == "disable"){
console.log(chalk.green("switching to slashDisable.js"))
require("./core/slashSystem/slashDisable")()
}else{
console.log(chalk.red("Internal Error: unknown slash mode!"))
process.exit(1)
}
}
}) })
var storage = require('./storage/storage') if (!isDev){
exports.TicketStorage = storage.ticketStorage require("./core/checker").checker()
exports.userTicketStorage = storage.userTicketStorage }
exports.transcriptStorage = storage.transcriptStorage
exports.ticketNumberStorage = storage.ticketNumberStorage
var ticket = require('./commands/ticket') if (process.argv[2] && !process.argv[2].startsWith("slash")){
ticket() var storage = require('./core/dynamicdatabase/storage')
exports.storage = storage
var ticketSystem = require('./commands/ticketSystem') //commands
ticketSystem() require('./commands/ticket')()
require("./commands/help")()
require("./commands/close")()
require("./commands/delete")()
require("./commands/rename")()
require("./commands/add")()
require("./commands/remove")()
require("./commands/reopen")()
var ticketExtra = require("./commands/ticketExtra") //core
ticketExtra() require('./core/ticketOpener')()
require("./core/ticketCloser").runThis()
require("./core/closebuttons")()
require("./core/reactionRoles")()
require("./core/ticketReopener")()
}
const debugLog = (debugString) => {
const content = fs.existsSync("./openticketdebug.txt") ? fs.readFileSync("./openticketdebug.txt").toString() : "==========================\n<OPEN TICKET DEBUG FILE:>\n=========================="
fs.writeFileSync("./openticketdebug.txt",content+"\nDEBUG: "+debugString)
}
const errorLog = (errorString,stack) => {
const content = fs.existsSync("./openticketdebug.txt") ? fs.readFileSync("./openticketdebug.txt").toString() : "==========================\n<OPEN TICKET DEBUG FILE:>\n=========================="
fs.writeFileSync("./openticketdebug.txt",content+"\nERROR: "+errorString+" STACK: "+stack)
}
client.on("debug", async (message) => {
if (message.startsWith("Provided token:")){
debugLog("Provided token: ***********bot token is invisible**************...")
return
}
debugLog(message)
});
process.on("uncaughtException",async (error,origin) => {
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"))
errorLog(error.name+": "+error.message+" | origin: "+origin,error.stack)
})
client.login(config.auth_token) client.login(config.auth_token)
+77
View File
@@ -0,0 +1,77 @@
{
"errors":{
"missingArgsTitle":"Invalid Arguments!",
"missingArgsDescription":"Missing Argument",
"noPermsTitle":"No Permissions!",
"noPermsDescription":"You don't have the correct roles to run this command!\nYou need the `ADMINISTRATOR` permission or be in the list of allowed roles!",
"chooseFromListTitle":"Invalid ID",
"chooseFromListDescription":"Choose one of the id's below:",
"boterror":"Bot Error!",
"notInTicketTitle":"You are not in a ticket!",
"notInTicketDescription":"This command doesn't work outside tickets!",
"ticketDoesntExist":"This ticket doesn't exist anymore!",
"roleDoesntExist":"This role doesn't exist anymore!",
"anotherOption":"This option is not a ticket but another type!",
"maxAmountTitle":"Max amount reached!",
"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!",
"somethingWentWrongTranscript":"Something went wrong while making the transcript!**\nPlease try again another time!"
},
"commands":{
"userAddedTitle":"User Added!",
"userAddedDescription":"{0} is added to this ticket!",
"userRemovedTitle":"User Removed!",
"userRemovedDescription":"{0} is removed from this ticket!",
"renameTitle":"The name is changed!",
"renameWarning":"Warning: you can only change the channel name 2 times per minute!\n(this is due discord rate limits)",
"closeTitle":"Close this ticket!",
"closeDescription":"You can close this ticket by clicking on the button below!",
"deleteTitle":"Delete this ticket!",
"deleteDescription":"You can delete this ticket by clicking on the button below!",
"reopenTitle":"Re-Open this ticket!",
"reopenDescription":"You can re-open this ticket by clicking on the button below!",
"ticketWarning":"The embed is in the message below!",
"maxTicketWarning":"**Warning:** _You can only create {0} ticket(s) at a time!_"
},
"helpMenu":{
"title":"Help Menu:",
"header1":"**Go to {0} to create a ticket!**\n\n",
"header2":"**Run the command `/new` or `/ticket` to create a ticket!**\n\n",
"msgCmd":"Spawn an embed with buttons. (admins only)",
"renameCmd":"Rename a ticket. (no spaces)",
"closeCmd":"Close a ticket.",
"deleteCmd":"Delete a ticket.",
"addCmd":"Add a user to the ticket.",
"removeCmd":"Remove a user from the ticket.",
"reopenCmd":"Re-Open a ticket after it was closed."
},
"buttons":{
"close":"Close Ticket",
"delete":"Delete Ticket",
"reopen":"Re-Open Ticket",
"sendTranscript":"Send Transcript File"
},
"messages":{
"reopenTitle":"Re-Opened this ticket!",
"reopenDescription":"Feel free to talk again!",
"closedTitle":"Closed this ticket!",
"closedDescription":"Only admins can talk in this ticket now!\n\n*Click on the button below to delete or to re-open this ticket!*",
"createdTitle":"Ticket Created!",
"createdDescription":"Your ticket is created, you can detect it by a ping!",
"newTicketDmTitle":"New Ticket!",
"closedTicketDmTitle":"Ticket Closed!",
"deletedTicketDmTitle":"Ticket Deleted!",
"closedTicketDmDescription":"Your ticket is closed!",
"deletedTicketDmDescription":"Your ticket is deleted!",
"newTranscriptTitle":"A new transcript is here!",
"newTranscriptDescription":"You can find the transcript in the text file above!",
"hereIsTheTranscript":"Here is the transcript:",
"chooseCategory":"choose a category:"
}
}
+79
View File
@@ -0,0 +1,79 @@
{
"errors":{
"missingArgsTitle":"Ongeldige Argumenten!",
"missingArgsDescription":"Geen Argument",
"noPermsTitle":"Geen permissies!",
"noPermsDescription":"Je hebt niet de juiste rollen om deze command uit te voeren!\nJe hebt de `ADMINISTRATOR` permissie nodig of je moet in de lijst van toegestane rollen zitten!",
"chooseFromListTitle":"Ongeldig ID",
"chooseFromListDescription":"Kies een van deze id's:",
"boterror":"Bot Error!",
"notInTicketTitle":"Je bent niet in een ticket!",
"notInTicketDescription":"Deze command werkt niet buiten tickets!",
"ticketDoesntExist":"Dit ticket bestaat niet meer!",
"roleDoesntExist":"Deze rol bestaat niet meer!",
"anotherOption":"Deze optie is geen ticket maar een ander type!",
"maxAmountTitle":"Max aantal bereikt!",
"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!",
"somethingWentWrongTranscript":"Iets ging fout bij het maken van het transcript!**\nProbeer een andere keer opnieuw!"
},
"commands":{
"userAddedTitle":"User Toegevoegd!",
"userAddedDescription":"{0} is toegevoegd aan dit ticket!",
"userRemovedTitle":"User Verwijderd!",
"userRemovedDescription":"{0} is verwijderd van dit ticket!",
"renameTitle":"De naam is veranderd!",
"renameWarning":"Waarschuwing: je kan de kanaalnaam maar 2 keer per minuut veranderen!\n(dit heeft te maken met discord rate limits)",
"closeTitle":"Sluit dit ticket!",
"closeDescription":"Je kan dit ticket sluiten door op de knop hier onder te duwen!",
"deleteTitle":"Verwijder dit ticket!",
"deleteDescription":"Je kan dit ticket verwijderen door op de knop hier onder te duwen!",
"reopenTitle":"Heropen dit ticket!",
"reopenDescription":"Je kan dit ticket heropenen door op de knop hier onder te duwen!",
"ticketWarning":"De embed is in het bericht hier onder!",
"maxTicketWarning":"**Waarschuwing:** _Je kan maar {0} ticket(s) tegelijkertijd aanmaken!_"
},
"helpMenu":{
"title":"Help Menu:",
"header1":"**Ga naar {0} om een ticket te maken!**\n\n",
"header2":"**Run de command `/new` of `/ticket` om een ticket te maken!**\n\n",
"msgCmd":"Spawn een embed met knoppen. (admins only)",
"renameCmd":"Hernoem een ticket. (geen spaties)",
"closeCmd":"Sluit een ticket.",
"deleteCmd":"Verwijder een ticket.",
"addCmd":"Voeg een user toe aan een ticket.",
"removeCmd":"Verwijder een user van een ticket.",
"reopenCmd":"Heropen een ticket nadat het gesloten wordt."
},
"buttons":{
"close":"Sluit Ticket",
"delete":"Verwijder Ticket",
"reopen":"Heropen Ticket",
"sendTranscript":"Stuur Transcript Bestand"
},
"messages":{
"reopenTitle":"Dit ticket is terug geopend!",
"reopenDescription":"Voel vrij om terug te praten!",
"closedTitle":"Dit ticket is gesloten!",
"closedDescription":"Nu kunnen alleen nog admins praten in dit ticket!\n\n*Klik op de knop hier onder om het ticket terug te openen of te verwijderen!*",
"createdTitle":"Ticket Gemaakt!",
"createdDescription":"Je ticket is gemaakt, je kan het detecteren bij een ping!",
"newTicketDmTitle":"Nieuw Ticket!",
"closedTicketDmTitle":"Ticket Gesloten!",
"deletedTicketDmTitle":"Ticket Verwijderd!",
"closedTicketDmDescription":"Je ticket is gesloten!",
"deletedTicketDmDescription":"Je ticket is verwijderd!",
"reopenTicketDmTitle":"Ticket Heropend!",
"reopenTicketDmDescription":"Je ticket is heropend!",
"newTranscriptTitle":"Een nieuw transcript is hier!",
"newTranscriptDescription":"Je kan het transcript vinden in het bestand hierboven!",
"hereIsTheTranscript":"Hier is het transcript:",
"chooseCategory":"kies een categorie:"
}
}
+79
View File
@@ -0,0 +1,79 @@
{
"errors":{
"missingArgsTitle":"Invalid Arguments!",
"missingArgsDescription":"Missing Argument",
"noPermsTitle":"No Permissions!",
"noPermsDescription":"You don't have the correct roles to run this command!\nYou need the `ADMINISTRATOR` permission or be in the list of allowed roles!",
"chooseFromListTitle":"Invalid ID",
"chooseFromListDescription":"Choose one of the id's below:",
"boterror":"Bot Error!",
"notInTicketTitle":"You are not in a ticket!",
"notInTicketDescription":"This command doesn't work outside tickets!",
"ticketDoesntExist":"This ticket doesn't exist anymore!",
"roleDoesntExist":"This role doesn't exist anymore!",
"anotherOption":"This option is not a ticket but another type!",
"maxAmountTitle":"Max amount reached!",
"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!",
"somethingWentWrongTranscript":"Something went wrong while making the transcript!**\nPlease try again another time!"
},
"commands":{
"userAddedTitle":"User Added!",
"userAddedDescription":"{0} is added to this ticket!",
"userRemovedTitle":"User Removed!",
"userRemovedDescription":"{0} is removed from this ticket!",
"renameTitle":"The name is changed!",
"renameWarning":"Warning: you can only change the channel name 2 times per minute!\n(this is due discord rate limits)",
"closeTitle":"Close this ticket!",
"closeDescription":"You can close this ticket by clicking on the button below!",
"deleteTitle":"Delete this ticket!",
"deleteDescription":"You can delete this ticket by clicking on the button below!",
"reopenTitle":"Re-Open this ticket!",
"reopenDescription":"You can re-open this ticket by clicking on the button below!",
"ticketWarning":"The embed is in the message below!",
"maxTicketWarning":"**Warning:** _You can only create {0} ticket(s) at a time!_"
},
"helpMenu":{
"title":"Help Menu:",
"header1":"**Go to {0} to create a ticket!**\n\n",
"header2":"**Run the command `/new` or `/ticket` to create a ticket!**\n\n",
"msgCmd":"Spawn an embed with buttons. (admins only)",
"renameCmd":"Rename a ticket. (no spaces)",
"closeCmd":"Close a ticket.",
"deleteCmd":"Delete a ticket.",
"addCmd":"Add a user to the ticket.",
"removeCmd":"Remove a user from the ticket.",
"reopenCmd":"Re-Open a ticket after it was closed."
},
"buttons":{
"close":"Close Ticket",
"delete":"Delete Ticket",
"reopen":"Re-Open Ticket",
"sendTranscript":"Send Transcript File"
},
"messages":{
"reopenTitle":"Re-Opened this ticket!",
"reopenDescription":"Feel free to talk again!",
"closedTitle":"Closed this ticket!",
"closedDescription":"Only admins can talk in this ticket now!\n\n*Click on the button below to delete or to re-open this ticket!*",
"createdTitle":"Ticket Created!",
"createdDescription":"Your ticket is created, you can detect it by a ping!",
"newTicketDmTitle":"New Ticket!",
"closedTicketDmTitle":"Ticket Closed!",
"deletedTicketDmTitle":"Ticket Deleted!",
"closedTicketDmDescription":"Your ticket is closed!",
"deletedTicketDmDescription":"Your ticket is deleted!",
"reopenTicketDmTitle":"Ticket Re-opened!",
"reopenTicketDmDescription":"Your ticket is re-opened!",
"newTranscriptTitle":"A new transcript is here!",
"newTranscriptDescription":"You can find the transcript in the text file above!",
"hereIsTheTranscript":"Here is the transcript:",
"chooseCategory":"choose a category:"
}
}
+79
View File
@@ -0,0 +1,79 @@
{
"errors":{
"missingArgsTitle":"Argumente invalide!",
"missingArgsDescription":"Argument lipsa",
"noPermsTitle":"Nu ai permisiunile necesare!",
"noPermsDescription":"Nu ai rolurile necesare!\nAi nevoie de permisiunea `ADMINISTRATOR` sau sa fii in lista rolurilor permise!",
"chooseFromListTitle":"ID invalid",
"chooseFromListDescription":"Alege unul dintre id-urile urmatoare:",
"boterror":"Eroare bot!",
"notInTicketTitle":"Nu esti intr-un ticket!",
"notInTicketDescription":"Aceasta comanda nu functioneaza in afara ticket-urilor!",
"ticketDoesntExist":"Acest ticket nu mai exista!",
"roleDoesntExist":"Acest rol nu mai exista",
"anotherOption":"Aceasta optiune nu este un ticket ci doar alt tip!",
"maxAmountTitle":"Limita a fost atinsa",
"maxAmountDescription":"Ai atins limita maxima de tickete\nNu mai poti creea altele!",
"somethingWentWrong":"**Ceva nu a mers bine :(**\nTe rugam sa incerci din nou mai tarziu",
"somethingWentWrongTranscript":"**Ceva nu a mers bine in timpul creerii copiei a ticket-ului!**\nTe rugam sa incerci din nou mai tarziu!"
},
"commands":{
"userAddedTitle":"Utilizator adaugat!",
"userAddedDescription":"{0} este adaugat la acest ticket!",
"userRemovedTitle":"Utilizator eliminat!",
"userRemovedDescription":"{0} este eliminat din acest ticket!",
"renameTitle":"Numele este schimbat!",
"renameWarning":"ATENTIE: poti schimba numele acestui ticket doar de 2 ori pe minut!\n(se datoreaza limitarii discord-ului)",
"closeTitle":"Inchide acest ticket",
"closeDescription":"Poti inchide acest ticket doar apasand butonul de mai jos!",
"deleteTitle":"Sterge acest ticket!",
"deleteDescription":"Poti sterge acest ticket doar apasand butonul de mai jos",
"reopenTitle":"Re-deschide acest ticket!",
"reopenDescription":"Poti redeschide acest ticket doar apasand butonul de mai jos!",
"ticketWarning":"Embed-ul se afla in mesajul de mai jos:",
"maxTicketWarning":"**ATENTIE:** _Poti creea doar {0} ticket-e odata!_"
},
"helpMenu":{
"title":"Meniu de ajutor:",
"header1":"**Deschide {0} pentru a creea un ticket!**\n\n",
"header2":"**Ruleaza comanda `/new` ori `/ticket` pentru a creea un ticket!**\n\n",
"msgCmd":"Afiseaza embed-ul cu tickete. (doar administratorii)",
"renameCmd":"Redenumeste un ticket. (fara spatii)",
"closeCmd":"Redenumeste un ticket ticket.",
"deleteCmd":"Sterge un ticket a ticket.",
"addCmd":"adauga un utilizator la ticket.",
"removeCmd":"Elimina un utilizator de la ticket.",
"reopenCmd":"Re-deschide un ticket dupa ce a fost inchis."
},
"buttons":{
"close":"Inchide Ticket-ul",
"delete":"Sterge Ticket-ul",
"reopen":"Re-deschide Ticket-ul",
"sendTranscript":"Trimite copia chat-ului ticket-ului"
},
"messages":{
"reopenTitle":"Ticket re-deschis",
"reopenDescription":"Simte-te comfortabil sa vorbesti din nou!",
"closedTitle":"Inchide acest ticket ticket!",
"closedDescription":"Doar administratorii pot vorbi in acest ticket de acum!\n\n*Apasa pe butonele de mai jos pentru a inchide/deschide ticket-ul!*",
"createdTitle":"Ticket Creat!",
"createdDescription":"Ticket-ul tau a fost creat, il poti vedea dupa mentionarea ta!",
"newTicketDmTitle":"Ticket Nou!",
"closedTicketDmTitle":"Ticket închis!",
"deletedTicketDmTitle":"Ticket șters!",
"closedTicketDmDescription":"Ticket-ul tau este închis!",
"deletedTicketDmDescription":"Ticket-ul tau este șters!",
"reopenTicketDmTitle":"Ticket Re-deschis!",
"reopenTicketDmDescription":"Ticket-ul tau este re-deschis!",
"newTranscriptTitle":"O noua copie a ticket-ului este aici!",
"newTranscriptDescription":"Poti vedea copia ticket-ului in fisierul .txt de mai sus!",
"hereIsTheTranscript":"Aceasta este copia ticket-ului:",
"chooseCategory":"Alege o categorie:"
}
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

+19 -8
View File
@@ -1,19 +1,30 @@
{ {
"name": "safemt-tickets", "name": "open-ticket",
"version": "1.0.0", "version": "2.1.0",
"description": "", "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": "echo \"Error: no test specified\" && exit 1",
"slashEnable": "node index.js slash enable",
"slashDisable": "node index.js slash disable",
"cleardata": "node ./core/dynamicdatabase/cleardata.js"
}, },
"author": "", "author": "DJdj Development",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"canvas": "^2.8.0", "chalk": "^5.0.1",
"discord.js": "^13.2.0", "discord.js": "^13.8.0",
"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"
} },
"repository": {
"type": "git",
"url": "git+https://github.com/DJj123dj/open-ticket.git"
},
"bugs": {
"url": "https://github.com/DJj123dj/open-ticket/issues"
},
"homepage": "https://github.com/DJj123dj/open-ticket#readme"
} }
BIN
View File
Binary file not shown.
-14
View File
@@ -1,14 +0,0 @@
const LocalStorage = require("node-localstorage")
const ticketStorage = new LocalStorage.LocalStorage("./storage/tickets")
exports.ticketStorage = ticketStorage
const userTicketStorage = new LocalStorage.LocalStorage("./storage/userTickets")
exports.userTicketStorage = userTicketStorage
const transcriptStorage = new LocalStorage.LocalStorage("./storage/transcripts")
exports.transcriptStorage = transcriptStorage
//const ticketNumberStorage = new LocalStorage.LocalStorage("./storage/ticketNumbers")
//exports.ticketNumberStorage = ticketNumberStorage