Compare commits

...
14 Commits
Author SHA1 Message Date
Jasper 90851f881d Open Ticket v4.1.2
Open Ticket v4.1.2
2026-02-06 21:25:32 +01:00
DJj123dj b972c97871 Fixed: Unknown interaction when on cooldown 2026-02-06 21:16:30 +01:00
DJj123dj db94f226fb Fixed: Panel embed was replaced with cooldown error 2026-02-06 20:59:36 +01:00
DJj123dj 6a4f40d862 (v4.1.2) Readme updates & general improvements 2026-02-06 20:48:21 +01:00
DJj123dj 1f402a848e (v4.1.2) Massive permission system cleanup 2026-02-06 20:08:55 +01:00
DJj123dj 24d98aeaeb (v4.1.2) Fixed autocomplete bug with many options 2026-02-06 17:45:31 +01:00
DJj123dj b95b8f239e Fixed typescript compilation error 2026-01-01 23:00:29 +01:00
DJj123dj 488b5fce53 Fixed fetch() errors of unknown guild members 2025-12-27 10:42:10 +01:00
DJj123dj c2117a67ed Updated German translation for v4.1 2025-12-03 16:20:17 +01:00
Jasper d31be1bb57 Open Ticket v4.1.1
Open Ticket v4.1.1
2025-11-16 11:44:45 +01:00
DJj123dj 76095bea30 Update README.md 2025-11-16 11:33:16 +01:00
DJj123dj da962c6c2e Major bugfixes & improvements for v4.1 2025-11-16 11:23:15 +01:00
DJj123dj a89d5c2149 Added 7 updated translations for v4.1 2025-11-16 10:43:46 +01:00
DJj123dj 7d5313c77e Open Ticket v4.1.1 2025-11-16 10:11:56 +01:00
91 changed files with 4075 additions and 3739 deletions
+1 -1
View File
@@ -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.0"
original["_TRANSLATION"]["otversion"] = "v4.1.2"
const finalText = formatter.stringify(original)
fs.writeFileSync("./languages/"+language,finalText)
}
+8 -23
View File
@@ -2,7 +2,7 @@
<img src="https://apis.dj-dj.be/cdn/openticket/logo.png" alt="Open Ticket Logo" width="500px">
[![discord](https://img.shields.io/badge/discord-support%20server-5865F2.svg?style=flat-square&logo=discord)](https://discord.com/invite/26vT9wt3n3)
[![version](https://img.shields.io/badge/version-4.1.0-brightgreen.svg?style=flat-square)](https://github.com/open-discord-bots/open-ticket/releases/tag/v4.1.0)
[![version](https://img.shields.io/badge/version-4.1.2-brightgreen.svg?style=flat-square)](https://github.com/open-discord-bots/open-ticket/releases/tag/v4.1.2)
[![Sponsor DJj123dj](https://img.shields.io/badge/sponsor-DJj123dj-ea4aaa?style=flat-square&logo=githubsponsors)](https://github.com/sponsors/DJj123dj)
[![Open Ticket supports Pterodactyl Eggs!](https://img.shields.io/badge/pterodactyl-supported-10539F?style=flat-square&logo=pterodactyl)](.eggs/README.md)
@@ -20,33 +20,18 @@ 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.
[**`openticket-egg-v4.1.0.json`**](openticket-egg-v4.1.0.json)
- This egg will always use Open Ticket `v4.1.0`. Open Ticket updates will not have an effect on this egg.
[**`openticket-egg-v4.0.7.json`**](openticket-egg-v4.0.7.json)
- This egg will always use Open Ticket `v4.0.7`. Open Ticket updates will not have an effect on this egg.
[**`openticket-egg-v4.0.6.json`**](openticket-egg-v4.0.6.json)
- This egg will always use Open Ticket `v4.0.6`. Open Ticket updates will not have an effect on this egg.
[**`openticket-egg-v4.0.5.json`**](openticket-egg-v4.0.5.json)
- This egg will always use Open Ticket `v4.0.5`. Open Ticket updates will not have an effect on this egg.
[**`openticket-egg-v4.0.4.json`**](openticket-egg-v4.0.4.json)
- This egg will always use Open Ticket `v4.0.4`. Open Ticket updates will not have an effect on this egg.
[**`openticket-egg-v4.0.3.json`**](openticket-egg-v4.0.3.json)
- This egg will always use Open Ticket `v4.0.3`. Open Ticket updates will not have an effect on this egg.
[**`openticket-egg-v4.0.2.json`**](openticket-egg-v4.0.2.json)
- This egg will always use Open Ticket `v4.0.2`. Open Ticket updates will not have an effect on this egg.
[**`openticket-egg-v4.0.1.json`**](openticket-egg-v4.0.1.json)
- This egg will always use Open Ticket `v4.0.1`. Open Ticket updates will not have an effect on this egg.
[**`openticket-egg-v4.0.0.json`**](openticket-egg-v4.0.0.json)
- This egg will always use Open Ticket `v4.0.0`. Open Ticket updates will not have an effect on this egg.
[**`openticket-egg-v3.5.9.json`**](openticket-egg-v3.5.9.json)
- This egg will always use Open Ticket `v3.5.9`. Open Ticket updates will not have an effect on this egg.
@@ -59,4 +44,4 @@ It's recommended to provide at least `1GB` of **Memory/RAM** and `5GB` of **disk
**Pterodactyl Eggs**<br>
[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)<br>
© 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)
-62
View File
@@ -1,62 +0,0 @@
{
"_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.0.2)",
"author": "support@dj-dj.be",
"description": "This is the official Pterodactyl egg for Open Ticket v4.0.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.0.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.0.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"
}
]
}
-62
View File
@@ -1,62 +0,0 @@
{
"_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.0.3)",
"author": "support@dj-dj.be",
"description": "This is the official Pterodactyl egg for Open Ticket v4.0.3, 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.0.3)\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.0.3\"\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"
}
]
}
-62
View File
@@ -1,62 +0,0 @@
{
"_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.0.4)",
"author": "support@dj-dj.be",
"description": "This is the official Pterodactyl egg for Open Ticket v4.0.4, 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.0.4)\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.0.4\"\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"
}
]
}
-62
View File
@@ -1,62 +0,0 @@
{
"_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.0.5)",
"author": "support@dj-dj.be",
"description": "This is the official Pterodactyl egg for Open Ticket v4.0.5, 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.0.5)\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.0.5\"\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"
}
]
}
-62
View File
@@ -1,62 +0,0 @@
{
"_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.0.6)",
"author": "support@dj-dj.be",
"description": "This is the official Pterodactyl egg for Open Ticket v4.0.6, 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.0.6)\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.0.6\"\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"
}
]
}
@@ -5,9 +5,9 @@
"update_url": null
},
"exported_at": "2025-03-16T18:10:18+01:00",
"name": "Open Ticket (v4.0.0)",
"name": "Open Ticket (v4.1.1)",
"author": "support@dj-dj.be",
"description": "This is the official Pterodactyl egg for Open Ticket v4.0.0, 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!",
"description": "This is the official Pterodactyl egg for Open Ticket v4.1.1, 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"
@@ -22,7 +22,7 @@
},
"scripts": {
"installation": {
"script": "#!\/bin\/bash\r\n# Open Ticket Installation Script (v4.0.0)\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.0.0\"\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",
"script": "#!\/bin\/bash\r\n# Open Ticket Installation Script (v4.1.1)\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.1\"\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"
}
@@ -5,9 +5,9 @@
"update_url": null
},
"exported_at": "2025-03-16T18:10:18+01:00",
"name": "Open Ticket (v4.0.1)",
"name": "Open Ticket (v4.1.2)",
"author": "support@dj-dj.be",
"description": "This is the official Pterodactyl egg for Open Ticket v4.0.1, 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!",
"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"
@@ -22,7 +22,7 @@
},
"scripts": {
"installation": {
"script": "#!\/bin\/bash\r\n# Open Ticket Installation Script (v4.0.1)\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.0.1\"\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",
"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"
}
+2 -2
View File
@@ -1,7 +1,7 @@
# Contributing Guidelines
<img src="https://apis.dj-dj.be/cdn/openticket/logo.png" alt="Open Ticket Logo" width="500px">
[![discord](https://img.shields.io/badge/discord-support%20server-5865F2.svg?style=flat-square&logo=discord)](https://discord.com/invite/26vT9wt3n3) [![version](https://img.shields.io/badge/version-4.1.0-brightgreen.svg?style=flat-square)](https://github.com/open-discord-bots/open-ticket/releases/tag/v4.1.0) [![Sponsor DJj123dj](https://img.shields.io/badge/sponsor-DJj123dj-ea4aaa?style=flat-square&logo=githubsponsors)](https://github.com/sponsors/DJj123dj)
[![discord](https://img.shields.io/badge/discord-support%20server-5865F2.svg?style=flat-square&logo=discord)](https://discord.com/invite/26vT9wt3n3) [![version](https://img.shields.io/badge/version-4.1.2-brightgreen.svg?style=flat-square)](https://github.com/open-discord-bots/open-ticket/releases/tag/v4.1.2) [![Sponsor DJj123dj](https://img.shields.io/badge/sponsor-DJj123dj-ea4aaa?style=flat-square&logo=githubsponsors)](https://github.com/sponsors/DJj123dj)
These are the Contributing Guidelines of Open Ticket!<br>
Here you can find everything you need to know about contributing to Open Ticket.<br>
@@ -89,4 +89,4 @@ you are **REQUIRED to send the bug privately via one of the following methods:**
**Contributing Guidelines**<br>
[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)<br>
© 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)
+11 -9
View File
@@ -14,19 +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 taken offline when v4.2 is released. |
| 4.1.1 | 🟦 | |
| 4.1.0 | ✅ | |
| 4.0.7 | ✅ | Supported Until October 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
@@ -49,4 +51,4 @@ If possible, try to provide screenshots!
**Security Policy**<br>
[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)<br>
© 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)
+1 -1
View File
@@ -1,6 +1,6 @@
<!-- omit from toc -->
# Open Ticket (License)
© 2025 - DJj123dj & Contributors
© 2021 - 2026 - DJj123dj & Contributors
#### Table Of Contents
- [General License](#general-license)
+24 -14
View File
@@ -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!<br>
> [📌 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)
---
<p align="center">
@@ -8,7 +10,7 @@
<br>Powered By<br>
<img src="https://apis.dj-dj.be/cdn/opendiscord/logo.png" alt="Open Ticket" width="170px"><br>
<a href="https://discord.com/invite/26vT9wt3n3"><img alt="Discord Invite Link" src="https://img.shields.io/badge/discord-support%20server-5865F2.svg?style=flat-square&logo=discord"></img></a>
<a href="https://github.com/open-discord-bots/open-ticket/releases/tag/v4.1.0"><img alt="Open Ticket Version" src="https://img.shields.io/badge/version-4.1.0-brightgreen.svg?style=flat-square"></img></a>
<a href="https://github.com/open-discord-bots/open-ticket/releases/tag/v4.1.2"><img alt="Open Ticket Version" src="https://img.shields.io/badge/version-4.1.2-brightgreen.svg?style=flat-square"></img></a>
<a href="https://otdocs.dj-dj.be"><img alt="Open Ticket Documentation" src="https://img.shields.io/badge/discord.js-v14-CB3837.svg?style=flat-square&logo=npm"></img></a>
<a href="https://github.com/open-discord-bots/open-ticket/blob/main/LICENSE"><img alt="Open Ticket License" src="https://img.shields.io/badge/license-GPL%203.0-important.svg?style=flat-square"></img></a>
<a href="https://otdocs.dj-dj.be"><img alt="Open Ticket Stars" src="https://img.shields.io/github/stars/djj123dj/open-ticket?color=yellow&label=stars&logo=github&style=flat-square"></img></a>
@@ -71,9 +73,11 @@ A big thanks to all our sponsors! Without them, it wouldn't be possible to creat
<table>
<tr>
<td><img src="https://github.com/guillee3.png" alt="Profile Picture" width="100px"></td>
<td><img src="https://github.com/yeeetSK.png" alt="Profile Picture" width="100px"></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/guillee3"><b>guillee3</b></a></td>
<td align="center"><a href="https://github.com/yeeetSK"><b>yeeetSK</b></a></td>
</tr>
</table>
@@ -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 |
@@ -165,16 +169,16 @@ With the amazing support of our translators, we've been able to translate Open T
|🟢⏳ |🇧🇩 Bengali |HanumeshGupta |
|🤖 |🇪🇪 Estonian |iamnotmega |
|🤖 |🇫🇮 Finnish |iamnotmega |
|🤖 |🇯🇵 Japanese |HanumeshGupta |
|🤖 |🇬🇷 Greek |HanumeshGupta |
|🤖 |🇸🇮 Slovenian |HanumeshGupta |
|🤖 |🇰🇷 Korean |HanumeshGupta |
|🤖 |🇮🇳 Tamil |HanumeshGupta |
|🤖 |🇨🇳 Simplified Chinese |HanumeshGupta |
|🤖 |❓ Kurdish |HanumeshGupta |
|🤖⏳ |🇷🇺 Russian |NoOneNook |
|🤖⏳ |🇱🇻 Latvian |NoOneNook |
|🤖⏳ |🇻🇳 Vietnamese |ngocdiep2006 |
|🤖⏳ |🇯🇵 Japanese |HanumeshGupta |
|🤖⏳ |🇬🇷 Greek |HanumeshGupta |
|🤖⏳ |🇸🇮 Slovenian |HanumeshGupta |
|🤖⏳ |🇰🇷 Korean |HanumeshGupta |
|🤖⏳ |🇮🇳 Tamil |HanumeshGupta |
|🤖⏳ |🇨🇳 Simplified Chinese |HanumeshGupta |
|🤖⏳ |❓ Kurdish |HanumeshGupta |
|🔴 |🇨🇳 Traditional Chinese|[⭐ Contribute!](.github/CONTRIBUTING.md)|
<!--[⭐ Contribute!](.github/CONTRIBUTING.md) -->
@@ -197,7 +201,7 @@ This will help us grow and reach even more people!
> [`ot-reviews`](https://github.com/open-discord-bots/plugins/tree/main/open-ticket/ot-reviews/),
> [`ot-feedback`](https://github.com/open-discord-bots/plugins/tree/main/open-ticket/ot-feedback/),
> [`ot-tags`](https://github.com/open-discord-bots/plugins/tree/main/open-ticket/ot-tags/),
> [`ot-config-reload`](https://github.com/open-discord-bots/plugins/tree/main/open-ticket/ot-config-reload/)**
> [`ot-restrictions`](https://github.com/open-discord-bots/plugins/tree/main/open-ticket/ot-restrictions/)**
#### Categories:
- **📄 Example** - These plugins serve as an example or starting template.
@@ -206,6 +210,7 @@ This will help us grow and reach even more people!
- **🎨 Customisation** - These plugins add even more customisation to the bot.
- **💼 Management** - These plugins add features that help you manage your server or ticket system.
- **🤖 Client** - These plugins add features affecting the Discord Client or bot itself.
- Please Create a new category when your plugin doesn't fit in one of the available categories.
### 📦 Official *(made by DJdj Development)*
|Name |Category |Description |
@@ -229,7 +234,10 @@ This will help us grow and reach even more people!
|[`ot-move-actions`](https://github.com/open-discord-bots/plugins/tree/main/open-ticket/ot-move-actions/) |💼 Management |Automatically unclaim/unpin a ticket when it's moved using `/move`. |
|[`ot-reviews`](https://github.com/open-discord-bots/plugins/tree/main/open-ticket/ot-reviews/) |💼 Management |Review system for Open Ticket! It is very customisable and has lots of features. |
|[`ot-tags`](https://github.com/open-discord-bots/plugins/tree/main/open-ticket/ot-tags/) |💼 Management |Use tags to quickly reply with a pre-existing text. |
|[`ot-restrictions`](https://github.com/open-discord-bots/plugins/tree/main/open-ticket/ot-restrictions/) |💼 Management |Restrict which roles can open a specific ticket option. |
|[`ot-better-status`](https://github.com/open-discord-bots/plugins/tree/main/open-ticket/ot-better-status/) |🤖 Client |An advanced status plugin to rotate between states. It also allows for the use of variables. |
|[`ot-channel-display`](https://github.com/open-discord-bots/plugins/tree/main/open-ticket/ot-channel-display/) |🤖 Client |A plugin to show different variables in a voice channel in your server. |
|[`ot-vanity`](https://github.com/open-discord-bots/plugins/tree/main/open-ticket/ot-vanity/) |🤖 Client |A plugin to detect the vanity status of members in the server and give them exclusive privilleges. |
### ✅ Verified *(made by community)*
|Name |Author |Category |Description |
@@ -240,6 +248,8 @@ This will help us grow and reach even more people!
|[`ot-assign-role`](https://github.com/open-discord-bots/plugins/tree/main/open-ticket/ot-assign-role/) |rapid.fast |💼 Management |This plugin assigns a predefined role to a user upon creating a ticket. |
|[`ot-volume-warning`](https://github.com/open-discord-bots/plugins/tree/main/open-ticket/ot-volume-warning/) |guillee.3 |💼 Management |Alerts ticket creators when too many tickets are open, indicating possible response delays. |
|[`od-reminders`](https://github.com/open-discord-bots/plugins/tree/main/open-ticket/od-reminders/) |guillee.3 |💼 Management |Set reminders that will be sent to a channel every specified time. |
|[`od-moderation`](https://github.com/open-discord-bots/plugins/tree/main/open-ticket/od-moderation/) |NotMukundOP |💼 Management |A simple moderation plugin for Open Discord with ban, kick & warnings. |
|[`ot-followups`](https://github.com/open-discord-bots/plugins/tree/main/open-ticket/ot-followups/) |guillee.3 |💼 Management |Send additional follow-up messages to a ticket. |
|[`ot-translate-cmds`](https://github.com/open-discord-bots/plugins/tree/main/open-ticket/ot-translate-cmds/) |guillee.3 |🤖 Client |Translate all built-in command names, descriptions & options. |
---
@@ -248,4 +258,4 @@ This will help us grow and reach even more people!
**README.md**<br>
[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)<br>
© 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)
+1 -1
View File
@@ -2,7 +2,7 @@
"_INFO":{
"support":"https://otdocs.dj-dj.be",
"discord":"https://discord.dj-dj.be",
"version":"open-ticket-v4.1.0"
"version":"open-ticket-v4.1.2"
},
"token":"insert your bot token here! (or leave empty when using 'tokenFromENV')",
+1 -1
View File
@@ -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.0 (or leave empty)",
"footer":"Open Ticket v4.1.2 (or leave empty)",
"fields":[
{"name":"field name","value":"field value","inline":false}
],
+1 -1
View File
@@ -14,7 +14,7 @@ process.argv.push(...flags)
██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║ ██║ ██║██║ ██╔═██╗ ██╔══╝ ██║
╚██████╔╝██║ ███████╗██║ ╚████║ ██║ ██║╚██████╗██║ ██╗███████╗ ██║
╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═╝
v4.1.0 - Made by DJj123dj & Contributors
v4.1.2 - Made by DJj123dj & Contributors
Discord: https://discord.dj-dj.be
Docs: https://otdocs.dj-dj.be
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION": {
"otversion": "v4.1.0",
"otversion": "v4.1.2",
"translators": ["palestinian"],
"lastedited": "06/12/2024",
"language": "Arabic",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["HanumeshGupta"],
"lastedited":"19/06/2025",
"language":"Bengali",
+2 -2
View File
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["guillee3"],
"lastedited":"09/11/2025",
"lastedited":"03/12/2025",
"language":"Catalan",
"automated":false
},
+2 -2
View File
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["DJj123dj"],
"lastedited":"09/11/2025",
"lastedited":"03/12/2025",
"language":"Custom",
"automated":false
},
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["spyeye_"],
"lastedited":"21/08/2024",
"language":"Czech",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["the_gamer"],
"lastedited":"26/09/2024",
"language":"Danish",
+3 -3
View File
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["DJj123dj"],
"lastedited":"09/11/2025",
"lastedited":"03/12/2025",
"language":"Dutch",
"automated":false
},
@@ -302,7 +302,7 @@
"permissionError":"Permission Error"
},
"descriptions":{
"askForInfo":"Contacteer the eigenaar van deze bot voor meer info!",
"askForInfo":"Contacteer de eigenaar van deze bot voor meer info!",
"askForInfoResolve":"Contacteer de eigenaar van deze bot als het probleem niet opgelost wordt na enkele keren.",
"internalError":"Gefaald om te reageren op deze {0} door een interne error!",
"optionMissing":"Een verplichte parameter mist in deze command!",
+2 -2
View File
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["DJj123dj"],
"lastedited":"09/11/2025",
"lastedited":"03/12/2025",
"language":"English",
"automated":false
},
+2 -2
View File
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["iamnotmega","ChatGPT"],
"lastedited":"09/11/2025",
"lastedited":"03/12/2025",
"language":"Estonian",
"automated":true
},
+2 -2
View File
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["iamnotmega","ChatGPT"],
"lastedited":"09/11/2025",
"lastedited":"03/12/2025",
"language":"Finnish",
"automated":true
},
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["guillee3"],
"lastedited":"04/12/2024",
"language":"French",
+156 -26
View File
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"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":"`<name>` => 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":"<Inhalt ist leer>",
"noTitle":"<kein Titel>",
"noDesc":"<keine Beschreibung>"
}
},
"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"
}
}
+245 -115
View File
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"translators":["HanumeshGupta"],
"lastedited":"19/06/2025",
"otversion":"v4.1.2",
"translators":["HanumeshGupta","ChatGPT"],
"lastedited":"03/12/2025",
"language":"Greek",
"automated":true
},
@@ -31,7 +31,15 @@
"stringContains":"Αυτή η συμβολοσειρά πρέπει να περιέχει {0}!",
"stringChoices":"Αυτή η συμβολοσειρά μπορεί να είναι μόνο μία από τις ακόλουθες τιμές: {0}!",
"stringRegex":"Αυτή η συμβολοσειρά είναι άκυρη!",
"stringInvertedContains":"Αυτή η συμβολοσειρά δεν επιτρέπεται να περιέχει {0}!",
"stringLowercase":"Αυτή η συμβολοσειρά πρέπει να είναι γραμμένη μόνο με πεζά!",
"stringUppercase":"Αυτή η συμβολοσειρά πρέπει να είναι γραμμένη μόνο με κεφαλαία!",
"stringSpecialCharacters":"Αυτή η συμβολοσειρά δεν επιτρέπεται να περιέχει ειδικούς χαρακτήρες! (a-z, 0-9 & κενό μόνο)",
"stringNoSpaces":"Αυτή η συμβολοσειρά δεν επιτρέπεται να περιέχει κενά!",
"stringCapitalWord":"Συνιστάται κάθε λέξη σε αυτήν τη συμβολοσειρά να ξεκινά με κεφαλαίο γράμμα!",
"stringCapitalSentence":"Φαίνεται ότι ορισμένες προτάσεις σε αυτήν τη συμβολοσειρά δεν ξεκινούν με κεφαλαίο γράμμα!",
"stringPunctuation":"Φαίνεται ότι η πρόταση σε αυτήν τη συμβολοσειρά δεν τελειώνει με σημείο στίξης!",
"numberTooShort":"Αυτός ο αριθμός δεν μπορεί να είναι μικρότερος από {0} ψηφία!",
"numberTooLong":"Αυτός ο αριθμός δεν μπορεί να είναι μεγαλύτερος από {0} ψηφία!",
"numberLengthInvalid":"Αυτός ο αριθμός πρέπει να είναι {0} ψηφία!",
@@ -48,10 +56,12 @@
"numberNegative":"Αυτός ο αριθμός δεν μπορεί να είναι αρνητικός!",
"numberPositive":"Αυτός ο αριθμός δεν μπορεί να είναι θετικός!",
"numberZero":"Αυτός ο αριθμός δεν μπορεί να είναι μηδέν!",
"numberNan":"Αυτός ο αριθμός δεν μπορεί να είναι NaN (Not A Number)!",
"numberInvertedContains":"Αυτός ο αριθμός δεν επιτρέπεται να περιέχει {0}!",
"booleanTrue":"Αυτό το boolean δεν μπορεί να είναι true!",
"booleanFalse":"Αυτό το boolean δεν μπορεί να είναι false!",
"arrayEmptyDisabled":"Αυτός ο πίνακας δεν επιτρέπεται να είναι κενός!",
"arrayEmptyRequired":"Αυτός ο πίνακας πρέπει να είναι κενός!",
"arrayTooShort":"Αυτός ο πίνακας πρέπει να έχει μήκος τουλάχιστον {0}!",
@@ -59,7 +69,7 @@
"arrayLengthInvalid":"Αυτός ο πίνακας πρέπει να έχει μήκος {0}!",
"arrayInvalidTypes":"Αυτός ο πίνακας μπορεί να περιέχει μόνο τους ακόλουθους τύπους: {0}!",
"arrayDouble":"Αυτός ο πίνακας δεν επιτρέπει την ίδια τιμή δύο φορές!",
"discordInvalidId":"Αυτό είναι ένα άκυρο discord {0} id!",
"discordInvalidIdOptions":"Αυτό είναι ένα άκυρο discord {0} id! Μπορείτε επίσης να χρησιμοποιήσετε ένα από αυτά: {1}!",
"discordInvalidToken":"Αυτό είναι ένα άκυρο discord token (συντακτικά)!",
@@ -76,7 +86,7 @@
"urlInvalidPath":"Αυτό το url έχει άκυρη διαδρομή!",
"idNotUnique":"Αυτό το id δεν είναι μοναδικό, χρησιμοποιήστε άλλο id!",
"idNonExistent":"Το id {0} δεν υπάρχει!",
"invalidType":"Αυτή η ιδιότητα πρέπει να είναι του τύπου: {0}!",
"propertyMissing":"Η ιδιότητα {0} λείπει από αυτό το αντικείμενο!",
"propertyOptional":"Η ιδιότητα {0} είναι προαιρετική σε αυτό το αντικείμενο!",
@@ -84,12 +94,13 @@
"nullInvalid":"Αυτή η ιδιότητα δεν μπορεί να είναι null!",
"switchInvalidType":"Αυτό πρέπει να είναι ένας από τους ακόλουθους τύπους: {0}!",
"objectSwitchInvalid":"Αυτό το αντικείμενο πρέπει να είναι ένας από τους ακόλουθους τύπους: {0}!",
"invalidLanguage":"Αυτή είναι μια άκυρη γλώσσα!",
"invalidButton":"Αυτό το κουμπί πρέπει να έχει τουλάχιστον ένα {0} ή {1}!",
"unusedOption":"Η επιλογή {0} δεν χρησιμοποιείται πουθενά!",
"unusedQuestion":"Η ερώτηση {0} δεν χρησιμοποιείται πουθενά!",
"dropdownOption":"Ένα πάνελ με ενεργοποιημένο dropdown μπορεί να περιέχει μόνο επιλογές τύπου 'ticket'!"
"dropdownOption":"Ένα πάνελ με ενεργοποιημένο dropdown μπορεί να περιέχει μόνο επιλογές τύπου 'ticket'!",
"customInvalidVersion":"Η έκδοση που καθορίστηκε στο config σας δεν ταιριάζει! Βεβαιωθείτε ότι έχετε ενημερώσει το config στην πιο πρόσφατη έκδοση!"
}
},
"actions":{
@@ -132,6 +143,7 @@
"blacklistAddDm":"Προστέθηκε στη Μαύρη Λίστα",
"blacklistRemoveDm":"Αφαιρέθηκε από τη Μαύρη Λίστα",
"clear":"Εισιτήρια Διαγράφηκαν",
"clearTickets":"Εκκαθάριση Tickets",
"roles":"Ενημέρωση Ρόλων",
"autoclose":"Αυτόματο Κλείσιμο",
@@ -139,7 +151,12 @@
"autocloseDisabled":"Απενεργοποιήθηκε Αυτόματο Κλείσιμο",
"autodelete":"Αυτόματη Διαγραφή",
"autodeleteEnabled":"Ενεργοποιήθηκε Αυτόματη Διαγραφή",
"autodeleteDisabled":"Απενεργοποιήθηκε Αυτόματη Διαγραφή"
"autodeleteDisabled":"Απενεργοποιήθηκε Αυτόματη Διαγραφή",
"topicSet":"Το Θέμα Αλλάχθηκε",
"prioritySet":"Η Προτεραιότητα Αλλάχθηκε",
"priorityGet":"Προτεραιότητα Ticket",
"transfer":"Το Ticket Μεταφέρθηκε"
},
"descriptions":{
"create":"Το εισιτήριό σας δημιουργήθηκε. Κάντε κλικ στο παρακάτω κουμπί για να το προσπελάσετε!",
@@ -154,7 +171,7 @@
"move":"Το εισιτήριο μετακινήθηκε στο {0} με επιτυχία!",
"add":"Ο {0} προστέθηκε στο εισιτήριο με επιτυχία!",
"remove":"Ο {0} αφαιρέθηκε από το εισιτήριο με επιτυχία!",
"helpExplanation":"`<όνομα>` => απαιτούμενη παράμετρος\n`[όνομα]` => προαιρετική παράμετρος",
"statsReset":"Τα στατιστικά του bot επαναφέρθηκαν με επιτυχία!",
"statsError":"Αδυναμία προβολής στατιστικών εισιτηρίου!\nτο {0} δεν είναι εισιτήριο!",
@@ -167,7 +184,7 @@
"clearVerify":"Είστε βέβαιοι ότι θέλετε να διαγράψετε πολλά εισιτήρια;\nΑυτή η ενέργεια δεν μπορεί να αναιρεθεί!",
"clearReady":"{0} εισιτήρια διαγράφηκαν με επιτυχία!",
"rolesEmpty":"Δεν ενημερώθηκαν ρόλοι!",
"autocloseLeave":"Αυτό το εισιτήριο έκλεισε αυτόματα επειδή ο δημιουργός άφησε τον server!",
"autocloseTimeout":"Αυτό το εισιτήριο έκλεισε αυτόματα επειδή ήταν ανενεργό για περισσότερο από `{0} ώρες`!",
"autodeleteLeave":"Αυτό το εισιτήριο διαγράφηκε αυτόματα επειδή ο δημιουργός άφησε τον server!",
@@ -176,11 +193,16 @@
"autocloseDisabled":"Το αυτόματο κλείσιμο απενεργοποιήθηκε σε αυτό το εισιτήριο!\nΔεν θα κλείνει πλέον αυτόματα!",
"autodeleteEnabled":"Η αυτόματη διαγραφή ενεργοποιήθηκε σε αυτό το εισιτήριο!\nΘα διαγραφεί όταν είναι ανενεργό για περισσότερο από `{0} ημέρες`!",
"autodeleteDisabled":"Η αυτόματη διαγραφή απενεργοποιήθηκε σε αυτό το εισιτήριο!\nΔεν θα διαγράφεται πλέον αυτόματα!",
"ticketMessageLimit":"Μπορείτε να δημιουργήσετε μόνο {0} εισιτήρια ταυτόχρονα!",
"ticketMessageAutoclose":"Αυτό το εισιτήριο θα κλείσει αυτόματα όταν είναι ανενεργό για {0} ώρες!",
"ticketMessageAutodelete":"Αυτό το εισιτήριο θα διαγραφεί αυτόματα όταν είναι ανενεργό για {0} ημέρες!",
"panelReady":"Μπορείτε να βρείτε το πάνελ παρακάτω!\nΑυτό το μήνυμα μπορεί τώρα να διαγραφεί!"
"panelReady":"Το πάνελ είναι διαθέσιμο στο επόμενο μήνυμα!\nΑυτό το μήνυμα μπορεί τώρα να διαγραφεί!",
"topicSet":"Το θέμα του καναλιού άλλαξε επιτυχώς από τον/την {0}!",
"prioritySet":"Η προτεραιότητα του ticket άλλαξε σε {0} από τον/την {1} επιτυχώς!",
"priorityGet":"Η τρέχουσα προτεραιότητα αυτού του ticket είναι {0}.",
"transfer":"Η ιδιοκτησία του ticket μεταφέρθηκε από τον/την {0} στον/στην {1} από τον/την {2} επιτυχώς!"
},
"modal":{
"closePlaceholder":"Γιατί έκλεισες αυτό το εισιτήριο;",
@@ -215,12 +237,19 @@
"addDm":"Ο {0} προστέθηκε στο εισιτήριό σας στον server μας!",
"removeLog":"Ο {0} αφαιρέθηκε από αυτό το εισιτήριο από τον {1}!",
"removeDm":"Ο {0} αφαιρέθηκε από το εισιτήριό σας στον server μας!",
"blacklistAddLog":"Ο {0} προστέθηκε στη μαύρη λίστα από τον {1}!",
"blacklistRemoveLog":"Ο {0} αφαιρέθηκε από τη μαύρη λίστα από τον {1}!",
"blacklistAddDm":"Έχετε προστεθεί στη μαύρη λίστα στον server μας!\nΑπό τώρα, δεν μπορείτε να δημιουργήσετε εισιτήριο!",
"blacklistRemoveDm":"Έχετε αφαιρεθεί από τη μαύρη λίστα στον server μας!\nΤώρα μπορείτε να δημιουργήσετε εισιτήρια ξανά!",
"clearLog":"{0} εισιτήρια διαγράφηκαν από τον {1}!"
"clearLog":"{0} εισιτήρια διαγράφηκαν από τον {1}!",
"transferLog":"Η ιδιοκτησία αυτού του ticket μεταφέρθηκε από τον/την {0} στον/στην {1} από τον/την {2}!",
"transferDm":"Η ιδιοκτησία του ticket σας μεταφέρθηκε από τον/την {0} στον/στην {1} στον server μας!",
"prioritySetLog":"Η προτεραιότητα αυτού του ticket άλλαξε σε {0} από τον/την {1}!",
"prioritySetDm":"Η προτεραιότητα του ticket σας άλλαξε σε {0} στον server μας!",
"roleUpdateLog":"Ο/Η {0} ενημέρωσε τους ρόλους του/της!",
"roleUpdateDm":"Οι ρόλοι σας στον server μας έχουν ενημερωθεί!"
}
},
"transcripts":{
@@ -229,7 +258,7 @@
"ready":"Δημιουργήθηκε Αντίγραφο",
"textFileDescription":"Αυτό είναι το αντίγραφο κειμένου ενός διαγεγραμμένου εισιτηρίου!",
"htmlProgress":"Παρακαλώ περιμένετε ενώ επεξεργάζεται αυτό το html αντίγραφο...",
"createdChannel":"Ένα νέο {0} αντίγραφο δημιουργήθηκε στον server!",
"createdCreator":"Ένα νέο {0} αντίγραφο δημιουργήθηκε για ένα από τα εισιτήριά σας!",
"createdParticipant":"Ένα νέο {0} αντίγραφο δημιουργήθηκε σε ένα εισιτήριο που συμμετείχατε!",
@@ -241,7 +270,19 @@
"retry":"Επανάληψη",
"continue":"Διαγραφή Χωρίς Αντίγραφο",
"backup":"Δημιουργία Αντιγράφου Ασφαλείας",
"error":"Κάτι πήγε στραβά κατά τη δημιουργία του αντιγράφου.\nΤι θα θέλατε να κάνετε;\n\nΑυτό το εισιτήριο δεν θα διαγραφεί μέχρι να κάνετε κλικ σε ένα από αυτά τα κουμπιά."
"error":"Κάτι πήγε στραβά κατά τη δημιουργία του αντιγράφου.\nΤι θα θέλατε να κάνετε;\n\nΑυτό το εισιτήριο δεν θα διαγραφεί μέχρι να κάνετε κλικ σε ένα από αυτά τα κουμπιά.",
"title":"Σφάλμα Transcript"
},
"text":{
"messagesTitle":"ΜΗΝΥΜΑΤΑ",
"embedTitle":"EMBED",
"fileTitle":"ΑΡΧΕΙΟ",
"fieldsTitle":"ΠΕΔΙΑ",
"reactionsTitle":"ΑΝΤΙΔΡΑΣΕΙΣ",
"statsTitle":"ΣΤΑΤΙΣΤΙΚΑ",
"emptyContent":"<το περιεχόμενο είναι κενό>",
"noTitle":"<χωρίς τίτλο>",
"noDesc":"<χωρίς περιγραφή>"
}
},
"errors":{
@@ -257,7 +298,8 @@
"unknownPanel":"Άγνωστο Πάνελ",
"notInGuild":"Δεν Είστε σε Server",
"channelRename":"Αδυναμία Μετονομασίας Κανάλι",
"busy":"Το Εισιτήριο Είναι Απασχολημένο"
"busy":"Το Εισιτήριο Είναι Απασχολημένο",
"permissionError":"Σφάλμα Δικαιωμάτων"
},
"descriptions":{
"askForInfo":"Επικοινωνήστε με τον ιδιοκτήτη αυτού του bot για περισσότερες πληροφορίες!",
@@ -280,7 +322,10 @@
"notInGuild":"Αυτό το {0} δεν λειτουργεί σε DM! Παρακαλώ δοκιμάστε ξανά σε έναν server!",
"channelRename":"Λόγω discord ratelimits, είναι αδύνατο για το bot να μετονομάσει το κανάλι. Το κανάλι θα μετονομαστεί αυτόματα σε 10 λεπτά αν το bot δεν επανεκκινηθεί.",
"channelRenameSource":"Η πηγή αυτού του σφάλματος είναι: {0}",
"busy":"Αδυναμία χρήσης αυτού του {0}!\nΤο εισιτήριο είναι αυτή τη στιγμή σε επεξεργασία από το bot.\n\nΠαρακαλώ δοκιμάστε ξανά σε λίγα δευτερόλεπτα!"
"busy":"Αδυναμία χρήσης αυτού του {0}!\nΤο εισιτήριο είναι αυτή τη στιγμή σε επεξεργασία από το bot.\n\nΠαρακαλώ δοκιμάστε ξανά σε λίγα δευτερόλεπτα!",
"closeBeforeMessage":"Αυτό το ticket δεν μπορεί να κλείσει/διαγραφεί πριν σταλεί ένα μήνυμα από έναν χρήστη.",
"closeBeforeAdminMessage":"Αυτό το ticket δεν μπορεί να κλείσει/διαγραφεί πριν σταλεί μήνυμα από έναν ticket admin ή μέλος υποστήριξης.",
"unableToCreateTicket":"Δεν μπορείτε να δημιουργήσετε ticket."
},
"optionInvalidReasons":{
"stringRegex":"Η τιμή δεν ταιριάζει με το μοτίβο!",
@@ -331,7 +376,6 @@
"added":"Προστέθηκε",
"removed":"Αφαιρέθηκε",
"filter":"Φίλτρο",
"claimedBy":"Αναλήφθηκε Από {0}",
"method":"Μέθοδος",
"type":"Τύπος",
"blacklisted":"Στη Μαύρη Λίστα",
@@ -355,7 +399,27 @@
"status":"Κατάσταση",
"claimed":"Αναληφθείς",
"pinned":"Καρφιτσωμένο",
"creationDate":"Ημερομηνία Δημιουργίας"
"creationDate":"Ημερομηνία Δημιουργίας",
"noone":"Κανείς",
"open":"Ανοιχτό",
"closed":"Κλειστό",
"priority":"Προτεραιότητα",
"participants":"Συμμετέχοντες",
"yes":"Ναι",
"no":"Όχι",
"option":"Επιλογή",
"topic":"Θέμα",
"uptime":"Χρόνος Λειτουργίας Συστήματος",
"messages":"Μηνύματα",
"embeds":"Embeds",
"files":"Αρχεία",
"components":"Στοιχεία",
"cooldown":"Χρόνος Αναμονής",
"maxTickets":"Μέγιστος Αριθμός Tickets",
"admins":"Διαχειριστές",
"roles":"Ρόλοι",
"size":"Μέγεθος"
},
"lowercase":{
"text":"κείμενο",
@@ -373,106 +437,172 @@
"panel":"Εμφάνιση μηνύματος με πτυσσόμενο μενού ή κουμπιά (για δημιουργία εισιτηρίου).",
"panelId":"Το αναγνωριστικό του πάνελ που θέλετε να εμφανίσετε.",
"panelAutoUpdate":"Θέλετε αυτό το πάνελ να ενημερώνεται αυτόματα όταν επεξεργαστεί;",
"ticket": "Δημιουργία εισιτηρίου αμέσως.",
"ticketId": "Το αναγνωριστικό του εισιτηρίου που θέλετε να δημιουργήσετε.",
"close": "Κλείσιμο εισιτηρίου.",
"delete": "Διαγραφή εισιτηρίου.",
"deleteNoTranscript": "Διαγραφή αυτού του εισιτηρίου χωρίς δημιουργία μεταγραφής.",
"reopen": "Επαναφορά εισιτηρίου.",
"claim": "Αιτηματοποίηση εισιτηρίου.",
"claimUser": "Αιτηματοποίηση αυτού του εισιτηρίου σε κάποιον άλλον αντί για εσάς.",
"unclaim": "Ακύρωση αιτηματοποίησης εισιτηρίου.",
"pin": "Καρφίτσωμα εισιτηρίου.",
"unpin": "Ξεκαρφίτσωμα εισιτηρίου.",
"move": "Μετακίνηση εισιτηρίου.",
"moveId": "Το αναγνωριστικό της επιλογής στην οποία θέλετε να μετακινήσετε.",
"rename": "Μετονομασία εισιτηρίου.",
"renameName": "Το νέο όνομα για αυτό το εισιτήριο.",
"add": "Προσθήκη χρήστη σε εισιτήριο.",
"addUser": "Ο χρήστης που θα προστεθεί.",
"remove": "Αφαίρεση χρήστη από εισιτήριο.",
"removeUser": "Ο χρήστης που θα αφαιρεθεί.",
"blacklist": "Διαχείριση μαύρης λίστας εισιτηρίων.",
"blacklistView": "Προβολή λίστας της τρέχουσας μαύρης λίστας.",
"blacklistAdd": "Προσθήκη χρήστη στη μαύρη λίστα.",
"blacklistRemove": "Αφαίρεση χρήστη από τη μαύρη λίστα.",
"blacklistGet": "Λήψη λεπτομερειών από έναν χρήστη στη μαύρη λίστα.",
"blacklistGetUser": "Ο χρήστης από τον οποίο θα ληφθούν λεπτομέρειες.",
"stats": "Προβολή στατιστικών από το bot, ένα μέλος ή ένα εισιτήριο.",
"statsReset": "Επαναφορά όλων των στατιστικών του bot (και έναρξη καταμέτρησης από το μηδέν).",
"statsGlobal": "Προβολή παγκόσμιων στατιστικών.",
"statsUser": "Προβολή στατιστικών ενός χρήστη στον server.",
"statsUserUser": "Ο χρήστης που θα προβληθεί.",
"statsTicket": "Προβολή στατιστικών ενός εισιτηρίου στον server.",
"statsTicketTicket": "Το εισιτήριο που θα προβληθεί.",
"clear": "Διαγραφή πολλαπλών εισιτηρίων ταυτόχρονα.",
"clearFilter": "Το φίλτρο για την εκκαθάριση εισιτηρίων.",
"clearFilters": {
"all": "Όλα",
"open": "Ανοιχτά",
"close": "Κλειστά",
"claim": "Αιτηματοποιημένα",
"unclaim": "Μη αιτηματοποιημένα",
"pin": "Καρφιτσωμένα",
"unpin": "Μη καρφιτσωμένα",
"autoclose": "Αυτόματα κλειστά"
"ticket":"Δημιουργία εισιτηρίου αμέσως.",
"ticketId":"Το αναγνωριστικό του εισιτηρίου που θέλετε να δημιουργήσετε.",
"close":"Κλείσιμο εισιτηρίου.",
"delete":"Διαγραφή εισιτηρίου.",
"deleteNoTranscript":"Διαγραφή αυτού του εισιτηρίου χωρίς δημιουργία μεταγραφής.",
"reopen":"Επαναφορά εισιτηρίου.",
"claim":"Αιτηματοποίηση εισιτηρίου.",
"claimUser":"Αιτηματοποίηση αυτού του εισιτηρίου σε κάποιον άλλον αντί για εσάς.",
"unclaim":"Ακύρωση αιτηματοποίησης εισιτηρίου.",
"pin":"Καρφίτσωμα εισιτηρίου.",
"unpin":"Ξεκαρφίτσωμα εισιτηρίου.",
"move":"Μετακίνηση εισιτηρίου.",
"moveId":"Το αναγνωριστικό της επιλογής στην οποία θέλετε να μετακινήσετε.",
"rename":"Μετονομασία εισιτηρίου.",
"renameName":"Το νέο όνομα για αυτό το εισιτήριο.",
"add":"Προσθήκη χρήστη σε εισιτήριο.",
"addUser":"Ο χρήστης που θα προστεθεί.",
"remove":"Αφαίρεση χρήστη από εισιτήριο.",
"removeUser":"Ο χρήστης που θα αφαιρεθεί.",
"blacklist":"Διαχείριση μαύρης λίστας εισιτηρίων.",
"blacklistView":"Προβολή λίστας της τρέχουσας μαύρης λίστας.",
"blacklistAdd":"Προσθήκη χρήστη στη μαύρη λίστα.",
"blacklistRemove":"Αφαίρεση χρήστη από τη μαύρη λίστα.",
"blacklistGet":"Λήψη λεπτομερειών από έναν χρήστη στη μαύρη λίστα.",
"blacklistGetUser":"Ο χρήστης από τον οποίο θα ληφθούν λεπτομέρειες.",
"stats":"Προβολή στατιστικών από το bot, ένα μέλος ή ένα εισιτήριο.",
"statsReset":"Επαναφορά όλων των στατιστικών του bot (και έναρξη καταμέτρησης από το μηδέν).",
"statsGlobal":"Προβολή παγκόσμιων στατιστικών.",
"statsUser":"Προβολή στατιστικών ενός χρήστη στον server.",
"statsUserUser":"Ο χρήστης που θα προβληθεί.",
"statsTicket":"Προβολή στατιστικών ενός εισιτηρίου στον server.",
"statsTicketTicket":"Το εισιτήριο που θα προβληθεί.",
"clear":"Διαγραφή πολλαπλών εισιτηρίων ταυτόχρονα.",
"clearFilter":"Το φίλτρο για την εκκαθάριση εισιτηρίων.",
"clearFilters":{
"all":"Όλα",
"open":"Ανοιχτά",
"close":"Κλειστά",
"claim":"Αιτηματοποιημένα",
"unclaim":"Μη αιτηματοποιημένα",
"pin":"Καρφιτσωμένα",
"unpin":"Μη καρφιτσωμένα",
"autoclose":"Αυτόματα κλειστά"
},
"autoclose": "Διαχείριση αυτόματου κλεισίματος σε εισιτήριο.",
"autocloseDisable": "Απενεργοποίηση αυτόματου κλεισίματος σε αυτό το εισιτήριο.",
"autocloseEnable": "Ενεργοποίηση αυτόματου κλεισίματος σε αυτό το εισιτήριο.",
"autocloseEnableTime": "Ο αριθμός των ωρών που απαιτείται για να κλείσει αυτόματα το εισιτήριο λόγω αδράνειας.",
"autodelete": "Διαχείριση αυτόματης διαγραφής σε εισιτήριο.",
"autodeleteDisable": "Απενεργοποίηση αυτόματης διαγραφής σε αυτό το εισιτήριο.",
"autodeleteEnable": "Ενεργοποίηση αυτόματης διαγραφής σε αυτό το εισιτήριο.",
"autodeleteEnableTime": "Ο αριθμός των ημερών που απαιτείται για να διαγραφεί αυτόματα το εισιτήριο λόγω αδράνειας."
"autoclose":"Διαχείριση αυτόματου κλεισίματος σε εισιτήριο.",
"autocloseDisable":"Απενεργοποίηση αυτόματου κλεισίματος σε αυτό το εισιτήριο.",
"autocloseEnable":"Ενεργοποίηση αυτόματου κλεισίματος σε αυτό το εισιτήριο.",
"autocloseEnableTime":"Ο αριθμός των ωρών που απαιτείται για να κλείσει αυτόματα το εισιτήριο λόγω αδράνειας.",
"autodelete":"Διαχείριση αυτόματης διαγραφής σε εισιτήριο.",
"autodeleteDisable":"Απενεργοποίηση αυτόματης διαγραφής σε αυτό το εισιτήριο.",
"autodeleteEnable":"Ενεργοποίηση αυτόματης διαγραφής σε αυτό το εισιτήριο.",
"autodeleteEnableTime":"Ο αριθμός των ημερών που απαιτείται για να διαγραφεί αυτόματα το εισιτήριο λόγω αδράνειας.",
"topic":"Διαχειριστείτε το θέμα του καναλιού ticket.",
"topicSet":"Ορίστε το θέμα του καναλιού ticket.",
"topicValue":"Το νέο θέμα του καναλιού.",
"topicList":"Λάβετε μια λίστα όλων των tickets με το θέμα και τα στατιστικά τους.",
"priority":"Διαχειριστείτε την προτεραιότητα του ticket.",
"prioritySet":"Ορίστε την προτεραιότητα του ticket.",
"priorityValue":"Η προτεραιότητα του καναλιού.",
"priorityGet":"Λάβετε την προτεραιότητα του ticket.",
"priorityList":"Λάβετε μια λίστα όλων των tickets με την κατάσταση προτεραιότητάς τους.",
"transfer":"Μεταφέρετε την ιδιοκτησία του ticket από έναν χρήστη σε άλλον.",
"transferUser":"Ο χρήστης στον οποίο θα γίνει η μεταφορά."
},
"helpMenu":{
"help": "Λήψη λίστας όλων των διαθέσιμων εντολών.",
"ticket": "Δημιουργία εισιτηρίου αμέσως.",
"close": "Κλείσιμο εισιτηρίου, αυτό απενεργοποιεί τη γραφή σε αυτό το κανάλι.",
"delete": "Διαγραφή εισιτηρίου, αυτό δημιουργεί μια μεταγραφή όταν είναι ενεργοποιημένη.",
"reopen": "Επαναφορά εισιτηρίου, αυτό ενεργοποιεί ξανά τη γραφή σε αυτό το κανάλι.",
"pin": "Καρφίτσωμα εισιτηρίου. Αυτό θα μετακινήσει το εισιτήριο στην κορυφή και θα προσθέσει ένα emoji '📌' στο όνομα.",
"unpin": "Ξεκαρφίτσωμα εισιτηρίου. Το εισιτήριο θα παραμείνει στη θέση του αλλά θα χάσει το emoji '📌'.",
"move": "Μετακίνηση εισιτηρίου. Αυτό θα αλλάξει τον τύπο αυτού του εισιτηρίου.",
"rename": "Μετονομασία εισιτηρίου. Αυτό θα αλλάξει το όνομα του καναλιού αυτού του εισιτηρίου.",
"claim": "Αιτηματοποίηση εισιτηρίου. Με αυτό, μπορείτε να ενημερώσετε την ομάδα σας ότι το χειρίζεστε.",
"unclaim": "Ακύρωση αιτηματοποίησης εισιτηρίου. Με αυτό, μπορείτε να ενημερώσετε την ομάδα σας ότι το εισιτήριο είναι ελεύθερο ξανά.",
"add": "Προσθήκη χρήστη σε εισιτήριο. Αυτό θα επιτρέψει στον χρήστη να διαβάζει και να γράφει σε αυτό το εισιτήριο.",
"remove": "Αφαίρεση χρήστη από εισιτήριο. Αυτό θα αφαιρέσει τη δυνατότητα ανάγνωσης και εγγραφής για έναν χρήστη σε αυτό το εισιτήριο.",
"panel": "Δημιουργία μηνύματος με αναπτυσσόμενο μενού ή κουμπιά (για δημιουργία εισιτηρίου).",
"blacklistView": "Προβολή λίστας της τρέχουσας μαύρης λίστας.",
"blacklistAdd": "Προσθήκη χρήστη στη μαύρη λίστα.",
"blacklistRemove": "Αφαίρεση χρήστη από τη μαύρη λίστα.",
"blacklistGet": "Λήψη λεπτομερειών από έναν χρήστη στη μαύρη λίστα.",
"statsGlobal": "Προβολή παγκόσμιων στατιστικών.",
"statsTicket": "Προβολή στατιστικών ενός εισιτηρίου στον server.",
"statsUser": "Προβολή στατιστικών ενός χρήστη στον server.",
"statsReset": "Επαναφορά όλων των στατιστικών του bot (και έναρξη καταμέτρησης από το μηδέν).",
"autocloseDisable": "Απενεργοποίηση αυτόματου κλεισίματος σε αυτό το εισιτήριο.",
"autocloseEnable": "Ενεργοποίηση αυτόματου κλεισίματος σε αυτό το εισιτήριο.",
"autodeleteDisable": "Απενεργοποίηση αυτόματης διαγραφής σε αυτό το εισιτήριο.",
"autodeleteEnable": "Ενεργοποίηση αυτόματης διαγραφής σε αυτό το εισιτήριο."
"help":"Λήψη λίστας όλων των διαθέσιμων εντολών.",
"ticket":"Δημιουργία εισιτηρίου αμέσως.",
"close":"Κλείσιμο εισιτηρίου, αυτό απενεργοποιεί τη γραφή σε αυτό το κανάλι.",
"delete":"Διαγραφή εισιτηρίου, αυτό δημιουργεί μια μεταγραφή όταν είναι ενεργοποιημένη.",
"reopen":"Επαναφορά εισιτηρίου, αυτό ενεργοποιεί ξανά τη γραφή σε αυτό το κανάλι.",
"pin":"Καρφίτσωμα εισιτηρίου. Αυτό θα μετακινήσει το εισιτήριο στην κορυφή και θα προσθέσει ένα emoji '📌' στο όνομα.",
"unpin":"Ξεκαρφίτσωμα εισιτηρίου. Το εισιτήριο θα παραμείνει στη θέση του αλλά θα χάσει το emoji '📌'.",
"move":"Μετακίνηση εισιτηρίου. Αυτό θα αλλάξει τον τύπο αυτού του εισιτηρίου.",
"rename":"Μετονομασία εισιτηρίου. Αυτό θα αλλάξει το όνομα του καναλιού αυτού του εισιτηρίου.",
"claim":"Αιτηματοποίηση εισιτηρίου. Με αυτό, μπορείτε να ενημερώσετε την ομάδα σας ότι το χειρίζεστε.",
"unclaim":"Ακύρωση αιτηματοποίησης εισιτηρίου. Με αυτό, μπορείτε να ενημερώσετε την ομάδα σας ότι το εισιτήριο είναι ελεύθερο ξανά.",
"add":"Προσθήκη χρήστη σε εισιτήριο. Αυτό θα επιτρέψει στον χρήστη να διαβάζει και να γράφει σε αυτό το εισιτήριο.",
"remove":"Αφαίρεση χρήστη από εισιτήριο. Αυτό θα αφαιρέσει τη δυνατότητα ανάγνωσης και εγγραφής για έναν χρήστη σε αυτό το εισιτήριο.",
"panel":"Δημιουργία μηνύματος με αναπτυσσόμενο μενού ή κουμπιά (για δημιουργία εισιτηρίου).",
"blacklistView":"Προβολή λίστας της τρέχουσας μαύρης λίστας.",
"blacklistAdd":"Προσθήκη χρήστη στη μαύρη λίστα.",
"blacklistRemove":"Αφαίρεση χρήστη από τη μαύρη λίστα.",
"blacklistGet":"Λήψη λεπτομερειών από έναν χρήστη στη μαύρη λίστα.",
"statsGlobal":"Προβολή παγκόσμιων στατιστικών.",
"statsTicket":"Προβολή στατιστικών ενός εισιτηρίου στον server.",
"statsUser":"Προβολή στατιστικών ενός χρήστη στον server.",
"statsReset":"Επαναφορά όλων των στατιστικών του bot (και έναρξη καταμέτρησης από το μηδέν).",
"autocloseDisable":"Απενεργοποίηση αυτόματου κλεισίματος σε αυτό το εισιτήριο.",
"autocloseEnable":"Ενεργοποίηση αυτόματου κλεισίματος σε αυτό το εισιτήριο.",
"autodeleteDisable":"Απενεργοποίηση αυτόματης διαγραφής σε αυτό το εισιτήριο.",
"autodeleteEnable":"Ενεργοποίηση αυτόματης διαγραφής σε αυτό το εισιτήριο.",
"categories":{
"general":"Γενικές Εντολές",
"basicTicket":"Βασικές Εντολές Ticket",
"advancedTicket":"Προχωρημένες Εντολές Ticket",
"userTicket":"Εντολές Ticket Χρήστη",
"admin":"Εντολές Διαχειριστή",
"advanced":"Προχωρημένες Εντολές",
"extra":"Επιπλέον Εντολές"
}
},
"stats":{
"scopes":{
"global": "Παγκόσμια Στατιστικά",
"system": "Στατιστικά Συστήματος",
"user": "Στατιστικά Χρήστη",
"ticket": "Στατιστικά Εισιτηρίου",
"participants": "Συμμετέχοντες"
"global":"Παγκόσμια Στατιστικά",
"system":"Στατιστικά Συστήματος",
"user":"Στατιστικά Χρήστη",
"ticket":"Στατιστικά Εισιτηρίου",
"participants":"Συμμετέχοντες",
"messages":"Μηνύματα"
},
"properties":{
"ticketsCreated": "Εισιτήρια Δημιουργήθηκαν",
"ticketsClosed": "Εισιτήρια Κλείσαν",
"ticketsDeleted": "Εισιτήρια Διαγράφηκαν",
"ticketsReopened": "Εισιτήρια Επαναφέρθηκαν",
"ticketsAutoclosed": "Εισιτήρια Αυτόματα Κλείσαν",
"ticketsClaimed": "Εισιτήρια Αιτηματοποιήθηκαν",
"ticketsPinned": "Εισιτήρια Καρφιτσώθηκαν",
"ticketsMoved": "Εισιτήρια Μετακινήθηκαν",
"usersBlacklisted": "Χρήστες στη Μαύρη Λίστα",
"transcriptsCreated": "Μεταγραφές Δημιουργήθηκαν"
"ticketsCreated":"Εισιτήρια Δημιουργήθηκαν",
"ticketsClosed":"Εισιτήρια Κλείσαν",
"ticketsDeleted":"Εισιτήρια Διαγράφηκαν",
"ticketsReopened":"Εισιτήρια Επαναφέρθηκαν",
"ticketsAutoclosed":"Εισιτήρια Αυτόματα Κλείσαν",
"ticketsClaimed":"Εισιτήρια Αιτηματοποιήθηκαν",
"ticketsPinned":"Εισιτήρια Καρφιτσώθηκαν",
"ticketsMoved":"Εισιτήρια Μετακινήθηκαν",
"usersBlacklisted":"Χρήστες στη Μαύρη Λίστα",
"transcriptsCreated":"Μεταγραφές Δημιουργήθηκαν",
"ticketsAutodeleted":"Tickets Αυτόματης Διαγραφής",
"ticketsTransferred":"Tickets Μεταφερμένα",
"ticketVolume":"Όγκος Tickets",
"averageTickets":"Μέσος Όρος Tickets/Χρήστη",
"currentTickets":"Τρέχοντα Tickets",
"age":"Ηλικία Ticket",
"responseTime":"Χρόνος Απόκρισης",
"resolutionTime":"Χρόνος Επίλυσης",
"createdOn":"Δημιουργήθηκε Στις",
"createdBy":"Δημιουργήθηκε Από",
"closedOn":"Έκλεισε Στις",
"closedBy":"Έκλεισε Από",
"claimedOn":"Διεκδικήθηκε Στις",
"claimedBy":"Διεκδικήθηκε Από",
"pinnedOn":"Καρφιτσώθηκε Στις",
"pinnedBy":"Καρφιτσώθηκε Από",
"deletedOn":"Διαγράφηκε Στις",
"deletedBy":"Διαγράφηκε Από"
},
"roles":{
"developer":"Developer",
"serverOwner":"Ιδιοκτήτης Server",
"serverAdmin":"Διαχειριστής Server",
"moderator":"Ομάδα Moderators",
"support":"Ομάδα Υποστήριξης",
"member":"Μέλος"
}
},
"panel":{
"selectTicket":"Επιλέξτε το ticket σας",
"selectRole":"Επιλέξτε τον ρόλο σας",
"selectOption":"Επιλέξτε την επιλογή σας"
},
"priorities":{
"urgent":"Επείγον",
"veryHigh":"Πολύ Υψηλή",
"high":"Υψηλή",
"normal":"Κανονική",
"low":"Χαμηλή",
"veryLow":"Πολύ Χαμηλή",
"none":"Καμία"
}
}
+2 -2
View File
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["challenger_nova"],
"lastedited":"09/11/2025",
"lastedited":"03/12/2025",
"language":"Hindi",
"automated":false
},
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["Kornel0706"],
"lastedited":"22/08/2024",
"language":"Hungarian",
+2 -2
View File
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["erxg"],
"lastedited":"09/11/2025",
"lastedited":"03/12/2025",
"language":"Indonesian",
"automated":false
},
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["fraden1mvp."],
"lastedited":"08/10/2024",
"language":"Italian",
+227 -91
View File
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"translators":["HanumeshGupta"],
"lastedited":"19/06/2025",
"otversion":"v4.1.2",
"translators":["HanumeshGupta","ChatGPT"],
"lastedited":"03/12/2025",
"language":"Japanese",
"automated":true
},
@@ -12,78 +12,95 @@
"headerOpenTicket":"チケットを開く",
"typeWarning":"[警告]",
"typeInfo":"[情報]",
"headerConfigChecker": "コンフィグチェッカー",
"headerDescription": "設定ファイルのエラーをチェック!",
"footerError": "{0}が修正されるまでボットは起動しません!",
"footerWarning": "起動前にすべての{0}を修正することを推奨します!",
"footerSupport": "サポート: {0} - ドキュメント: {1}",
"compactInformation": "詳細は{0}を使用してください!",
"dataPath": "パス",
"dataDocs": "ドキュメント",
"dataMessages": "メッセージ"
"headerConfigChecker":"コンフィグチェッカー",
"headerDescription":"設定ファイルのエラーをチェック!",
"footerError":"{0}が修正されるまでボットは起動しません!",
"footerWarning":"起動前にすべての{0}を修正することを推奨します!",
"footerSupport":"サポート: {0} - ドキュメント: {1}",
"compactInformation":"詳細は{0}を使用してください!",
"dataPath":"パス",
"dataDocs":"ドキュメント",
"dataMessages":"メッセージ"
},
"messages":{
"stringTooShort": "この文字列は{0}文字より短くできません!",
"stringTooLong": "この文字列は{0}文字より長くできません!",
"stringLengthInvalid": "この文字列は{0}文字でなければなりません!",
"stringStartsWith": "この文字列は「{0}」で始まる必要があります!",
"stringEndsWith": "この文字列は「{0}」で終わる必要があります!",
"stringContains": "この文字列には「{0}」が含まれている必要があります!",
"stringChoices": "この文字列は次のいずれかの値でなければなりません: {0}!",
"stringRegex": "この文字列は無効です!",
"numberTooShort": "この数値は{0}桁より短くできません!",
"numberTooLong": "この数値は{0}桁より長くできません!",
"numberLengthInvalid": "この数値は{0}桁でなければなりません!",
"numberTooSmall": "この数値は{0}以上でなければなりません!",
"numberTooLarge": "この数値は{0}以下でなければなりません!",
"numberNotEqual": "この数値は{0}でなければなりません!",
"numberStep": "この数値は{0}の倍数でなければなりません!",
"numberStepOffset": "この数値は{1}から始まる{0}の倍数でなければなりません!",
"numberStartsWith": "この数値は「{0}」で始まる必要があります!",
"numberEndsWith": "この数値は「{0}」で終わる必要があります!",
"numberContains": "この数値には「{0}」が含まれている必要があります!",
"numberChoices": "この数値は次のいずれかの値でなければなりません: {0}!",
"numberFloat": "この数値は小数にできません!",
"numberNegative": "この数値は負の値にできません!",
"numberPositive": "この数値は正の値にできません!",
"numberZero": "この数値はゼロにできません!",
"booleanTrue": "このブール値はtrueにできません!",
"booleanFalse": "このブール値はfalseにできません!",
"arrayEmptyDisabled": "この配列を空にすることは許可されていません!",
"arrayEmptyRequired": "この配列は空でなければなりません!",
"arrayTooShort": "この配列の長さは少なくとも{0}でなければなりません!",
"arrayTooLong": "この配列の長さは最大{0}でなければなりません!",
"arrayLengthInvalid": "この配列の長さは{0}でなければなりません!",
"arrayInvalidTypes": "この配列に含めることができる型は次のみです: {0}!",
"arrayDouble": "この配列では同じ値を2回使用できません!",
"discordInvalidId": "これは無効なDiscordの{0}IDです!",
"discordInvalidIdOptions": "これは無効なDiscordの{0}IDです! 代わりに次のいずれかを使用できます: {1}!",
"discordInvalidToken": "これは無効なDiscordトークンです(構文的に)!",
"colorInvalid": "これは無効なHEXカラーコードです!",
"emojiTooShort": "この文字列には少なくとも{0}個の絵文字が必要です!",
"emojiTooLong": "この文字列には最大{0}個の絵文字しか含められません!",
"emojiCustom": "この絵文字はDiscordのカスタム絵文字にできません!",
"emojiInvalid": "これは無効な絵文字です!",
"urlInvalid": "このURLは無効です!",
"urlInvalidHttp": "This url can only use the https:// protocol!",
"urlInvalidProtocol": "This url can only use the http:// & https:// protocols!",
"urlInvalidHostname": "このURLのホスト名は許可されていません!",
"urlInvalidExtension": "このURLの拡張子が無効です! 次のいずれかを選択してください: {0}!",
"urlInvalidPath": "このURLのパスが無効です!",
"idNotUnique": "このIDは一意ではありません。別のIDを使用してください!",
"idNonExistent": "ID「{0}」は存在しません!",
"invalidType": "このプロパティは{0}型でなければなりません!",
"propertyMissing": "このオブジェクトにはプロパティ「{0}」がありません!",
"propertyOptional": "このオブジェクトではプロパティ「{0}」はオプションです!",
"objectDisabled": "このオブジェクトは無効です。{0}を使用して有効にしてください!",
"nullInvalid": "このプロパティはnullにできません!",
"switchInvalidType": "これは次のいずれかの型でなければなりません: {0}!",
"objectSwitchInvalid": "このオブジェクトは次のいずれかの型でなければなりません: {0}!",
"invalidLanguage": "これは無効な言語です!",
"invalidButton": "このボタンには少なくとも「{0}」または「{1}」が必要です!",
"unusedOption": "オプション「{0}」はどこでも使用されていません!",
"unusedQuestion": "質問「{0}」はどこでも使用されていません!",
"dropdownOption": "ドロップダウンが有効なパネルには「ticket」タイプのオプションのみ含めることができます!"
"stringTooShort":"この文字列は{0}文字より短くできません!",
"stringTooLong":"この文字列は{0}文字より長くできません!",
"stringLengthInvalid":"この文字列は{0}文字でなければなりません!",
"stringStartsWith":"この文字列は「{0}」で始まる必要があります!",
"stringEndsWith":"この文字列は「{0}」で終わる必要があります!",
"stringContains":"この文字列には「{0}」が含まれている必要があります!",
"stringChoices":"この文字列は次のいずれかの値でなければなりません: {0}!",
"stringRegex":"この文字列は無効です!",
"stringInvertedContains":"この文字列には {0} を含めることはできません!",
"stringLowercase":"この文字列はすべて小文字で書かなければなりません!",
"stringUppercase":"この文字列はすべて大文字で書かなければなりません!",
"stringSpecialCharacters":"この文字列には特殊文字を含めることはできません!(a-z、0-9、スペースのみ)",
"stringNoSpaces":"この文字列にはスペースを含めることはできません!",
"stringCapitalWord":"この文字列の各単語は大文字で始めることを推奨します!",
"stringCapitalSentence":"この文字列の一部の文が大文字で始まっていないようです!",
"stringPunctuation":"この文字列の文が句読点で終わっていないようです!",
"numberTooShort":"この数値は{0}桁より短くできません!",
"numberTooLong":"この数値は{0}桁より長くできません!",
"numberLengthInvalid":"この数値は{0}桁でなければなりません!",
"numberTooSmall":"この数値は{0}以上でなければなりません!",
"numberTooLarge":"この数値は{0}以下でなければなりません!",
"numberNotEqual":"この数値は{0}でなければなりません!",
"numberStep":"この数値は{0}の倍数でなければなりません!",
"numberStepOffset":"この数値は{1}から始まる{0}の倍数でなければなりません!",
"numberStartsWith":"この数値は「{0}」で始まる必要があります!",
"numberEndsWith":"この数値は「{0}」で終わる必要があります!",
"numberContains":"この数値には「{0}」が含まれている必要があります!",
"numberChoices":"この数値は次のいずれかの値でなければなりません: {0}!",
"numberFloat":"この数値は小数にできません!",
"numberNegative":"この数値は負の値にできません!",
"numberPositive":"この数値は正の値にできません!",
"numberZero":"この数値はゼロにできません!",
"numberNan":"この数値は NaN(Not A Number)であってはなりません!",
"numberInvertedContains":"この数値には {0} を含めることはできません!",
"booleanTrue":"このブール値はtrueにできません!",
"booleanFalse":"このブール値はfalseにできません!",
"arrayEmptyDisabled":"この配列を空にすることは許可されていません!",
"arrayEmptyRequired":"この配列は空でなければなりません!",
"arrayTooShort":"この配列の長さは少なくとも{0}でなければなりません!",
"arrayTooLong":"この配列の長さは最大{0}でなければなりません!",
"arrayLengthInvalid":"この配列の長さは{0}でなければなりません!",
"arrayInvalidTypes":"この配列に含めることができる型は次のみです: {0}!",
"arrayDouble":"この配列では同じ値を2回使用できません!",
"discordInvalidId":"これは無効なDiscordの{0}IDです!",
"discordInvalidIdOptions":"これは無効なDiscordの{0}IDです! 代わりに次のいずれかを使用できます: {1}!",
"discordInvalidToken":"これは無効なDiscordトークンです(構文的に)!",
"colorInvalid":"これは無効なHEXカラーコードです!",
"emojiTooShort":"この文字列には少なくとも{0}個の絵文字が必要です!",
"emojiTooLong":"この文字列には最大{0}個の絵文字しか含められません!",
"emojiCustom":"この絵文字はDiscordのカスタム絵文字にできません!",
"emojiInvalid":"これは無効な絵文字です!",
"urlInvalid":"このURLは無効です!",
"urlInvalidHttp":"This url can only use the https:// protocol!",
"urlInvalidProtocol":"This url can only use the http:// & https:// protocols!",
"urlInvalidHostname":"このURLのホスト名は許可されていません!",
"urlInvalidExtension":"このURLの拡張子が無効です! 次のいずれかを選択してください: {0}!",
"urlInvalidPath":"このURLのパスが無効です!",
"idNotUnique":"このIDは一意ではありません。別のIDを使用してください!",
"idNonExistent":"ID「{0}」は存在しません!",
"invalidType":"このプロパティは{0}型でなければなりません!",
"propertyMissing":"このオブジェクトにはプロパティ「{0}」がありません!",
"propertyOptional":"このオブジェクトではプロパティ「{0}」はオプションです!",
"objectDisabled":"このオブジェクトは無効です。{0}を使用して有効にしてください!",
"nullInvalid":"このプロパティはnullにできません!",
"switchInvalidType":"これは次のいずれかの型でなければなりません: {0}!",
"objectSwitchInvalid":"このオブジェクトは次のいずれかの型でなければなりません: {0}!",
"invalidLanguage":"これは無効な言語です!",
"invalidButton":"このボタンには少なくとも「{0}」または「{1}」が必要です!",
"unusedOption":"オプション「{0}」はどこでも使用されていません!",
"unusedQuestion":"質問「{0}」はどこでも使用されていません!",
"dropdownOption":"ドロップダウンが有効なパネルには「ticket」タイプのオプションのみ含めることができます!",
"customInvalidVersion":"設定ファイルに指定されたバージョンが一致しません! 設定を最新バージョンに更新してください!"
}
},
"actions":{
@@ -126,6 +143,7 @@
"blacklistAddDm":"ブラックリストに追加されました",
"blacklistRemoveDm":"ブラックリストから解除されました",
"clear":"チケットが一括削除されました",
"clearTickets":"チケットをクリア",
"roles":"ロールが更新されました",
"autoclose":"チケットが自動閉じされました",
@@ -133,7 +151,12 @@
"autocloseDisabled":"自動閉じが無効化されました",
"autodelete":"チケットが自動削除されました",
"autodeleteEnabled":"自動削除が有効化されました",
"autodeleteDisabled":"自動削除が無効化されました"
"autodeleteDisabled":"自動削除が無効化されました",
"topicSet":"トピックが変更されました",
"prioritySet":"優先度が変更されました",
"priorityGet":"チケットの優先度",
"transfer":"チケットが転送されました"
},
"descriptions":{
"create":"チケットが作成されました。下のボタンをクリックしてアクセスしてください!",
@@ -148,7 +171,7 @@
"move":"チケットが「{0}」に正常に移動されました!",
"add":"{0}がチケットに正常に追加されました!",
"remove":"{0}がチケットから正常に削除されました!",
"helpExplanation":"`<名前>` => 必須パラメータ\n`[名前]` => オプションパラメータ",
"statsReset":"ボットの統計が正常にリセットされました!",
"statsError":"チケット統計を表示できません!\n{0}はチケットではありません!",
@@ -161,7 +184,7 @@
"clearVerify":"複数のチケットを削除してもよろしいですか?\nこの操作は元に戻せません!",
"clearReady":"{0}件のチケットが正常に削除されました!",
"rolesEmpty":"更新されたロールはありません!",
"autocloseLeave":"作成者がサーバーを退出したため、このチケットは自動閉じされました!",
"autocloseTimeout":"このチケットは{0}時間以上非アクティブだったため自動閉じされました!",
"autodeleteLeave":"作成者がサーバーを退出したため、このチケットは自動削除されました!",
@@ -170,11 +193,16 @@
"autocloseDisabled":"このチケットで自動閉じが無効化されました!\n今後は自動的に閉じられません!",
"autodeleteEnabled":"このチケットで自動削除が有効化されました!\n{0}日間以上非アクティブの場合に自動的に削除されます!",
"autodeleteDisabled":"このチケットで自動削除が無効化されました!\n今後は自動的に削除されません!",
"ticketMessageLimit":"同時に作成できるチケットは{0}件までです!",
"ticketMessageAutoclose":"このチケットは{0}時間非アクティブの場合に自動閉じされます!",
"ticketMessageAutodelete":"このチケットは{0}日間非アクティブの場合に自動削除されます!",
"panelReady":"下にパネルが表示されます!\nこのメッセージは削除可能です!"
"panelReady":"パネルは次のメッセージで利用できます!\nこのメッセージは削除しても構いません!",
"topicSet":"チャンネルのトピックは {0} によって正常に変更されました!",
"prioritySet":"チケットの優先度は {1} により {0} に正常に変更されました!",
"priorityGet":"このチケットの現在の優先度は {0} です。",
"transfer":"チケットの所有権は {2} によって {0} から {1} に正常に転送されました!"
},
"modal":{
"closePlaceholder":"このチケットを閉じた理由は?",
@@ -209,12 +237,19 @@
"addDm":"サーバーであなたのチケットに{0}が追加されました!",
"removeLog":"{1}によって{0}がこのチケットから削除されました!",
"removeDm":"サーバーであなたのチケットから{0}が削除されました!",
"blacklistAddLog":"{1}によって{0}がブラックリストに追加されました!",
"blacklistRemoveLog":"{1}によって{0}がブラックリストから解除されました!",
"blacklistAddDm":"あなたはサーバーのブラックリストに追加されました!\n今後チケットを作成できなくなります!",
"blacklistRemoveDm":"あなたはサーバーのブラックリストから解除されました!\n再びチケットを作成できるようになりました!",
"clearLog":"{1}によって{0}件のチケットが削除されました!"
"clearLog":"{1}によって{0}件のチケットが削除されました!",
"transferLog":"このチケットの所有権は {2} によって {0} から {1} に転送されました!",
"transferDm":"あなたのチケットの所有権はサーバー内で {0} から {1} に転送されました!",
"prioritySetLog":"このチケットの優先度は {1} により {0} に変更されました!",
"prioritySetDm":"あなたのチケットの優先度はサーバー内で {0} に変更されました!",
"roleUpdateLog":"{0} がロールを更新しました!",
"roleUpdateDm":"サーバー内のあなたのロールが更新されました!"
}
},
"transcripts":{
@@ -223,7 +258,7 @@
"ready":"トランスクリプトが作成されました",
"textFileDescription":"これは削除されたチケットのテキストトランスクリプトです!",
"htmlProgress":"HTMLトランスクリプトを処理中です。お待ちください...",
"createdChannel":"サーバーに新しい{0}トランスクリプトが作成されました!",
"createdCreator":"あなたのチケットの{0}トランスクリプトが作成されました!",
"createdParticipant":"参加したチケットの{0}トランスクリプトが作成されました!",
@@ -235,7 +270,19 @@
"retry":"再試行",
"continue":"トランスクリプトなしで削除",
"backup":"バックアップトランスクリプトを作成",
"error":"トランスクリプトの作成中にエラーが発生しました。\nどうしますか?\n\nいずれかのボタンをクリックするまでチケットは削除されません。"
"error":"トランスクリプトの作成中にエラーが発生しました。\nどうしますか?\n\nいずれかのボタンをクリックするまでチケットは削除されません。",
"title":"トランスクリプトエラー"
},
"text":{
"messagesTitle":"メッセージ",
"embedTitle":"EMBED",
"fileTitle":"ファイル",
"fieldsTitle":"フィールド",
"reactionsTitle":"リアクション",
"statsTitle":"統計",
"emptyContent":"<内容は空です>",
"noTitle":"<タイトルなし>",
"noDesc":"<説明なし>"
}
},
"errors":{
@@ -251,10 +298,11 @@
"unknownPanel":"不明なパネル",
"notInGuild":"サーバー内にいません",
"channelRename":"チャンネル名を変更できません",
"busy":"チケットは使用中です"
"busy":"チケットは使用中です",
"permissionError":"権限エラー"
},
"descriptions":{
"askForInfo":"詳細はボットの所有者に問い合わせてください!",
"askForInfo":"詳細はボットの所有者に問い合わせてください!",
"askForInfoResolve":"数回試しても解決しない場合は、ボットの所有者に連絡してください。",
"internalError":"内部エラーのため、この{0}に応答できませんでした!",
"optionMissing":"このコマンドに必要なパラメータが不足しています!",
@@ -274,7 +322,10 @@
"notInGuild":"この{0}はDMでは動作しません!サーバー内で再試行してください!",
"channelRename":"Discordのレートリミットにより、現在チャンネル名を変更できません。10分以内に自動的に変更されます。",
"channelRenameSource":"エラーの原因:{0}",
"busy":"この{0}は使用できません!\nチケットは現在処理中です。\n\n数秒後にもう一度お試しください!"
"busy":"この{0}は使用できません!\nチケットは現在処理中です。\n\n数秒後にもう一度お試しください!",
"closeBeforeMessage":"ユーザーがメッセージを送信する前に、このチケットを閉じたり削除したりすることはできません。",
"closeBeforeAdminMessage":"チケット管理者またはサポートメンバーがメッセージを送信する前に、このチケットを閉じたり削除したりすることはできません。",
"unableToCreateTicket":"チケットを作成することはできません。"
},
"optionInvalidReasons":{
"stringRegex":"値がパターンに一致しません!",
@@ -325,7 +376,6 @@
"added":"追加済み",
"removed":"削除済み",
"filter":"フィルター",
"claimedBy":"{0}が引き受け",
"method":"方法",
"type":"タイプ",
"blacklisted":"ブラックリスト",
@@ -349,7 +399,27 @@
"status":"ステータス",
"claimed":"引き受け済み",
"pinned":"ピン留め済み",
"creationDate":"作成日時"
"creationDate":"作成日時",
"noone":"該当なし",
"open":"オープン",
"closed":"クローズ",
"priority":"優先度",
"participants":"参加者",
"yes":"はい",
"no":"いいえ",
"option":"オプション",
"topic":"トピック",
"uptime":"システム稼働時間",
"messages":"メッセージ",
"embeds":"埋め込み",
"files":"ファイル",
"components":"コンポーネント",
"cooldown":"クールダウン",
"maxTickets":"最大チケット数",
"admins":"管理者",
"roles":"ロール",
"size":"サイズ"
},
"lowercase":{
"text":"テキスト",
@@ -378,6 +448,7 @@
"unclaim":"チケットの引き受けを解除します。",
"pin":"チケットをピン留めします。",
"unpin":"チケットのピン留めを解除します。",
"move":"チケットを移動します。",
"moveId":"移動先のオプション識別子。",
"rename":"チケット名を変更します。",
@@ -386,6 +457,7 @@
"addUser":"追加するユーザー。",
"remove":"ユーザーをチケットから削除します。",
"removeUser":"削除するユーザー。",
"blacklist":"チケットブラックリストを管理します。",
"blacklistView":"現在のブラックリストを表示します。",
"blacklistAdd":"ユーザーをブラックリストに追加します。",
@@ -399,6 +471,7 @@
"statsUserUser":"表示するユーザー。",
"statsTicket":"サーバー内のチケット統計を表示します。",
"statsTicketTicket":"表示するチケット。",
"clear":"複数のチケットを同時に削除します。",
"clearFilter":"チケットを一括削除するフィルター。",
"clearFilters":{
@@ -411,6 +484,7 @@
"unpin":"ピン留め解除済み",
"autoclose":"自動閉じ済み"
},
"autoclose":"チケットの自動閉じを管理します。",
"autocloseDisable":"このチケットの自動閉じを無効にします。",
"autocloseEnable":"このチケットの自動閉じを有効にします。",
@@ -418,7 +492,19 @@
"autodelete":"チケットの自動削除を管理します。",
"autodeleteDisable":"このチケットの自動削除を無効にします。",
"autodeleteEnable":"このチケットの自動削除を有効にします。",
"autodeleteEnableTime":"チケットを自動削除する非アクティブ時間(日単位)。"
"autodeleteEnableTime":"チケットを自動削除する非アクティブ時間(日単位)。",
"topic":"チケットチャネルのトピックを管理します。",
"topicSet":"チケットチャネルのトピックを設定します。",
"topicValue":"チャンネルの新しいトピック。",
"topicList":"すべてのチケットをトピックと統計付きで一覧表示します。",
"priority":"チケットの優先度を管理します。",
"prioritySet":"チケットの優先度を設定します。",
"priorityValue":"チャンネルの優先度。",
"priorityGet":"チケットの優先度を取得します。",
"priorityList":"すべてのチケットを優先度ステータス付きで一覧表示します。",
"transfer":"チケットの所有権を別のユーザーに転送します。",
"transferUser":"転送先のユーザー。"
},
"helpMenu":{
"help":"利用可能なすべてのコマンドのリストを表示します。",
@@ -446,7 +532,16 @@
"autocloseDisable":"このチケットの自動閉じを無効にします。",
"autocloseEnable":"このチケットの自動閉じを有効にします。",
"autodeleteDisable":"このチケットの自動削除を無効にします。",
"autodeleteEnable":"このチケットの自動削除を有効にします。"
"autodeleteEnable":"このチケットの自動削除を有効にします。",
"categories":{
"general":"一般コマンド",
"basicTicket":"基本チケットコマンド",
"advancedTicket":"高度なチケットコマンド",
"userTicket":"ユーザーチケットコマンド",
"admin":"管理者コマンド",
"advanced":"高度なコマンド",
"extra":"追加コマンド"
}
},
"stats":{
"scopes":{
@@ -454,7 +549,8 @@
"system":"システム統計",
"user":"ユーザー統計",
"ticket":"チケット統計",
"participants":"参加者"
"participants":"参加者",
"messages":"メッセージ"
},
"properties":{
"ticketsCreated":"作成済みチケット",
@@ -466,7 +562,47 @@
"ticketsPinned":"ピン留め済みチケット",
"ticketsMoved":"移動済みチケット",
"usersBlacklisted":"ブラックリストユーザー",
"transcriptsCreated":"作成済みトランスクリプト"
"transcriptsCreated":"作成済みトランスクリプト",
"ticketsAutodeleted":"自動削除されたチケット",
"ticketsTransferred":"転送されたチケット",
"ticketVolume":"チケット量",
"averageTickets":"平均チケット数/ユーザー",
"currentTickets":"現在のチケット",
"age":"チケットの経過時間",
"responseTime":"応答時間",
"resolutionTime":"解決時間",
"createdOn":"作成日",
"createdBy":"作成者",
"closedOn":"クローズ日",
"closedBy":"クローズ者",
"claimedOn":"引き受け日",
"claimedBy":"引き受け者",
"pinnedOn":"ピン留め日",
"pinnedBy":"ピン留め者",
"deletedOn":"削除日",
"deletedBy":"削除者"
},
"roles":{
"developer":"開発者",
"serverOwner":"サーバーオーナー",
"serverAdmin":"サーバー管理者",
"moderator":"モデレーターチーム",
"support":"サポートチーム",
"member":"メンバー"
}
},
"panel":{
"selectTicket":"チケットを選択してください",
"selectRole":"ロールを選択してください",
"selectOption":"オプションを選択してください"
},
"priorities":{
"urgent":"緊急",
"veryHigh":"非常に高い",
"high":"高い",
"normal":"普通",
"low":"低い",
"veryLow":"非常に低い",
"none":"なし"
}
}
+549 -419
View File
File diff suppressed because it is too large Load Diff
+559 -416
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION": {
"otversion": "v4.1.0",
"otversion": "v4.1.2",
"translators": ["NoOneNook"],
"lastedited": "25/03/2025",
"language": "Latvian",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["TsgIndrius"],
"lastedited":"26/01/2025",
"language":"Lithuanian",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION": {
"otversion": "v4.1.0",
"otversion": "v4.1.2",
"translators": ["NoOneNook"],
"lastedited": "25/03/2025",
"language": "Norwegian",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["dysashop","zhavis"],
"lastedited":"28/05/2025",
"language":"Persian",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["DanoGlez"],
"lastedited":"28/01/2025",
"language":"Polish",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["quiradon"],
"lastedited":"20/08/2024",
"language":"Portuguese",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["SankeDev"],
"lastedited":"27/08/2024",
"language":"Romanian",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION": {
"otversion": "v4.1.0",
"otversion": "v4.1.2",
"translators": ["NoOneNook"],
"lastedited": "25/03/2025",
"language": "Russian",
File diff suppressed because it is too large Load Diff
+547 -417
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["Redactado","Josuens"],
"lastedited":"22/08/2024",
"language":"Spanish",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION": {
"otversion": "v4.1.0",
"otversion": "v4.1.2",
"translators": ["NoOneNook"],
"lastedited": "25/03/2025",
"language": "Svenska",
+563 -433
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1,8 +1,8 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["modshd"],
"lastedited":"09/11/2025",
"lastedited":"03/12/2025",
"language":"Thai",
"automated":false
},
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION": {
"otversion": "v4.1.0",
"otversion": "v4.1.2",
"translators": ["palestinian"],
"lastedited": "26/11/2024",
"language": "Turkish",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["Anderskiy"],
"lastedited":"31/08/2024",
"language":"Ukrainian",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"_TRANSLATION":{
"otversion":"v4.1.0",
"otversion":"v4.1.2",
"translators":["ngocdiep2006"],
"lastedited":"07/04/2025",
"language":"Vietnamese",
+5 -5
View File
@@ -1,7 +1,7 @@
{
"name": "open-ticket",
"author": "DJdj Development",
"version": "4.1.0",
"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",
@@ -25,14 +25,14 @@
"type": "commonjs",
"license": "GPL-3.0-only",
"dependencies": {
"@discordjs/rest": "^2.4.2",
"@discordjs/rest": "^2.6.0",
"@types/node": "^22.5.0",
"@types/terminal-kit": "^2.5.7",
"ansis": "^2.3.0",
"discord.js": "^14.22.1",
"ansis": "^4.2.0",
"discord.js": "^14.24.2",
"formatted-json-stringify": "^1.2.1",
"terminal-kit": "^3.1.2",
"typescript": "^5.5.4"
"typescript": "^5.9.3"
},
"repository": {
"type": "git",
+34 -70
View File
@@ -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")}))
+62 -140
View File
@@ -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")}))
+14 -34
View File
@@ -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}))
+16 -35
View File
@@ -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
+15 -34
View File
@@ -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
+13 -36
View File
@@ -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}))
+15 -34
View File
@@ -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}))
+11 -35
View File
@@ -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()
+19 -38
View File
@@ -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}))
}),
+16 -35
View File
@@ -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")}))
+12 -38
View File
@@ -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}))
+13 -34
View File
@@ -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}))
+13 -39
View File
@@ -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)
+15 -1
View File
@@ -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}))
+15 -34
View File
@@ -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
+14 -34
View File
@@ -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}))
+14 -34
View File
@@ -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}))
+15 -34
View File
@@ -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}))
+3 -2
View File
@@ -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)){
+26 -2
View File
@@ -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
+34 -77
View File
@@ -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
+15 -34
View File
@@ -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
+14 -34
View File
@@ -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}))
+15 -34
View File
@@ -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}))
+15 -34
View File
@@ -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}))
+3 -2
View File
@@ -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)
}
}
+2 -2
View File
@@ -133,7 +133,7 @@ export class ODMain {
constructor(){
this.versions = new ODVersionManager_Default()
this.versions.add(ODVersion.fromString("opendiscord:version","v4.1.0"))
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)
+4 -4
View File
@@ -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.0"})
else newConfig.headers = {"User-Agent":"OpenDiscordBots-OpenTicket/4.1.0"}
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.0"})
else newConfig.headers = {"User-Agent":"OpenDiscordBots-OpenTicket/4.1.0"}
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
}
+54 -3
View File
@@ -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<ODPermissionResult>
/**## 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<ODPermission> {
/**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<ODPermission> {
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<ODPermission> {
//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<ODPermission> {
//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<ODPermission> {
//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<ODPermissionCommandResult> {
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}
}
}
}
+1 -1
View File
@@ -147,7 +147,7 @@ export class ODPlugin extends ODManagerData {
if ((this.enabled && !this.crashed) || force){
try{
//import relative plugin directory path (works on windows & unix based systems)
const pluginPath = nodepath.join("../../../../plugins/",this.getStartFile())
const pluginPath = nodepath.join("../../../../plugins/",this.getStartFile()).replaceAll("\\","/")
await import(pluginPath)
debug.console.log("Plugin \""+this.id.value+"\" loaded successfully!","plugin")
this.executed = true
+14 -10
View File
@@ -417,7 +417,7 @@ export class ODCommandResponderInstance {
/**Defer this command. */
async defer(ephemeral:boolean){
if (this.type != "interaction" || !(this.interaction instanceof discord.ChatInputCommandInteraction)) return false
if (this.interaction.deferred) return false
if (this.interaction.deferred || this.interaction.replied) return false
const msgFlags: number[] = ephemeral ? [discord.MessageFlags.Ephemeral] : []
await this.interaction.deferReply({flags:msgFlags})
this.didReply = true
@@ -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
}
@@ -589,7 +590,7 @@ export class ODButtonResponderInstance {
}
/**Defer this button. */
async defer(type:"reply"|"update", ephemeral:boolean){
if (this.interaction.deferred) return false
if (this.interaction.deferred || this.interaction.replied) return false
if (type == "reply"){
const msgFlags: number[] = ephemeral ? [discord.MessageFlags.Ephemeral] : []
await this.interaction.deferReply({flags:msgFlags})
@@ -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
}
@@ -877,7 +879,7 @@ export class ODDropdownResponderInstance {
}
/**Defer this dropdown. */
async defer(type:"reply"|"update", ephemeral:boolean){
if (this.interaction.deferred) return false
if (this.interaction.deferred || this.interaction.replied) return false
if (type == "reply"){
const msgFlags: number[] = ephemeral ? [discord.MessageFlags.Ephemeral] : []
await this.interaction.deferReply({flags:msgFlags})
@@ -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
}
@@ -1096,7 +1099,7 @@ export class ODModalResponderInstance {
}
/**Defer this modal. */
async defer(type:"reply"|"update", ephemeral:boolean){
if (this.interaction.deferred) return false
if (this.interaction.deferred || this.interaction.replied) return false
if (type == "reply"){
const msgFlags: number[] = ephemeral ? [discord.MessageFlags.Ephemeral] : []
await this.interaction.deferReply({flags:msgFlags})
@@ -1251,7 +1254,7 @@ export class ODContextMenuResponderInstance {
}
/**Defer this context menu. */
async defer(type:"reply", ephemeral:boolean){
if (this.interaction.deferred) return false
if (this.interaction.deferred || this.interaction.replied) return false
if (type == "reply"){
const msgFlags: number[] = ephemeral ? [discord.MessageFlags.Ephemeral] : []
await this.interaction.deferReply({flags:msgFlags})
@@ -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)
}
}
+9 -1
View File
@@ -357,13 +357,21 @@ export class ODOptionSuffixManager extends ODManager<ODOptionSuffix> {
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`
+6 -1
View File
@@ -575,6 +575,11 @@ async function renderQuickSetupTicketCount(backFn:() => api.ODPromiseVoid){
"3️⃣ 3 Ticket Options",
"4️⃣ 4 Ticket Options",
"5️⃣ 5 Ticket Options",
"6️⃣ 6 Ticket Options",
"7️⃣ 7 Ticket Options",
"8️⃣ 8 Ticket Options",
"9️⃣ 9 Ticket Options",
"🔟 10 Ticket Options",
],{
leftPadding:"> ",
style:terminal.cyan,
@@ -1208,7 +1213,7 @@ async function saveQuickSetupConfig(){
_INFO:{
support:"https://otdocs.dj-dj.be",
discord:"https://discord.dj-dj.be",
version:"open-ticket-v4.0.6"
version:"open-ticket-"+opendiscord.versions.get("opendiscord:version").toString()
},
token:quickSetupStorage.client?.token ?? "<unknown-token>",
+2
View File
@@ -47,8 +47,10 @@ opendiscord.debug.debug("Using Node.js "+process.version+"!")
try{
const packageJson = JSON.parse(fs.readFileSync("./package.json").toString())
opendiscord.debug.debug("Using discord.js "+packageJson.dependencies["discord.js"]+"!")
opendiscord.debug.debug("Using @discordjs/rest "+packageJson.dependencies["@discordjs/rest"]+"!")
opendiscord.debug.debug("Using ansis "+packageJson.dependencies["ansis"]+"!")
opendiscord.debug.debug("Using formatted-json-stringify "+packageJson.dependencies["formatted-json-stringify"]+"!")
opendiscord.debug.debug("Using terminal-kit "+packageJson.dependencies["terminal-kit"]+"!")
opendiscord.debug.debug("Using typescript "+packageJson.dependencies["typescript"]+"!")
}catch{
opendiscord.debug.debug("Failed to fetch module versions!")
+8 -1
View File
@@ -134,5 +134,12 @@ export const migrations = [
ticketDatabase.set("opendiscord:ticket",ticket.key,ticketData)
}
})
}),
//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 () => {}),
]
+1 -1
View File
@@ -20,7 +20,7 @@
INFORMATION:
============
Open Ticket v4.1.0 - © DJdj Development
Open Ticket v4.1.2 - © DJdj Development
support us: https://github.com/sponsors/DJj123dj
discord: https://discord.dj-dj.be
+25 -5
View File
@@ -1,13 +1,33 @@
[
{
"message":{
"title":"Open Ticket v4.0",
"title":"Update Required",
"titleColor":"red",
"description":"Open Ticket v4.0 has officially been released! Please give our project a star to help us grow!",
"description":"This version of Open Ticket will soon be deprecated, please update to v4.1 or higher!",
"descriptionColor":"normal"
},
"active":{
"versions":["4.0.0","4.0.1","4.0.2","4.0.3","4.0.4"],
"versions":["4.0.0","4.0.1","4.0.2","4.0.3","4.0.4","4.0.5"],
"languages":[],
"allLanguages":true,
"usingPlugins":true,
"notUsingPlugins":true,
"usingSlashCommands":true,
"notUsingSlashCommands":true,
"notUsingTranscripts":true,
"usingTextTranscripts":true,
"usingHtmlTranscripts":true
}
},
{
"message":{
"title":"Open Ticket v4.1",
"titleColor":"green",
"description":"Open Ticket v4.1 has officially been released! Go check it out!",
"descriptionColor":"normal"
},
"active":{
"versions":["4.0.0","4.0.1","4.0.2","4.0.3","4.0.4","4.0.5","4.0.6","4.0.7"],
"languages":[],
"allLanguages":true,
"usingPlugins":true,
@@ -27,7 +47,7 @@
"descriptionColor":"normal"
},
"active":{
"versions":["4.0.0","4.0.1","4.0.2","4.0.3","4.0.4","4.0.5","4.0.6","4.0.7","4.0.8","4.0.9","4.1.0"],
"versions":["4.0.0","4.0.1","4.0.2","4.0.3","4.0.4","4.0.5","4.0.6","4.0.7","4.1.0","4.1.1","4.1.2","4.1.3","4.1.4","4.1.5"],
"languages":[],
"allLanguages":true,
"usingPlugins":true,
@@ -47,7 +67,7 @@
"descriptionColor":"normal"
},
"active":{
"versions":["4.0.0","4.0.1","4.0.2","4.0.3","4.0.4","4.0.5","4.0.6","4.0.7","4.0.8","4.0.9","4.1.0"],
"versions":["4.0.0","4.0.1","4.0.2","4.0.3","4.0.4","4.0.5","4.0.6","4.0.7","4.1.0","4.1.1","4.1.2","4.1.3","4.1.4","4.1.5"],
"languages":[],
"allLanguages":true,
"usingPlugins":true,