1.4.0 beta

This commit is contained in:
DJj123dj
2022-05-02 11:07:56 +02:00
parent 5fc3ba3279
commit af8d6351af
53 changed files with 1323 additions and 903 deletions
+218
View File
@@ -0,0 +1,218 @@
/** =============================
** NOT READY YET
** =============================*/
module.exports = 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 ERROR: "+message)
}
const createWarn = (message) => {
isWarn = true
warnList.push("open-ticket WARNING: "+message)
}
//checker
//token
if (config.auth_token.includes(" ")){
createError("invalid token | there are spaces in your token!")
}
if (config.auth_token.length < 40){
createError("invalid token | length not correct!")
}
//color
if (!config.main_color.startsWith("#")){
createError("color not detected | 'main_color' doesn't start with a '#'!")
}
if (config.main_color.length > 7 || config.main_color.length < 7){
createError("color not detected | 'main_color' is not a valid hex color!")
}
//admin
if (config.botperms_role.includes(" ")){
createError("invalid role id | 'botperms_role' is not a valid role id!")
}
if (config.botperms_role.length > 20|| config.botperms_role.length < 16){
createError("invalid role id | 'botperms_role' is not a valid role id!")
}
//prefix
if (config.prefix == ""){
createError("no prefix | 'prefix' is empty!")
}
if (config.prefix.length > 3){
createWarn("long prefix | your prefix is a little bit long!")
}
//status
if (config.status.enabled && (config.status.type != "PLAYING" && config.status.type != "LISTENING" && config.status.type != "WATCHING" && config.status.type != "CUSTOM")){
createError("status error | 'status/type' is invalid!")
}
if (config.status.enabled && config.status.text.length < 1){
createError("status error | 'status/text' must be at least 1 character long!")
}
//ticketchannel
if (config.system.ticket_channel.includes(" ")){
createWarn("invalid channel id | 'system/ticket_channel' is not a valid channel id!")
}
if (config.system.ticket_channel.length < 1){
createWarn("no ticket channel | 'system/ticket_channel' is empty")
}else if (config.system.ticket_channel.length > 20|| config.system.ticket_channel.length < 16){
createWarn("invalid channel id | 'system/ticket_channel' is not a valid channel id!")
}
//maxticket
if (config.system.max_allowed_tickets < 1){
createWarn("no tickets | if 'system/max_allowed_tickets' is under 1 you can't create any ticket")
}
//category
if (config.system.enable_category == true && config.system.ticket_category.includes(" ")){
createError("invalid category id | 'system/ticket_category' is not a valid category id!")
}
if (config.system.enable_category && config.system.ticket_category.length > 20 || config.system.ticket_category.length < 16){
createError("invalid category id | 'system/ticket_category' is not a valid category id!")
}
//everyoneaccess
if (config.system["has@everyoneaccess"] == true){
createWarn("access | everyone has access to the tickets!")
}
//memberrole
if (config.system.member_role.includes(" ")){
createError("invalid role id | 'system/member_role' is not a valid role id!")
}
if (config.system.member_role.length > 20){
createError("invalid role id | 'system/member_role' is not a valid role id!")
}
if (config.system.member_role == "" || config.system.member_role == " " || config.system.member_role == "false" || config.system.member_role == "null" || config.system.member_role == "0"){
createWarn("no member role | 'system/member_role' is not valid so technically everyone can view a ticket!")
}
//transcript
if (config.system.enable_transcript && config.system.transcript_channel.includes(" ")){
createError("invalid channel id | 'system/transcript_channel' is not a valid channel id!")
}
if (config.system.enable_transcript && config.system.transcript_channel.length > 20 || config.system.transcript_channel.length < 16){
createError("invalid channel id | 'system/transcript_channel' is not a valid channel id!")
}
//messages
if (config.messages.general.nopermissions.length < 1){
createError("no message | 'messages/general/nopermissions' is empty!")
}
if (config.messages.ticket.newTicketEmbed.length < 1){
createError("no message | 'messages/ticket/newTicketEmbed' is empty!")
}
if (config.messages.dm.alreadyCreated.length < 1){
createError("no message | 'messages/dm/alreadyCreated' is empty!")
}
if (config.messages.dm.newTicket.length < 1){
createError("no message | 'messages/dm/newTicket' is empty!")
}
if (config.messages.dm.closeTicket.length < 1){
createError("no message | 'messages/dm/closeTicket' is empty!")
}
//layout
const checkLayout = (layout,layoutname,color,footer,thumbnail) => {
if (color){
if (!layout.customColor.startsWith("#")){
createError("color not detected | 'layout/"+layoutname+"/customColor' doesn't start with a '#'!")
}
if (layout.customColor.length > 7 || layout.customColor.length < 7){
createError("color not detected | 'layout/"+layoutname+"/customColor' is not a valid hex color!")
}
}
if (footer){
if (layout.footer.length < 1){
createError("no footer | 'layout/"+layoutname+"/footer' doesn't have a footer!")
}
}
if (thumbnail){
if (!layout.thumbnailURL.startsWith("https://") && !layout.thumbnailURL.startsWith("http://")){
createError("thumbnail | the thumbnail url in 'layout/"+layoutname+"/thumbnailURL' is not a valid url!")
}
}
}
checkLayout(config.layout.ticketEmbed,"ticketEmbed",config.layout.ticketEmbed.customColorEnabled,config.layout.ticketEmbed.footerEnabled,config.layout.ticketEmbed.thumbnailEnabled)
checkLayout(config.layout.ticketMsg,"ticketMsg",config.layout.ticketMsg.customColorEnabled,config.layout.ticketMsg.footerEnabled,config.layout.ticketMsg.thumbnailEnabled)
checkLayout(config.layout.transcripts,"transcripts",config.layout.transcripts.customColorEnabled,false,config.layout.transcripts.thumbnailEnabled)
const checkOption = (ticket,ticketname,enabled,urlmode) => {
if (enabled){
if (ticket.icon.length > 0){
const emojiRegex = /\p{Emoji}/u
const isEmoji = emojiRegex.test(ticket.icon)
if (isEmoji == false){
createWarn("invalid emoji | 'options/"+ticketname+"/icon' is not a valid emoji (code can be wrong)")
}
}
if (ticket.description.length < 1){
createWarn("no description | 'options/"+ticketname+"/description' is empty")
}
if (ticket.name.length < 1){
createWarn("no description | 'options/"+ticketname+"/name' is empty")
}
if (ticket.channel_prefix.length < 1){
createWarn("no description | 'options/"+ticketname+"/channel_prefix' is empty")
}
if (ticket.isURL == true && ticket.color != "red" && ticket.color != "blue" && ticket.color != "green" && ticket.color != "gray" && ticket.color != "none"){
createWarn("invalid button color | 'options/"+ticketname+"/color' must be one of (red,green,blue,gray,none)")
}
if (urlmode && (!ticket.url.startsWith("https://") && !ticket.url.startsWith("http://"))){
createError("url invalid | the url in 'options/"+ticketname+"/url' is not a valid url!")
}
}
return
}
checkOption(config.options.ticket1,"ticket1",config.options.ticket1.enabled,config.options.ticket1.isURL)
checkOption(config.options.ticket2,"ticket2",config.options.ticket2.enabled,config.options.ticket2.isURL)
checkOption(config.options.ticket3,"ticket3",config.options.ticket3.enabled,config.options.ticket3.isURL)
checkOption(config.options.ticket4,"ticket4",config.options.ticket4.enabled,config.options.ticket4.isURL)
checkOption(config.options.ticket5,"ticket5",config.options.ticket5.enabled,config.options.ticket5.isURL)
checkOption(config.options.ticket6,"ticket6",config.options.ticket6.enabled,config.options.ticket6.isURL)
//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!"))
}
}
+206
View File
@@ -0,0 +1,206 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = require("../config.json")
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("Close Ticket")
.setEmoji("🔒")
)
.addComponents(
new discord.MessageButton()
.setCustomId("deleteTicket")
.setDisabled(false)
.setStyle("DANGER")
.setLabel("Delete Ticket")
.setEmoji("❌")
)
var closeRowClosed = new discord.MessageActionRow()
.addComponents(
new discord.MessageButton()
.setCustomId("deleteTicket1")
.setDisabled(false)
.setStyle("DANGER")
.setLabel("Delete Ticket")
.setEmoji("❌")
)
.addComponents(
new discord.MessageButton()
.setCustomId("sendTranscript")
.setDisabled(false)
.setStyle("SECONDARY")
.setLabel("Send Transcript File")
.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()
interaction.message.edit({components:[closeRowClosed]})
/**
* @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()
/**
* @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()
/**
* @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")
})
}
+18
View File
@@ -0,0 +1,18 @@
/** =============================
** 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
+113
View File
@@ -0,0 +1,113 @@
const config = require("../config.json")
/**
* @param {Number} index
* @param {"id"|"name"|"description"|"icon"|"label"|"type"|"color"|"adminroles"|"channelprefix"|"category"|"message"|"enableDMMessage"} 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"} 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
}
}
/**
*
* @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
}
}
+23
View File
@@ -0,0 +1,23 @@
const discord = require("discord.js")
const client = require("../../index").client
const config = require("../../config.json")
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!"))
}
})
}
+162
View File
@@ -0,0 +1,162 @@
const discord = require("discord.js")
const client = require("../../index").client
const config = require("../../config.json")
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)
console.log(option.id)
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
setInterval(() => {
console.log("[status] there are "+chalk.blue(readystats+" out of 8")+" commands ready! (this can take some time)")
if (readystats >= 8){
console.log(chalk.green("ready!"))
console.log(chalk.blue("you can now start the bot with 'npm start'!"))
process.exit(1)
}
},1000)
//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++
})
}
+153
View File
@@ -0,0 +1,153 @@
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
/**
*
* @param {discord.Interaction} interaction
* @param {String} prefix
* @param {"delete"|"close"|"deletenotranscript"} mode
*/
exports.closeTicket = async (interaction,prefix,mode) => {
const channelmessages = await interaction.channel.messages.fetch()
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 = userTicketStorage.getItem(interaction.channel.id)
var getusernameStep1 = client.users.cache.find(u => u.id === getuserID)
var enableTranscript = true
if (mode == "delete"){
interaction.channel.delete()
if (config.logs){console.log("[system] deleted a ticket (name:"+interaction.channel.name+",user:"+interaction.user.username+")")}
ticketStorage.setItem(getuserID,Number(ticketStorage.getItem(getuserID)) - 1)
}else if (mode == "close"){
var permissionArray = []
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("Delete Ticket")
.setEmoji("❌")
)
.addComponents(
new discord.MessageButton()
.setCustomId("sendTranscript")
.setDisabled(false)
.setStyle("SECONDARY")
.setLabel("Send Transcript File")
.setEmoji("📄")
)
const embed = new discord.MessageEmbed()
.setColor(config.main_color)
.setTitle("Closed this ticket!")
.setDescription("Only admins can now talk in this ticket!\n\n*Click on the button below to delete this ticket*")
interaction.channel.send({embeds:[embed],components:[closeButtonRow]})
}else if (mode == "deletenotranscript"){
enableTranscript = false
interaction.channel.delete()
if (config.logs){console.log("[system] deleted a ticket (name:"+interaction.channel.name+",user:"+interaction.user.username+")")}
ticketStorage.setItem(getuserID,Number(ticketStorage.getItem(getuserID)) - 1)
}
if (enableTranscript == true && mode != "deletenotranscript"){
if (config.system.enable_transcript || config.system.enable_DM_transcript){
var fileattachment = await require("./transcript").createTranscript(channelmessages)
if (fileattachment == false){console.log("[transcript] internal error: no transcript is created!");return}
}
if (getusernameStep1 == null || getusernameStep1 == undefined || getusernameStep1 == false || getusernameStep1 == ""){
var getuserNAME = ":usernotfound:"
}else {
var getuserNAME = getusernameStep1.username
}
if (config.system.enable_transcript){
const transcriptEmbed = new discord.MessageEmbed()
.setColor(config.main_color)
.setTitle("A new transcript is here!")
.setAuthor({name:interaction.user.username,iconURL:interaction.user.displayAvatarURL({format:"png"})})
.setDescription("You can find the transcript in the text file above!")
.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("Here is a transcript of your ticket!")
.setDescription("You can find the transcript in the text file above!")
.setFooter({text:"ticket: "+ticketuserarray})
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)
if (fileattachment == false){
console.log("[transcript] internal error: no transcript is created!")
interaction.channel.send({content:"**Something went wrong while making the transcript!**\nPlease try again another time!"})
return
}
interaction.channel.send({content:"**Here is the transcript:**",files:[fileattachment]})
})
}
+133
View File
@@ -0,0 +1,133 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = require("../config.json")
const getOptions = require("./getoptions")
const getbyId = getOptions.getOptionsById
/**
*
* @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 {getOptions.exportedOptionClass[]}*/
var buttons = []
data.options.forEach((option) => {
var optionIdStats = getbyId("newT"+option)
if (!optionIdStats){
var optionIdStats = {
id:"NOTICKET",
name:"ERROR",
description:"There is a ticket in your config.json/messages that doesn't exist.",
icon:"",
label:"ERROR",
type:"ticket",
color:"red",
adminroles:["0"],
channelprefix:"error-",
category:"",
message:"ERROR!",
enableDMMessage:false
}
return
}
buttons.push(optionIdStats)
})
//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__choose a category:__\n"
var ticketExplainations = []
buttons.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**Warning:** _You can only create "+config.system.max_allowed_tickets+" ticket(s) at a time!_"
}
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())
}
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"
}
buttons.forEach((button,index) => {
if (button.label){var label = button.label}else{var label = null}
if (button.icon){var icon = button.icon}else{var icon = null}
var color = getColor(button.color)
componentRows[currentRow].addComponents([
new discord.MessageButton()
.setCustomId("newT"+button.id)
.setLabel(label)
.setEmoji(icon)
.setStyle(color)
.setDisabled(false)
])
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()
+171
View File
@@ -0,0 +1,171 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = require("../config.json")
const getconfigoptions = require("./getoptions")
const ticketStorage = bot.TicketStorage
const userTicketStorage = bot.userTicketStorage
const transcriptStorage = bot.transcriptStorage
module.exports = () => {
var closeButton = new discord.MessageActionRow()
.addComponents(
new discord.MessageButton()
.setCustomId("closeTicket")
.setDisabled(false)
.setStyle("SECONDARY")
.setLabel("Close Ticket")
.setEmoji("🔒")
)
.addComponents(
new discord.MessageButton()
.setCustomId("deleteTicket")
.setDisabled(false)
.setStyle("DANGER")
.setLabel("Delete Ticket")
.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 (getconfigoptions.getTicketValues("id").includes(customId)){
if (interaction.isButton()){
interaction.deferUpdate()
}else if (interaction.isCommand()){
interaction.reply({content:"Your ticket is created!"})
}
//ticketoptions from config
const currentTicketOptions = getconfigoptions.getOptionsById(customId)
if (ticketStorage.getItem(interaction.member.id) == null || ticketStorage.getItem(interaction.member.id) == "false"|| Number(ticketStorage.getItem(interaction.member.id)) < config.system.max_allowed_tickets){
try{
if (config.system.enable_DM_Messages){
interaction.member.send({content:currentTicketOptions.message})
}
}
catch{console.log("[system] can't send DM to member, member doesn't allow dm's")}
//update storage
ticketStorage.setItem(interaction.member.id,Number(ticketStorage.getItem(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 was created",
permissionOverwrites:permissionsArray
}).then((ticketChannel) => {
userTicketStorage.setItem(ticketChannel.id,interaction.member.id)
var ticketEmbed = new discord.MessageEmbed()
.setColor(config.main_color)
.setTitle("You created a ticket!")
.setDescription("The staff will help you soon!\n\n*Click on the button below to close the ticket!*")
ticketChannel.send({
content:"<@"+interaction.member.id+"> @everyone",
embeds:[ticketEmbed],
components:[closeButton]
}).then(firstmsg => {
firstmsg.pin()
})
if (config.logs){console.log("[system] created a new ticket (name:"+logsname+",user:"+interaction.user.username+")")}
})
}else{
try {
if (config.system.enable_DM_Messages){
interaction.member.send("you already have the maximum number of tickets allowed!")
}
}
catch{console.log("[system] can't send DM to member, member doesn't allow dm's")}
}
}
})
}
+36
View File
@@ -0,0 +1,36 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = require("../config.json")
/**
*
* @param {discord.Message[]} messagecollection
* @returns new `discord.messageAttachment`
*/
exports.createTranscript = async (messagecollection) => {
try {
const filearray = ["TRANSCRIPT 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.txt")
}catch(err){
console.log(err)
return false
}
}
+13
View File
@@ -0,0 +1,13 @@
const config = require("../../config.json")
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
}