From e6f6aa1af4db2d5a1b42b0d9063ba3ca2e4dc0e5 Mon Sep 17 00:00:00 2001 From: DJj123dj <80536295+DJj123dj@users.noreply.github.com> Date: Thu, 14 May 2026 23:13:38 +0200 Subject: [PATCH] Code cleanup & bugfixes --- package.json | 2 +- src/actions/handleTranscriptErrors.ts | 116 ++++++++------------------ src/actions/utilities.ts | 4 +- src/commands/add.ts | 40 ++++----- src/commands/autoclose.ts | 46 ++++------ src/commands/autodelete.ts | 40 +++------ src/commands/blacklist.ts | 1 + src/commands/clear.ts | 21 ++--- src/commands/help.ts | 11 +-- src/commands/move.ts | 43 ++++------ src/commands/panel.ts | 32 +++---- src/commands/priority.ts | 41 ++++----- src/commands/remove.ts | 38 +++------ src/commands/rename.ts | 42 ++++------ src/commands/role.ts | 9 +- src/commands/stats.ts | 74 ++-------------- src/commands/ticket.ts | 114 +++++++++++-------------- src/commands/topic.ts | 40 +++------ src/commands/transfer.ts | 42 ++++------ src/core/mappings/responder.ts | 48 +++++------ 20 files changed, 282 insertions(+), 522 deletions(-) diff --git a/package.json b/package.json index 122e24b..ab7ab68 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "license": "GPL-3.0-only", "dependencies": { "@discordjs/rest": "^2.6.1", - "@open-discord-bots/framework": "^0.3.14", + "@open-discord-bots/framework": "^0.3.15", "@types/node": "^22.5.0", "@types/terminal-kit": "^2.5.7", "ansis": "^4.2.0", diff --git a/src/actions/handleTranscriptErrors.ts b/src/actions/handleTranscriptErrors.ts index 11b01ff..e7bbc9f 100644 --- a/src/actions/handleTranscriptErrors.ts +++ b/src/actions/handleTranscriptErrors.ts @@ -2,6 +2,7 @@ //TRANSCRIPT ERROR SYSTEM /////////////////////////////////////// import {opendiscord, api, utilities} from "../index.js" +import * as actionUtils from "../actions/utilities.js" const generalConfig = opendiscord.configs.get("opendiscord:general") @@ -11,42 +12,30 @@ export async function registerButtonResponders(){ opendiscord.responders.buttons.get("opendiscord:transcript-error-retry").workers.add([ new api.ODWorker("opendiscord:delete-ticket",0,async (instance,params,origin,cancel) => { const {guild,channel,user,member} = instance + + //responder checks + const hasPerms = await actionUtils.replyHasPermissions(instance,origin,"delete") + if (!hasPerms) return cancel() + + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || channel.isDMBased()) return cancel() + + const ticket = await actionUtils.replyIsTicket(instance,origin) + if (!ticket) return cancel() + + const isAvailable = await actionUtils.replyTicketIsAvailable(instance,origin,ticket) + if (!isAvailable) return cancel() + + //fetch data const originalOrigin = instance.interaction.customId.split("_")[1] as api.ODActionManagerIdMappings["opendiscord:delete-ticket"]["origin"] - //check permissions - const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.delete,"support",user,member,channel,guild) - if (!permsResult.hasPerms){ - if (permsResult.reason == "not-in-server") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - else await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild,channel,user,permissions:["support"]})) - return cancel() - } - - //check is in guild/server - if (!guild){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - return cancel() - } - - //check if ticket exists - const ticket = opendiscord.tickets.get(channel.id) - if (!ticket || channel.isDMBased()){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-unknown").build("button",{guild,channel,user})) - return cancel() - } - //return when busy - if (ticket.get("opendiscord:busy").value){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-busy").build("button",{guild,channel,user})) - return cancel() - } - //start deleting ticket (without reason) await instance.defer("update",false) //don't await DELETE action => else it will update the message after the channel has been deleted opendiscord.actions.get("opendiscord:delete-ticket").run(originalOrigin,{guild,channel,user,ticket,reason:"Transcript Error (Retried)",sendMessage:false,withoutTranscript:false}) - //update ticket (for ticket message) => no-await doesn't wait for the action to set this variable - ticket.get("opendiscord:for-deletion").value = true + + ticket.get("opendiscord:for-deletion").value = true //disable ticket message buttons await instance.update(await opendiscord.builders.messages.getSafe("opendiscord:delete-message").build("other",{guild,channel,user,ticket,reason:"Transcript Error (Retried)"})) - }), new api.ODWorker("opendiscord:logs",-1,async (instance,params,origin,cancel) => { const {user,channel} = instance @@ -64,64 +53,31 @@ export async function registerButtonResponders(){ //TRANSCRIPT ERROR CONTINUE opendiscord.responders.buttons.add(new api.ODButtonResponder("opendiscord:transcript-error-continue",/^od:transcript-error-continue_([^_]+)/)) opendiscord.responders.buttons.get("opendiscord:transcript-error-continue").workers.add([ - new api.ODWorker("opendiscord:permissions",1,async (instance,params,origin,cancel) => { - const permissionMode = generalConfig.data.system.permissions.delete - - if (permissionMode == "none"){ - //no permissions - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build("button",{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]})) - return cancel() - }else if (permissionMode == "everyone") return - else if (permissionMode == "admin"){ - if (!opendiscord.permissions.hasPermissions("support",await opendiscord.permissions.getPermissions(instance.user,instance.channel,instance.guild))){ - //no permissions - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build("button",{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:["support"]})) - return cancel() - }else return - }else{ - if (!instance.guild || !instance.member){ - //error - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build("button",{guild:instance.guild,channel:instance.channel,user:instance.user,error:"Permission Error: Not in Server #1",layout:"advanced"})) - return cancel() - } - const role = await opendiscord.client.fetchGuildRole(instance.guild,permissionMode) - if (!role){ - //error - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build("button",{guild:instance.guild,channel:instance.channel,user:instance.user,error:"Permission Error: Not in Server #2",layout:"advanced"})) - return cancel() - } - if (!role.members.has(instance.member.id)){ - //no permissions - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build("button",{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]})) - return cancel() - }else return - } - }), new api.ODWorker("opendiscord:delete-ticket",0,async (instance,params,origin,cancel) => { const {guild,channel,user} = instance - const originalOrigin = instance.interaction.customId.split("_")[1] as api.ODActionManagerIdMappings["opendiscord:delete-ticket"]["origin"] - if (!guild){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - return cancel() - } - const ticket = opendiscord.tickets.get(channel.id) - if (!ticket || channel.isDMBased()){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-unknown").build("button",{guild,channel,user})) - return cancel() - } - //return when busy - if (ticket.get("opendiscord:busy").value){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-busy").build("button",{guild,channel,user})) - return cancel() - } + //responder checks + const hasPerms = await actionUtils.replyHasPermissions(instance,origin,"delete") + if (!hasPerms) return cancel() + + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || channel.isDMBased()) return cancel() + + const ticket = await actionUtils.replyIsTicket(instance,origin) + if (!ticket) return cancel() + + const isAvailable = await actionUtils.replyTicketIsAvailable(instance,origin,ticket) + if (!isAvailable) return cancel() - //start deleting ticket (without reason) + //fetch data + const originalOrigin = instance.interaction.customId.split("_")[1] as api.ODActionManagerIdMappings["opendiscord:delete-ticket"]["origin"] + + //start deleting ticket (without reason & without transcript) await instance.defer("update",false) //don't await DELETE action => else it will update the message after the channel has been deleted opendiscord.actions.get("opendiscord:delete-ticket").run(originalOrigin,{guild,channel,user,ticket,reason:"Transcript Error (Continued)",sendMessage:false,withoutTranscript:true}) - //update ticket (for ticket message) => no-await doesn't wait for the action to set this variable - ticket.get("opendiscord:for-deletion").value = true + + ticket.get("opendiscord:for-deletion").value = true //disable ticket message buttons await instance.update(await opendiscord.builders.messages.getSafe("opendiscord:delete-message").build("other",{guild,channel,user,ticket,reason:"Transcript Error (Continued)"})) }), diff --git a/src/actions/utilities.ts b/src/actions/utilities.ts index ae657de..30f8da7 100644 --- a/src/actions/utilities.ts +++ b/src/actions/utilities.ts @@ -27,11 +27,11 @@ export async function replyInteractiveMessageState(instance:api.ODButtonResponde } /**Check the permissions for this command. If not allowed, auto replies with error and returns `false`. When `false` is received, the worker should be returned and canceled. */ -export async function replyHasPermissions(instance:api.ODButtonResponderInstance|api.ODCommandResponderInstance|api.ODDropdownResponderInstance|api.ODModalResponderInstance,origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",commandName:keyof api.ODGeneralJsonConfig_SystemPermissions) { +export async function replyHasPermissions(instance:api.ODButtonResponderInstance|api.ODCommandResponderInstance|api.ODDropdownResponderInstance|api.ODModalResponderInstance,origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",commandName:keyof api.ODGeneralJsonConfig_SystemPermissions,settings?:api.ODPermissionSettings) { //check permissions const {user,member,channel,guild} = instance const generalConfig = opendiscord.configs.get("opendiscord:general") - const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions[commandName],"support",user,member,channel,guild) + const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions[commandName],"support",user,member,channel,guild,settings) if (!permsResult.hasPerms){ if (permsResult.reason == "not-in-server" && channel) await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) diff --git a/src/commands/add.ts b/src/commands/add.ts index 0298bcb..00601f2 100644 --- a/src/commands/add.ts +++ b/src/commands/add.ts @@ -3,6 +3,7 @@ /////////////////////////////////////// import {opendiscord, api, utilities} from "../index.js" import * as discord from "discord.js" +import * as actionUtils from "../actions/utilities.js" const generalConfig = opendiscord.configs.get("opendiscord:general") @@ -13,33 +14,20 @@ export async function registerCommandResponders(){ new api.ODWorker("opendiscord:add",0,async (instance,params,origin,cancel) => { const {guild,channel,user,member} = instance - //check permissions - const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.add,"support",user,member,channel,guild) - if (!permsResult.hasPerms){ - if (permsResult.reason == "not-in-server") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - else await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild,channel,user,permissions:["support"]})) - return cancel() - } - - //check if in guild/Server - if (!guild){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - return cancel() - } - - //check if ticket exists - const ticket = opendiscord.tickets.get(channel.id) - if (!ticket || channel.isDMBased()){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-unknown").build("button",{guild,channel,user})) - return cancel() - } - - //return when busy - if (ticket.get("opendiscord:busy").value){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-busy").build("button",{guild,channel,user})) - return cancel() - } + //responder checks + const hasPerms = await actionUtils.replyHasPermissions(instance,origin,"add") + if (!hasPerms) return cancel() + + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || channel.isDMBased()) return cancel() + + const ticket = await actionUtils.replyIsTicket(instance,origin) + if (!ticket) return cancel() + + const isAvailable = await actionUtils.replyTicketIsAvailable(instance,origin,ticket) + if (!isAvailable) return cancel() + //fetch data const data = instance.options.getUser("user",true) const reason = instance.options.getString("reason",false) diff --git a/src/commands/autoclose.ts b/src/commands/autoclose.ts index dc0c1f6..57e5c74 100644 --- a/src/commands/autoclose.ts +++ b/src/commands/autoclose.ts @@ -3,6 +3,7 @@ /////////////////////////////////////// import {opendiscord, api, utilities} from "../index.js" import * as discord from "discord.js" +import * as actionUtils from "../actions/utilities.js" const generalConfig = opendiscord.configs.get("opendiscord:general") @@ -12,39 +13,22 @@ export async function registerCommandResponders(){ opendiscord.responders.commands.get("opendiscord:autoclose").workers.add([ new api.ODWorker("opendiscord:autoclose",0,async (instance,params,origin,cancel) => { const {guild,channel,user,member} = instance - - //check permissions - const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.autoclose,"support",user,member,channel,guild) - if (!permsResult.hasPerms){ - if (permsResult.reason == "not-in-server") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - else await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild,channel,user,permissions:["support"]})) - return cancel() - } - //check is in guild/server - if (!guild){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build(origin,{channel:instance.channel,user:instance.user})) - return cancel() - } + //responder checks + const hasPerms = await actionUtils.replyHasPermissions(instance,origin,"autoclose") + if (!hasPerms) return cancel() + + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || channel.isDMBased()) return cancel() + + const ticket = await actionUtils.replyIsTicket(instance,origin) + if (!ticket) return cancel() + + const isAvailable = await actionUtils.replyTicketIsAvailable(instance,origin,ticket) + if (!isAvailable) return cancel() - //check if ticket exists - const ticket = opendiscord.tickets.get(channel.id) - if (!ticket || channel.isDMBased()){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-unknown").build("button",{guild,channel,user})) - return - } - - //return when already closed - if (ticket.get("opendiscord:closed").value){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build("button",{guild,channel,user,error:opendiscord.languages.getTranslation("errors.actionInvalid.close"),layout:"simple"})) - return cancel() - } - - //return when busy - if (ticket.get("opendiscord:busy").value){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-busy").build("button",{guild,channel,user})) - return cancel() - } + const isTicketOpen = await actionUtils.replyTicketMustBeOpen(instance,origin,ticket) + if (!isTicketOpen) return cancel() //subcommands const scope = instance.options.getSubCommand() diff --git a/src/commands/autodelete.ts b/src/commands/autodelete.ts index f9c35c7..184440b 100644 --- a/src/commands/autodelete.ts +++ b/src/commands/autodelete.ts @@ -3,6 +3,7 @@ /////////////////////////////////////// import {opendiscord, api, utilities} from "../index.js" import * as discord from "discord.js" +import * as actionUtils from "../actions/utilities.js" const generalConfig = opendiscord.configs.get("opendiscord:general") @@ -13,33 +14,18 @@ export async function registerCommandResponders(){ new api.ODWorker("opendiscord:autodelete",0,async (instance,params,origin,cancel) => { const {guild,channel,user,member} = instance - //check permissions - const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.autodelete,"support",user,member,channel,guild) - if (!permsResult.hasPerms){ - if (permsResult.reason == "not-in-server") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - else await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild,channel,user,permissions:["support"]})) - return cancel() - } - - //check is in guild/server - if (!guild){ - //error - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build(origin,{channel:instance.channel,user:instance.user})) - return cancel() - } - - //check if ticket exists - const ticket = opendiscord.tickets.get(channel.id) - if (!ticket || channel.isDMBased()){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-unknown").build("button",{guild,channel,user})) - return - } - - //return when busy - if (ticket.get("opendiscord:busy").value){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-busy").build("button",{guild,channel,user})) - return cancel() - } + //responder checks + const hasPerms = await actionUtils.replyHasPermissions(instance,origin,"autodelete") + if (!hasPerms) return cancel() + + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || channel.isDMBased()) return cancel() + + const ticket = await actionUtils.replyIsTicket(instance,origin) + if (!ticket) return cancel() + + const isAvailable = await actionUtils.replyTicketIsAvailable(instance,origin,ticket) + if (!isAvailable) return cancel() //subcommands const scope = instance.options.getSubCommand() diff --git a/src/commands/blacklist.ts b/src/commands/blacklist.ts index 8388762..edd5996 100644 --- a/src/commands/blacklist.ts +++ b/src/commands/blacklist.ts @@ -3,6 +3,7 @@ /////////////////////////////////////// import {opendiscord, api, utilities} from "../index.js" import * as discord from "discord.js" +import * as actionUtils from "../actions/utilities.js" const generalConfig = opendiscord.configs.get("opendiscord:general") diff --git a/src/commands/clear.ts b/src/commands/clear.ts index 891b21d..15e7f66 100644 --- a/src/commands/clear.ts +++ b/src/commands/clear.ts @@ -14,21 +14,16 @@ export async function registerCommandResponders(){ opendiscord.responders.commands.get("opendiscord:clear").workers.add([ new api.ODWorker("opendiscord:clear",0,async (instance,params,origin,cancel) => { const {user,member,channel,guild} = instance - + + //responder checks //check permissions (only allow global admins: ticket admins aren't allowed to clear tickets) - const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.clear,"support",user,member,channel,guild,{allowChannelUserScope:false,allowChannelRoleScope:false}) - if (!permsResult.hasPerms){ - if (permsResult.reason == "not-in-server") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - else await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild,channel,user,permissions:["support"]})) - return cancel() - } - - //check is in guild/server - if (!guild || channel.isDMBased()){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - return cancel() - } + const hasPerms = await actionUtils.replyHasPermissions(instance,origin,"clear",{allowChannelUserScope:false,allowChannelRoleScope:false}) + if (!hasPerms) return cancel() + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || channel.isDMBased()) return cancel() + + //fetch data const tempFilter = instance.options.getString("filter",false) const filter = (tempFilter) ? tempFilter.toLowerCase() as api.ODTicketClearFilter : "all" const channelNameList: string[] = [] diff --git a/src/commands/help.ts b/src/commands/help.ts index d678118..3f0e50f 100644 --- a/src/commands/help.ts +++ b/src/commands/help.ts @@ -3,6 +3,7 @@ /////////////////////////////////////// import {opendiscord, api, utilities} from "../index.js" import * as discord from "discord.js" +import * as actionUtils from "../actions/utilities.js" const generalConfig = opendiscord.configs.get("opendiscord:general") @@ -13,13 +14,9 @@ export async function registerCommandResponders(){ new api.ODWorker("opendiscord:help",0,async (instance,params,origin,cancel) => { const {guild,channel,user,member} = instance - //check permissions - const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.help,"support",user,member,channel,guild) - if (!permsResult.hasPerms){ - if (permsResult.reason == "not-in-server") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - else await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild,channel,user,permissions:["support"]})) - return cancel() - } + //responder checks + const hasPerms = await actionUtils.replyHasPermissions(instance,origin,"help") + if (!hasPerms) return cancel() //calculate slash/text mode for help menu let mode: "slash"|"text" diff --git a/src/commands/move.ts b/src/commands/move.ts index 82435c2..ffab4ab 100644 --- a/src/commands/move.ts +++ b/src/commands/move.ts @@ -3,6 +3,7 @@ /////////////////////////////////////// import {opendiscord, api, utilities} from "../index.js" import * as discord from "discord.js" +import * as actionUtils from "../actions/utilities.js" const generalConfig = opendiscord.configs.get("opendiscord:general") @@ -12,37 +13,25 @@ export async function registerCommandResponders(){ opendiscord.responders.commands.get("opendiscord:move").workers.add([ new api.ODWorker("opendiscord:move",0,async (instance,params,origin,cancel) => { const {guild,channel,user,member} = instance - - //check permissions - const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.move,"support",user,member,channel,guild) - if (!permsResult.hasPerms){ - if (permsResult.reason == "not-in-server") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - else await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild,channel,user,permissions:["support"]})) - return cancel() - } - - //check if in guild/server - if (!guild){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - return cancel() - } - - //check if ticket exists - const ticket = opendiscord.tickets.get(channel.id) - if (!ticket || channel.isDMBased()){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-unknown").build("button",{guild,channel,user})) - return cancel() - } - //return when busy - if (ticket.get("opendiscord:busy").value){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-busy").build("button",{guild,channel,user})) - return cancel() - } + + //responder checks + const hasPerms = await actionUtils.replyHasPermissions(instance,origin,"move") + if (!hasPerms) return cancel() + + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || channel.isDMBased()) return cancel() + + const ticket = await actionUtils.replyIsTicket(instance,origin) + if (!ticket) return cancel() + + const isAvailable = await actionUtils.replyTicketIsAvailable(instance,origin,ticket) + if (!isAvailable) return cancel() + //fetch data const id = instance.options.getString("id",true) const reason = instance.options.getString("reason",false) - const option = opendiscord.options.get(id) + //return if unknown option if (!option || !(option instanceof api.ODTicketOption)){ instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build("button",{guild,channel,user,error:opendiscord.languages.getTranslation("errors.titles.unknownOption"),layout:"simple"})) diff --git a/src/commands/panel.ts b/src/commands/panel.ts index 762c5ed..56dde86 100644 --- a/src/commands/panel.ts +++ b/src/commands/panel.ts @@ -3,6 +3,7 @@ /////////////////////////////////////// import {opendiscord, api, utilities} from "../index.js" import * as discord from "discord.js" +import * as actionUtils from "../actions/utilities.js" const generalConfig = opendiscord.configs.get("opendiscord:general") @@ -12,22 +13,21 @@ export async function registerCommandResponders(){ opendiscord.responders.commands.get("opendiscord:panel").workers.add([ new api.ODWorker("opendiscord:panel",0,async (instance,params,origin,cancel) => { const {guild,channel,user,member} = instance - - //check permissions - const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.panel,"support",user,member,channel,guild) - if (!permsResult.hasPerms){ - if (permsResult.reason == "not-in-server") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - else await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild,channel,user,permissions:["support"]})) - return cancel() - } - - //check is in guild/server - if (!guild || instance.channel.type == discord.ChannelType.GroupDM){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build(origin,{channel:instance.channel,user:instance.user})) - return cancel() - } - //get panel data + //responder checks + const hasPerms = await actionUtils.replyHasPermissions(instance,origin,"panel") + if (!hasPerms) return cancel() + + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || channel.isDMBased()) return cancel() + + const ticket = await actionUtils.replyIsTicket(instance,origin) + if (!ticket) return cancel() + + const isAvailable = await actionUtils.replyTicketIsAvailable(instance,origin,ticket) + if (!isAvailable) return cancel() + + //fetch data const id = instance.options.getString("id",true) const panel = opendiscord.panels.get(id) if (!panel){ @@ -36,7 +36,7 @@ export async function registerCommandResponders(){ } await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:panel-ready").build(origin,{guild,channel,user,panel})) - const panelMessage = await instance.channel.send((await opendiscord.builders.messages.getSafe("opendiscord:panel").build(origin,{guild,channel,user,panel})).message) + const panelMessage = await channel.send((await opendiscord.builders.messages.getSafe("opendiscord:panel").build(origin,{guild,channel,user,panel})).message) //add panel to database (this way, the bot knows where all panels are located) const globalDatabase = opendiscord.databases.get("opendiscord:global") diff --git a/src/commands/priority.ts b/src/commands/priority.ts index dbf3f5e..95e04d4 100644 --- a/src/commands/priority.ts +++ b/src/commands/priority.ts @@ -3,6 +3,7 @@ /////////////////////////////////////// import {opendiscord, api, utilities} from "../index.js" import * as discord from "discord.js" +import * as actionUtils from "../actions/utilities.js" const generalConfig = opendiscord.configs.get("opendiscord:general") @@ -12,33 +13,19 @@ export async function registerCommandResponders(){ opendiscord.responders.commands.get("opendiscord:priority").workers.add([ new api.ODWorker("opendiscord:priority",0,async (instance,params,origin,cancel) => { const {guild,channel,user,member} = instance - - //check permissions - const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.priority,"support",user,member,channel,guild) - if (!permsResult.hasPerms){ - if (permsResult.reason == "not-in-server") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - else await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild,channel,user,permissions:["support"]})) - return cancel() - } - - //check is in guild/server - if (!guild){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - return cancel() - } - - //check if ticket exists - const ticket = opendiscord.tickets.get(channel.id) - if (!ticket || channel.isDMBased()){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-unknown").build("button",{guild,channel,user})) - return cancel() - } - - //return when busy - if (ticket.get("opendiscord:busy").value){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-busy").build("button",{guild,channel,user})) - return cancel() - } + + //responder checks + const hasPerms = await actionUtils.replyHasPermissions(instance,origin,"priority") + if (!hasPerms) return cancel() + + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || channel.isDMBased()) return cancel() + + const ticket = await actionUtils.replyIsTicket(instance,origin) + if (!ticket) return cancel() + + const isAvailable = await actionUtils.replyTicketIsAvailable(instance,origin,ticket) + if (!isAvailable) return cancel() //subcommands const scope = instance.options.getSubCommand() diff --git a/src/commands/remove.ts b/src/commands/remove.ts index 9196d62..6874490 100644 --- a/src/commands/remove.ts +++ b/src/commands/remove.ts @@ -3,6 +3,7 @@ /////////////////////////////////////// import {opendiscord, api, utilities} from "../index.js" import * as discord from "discord.js" +import * as actionUtils from "../actions/utilities.js" const generalConfig = opendiscord.configs.get("opendiscord:general") @@ -12,34 +13,21 @@ export async function registerCommandResponders(){ opendiscord.responders.commands.get("opendiscord:remove").workers.add([ new api.ODWorker("opendiscord:remove",0,async (instance,params,origin,cancel) => { const {guild,channel,user,member} = instance - - //check permissions - const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.remove,"support",user,member,channel,guild) - if (!permsResult.hasPerms){ - if (permsResult.reason == "not-in-server") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - else await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild,channel,user,permissions:["support"]})) - return cancel() - } - //check is in guild/server - if (!guild){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - return cancel() - } - - //check if ticket exists - const ticket = opendiscord.tickets.get(channel.id) - if (!ticket || channel.isDMBased()){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-unknown").build("button",{guild,channel,user})) - return cancel() - } + //responder checks + const hasPerms = await actionUtils.replyHasPermissions(instance,origin,"remove") + if (!hasPerms) return cancel() - //return when busy - if (ticket.get("opendiscord:busy").value){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-busy").build("button",{guild,channel,user})) - return cancel() - } + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || channel.isDMBased()) return cancel() + + const ticket = await actionUtils.replyIsTicket(instance,origin) + if (!ticket) return cancel() + + const isAvailable = await actionUtils.replyTicketIsAvailable(instance,origin,ticket) + if (!isAvailable) return cancel() + //fetch data const data = instance.options.getUser("user",true) const reason = instance.options.getString("reason",false) diff --git a/src/commands/rename.ts b/src/commands/rename.ts index 9997028..376acec 100644 --- a/src/commands/rename.ts +++ b/src/commands/rename.ts @@ -3,6 +3,7 @@ /////////////////////////////////////// import {opendiscord, api, utilities} from "../index.js" import * as discord from "discord.js" +import * as actionUtils from "../actions/utilities.js" const generalConfig = opendiscord.configs.get("opendiscord:general") @@ -12,34 +13,21 @@ export async function registerCommandResponders(){ opendiscord.responders.commands.get("opendiscord:rename").workers.add([ new api.ODWorker("opendiscord:rename",0,async (instance,params,origin,cancel) => { const {guild,channel,user,member} = instance - - //check permissions - const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.rename,"support",user,member,channel,guild) - if (!permsResult.hasPerms){ - if (permsResult.reason == "not-in-server") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - else await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild,channel,user,permissions:["support"]})) - return cancel() - } - - //check is in guild/server - if (!guild){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - return cancel() - } - - //check if ticket exists - const ticket = opendiscord.tickets.get(channel.id) - if (!ticket || channel.isDMBased()){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-unknown").build("button",{guild,channel,user})) - return cancel() - } - - //return when busy - if (ticket.get("opendiscord:busy").value){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-busy").build("button",{guild,channel,user})) - return cancel() - } + + //responder checks + const hasPerms = await actionUtils.replyHasPermissions(instance,origin,"rename") + if (!hasPerms) return cancel() + + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || channel.isDMBased()) return cancel() + + const ticket = await actionUtils.replyIsTicket(instance,origin) + if (!ticket) return cancel() + + const isAvailable = await actionUtils.replyTicketIsAvailable(instance,origin,ticket) + if (!isAvailable) return cancel() + //fetch data const name = instance.options.getString("name",true) const reason = instance.options.getString("reason",false) diff --git a/src/commands/role.ts b/src/commands/role.ts index d31a291..14e7eb3 100644 --- a/src/commands/role.ts +++ b/src/commands/role.ts @@ -3,6 +3,7 @@ /////////////////////////////////////// import {opendiscord, api, utilities} from "../index.js" import * as discord from "discord.js" +import * as actionUtils from "../actions/utilities.js" const generalConfig = opendiscord.configs.get("opendiscord:general") @@ -13,11 +14,9 @@ export async function registerButtonResponders(){ new api.ODWorker("opendiscord:role-option",0,async (instance,params,origin,cancel) => { const {guild,channel,user} = instance - //check is in guild/server - if (!guild){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build(origin,{channel:instance.channel,user:instance.user})) - return cancel() - } + //responder checks + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || channel.isDMBased()) return cancel() //get option data const optionId = instance.interaction.customId.split("_")[2] diff --git a/src/commands/stats.ts b/src/commands/stats.ts index 0886129..4dc1950 100644 --- a/src/commands/stats.ts +++ b/src/commands/stats.ts @@ -3,6 +3,7 @@ /////////////////////////////////////// import {opendiscord, api, utilities} from "../index.js" import * as discord from "discord.js" +import * as actionUtils from "../actions/utilities.js" const generalConfig = opendiscord.configs.get("opendiscord:general") @@ -10,81 +11,23 @@ export async function registerCommandResponders(){ //STATS COMMAND RESPONDER opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:stats",generalConfig.data.prefix,/^stats/)) opendiscord.responders.commands.get("opendiscord:stats").workers.add([ - new api.ODWorker("opendiscord:permissions",1,async (instance,params,origin,cancel) => { - const permissionMode = generalConfig.data.system.permissions.stats - - //command is disabled - if (permissionMode == "none"){ - //no permissions - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build("button",{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]})) - return cancel() - } - - //reset subcommand is owner/developer only - if (instance.options.getSubCommand() == "reset"){ - if (!opendiscord.permissions.hasPermissions("owner",await opendiscord.permissions.getPermissions(instance.user,instance.channel,instance.guild))){ - //no permissions - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:["owner","developer"]})) - return cancel() - }else return - } - - //permissions for normal scopes - if (permissionMode == "everyone") return - else if (permissionMode == "admin"){ - if (!opendiscord.permissions.hasPermissions("support",await opendiscord.permissions.getPermissions(instance.user,instance.channel,instance.guild))){ - //no permissions - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:["support"]})) - return cancel() - }else return - }else{ - if (!instance.guild || !instance.member){ - //error - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build(origin,{guild:instance.guild,channel:instance.channel,user:instance.user,error:"Permission Error: Not in Server #1",layout:"advanced"})) - return cancel() - } - const role = await opendiscord.client.fetchGuildRole(instance.guild,permissionMode) - if (!role){ - //error - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build(origin,{guild:instance.guild,channel:instance.channel,user:instance.user,error:"Permission Error: Not in Server #2",layout:"advanced"})) - return cancel() - } - if (!role.members.has(instance.member.id)){ - //no permissions - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]})) - return cancel() - }else return - } - }), new api.ODWorker("opendiscord:stats",0,async (instance,params,origin,cancel) => { const {user,member,channel,guild} = instance //check permissions - if (generalConfig.data.system.permissions.stats === "none"){ - //command is disabled - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build("button",{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]})) - return cancel() - - }else if (instance.options.getSubCommand() === "reset" && !opendiscord.permissions.hasPermissions("owner",await opendiscord.permissions.getPermissions(instance.user,instance.channel,instance.guild))){ + if (instance.options.getSubCommand() === "reset" && !opendiscord.permissions.hasPermissions("owner",await opendiscord.permissions.getPermissions(instance.user,instance.channel,instance.guild))){ //reset --> owner/developer role is required - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:["owner","developer"]})) + await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:["owner","developer"]})) return cancel() - }else{ //default permissions check - const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.stats,"support",user,member,channel,guild) - if (!permsResult.hasPerms){ - if (permsResult.reason == "not-in-server") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - else await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild,channel,user,permissions:["support"]})) - return cancel() - } + const hasPerms = await actionUtils.replyHasPermissions(instance,origin,"stats") + if (!hasPerms) return cancel() } - //check is in guild/server - if (!guild){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build(origin,{channel:instance.channel,user:instance.user})) - return cancel() - } + //responder checks + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || channel.isDMBased()) return cancel() //subcommands const scope = instance.options.getSubCommand() @@ -108,7 +51,6 @@ export async function registerCommandResponders(){ const reason = instance.options.getString("reason",false) opendiscord.statistics.reset() await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:stats-reset").build(origin,{guild,channel,user,reason})) - } }), new api.ODWorker("opendiscord:logs",-1,(instance,params,origin,cancel) => { diff --git a/src/commands/ticket.ts b/src/commands/ticket.ts index 06e398c..d821ef6 100644 --- a/src/commands/ticket.ts +++ b/src/commands/ticket.ts @@ -3,6 +3,7 @@ /////////////////////////////////////// import {opendiscord, api, utilities} from "../index.js" import * as discord from "discord.js" +import * as actionUtils from "../actions/utilities.js" const generalConfig = opendiscord.configs.get("opendiscord:general") const lang = opendiscord.languages @@ -13,14 +14,14 @@ async function checkTicketCreationPerms(instance:api.ODButtonResponderInstance|a if (!permsRes.valid && instance.channel){ //error const newOrigin = (origin === "slash" || origin === "text") ? origin : "other" - if (permsRes.reason == "blacklist") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-blacklisted").build(newOrigin,{guild:instance.guild,channel:instance.channel,user:instance.user})) - else if (permsRes.reason == "cooldown") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-cooldown").build(newOrigin,{guild:instance.guild,channel:instance.channel,user:instance.user,until:permsRes.cooldownUntil})) - else if (permsRes.reason == "global-limit") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(newOrigin,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"global"})) - else if (permsRes.reason == "global-user-limit") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(newOrigin,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"global-user"})) - else if (permsRes.reason == "option-limit") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(newOrigin,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"option"})) - else if (permsRes.reason == "option-user-limit") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(newOrigin,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"option-user"})) - else if (permsRes.reason == "custom") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build(newOrigin,{guild:instance.guild,channel:instance.channel,user:instance.user,layout:"simple",error:permsRes.customReason ?? lang.getTranslation("errors.descriptions.unableToCreateTicket")+" `Unknown invalid_permission_reason => no reason specified by plugin`",customTitle:lang.getTranslation("errors.titles.permissionError")})) - else instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build(newOrigin,{guild:instance.guild,channel:instance.channel,user:instance.user,error:"Unknown invalid_permission reason => calculation failed #1",layout:"advanced"})) + if (permsRes.reason == "blacklist") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-blacklisted").build(newOrigin,{guild:instance.guild,channel:instance.channel,user:instance.user})) + else if (permsRes.reason == "cooldown") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-cooldown").build(newOrigin,{guild:instance.guild,channel:instance.channel,user:instance.user,until:permsRes.cooldownUntil})) + else if (permsRes.reason == "global-limit") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(newOrigin,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"global"})) + else if (permsRes.reason == "global-user-limit") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(newOrigin,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"global-user"})) + else if (permsRes.reason == "option-limit") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(newOrigin,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"option"})) + else if (permsRes.reason == "option-user-limit") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(newOrigin,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"option-user"})) + else if (permsRes.reason == "custom") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build(newOrigin,{guild:instance.guild,channel:instance.channel,user:instance.user,layout:"simple",error:permsRes.customReason ?? lang.getTranslation("errors.descriptions.unableToCreateTicket")+" `Unknown invalid_permission_reason => no reason specified by plugin`",customTitle:lang.getTranslation("errors.titles.permissionError")})) + else await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build(newOrigin,{guild:instance.guild,channel:instance.channel,user:instance.user,error:"Unknown invalid_permission reason => calculation failed #1",layout:"advanced"})) return false }else return true } @@ -31,39 +32,31 @@ export async function registerCommandResponders(){ opendiscord.responders.commands.get("opendiscord:ticket").workers.add([ new api.ODWorker("opendiscord:ticket",0,async (instance,params,origin,cancel) => { const {user,member,channel,guild} = instance - - //check permissions - const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.ticket,"support",user,member,channel,guild) - if (!permsResult.hasPerms){ - if (permsResult.reason == "not-in-server") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - else await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild,channel,user,permissions:["support"]})) - return cancel() - } - - //check is in guild/server - if (!guild){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build(origin,{channel:instance.channel,user:instance.user})) - return cancel() - } + + //responder checks + const hasPerms = await actionUtils.replyHasPermissions(instance,origin,"ticket") + if (!hasPerms) return cancel() + + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || channel.isDMBased()) return cancel() //get option data const optionId = instance.options.getString("id",true) const option = opendiscord.options.get(optionId) if (!option || !(option instanceof api.ODTicketOption)){ - //error instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-option-unknown").build(origin,{guild:instance.guild,channel:instance.channel,user:instance.user})) return cancel() } //start ticket creation if (option.exists("opendiscord:questions") && option.get("opendiscord:questions").value.length > 0){ - //send modal + //SEND MODAL instance.modal(await opendiscord.builders.modals.getSafe("opendiscord:ticket-questions").build(origin,{guild,channel,user,option})) }else{ - //check ticket permissions + //check ticket permissions (modals need check after submit) if (!(await checkTicketCreationPerms(instance,origin,guild,user,option))) return cancel() - - //create ticket + + //CREATE TICKET await instance.defer(true) const res = await opendiscord.actions.get("opendiscord:create-ticket").run(origin,{guild,user,answers:[],option}) if (!res.channel || !res.ticket){ @@ -91,30 +84,28 @@ export async function registerButtonResponders(){ opendiscord.responders.buttons.get("opendiscord:ticket-option").workers.add( new api.ODWorker("opendiscord:ticket-option",0,async (instance,params,origin,cancel) => { const {guild,channel,user} = instance - if (!guild){ - //error - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build(origin,{channel:instance.channel,user:instance.user})) - return cancel() - } + + //responder checks + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || channel.isDMBased()) return cancel() - //get option + //get option data const optionId = instance.interaction.customId.split("_")[2] const option = opendiscord.options.get(optionId) if (!option || !(option instanceof api.ODTicketOption)){ - //error instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-option-unknown").build(origin,{guild:instance.guild,channel:instance.channel,user:instance.user})) return cancel() } //start ticket creation if (option.exists("opendiscord:questions") && option.get("opendiscord:questions").value.length > 0){ - //send modal + //SEND MODAL instance.modal(await opendiscord.builders.modals.getSafe("opendiscord:ticket-questions").build("panel-button",{guild,channel,user,option})) }else{ - //check ticket permissions + //check ticket permissions (modals need check after submit) if (!(await checkTicketCreationPerms(instance,"panel-button",guild,user,option))) return cancel() - - //create ticket + + //CREATE TICKET await instance.defer((generalConfig.data.system.replyOnTicketCreation) ? "reply" : "update",true) const res = await opendiscord.actions.get("opendiscord:create-ticket").run("panel-button",{guild,user,answers:[],option}) @@ -135,30 +126,28 @@ export async function registerDropdownResponders(){ opendiscord.responders.dropdowns.get("opendiscord:panel-dropdown-tickets").workers.add( new api.ODWorker("opendiscord:panel-dropdown-tickets",0,async (instance,params,origin,cancel) => { const {guild,channel,user} = instance - if (!guild){ - //error - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build(origin,{channel:instance.channel,user:instance.user})) - return cancel() - } + + //responder checks + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || channel.isDMBased()) return cancel() - //get option + //get option data const optionId = instance.values.getStringValues()[0].split("_")[2] const option = opendiscord.options.get(optionId) if (!option || !(option instanceof api.ODTicketOption)){ - //error instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-option-unknown").build(origin,{guild:instance.guild,channel:instance.channel,user:instance.user})) return cancel() } //start ticket creation if (option.exists("opendiscord:questions") && option.get("opendiscord:questions").value.length > 0){ - //send modal + //SEND MODAL instance.modal(await opendiscord.builders.modals.getSafe("opendiscord:ticket-questions").build("panel-dropdown",{guild,channel,user,option})) }else{ - //check ticket permissions + //check ticket permissions (modals need check after submit) if (!(await checkTicketCreationPerms(instance,"panel-dropdown",guild,user,option))) return cancel() - - //create ticket + + //CREATE TICKET await instance.defer((generalConfig.data.system.replyOnTicketCreation) ? "reply" : "update",true) const res = await opendiscord.actions.get("opendiscord:create-ticket").run("panel-dropdown",{guild,user,answers:[],option}) @@ -187,25 +176,23 @@ export async function registerModalResponders(){ opendiscord.responders.modals.get("opendiscord:ticket-questions").workers.add([ new api.ODWorker("opendiscord:ticket-questions",0,async (instance,params,origin,cancel) => { const {guild,channel,user} = instance - await instance.defer((generalConfig.data.system.replyOnTicketCreation) ? "reply" : "update",true) - if (!channel) throw new api.ODSystemError("The 'Ticket Questions' modal requires a channel for responding!") - if (!guild){ - //error - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build(origin,{channel,user:instance.user})) - return cancel() - } + + //responder checks + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || !channel || channel.isDMBased()) return cancel() - const originalOrigin = instance.interaction.customId.split("_")[2] as ("panel-button"|"panel-dropdown"|"slash"|"text"|"other") - - //get option + //get option data const optionId = instance.interaction.customId.split("_")[1] const option = opendiscord.options.get(optionId) if (!option || !(option instanceof api.ODTicketOption)){ - //error instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-option-unknown").build(origin,{guild:instance.guild,channel,user:instance.user})) return cancel() } + //check ticket permissions (modals need check after submit) + const originalOrigin = instance.interaction.customId.split("_")[2] as ("panel-button"|"panel-dropdown"|"slash"|"text"|"other") + if (!(await checkTicketCreationPerms(instance,originalOrigin,guild,user,option))) return cancel() + //get answers const answers: {id:string,name:string,type:"short"|"paragraph",value:string|null}[] = [] option.get("opendiscord:questions").value.forEach((id) => { @@ -227,11 +214,10 @@ export async function registerModalResponders(){ }) } }) + + await instance.defer((generalConfig.data.system.replyOnTicketCreation) ? "reply" : "update",true) - //check ticket permissions - if (!(await checkTicketCreationPerms(instance,originalOrigin,guild,user,option))) return cancel() - - //create ticket + //CREATE TICKET const res = await opendiscord.actions.get("opendiscord:create-ticket").run(originalOrigin,{guild,user,answers,option}) if (!res.channel || !res.ticket){ //error diff --git a/src/commands/topic.ts b/src/commands/topic.ts index 10a2cb6..8143f96 100644 --- a/src/commands/topic.ts +++ b/src/commands/topic.ts @@ -3,6 +3,7 @@ /////////////////////////////////////// import {opendiscord, api, utilities} from "../index.js" import * as discord from "discord.js" +import * as actionUtils from "../actions/utilities.js" const generalConfig = opendiscord.configs.get("opendiscord:general") @@ -12,33 +13,18 @@ export async function registerCommandResponders(){ opendiscord.responders.commands.get("opendiscord:topic").workers.add([ new api.ODWorker("opendiscord:topic",0,async (instance,params,origin,cancel) => { const {user,member,channel,guild} = instance - - //check permissions - const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.topic,"support",user,member,channel,guild) - if (!permsResult.hasPerms){ - if (permsResult.reason == "not-in-server") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - else await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild,channel,user,permissions:["support"]})) - return cancel() - } - - //check is in guild/Server - if (!guild){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - return cancel() - } - - //check if ticket exists - const ticket = opendiscord.tickets.get(channel.id) - if (!ticket || channel.isDMBased()){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-unknown").build("button",{guild,channel,user})) - return cancel() - } - - //return when busy - if (ticket.get("opendiscord:busy").value){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-busy").build("button",{guild,channel,user})) - return cancel() - } + //responder checks + const hasPerms = await actionUtils.replyHasPermissions(instance,origin,"topic") + if (!hasPerms) return cancel() + + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || channel.isDMBased()) return cancel() + + const ticket = await actionUtils.replyIsTicket(instance,origin) + if (!ticket) return cancel() + + const isAvailable = await actionUtils.replyTicketIsAvailable(instance,origin,ticket) + if (!isAvailable) return cancel() //subcommands const scope = instance.options.getSubCommand() diff --git a/src/commands/transfer.ts b/src/commands/transfer.ts index 695aea8..12105c3 100644 --- a/src/commands/transfer.ts +++ b/src/commands/transfer.ts @@ -3,6 +3,7 @@ /////////////////////////////////////// import {opendiscord, api, utilities} from "../index.js" import * as discord from "discord.js" +import * as actionUtils from "../actions/utilities.js" const generalConfig = opendiscord.configs.get("opendiscord:general") @@ -12,34 +13,21 @@ export async function registerCommandResponders(){ opendiscord.responders.commands.get("opendiscord:transfer").workers.add([ new api.ODWorker("opendiscord:transfer",0,async (instance,params,origin,cancel) => { const {user,member,channel,guild} = instance - - //check permissions - const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.transfer,"support",user,member,channel,guild) - if (!permsResult.hasPerms){ - if (permsResult.reason == "not-in-server") await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - else await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(origin,{guild,channel,user,permissions:["support"]})) - return cancel() - } - - //check is in guild/Server - if (!guild){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build("button",{channel,user})) - return cancel() - } - - //check if ticket exists - const ticket = opendiscord.tickets.get(channel.id) - if (!ticket || channel.isDMBased()){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-unknown").build("button",{guild,channel,user})) - return cancel() - } - - //return when busy - if (ticket.get("opendiscord:busy").value){ - instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-ticket-busy").build("button",{guild,channel,user})) - return cancel() - } + + //responder checks + const hasPerms = await actionUtils.replyHasPermissions(instance,origin,"transfer") + if (!hasPerms) return cancel() + + const isInGuild = await actionUtils.replyIsInGuild(instance,origin) + if (!isInGuild || !guild || channel.isDMBased()) return cancel() + + const ticket = await actionUtils.replyIsTicket(instance,origin) + if (!ticket) return cancel() + + const isAvailable = await actionUtils.replyTicketIsAvailable(instance,origin,ticket) + if (!isAvailable) return cancel() + //fetch data const oldCreator = await opendiscord.tickets.getTicketUser(ticket,"creator") ?? opendiscord.client.client.user const newCreator = instance.options.getUser("user",true) const reason = instance.options.getString("reason",false) diff --git a/src/core/mappings/responder.ts b/src/core/mappings/responder.ts index db257f6..036c509 100644 --- a/src/core/mappings/responder.ts +++ b/src/core/mappings/responder.ts @@ -8,31 +8,31 @@ import * as api from "@open-discord-bots/framework/api" * It's used to generate typescript declarations for this class. */ export interface ODCommandResponderManagerIdMappings extends api.ODCommandResponderManagerIdConstraint { - "opendiscord:help":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:help"|"opendiscord:logs"}, - "opendiscord:stats":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:stats"|"opendiscord:logs"}, - "opendiscord:panel":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:panel"|"opendiscord:logs"}, - "opendiscord:ticket":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:ticket"|"opendiscord:logs"}, - "opendiscord:blacklist":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:blacklist"|"opendiscord:discord-logs"|"opendiscord:logs"}, + "opendiscord:help":{origin:"slash"|"text",params:{},workers:"opendiscord:help"|"opendiscord:logs"}, + "opendiscord:stats":{origin:"slash"|"text",params:{},workers:"opendiscord:stats"|"opendiscord:logs"}, + "opendiscord:panel":{origin:"slash"|"text",params:{},workers:"opendiscord:panel"|"opendiscord:logs"}, + "opendiscord:ticket":{origin:"slash"|"text",params:{},workers:"opendiscord:ticket"|"opendiscord:logs"}, + "opendiscord:blacklist":{origin:"slash"|"text",params:{},workers:"opendiscord:blacklist"|"opendiscord:discord-logs"|"opendiscord:logs"}, - "opendiscord:close":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:close"|"opendiscord:logs"}, - "opendiscord:reopen":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:reopen"|"opendiscord:logs"}, - "opendiscord:delete":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:delete"|"opendiscord:logs"}, - "opendiscord:claim":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:claim"|"opendiscord:logs"}, - "opendiscord:unclaim":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:unclaim"|"opendiscord:logs"}, - "opendiscord:pin":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:pin"|"opendiscord:logs"}, - "opendiscord:unpin":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:unpin"|"opendiscord:logs"}, + "opendiscord:close":{origin:"slash"|"text",params:{},workers:"opendiscord:close"|"opendiscord:logs"}, + "opendiscord:reopen":{origin:"slash"|"text",params:{},workers:"opendiscord:reopen"|"opendiscord:logs"}, + "opendiscord:delete":{origin:"slash"|"text",params:{},workers:"opendiscord:delete"|"opendiscord:logs"}, + "opendiscord:claim":{origin:"slash"|"text",params:{},workers:"opendiscord:claim"|"opendiscord:logs"}, + "opendiscord:unclaim":{origin:"slash"|"text",params:{},workers:"opendiscord:unclaim"|"opendiscord:logs"}, + "opendiscord:pin":{origin:"slash"|"text",params:{},workers:"opendiscord:pin"|"opendiscord:logs"}, + "opendiscord:unpin":{origin:"slash"|"text",params:{},workers:"opendiscord:unpin"|"opendiscord:logs"}, - "opendiscord:rename":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:rename"|"opendiscord:logs"}, - "opendiscord:move":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:move"|"opendiscord:logs"}, - "opendiscord:add":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:add"|"opendiscord:logs"}, - "opendiscord:remove":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:remove"|"opendiscord:logs"}, - "opendiscord:clear":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:clear"|"opendiscord:logs"}, - "opendiscord:topic":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:topic"|"opendiscord:logs"}, - "opendiscord:priority":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:priority"|"opendiscord:logs"}, - "opendiscord:transfer":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:transfer"|"opendiscord:logs"}, + "opendiscord:rename":{origin:"slash"|"text",params:{},workers:"opendiscord:rename"|"opendiscord:logs"}, + "opendiscord:move":{origin:"slash"|"text",params:{},workers:"opendiscord:move"|"opendiscord:logs"}, + "opendiscord:add":{origin:"slash"|"text",params:{},workers:"opendiscord:add"|"opendiscord:logs"}, + "opendiscord:remove":{origin:"slash"|"text",params:{},workers:"opendiscord:remove"|"opendiscord:logs"}, + "opendiscord:clear":{origin:"slash"|"text",params:{},workers:"opendiscord:clear"|"opendiscord:logs"}, + "opendiscord:topic":{origin:"slash"|"text",params:{},workers:"opendiscord:topic"|"opendiscord:logs"}, + "opendiscord:priority":{origin:"slash"|"text",params:{},workers:"opendiscord:priority"|"opendiscord:logs"}, + "opendiscord:transfer":{origin:"slash"|"text",params:{},workers:"opendiscord:transfer"|"opendiscord:logs"}, - "opendiscord:autoclose":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:autoclose"|"opendiscord:logs"}, - "opendiscord:autodelete":{origin:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:autodelete"|"opendiscord:logs"}, + "opendiscord:autoclose":{origin:"slash"|"text",params:{},workers:"opendiscord:autoclose"|"opendiscord:logs"}, + "opendiscord:autodelete":{origin:"slash"|"text",params:{},workers:"opendiscord:autodelete"|"opendiscord:logs"}, } /**## ODButtonResponderManagerIdMappings `interface` @@ -57,8 +57,8 @@ export interface ODButtonResponderManagerIdMappings extends api.ODButtonResponde "opendiscord:reopen-ticket":{origin:"button",params:{},workers:"opendiscord:reopen-ticket"}, "opendiscord:delete-ticket":{origin:"button",params:{},workers:"opendiscord:delete-ticket"}, - "opendiscord:transcript-error-retry":{origin:"button",params:{},workers:"opendiscord:permissions"|"opendiscord:delete-ticket"|"opendiscord:logs"}, - "opendiscord:transcript-error-continue":{origin:"button",params:{},workers:"opendiscord:permissions"|"opendiscord:delete-ticket"|"opendiscord:logs"}, + "opendiscord:transcript-error-retry":{origin:"button",params:{},workers:"opendiscord:delete-ticket"|"opendiscord:logs"}, + "opendiscord:transcript-error-continue":{origin:"button",params:{},workers:"opendiscord:delete-ticket"|"opendiscord:logs"}, "opendiscord:clear-continue":{origin:"button",params:{},workers:"opendiscord:clear-continue"}, }