diff --git a/.docs/mergeTranslations.js b/.docs/mergeTranslations.js
index deb9ca8..0854ee2 100644
--- a/.docs/mergeTranslations.js
+++ b/.docs/mergeTranslations.js
@@ -643,7 +643,7 @@ for (const language of fs.readdirSync(".docs/languages/")){
}
}
original["_TRANSLATION"]["lastedited"] = new Date().toLocaleDateString("nl-BE",{day:"2-digit",month:"2-digit",year:"numeric"})
- original["_TRANSLATION"]["otversion"] = "v4.1.1"
+ original["_TRANSLATION"]["otversion"] = "v4.1.2"
const finalText = formatter.stringify(original)
fs.writeFileSync("./languages/"+language,finalText)
}
\ No newline at end of file
diff --git a/.eggs/README.md b/.eggs/README.md
index f35f3f7..79d6bb1 100644
--- a/.eggs/README.md
+++ b/.eggs/README.md
@@ -2,7 +2,7 @@
[](https://discord.com/invite/26vT9wt3n3)
-[](https://github.com/open-discord-bots/open-ticket/releases/tag/v4.1.1)
+[](https://github.com/open-discord-bots/open-ticket/releases/tag/v4.1.2)
[](https://github.com/sponsors/DJj123dj)
[](.eggs/README.md)
@@ -20,6 +20,9 @@ It's recommended to provide at least `1GB` of **Memory/RAM** and `5GB` of **disk
[**`openticket-egg-main.json` (Recommended)**](openticket-egg-main.json)
- This egg will use the `main` branch of Open Ticket.
+[**`openticket-egg-v4.1.2.json`**](openticket-egg-v4.1.2.json)
+- This egg will always use Open Ticket `v4.1.2`. Open Ticket updates will not have an effect on this egg.
+
[**`openticket-egg-v4.1.1.json`**](openticket-egg-v4.1.1.json)
- This egg will always use Open Ticket `v4.1.1`. Open Ticket updates will not have an effect on this egg.
@@ -41,4 +44,4 @@ It's recommended to provide at least `1GB` of **Memory/RAM** and `5GB` of **disk
**Pterodactyl Eggs**
[Changelog](https://otgithub.dj-dj.be/releases) - [Documentation](https://otdocs.dj-dj.be) - [Website](https://openticket.dj-dj.be) - [Support Server](https://discord.dj-dj.be) - [License](./LICENSE.md)
-© 2025 - [DJdj Development](https://www.dj-dj.be) - [Terms](https://www.dj-dj.be/terms) - [Privacy Policy](https://www.dj-dj.be/privacy) - [Support Us](https://github.com/sponsors/DJj123dj)
\ No newline at end of file
+© 2021 - 2026 - [DJdj Development](https://www.dj-dj.be) - [Terms](https://www.dj-dj.be/terms) - [Privacy Policy](https://www.dj-dj.be/privacy) - [Support Us](https://github.com/sponsors/DJj123dj)
\ No newline at end of file
diff --git a/.eggs/openticket-egg-v4.1.2.json b/.eggs/openticket-egg-v4.1.2.json
new file mode 100644
index 0000000..45d81a3
--- /dev/null
+++ b/.eggs/openticket-egg-v4.1.2.json
@@ -0,0 +1,62 @@
+{
+ "_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PTERODACTYL PANEL - PTERODACTYL.IO",
+ "meta": {
+ "version": "PTDL_v2",
+ "update_url": null
+ },
+ "exported_at": "2025-03-16T18:10:18+01:00",
+ "name": "Open Ticket (v4.1.2)",
+ "author": "support@dj-dj.be",
+ "description": "This is the official Pterodactyl egg for Open Ticket v4.1.2, the most advanced & customisable discord ticket bot that you will ever find! You can customise up to 300+ variables! This includes Html Transcripts, Advanced Plugins, Custom Embeds, Questions\/Modals, Stats & more!",
+ "features": null,
+ "docker_images": {
+ "ghcr.io\/parkervcp\/yolks:nodejs_20": "ghcr.io\/parkervcp\/yolks:nodejs_20"
+ },
+ "file_denylist": [],
+ "startup": "if [[ ! -z ${NODE_PACKAGES} ]]; then npm install ${NODE_PACKAGES}; fi; if [[ ! -z ${UNNODE_PACKAGES} ]]; then npm uninstall ${UNNODE_PACKAGES}; fi; if [ -f \/home\/container\/package.json ]; then npm install; fi; node \"\/home\/container\/index.js\" ${NODE_FLAGS};",
+ "config": {
+ "files": "{}",
+ "startup": "{\r\n \"done\": \"STARTUP INFO:\"\r\n}",
+ "logs": "{}",
+ "stop": "^C"
+ },
+ "scripts": {
+ "installation": {
+ "script": "#!\/bin\/bash\r\n# Open Ticket Installation Script (v4.1.2)\r\n# Inspired by: Node.js Installation Script\r\n# \u00a9 DJdj Development\r\n\r\necho -e \"[OT INSTALLER] installing dependencies. please wait...\"\r\napt update\r\napt install -y git curl\r\n\r\necho -e \"[OT INSTALLER] updating npm. please wait...\"\r\nnpm install npm@latest --location=global\r\n\r\nmkdir -p \/mnt\/server\r\ncd \/mnt\/server\r\n\r\nBRANCH=\"v4.1.2\"\r\n\r\nif [ \"$(ls -A \/mnt\/server)\" ]; then\r\n echo -e \"[OT INSTALLER] \/mnt\/server directory is not empty.\"\r\n if [ -d .git ]; then\r\n echo -e \"[OT INSTALLER] .git directory exists\"\r\n if [ -f .git\/config ]; then\r\n echo -e \"[OT INSTALLER] loading info from git config\"\r\n ORIGIN=$(git config --get remote.origin.url)\r\n else\r\n echo -e \"[OT INSTALLER] files found with no git config\"\r\n echo -e \"[OT INSTALLER] closing out without touching things to not break anything\"\r\n exit 10\r\n fi\r\n fi\r\n\r\n if [ \"${ORIGIN}\" == \"https:\/\/github.com\/open-discord-bots\/open-ticket.git\" ]; then\r\n echo \"pulling latest from github\"\r\n git pull\r\n fi\r\nelse\r\n echo -e \"[OT INSTALLER] \/mnt\/server is empty.\"\r\n echo -e \"[OT INSTALLER] cloning files into repo.\"\r\n if [ -z ${BRANCH} ]; then\r\n echo -e \"[OT INSTALLER] cloning default branch\"\r\n git clone https:\/\/github.com\/open-discord-bots\/open-ticket.git .\r\n else\r\n echo -e \"[OT INSTALLER] cloning ${BRANCH}'\"\r\n git clone --single-branch --branch ${BRANCH} https:\/\/github.com\/open-discord-bots\/open-ticket.git .\r\n fi\r\nfi\r\n\r\necho -e \"[OT INSTALLER] installing Open Ticket node.js packages.\"\r\nif [ -f \/mnt\/server\/package.json ]; then\r\n \/usr\/local\/bin\/npm install --omit=dev\r\nfi\r\n\r\necho -e \"[OT INSTALLER] installing custom node.js packages.\"\r\nif [[ ! -z ${NODE_PACKAGES} ]]; then\r\n \/usr\/local\/bin\/npm install ${NODE_PACKAGES}\r\nfi\r\n\r\necho -e \"[OT INSTALLER] install complete!\"\r\nexit 0",
+ "container": "node:latest",
+ "entrypoint": "bash"
+ }
+ },
+ "variables": [
+ {
+ "name": "Additional Npm Packages",
+ "description": "Specify additional npm packages used by Open Ticket plugins. Use spaces to separate.",
+ "env_variable": "NODE_PACKAGES",
+ "default_value": "",
+ "user_viewable": false,
+ "user_editable": true,
+ "rules": "string|nullable",
+ "field_type": "text"
+ },
+ {
+ "name": "Startup Flags",
+ "description": "Start the bot with additional Open Ticket flags. Separate using spaces.\r\nA full reference list can be found in the documentation.",
+ "env_variable": "NODE_FLAGS",
+ "default_value": "",
+ "user_viewable": false,
+ "user_editable": true,
+ "rules": "string|nullable",
+ "field_type": "text"
+ },
+ {
+ "name": "Uninstall Npm Packages",
+ "description": "A list of npm packages to uninstall. Separate by spaces.",
+ "env_variable": "UNNODE_PACKAGES",
+ "default_value": "",
+ "user_viewable": false,
+ "user_editable": true,
+ "rules": "string|nullable",
+ "field_type": "text"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index e583f05..f385196 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -1,7 +1,7 @@
# Contributing Guidelines
-[](https://discord.com/invite/26vT9wt3n3) [](https://github.com/open-discord-bots/open-ticket/releases/tag/v4.1.1) [](https://github.com/sponsors/DJj123dj)
+[](https://discord.com/invite/26vT9wt3n3) [](https://github.com/open-discord-bots/open-ticket/releases/tag/v4.1.2) [](https://github.com/sponsors/DJj123dj)
These are the Contributing Guidelines of Open Ticket!
Here you can find everything you need to know about contributing to Open Ticket.
@@ -89,4 +89,4 @@ you are **REQUIRED to send the bug privately via one of the following methods:**
**Contributing Guidelines**
[Changelog](https://otgithub.dj-dj.be/releases) - [Documentation](https://otdocs.dj-dj.be) - [Website](https://openticket.dj-dj.be) - [Support Server](https://discord.dj-dj.be) - [License](./LICENSE.md)
-© 2025 - [DJdj Development](https://www.dj-dj.be) - [Terms](https://www.dj-dj.be/terms) - [Privacy Policy](https://www.dj-dj.be/privacy) - [Support Us](https://github.com/sponsors/DJj123dj)
\ No newline at end of file
+© 2021 - 2026 - [DJdj Development](https://www.dj-dj.be) - [Terms](https://www.dj-dj.be/terms) - [Privacy Policy](https://www.dj-dj.be/privacy) - [Support Us](https://github.com/sponsors/DJj123dj)
\ No newline at end of file
diff --git a/.github/SECURITY.md b/.github/SECURITY.md
index f9216c0..0d27c2d 100644
--- a/.github/SECURITY.md
+++ b/.github/SECURITY.md
@@ -14,20 +14,21 @@ This list will be updated on every release.
- 🟦 In Development **(ideas, bugs, support, html transcripts)**
- ✅ Supported **(features, bugs, support, docs, html transcripts)**
- 🚧 Maintenance **(support, docs, html transcripts)**
-- 🟧 Deprecated **(docs)**
+- 🟧 Deprecated **(docs only)**
- ❌ Fully Deprecated
| Version | Supported | Notes |
|------------|-----------|---------------------------------------------------------------|
-| 4.2.0 | 🟦 | Transcripts v2.0 will be inaccessible when v4.2 is released. |
-| 4.1.2 | 🟦 | |
-| 4.1.1 | ✅ | |
-| 4.1.0 | ✅ | |
-| 4.0.7 | ✅ | Supported Until December 2025 (LTS) |
+| 4.2.0 | 🟦 | In Development |
+| 4.1.x | 🟦 | In Development |
+| 4.1.2 | ✅ | |
+| 4.1.1 | ✅ | Supported Until April 2026 (LTS) |
+| 4.1.0 | 🚧 | |
+| 4.0.7 | 🚧 | |
| 4.0.6 | 🚧 | |
-| 4.0.5 | 🚧 | |
-| 4.0.4 | 🚧 | |
-| < 4.0.4 | 🟧 | Deprecated Transcripts v2.0, Documentation Only |
+| 4.0.5 | 🟧 | Deprecated |
+| 4.0.4 | 🟧 | Deprecated |
+| < 4.0.4 | 🟧 | Deprecated, Transcripts v2.0, Documentation Only |
| < 4.0.0 | ❌ | |
### 🕷️ Reporting Vulnerabilities
@@ -50,4 +51,4 @@ If possible, try to provide screenshots!
**Security Policy**
[Changelog](https://otgithub.dj-dj.be/releases) - [Documentation](https://otdocs.dj-dj.be) - [Website](https://openticket.dj-dj.be) - [Support Server](https://discord.dj-dj.be) - [License](./LICENSE.md)
-© 2025 - [DJdj Development](https://www.dj-dj.be) - [Terms](https://www.dj-dj.be/terms) - [Privacy Policy](https://www.dj-dj.be/privacy) - [Support Us](https://github.com/sponsors/DJj123dj)
\ No newline at end of file
+© 2021 - 2026 - [DJdj Development](https://www.dj-dj.be) - [Terms](https://www.dj-dj.be/terms) - [Privacy Policy](https://www.dj-dj.be/privacy) - [Support Us](https://github.com/sponsors/DJj123dj)
\ No newline at end of file
diff --git a/LICENSE.md b/LICENSE.md
index c40fc44..8d20042 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,6 +1,6 @@
# Open Ticket (License)
-© 2025 - DJj123dj & Contributors
+© 2021 - 2026 - DJj123dj & Contributors
#### Table Of Contents
- [General License](#general-license)
diff --git a/README.md b/README.md
index 0378ef7..3f57fda 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
-> ### 🎥 Content Creators
-> Hey there! We're searching for content creators that would like to create a tutorial or setup guide for Open Ticket!
-> [📌 More Information](.github/CONTENT_CREATORS.md)
+> ### 📌 Open Ticket Quick Links
+> - [⏱️ Quick Setup](#️-quick-setup-using-cli)
+> - [📔 Documentation](https://otdocs.dj-dj.be)
+> - [🧩 Available Plugins](#-plugins)
+> - [📞 Discord Server](https://discord.dj-dj.be)
---
@@ -8,7 +10,7 @@
Powered By

-
+
@@ -71,9 +73,11 @@ A big thanks to all our sponsors! Without them, it wouldn't be possible to creat
@@ -144,7 +148,7 @@ With the amazing support of our translators, we've been able to translate Open T
|🟢 |❓ Catalan |guillee3 |
|🟢 |🇮🇩 Indonesian |erxg |
|🟢 |🇮🇳 Hindi |challenger_nova |
-|🟢⏳ |🇩🇪 German |benzorich |
+|🟢 |🇩🇪 German |benzorich |
|🟢⏳ |🇪🇸 Spanish |redactado & josuens |
|🟢⏳ |🇫🇷 French |guillee.3 |
|🟢⏳ |🇵🇹 Portuguese |quiradon |
@@ -254,4 +258,4 @@ This will help us grow and reach even more people!
**README.md**
[Changelog](https://otgithub.dj-dj.be/releases) - [Documentation](https://otdocs.dj-dj.be) - [Website](https://openticket.dj-dj.be) - [Support Server](https://discord.dj-dj.be) - [License](./LICENSE.md)
-© 2025 - [DJdj Development](https://www.dj-dj.be) - [Terms](https://www.dj-dj.be/terms) - [Privacy Policy](https://www.dj-dj.be/privacy) - [Support Us](https://github.com/sponsors/DJj123dj)
+© 2021 - 2026 - [DJdj Development](https://www.dj-dj.be) - [Terms](https://www.dj-dj.be/terms) - [Privacy Policy](https://www.dj-dj.be/privacy) - [Support Us](https://github.com/sponsors/DJj123dj)
diff --git a/config/general.json b/config/general.json
index 1a69e66..5c62a2b 100644
--- a/config/general.json
+++ b/config/general.json
@@ -2,7 +2,7 @@
"_INFO":{
"support":"https://otdocs.dj-dj.be",
"discord":"https://discord.dj-dj.be",
- "version":"open-ticket-v4.1.1"
+ "version":"open-ticket-v4.1.2"
},
"token":"insert your bot token here! (or leave empty when using 'tokenFromENV')",
diff --git a/config/panels.json b/config/panels.json
index 8747aff..f8f8f1b 100644
--- a/config/panels.json
+++ b/config/panels.json
@@ -17,7 +17,7 @@
"image":"https://www.example.com/image.png (or leave empty)",
"thumbnail":"https://www.example.com/image.png (or leave empty)",
- "footer":"Open Ticket v4.1.1 (or leave empty)",
+ "footer":"Open Ticket v4.1.2 (or leave empty)",
"fields":[
{"name":"field name","value":"field value","inline":false}
],
diff --git a/index.js b/index.js
index 440a9ef..c3bdea0 100644
--- a/index.js
+++ b/index.js
@@ -14,7 +14,7 @@ process.argv.push(...flags)
██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║ ██║ ██║██║ ██╔═██╗ ██╔══╝ ██║
╚██████╔╝██║ ███████╗██║ ╚████║ ██║ ██║╚██████╗██║ ██╗███████╗ ██║
╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═╝
- v4.1.1 - Made by DJj123dj & Contributors
+ v4.1.2 - Made by DJj123dj & Contributors
Discord: https://discord.dj-dj.be
Docs: https://otdocs.dj-dj.be
diff --git a/languages/arabic.json b/languages/arabic.json
index cd340f6..238fb0f 100644
--- a/languages/arabic.json
+++ b/languages/arabic.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION": {
- "otversion": "v4.1.1",
+ "otversion": "v4.1.2",
"translators": ["palestinian"],
"lastedited": "06/12/2024",
"language": "Arabic",
diff --git a/languages/bengali.json b/languages/bengali.json
index 2b759c0..32258f0 100644
--- a/languages/bengali.json
+++ b/languages/bengali.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["HanumeshGupta"],
"lastedited":"19/06/2025",
"language":"Bengali",
diff --git a/languages/catalan.json b/languages/catalan.json
index 18a26e9..cf8ddba 100644
--- a/languages/catalan.json
+++ b/languages/catalan.json
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["guillee3"],
- "lastedited":"16/11/2025",
+ "lastedited":"03/12/2025",
"language":"Catalan",
"automated":false
},
diff --git a/languages/custom.json b/languages/custom.json
index bfa160c..cd615aa 100644
--- a/languages/custom.json
+++ b/languages/custom.json
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["DJj123dj"],
- "lastedited":"16/11/2025",
+ "lastedited":"03/12/2025",
"language":"Custom",
"automated":false
},
diff --git a/languages/czech.json b/languages/czech.json
index 82dcd9f..8c0c68f 100644
--- a/languages/czech.json
+++ b/languages/czech.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["spyeye_"],
"lastedited":"21/08/2024",
"language":"Czech",
diff --git a/languages/danish.json b/languages/danish.json
index 4febf42..da10044 100644
--- a/languages/danish.json
+++ b/languages/danish.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["the_gamer"],
"lastedited":"26/09/2024",
"language":"Danish",
diff --git a/languages/dutch.json b/languages/dutch.json
index 982d582..a52c97a 100644
--- a/languages/dutch.json
+++ b/languages/dutch.json
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["DJj123dj"],
- "lastedited":"16/11/2025",
+ "lastedited":"03/12/2025",
"language":"Dutch",
"automated":false
},
diff --git a/languages/english.json b/languages/english.json
index 1ed67c7..7639e07 100644
--- a/languages/english.json
+++ b/languages/english.json
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["DJj123dj"],
- "lastedited":"16/11/2025",
+ "lastedited":"03/12/2025",
"language":"English",
"automated":false
},
diff --git a/languages/estonian.json b/languages/estonian.json
index 73ccdb0..d339152 100644
--- a/languages/estonian.json
+++ b/languages/estonian.json
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["iamnotmega","ChatGPT"],
- "lastedited":"16/11/2025",
+ "lastedited":"03/12/2025",
"language":"Estonian",
"automated":true
},
diff --git a/languages/finnish.json b/languages/finnish.json
index b35da41..29f3c90 100644
--- a/languages/finnish.json
+++ b/languages/finnish.json
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["iamnotmega","ChatGPT"],
- "lastedited":"16/11/2025",
+ "lastedited":"03/12/2025",
"language":"Finnish",
"automated":true
},
diff --git a/languages/french.json b/languages/french.json
index ce0306e..93eebb7 100644
--- a/languages/french.json
+++ b/languages/french.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["guillee3"],
"lastedited":"04/12/2024",
"language":"French",
diff --git a/languages/german.json b/languages/german.json
index 7731b68..d0bfd55 100644
--- a/languages/german.json
+++ b/languages/german.json
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["benzorich"],
- "lastedited":"06/10/2024",
+ "lastedited":"03/12/2025",
"language":"German",
"automated":false
},
@@ -31,7 +31,15 @@
"stringContains":"Diese Zeichenfolge muss {0} enthalten!",
"stringChoices":"Diese Zeichenfolge kann nur einen der folgenden Werte annehmen: {0}!",
"stringRegex":"Diese Zeichenfolge ist ungültig!",
-
+ "stringInvertedContains":"Diese Zeichenkette darf {0} nicht enthalten!",
+ "stringLowercase":"Diese Zeichenkette muss ausschließlich in Kleinbuchstaben geschrieben werden!",
+ "stringUppercase":"Diese Zeichenkette muss ausschließlich in Großbuchstaben geschrieben werden!",
+ "stringSpecialCharacters":"Diese Zeichenkette darf keine Sonderzeichen enthalten! (nur a-z, 0-9 & Leerzeichen)",
+ "stringNoSpaces":"Diese Zeichenkette darf keine Leerzeichen enthalten!",
+ "stringCapitalWord":"Es wird empfohlen, dass jedes Wort in dieser Zeichenkette mit einem Großbuchstaben beginnt!",
+ "stringCapitalSentence":"Es sieht so aus, als würden einige Sätze in dieser Zeichenkette nicht mit einem Großbuchstaben beginnen!",
+ "stringPunctuation":"Es sieht so aus, als würde der Satz in dieser Zeichenkette nicht mit einem Satzzeichen enden!",
+
"numberTooShort":"Diese Zahl kann nicht kürzer als {0} Zeichen sein!",
"numberTooLong":"Diese Nummer darf nicht länger als {0} Zeichen sein!",
"numberLengthInvalid":"Diese Nummer muss {0} Zeichen lang sein!",
@@ -48,10 +56,12 @@
"numberNegative":"Diese Zahl kann nicht negativ sein!",
"numberPositive":"Diese Zahl kann nicht positiv sein!",
"numberZero":"Diese Zahl kann nicht Null sein!",
-
+ "numberNan":"Diese Zahl darf nicht NaN (Not A Number) sein!",
+ "numberInvertedContains":"Diese Zahl darf {0} nicht enthalten!",
+
"booleanTrue":"Dieser boolean Wert kann nicht wahr sein!",
"booleanFalse":"Dieser boolean Wert kann nicht falsch sein!",
-
+
"arrayEmptyDisabled":"Dieses Array darf nicht leer sein!",
"arrayEmptyRequired":"Dieses Array muss leer sein!",
"arrayTooShort":"Dieses Array muss eine Länge von mindestens {0} haben!",
@@ -59,7 +69,7 @@
"arrayLengthInvalid":"Dieses Array muss eine Länge von {0} haben!",
"arrayInvalidTypes":"Dieses Array kann nur die folgenden Typen enthalten: {0}!",
"arrayDouble":"In diesem Array darf derselbe Wert nicht zweimal vorkommen!",
-
+
"discordInvalidId":"Dies ist eine ungültige Discord {0} id!",
"discordInvalidIdOptions":"Dies ist eine ungültige Discord {0} id! Du kannst auch eine der folgenden verwenden: {1}!",
"discordInvalidToken":"Das ist ein ungültiger Discord-Token (syntaktisch)!",
@@ -76,7 +86,7 @@
"urlInvalidPath":"Diese Url hat einen ungültigen Pfad!",
"idNotUnique":"Diese ID ist nicht eindeutig, verwenden Sie stattdessen eine andere ID!",
"idNonExistent":"Die ID {0} existiert nicht!",
-
+
"invalidType":"Diese Eigenschaft muss vom Typ sein: {0}!",
"propertyMissing":"Die Eigenschaft {0} fehlt in diesem Objekt!",
"propertyOptional":"Die Eigenschaft {0} ist in diesem Objekt optional!",
@@ -84,12 +94,13 @@
"nullInvalid":"Diese Eigenschaft kann nicht null sein!",
"switchInvalidType":"Dies muss einer der folgenden Typen sein: {0}!",
"objectSwitchInvalid":"Dieses Objekt muss einer der folgenden Typen sein: {0}!",
-
+
"invalidLanguage":"Dies ist eine ungültige Sprache!",
"invalidButton":"Dieser Button muss mindestens eine {0} oder {1} enthalten!",
"unusedOption":"Die Option {0} wird nirgends verwendet!",
"unusedQuestion":"Die Frage {0} wird nirgends verwendet!",
- "dropdownOption":"Ein Panel mit aktiviertem Dropdown kann nur Optionen vom Typ 'Ticket' enthalten!"
+ "dropdownOption":"Ein Panel mit aktiviertem Dropdown kann nur Optionen vom Typ 'Ticket' enthalten!",
+ "customInvalidVersion":"Die in deiner Konfiguration angegebene Version stimmt nicht überein! Stelle sicher, dass du die Konfiguration auf die neueste Version aktualisiert hast!"
}
},
"actions":{
@@ -132,6 +143,7 @@
"blacklistAddDm":"Zur Blacklist hinzugefügt",
"blacklistRemoveDm":"Von der Blacklist entfernen",
"clear":"Freigegebene Tickets",
+ "clearTickets":"Tickets Löschen",
"roles":"Aktualisierte Rollen",
"autoclose":"Ticket automatisch geschlossen",
@@ -139,7 +151,12 @@
"autocloseDisabled":"Automatisches schließen Deaktiviert",
"autodelete":"Ticket automatisch gelöscht",
"autodeleteEnabled":"Automatisches Löschen Aktiviert",
- "autodeleteDisabled":"Automatisches Löschen Deaktiviert"
+ "autodeleteDisabled":"Automatisches Löschen Deaktiviert",
+
+ "topicSet":"Thema Geändert",
+ "prioritySet":"Priorität Geändert",
+ "priorityGet":"Ticket-Priorität",
+ "transfer":"Ticket Übertragen"
},
"descriptions":{
"create":"Ihr Ticket wurde bereits erstellt. Klicken Sie auf die Button unten, um es zu öffnen!",
@@ -154,7 +171,7 @@
"move":"Das Ticket wurde erfolgreich nach {0} verschoben!",
"add":"{0} wurde erfolgreich zum Ticket hinzugefügt!",
"remove":"{0} wurde erfolgreich aus dem Ticket entfernt!",
-
+
"helpExplanation":"`` => erforderlicher Parameter\n`[name]` => optionaler Parameter",
"statsReset":"Die Bot-Statistiken wurden erfolgreich zurückgesetzt!",
"statsError":"Ticketstatistiken können nicht angezeigt werden!\n{0} ist kein Ticket!",
@@ -167,7 +184,7 @@
"clearVerify":"Sind Sie sicher, dass Sie mehrere Tickets löschen möchten?\nDiese Aktion kann nicht rückgängig gemacht werden!",
"clearReady":"{0} Tickets wurden erfolgreich gelöscht!",
"rolesEmpty":"Es wurden keine Rollen aktualisiert!",
-
+
"autocloseLeave":"Dieses Ticket wurde automatisch geschlossen, weil der Ersteller den Server verlassen hat!",
"autocloseTimeout":"Dieses Ticket wurde automatisch geschlossen, da es seit mehr als `{0}h` inaktiv ist!",
"autodeleteLeave":"Dieses Ticket wurde automatisch gelöscht, weil der Ersteller den Server verlassen hat!",
@@ -176,11 +193,16 @@
"autocloseDisabled":"Autoclose wurde für dieses Ticket deaktiviert! Es wird nicht mehr automatisch geschlossen!",
"autodeleteEnabled":"Automatisches Löschen wurde für dieses Ticket aktiviert! Es wird gelöscht, wenn es länger als `{0} Tage` inaktiv ist!",
"autodeleteDisabled":"Automatisches Löschen wurde bei diesem Ticket deaktiviert! Es wird nicht mehr automatisch gelöscht!",
-
+
"ticketMessageLimit":"Sie können nur {0} Tickets gleichzeitig erstellen!",
"ticketMessageAutoclose":"Dieses Ticket wird automatisch geschlossen, wenn es {0}h lang inaktiv war!",
"ticketMessageAutodelete":"Dieses Ticket wird automatisch gelöscht, wenn es {0} Tage lang inaktiv war!",
- "panelReady":"Sie finden das Panel unten!\nDiese Nachricht kann jetzt gelöscht werden!"
+ "panelReady":"Das Panel ist in der folgenden Nachricht verfügbar!\nDiese Nachricht kann nun gelöscht werden!",
+
+ "topicSet":"Das Kanalthema wurde erfolgreich von {0} geändert!",
+ "prioritySet":"Die Ticket-Priorität wurde erfolgreich von {1} auf {0} geändert!",
+ "priorityGet":"Die aktuelle Priorität dieses Tickets ist {0}.",
+ "transfer":"Das Ticket wurde erfolgreich von {0} an {1} durch {2} übertragen!"
},
"modal":{
"closePlaceholder":"Warum haben Sie dieses Ticket geschlossen?",
@@ -215,12 +237,19 @@
"addDm":"{0} wurde zu Ihrem Ticket auf unserem Server hinzugefügt!",
"removeLog":"{0} wurde von {1} aus diesem Ticket entfernt!",
"removeDm":"{0} wurde von Ihrem Ticket auf unserem Server entfernt!",
-
+
"blacklistAddLog":"{0} wurde von {1} auf die Blacklist gesetzt!",
"blacklistRemoveLog":"{0} wurde von {1} von der Blacklist entfernt!",
"blacklistAddDm":"Sie wurden in unserem Server auf die Blacklist gesetzt!\nAb sofort können Sie kein Ticket mehr erstellen!",
"blacklistRemoveDm":"Sie wurden von der Blacklist unseres Servers entfernt!\n Jetzt können Sie wieder Tickets erstellen!",
- "clearLog":"{0} Tickets wurden von {1} gelöscht!"
+ "clearLog":"{0} Tickets wurden von {1} gelöscht!",
+
+ "transferLog":"Das Ticket wurde von {0} an {1} durch {2} übertragen!",
+ "transferDm":"Dein Ticket wurde von {0} an {1} auf unserem Server übertragen!",
+ "prioritySetLog":"Die Priorität dieses Tickets wurde von {1} auf {0} geändert!",
+ "prioritySetDm":"Die Priorität deines Tickets wurde auf unserem Server auf {0} geändert!",
+ "roleUpdateLog":"{0} hat seine Rollen aktualisiert!",
+ "roleUpdateDm":"Deine Rollen auf unserem Server wurden aktualisiert!"
}
},
"transcripts":{
@@ -229,7 +258,7 @@
"ready":"Transkript erstellt",
"textFileDescription":"Dies ist die Textabschrift eines gelöschten Tickets!",
"htmlProgress":"Bitte warten Sie, während dieses html-Transkript verarbeitet wird...",
-
+
"createdChannel":"Ein neues {0} Transkript wurde auf dem Server erstellt!",
"createdCreator":"Es wurde ein neues {0} Transkript für eines Ihrer Tickets erstellt!",
"createdParticipant":"In einem der Tickets, an denen Sie teilgenommen haben, wurde ein neues {0} Transkript erstellt!",
@@ -241,7 +270,19 @@
"retry":"Erneut versuchen",
"continue":"Löschen ohne Transkript",
"backup":"Sicherungstranskript erstellen",
- "error":"Beim Versuch, das Transkript zu erstellen, ist etwas schief gelaufen.\nWas möchten Sie tun?\n\nDieses Ticket wird erst gelöscht, wenn Sie auf eine der folgenden Buttons klicken."
+ "error":"Beim Versuch, das Transkript zu erstellen, ist etwas schief gelaufen.\nWas möchten Sie tun?\n\nDieses Ticket wird erst gelöscht, wenn Sie auf eine der folgenden Buttons klicken.",
+ "title":"Transkript-Fehler"
+ },
+ "text":{
+ "messagesTitle":"NACHRICHTEN",
+ "embedTitle":"EMBED",
+ "fileTitle":"DATEI",
+ "fieldsTitle":"FELDER",
+ "reactionsTitle":"REAKTIONEN",
+ "statsTitle":"STATISTIKEN",
+ "emptyContent":"",
+ "noTitle":"",
+ "noDesc":""
}
},
"errors":{
@@ -257,7 +298,8 @@
"unknownPanel":"Unbekanntes Panel",
"notInGuild":"Nicht auf dem Server",
"channelRename":"Kanal kann nicht umbenannt werden",
- "busy":"Ticket ist besetzt"
+ "busy":"Ticket ist besetzt",
+ "permissionError":"Berechtigungsfehler"
},
"descriptions":{
"askForInfo":"Kontaktieren Sie den Besitzer dieses Bots für weitere Informationen!",
@@ -280,7 +322,10 @@
"notInGuild":"{0} funktioniert nicht in DM! Bitte versuchen Sie es erneut auf einem Server!",
"channelRename":"Aufgrund von Discord-Ratelimits ist es dem Bot derzeit nicht möglich, den Channel umzubenennen. Der Channel wird nach 10 Minuten automatisch umbenannt, wenn der Bot nicht neu gestartet wird.",
"channelRenameSource":"Die Quelle dieses Fehlers ist: {0}",
- "busy":"{0} kann nicht verwendet werden!\nDas Ticket wird derzeit vom Bot bearbeitet.\n\nBitte versuchen Sie es in ein paar Sekunden erneut!"
+ "busy":"{0} kann nicht verwendet werden!\nDas Ticket wird derzeit vom Bot bearbeitet.\n\nBitte versuchen Sie es in ein paar Sekunden erneut!",
+ "closeBeforeMessage":"Dieses Ticket kann nicht geschlossen/gelöscht werden, bevor eine Nachricht von einem Benutzer gesendet wurde.",
+ "closeBeforeAdminMessage":"Dieses Ticket kann nicht geschlossen/gelöscht werden, bevor eine Nachricht von einem Ticket-Admin oder Support-Mitglied gesendet wurde.",
+ "unableToCreateTicket":"Du kannst kein Ticket erstellen."
},
"optionInvalidReasons":{
"stringRegex":"Wert stimmt nicht mit Muster überein!",
@@ -331,7 +376,6 @@
"added":"Hinzugefügt",
"removed":"Entfernt",
"filter":"Filter",
- "claimedBy":"Beansprucht von {0}",
"method":"Methode",
"type":"Typ",
"blacklisted":"Gesperrt",
@@ -355,7 +399,27 @@
"status":"Status",
"claimed":"Beansprucht",
"pinned":"Angepinnt",
- "creationDate":"Erstellungsdatum"
+ "creationDate":"Erstellungsdatum",
+
+ "noone":"Niemand",
+ "open":"Offen",
+ "closed":"Geschlossen",
+ "priority":"Priorität",
+ "participants":"Teilnehmer",
+ "yes":"Ja",
+ "no":"Nein",
+ "option":"Option",
+ "topic":"Thema",
+ "uptime":"System-Laufzeit",
+ "messages":"Nachrichten",
+ "embeds":"Embeds",
+ "files":"Dateien",
+ "components":"Komponenten",
+ "cooldown":"Cooldown",
+ "maxTickets":"Max. Tickets",
+ "admins":"Admins",
+ "roles":"Rollen",
+ "size":"Größe"
},
"lowercase":{
"text":"text",
@@ -384,6 +448,7 @@
"unclaim":"Beanspruchen Sie ein Ticket zurück.",
"pin":"Pinne ein Ticket an.",
"unpin":"Pinne ein Ticket ab.",
+
"move":"Verschieben Sie ein Ticket.",
"moveId":"Die Kennung der Option.",
"rename":"Ein Ticket umbenennen.",
@@ -392,6 +457,7 @@
"addUser":"Der hinzuzufügende Benutzer.",
"remove":"Entfernen Sie einen Benutzer aus einem Ticket.",
"removeUser":"Der zu entfernende Benutzer.",
+
"blacklist":"Verwalten Sie die Blacklist für Tickets.",
"blacklistView":"Zeigen Sie eine Liste der aktuellen Blacklist an.",
"blacklistAdd":"Hinzufügen eines Benutzers zur Blacklist.",
@@ -405,6 +471,7 @@
"statsUserUser":"Der zu betrachtende Benutzer.",
"statsTicket":"Anzeigen der Statistiken eines Tickets auf dem Server.",
"statsTicketTicket":"Das Ticket zur Betrachtung.",
+
"clear":"Mehrere Tickets gleichzeitig löschen. Optional kann ein Filter angegeben werden.",
"clearFilter":"Der Filter zum Löschen von Tickets.",
"clearFilters":{
@@ -417,6 +484,7 @@
"unpin":"nicht Angepinnte",
"autoclose":"Autoclosed"
},
+
"autoclose":"Verwalten Sie die automatische Schließung in einem Ticket.",
"autocloseDisable":"Deaktivieren Sie das automatische Schließen in diesem Ticket.",
"autocloseEnable":"Aktivieren Sie das automatische Schließen in diesem Ticket.",
@@ -424,7 +492,19 @@
"autodelete":"Verwalten Sie die automatische Löschung in einem Ticket.",
"autodeleteDisable":"Deaktivieren Sie das automatische Löschen in diesem Ticket.",
"autodeleteEnable":"Aktivieren Sie das automatische Löschen in diesem Ticket.",
- "autodeleteEnableTime":"Die Anzahl der Tage, die das Ticket inaktiv sein muss, um es zu löschen."
+ "autodeleteEnableTime":"Die Anzahl der Tage, die das Ticket inaktiv sein muss, um es zu löschen.",
+
+ "topic":"Verwalte das Thema des Ticket-Kanals.",
+ "topicSet":"Setze das Thema des Ticket-Kanals.",
+ "topicValue":"Das neue Thema des Kanals.",
+ "topicList":"Zeige eine Liste aller Tickets mit ihrem Thema und Statistiken an.",
+ "priority":"Verwalte die Priorität des Tickets.",
+ "prioritySet":"Setze die Priorität des Tickets.",
+ "priorityValue":"Die Priorität des Kanals.",
+ "priorityGet":"Zeige die Priorität des Tickets an.",
+ "priorityList":"Zeige eine Liste aller Tickets mit ihrem Prioritätsstatus an.",
+ "transfer":"Übertrage das Ticket von einem Benutzer an einen anderen.",
+ "transferUser":"Der Benutzer, an den übertragen werden soll."
},
"helpMenu":{
"help":"Erhalten Sie eine Liste mit allen verfügbaren Befehlen.",
@@ -452,7 +532,16 @@
"autocloseDisable":"Deaktivieren Sie das automatische Schließen in diesem Ticket.",
"autocloseEnable":"Aktivieren Sie das automatische Schließen in diesem Ticket.",
"autodeleteDisable":"Deaktivieren Sie das automatische Löschen in diesem Ticket.",
- "autodeleteEnable":"Aktivieren Sie das automatische Löschen in diesem Ticket."
+ "autodeleteEnable":"Aktivieren Sie das automatische Löschen in diesem Ticket.",
+ "categories":{
+ "general":"Allgemeine Befehle",
+ "basicTicket":"Basis-Ticket-Befehle",
+ "advancedTicket":"Erweiterte Ticket-Befehle",
+ "userTicket":"Benutzer-Ticket-Befehle",
+ "admin":"Admin-Befehle",
+ "advanced":"Erweiterte Befehle",
+ "extra":"Extra-Befehle"
+ }
},
"stats":{
"scopes":{
@@ -460,7 +549,8 @@
"system":"System-Statistiken",
"user":"Benutzer-Statistiken",
"ticket":"Ticket-Statistiken",
- "participants":"Teilnehmer"
+ "participants":"Teilnehmer",
+ "messages":"Nachrichten"
},
"properties":{
"ticketsCreated":"Tickets erstellt",
@@ -472,7 +562,47 @@
"ticketsPinned":"Tickets angepinnt",
"ticketsMoved":"Tickets verschoben",
"usersBlacklisted":"Nutzer auf der Blacklist",
- "transcriptsCreated":"Transcripts erstellt"
+ "transcriptsCreated":"Transcripts erstellt",
+ "ticketsAutodeleted":"Automatisch gelöschte Tickets",
+ "ticketsTransferred":"Übertragene Tickets",
+ "ticketVolume":"Ticket-Volumen",
+ "averageTickets":"Durchschnittliche Tickets/Benutzer",
+ "currentTickets":"Aktuelle Tickets",
+ "age":"Ticket-Alter",
+ "responseTime":"Antwortzeit",
+ "resolutionTime":"Lösungszeit",
+ "createdOn":"Erstellt am",
+ "createdBy":"Erstellt von",
+ "closedOn":"Geschlossen am",
+ "closedBy":"Geschlossen von",
+ "claimedOn":"Angenommen am",
+ "claimedBy":"Angenommen von",
+ "pinnedOn":"Angepinnt am",
+ "pinnedBy":"Angepinnt von",
+ "deletedOn":"Gelöscht am",
+ "deletedBy":"Gelöscht von"
+ },
+ "roles":{
+ "developer":"Entwickler",
+ "serverOwner":"Server-Besitzer",
+ "serverAdmin":"Server-Administrator",
+ "moderator":"Moderatoren-Team",
+ "support":"Support-Team",
+ "member":"Mitglied"
}
+ },
+ "panel":{
+ "selectTicket":"Wähle dein Ticket",
+ "selectRole":"Wähle deine Rolle",
+ "selectOption":"Wähle deine Option"
+ },
+ "priorities":{
+ "urgent":"Dringend",
+ "veryHigh":"Sehr Hoch",
+ "high":"Hoch",
+ "normal":"Normal",
+ "low":"Niedrig",
+ "veryLow":"Sehr Niedrig",
+ "none":"Keine"
}
}
\ No newline at end of file
diff --git a/languages/greek.json b/languages/greek.json
index 69c651d..cb11870 100644
--- a/languages/greek.json
+++ b/languages/greek.json
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["HanumeshGupta","ChatGPT"],
- "lastedited":"16/11/2025",
+ "lastedited":"03/12/2025",
"language":"Greek",
"automated":true
},
diff --git a/languages/hindi.json b/languages/hindi.json
index fe5212f..d8e3de0 100644
--- a/languages/hindi.json
+++ b/languages/hindi.json
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["challenger_nova"],
- "lastedited":"16/11/2025",
+ "lastedited":"03/12/2025",
"language":"Hindi",
"automated":false
},
diff --git a/languages/hungarian.json b/languages/hungarian.json
index 3d11c28..ba38be9 100644
--- a/languages/hungarian.json
+++ b/languages/hungarian.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["Kornel0706"],
"lastedited":"22/08/2024",
"language":"Hungarian",
diff --git a/languages/indonesian.json b/languages/indonesian.json
index 38651c4..8693ee0 100644
--- a/languages/indonesian.json
+++ b/languages/indonesian.json
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["erxg"],
- "lastedited":"16/11/2025",
+ "lastedited":"03/12/2025",
"language":"Indonesian",
"automated":false
},
diff --git a/languages/italian.json b/languages/italian.json
index f437372..18500da 100644
--- a/languages/italian.json
+++ b/languages/italian.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["fraden1mvp."],
"lastedited":"08/10/2024",
"language":"Italian",
diff --git a/languages/japanese.json b/languages/japanese.json
index bd1ff6c..8a5a047 100644
--- a/languages/japanese.json
+++ b/languages/japanese.json
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["HanumeshGupta","ChatGPT"],
- "lastedited":"16/11/2025",
+ "lastedited":"03/12/2025",
"language":"Japanese",
"automated":true
},
diff --git a/languages/korean.json b/languages/korean.json
index 1d1f9ea..2827074 100644
--- a/languages/korean.json
+++ b/languages/korean.json
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["HanumeshGupta","ChatGPT"],
- "lastedited":"16/11/2025",
+ "lastedited":"03/12/2025",
"language":"Korean",
"automated":true
},
diff --git a/languages/kurdish.json b/languages/kurdish.json
index c2c8a86..1108685 100644
--- a/languages/kurdish.json
+++ b/languages/kurdish.json
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["HanumeshGupta","ChatGPT"],
- "lastedited":"16/11/2025",
+ "lastedited":"03/12/2025",
"language":"Kurdish",
"automated":false
},
diff --git a/languages/latvian.json b/languages/latvian.json
index cc8070d..fc40af4 100644
--- a/languages/latvian.json
+++ b/languages/latvian.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION": {
- "otversion": "v4.1.1",
+ "otversion": "v4.1.2",
"translators": ["NoOneNook"],
"lastedited": "25/03/2025",
"language": "Latvian",
diff --git a/languages/lithuanian.json b/languages/lithuanian.json
index 016a824..3ceb5a1 100644
--- a/languages/lithuanian.json
+++ b/languages/lithuanian.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["TsgIndrius"],
"lastedited":"26/01/2025",
"language":"Lithuanian",
diff --git a/languages/norwegian.json b/languages/norwegian.json
index 84a72dc..91cfe16 100644
--- a/languages/norwegian.json
+++ b/languages/norwegian.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION": {
- "otversion": "v4.1.1",
+ "otversion": "v4.1.2",
"translators": ["NoOneNook"],
"lastedited": "25/03/2025",
"language": "Norwegian",
diff --git a/languages/persian.json b/languages/persian.json
index dd24b07..1ee9a45 100644
--- a/languages/persian.json
+++ b/languages/persian.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["dysashop","zhavis"],
"lastedited":"28/05/2025",
"language":"Persian",
diff --git a/languages/polish.json b/languages/polish.json
index bfa3d8e..bbd35dc 100644
--- a/languages/polish.json
+++ b/languages/polish.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["DanoGlez"],
"lastedited":"28/01/2025",
"language":"Polish",
diff --git a/languages/portuguese.json b/languages/portuguese.json
index 208e748..ff76c90 100644
--- a/languages/portuguese.json
+++ b/languages/portuguese.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["quiradon"],
"lastedited":"20/08/2024",
"language":"Portuguese",
diff --git a/languages/romanian.json b/languages/romanian.json
index 82a4bf1..19fb1aa 100644
--- a/languages/romanian.json
+++ b/languages/romanian.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["SankeDev"],
"lastedited":"27/08/2024",
"language":"Romanian",
diff --git a/languages/russian.json b/languages/russian.json
index f14fe96..a0411cd 100644
--- a/languages/russian.json
+++ b/languages/russian.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION": {
- "otversion": "v4.1.1",
+ "otversion": "v4.1.2",
"translators": ["NoOneNook"],
"lastedited": "25/03/2025",
"language": "Russian",
diff --git a/languages/simplified-chinese.json b/languages/simplified-chinese.json
index 3e7894b..2a5d02c 100644
--- a/languages/simplified-chinese.json
+++ b/languages/simplified-chinese.json
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["HanumeshGupta","ChatGPT"],
- "lastedited":"16/11/2025",
+ "lastedited":"03/12/2025",
"language":"Simplified Chainese",
"automated":true
},
diff --git a/languages/slovenian.json b/languages/slovenian.json
index a7dae38..84b1da6 100644
--- a/languages/slovenian.json
+++ b/languages/slovenian.json
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["HanumeshGupta","ChatGPT"],
- "lastedited":"16/11/2025",
+ "lastedited":"03/12/2025",
"language":"Solvenian",
"automated":true
},
diff --git a/languages/spanish.json b/languages/spanish.json
index f9a96a2..34e98ea 100644
--- a/languages/spanish.json
+++ b/languages/spanish.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["Redactado","Josuens"],
"lastedited":"22/08/2024",
"language":"Spanish",
diff --git a/languages/swedish.json b/languages/swedish.json
index d117fcb..e319ee3 100644
--- a/languages/swedish.json
+++ b/languages/swedish.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION": {
- "otversion": "v4.1.1",
+ "otversion": "v4.1.2",
"translators": ["NoOneNook"],
"lastedited": "25/03/2025",
"language": "Svenska",
diff --git a/languages/tamil.json b/languages/tamil.json
index 1d72cf7..97b0ff7 100644
--- a/languages/tamil.json
+++ b/languages/tamil.json
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["HanumeshGupta","ChatGPT"],
- "lastedited":"16/11/2025",
+ "lastedited":"03/12/2025",
"language":"Tamil",
"automated":true
},
diff --git a/languages/thai.json b/languages/thai.json
index 7f47338..13c120e 100644
--- a/languages/thai.json
+++ b/languages/thai.json
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["modshd"],
- "lastedited":"16/11/2025",
+ "lastedited":"03/12/2025",
"language":"Thai",
"automated":false
},
diff --git a/languages/turkish.json b/languages/turkish.json
index 88e9906..5c286f7 100644
--- a/languages/turkish.json
+++ b/languages/turkish.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION": {
- "otversion": "v4.1.1",
+ "otversion": "v4.1.2",
"translators": ["palestinian"],
"lastedited": "26/11/2024",
"language": "Turkish",
diff --git a/languages/ukrainian.json b/languages/ukrainian.json
index e946d89..83f7888 100644
--- a/languages/ukrainian.json
+++ b/languages/ukrainian.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["Anderskiy"],
"lastedited":"31/08/2024",
"language":"Ukrainian",
diff --git a/languages/vietnamese.json b/languages/vietnamese.json
index e038411..71a63dc 100644
--- a/languages/vietnamese.json
+++ b/languages/vietnamese.json
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
- "otversion":"v4.1.1",
+ "otversion":"v4.1.2",
"translators":["ngocdiep2006"],
"lastedited":"07/04/2025",
"language":"Vietnamese",
diff --git a/package.json b/package.json
index 7e6c462..ec4f105 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "open-ticket",
"author": "DJdj Development",
- "version": "4.1.1",
+ "version": "4.1.2",
"description": "The most advanced open-source discord ticket bot with HTML transcripts, plugins, questions, claiming, pinning & more! Using discord.js v14 & JSON database! ",
"keywords": [
"ticket-bot",
diff --git a/src/actions/closeTicket.ts b/src/actions/closeTicket.ts
index 083a903..e09bb2c 100644
--- a/src/actions/closeTicket.ts
+++ b/src/actions/closeTicket.ts
@@ -169,62 +169,44 @@ export const registerVerifyBars = async () => {
//CLOSE TICKET TICKET MESSAGE
opendiscord.verifybars.add(new api.ODVerifyBar("opendiscord:close-ticket-ticket-message",opendiscord.builders.messages.getSafe("opendiscord:verifybar-ticket-message"),!generalConfig.data.system.disableVerifyBars))
opendiscord.verifybars.get("opendiscord:close-ticket-ticket-message").success.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.close
-
- 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:close-ticket",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ const {user,member,channel,guild} = instance
+
+ //check permissions
+ const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.close,"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("button",{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 already closed
if (ticket.get("opendiscord:closed").value){
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build("button",{guild,channel,user,error:lang.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()
}
+
//return when not allowed because of missing messages
- if (!generalConfig.data.system.allowCloseBeforeMessage || !generalConfig.data.system.allowCloseBeforeAdminMessage){
+ if (!permsResult.isAdmin && (!generalConfig.data.system.allowCloseBeforeMessage || !generalConfig.data.system.allowCloseBeforeAdminMessage)){
const analysis = await opendiscord.transcripts.collector.ticketUserMessagesAnalysis(ticket,guild,channel)
if (analysis && !generalConfig.data.system.allowCloseBeforeMessage && analysis.totalMessages < 1){
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build("button",{guild,channel,user,layout:"simple",error:lang.getTranslation("errors.descriptions.closeBeforeMessage"),customTitle:lang.getTranslation("errors.titles.noPermissions")}))
@@ -268,62 +250,44 @@ export const registerVerifyBars = async () => {
//CLOSE TICKET REOPEN MESSAGE
opendiscord.verifybars.add(new api.ODVerifyBar("opendiscord:close-ticket-reopen-message",opendiscord.builders.messages.getSafe("opendiscord:verifybar-reopen-message"),!generalConfig.data.system.disableVerifyBars))
opendiscord.verifybars.get("opendiscord:close-ticket-reopen-message").success.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.close
-
- 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:close-ticket",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ const {user,member,channel,guild} = instance
+
+ //check permissions
+ const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.close,"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("button",{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 already closed
if (ticket.get("opendiscord:closed").value){
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build("button",{guild,channel,user,error:lang.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()
}
+
//return when not allowed because of missing messages
- if (!generalConfig.data.system.allowCloseBeforeMessage || !generalConfig.data.system.allowCloseBeforeAdminMessage){
+ if (!permsResult.isAdmin && (!generalConfig.data.system.allowCloseBeforeMessage || !generalConfig.data.system.allowCloseBeforeAdminMessage)){
const analysis = await opendiscord.transcripts.collector.ticketUserMessagesAnalysis(ticket,guild,channel)
if (analysis && !generalConfig.data.system.allowCloseBeforeMessage && analysis.totalMessages < 1){
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build("button",{guild,channel,user,layout:"simple",error:lang.getTranslation("errors.descriptions.closeBeforeMessage"),customTitle:lang.getTranslation("errors.titles.noPermissions")}))
diff --git a/src/actions/deleteTicket.ts b/src/actions/deleteTicket.ts
index 07d6996..68b0d16 100644
--- a/src/actions/deleteTicket.ts
+++ b/src/actions/deleteTicket.ts
@@ -119,8 +119,16 @@ export const registerVerifyBars = async () => {
//DELETE TICKET TICKET MESSAGE
opendiscord.verifybars.add(new api.ODVerifyBar("opendiscord:delete-ticket-ticket-message",opendiscord.builders.messages.getSafe("opendiscord:verifybar-ticket-message"),!generalConfig.data.system.disableVerifyBars))
opendiscord.verifybars.get("opendiscord:delete-ticket-ticket-message").success.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.delete
+ new api.ODWorker("opendiscord:delete-ticket",0,async (instance,params,source,cancel) => {
+ const {user,member,channel,guild} = instance
+
+ //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("button",{guild,channel,user,permissions:["support"]}))
+ return cancel()
+ }
//don't allow deleteWithoutTranscript to non-global-admins when enabled
if (params.data == "no-transcript" && generalConfig.data.system.adminOnlyDeleteWithoutTranscript){
@@ -130,54 +138,27 @@ export const registerVerifyBars = async () => {
}
}
- 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,source,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("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()
}
+
//return when not allowed because of missing messages
- if (!generalConfig.data.system.allowCloseBeforeMessage || !generalConfig.data.system.allowCloseBeforeAdminMessage){
+ if (!permsResult.isAdmin && (!generalConfig.data.system.allowCloseBeforeMessage || !generalConfig.data.system.allowCloseBeforeAdminMessage)){
const analysis = await opendiscord.transcripts.collector.ticketUserMessagesAnalysis(ticket,guild,channel)
if (analysis && !generalConfig.data.system.allowCloseBeforeMessage && analysis.totalMessages < 1){
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build("button",{guild,channel,user,layout:"simple",error:lang.getTranslation("errors.descriptions.closeBeforeMessage"),customTitle:lang.getTranslation("errors.titles.noPermissions")}))
@@ -224,8 +205,16 @@ export const registerVerifyBars = async () => {
//DELETE TICKET CLOSE MESSAGE
opendiscord.verifybars.add(new api.ODVerifyBar("opendiscord:delete-ticket-close-message",opendiscord.builders.messages.getSafe("opendiscord:verifybar-close-message"),!generalConfig.data.system.disableVerifyBars))
opendiscord.verifybars.get("opendiscord:delete-ticket-close-message").success.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.delete
+ new api.ODWorker("opendiscord:delete-ticket",0,async (instance,params,source,cancel) => {
+ const {user,member,channel,guild} = instance
+
+ //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("button",{guild,channel,user,permissions:["support"]}))
+ return cancel()
+ }
//don't allow deleteWithoutTranscript to non-global-admins when enabled
if (params.data == "no-transcript" && generalConfig.data.system.adminOnlyDeleteWithoutTranscript){
@@ -235,54 +224,27 @@ export const registerVerifyBars = async () => {
}
}
- 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,source,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("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()
}
+
//return when not allowed because of missing messages
- if (!generalConfig.data.system.allowCloseBeforeMessage || !generalConfig.data.system.allowCloseBeforeAdminMessage){
+ if (!permsResult.isAdmin && (!generalConfig.data.system.allowCloseBeforeMessage || !generalConfig.data.system.allowCloseBeforeAdminMessage)){
const analysis = await opendiscord.transcripts.collector.ticketUserMessagesAnalysis(ticket,guild,channel)
if (analysis && !generalConfig.data.system.allowCloseBeforeMessage && analysis.totalMessages < 1){
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build("button",{guild,channel,user,layout:"simple",error:lang.getTranslation("errors.descriptions.closeBeforeMessage"),customTitle:lang.getTranslation("errors.titles.noPermissions")}))
@@ -333,8 +295,16 @@ export const registerVerifyBars = async () => {
//DELETE TICKET REOPEN MESSAGE
opendiscord.verifybars.add(new api.ODVerifyBar("opendiscord:delete-ticket-reopen-message",opendiscord.builders.messages.getSafe("opendiscord:verifybar-reopen-message"),!generalConfig.data.system.disableVerifyBars))
opendiscord.verifybars.get("opendiscord:delete-ticket-reopen-message").success.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.delete
+ new api.ODWorker("opendiscord:delete-ticket",0,async (instance,params,source,cancel) => {
+ const {user,member,channel,guild} = instance
+
+ //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("button",{guild,channel,user,permissions:["support"]}))
+ return cancel()
+ }
//don't allow deleteWithoutTranscript to non-global-admins when enabled
if (params.data == "no-transcript" && generalConfig.data.system.adminOnlyDeleteWithoutTranscript){
@@ -344,54 +314,26 @@ export const registerVerifyBars = async () => {
}
}
- 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,source,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("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()
}
//return when not allowed because of missing messages
- if (!generalConfig.data.system.allowCloseBeforeMessage || !generalConfig.data.system.allowCloseBeforeAdminMessage){
+ if (!permsResult.isAdmin && (!generalConfig.data.system.allowCloseBeforeMessage || !generalConfig.data.system.allowCloseBeforeAdminMessage)){
const analysis = await opendiscord.transcripts.collector.ticketUserMessagesAnalysis(ticket,guild,channel)
if (analysis && !generalConfig.data.system.allowCloseBeforeMessage && analysis.totalMessages < 1){
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build("button",{guild,channel,user,layout:"simple",error:lang.getTranslation("errors.descriptions.closeBeforeMessage"),customTitle:lang.getTranslation("errors.titles.noPermissions")}))
@@ -442,8 +384,16 @@ export const registerVerifyBars = async () => {
//DELETE TICKET AUTOCLOSE MESSAGE
opendiscord.verifybars.add(new api.ODVerifyBar("opendiscord:delete-ticket-autoclose-message",opendiscord.builders.messages.getSafe("opendiscord:verifybar-autoclose-message"),!generalConfig.data.system.disableVerifyBars))
opendiscord.verifybars.get("opendiscord:delete-ticket-autoclose-message").success.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.delete
+ new api.ODWorker("opendiscord:delete-ticket",0,async (instance,params,source,cancel) => {
+ const {user,member,channel,guild} = instance
+
+ //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("button",{guild,channel,user,permissions:["support"]}))
+ return cancel()
+ }
//don't allow deleteWithoutTranscript to non-global-admins when enabled
if (params.data == "no-transcript" && generalConfig.data.system.adminOnlyDeleteWithoutTranscript){
@@ -453,54 +403,26 @@ export const registerVerifyBars = async () => {
}
}
- 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,source,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("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()
}
//return when not allowed because of missing messages
- if (!generalConfig.data.system.allowCloseBeforeMessage || !generalConfig.data.system.allowCloseBeforeAdminMessage){
+ if (!permsResult.isAdmin && (!generalConfig.data.system.allowCloseBeforeMessage || !generalConfig.data.system.allowCloseBeforeAdminMessage)){
const analysis = await opendiscord.transcripts.collector.ticketUserMessagesAnalysis(ticket,guild,channel)
if (analysis && !generalConfig.data.system.allowCloseBeforeMessage && analysis.totalMessages < 1){
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build("button",{guild,channel,user,layout:"simple",error:lang.getTranslation("errors.descriptions.closeBeforeMessage"),customTitle:lang.getTranslation("errors.titles.noPermissions")}))
diff --git a/src/commands/add.ts b/src/commands/add.ts
index ab68104..43d4b89 100644
--- a/src/commands/add.ts
+++ b/src/commands/add.ts
@@ -10,50 +10,30 @@ export const registerCommandResponders = async () => {
//ADD COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:add",generalConfig.data.prefix,"add"))
opendiscord.responders.commands.get("opendiscord:add").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.add
-
- 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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:add",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ 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(source,{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}))
diff --git a/src/commands/autoclose.ts b/src/commands/autoclose.ts
index 6200479..bdf5a8b 100644
--- a/src/commands/autoclose.ts
+++ b/src/commands/autoclose.ts
@@ -10,62 +10,43 @@ export const registerCommandResponders = async () => {
//AUTOCLOSE COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:autoclose",generalConfig.data.prefix,/^autoclose/))
opendiscord.responders.commands.get("opendiscord:autoclose").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.autoclose
-
- 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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:autoclose",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ 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(source,{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(source,{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 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()
}
+ //subcommands
const scope = instance.options.getSubCommand()
if (!scope || (scope != "disable" && scope != "enable")) return
diff --git a/src/commands/autodelete.ts b/src/commands/autodelete.ts
index acf4941..f912668 100644
--- a/src/commands/autodelete.ts
+++ b/src/commands/autodelete.ts
@@ -10,57 +10,38 @@ export const registerCommandResponders = async () => {
//AUTODELETE COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:autodelete",generalConfig.data.prefix,/^autodelete/))
opendiscord.responders.commands.get("opendiscord:autodelete").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.autodelete
-
- 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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:autodelete",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ 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(source,{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(source,{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()
}
+ //subcommands
const scope = instance.options.getSubCommand()
if (!scope || (scope != "disable" && scope != "enable")) return
diff --git a/src/commands/blacklist.ts b/src/commands/blacklist.ts
index b33c3fe..16e8548 100644
--- a/src/commands/blacklist.ts
+++ b/src/commands/blacklist.ts
@@ -10,49 +10,26 @@ export const registerCommandResponders = async () => {
//BLACKLIST COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:blacklist",generalConfig.data.prefix,/^blacklist/))
opendiscord.responders.commands.get("opendiscord:blacklist").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.blacklist
-
- 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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:blacklist",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ const {guild,channel,user,member} = instance
+
+ //check permissions
+ const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.blacklist,"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(source,{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(source,{channel:instance.channel,user:instance.user}))
return cancel()
}
+
+ //subcommands
const scope = instance.options.getSubCommand()
if (!scope || (scope != "add" && scope != "get" && scope != "remove" && scope != "view")) return
-
if (scope == "view"){
await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:blacklist-view").build(source,{guild,channel,user}))
diff --git a/src/commands/claim.ts b/src/commands/claim.ts
index d47aedb..72c2b6c 100644
--- a/src/commands/claim.ts
+++ b/src/commands/claim.ts
@@ -10,55 +10,36 @@ export const registerCommandResponders = async () => {
//CLAIM COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:claim",generalConfig.data.prefix,"claim"))
opendiscord.responders.commands.get("opendiscord:claim").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.claim
-
- 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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:claim",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ const {guild,channel,user,member} = instance
+
+ //check permissions
+ const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.claim,"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(source,{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 already claimed
if (ticket.get("opendiscord:claimed").value){
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build("button",{guild,channel,user,error:opendiscord.languages.getTranslation("errors.actionInvalid.claim"),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}))
diff --git a/src/commands/clear.ts b/src/commands/clear.ts
index 3eb7b66..1de6e25 100644
--- a/src/commands/clear.ts
+++ b/src/commands/clear.ts
@@ -10,42 +10,18 @@ export const registerCommandResponders = async () => {
//CLEAR COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:clear",generalConfig.data.prefix,"clear"))
opendiscord.responders.commands.get("opendiscord:clear").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.clear
-
- 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"){
- //only allow global admins (ticket admins aren't allowed to clear tickets)
- if (!opendiscord.permissions.hasPermissions("support",await opendiscord.permissions.getPermissions(instance.user,instance.channel,instance.guild,{allowChannelUserScope:false,allowChannelRoleScope:false}))){
- //no permissions
- instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:clear",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ const {user,member,channel,guild} = instance
+
+ //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(source,{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()
diff --git a/src/commands/close.ts b/src/commands/close.ts
index 8aac86a..8f2c01b 100644
--- a/src/commands/close.ts
+++ b/src/commands/close.ts
@@ -11,62 +11,44 @@ export const registerCommandResponders = async () => {
//CLOSE COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:close",generalConfig.data.prefix,"close"))
opendiscord.responders.commands.get("opendiscord:close").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.close
-
- 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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:close",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ const {user,member,channel,guild} = instance
+
+ //check permissions
+ const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.close,"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(source,{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 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()
}
+
//return when not allowed because of missing messages
- if (!generalConfig.data.system.allowCloseBeforeMessage || !generalConfig.data.system.allowCloseBeforeAdminMessage){
+ if (!permsResult.isAdmin && (!generalConfig.data.system.allowCloseBeforeMessage || !generalConfig.data.system.allowCloseBeforeAdminMessage)){
const analysis = await opendiscord.transcripts.collector.ticketUserMessagesAnalysis(ticket,guild,channel)
if (analysis && !generalConfig.data.system.allowCloseBeforeMessage && analysis.totalMessages < 1){
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build("button",{guild,channel,user,layout:"simple",error:lang.getTranslation("errors.descriptions.closeBeforeMessage"),customTitle:lang.getTranslation("errors.titles.noPermissions")}))
@@ -77,11 +59,10 @@ export const registerCommandResponders = async () => {
return cancel()
}
}
-
- const reason = instance.options.getString("reason",false)
-
+
//start closing ticket
await instance.defer(false)
+ const reason = instance.options.getString("reason",false)
await opendiscord.actions.get("opendiscord:close-ticket").run(source,{guild,channel,user,ticket,reason,sendMessage:false})
await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:close-message").build(source,{guild,channel,user,ticket,reason}))
}),
diff --git a/src/commands/delete.ts b/src/commands/delete.ts
index 24ea2ec..ebe4c32 100644
--- a/src/commands/delete.ts
+++ b/src/commands/delete.ts
@@ -11,57 +11,38 @@ export const registerCommandResponders = async () => {
//DELETE COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:delete",generalConfig.data.prefix,"delete"))
opendiscord.responders.commands.get("opendiscord:delete").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:delete",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ const {user,member,channel,guild} = instance
+
+ //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(source,{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()
}
+
//return when not allowed because of missing messages
- if (!generalConfig.data.system.allowCloseBeforeMessage || !generalConfig.data.system.allowCloseBeforeAdminMessage){
+ if (!permsResult.isAdmin && (!generalConfig.data.system.allowCloseBeforeMessage || !generalConfig.data.system.allowCloseBeforeAdminMessage)){
const analysis = await opendiscord.transcripts.collector.ticketUserMessagesAnalysis(ticket,guild,channel)
if (analysis && !generalConfig.data.system.allowCloseBeforeMessage && analysis.totalMessages < 1){
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build("button",{guild,channel,user,layout:"simple",error:lang.getTranslation("errors.descriptions.closeBeforeMessage"),customTitle:lang.getTranslation("errors.titles.noPermissions")}))
diff --git a/src/commands/help.ts b/src/commands/help.ts
index 3679785..a8eb799 100644
--- a/src/commands/help.ts
+++ b/src/commands/help.ts
@@ -10,47 +10,21 @@ export const registerCommandResponders = async () => {
//HELP COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:help",generalConfig.data.prefix,"help"))
opendiscord.responders.commands.get("opendiscord:help").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.help
-
- 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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:help",0,async (instance,params,source,cancel) => {
- const preferSlashOverText = generalConfig.data.system.preferSlashOverText
+ 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(source,{guild,channel,user,permissions:["support"]}))
+ return cancel()
+ }
+
+ //calculate slash/text mode for help menu
let mode: "slash"|"text"
- if (generalConfig.data.slashCommands && generalConfig.data.textCommands){
- mode = (preferSlashOverText) ? "slash" : "text"
-
- }else if (!generalConfig.data.slashCommands) mode = "text"
+ if (generalConfig.data.slashCommands && generalConfig.data.textCommands) mode = (generalConfig.data.system.preferSlashOverText) ? "slash" : "text"
+ else if (!generalConfig.data.slashCommands) mode = "text"
else mode = "slash"
await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:help-menu").build(source,{mode,page:0}))
diff --git a/src/commands/move.ts b/src/commands/move.ts
index 3a63498..93ad8ed 100644
--- a/src/commands/move.ts
+++ b/src/commands/move.ts
@@ -10,45 +10,24 @@ export const registerCommandResponders = async () => {
//MOVE COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:move",generalConfig.data.prefix,"move"))
opendiscord.responders.commands.get("opendiscord:move").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.move
-
- 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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:move",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ 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(source,{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}))
diff --git a/src/commands/panel.ts b/src/commands/panel.ts
index 22218db..cb84407 100644
--- a/src/commands/panel.ts
+++ b/src/commands/panel.ts
@@ -10,56 +10,30 @@ export const registerCommandResponders = async () => {
//PANEL COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:panel",generalConfig.data.prefix,/^panel/))
opendiscord.responders.commands.get("opendiscord:panel").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.panel
-
- //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()
- }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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:panel",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ 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(source,{guild,channel,user,permissions:["support"]}))
+ return cancel()
+ }
+
+ //check is in guild/server
if (!guild || instance.channel.type == discord.ChannelType.GroupDM){
- //error
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build(source,{channel:instance.channel,user:instance.user}))
return cancel()
}
+ //get panel data
const id = instance.options.getString("id",true)
const panel = opendiscord.panels.get(id)
-
if (!panel){
- //invalid panel
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-panel-unknown").build(source,{guild,channel,user}))
return cancel()
- }
+ }
await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:panel-ready").build(source,{guild,channel,user,panel}))
const panelMessage = await instance.channel.send((await opendiscord.builders.messages.getSafe("opendiscord:panel").build(source,{guild,channel,user,panel})).message)
diff --git a/src/commands/pin.ts b/src/commands/pin.ts
index e58858f..f1a8499 100644
--- a/src/commands/pin.ts
+++ b/src/commands/pin.ts
@@ -44,21 +44,35 @@ export const registerCommandResponders = async () => {
}
}),
new api.ODWorker("opendiscord:pin",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ const {guild,channel,user,member} = instance
+
+ //check permissions
+ const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.pin,"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(source,{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 already pinned
if (ticket.get("opendiscord:pinned").value){
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build("button",{guild,channel,user,error:opendiscord.languages.getTranslation("errors.actionInvalid.pin"),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}))
diff --git a/src/commands/priority.ts b/src/commands/priority.ts
index cbf6744..39812ca 100644
--- a/src/commands/priority.ts
+++ b/src/commands/priority.ts
@@ -10,56 +10,37 @@ export const registerCommandResponders = async () => {
//PRIORITY COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:priority",generalConfig.data.prefix,"priority"))
opendiscord.responders.commands.get("opendiscord:priority").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.priority
-
- 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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:priority",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ 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(source,{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()
}
+ //subcommands
const scope = instance.options.getSubCommand()
if (!scope || (scope != "set" && scope != "get")) return
diff --git a/src/commands/remove.ts b/src/commands/remove.ts
index 6e71533..c6ec472 100644
--- a/src/commands/remove.ts
+++ b/src/commands/remove.ts
@@ -10,50 +10,30 @@ export const registerCommandResponders = async () => {
//REMOVE COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:remove",generalConfig.data.prefix,"remove"))
opendiscord.responders.commands.get("opendiscord:remove").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.remove
-
- 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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:remove",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ 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(source,{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}))
diff --git a/src/commands/rename.ts b/src/commands/rename.ts
index f84740d..7bbee26 100644
--- a/src/commands/rename.ts
+++ b/src/commands/rename.ts
@@ -10,50 +10,30 @@ export const registerCommandResponders = async () => {
//RENAME COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:rename",generalConfig.data.prefix,"rename"))
opendiscord.responders.commands.get("opendiscord:rename").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.rename
-
- 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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:rename",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ 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(source,{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}))
diff --git a/src/commands/reopen.ts b/src/commands/reopen.ts
index f398aec..fb86a30 100644
--- a/src/commands/reopen.ts
+++ b/src/commands/reopen.ts
@@ -10,55 +10,36 @@ export const registerCommandResponders = async () => {
//REOPEN COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:reopen",generalConfig.data.prefix,"reopen"))
opendiscord.responders.commands.get("opendiscord:reopen").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.reopen
-
- 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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:reopen",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ const {guild,channel,user,member} = instance
+
+ //check permissions
+ const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.reopen,"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(source,{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 not 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.reopen"),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}))
diff --git a/src/commands/role.ts b/src/commands/role.ts
index 0081df6..e9de633 100644
--- a/src/commands/role.ts
+++ b/src/commands/role.ts
@@ -12,13 +12,14 @@ export const registerButtonResponders = async () => {
opendiscord.responders.buttons.get("opendiscord:role-option").workers.add(
new api.ODWorker("opendiscord:role-option",0,async (instance,params,source,cancel) => {
const {guild,channel,user} = instance
+
+ //check is in guild/server
if (!guild){
- //error
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-not-in-guild").build(source,{channel:instance.channel,user:instance.user}))
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.ODRoleOption)){
diff --git a/src/commands/stats.ts b/src/commands/stats.ts
index c308c3f..46be1fb 100644
--- a/src/commands/stats.ts
+++ b/src/commands/stats.ts
@@ -57,12 +57,36 @@ export const registerCommandResponders = async () => {
}
}),
new api.ODWorker("opendiscord:stats",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ 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))){
+ //reset --> owner/developer role is required
+ instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions").build(source,{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(source,{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(source,{channel:instance.channel,user:instance.user}))
return cancel()
}
+
+ //subcommands
const scope = instance.options.getSubCommand()
if (!scope || (scope != "global" && scope != "ticket" && scope != "user" && scope != "reset")) return
diff --git a/src/commands/ticket.ts b/src/commands/ticket.ts
index 45fcddb..65159fb 100644
--- a/src/commands/ticket.ts
+++ b/src/commands/ticket.ts
@@ -7,52 +7,46 @@ import * as discord from "discord.js"
const generalConfig = opendiscord.configs.get("opendiscord:general")
const lang = opendiscord.languages
+async function checkTicketCreationPerms(instance:api.ODButtonResponderInstance|api.ODDropdownResponderInstance|api.ODModalResponderInstance|api.ODCommandResponderInstance,source:api.ODActionManagerIds_Default["opendiscord:create-ticket-permissions"]["source"],guild:discord.Guild,user:discord.User,option:api.ODTicketOption){
+ //check ticket permissions
+ const permsRes = await opendiscord.actions.get("opendiscord:create-ticket-permissions").run(source,{guild,user,option})
+ if (!permsRes.valid && instance.channel){
+ //error
+ const newSource = (source === "slash" || source === "text") ? source : "other"
+ if (permsRes.reason == "blacklist") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-blacklisted").build(newSource,{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(newSource,{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(newSource,{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(newSource,{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(newSource,{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(newSource,{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(newSource,{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(newSource,{guild:instance.guild,channel:instance.channel,user:instance.user,error:"Unknown invalid_permission reason => calculation failed #1",layout:"advanced"}))
+ return false
+ }else return true
+}
+
export const registerCommandResponders = async () => {
//TICKET COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:ticket",generalConfig.data.prefix,/^ticket/))
opendiscord.responders.commands.get("opendiscord:ticket").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.ticket
-
- 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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:ticket",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ 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(source,{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(source,{channel:instance.channel,user:instance.user}))
return cancel()
}
- //get option
+ //get option data
const optionId = instance.options.getString("id",true)
const option = opendiscord.options.get(optionId)
if (!option || !(option instanceof api.ODTicketOption)){
@@ -62,19 +56,7 @@ export const registerCommandResponders = async () => {
}
//check ticket permissions
- const res = await opendiscord.actions.get("opendiscord:create-ticket-permissions").run(source,{guild,user,option})
- if (!res.valid){
- //error
- if (res.reason == "blacklist") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-blacklisted").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user}))
- else if (res.reason == "cooldown") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-cooldown").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user,until:res.cooldownUntil}))
- else if (res.reason == "global-limit") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"global"}))
- else if (res.reason == "global-user-limit") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"global-user"}))
- else if (res.reason == "option-limit") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"option"}))
- else if (res.reason == "option-user-limit") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"option-user"}))
- else if (res.reason == "custom") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user,layout:"simple",error:res.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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,error:"Unknown invalid_permission reason => calculation failed #1",layout:"advanced"}))
- return cancel()
- }
+ if (!(await checkTicketCreationPerms(instance,source,guild,user,option))) return cancel()
//start ticket creation
if (option.exists("opendiscord:questions") && option.get("opendiscord:questions").value.length > 0){
@@ -125,19 +107,7 @@ export const registerButtonResponders = async () => {
}
//check ticket permissions
- const res = await opendiscord.actions.get("opendiscord:create-ticket-permissions").run("panel-button",{guild,user,option})
- if (!res.valid){
- //error
- if (res.reason == "blacklist") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-blacklisted").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user}))
- else if (res.reason == "cooldown") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-cooldown").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user,until:res.cooldownUntil}))
- else if (res.reason == "global-limit") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"global"}))
- else if (res.reason == "global-user-limit") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"global-user"}))
- else if (res.reason == "option-limit") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"option"}))
- else if (res.reason == "option-user-limit") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"option-user"}))
- else if (res.reason == "custom") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user,layout:"simple",error:res.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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,error:"Unknown invalid_permission reason => calculation failed #1",layout:"advanced"}))
- return cancel()
- }
+ if (!(await checkTicketCreationPerms(instance,"panel-button",guild,user,option))) return cancel()
//start ticket creation
if (option.exists("opendiscord:questions") && option.get("opendiscord:questions").value.length > 0){
@@ -181,19 +151,7 @@ export const registerDropdownResponders = async () => {
}
//check ticket permissions
- const res = await opendiscord.actions.get("opendiscord:create-ticket-permissions").run("panel-dropdown",{guild,user,option})
- if (!res.valid){
- //error
- if (res.reason == "blacklist") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-blacklisted").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user}))
- else if (res.reason == "cooldown") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-cooldown").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user,until:res.cooldownUntil}))
- else if (res.reason == "global-limit") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"global"}))
- else if (res.reason == "global-user-limit") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"global-user"}))
- else if (res.reason == "option-limit") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"option"}))
- else if (res.reason == "option-user-limit") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-no-permissions-limits").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user,limit:"option-user"}))
- else if (res.reason == "custom") instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build(source,{guild:instance.guild,channel:instance.channel,user:instance.user,layout:"simple",error:res.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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,error:"Unknown invalid_permission reason => calculation failed #1",layout:"advanced"}))
- return cancel()
- }
+ if (!(await checkTicketCreationPerms(instance,"panel-dropdown",guild,user,option))) return cancel()
//start ticket creation
if (option.exists("opendiscord:questions") && option.get("opendiscord:questions").value.length > 0){
@@ -229,6 +187,7 @@ export const registerModalResponders = async () => {
opendiscord.responders.modals.get("opendiscord:ticket-questions").workers.add([
new api.ODWorker("opendiscord:ticket-questions",0,async (instance,params,source,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
@@ -270,8 +229,6 @@ export const registerModalResponders = async () => {
})
//create ticket
- await instance.defer((generalConfig.data.system.replyOnTicketCreation) ? "reply" : "update",true)
-
const res = await opendiscord.actions.get("opendiscord:create-ticket").run(originalSource,{guild,user,answers,option})
if (!res.channel || !res.ticket){
//error
diff --git a/src/commands/topic.ts b/src/commands/topic.ts
index f8423c7..79992c2 100644
--- a/src/commands/topic.ts
+++ b/src/commands/topic.ts
@@ -10,56 +10,37 @@ export const registerCommandResponders = async () => {
//TOPIC COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:topic",generalConfig.data.prefix,"topic"))
opendiscord.responders.commands.get("opendiscord:topic").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.topic
-
- 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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:topic",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ 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(source,{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()
}
+ //subcommands
const scope = instance.options.getSubCommand()
if (!scope || (scope != "set")) return
diff --git a/src/commands/transfer.ts b/src/commands/transfer.ts
index 18c8c8b..5aa2298 100644
--- a/src/commands/transfer.ts
+++ b/src/commands/transfer.ts
@@ -10,50 +10,30 @@ export const registerCommandResponders = async () => {
//TRANSFER COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:transfer",generalConfig.data.prefix,"transfer"))
opendiscord.responders.commands.get("opendiscord:transfer").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.transfer
-
- 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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:transfer",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ 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(source,{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}))
diff --git a/src/commands/unclaim.ts b/src/commands/unclaim.ts
index 0cdec44..73cb608 100644
--- a/src/commands/unclaim.ts
+++ b/src/commands/unclaim.ts
@@ -10,55 +10,36 @@ export const registerCommandResponders = async () => {
//UNCLAIM COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:unclaim",generalConfig.data.prefix,"unclaim"))
opendiscord.responders.commands.get("opendiscord:unclaim").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.unclaim
-
- 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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:unclaim",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ const {user,member,channel,guild} = instance
+
+ //check permissions
+ const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.unclaim,"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(source,{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 not claimed
if (!ticket.get("opendiscord:claimed").value){
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build("button",{guild,channel,user,error:opendiscord.languages.getTranslation("errors.actionInvalid.unclaim"),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}))
diff --git a/src/commands/unpin.ts b/src/commands/unpin.ts
index 06095ca..30a9579 100644
--- a/src/commands/unpin.ts
+++ b/src/commands/unpin.ts
@@ -10,55 +10,36 @@ export const registerCommandResponders = async () => {
//UNPIN COMMAND RESPONDER
opendiscord.responders.commands.add(new api.ODCommandResponder("opendiscord:unpin",generalConfig.data.prefix,"unpin"))
opendiscord.responders.commands.get("opendiscord:unpin").workers.add([
- new api.ODWorker("opendiscord:permissions",1,async (instance,params,source,cancel) => {
- const permissionMode = generalConfig.data.system.permissions.unpin
-
- 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(source,{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(source,{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(source,{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(source,{guild:instance.guild,channel:instance.channel,user:instance.user,permissions:[]}))
- return cancel()
- }else return
- }
- }),
new api.ODWorker("opendiscord:unpin",0,async (instance,params,source,cancel) => {
- const {guild,channel,user} = instance
+ const {user,member,channel,guild} = instance
+
+ //check permissions
+ const permsResult = await opendiscord.permissions.checkCommandPerms(generalConfig.data.system.permissions.unpin,"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(source,{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 not pinned yet
if (!ticket.get("opendiscord:pinned").value){
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build("button",{guild,channel,user,error:opendiscord.languages.getTranslation("errors.actionInvalid.unpin"),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}))
diff --git a/src/core/api/defaults/permission.ts b/src/core/api/defaults/permission.ts
index 23b4b02..2a67d3e 100644
--- a/src/core/api/defaults/permission.ts
+++ b/src/core/api/defaults/permission.ts
@@ -3,6 +3,7 @@
///////////////////////////////////////
import { ODDebugger } from "../modules/console"
import { ODPermissionManager } from "../modules/permission"
+import { ODClientManager_Default } from "./client"
/**## ODPermissionManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODPermissionManager class.
@@ -11,8 +12,8 @@ import { ODPermissionManager } from "../modules/permission"
* This default class is made for the global variable `opendiscord.permissions`!
*/
export class ODPermissionManager_Default extends ODPermissionManager {
- constructor(debug:ODDebugger){
- super(debug,true)
+ constructor(debug:ODDebugger,client:ODClientManager_Default){
+ super(debug,client,true)
}
}
diff --git a/src/core/api/main.ts b/src/core/api/main.ts
index 2849516..8cc2400 100644
--- a/src/core/api/main.ts
+++ b/src/core/api/main.ts
@@ -133,7 +133,7 @@ export class ODMain {
constructor(){
this.versions = new ODVersionManager_Default()
- this.versions.add(ODVersion.fromString("opendiscord:version","v4.1.1"))
+ this.versions.add(ODVersion.fromString("opendiscord:version","v4.1.2"))
this.versions.add(ODVersion.fromString("opendiscord:api","v1.0.0"))
this.versions.add(ODVersion.fromString("opendiscord:transcripts","v2.1.0"))
this.versions.add(ODVersion.fromString("opendiscord:livestatus","v2.0.0"))
@@ -157,7 +157,7 @@ export class ODMain {
this.responders = new ODResponderManager_Default(this.debug,this.client)
this.actions = new ODActionManager_Default(this.debug)
this.verifybars = new ODVerifyBarManager_Default(this.debug)
- this.permissions = new ODPermissionManager_Default(this.debug)
+ this.permissions = new ODPermissionManager_Default(this.debug,this.client)
this.cooldowns = new ODCooldownManager_Default(this.debug)
this.helpmenu = new ODHelpMenuManager_Default(this.debug)
this.stats = new ODStatsManager_Default(this.debug)
diff --git a/src/core/api/modules/base.ts b/src/core/api/modules/base.ts
index 4275a7e..69e91e3 100644
--- a/src/core/api/modules/base.ts
+++ b/src/core/api/modules/base.ts
@@ -560,8 +560,8 @@ export class ODHTTPGetRequest {
this.throwOnError = throwOnError
const newConfig = config ?? {}
newConfig.method = "GET"
- if (newConfig.headers) Object.assign(newConfig.headers,{"User-Agent":"OpenDiscordBots-OpenTicket/4.1.1"})
- else newConfig.headers = {"User-Agent":"OpenDiscordBots-OpenTicket/4.1.1"}
+ if (newConfig.headers) Object.assign(newConfig.headers,{"User-Agent":"OpenDiscordBots-OpenTicket/4.1.2"})
+ else newConfig.headers = {"User-Agent":"OpenDiscordBots-OpenTicket/4.1.2"}
this.config = newConfig
}
@@ -615,8 +615,8 @@ export class ODHTTPPostRequest {
this.throwOnError = throwOnError
const newConfig = config ?? {}
newConfig.method = "POST"
- if (newConfig.headers) Object.assign(newConfig.headers,{"User-Agent":"OpenDiscordBots-OpenTicket/4.1.1"})
- else newConfig.headers = {"User-Agent":"OpenDiscordBots-OpenTicket/4.1.1"}
+ if (newConfig.headers) Object.assign(newConfig.headers,{"User-Agent":"OpenDiscordBots-OpenTicket/4.1.2"})
+ else newConfig.headers = {"User-Agent":"OpenDiscordBots-OpenTicket/4.1.2"}
this.config = newConfig
}
diff --git a/src/core/api/modules/permission.ts b/src/core/api/modules/permission.ts
index fbfd12b..4b4f883 100644
--- a/src/core/api/modules/permission.ts
+++ b/src/core/api/modules/permission.ts
@@ -4,6 +4,7 @@
import { ODId, ODValidId, ODManager, ODSystemError, ODManagerData } from "./base"
import * as discord from "discord.js"
import { ODDebugger } from "./console"
+import { ODClientManager } from "./client"
/**## ODPermissionType `type`
* All available permission types/levels. Can be used in the `ODPermission` class.
@@ -100,6 +101,20 @@ export interface ODPermissionSettings {
*/
export type ODPermissionCalculationCallback = (user:discord.User, channel?:discord.Channel|null, guild?:discord.Guild|null, settings?:ODPermissionSettings|null) => Promise
+/**## ODPermissionCommandResult `type`
+ * The result of calculating permissions for a command.
+ */
+export type ODPermissionCommandResult = {
+ /**Returns `true` when the user has valid permissions. */
+ hasPerms:false,
+ reason:"no-perms"|"disabled"|"not-in-server"
+}|{
+ /**Returns `true` when the user has valid permissions. */
+ hasPerms:true,
+ /**Is the user a server admin or a normal member? This does not decide if the user has permissions or not. */
+ isAdmin:boolean
+}
+
/**## ODPermissionManager `class`
* This is an Open Ticket permission manager.
*
@@ -109,8 +124,12 @@ export type ODPermissionCalculationCallback = (user:discord.User, channel?:disco
* Add new permissions using the `ODPermission` class in your plugin!
*/
export class ODPermissionManager extends ODManager {
+ /**Alias for Open Ticket debugger. */
+ #debug: ODDebugger
/**The function for calculating permissions in this manager. */
#calculation: ODPermissionCalculationCallback|null
+ /**An alias to the Open Discord client manager. */
+ #client: ODClientManager
/**The result which is returned when no other permissions match. (`member` by default) */
defaultResult: ODPermissionResult = {
level:ODPermissionLevel["member"],
@@ -119,9 +138,11 @@ export class ODPermissionManager extends ODManager {
source:null
}
- constructor(debug:ODDebugger, useDefaultCalculation?:boolean){
+ constructor(debug:ODDebugger, client:ODClientManager, useDefaultCalculation?:boolean){
super(debug,"permission")
+ this.#debug = debug
this.#calculation = useDefaultCalculation ? this.#defaultCalculation : null
+ this.#client = client
}
/**Edit the permission calculation function in this manager. */
@@ -193,7 +214,7 @@ export class ODPermissionManager extends ODManager {
//check for global role permissions
if (allowGlobalRoleScope){
if (guild){
- const member = await guild.members.fetch(user.id)
+ const member = await this.#client.fetchGuildMember(guild,user.id)
if (member){
const memberRoles = member.roles.cache.map((role) => role.id)
const roles = this.getFiltered((permission) => (!idRegex || (idRegex && idRegex.test(permission.id.value))) && permission.scope == "global-role" && (permission.value instanceof discord.Role) && memberRoles.includes(permission.value.id) && permission.value.guild.id == guild.id)
@@ -256,7 +277,7 @@ export class ODPermissionManager extends ODManager {
//check for channel role permissions
if (allowChannelRoleScope){
- const member = await guild.members.fetch(user.id)
+ const member = await this.#client.fetchGuildMember(guild,user.id)
if (member){
const memberRoles = member.roles.cache.map((role) => role.id)
const roles = this.getFiltered((permission) => (!idRegex || (idRegex && idRegex.test(permission.id.value))) && permission.scope == "channel-role" && permission.channel && (permission.channel.id == channel.id) && (permission.value instanceof discord.Role) && memberRoles.includes(permission.value.id) && permission.value.guild.id == guild.id)
@@ -286,4 +307,34 @@ export class ODPermissionManager extends ODManager {
//spread result to prevent accidental modification because of referencing
return {...this.defaultResult}
}
+
+ /**Check the permissions for a certain command of the bot. */
+ async checkCommandPerms(permissionMode:string,requiredLevel:ODPermissionType,user:discord.User,member?:discord.GuildMember|null,channel?:discord.Channel|null,guild?:discord.Guild|null,settings?:ODPermissionSettings): Promise {
+ if (permissionMode === "none"){
+ return {hasPerms:false,reason:"disabled"}
+
+ }else if (permissionMode === "everyone"){
+ const isAdmin = this.hasPermissions(requiredLevel,await this.getPermissions(user,channel,guild,settings))
+ return {hasPerms:true,isAdmin}
+
+ }else if (permissionMode === "admin"){
+ const isAdmin = this.hasPermissions(requiredLevel,await this.getPermissions(user,channel,guild,settings))
+ if (!isAdmin) return {hasPerms:false,reason:"no-perms"}
+ else return {hasPerms:true,isAdmin}
+ }else{
+ if (!guild || !member){
+ this.#debug.debug("ODPermissionManager.checkCommandPerms(): Permission Error, Not in server! (#1)")
+ return {hasPerms:false,reason:"not-in-server"}
+ }
+ const role = await this.#client.fetchGuildRole(guild,permissionMode)
+ if (!role){
+ this.#debug.debug("ODPermissionManager.checkCommandPerms(): Permission Error, Not in server! (#2)")
+ return {hasPerms:false,reason:"not-in-server"}
+ }
+ if (!role.members.has(member.id)) return {hasPerms:false,reason:"no-perms"}
+
+ const isAdmin = this.hasPermissions(requiredLevel,await this.getPermissions(user,channel,guild,settings))
+ return {hasPerms:true,isAdmin}
+ }
+ }
}
\ No newline at end of file
diff --git a/src/core/api/modules/responder.ts b/src/core/api/modules/responder.ts
index dbe78ea..3398ab2 100644
--- a/src/core/api/modules/responder.ts
+++ b/src/core/api/modules/responder.ts
@@ -426,7 +426,8 @@ export class ODCommandResponderInstance {
/**Show a modal as reply to this command. */
async modal(modal:ODModalBuildResult){
if (this.type != "interaction" || !(this.interaction instanceof discord.ChatInputCommandInteraction)) return false
- this.interaction.showModal(modal.modal)
+ if (this.interaction.deferred || this.interaction.replied) return false
+ await this.interaction.showModal(modal.modal)
this.didReply = true
return true
}
@@ -601,7 +602,8 @@ export class ODButtonResponderInstance {
}
/**Show a modal as reply to this button. */
async modal(modal:ODModalBuildResult){
- this.interaction.showModal(modal.modal)
+ if (this.interaction.deferred || this.interaction.replied) return false
+ await this.interaction.showModal(modal.modal)
this.didReply = true
return true
}
@@ -889,7 +891,8 @@ export class ODDropdownResponderInstance {
}
/**Show a modal as reply to this dropdown. */
async modal(modal:ODModalBuildResult){
- this.interaction.showModal(modal.modal)
+ if (this.interaction.deferred || this.interaction.replied) return false
+ await this.interaction.showModal(modal.modal)
this.didReply = true
return true
}
@@ -1261,7 +1264,8 @@ export class ODContextMenuResponderInstance {
}
/**Show a modal as reply to this context menu. */
async modal(modal:ODModalBuildResult){
- this.interaction.showModal(modal.modal)
+ if (this.interaction.deferred || this.interaction.replied) return false
+ await this.interaction.showModal(modal.modal)
this.didReply = true
return true
}
@@ -1389,7 +1393,7 @@ export class ODAutocompleteResponderInstance {
else return raw
})
- const filteredChoices = newChoices.filter((choice) => choice.name.startsWith(this.target.value) || choice.value.toString().startsWith(this.target.value))
+ const filteredChoices = newChoices.filter((choice) => choice.name.startsWith(this.target.value) || choice.value.toString().startsWith(this.target.value)).slice(0,25)
return await this.autocomplete(filteredChoices)
}
}
diff --git a/src/core/api/openticket/option.ts b/src/core/api/openticket/option.ts
index f5351a7..69d2be9 100644
--- a/src/core/api/openticket/option.ts
+++ b/src/core/api/openticket/option.ts
@@ -357,13 +357,21 @@ export class ODOptionSuffixManager extends ODManager {
const suffix = this.getAll().find((suffix) => suffix.option.id.value == option.id.value)
if (!suffix) return null
try{
- const member = await guild.members.fetch(user.id)
+ const member = await this.#getMember(guild,user)
+ if (!member) return null
return await suffix.getSuffix(member)
}catch(err){
process.emit("uncaughtException",err)
return null
}
}
+ async #getMember(guild:discord.Guild,user:discord.User){
+ try{
+ return await guild.members.fetch(user.id)
+ }catch{
+ return null
+ }
+ }
}
/**## ODOptionSuffix `class`
diff --git a/src/core/startup/migration.ts b/src/core/startup/migration.ts
index ef25ee8..e127dad 100644
--- a/src/core/startup/migration.ts
+++ b/src/core/startup/migration.ts
@@ -139,4 +139,7 @@ export const migrations = [
//MIGRATE TO v4.1.1
new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.1.1"),async () => {},async () => {}),
+ //MIGRATE TO v4.1.2
+ new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.1.2"),async () => {},async () => {}),
+
]
\ No newline at end of file
diff --git a/src/index.ts b/src/index.ts
index 95631bf..6d0090f 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -20,7 +20,7 @@
INFORMATION:
============
- Open Ticket v4.1.1 - © DJdj Development
+ Open Ticket v4.1.2 - © DJdj Development
support us: https://github.com/sponsors/DJj123dj
discord: https://discord.dj-dj.be