diff --git a/README.md b/README.md index 819bed8..b60fb15 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,13 @@ There will be massive improvements for more stability & features! But the best p 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-3.5.4-brightgreen.svg?style=flat-square)](https://github.com/DJj123dj/open-ticket/releases/tag/v3.5.4) [![discord.js](https://img.shields.io/badge/discord.js-v14-CB3837.svg?style=flat-square&logo=npm)]() [![license](https://img.shields.io/badge/license-GPL%203.0-important.svg?style=flat-square)](https://github.com/DJj123dj/open-ticket/blob/main/LICENSE) [![stars](https://img.shields.io/github/stars/djj123dj/open-ticket?color=yellow&label=stars&logo=github&style=flat-square)](https://docs.openticket.dj-dj.be) +[![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-3.5.4-brightgreen.svg?style=flat-square)](https://github.com/DJj123dj/open-ticket/releases/tag/v3.5.4) [![discord.js](https://img.shields.io/badge/discord.js-v14-CB3837.svg?style=flat-square&logo=npm)]() [![license](https://img.shields.io/badge/license-GPL%203.0-important.svg?style=flat-square)](https://github.com/DJj123dj/open-ticket/blob/main/LICENSE) [![stars](https://img.shields.io/github/stars/djj123dj/open-ticket?color=yellow&label=stars&logo=github&style=flat-square)](https://otdocs.dj-dj.be) ### Open Ticket Open Ticket is the most customisable discord ticket bot that you will ever find! There are more than 150 options to customise in the config! This includes html transcripts, unlimited tickets, custom embeds & more! Did you know that even the html transcripts are highly customisable? Don't wait and check it out! If you're having trouble setting the bot up, feel free to join our support server and we will help you further! Take a look at all the features and discover the possibilities! -### [Visit the Documentation!](https://docs.openticket.dj-dj.be/quick-start) +### [Visit the Documentation!](https://otdocs.dj-dj.be/quick-start) ## Features - **🎉 advanced html transcripts!** @@ -70,10 +70,11 @@ Take a look at all the features and discover the possibilities! |Indonesian |erxg |🟢 Up To Date | |Kurdish |raze.hama |🟢 Up To Date | |Hungarian |Snowy |🔴 Outdated | +|Persian |sasanwm |🟢 Up To Date | ## links current version: _v3.5.4_
changelog: [click here](https://otgithub.dj-dj.be/releases) -
documentation: [click here](https://docs.openticket.dj-dj.be/quick-start) +
documentation: [click here](https://otdocs.dj-dj.be/quick-start) -© 2023 - DJdj Development | [website](https://www.dj-dj.be) | [discord](https://discord.dj-dj.be) | [terms of service](https://www.dj-dj.be/terms) +© 2024 - DJdj Development | [website](https://www.dj-dj.be) | [discord](https://discord.dj-dj.be) | [terms of service](https://www.dj-dj.be/terms) diff --git a/commands/close.js b/commands/close.js index 51694c7..f24e802 100644 --- a/commands/close.js +++ b/commands/close.js @@ -57,8 +57,6 @@ module.exports = () => { const reason = interaction.options.getString("reason") ? interaction.options.getString("reason") : false - - const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id) if (hiddendata.length < 1) return interaction.reply({embeds:[bot.errorLog.notInATicket]}) const ticketId = hiddendata.find(d => d.key == "type").value diff --git a/commands/reopen.js b/commands/reopen.js index b02cc3d..6e56f95 100644 --- a/commands/reopen.js +++ b/commands/reopen.js @@ -23,7 +23,7 @@ module.exports = () => { msg.channel.send({embeds:[bot.embeds.commands.reopenEmbed(msg.author)],components:[bot.buttons.close.openRowNormal]}) - require("../core/ticketActions/ticketReopener").reopenTicket(msg.guild,msg.channel,msg.author) + require("../core/ticketActions/ticketReopener").reopenTicket(msg.guild,msg.channel,msg.author,ticketId) log("command","someone used the 'reopen' command",[{key:"user",value:msg.author.username}]) APIEvents.onCommand("reopen",true,msg.author,msg.channel,msg.guild,new Date()) @@ -43,7 +43,7 @@ module.exports = () => { await interaction.editReply({embeds:[bot.embeds.commands.reopenEmbed(interaction.user)],components:[bot.buttons.close.openRowNormal]}) - require("../core/ticketActions/ticketReopener").reopenTicket(interaction.guild,interaction.channel,interaction.user) + require("../core/ticketActions/ticketReopener").reopenTicket(interaction.guild,interaction.channel,interaction.user,ticketId) log("command","someone used the 'reopen' command",[{key:"user",value:interaction.user.username}]) APIEvents.onCommand("reopen",true,interaction.user,interaction.channel,interaction.guild,new Date()) diff --git a/config.json b/config.json index cf6362f..1f1a418 100644 --- a/config.json +++ b/config.json @@ -1,4 +1,7 @@ { + "_DOCUMENTATION":"https://otdocs.dj-dj.be", + "_SUPPORT":"https://discord.dj-dj.be", + "color":"#ffffff", "serverId":"server id (for slash cmds)", "token":{ @@ -28,10 +31,9 @@ "answerInEphemeralOnOpen":true }, - "SUPPORT":"Take look at our wiki: https://docs.openticket.dj-dj.be or join our discord server: https://discord.dj-dj.be if you need support!", "options":[ { - "id":"general", + "id":"example-ticket", "name":"Question", "description":"Create this ticket if you have a question.", "icon":"🎫", @@ -74,10 +76,9 @@ "roleId":"012345678910" } } - }, { - "id":"website", + "id":"example-website", "name":"Website", "description":"Go to our website.", "icon":"✅", @@ -85,27 +86,25 @@ "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", + "id":"example-role", + "name":"Update Ping", + "description":"Click here to get pinged for updates!", + "icon":"📢", + "label":"Update Ping", "type":"role", "color":"red", "roles":["discord role id"], "mode":"add&remove|remove|add", "enableDmOnOpen":true - } ], "messages":[ { - "id":"1", + "id":"example-embed", "name":"Choose Your Ticket", "description":"You can click one of the buttons below!", "dropdown":false, @@ -125,7 +124,7 @@ "enableCustomColor":false, "color":"#ffffff", - "options":["general","apply"], + "options":["example-ticket","example-website","example-role"], "other":{ "enableTicketExplaination":true, @@ -146,4 +145,4 @@ } } ] -} +} \ No newline at end of file diff --git a/core/api/api.js b/core/api/api.js index 03c633f..888fb3e 100644 --- a/core/api/api.js +++ b/core/api/api.js @@ -4,7 +4,7 @@ const bot = require("../../index") exports.client = bot.client exports.config = bot.config exports.utils = { - log:bot.errorLog.log(), + log:bot.errorLog.log, storage:bot.storage } diff --git a/core/checker.js b/core/checker.js index 7b90eac..ce54293 100644 --- a/core/checker.js +++ b/core/checker.js @@ -29,23 +29,23 @@ exports.checker = async () => { /**@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)){ + if (value.length < 16 || value.length > 40 || !/^\d+$/.test(value)){ createError("'"+path+"' | this user id is invalid") } }else if (mode == "channelid"){ - if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){ + if (value.length < 16 || value.length > 40 || !/^\d+$/.test(value)){ createError("'"+path+"' | this channel id is invalid") } }else if (mode == "roleid"){ - if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){ + if (value.length < 16 || value.length > 40 || !/^\d+$/.test(value)){ createError("'"+path+"' | this role id is invalid") } }else if (mode == "serverid"){ - if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){ + if (value.length < 16 || value.length > 40 || !/^\d+$/.test(value)){ createError("'"+path+"' | this server id is invalid") } }else if (mode == "categoryid"){ - if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){ + if (value.length < 16 || value.length > 40 || !/^\d+$/.test(value)){ createError("'"+path+"' | this category id is invalid") } } @@ -402,11 +402,11 @@ exports.checker = async () => { } } - //--------------------------| - //--------------------------| - //checker => START HERE | - //--------------------------| - //--------------------------| + ////////////////////////////////////////// + ////////////////////////////////////////// + /////////!!! CHECKER.JS START !!!///////// + ////////////////////////////////////////// + ////////////////////////////////////////// var configArray = ["color","serverId","token","adminRoles","prefix","languageFile","status","system","options","messages"] configArray.forEach((item) => { @@ -416,19 +416,44 @@ exports.checker = async () => { }) checkHexColor(config.color,"main_color") - checkDiscord("serverid",config.serverId,"server_id") + checkDiscord("serverid",config.serverId,"serverId") if (!require("./api/api.json").disable.checkerjs.token && !config.token.fromENV) checkToken(config.token.value) - checkType(config.adminRoles,"array","/main_adminroles") - checkDiscordArray("roleid",config.adminRoles,"main_adminroles") + checkType(config.adminRoles,"array","/adminRoles") + checkDiscordArray("roleid",config.adminRoles,"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") && !lf.startsWith("german") && !lf.startsWith("arabic") && !lf.startsWith("spanish") && !lf.startsWith("portuguese") && !lf.startsWith("french") && !lf.startsWith("italian") && !lf.startsWith("czech") && !lf.startsWith("danish") && !lf.startsWith("russian") && !lf.startsWith("turkish") && !lf.startsWith("polish") && !lf.startsWith("slovenian") && !lf.startsWith("thai") && !lf.startsWith("norwegian") && !lf.startsWith("greek") && !lf.startsWith("ukrainian") && !lf.startsWith("hungarian") && !lf.startsWith("indonesian") && !lf.startsWith("kurdish")){ - createError("'languagefile' | invalid language, more info in the wiki") + //languagefile + checkType(config.languageFile,"string","languageFile") + const languageList = [ + "custom", + "english", + "dutch", + "romanian", + "german", + "arabic", + "spanish", + "portuguese", + "french", + "italian", + "czech", + "danish", + "russian", + "turkish", + "polish", + "slovenian", + "thai", + "norwegian", + "greek", + "ukrainian", + "hungarian", + "indonesian", + "kurdish", + "persian" + ] + if (!languageList.some((l) => config.languageFile.startsWith(l))){ + createError("'languageFile' | invalid language, more info in the wiki") } //status: @@ -483,34 +508,35 @@ exports.checker = async () => { //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]) - if (splitw[3]){splitstring = splitstring+chalk.yellow(splitw[3])} - if (splitw[4]){splitstring = splitstring+chalk.yellow(splitw[4])} - if (splitw[5]){splitstring = splitstring+chalk.yellow(splitw[5])} - }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!")) + 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]) + if (splitw[3]){splitstring = splitstring+chalk.yellow(splitw[3])} + if (splitw[4]){splitstring = splitstring+chalk.yellow(splitw[4])} + if (splitw[5]){splitstring = splitstring+chalk.yellow(splitw[5])} + }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!")) + } + console.log(chalk.bold.green("\nDOCUMENTATION => https://otdocs.dj-dj.be\nSUPPORT => https://discord.dj-dj.be\n")) + process.exit(0) + }else if (isWarn){ + console.log("===========================") + console.log("=> "+chalk.bgYellow("if you ignore warns, some things may work differently than expected!")) + console.log(chalk.bold.green("\nDOCUMENTATION => https://otdocs.dj-dj.be\nSUPPORT => https://discord.dj-dj.be\n")) } - 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!")) } - } diff --git a/core/dynamicdatabase/cleardata.js b/core/dynamicdatabase/cleardata.js deleted file mode 100644 index be11d68..0000000 --- a/core/dynamicdatabase/cleardata.js +++ /dev/null @@ -1,53 +0,0 @@ -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) -} \ No newline at end of file diff --git a/core/interactionHandlers/handlers/accepted/closing.js b/core/interactionHandlers/handlers/accepted/closing.js index 7f2eb40..6bc4cc8 100644 --- a/core/interactionHandlers/handlers/accepted/closing.js +++ b/core/interactionHandlers/handlers/accepted/closing.js @@ -40,7 +40,7 @@ module.exports = () => { if (!permissionChecker.sendUserNoPerms(interaction.user)){ permissionChecker.sendChannelNoPerms(interaction.channel,interaction.user) } - interaction.message.edit({components:[firstcomponents]}) + interaction.message.edit({components:firstcomponents}) closeTicketButtonChecker = false return } diff --git a/core/interactionHandlers/handlers/accepted/closingReason.js b/core/interactionHandlers/handlers/accepted/closingReason.js index 7e23d9c..5b149e3 100644 --- a/core/interactionHandlers/handlers/accepted/closingReason.js +++ b/core/interactionHandlers/handlers/accepted/closingReason.js @@ -65,7 +65,7 @@ module.exports = () => { if (!permissionChecker.sendUserNoPerms(interaction.user)){ permissionChecker.sendChannelNoPerms(interaction.channel,interaction.user) } - interaction.message.edit({components:[firstcomponents]}) + interaction.message.edit({components:firstcomponents}) closeTicketButtonChecker = false return interaction.deferUpdate() } diff --git a/core/interactionHandlers/handlers/accepted/reopening.js b/core/interactionHandlers/handlers/accepted/reopening.js index 0a2ded5..45959a5 100644 --- a/core/interactionHandlers/handlers/accepted/reopening.js +++ b/core/interactionHandlers/handlers/accepted/reopening.js @@ -21,8 +21,21 @@ module.exports = () => { if (!interaction.isButton()) return if (interaction.customId != "OTreopenTicket") return + const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id) + if (hiddendata.length < 1) return interaction.reply({embeds:[bot.errorLog.notInATicket]}) + const ticketId = hiddendata.find(d => d.key == "type").value + + if (config.system.closeMode == "adminonly"){ + if (!permissionChecker.ticket(interaction.user.id,interaction.guild.id,ticketId)){ + if (!permissionChecker.sendUserNoPerms(interaction.user)){ + permissionChecker.sendChannelNoPerms(interaction.channel,interaction.user) + } + return interaction.deferUpdate() + } + } + await interaction.deferUpdate() interaction.message.edit({embeds:[bot.embeds.commands.reopenEmbed(interaction.user)],components:[bot.buttons.close.openRowNormal]}) - require("../../../ticketActions/ticketReopener").reopenTicket(interaction.guild,interaction.channel,interaction.user) + require("../../../ticketActions/ticketReopener").reopenTicket(interaction.guild,interaction.channel,interaction.user,ticketId) }) } \ No newline at end of file diff --git a/core/ticketActions/ticketOpener.js b/core/ticketActions/ticketOpener.js index 300693c..b5df529 100755 --- a/core/ticketActions/ticketOpener.js +++ b/core/ticketActions/ticketOpener.js @@ -63,7 +63,7 @@ module.exports = () => { } catch{} } - if (storage.get("amountOfUserTickets",interaction.member.id) == null || storage.get("amountOfUserTickets",interaction.member.id) == "false"|| Number(storage.get("amountOfUserTickets",interaction.member.id)) < config.system.maxAmountOfTickets){ + if (storage.get("amountOfUserTickets",interaction.member.id) == null || storage.get("amountOfUserTickets",interaction.member.id) == "false"|| Number(storage.get("amountOfUserTickets",interaction.member.id)) <= config.system.maxAmountOfTickets){ //update storage storage.set("amountOfUserTickets",interaction.member.id,Number(storage.get("amountOfUserTickets",interaction.member.id))+1) @@ -258,6 +258,7 @@ module.exports = () => { }) }else{ + interaction.editReply({embeds:[bot.errorLog.warning(l.errors.maxAmountTitle,l.errors.maxAmountDescription)]}) try { if (config.system.dmMessages){ interaction.member.send({embeds:[bot.errorLog.warning(l.errors.maxAmountTitle,l.errors.maxAmountDescription)]}) diff --git a/core/ticketActions/ticketReopener.js b/core/ticketActions/ticketReopener.js index e01aa45..56052ea 100755 --- a/core/ticketActions/ticketReopener.js +++ b/core/ticketActions/ticketReopener.js @@ -6,15 +6,26 @@ const log = bot.errorLog.log const l = bot.language const storage = bot.storage const pfb = discord.PermissionFlagsBits +const permsChecker = require("../utils/permisssionChecker") /** * * @param {discord.Guild} guild * @param {discord.TextBasedChannel} channel * @param {discord.User} user + * @param {String} ticketId option id * @returns */ -const reopenTicket = (guild,channel,user) => { +const reopenTicket = (guild,channel,user,ticketId) => { + //check perms + if (config.system.closeMode == "adminonly"){ + if (!guild) return + if (!permsChecker.ticket(user.id,guild.id,ticketId)){ + permsChecker.sendUserNoPerms(user) + return + } + } + log("system","re-opened a ticket",[{key:"ticket",value:channel.name},{key:"user",value:user.username}]) var permissionsArray = [] diff --git a/core/transcriptSystem/communication/compileJsonV2.js b/core/transcriptSystem/communication/compileJsonV2.js index e59313e..c2ac6f4 100644 --- a/core/transcriptSystem/communication/compileJsonV2.js +++ b/core/transcriptSystem/communication/compileJsonV2.js @@ -215,7 +215,7 @@ exports.compile = (guild,channel,user,messagesInv,data) => { interactionName:msg.interaction.commandName }, user:{ - name:msg.interaction.user.username, + name:msg.interaction.user.displayName, id:msg.interaction.user.id, color:replycolor, pfp:msg.interaction.user.displayAvatarURL(), @@ -227,15 +227,15 @@ exports.compile = (guild,channel,user,messagesInv,data) => { }else if (replytype == "reply"){ var replycontentRAW = messages.find((msg2) => msg2.id == msg.reference.messageId) - var replycontent = (replycontentRAW && replycontentRAW.content) ? replycontentRAW.content.slice(0,(60-replycontentRAW.author.username.length)) : "deleted this message" + var replycontent = (replycontentRAW && replycontentRAW.content) ? replycontentRAW.content.slice(0,(60-replycontentRAW.author.displayName.length)) : "deleted this message" const replycolorRAW = (replycontentRAW) ? msg.guild.members.cache.find((m) => m.id == replycontentRAW.author.id) : false const replycolor = (replycolorRAW) ? replycolorRAW.displayHexColor.replace("#000000","#ffffff") : "#ffffff" var user = (replycontentRAW && replycontentRAW.content) ? { - name:(replycontentRAW) ? replycontentRAW.author.username : "undefined", + name:(replycontentRAW) ? replycontentRAW.author.displayName : "undefined", id:(replycontentRAW) ? replycontentRAW.author.id : "undefined", color:replycolor, - pfp:(replycontentRAW) ? replycontentRAW.author.username : "", + pfp:(replycontentRAW) ? replycontentRAW.author.displayName : "", bot:(replycontentRAW) ? replycontentRAW.author.bot : false, system:(replycontentRAW) ? replycontentRAW.author.system : false, verifiedBot:(replycontentRAW) ? replycontentRAW.author.flags.has(discord.UserFlags.VerifiedBot) : false, @@ -264,7 +264,7 @@ exports.compile = (guild,channel,user,messagesInv,data) => { const authorColor = msg.member ? msg.member.displayHexColor.replace("#000000","#ffffff") : "#ffffff" messagesArray.push({ author:{ - name:msg.author.username, + name:msg.author.displayName, id:msg.author.id, color:authorColor, pfp:msg.author.displayAvatarURL(), @@ -332,7 +332,7 @@ exports.compile = (guild,channel,user,messagesInv,data) => { creatorid:data.ticket.creatorid, creatorpfp:data.ticket.creatorpfp, - closedbyname:user.username, + closedbyname:user.displayName, closedbyid:user.id, closedbypfp:user.displayAvatarURL(), diff --git a/core/transcriptSystem/communication/index.js b/core/transcriptSystem/communication/index.js index 1f1d51c..48b8b88 100644 --- a/core/transcriptSystem/communication/index.js +++ b/core/transcriptSystem/communication/index.js @@ -22,7 +22,7 @@ exports.upload = async (json) => { resolve(res.data) }catch(err){ - console.log("failed transcript upload!",err.response) + console.log("Failed HTML transcript upload! Reached Ratelimit 429!") resolve(false) } }) diff --git a/core/transcriptSystem/embeds.js b/core/transcriptSystem/embeds.js index d2ec977..9a73d3b 100644 --- a/core/transcriptSystem/embeds.js +++ b/core/transcriptSystem/embeds.js @@ -74,7 +74,7 @@ exports.tserror = (name,id,user,err) => { const errDesc = (typeof err == "string") ? "\n"+err : "" - embed.setDescription("Something went wrong while creating the HTML transcript.\n\n[possible reasons](https://docs.openticket.dj-dj.be/the-system/transcripts/transcript-errors)"+errDesc) + embed.setDescription("Something went wrong while creating the HTML transcript.\n\n[possible reasons](https://otdocs.dj-dj.be/docs/current/docs/system/transcripts)"+errDesc) return embed } diff --git a/core/transcriptSystem/manager.js b/core/transcriptSystem/manager.js index 28d1c1c..ac6895e 100644 --- a/core/transcriptSystem/manager.js +++ b/core/transcriptSystem/manager.js @@ -88,13 +88,13 @@ module.exports = async (messages,guild,channel,user,reason) => { }, bot:{ - name:client.user.username, + name:client.user.displayName, id:client.user.id, pfp:client.user.displayAvatarURL(), }, ticket:{ creatorid:ticketopener.id, - creatorname:ticketopener.username, + creatorname:ticketopener.displayName, creatorpfp:ticketopener.displayAvatarURL(), openedtime:opentime.getTime(), @@ -123,7 +123,25 @@ module.exports = async (messages,guild,channel,user,reason) => { } const TSdata = await require("./communication/index").upload(JSONDATA) - if (!TSdata) return false + if (!TSdata){ + const attachment = await require("./oldTranscript").createTranscript(messages,channel) + const errembed = tsembeds.tserror(chName,chId,user,"`HTML Transcript API: reached ratelimit`") + + if (tsconfig.sendTranscripts.enableChannel){ + /**@type {discord.TextChannel|undefined} */ + const tc = guild.channels.cache.find((c) => c.id == tsconfig.sendTranscripts.channel) + + if (!tc) return + tc.send({embeds:[errembed],files:[attachment]}) + } + if (tsconfig.sendTranscripts.enableDM && user){ + const embed = tsembeds.tsready(chName,null,user,ticketopener) + try { + ticketopener.send({embeds:[embed],files:[attachment]}) + }catch{} + } + return false + } if (TSdata.status == "success"){ //MAKE THIS COMPATIBLE WITH PREMIUM "customTranscriptUrl" IN FUTURE VERSIONS!! diff --git a/index.js b/index.js index 6cbe24f..67b1464 100644 --- a/index.js +++ b/index.js @@ -38,7 +38,7 @@ Send ./openticketdebug.txt when there are errors! */ - +/** discord :)*/ const discord = require("discord.js") const fs = require('fs') const {GatewayIntentBits,Partials} = discord @@ -54,7 +54,7 @@ const client = new discord.Client({ partials:[Partials.Channel,Partials.Message] }) exports.client = client -client.setMaxListeners(100) +client.setMaxListeners(120) if (process.argv.some((v) => v == "--debug")) console.log("[TEMP_DEBUG]","created client") //LOAD CONFIG @@ -161,6 +161,10 @@ client.on('ready',async () => { if (config.status.enabled){ setStatus(config.status.type,config.status.text) + //refresh status every 10 minutes + setInterval(() => { + setStatus(config.status.type,config.status.text) + },(60*10*1000)) } this.actionRecorder.push({ diff --git a/language/persian.json b/language/persian.json new file mode 100644 index 0000000..71fa80a --- /dev/null +++ b/language/persian.json @@ -0,0 +1,135 @@ +{ + "_CREDITS":"sasanwm", + "_INFO":"This file is a translation for open ticket 3.5.4", + + "errors":{ + "missingArgsTitle":"آرگومان‌های گم شده!", + "missingArgsDescription":"آرگومان گم شده", + "noPermsTitle":"شما دسترسی نداری!", + "noPermsDescription":"شما نیاز به دسترسی `ADMINISTRATOR` دارید یا باید در لیست رول‌های مجاز باشید!", + "noPermsDelete":"فقط ادمین ها میتونند یک تیکت رو حذف کنند!", + "chooseFromListTitle":"ایدی نامعتبر", + "chooseFromListDescription":"یکی از ایدی‌های زیر رو انتخاب کن:", + "boterror":"خطای ربات!", + "notInTicketTitle":"شما در یک تیکت نیستید!", + "notInTicketDescription":"این کامند خارج از تیکت‌ها کار نمیکند!", + "ticketDoesntExist":"این تیکت دیگه وجود نداره!", + "roleDoesntExist":"این رول دیگه وجود نداره!", + "anotherOption":"این گزینه یک تیکت نیست بلکه نوع دیگه ای هست!", + "maxAmountTitle":"حداکثر مقدار رسیده هست!", + "maxAmountDescription":"شما به حداکثر تعداد تیکت‌های مجاز رسیدید!\nبنابراین نمیتونید یکی دیگه ایجاد کنید!", + "somethingWentWrong":"**مشکلی پیش اومد!**\nدوباره تلاش کن!" + }, + "commands":{ + "userAddedTitle":"{0} به این تیکت اضافه شد!", + "userRemovedTitle":"{0} از این تیکت حذف شد!", + "renameTitle":"اسم به {0} تغییر یافت!", + "closeTitle":"این تیکت بسته شد!", + "deleteTitle":"حذف این تیکت...", + "reopenTitle":"این تیکت دوباره باز شد!", + + "claimTitle":"این تیکت به {0} اختصاص یافته است", + "unclaimTitle":"این تیکت دیگه به اختصاص یک یوزر نمیباشد!", + "changeTitle":"نوع تیکت به {0} تغییر یافت!", + + "statsTitle":"آمار اینجا {0} هست!", + "autocloseTitle":"این تیکت به طور خودکار بعد از {0} بسته خواهد شد!", + "autocloseRejectTitle":"این تیکت دیگه به طور خودکار بسته نخواهد شد!", + "autocloseWarn":"این فقط بر روی تیکت‌های غیرفعال تأثیر میزاره!", + + "goToTicket":"رفتن به تیکت", + "ticketWarning":"امبد در پیام زیر هست!", + "maxTicketWarning":"**هشدار:** _شما فقط میتوانید {0} تیکت رو در همان زمان ایجاد کنید!_" + }, + "helpMenu":{ + "title":"کامند های موجود:", + "header1":"**به {0} براید تا یک تیکت ایجاد کنید!**\n\n", + "header2":"**کامند `/new` یا `/ticket` رو اجرو کن تا یک تیکت ایجاد کنید!**\n\n", + + "msgCmd":"فرستادن یک امبد با دکمه ها (فقط ادمین ها)", + "renameCmd":"اسم یک تیکت رو تغییر دهید. (بدون فاصله)", + "closeCmd":"بستن یک تیکت.", + "deleteCmd":"حذف یک تیکت.", + "addCmd":"اضافه کردن یک یوزر به تیکت.", + "removeCmd":"حذف کردن یک یوزر از تیکت.", + "reopenCmd":"باز کردن یک تیکت پس از بسته شدن.", + "changeCmd":"تغییر دادن نوع تیکت.", + "claimCmd":"به اختیار گرفتن یک تیکت.", + "unclaimCmd":"خارج کردن یک تیکت از اختیار خود.", + "statsCmd":"مشاهده کردن امار یک تیکت.", + "autocloseCmd":"تنظیم زمان بندی برای بسته شدن خودکار تیکت. " + }, + "buttons":{ + "close":"بستن تیکت", + "delete":"حذف تیکت", + "reopen":"بازکردن مجدد تیکت", + "closeWithReason":"بستن با دلیل" + }, + "messages":{ + "closedDescription":"فقط ادمین‌ها میتواننند در این تیکت صحبت کنند!\n\n*برای حذف یا بازکردن این تیکت، روی دکمه زیر کلیک کن!*", + "createdTitle":"تیکت ایجاد شد!", + "createdDescription":"تیکت شما ایجاد شده، توی تیکت منشن شدی!", + + "newTicketDmTitle":"تیکت جدید!", + "closedTicketDmTitle":"تیکت بسته شد!", + "deletedTicketDmTitle":"تیکت حذف شد!", + "closedTicketDmDescription":"تیکت شما بسته شده هست!", + "deletedTicketDmDescription":"تیکت شما حذف شده هست!", + "reopenTicketDmTitle":"تیکت دوباره باز شد!", + "reopenTicketDmDescription":"تیکت شما دوباره باز شده هست!", + + "chooseCategory":"یک دسته بندی رو انتخاب کن:", + "gettingdeleted":"تیکت در حال حذف شدن هست...", + + "none":"هیچ", + "reason":"دلیل", + "createdat":"ایجاد شده در", + "openedby":"باز شده توسط", + "deletedby":"حذف شده توسط", + "closedby":"بسته شده توسط", + + "modalreason":"دلیل بستن این تیکت چیه؟", + "chooseATicket": "یک تیکت رو انتخاب کن" + }, + "transcripts":{ + "title":"گزارش", + "processed":"این گزارش در حال پردازش هست", + "wait":"لطفاً صبر کن!", + "estimated":"زمان تقریبی", + "available":"گزارش در دسترس هست در اینجا" + }, + "stats":{ + "globalTitle":"آمار گلوبال", + "ticketTitle":"آمار تیکت برای {0}", + "userTitle":"آمار یوزر برای {0}", + "systemTitle":"آمار سیستم", + "versionTitle":"ورژن ربات", + + "ticketsCreated":"تیکت‌های ایجاد شده", + "ticketsClosed":"تیکت‌های بسته شده", + "ticketsDeleted":"تیکت‌های حذف شده", + "ticketsReopened":"تیکت‌های دوباره باز شده", + "ticketsAutoclosed":"تیکت‌های به طور خودکار بسته شده", + "transcriptsCreated":"گزارش‌های ایجاد شده", + "startupDate":"تاریخ راه‌اندازی‌", + "latestUpdate":"آخرین بروزرسانی", + "ticketCreatedOn":"تیکت ایجاد شده در", + "ticketCreatedBy":"تیکت ایجاد شده توسط", + "messagesSent":"پیام‌های ارسال شده", + "status":"وضعیت", + "participants":"مشارکت‌کنندگان", + "role":"رول", + + "switches":{ + "globalAdmin":"ادمین گلوبال", + "ticketAdmin":"ادمین تیکت", + "member":"ممبر", + "open":"باز", + "reopened":"دوباره باز شده", + "closed":"بسته شده", + "autoclosed":"بسته شده به طور خودکار" + }, + + "errorUserNotFound":"این یوزر در دیتابیس آمار پیدا نمیشه!" + } +} \ No newline at end of file diff --git a/package.json b/package.json index d7368fe..7dd5c78 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,15 @@ { "name": "open-ticket", + "author": "DJdj Development", "version": "3.5.4", - "description": "TThe most advanced open-source discord ticket bot with HTML transcripts and plugins! It uses discord.js v14 & no database required!", + "description": "The most advanced open-source discord ticket bot with HTML transcripts and plugins! It uses discord.js v14 & no database required!", "main": "index.js", "scripts": { "start": "node index.js", "test": "node index.js --devconfig --noerrorupload", "slashEnable": "node index.js slash enable", - "slashDisable": "node index.js slash disable", - "cleardata": "node ./core/dynamicdatabase/cleardata.js" + "slashDisable": "node index.js slash disable" }, - "author": "DJdj Development", "license": "ISC", "dependencies": { "axios": "^1.6.2", @@ -22,7 +21,8 @@ "url": "git+https://github.com/DJj123dj/open-ticket.git" }, "bugs": { - "url": "https://github.com/DJj123dj/open-ticket/issues" + "url": "https://github.com/DJj123dj/open-ticket/issues", + "email": "support@dj-dj.be" }, - "homepage": "https://github.com/DJj123dj/open-ticket#readme" + "homepage": "https://openticket.dj-dj.be" }