Compare commits

..
21 Commits
Author SHA1 Message Date
Jasper a12f60136a Open Ticket v4.0.6
Open Ticket v4.0.6
2025-05-31 11:01:13 +02:00
DJj123dj 1d05d04bf2 Updated all versions to v4.0.6 2025-05-31 10:51:29 +02:00
DJj123dj ff6a9eefaf Update package.json 2025-05-31 10:43:04 +02:00
DJj123dj aa9004d7e2 Compare/diff persian language + translation improv 2025-05-31 10:42:18 +02:00
Jasper 7e1fe78a26 Merge pull request #172 from zhavis/development (Persian translation)
Create persian.json
2025-05-31 10:29:05 +02:00
DJj123dj 675571b8d8 Added recommended hostings to README.md
Want to advertise your hosting too? Contact us in our discord server.
2025-05-31 10:24:32 +02:00
DJj123dj 48f0d65fad Fixed slash cmd registration bug
This was caused by already registered commands of a different type than 'chatInput'.
2025-05-31 10:24:04 +02:00
zhavihosseini a54422b222 Create persian.json 2025-05-28 07:11:03 +03:30
Jasper b965a4f5a2 Open Ticket v4.0.5
Open Ticket v4.0.5
2025-05-03 21:09:55 +02:00
DJj123dj 0d8dd8cd17 Updated all versions to v4.0.5 2025-05-03 21:02:47 +02:00
DJj123dj 6ac432cadc Fix: Panels now require at least 1 option. 2025-05-03 20:59:22 +02:00
DJj123dj dec6c7598b Improv: Decreased QuickBuilder boilerplate params 2025-05-03 20:58:50 +02:00
DJj123dj 2de2e3cd9b Fixed option suffixes with ot-sqlite-database 2025-05-03 18:34:10 +02:00
Jasper 5d0776a9b9 Open Ticket v4.0.4
Open Ticket v4.0.4
2025-05-01 14:10:55 +02:00
Jasper 7bf843c851 Dev v4.0.4
Dev v4.0.4
2025-05-01 14:05:56 +02:00
DJj123dj 3e3ea9263f Updated all versions to v4.0.4 2025-05-01 14:05:06 +02:00
DJj123dj bb5c3e9c8d Support for HTML Transcripts v2.1 2025-05-01 13:56:38 +02:00
Jasper 94f32674cb Open Ticket v4.0.3
Open Ticket v4.0.3
2025-04-28 18:27:48 +02:00
DJj123dj e8eb52e00b #155 : Fixed reply on creation when disabled.
Fixed a bug that caused the bot to send a partial ephemeral message while "replyOnTicketCreation" was disabled.
2025-04-28 18:22:54 +02:00
DJj123dj 4efa165949 Updated all versions to v4.0.3 2025-04-27 18:21:56 +02:00
DJj123dj 4c3e4ef9a5 Fixed bug due to discord.js new components 2025-04-27 18:17:38 +02:00
60 changed files with 1222 additions and 360 deletions
+13 -1
View File
@@ -2,7 +2,7 @@
<img src="https://apis.dj-dj.be/cdn/openticket/logo.png" alt="Open Ticket Logo" width="500px"> <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) [![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.0.2-brightgreen.svg?style=flat-square)](https://github.com/open-discord-bots/open-ticket/releases/tag/v4.0.2) [![version](https://img.shields.io/badge/version-4.0.6-brightgreen.svg?style=flat-square)](https://github.com/open-discord-bots/open-ticket/releases/tag/v4.0.6)
[![Sponsor DJj123dj](https://img.shields.io/badge/sponsor-DJj123dj-ea4aaa?style=flat-square&logo=githubsponsors)](https://github.com/sponsors/DJj123dj) [![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) [![Open Ticket supports Pterodactyl Eggs!](https://img.shields.io/badge/pterodactyl-supported-10539F?style=flat-square&logo=pterodactyl)](.eggs/README.md)
@@ -20,6 +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) [**`openticket-egg-main.json` (Recommended)**](openticket-egg-main.json)
- This egg will use the `main` branch of Open Ticket. - This egg will use the `main` branch of Open Ticket.
[**`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) [**`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. - This egg will always use Open Ticket `v4.0.2`. Open Ticket updates will not have an effect on this egg.
+62
View File
@@ -0,0 +1,62 @@
{
"_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PTERODACTYL PANEL - PTERODACTYL.IO",
"meta": {
"version": "PTDL_v2",
"update_url": null
},
"exported_at": "2025-03-16T18:10:18+01:00",
"name": "Open Ticket (v4.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
@@ -0,0 +1,62 @@
{
"_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PTERODACTYL PANEL - PTERODACTYL.IO",
"meta": {
"version": "PTDL_v2",
"update_url": null
},
"exported_at": "2025-03-16T18:10:18+01:00",
"name": "Open Ticket (v4.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
@@ -0,0 +1,62 @@
{
"_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PTERODACTYL PANEL - PTERODACTYL.IO",
"meta": {
"version": "PTDL_v2",
"update_url": null
},
"exported_at": "2025-03-16T18:10:18+01:00",
"name": "Open Ticket (v4.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
@@ -0,0 +1,62 @@
{
"_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PTERODACTYL PANEL - PTERODACTYL.IO",
"meta": {
"version": "PTDL_v2",
"update_url": null
},
"exported_at": "2025-03-16T18:10:18+01:00",
"name": "Open Ticket (v4.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"
}
]
}
+1 -1
View File
@@ -1,7 +1,7 @@
# Contributing Guidelines # Contributing Guidelines
<img src="https://apis.dj-dj.be/cdn/openticket/logo.png" alt="Open Ticket Logo" width="500px"> <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.0.2-brightgreen.svg?style=flat-square)](https://github.com/open-discord-bots/open-ticket/releases/tag/v4.0.2) [![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.0.6-brightgreen.svg?style=flat-square)](https://github.com/open-discord-bots/open-ticket/releases/tag/v4.0.6) [![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> These are the Contributing Guidelines of Open Ticket!<br>
Here you can find everything you need to know about contributing to Open Ticket.<br> Here you can find everything you need to know about contributing to Open Ticket.<br>
+10 -8
View File
@@ -1,7 +1,7 @@
# Security Policy # Security Policy
<img src="https://apis.dj-dj.be/cdn/openticket/logo.png" alt="Open Ticket Logo" width="500px"> <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.0.1-brightgreen.svg?style=flat-square)](https://github.com/open-discord-bots/open-ticket/releases/tag/v4.0.1) [![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.0.4-brightgreen.svg?style=flat-square)](https://github.com/open-discord-bots/open-ticket/releases/tag/v4.0.4) [![Sponsor DJj123dj](https://img.shields.io/badge/sponsor-DJj123dj-ea4aaa?style=flat-square&logo=githubsponsors)](https://github.com/sponsors/DJj123dj)
This is the Security Policy of Open Ticket!<br> This is the Security Policy of Open Ticket!<br>
Here you can find a list of all supported & deprecated versions of the bot.<br> Here you can find a list of all supported & deprecated versions of the bot.<br>
@@ -18,14 +18,16 @@ This list will be updated on every release.
- ❌ Fully Deprecated - ❌ Fully Deprecated
| Version | Supported | Notes | | Version | Supported | Notes |
|------------|-----------|--------------------------------| |------------|-----------|------------------------------------------|
| 4.1.0 | 🟦 | | | 4.1.0 | 🟦 | |
| 4.0.2 | ✅ | | | 4.0.6 | ✅ | |
| 4.0.1 | ✅ | | | 4.0.5 | ✅ | |
| 4.0.0 | ✅ | | | 4.0.4 | ✅ | Supported until July 2025 (LTS) |
| 3.5.9 | 🚧 | Supported until May 2025 (LTS) | | 4.0.3 | 🚧 | Transcripts v2.0 (Offline August 2025) |
| 3.5.8 | 🟧 | Documentation Only | | 4.0.2 | 🟧 | Documentation Only (discord.js bug) |
| < 3.5.8 | ❌ | | | 4.0.1 | 🟧 | Documentation Only |
| 4.0.0 | 🟧 | Documentation Only |
| < 4.0.0 | ❌ | |
### 🕷️ Reporting Vulnerabilities ### 🕷️ Reporting Vulnerabilities
You can report vulnerabilities, errors & bugs using one of the following methods: You can report vulnerabilities, errors & bugs using one of the following methods:
+13 -6
View File
@@ -8,7 +8,7 @@
<br>Powered By<br> <br>Powered By<br>
<img src="https://apis.dj-dj.be/cdn/opendiscord/logo.png" alt="Open Ticket" width="170px"><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://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.0.2"><img alt="Open Ticket Version" src="https://img.shields.io/badge/version-4.0.2-brightgreen.svg?style=flat-square"></img></a> <a href="https://github.com/open-discord-bots/open-ticket/releases/tag/v4.0.6"><img alt="Open Ticket Version" src="https://img.shields.io/badge/version-4.0.6-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://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://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> <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>
@@ -20,7 +20,7 @@
<p align="center"> <p align="center">
Open Ticket is the most advanced & customisable discord ticket bot that you will ever find! You can customise up to 300+ variables! This includes <code>Html Transcripts</code>, <code>Advanced Plugins</code>, <code>Custom Embeds</code>, <code>Questions/Modals</code>, <code>Stats</code> & more! Open Ticket is the most advanced & customisable discord ticket bot that you will ever find! You can customise up to 300+ variables! This includes <code>Html Transcripts</code>, <code>Advanced Plugins</code>, <code>Custom Embeds</code>, <code>Questions/Modals</code>, <code>Stats</code> & more!
You're also able to customise every little aspect of the bot! From embeds to transcripts. Open Ticket is also translated in more than <code>27 Languages</code>! If you need any help, feel free to join our <a href="https://discord.dj-dj.be">discord server</a>! You're also able to customise every little aspect of the bot! From embeds to transcripts. Open Ticket is also translated in more than <code>28 Languages</code>! If you need any help, feel free to join our <a href="https://discord.dj-dj.be">discord server</a>!
</p> </p>
<p align="center"><b>⭐️ Help us grow by giving a star! ⭐️</b></p> <p align="center"><b>⭐️ Help us grow by giving a star! ⭐️</b></p>
@@ -32,7 +32,7 @@ You're also able to customise every little aspect of the bot! From embeds to tra
- **📈 scalable** - Open Ticket is made to handle huge servers! (Already tested in **servers with 100k members**) - **📈 scalable** - Open Ticket is made to handle huge servers! (Already tested in **servers with 100k members**)
- **📄 HTML transcripts** - Make use of the most customisable, beautiful and easy-to-use HTML Transcripts! - **📄 HTML transcripts** - Make use of the most customisable, beautiful and easy-to-use HTML Transcripts!
- **✅ ticket actions** - Close, Reopen, Delete, Claim, Pin, Rename & Move all your tickets! - **✅ ticket actions** - Close, Reopen, Delete, Claim, Pin, Rename & Move all your tickets!
- **🇬🇧 translation** - Open Ticket has been translated in more than **27 languages** by our community! - **🇬🇧 translation** - Open Ticket has been translated in more than **28 languages** by our community!
- **🎨 customisation** - Open Ticket has been created around customisation, everything can be customised! - **🎨 customisation** - Open Ticket has been created around customisation, everything can be customised!
- **🖥️ interactions** - The bot has full support for Buttons, Dropdowns, Slash Commands and Modals! - **🖥️ interactions** - The bot has full support for Buttons, Dropdowns, Slash Commands and Modals!
- **∞ unlimited** - Create an infinite amount of tickets & panels! - **∞ unlimited** - Create an infinite amount of tickets & panels!
@@ -68,10 +68,10 @@ A big thanks to all our sponsors! Without them, it wouldn't be possible to creat
<table> <table>
<tr> <tr>
<td><img src="https://github.com/roppl3r.png" alt="Profile Picture" width="100px"></td> <td><img src="https://github.com/guillee3.png" alt="Profile Picture" width="100px"></td>
</tr> </tr>
<tr> <tr>
<td align="center"><a href="https://github.com/roppl3r"><b>roppl3r</b></a></td> <td align="center"><a href="https://github.com/guillee3"><b>guillee3</b></a></td>
</tr> </tr>
</table> </table>
@@ -93,6 +93,13 @@ A big thanks to all our sponsors! Without them, it wouldn't be possible to creat
> - Fix these errors and restart the bot. > - Fix these errors and restart the bot.
> 6. Enjoy using Open Ticket! > 6. Enjoy using Open Ticket!
> ### [📔 Visit Documentation](https://otdocs.dj-dj.be) > ### [📔 Visit Documentation](https://otdocs.dj-dj.be)
>
> ### 🖥️ Recommended Hostings
> - [⭐ **Peakhosting.nl**](https://peakhosting.nl/) - Official support for Open Ticket pterodactyl eggs.
> - **Any Pterodactyl-Based Panel** - Easy installation & configuration.
> - **A Virtual Private Server (VPS)** - Extra customisation & more stability. Recommended for large servers.
>
> *❤️ Want to display your hosting here? Contact us in our [Discord server](https://discord.dj-dj.be)!*
## 📸 Preview ## 📸 Preview
<img alt="An example of a panel." src="https://apis.dj-dj.be/cdn/openticket/preview-v4/panel-examples.png"> <img alt="An example of a panel." src="https://apis.dj-dj.be/cdn/openticket/preview-v4/panel-examples.png">
@@ -147,6 +154,7 @@ Without our translators, it wouldn't be possible to translate Open Ticket in so
|🟢 |🇵🇱 Polish |danoglez | |🟢 |🇵🇱 Polish |danoglez |
|🟢 |🇳🇴 Norwegian |NoOneNook | |🟢 |🇳🇴 Norwegian |NoOneNook |
|🟢 |🇸🇪 Swedish |NoOneNook | |🟢 |🇸🇪 Swedish |NoOneNook |
|🟢 |🇮🇷 Persian |dysashop & zhavis |
|🤖 |🇪🇪 Estonian |iamnotmega | |🤖 |🇪🇪 Estonian |iamnotmega |
|🤖 |🇫🇮 Finnish |iamnotmega | |🤖 |🇫🇮 Finnish |iamnotmega |
|🤖 |🇷🇺 Russian |NoOneNook | |🤖 |🇷🇺 Russian |NoOneNook |
@@ -159,7 +167,6 @@ Without our translators, it wouldn't be possible to translate Open Ticket in so
|🔴 |🇸🇮 Slovenian |[⭐ Contribute!](.github/CONTRIBUTING.md)| |🔴 |🇸🇮 Slovenian |[⭐ Contribute!](.github/CONTRIBUTING.md)|
|🔴 |🇬🇷 Greek |[⭐ Contribute!](.github/CONTRIBUTING.md)| |🔴 |🇬🇷 Greek |[⭐ Contribute!](.github/CONTRIBUTING.md)|
|🔴 |❓ Kurdish |[⭐ Contribute!](.github/CONTRIBUTING.md)| |🔴 |❓ Kurdish |[⭐ Contribute!](.github/CONTRIBUTING.md)|
|🔴 |❓ Persian |[⭐ Contribute!](.github/CONTRIBUTING.md)|
## ⭐️ Star History ## ⭐️ Star History
Please give this repository a star if you like it. Please give this repository a star if you like it.
+1 -1
View File
@@ -2,7 +2,7 @@
"_INFO":{ "_INFO":{
"support":"https://otdocs.dj-dj.be", "support":"https://otdocs.dj-dj.be",
"discord":"https://discord.dj-dj.be", "discord":"https://discord.dj-dj.be",
"version":"open-ticket-v4.0.2" "version":"open-ticket-v4.0.6"
}, },
"token":"your bot token here! (or leave empty when using 'tokenFromENV')", "token":"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)", "image":"https://www.example.com/image.png (or leave empty)",
"thumbnail":"https://www.example.com/image.png (or leave empty)", "thumbnail":"https://www.example.com/image.png (or leave empty)",
"footer":"Open Ticket v4.0.2 (or leave empty)", "footer":"Open Ticket v4.0.6 (or leave empty)",
"fields":[ "fields":[
{"name":"field name","value":"field value","inline":false} {"name":"field name","value":"field value","inline":false}
], ],
+1 -1
View File
@@ -49,7 +49,7 @@
}, },
"favicon":{ "favicon":{
"enableCustomFavicon":false, "enableCustomFavicon":false,
"imageUrl":"https://transcripts.dj-dj.be/favicon.png" "imageUrl":"https://t.dj-dj.be/favicon.png"
} }
} }
} }
+1 -1
View File
@@ -14,7 +14,7 @@ process.argv.push(...flags)
██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║ ██║ ██║██║ ██╔═██╗ ██╔══╝ ██║ ██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║ ██║ ██║██║ ██╔═██╗ ██╔══╝ ██║
╚██████╔╝██║ ███████╗██║ ╚████║ ██║ ██║╚██████╗██║ ██╗███████╗ ██║ ╚██████╔╝██║ ███████╗██║ ╚████║ ██║ ██║╚██████╗██║ ██╗███████╗ ██║
╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═╝
v4.0.2 - Made by DJj123dj & Contributors v4.0.6 - Made by DJj123dj & Contributors
Discord: https://discord.dj-dj.be Discord: https://discord.dj-dj.be
Docs: https://otdocs.dj-dj.be Docs: https://otdocs.dj-dj.be
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION": { "_TRANSLATION": {
"otversion": "v4.0.2", "otversion": "v4.0.6",
"translators": ["palestinian"], "translators": ["palestinian"],
"lastedited": "06/12/2024", "lastedited": "06/12/2024",
"language": "Arabic", "language": "Arabic",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["guillee3"], "translators":["guillee3"],
"lastedited":"21/08/2024", "lastedited":"21/08/2024",
"language":"Catalan", "language":"Catalan",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["DJj123dj"], "translators":["DJj123dj"],
"lastedited":"21/08/2024", "lastedited":"21/08/2024",
"language":"Custom", "language":"Custom",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["spyeye_"], "translators":["spyeye_"],
"lastedited":"21/08/2024", "lastedited":"21/08/2024",
"language":"Czech", "language":"Czech",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["the_gamer"], "translators":["the_gamer"],
"lastedited":"26/09/2024", "lastedited":"26/09/2024",
"language":"Danish", "language":"Danish",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["DJj123dj"], "translators":["DJj123dj"],
"lastedited":"21/08/2024", "lastedited":"21/08/2024",
"language":"Dutch", "language":"Dutch",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["DJj123dj"], "translators":["DJj123dj"],
"lastedited":"21/08/2024", "lastedited":"21/08/2024",
"language":"English", "language":"English",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["iamnotmega","ChatGPT"], "translators":["iamnotmega","ChatGPT"],
"lastedited":"21/10/2024", "lastedited":"21/10/2024",
"language":"Estonian", "language":"Estonian",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["iamnotmega","ChatGPT"], "translators":["iamnotmega","ChatGPT"],
"lastedited":"21/10/2024", "lastedited":"21/10/2024",
"language":"Finnish", "language":"Finnish",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["guillee3"], "translators":["guillee3"],
"lastedited":"04/12/2024", "lastedited":"04/12/2024",
"language":"French", "language":"French",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["benzorich"], "translators":["benzorich"],
"lastedited":"06/10/2024", "lastedited":"06/10/2024",
"language":"German", "language":"German",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["an_developer"], "translators":["an_developer"],
"lastedited":"14/12/2024", "lastedited":"14/12/2024",
"language":"Hindi", "language":"Hindi",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["Kornel0706"], "translators":["Kornel0706"],
"lastedited":"22/08/2024", "lastedited":"22/08/2024",
"language":"Hungarian", "language":"Hungarian",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["erxg"], "translators":["erxg"],
"lastedited":"25/08/2024", "lastedited":"25/08/2024",
"language":"Indonesian", "language":"Indonesian",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["fraden1mvp."], "translators":["fraden1mvp."],
"lastedited":"08/10/2024", "lastedited":"08/10/2024",
"language":"Italian", "language":"Italian",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION": { "_TRANSLATION": {
"otversion": "v4.0.2", "otversion": "v4.0.6",
"translators": ["NoOneNook"], "translators": ["NoOneNook"],
"lastedited": "25/03/2025", "lastedited": "25/03/2025",
"language": "Latvian", "language": "Latvian",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["TsgIndrius"], "translators":["TsgIndrius"],
"lastedited":"26/01/2025", "lastedited":"26/01/2025",
"language":"Lithuanian", "language":"Lithuanian",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION": { "_TRANSLATION": {
"otversion": "v4.0.2", "otversion": "v4.0.6",
"translators": ["NoOneNook"], "translators": ["NoOneNook"],
"lastedited": "25/03/2025", "lastedited": "25/03/2025",
"language": "Norwegian", "language": "Norwegian",
+478
View File
@@ -0,0 +1,478 @@
{
"_TRANSLATION":{
"otversion":"v4.0.6",
"translators":["dysashop","zhavis"],
"lastedited":"28/05/2025",
"language":"Persian",
"automated":false
},
"checker":{
"system":{
"typeError":"[خطا]",
"headerOpenTicket":"بازکردن تیکت",
"typeWarning":"[اخطار]",
"typeInfo":"[اطلاعات]",
"headerConfigChecker":"جستجوگر پیکربندی",
"headerDescription":"برای خطاها فایل پیکربندی ( کانفیگ ) خود را چک کنید",
"footerError":"ربات تا تمام مدت شروع نمی شود {0}'s ثابت هستند!",
"footerWarning":"توصیه میشه همه رو تعمیر کنید {0}'s قبل از شروع کردن!",
"footerSupport":"پشتیبانی: {0} - اسناد: {1}",
"compactInformation":"استفاده کنید {0} برای اطلاعات بیشتر!",
"dataPath":"path",
"dataDocs":"docs",
"dataMessages":"message"
},
"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": "این عدد باید مضربی از {0} باشد و با {1} شروع شود!",
"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": "این آرایه نمی‌تواند مقادیر تکراری داشته باشد!",
"discordInvalidId": "این شناسه دیسکورد {0} نامعتبر است!",
"discordInvalidIdOptions": "این شناسه دیسکورد {0} نامعتبر است! می‌توانید از یکی از این موارد استفاده کنید: {1}!",
"discordInvalidToken": "این توکن دیسکورد از نظر ساختاری نامعتبر است!",
"colorInvalid": "این کد رنگ هگزادسیمال نامعتبر است!",
"emojiTooShort": "این رشته باید حداقل {0} ایموجی داشته باشد!",
"emojiTooLong": "این رشته باید حداکثر {0} ایموجی داشته باشد!",
"emojiCustom": "این ایموجی نمی‌تواند یک ایموجی سفارشی دیسکورد باشد!",
"emojiInvalid": "این ایموجی نامعتبر است!",
"urlInvalid": "این آدرس URL نامعتبر است!",
"urlInvalidHttp": "این آدرس URL فقط می‌تواند از پروتکل https:// استفاده کند!",
"urlInvalidProtocol": "این آدرس URL فقط می‌تواند از پروتکل‌های http:// و https:// استفاده کند!",
"urlInvalidHostname": "این آدرس URL دارای نام میزبان غیرمجازی است!",
"urlInvalidExtension": "این آدرس URL دارای پسوند نامعتبر است! یکی از موارد زیر را انتخاب کنید: {0}!",
"urlInvalidPath": "این آدرس URL دارای مسیر نامعتبر است!",
"idNotUnique": "این شناسه یکتا نیست، لطفاً از شناسه دیگری استفاده کنید!",
"idNonExistent": "شناسه {0} وجود ندارد!",
"invalidType": "این ویژگی باید از نوع {0} باشد!",
"propertyMissing": "ویژگی {0} در این شیء وجود ندارد!",
"propertyOptional": "ویژگی {0} در این شیء اختیاری است!",
"objectDisabled": "این شیء غیرفعال است، آن را با استفاده از {0} فعال کنید!",
"nullInvalid": "این ویژگی نمی‌تواند null باشد!",
"switchInvalidType": "این باید یکی از انواع زیر باشد: {0}!",
"objectSwitchInvalid": "این شیء باید یکی از انواع زیر باشد: {0}!",
"invalidLanguage": "این زبان نامعتبر است!",
"invalidButton": "این دکمه باید حداقل شامل یک {0} یا {1} باشد!",
"unusedOption": "گزینه {0} در هیچ جایی استفاده نشده است!",
"unusedQuestion": "سوال {0} در هیچ جایی استفاده نشده است!",
"dropdownOption": "پنلی که منوی کشویی آن فعال است، فقط می‌تواند شامل گزینه‌هایی از نوع 'تیکت' باشد!"
}
},
"actions":{
"buttons":{
"create": "بازدید از تیکت",
"close": "بستن تیکت",
"delete": "حذف تیکت",
"reopen": "بازگشایی تیکت",
"claim": "اختصاص تیکت",
"unclaim": "لغو اختصاص تیکت",
"pin": "پین کردن تیکت",
"unpin": "لغو پین تیکت",
"clear": "حذف تیکت‌ها",
"helpSwitchSlash": "مشاهده دستورات اسلش",
"helpSwitchText": "مشاهده دستورات متنی",
"helpPage": "صفحه {0}",
"withReason": "با دلیل",
"withoutTranscript": "بدون رونوشت"
},
"titles":{
"created": "تیکت ایجاد شد",
"close": "تیکت بسته شد",
"delete": "تیکت حذف شد",
"reopen": "تیکت بازگشایی شد",
"claim": "تیکت اختصاص یافت",
"unclaim": "اختصاص تیکت لغو شد",
"pin": "تیکت پین شد",
"unpin": "پین تیکت لغو شد",
"rename": "نام تیکت تغییر یافت",
"move": "تیکت منتقل شد",
"add": "کاربر به تیکت اضافه شد",
"remove": "کاربر از تیکت حذف شد",
"help": "دستورات موجود",
"statsReset": "بازنشانی آمار",
"blacklistAdd": "کاربر به لیست سیاه اضافه شد",
"blacklistRemove": "کاربر از لیست سیاه آزاد شد",
"blacklistGet": "کاربر لیست سیاه",
"blacklistView": "لیست سیاه کنونی",
"blacklistAddDm": "به لیست سیاه اضافه شد",
"blacklistRemoveDm": "از لیست سیاه حذف شد",
"clear": "تیکت‌ها پاکسازی شدند",
"roles": "نقش‌ها به‌روزرسانی شدند",
"autoclose": "تیکت به‌صورت خودکار بسته شد",
"autocloseEnabled": "بسته شدن خودکار فعال شد",
"autocloseDisabled": "بسته شدن خودکار غیرفعال شد",
"autodelete": "تیکت به‌صورت خودکار حذف شد",
"autodeleteEnabled": "حذف خودکار فعال شد",
"autodeleteDisabled": "حذف خودکار غیرفعال شد"
},
"descriptions":{
"create": "تیکت شما با موفقیت ایجاد شد. برای دسترسی به آن، روی دکمه زیر کلیک کنید!",
"close": "تیکت با موفقیت بسته شد!",
"delete": "تیکت با موفقیت حذف شد!",
"reopen": "تیکت با موفقیت دوباره باز شد!",
"claim": "تیکت با موفقیت به شما اختصاص یافت!",
"unclaim": "تیکت با موفقیت از حالت اختصاص‌یافته خارج شد!",
"pin": "تیکت با موفقیت پین شد!",
"unpin": "تیکت با موفقیت از حالت پین خارج شد!",
"rename": "نام تیکت با موفقیت به {0} تغییر یافت!",
"move": "تیکت با موفقیت به {0} منتقل شد!",
"add": "کاربر {0} با موفقیت به تیکت اضافه شد!",
"remove": "کاربر {0} با موفقیت از تیکت حذف شد!",
"helpExplanation": "`<name>`: پارامتر اجباری\n`[name]`: پارامتر اختیاری",
"statsReset": "آمار ربات با موفقیت بازنشانی شد!",
"statsError": "امکان مشاهده آمار تیکت وجود ندارد!\n{0} یک تیکت معتبر نیست!",
"blacklistAdd": "کاربر {0} با موفقیت به لیست سیاه اضافه شد!",
"blacklistRemove": "کاربر {0} با موفقیت از لیست سیاه آزاد شد!",
"blacklistGetSuccess": "کاربر {0} در حال حاضر در لیست سیاه قرار دارد!",
"blacklistGetEmpty": "کاربر {0} در حال حاضر در لیست سیاه نیست!",
"blacklistViewEmpty": "هنوز هیچ کاربری به لیست سیاه اضافه نشده است!",
"blacklistViewTip": "برای افزودن کاربر به لیست سیاه از دستور `/blacklist add` استفاده کنید!",
"clearVerify": "آیا مطمئن هستید که می‌خواهید چندین تیکت را حذف کنید؟\nاین اقدام قابل بازگشت نیست!",
"clearReady": "{0} تیکت با موفقیت حذف شدند!",
"rolesEmpty": "هیچ نقشی به‌روزرسانی نشد!",
"autocloseLeave": "این تیکت به‌طور خودکار بسته شد زیرا ایجادکننده آن سرور را ترک کرده است!",
"autocloseTimeout": "این تیکت به‌طور خودکار بسته شد زیرا بیش از {0} ساعت غیرفعال بوده است!",
"autodeleteLeave": "این تیکت به‌طور خودکار حذف شد زیرا ایجادکننده آن سرور را ترک کرده است!",
"autodeleteTimeout": "این تیکت به‌طور خودکار حذف شد زیرا بیش از {0} روز غیرفعال بوده است!",
"autocloseEnabled": "قابلیت بسته شدن خودکار برای این تیکت فعال شد!\nتیکت پس از {0} ساعت غیرفعال بودن بسته خواهد شد!",
"autocloseDisabled": "قابلیت بسته شدن خودکار برای این تیکت غیرفعال شد!\nتیکت دیگر به‌صورت خودکار بسته نخواهد شد!",
"autodeleteEnabled": "قابلیت حذف خودکار برای این تیکت فعال شد!\nتیکت پس از {0} روز غیرفعال بودن حذف خواهد شد!",
"autodeleteDisabled": "قابلیت حذف خودکار برای این تیکت غیرفعال شد!\nتیکت دیگر به‌صورت خودکار حذف نخواهد شد!",
"ticketMessageLimit": "شما تنها می‌توانید همزمان {0} تیکت ایجاد کنید!",
"ticketMessageAutoclose": "این تیکت پس از {0} ساعت غیرفعال بودن به‌صورت خودکار بسته خواهد شد!",
"ticketMessageAutodelete": "این تیکت پس از {0} روز غیرفعال بودن به‌صورت خودکار حذف خواهد شد!",
"panelReady": "پنل در زیر قابل مشاهده است!\nاکنون می‌توانید این پیام را حذف کنید!"
},
"modal":{
"closePlaceholder": "چرا این تیکت را بستید؟",
"deletePlaceholder": "چرا این تیکت را حذف کردید؟",
"reopenPlaceholder": "چرا این تیکت را دوباره باز کردید؟",
"claimPlaceholder": "چرا این تیکت را به خود اختصاص دادید؟",
"unclaimPlaceholder": "چرا اختصاص این تیکت را لغو کردید؟",
"pinPlaceholder": "چرا این تیکت را پین کردید؟",
"unpinPlaceholder": "چرا پین این تیکت را لغو کردید؟"
},
"logs":{
"createLog": "تیکت جدیدی توسط {0} ایجاد شد!",
"closeLog": "این تیکت توسط {0} بسته شد!",
"closeDm": "تیکت شما در سرور ما بسته شد!",
"deleteLog": "این تیکت توسط {0} حذف شد!",
"deleteDm": "تیکت شما در سرور ما حذف شد!",
"reopenLog": "این تیکت توسط {0} دوباره باز شد!",
"reopenDm": "تیکت شما در سرور ما دوباره باز شد!",
"claimLog": "این تیکت توسط {0} اختصاص یافت!",
"claimDm": "تیکت شما در سرور ما اختصاص یافت!",
"unclaimLog": "اختصاص این تیکت توسط {0} لغو شد!",
"unclaimDm": "اختصاص تیکت شما در سرور ما لغو شد!",
"pinLog": "این تیکت توسط {0} پین شد!",
"pinDm": "تیکت شما در سرور ما پین شد!",
"unpinLog": "پین این تیکت توسط {0} لغو شد!",
"unpinDm": "پین تیکت شما در سرور ما لغو شد!",
"renameLog": "این تیکت توسط {1} به {0} تغییر نام یافت!",
"renameDm": "تیکت شما در سرور ما به {0} تغییر نام یافت!",
"moveLog": "این تیکت توسط {1} به {0} منتقل شد!",
"moveDm": "تیکت شما در سرور ما به {0} منتقل شد!",
"addLog": "کاربر {0} توسط {1} به این تیکت اضافه شد!",
"addDm": "کاربر {0} به تیکت شما در سرور ما اضافه شد!",
"removeLog": "کاربر {0} توسط {1} از این تیکت حذف شد!",
"removeDm": "کاربر {0} از تیکت شما در سرور ما حذف شد!",
"blacklistAddLog": "کاربر {0} توسط {1} به لیست سیاه اضافه شد!",
"blacklistRemoveLog": "کاربر {0} توسط {1} از لیست سیاه حذف شد!",
"blacklistAddDm": "شما در سرور ما به لیست سیاه اضافه شدید!\nاز این پس نمی‌توانید تیکت ایجاد کنید!",
"blacklistRemoveDm": "شما از لیست سیاه در سرور ما حذف شدید!\nاکنون می‌توانید دوباره تیکت ایجاد کنید!",
"clearLog": "{0} تیکت توسط {1} حذف شدند!"
}
},
"transcripts":{
"success":{
"visit": "بازدید از رونوشت",
"ready": "رونوشت ایجاد شد",
"textFileDescription": "این فایل متنی، رونوشت یک تیکت حذف‌شده است!",
"htmlProgress": "لطفاً صبر کنید تا این رونوشت HTML پردازش شود...",
"createdChannel": "یک رونوشت {0} جدید در سرور ایجاد شد!",
"createdCreator": "یک رونوشت {0} جدید برای یکی از تیکت‌های شما ایجاد شد!",
"createdParticipant": "یک رونوشت {0} جدید در یکی از تیکت‌هایی که در آن مشارکت داشتید ایجاد شد!",
"createdActiveAdmin": "یک رونوشت {0} جدید در یکی از تیکت‌هایی که به‌عنوان مدیر در آن مشارکت داشتید ایجاد شد!",
"createdEveryAdmin": "یک رونوشت {0} جدید در یکی از تیکت‌هایی که شما مدیر آن بودید ایجاد شد!",
"createdOther": "یک رونوشت {0} جدید ایجاد شد!"
},
"errors":{
"retry": "دوباره تلاش کنید",
"continue": "حذف بدون رونوشت",
"backup": "ایجاد رونوشت پشتیبان",
"error": "مشکلی در هنگام ایجاد رونوشت رخ داد.\nمی‌خواهید چه کاری انجام دهید؟\n\nاین تیکت تا زمانی که یکی از این دکمه‌ها را کلیک نکنید حذف نخواهد شد."
}
},
"errors":{
"titles":{
"internalError": "خطای داخلی",
"optionMissing": "گزینه دستور غایب است",
"optionInvalid": "گزینه دستور نامعتبر است",
"unknownCommand": "دستور ناشناخته",
"noPermissions": "بدون مجوز",
"unknownTicket": "تیکت ناشناخته",
"deprecatedTicket": "تیکت منسوخ‌شده",
"unknownOption": "گزینه ناشناخته",
"unknownPanel": "پنل ناشناخته",
"notInGuild": "خارج از سرور",
"channelRename": "عدم امکان تغییر نام کانال",
"busy": "تیکت مشغول است"
},
"descriptions":{
"askForInfo": "برای اطلاعات بیشتر با صاحب این ربات تماس بگیرید!",
"askForInfoResolve": "اگر این مشکل پس از چند بار تلاش برطرف نشد، با صاحب این ربات تماس بگیرید.",
"internalError": "به دلیل خطای داخلی، امکان پاسخ به این {0} وجود نداشت!",
"optionMissing": "یک پارامتر ضروری در این دستور وجود ندارد!",
"optionInvalid": "یک پارامتر در این دستور نامعتبر است!",
"optionInvalidChoose": "یکی از موارد زیر را انتخاب کنید:",
"unknownCommand": "برای اطلاعات بیشتر، منوی راهنما را بررسی کنید!",
"noPermissions": "شما اجازه استفاده از این {0} را ندارید!",
"noPermissionsList": "مجوزهای مورد نیاز: (یکی از آنها)",
"noPermissionsCooldown": "به دلیل وجود محدودیت زمانی، اجازه استفاده از این {0} را ندارید!",
"noPermissionsBlacklist": "چون در لیست سیاه قرار دارید، اجازه استفاده از این {0} را ندارید!",
"noPermissionsLimitGlobal": "به دلیل رسیدن سرور به حداکثر تعداد تیکت، نمی‌توانید تیکت ایجاد کنید!",
"noPermissionsLimitGlobalUser": "به دلیل رسیدن شما به حداکثر تعداد تیکت، نمی‌توانید تیکت ایجاد کنید!",
"noPermissionsLimitOption": "به دلیل رسیدن سرور به حداکثر تعداد تیکت برای این گزینه، نمی‌توانید تیکت ایجاد کنید!",
"noPermissionsLimitOptionUser": "به دلیل رسیدن شما به حداکثر تعداد تیکت برای این گزینه، نمی‌توانید تیکت ایجاد کنید!",
"unknownTicket": "این دستور را دوباره در یک تیکت معتبر امتحان کنید!",
"deprecatedTicket": "کانال کنونی یک تیکت معتبر نیست! ممکن است این تیکت از نسخه قدیمی Open Ticket باشد!",
"notInGuild": "این {0} در پیام‌های مستقیم (DM) کار نمی‌کند! لطفاً دوباره در یک سرور امتحان کنید!",
"channelRename": "به دلیل محدودیت‌های نرخ دیسکورد، ربات در حال حاضر نمی‌تواند نام کانال را تغییر دهد. اگر ربات ری‌استارت نشود، نام کانال ظرف 10 دقیقه به‌طور خودکار تغییر خواهد کرد.",
"channelRenameSource": "منبع این خطا: {0}",
"busy": "امکان استفاده از این {0} وجود ندارد!\nتیکت در حال پردازش توسط ربات است.\n\nلطفاً چند ثانیه دیگر دوباره امتحان کنید!"
},
"optionInvalidReasons":{
"stringRegex": "مقدار با الگوی مورد نظر مطابقت ندارد!",
"stringMinLength": "مقدار باید حداقل {0} کاراکتر باشد!",
"stringMaxLength": "مقدار باید حداکثر {0} کاراکتر باشد!",
"numberInvalid": "عدد نامعتبر است!",
"numberMin": "عدد باید حداقل {0} باشد!",
"numberMax": "عدد باید حداکثر {0} باشد!",
"numberDecimal": "عدد نمی‌تواند اعشاری باشد!",
"numberNegative": "عدد نمی‌تواند منفی باشد!",
"numberPositive": "عدد نمی‌تواند مثبت باشد!",
"numberZero": "عدد نمی‌تواند صفر باشد!",
"channelNotFound": "کانال یافت نشد!",
"userNotFound": "کاربر یافت نشد!",
"roleNotFound": "نقش یافت نشد!",
"memberNotFound": "کاربر یافت نشد!",
"mentionableNotFound": "کاربر یا نقش یافت نشد!",
"channelType": "نوع کانال نامعتبر است!",
"notInGuild": "این گزینه نیازمند حضور شما در یک سرور است!"
},
"permissions":{
"developer": "شما باید توسعه‌دهنده این ربات باشید.",
"owner": "شما باید صاحب سرور باشید.",
"admin": "شما باید مدیر سرور باشید.",
"moderator": "شما باید ناظم (مدراتور) باشید.",
"support": "شما باید عضو تیم پشتیبانی باشید.",
"member": "شما باید عضو سرور باشید.",
"discord-administrator": "شما باید مجوز `ADMINISTRATOR` را داشته باشید."
},
"actionInvalid":{
"close": "تیکت قبلاً بسته شده است!",
"reopen": "تیکت هنوز بسته نشده است!",
"claim": "تیکت قبلاً اختصاص یافته است!",
"unclaim": "تیکت هنوز اختصاص نیافته است!",
"pin": "تیکت قبلاً پین شده است!",
"unpin": "تیکت هنوز پین نشده است!",
"add": "این کاربر قبلاً به تیکت دسترسی دارد!",
"remove": "امکان حذف این کاربر از تیکت وجود ندارد!"
}
},
"params":{
"uppercase":{
"ticket": "تیکت",
"tickets": "تیکت‌ها",
"reason": "دلیل",
"creator": "ایجادکننده",
"remaining": "زمان باقی‌مانده",
"added": "اضافه‌شده",
"removed": "حذف‌شده",
"filter": "فیلتر",
"claimedBy": "اختصاص‌یافته به {0}",
"method": "روش",
"type": "نوع",
"blacklisted": "در لیست سیاه",
"panel": "پنل",
"command": "دستور",
"system": "سیستم",
"true": "درست",
"false": "نادرست",
"syntax": "نحوه نگارش",
"originalName": "نام اصلی",
"newName": "نام جدید",
"until": "تا",
"validOptions": "گزینه‌های معتبر",
"validPanels": "پنل‌های معتبر",
"autoclose": "بسته شدن خودکار",
"autodelete": "حذف خودکار",
"startupDate": "تاریخ راه‌اندازی",
"version": "نسخه",
"name": "نام",
"role": "نقش",
"status": "وضعیت",
"claimed": "اختصاص‌یافته",
"pinned": "پین‌شده",
"creationDate": "تاریخ ایجاد"
},
"lowercase":{
"text": "متن",
"html": "اچ‌تی‌ام‌ال",
"command": "دستور",
"modal": "پنجره بازشو",
"button": "دکمه",
"dropdown": "منوی کشویی",
"method": "روش"
}
},
"commands":{
"reason": "یک دلیل اختیاری مشخص کنید که در لاگ‌ها قابل مشاهده خواهد بود.",
"help": "لیستی از تمام دستورات موجود را دریافت کنید.",
"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": "آمار ربات، یک عضو یا یک تیکت را مشاهده کنید.",
"statsReset": "تمام آمار ربات را بازنشانی کنید (و شمارش را از صفر شروع کنید).",
"statsGlobal": "آمار کلی را مشاهده کنید.",
"statsUser": "آمار یک کاربر در سرور را مشاهده کنید.",
"statsUserUser": "کاربری که می‌خواهید آمارش را مشاهده کنید.",
"statsTicket": "آمار یک تیکت در سرور را مشاهده کنید.",
"statsTicketTicket": "تیکتی که می‌خواهید آمارش را مشاهده کنید.",
"clear": "چندین تیکت را به‌صورت همزمان حذف کنید.",
"clearFilter": "فیلتر برای حذف تیکت‌ها.",
"clearFilters": {
"all": "همه",
"open": "باز",
"close": "بسته",
"claim": "اختصاص‌یافته",
"unclaim": "بدون اختصاص",
"pin": "پین‌شده",
"unpin": "بدون پین",
"autoclose": "بسته‌شده خودکار"
},
"autoclose": "مدیریت بسته شدن خودکار در یک تیکت.",
"autocloseDisable": "غیرفعال کردن بسته شدن خودکار در این تیکت.",
"autocloseEnable": "فعال کردن بسته شدن خودکار در این تیکت.",
"autocloseEnableTime": "تعداد ساعاتی که این تیکت باید غیرفعال باشد تا بسته شود.",
"autodelete": "مدیریت حذف خودکار در یک تیکت.",
"autodeleteDisable": "غیرفعال کردن حذف خودکار در این تیکت.",
"autodeleteEnable": "فعال کردن حذف خودکار در این تیکت.",
"autodeleteEnableTime": "تعداد روزهایی که این تیکت باید غیرفعال باشد تا حذف شود."
},
"helpMenu":{
"help": "لیستی از تمام دستورات موجود را دریافت کنید.",
"ticket": "فوراً یک تیکت ایجاد کنید.",
"close": "یک تیکت را ببندید، این کار نوشتن در این کانال را غیرفعال می‌کند.",
"delete": "یک تیکت را حذف کنید، این کار در صورت فعال بودن، یک رونوشت ایجاد می‌کند.",
"reopen": "یک تیکت را دوباره باز کنید، این کار نوشتن در این کانال را دوباره فعال می‌کند.",
"pin": "یک تیکت را پین کنید. این کار تیکت را به بالای لیست منتقل می‌کند و ایموجی '📌' به نام آن اضافه می‌شود.",
"unpin": "پین یک تیکت را لغو کنید. تیکت در جایگاه فعلی خود باقی می‌ماند اما ایموجی '📌' از نام آن حذف می‌شود.",
"move": "یک تیکت را منتقل کنید. این کار نوع تیکت را تغییر می‌دهد.",
"rename": "نام یک تیکت را تغییر دهید. این کار نام کانال تیکت را تغییر می‌دهد.",
"claim": "یک تیکت را به خود اختصاص دهید. با این کار به تیم خود اطلاع می‌دهید که شما این تیکت را مدیریت می‌کنید.",
"unclaim": "اختصاص یک تیکت را لغو کنید. با این کار به تیم خود اطلاع می‌دهید که این تیکت دوباره آزاد است.",
"add": "یک کاربر را به تیکت اضافه کنید. این کار به کاربر امکان خواندن و نوشتن در تیکت را می‌دهد.",
"remove": "یک کاربر را از تیکت حذف کنید. این کار امکان خواندن و نوشتن کاربر در تیکت را حذف می‌کند.",
"panel": "یک پیام با منوی کشویی یا دکمه‌ها ایجاد کنید (برای ساخت تیکت).",
"blacklistView": "لیستی از لیست سیاه کنونی را مشاهده کنید.",
"blacklistAdd": "یک کاربر را به لیست سیاه اضافه کنید.",
"blacklistRemove": "یک کاربر را از لیست سیاه حذف کنید.",
"blacklistGet": "جزئیات یک کاربر در لیست سیاه را دریافت کنید.",
"statsGlobal": "آمار کلی را مشاهده کنید.",
"statsTicket": "آمار یک تیکت در سرور را مشاهده کنید.",
"statsUser": "آمار یک کاربر در سرور را مشاهده کنید.",
"statsReset": "تمام آمار ربات را بازنشانی کنید (و شمارش را از صفر شروع کنید).",
"autocloseDisable": "بسته شدن خودکار را در این تیکت غیرفعال کنید.",
"autocloseEnable": "بسته شدن خودکار را در این تیکت فعال کنید.",
"autodeleteDisable": "حذف خودکار را در این تیکت غیرفعال کنید.",
"autodeleteEnable": "حذف خودکار را در این تیکت فعال کنید."
},
"stats":{
"scopes":{
"global": "آمار کلی",
"system": "آمار سیستم",
"user": "آمار کاربر",
"ticket": "آمار تیکت",
"participants": "مشارکت‌کنندگان"
},
"properties":{
"ticketsCreated": "تیکت‌های ایجادشده",
"ticketsClosed": "تیکت‌های بسته‌شده",
"ticketsDeleted": "تیکت‌های حذف‌شده",
"ticketsReopened": "تیکت‌های دوباره بازشده",
"ticketsAutoclosed": "تیکت‌های بسته‌شده خودکار",
"ticketsClaimed": "تیکت‌های اختصاص‌ یافته",
"ticketsPinned": "تیکت‌های پین‌ شده",
"ticketsMoved": "تیکت‌های منتقل‌ شده",
"usersBlacklisted": "کاربران در لیست سیاه",
"transcriptsCreated": "رونوشت‌های ایجادشده"
}
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["DanoGlez"], "translators":["DanoGlez"],
"lastedited":"28/01/2025", "lastedited":"28/01/2025",
"language":"Polish", "language":"Polish",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["quiradon"], "translators":["quiradon"],
"lastedited":"20/08/2024", "lastedited":"20/08/2024",
"language":"Portuguese", "language":"Portuguese",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["SankeDev"], "translators":["SankeDev"],
"lastedited":"27/08/2024", "lastedited":"27/08/2024",
"language":"Romanian", "language":"Romanian",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION": { "_TRANSLATION": {
"otversion": "v4.0.2", "otversion": "v4.0.6",
"translators": ["NoOneNook"], "translators": ["NoOneNook"],
"lastedited": "25/03/2025", "lastedited": "25/03/2025",
"language": "Russian", "language": "Russian",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["Redactado","Josuens"], "translators":["Redactado","Josuens"],
"lastedited":"22/08/2024", "lastedited":"22/08/2024",
"language":"Spanish", "language":"Spanish",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION": { "_TRANSLATION": {
"otversion": "v4.0.2", "otversion": "v4.0.6",
"translators": ["NoOneNook"], "translators": ["NoOneNook"],
"lastedited": "25/03/2025", "lastedited": "25/03/2025",
"language": "Svenska", "language": "Svenska",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["modshd"], "translators":["modshd"],
"lastedited":"13/11/2024", "lastedited":"13/11/2024",
"language":"Thai", "language":"Thai",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION": { "_TRANSLATION": {
"otversion": "v4.0.2", "otversion": "v4.0.6",
"translators": ["palestinian"], "translators": ["palestinian"],
"lastedited": "26/11/2024", "lastedited": "26/11/2024",
"language": "Turkish", "language": "Turkish",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["Anderskiy"], "translators":["Anderskiy"],
"lastedited":"31/08/2024", "lastedited":"31/08/2024",
"language":"Ukrainian", "language":"Ukrainian",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_TRANSLATION":{ "_TRANSLATION":{
"otversion":"v4.0.2", "otversion":"v4.0.6",
"translators":["ngocdiep2006"], "translators":["ngocdiep2006"],
"lastedited":"07/04/2025", "lastedited":"07/04/2025",
"language":"Vietnamese", "language":"Vietnamese",
+3 -3
View File
@@ -1,7 +1,7 @@
{ {
"name": "open-ticket", "name": "open-ticket",
"author": "DJdj Development", "author": "DJdj Development",
"version": "4.0.2", "version": "4.0.6",
"description": "The most advanced open-source discord ticket bot with HTML transcripts, plugins, questions, claiming, pinning & more! Using discord.js v14 & JSON database! ", "description": "The most advanced open-source discord ticket bot with HTML transcripts, plugins, questions, claiming, pinning & more! Using discord.js v14 & JSON database! ",
"keywords": [ "keywords": [
"ticket-bot", "ticket-bot",
@@ -25,7 +25,7 @@
"@discordjs/rest": "^2.4.2", "@discordjs/rest": "^2.4.2",
"@types/node": "^22.5.0", "@types/node": "^22.5.0",
"ansis": "^2.3.0", "ansis": "^2.3.0",
"discord.js": "^14.17.2", "discord.js": "^14.19.3",
"formatted-json-stringify": "^1.1.0", "formatted-json-stringify": "^1.1.0",
"typescript": "^5.5.4" "typescript": "^5.5.4"
}, },
@@ -42,7 +42,7 @@
"#opendiscord": "./dist/src/index.js", "#opendiscord": "./dist/src/index.js",
"#opendiscord-types": "./dist/src/core/api/api.js" "#opendiscord-types": "./dist/src/core/api/api.js"
}, },
"funding":{ "funding": {
"type": "individual", "type": "individual",
"url": "https://github.com/sponsors/DJj123dj" "url": "https://github.com/sponsors/DJj123dj"
} }
+1 -1
View File
@@ -20,7 +20,7 @@ export const registerActions = async () => {
const channelCategory = option.get("opendiscord:channel-category").value const channelCategory = option.get("opendiscord:channel-category").value
const channelBackupCategory = option.get("opendiscord:channel-category-backup").value const channelBackupCategory = option.get("opendiscord:channel-category-backup").value
const channelDescription = option.get("opendiscord:channel-description").value const channelDescription = option.get("opendiscord:channel-description").value
const channelSuffix = opendiscord.options.suffix.getSuffixFromOption(option,user) const channelSuffix = await opendiscord.options.suffix.getSuffixFromOption(option,user)
const channelName = channelPrefix+channelSuffix const channelName = channelPrefix+channelSuffix
//handle category //handle category
+6 -2
View File
@@ -38,7 +38,9 @@ export const registerActions = async () => {
await opendiscord.events.get("onTranscriptInit").emit([opendiscord.transcripts,ticket,channel,user]) await opendiscord.events.get("onTranscriptInit").emit([opendiscord.transcripts,ticket,channel,user])
if (instance.compiler.init){ if (instance.compiler.init){
try{ try{
instance.initData = null
const result = await instance.compiler.init(ticket,channel,user) const result = await instance.compiler.init(ticket,channel,user)
instance.initData = result.initData
if (result.success && result.pendingMessage && transcriptConfig.data.general.enableChannel){ if (result.success && result.pendingMessage && transcriptConfig.data.general.enableChannel){
//send init message to channel //send init message to channel
const post = opendiscord.posts.get("opendiscord:transcripts") const post = opendiscord.posts.get("opendiscord:transcripts")
@@ -49,7 +51,9 @@ export const registerActions = async () => {
instance.pendingMessage = null instance.pendingMessage = null
instance.errorReason = result.errorReason instance.errorReason = result.errorReason
throw new api.ODSystemError("ODAction(ot:create-transcript) => Known Init Error => "+result.errorReason) throw new api.ODSystemError("ODAction(ot:create-transcript) => Known Init Error => "+result.errorReason)
}else instance.pendingMessage = null }else{
instance.pendingMessage = null
}
}catch(err){ }catch(err){
instance.success = false instance.success = false
cancel() cancel()
@@ -72,7 +76,7 @@ export const registerActions = async () => {
await opendiscord.events.get("onTranscriptCompile").emit([opendiscord.transcripts,ticket,channel,user]) await opendiscord.events.get("onTranscriptCompile").emit([opendiscord.transcripts,ticket,channel,user])
if (instance.compiler.compile){ if (instance.compiler.compile){
try{ try{
const result = await instance.compiler.compile(ticket,channel,user) const result = await instance.compiler.compile(ticket,channel,user,instance.initData)
if (!result.success){ if (!result.success){
instance.errorReason = result.errorReason instance.errorReason = result.errorReason
throw new api.ODSystemError("ODAction(ot:create-transcript) => Known Compiler Error => "+result.errorReason) throw new api.ODSystemError("ODAction(ot:create-transcript) => Known Compiler Error => "+result.errorReason)
+6 -3
View File
@@ -142,7 +142,8 @@ export const registerButtonResponders = async () => {
instance.modal(await opendiscord.builders.modals.getSafe("opendiscord:ticket-questions").build("panel-button",{guild,channel,user,option})) instance.modal(await opendiscord.builders.modals.getSafe("opendiscord:ticket-questions").build("panel-button",{guild,channel,user,option}))
}else{ }else{
//create ticket //create ticket
await instance.defer("reply",true) await instance.defer((generalConfig.data.system.replyOnTicketCreation) ? "reply" : "update",true)
const res = await opendiscord.actions.get("opendiscord:create-ticket").run("panel-button",{guild,user,answers:[],option}) const res = await opendiscord.actions.get("opendiscord:create-ticket").run("panel-button",{guild,user,answers:[],option})
if (!res.channel || !res.ticket){ if (!res.channel || !res.ticket){
//error //error
@@ -196,7 +197,8 @@ export const registerDropdownResponders = async () => {
instance.modal(await opendiscord.builders.modals.getSafe("opendiscord:ticket-questions").build("panel-dropdown",{guild,channel,user,option})) instance.modal(await opendiscord.builders.modals.getSafe("opendiscord:ticket-questions").build("panel-dropdown",{guild,channel,user,option}))
}else{ }else{
//create ticket //create ticket
await instance.defer("reply",true) await instance.defer((generalConfig.data.system.replyOnTicketCreation) ? "reply" : "update",true)
const res = await opendiscord.actions.get("opendiscord:create-ticket").run("panel-dropdown",{guild,user,answers:[],option}) const res = await opendiscord.actions.get("opendiscord:create-ticket").run("panel-dropdown",{guild,user,answers:[],option})
if (!res.channel || !res.ticket){ if (!res.channel || !res.ticket){
//error //error
@@ -264,7 +266,8 @@ export const registerModalResponders = async () => {
}) })
//create ticket //create ticket
await instance.defer("reply",true) 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}) const res = await opendiscord.actions.get("opendiscord:create-ticket").run(originalSource,{guild,user,answers,option})
if (!res.channel || !res.ticket){ if (!res.channel || !res.ticket){
//error //error
+1 -1
View File
@@ -25,7 +25,7 @@ export interface ODActionManagerIds_Default {
"opendiscord:create-transcript":{ "opendiscord:create-transcript":{
source:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other", source:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket}, params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket},
result:{compiler:ODTranscriptCompiler<any>, success:boolean, result:ODTranscriptCompilerCompileResult<any>, errorReason:string|null, pendingMessage:ODMessageBuildSentResult<true>|null, participants:{user:discord.User,role:"creator"|"participant"|"admin"}[]}, result:{compiler:ODTranscriptCompiler<any,object|null>, success:boolean, result:ODTranscriptCompilerCompileResult<any>, errorReason:string|null, pendingMessage:ODMessageBuildSentResult<true>|null, initData:object|null, participants:{user:discord.User,role:"creator"|"participant"|"admin"}[]},
workers:"opendiscord:select-compiler"|"opendiscord:init-transcript"|"opendiscord:compile-transcript"|"opendiscord:ready-transcript"|"opendiscord:logs" workers:"opendiscord:select-compiler"|"opendiscord:init-transcript"|"opendiscord:compile-transcript"|"opendiscord:ready-transcript"|"opendiscord:logs"
}, },
"opendiscord:create-ticket":{ "opendiscord:create-ticket":{
+12 -12
View File
@@ -58,9 +58,9 @@ export interface ODButtonManagerIds_Default {
"opendiscord:pin-ticket":{source:"ticket-message"|"unpin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:pin-ticket"}, "opendiscord:pin-ticket":{source:"ticket-message"|"unpin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:pin-ticket"},
"opendiscord:unpin-ticket":{source:"ticket-message"|"pin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:unpin-ticket"}, "opendiscord:unpin-ticket":{source:"ticket-message"|"pin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:unpin-ticket"},
"opendiscord:transcript-html-visit":{source:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string}>,result:ODTranscriptCompilerCompileResult<{url:string}>},workers:"opendiscord:transcript-html-visit"}, "opendiscord:transcript-html-visit":{source:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}>,result:ODTranscriptCompilerCompileResult<{url:string,availableUntil:Date}>},workers:"opendiscord:transcript-html-visit"},
"opendiscord:transcript-error-retry":{source:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any>,reason:string|null},workers:"opendiscord:transcript-error-retry"}, "opendiscord:transcript-error-retry":{source:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any,object|null>,reason:string|null},workers:"opendiscord:transcript-error-retry"},
"opendiscord:transcript-error-continue":{source:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any>,reason:string|null},workers:"opendiscord:transcript-error-continue"}, "opendiscord:transcript-error-continue":{source:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any,object|null>,reason:string|null},workers:"opendiscord:transcript-error-continue"},
"opendiscord:clear-continue":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"opendiscord:clear-continue"}, "opendiscord:clear-continue":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"opendiscord:clear-continue"},
} }
@@ -170,7 +170,7 @@ export class ODDropdown_Default<Source extends string, Params, WorkerIds extends
* It's used to generate typescript declarations for this class. * It's used to generate typescript declarations for this class.
*/ */
export interface ODFileManagerIds_Default { export interface ODFileManagerIds_Default {
"opendiscord:text-transcript":{source:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any>,result:ODTranscriptCompilerCompileResult<any>},workers:"opendiscord:text-transcript"} "opendiscord:text-transcript":{source:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any,object|null>,result:ODTranscriptCompilerCompileResult<any>},workers:"opendiscord:text-transcript"}
} }
/**## ODFileManager_Default `default_class` /**## ODFileManager_Default `default_class`
@@ -275,10 +275,10 @@ export interface ODEmbedManagerIds_Default {
"opendiscord:blacklist-dm":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"add"|"remove",data:discord.User,reason:string|null},workers:"opendiscord:blacklist-dm"}, "opendiscord:blacklist-dm":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"add"|"remove",data:discord.User,reason:string|null},workers:"opendiscord:blacklist-dm"},
"opendiscord:blacklist-logs":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"add"|"remove",data:discord.User,reason:string|null},workers:"opendiscord:blacklist-logs"}, "opendiscord:blacklist-logs":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"add"|"remove",data:discord.User,reason:string|null},workers:"opendiscord:blacklist-logs"},
"opendiscord:transcript-text-ready":{source:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{contents:string}>,result:ODTranscriptCompilerCompileResult<{contents:string}>},workers:"opendiscord:transcript-text-ready"}, "opendiscord:transcript-text-ready":{source:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{contents:string},null>,result:ODTranscriptCompilerCompileResult<{contents:string}>},workers:"opendiscord:transcript-text-ready"},
"opendiscord:transcript-html-ready":{source:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string}>,result:ODTranscriptCompilerCompileResult<{url:string}>},workers:"opendiscord:transcript-html-ready"}, "opendiscord:transcript-html-ready":{source:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}>,result:ODTranscriptCompilerCompileResult<{url:string,availableUntil:Date}>},workers:"opendiscord:transcript-html-ready"},
"opendiscord:transcript-html-progress":{source:"channel"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string}>,remaining:number},workers:"opendiscord:transcript-html-progress"}, "opendiscord:transcript-html-progress":{source:"channel"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}>,remaining:number},workers:"opendiscord:transcript-html-progress"},
"opendiscord:transcript-error":{source:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any>,reason:string|null},workers:"opendiscord:transcript-error"}, "opendiscord:transcript-error":{source:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any,object|null>,reason:string|null},workers:"opendiscord:transcript-error"},
"opendiscord:reaction-role":{source:"panel-button"|"other",params:{guild:discord.Guild,user:discord.User,role:ODRole,result:ODRoleUpdateResult[]},workers:"opendiscord:reaction-role"}, "opendiscord:reaction-role":{source:"panel-button"|"other",params:{guild:discord.Guild,user:discord.User,role:ODRole,result:ODRoleUpdateResult[]},workers:"opendiscord:reaction-role"},
"opendiscord:clear-verify-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"opendiscord:clear-verify-message"}, "opendiscord:clear-verify-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"opendiscord:clear-verify-message"},
@@ -406,10 +406,10 @@ export interface ODMessageManagerIds_Default {
"opendiscord:blacklist-dm":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"add"|"remove",data:discord.User,reason:string|null},workers:"opendiscord:blacklist-dm"}, "opendiscord:blacklist-dm":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"add"|"remove",data:discord.User,reason:string|null},workers:"opendiscord:blacklist-dm"},
"opendiscord:blacklist-logs":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"add"|"remove",data:discord.User,reason:string|null},workers:"opendiscord:blacklist-logs"}, "opendiscord:blacklist-logs":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"add"|"remove",data:discord.User,reason:string|null},workers:"opendiscord:blacklist-logs"},
"opendiscord:transcript-text-ready":{source:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{contents:string}>,result:ODTranscriptCompilerCompileResult<{contents:string}>},workers:"opendiscord:transcript-text-ready"}, "opendiscord:transcript-text-ready":{source:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{contents:string},null>,result:ODTranscriptCompilerCompileResult<{contents:string}>},workers:"opendiscord:transcript-text-ready"},
"opendiscord:transcript-html-ready":{source:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string}>,result:ODTranscriptCompilerCompileResult<{url:string}>},workers:"opendiscord:transcript-html-ready"}, "opendiscord:transcript-html-ready":{source:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}>,result:ODTranscriptCompilerCompileResult<{url:string,availableUntil:Date}>},workers:"opendiscord:transcript-html-ready"},
"opendiscord:transcript-html-progress":{source:"channel"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string}>,remaining:number},workers:"opendiscord:transcript-html-progress"}, "opendiscord:transcript-html-progress":{source:"channel"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}>,remaining:number},workers:"opendiscord:transcript-html-progress"},
"opendiscord:transcript-error":{source:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any>,reason:string|null},workers:"opendiscord:transcript-error"}, "opendiscord:transcript-error":{source:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any,object|null>,reason:string|null},workers:"opendiscord:transcript-error"},
"opendiscord:reaction-role":{source:"panel-button"|"other",params:{guild:discord.Guild,user:discord.User,role:ODRole,result:ODRoleUpdateResult[]},workers:"opendiscord:reaction-role"}, "opendiscord:reaction-role":{source:"panel-button"|"other",params:{guild:discord.Guild,user:discord.User,role:ODRole,result:ODRoleUpdateResult[]},workers:"opendiscord:reaction-role"},
"opendiscord:clear-verify-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"opendiscord:clear-verify-message"}, "opendiscord:clear-verify-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"opendiscord:clear-verify-message"},
+1
View File
@@ -472,6 +472,7 @@ export interface ODLanguageManagerIds_Default {
"opendiscord:russian":ODLanguage, "opendiscord:russian":ODLanguage,
"opendiscord:swedish":ODLanguage, "opendiscord:swedish":ODLanguage,
"opendiscord:vietnamese":ODLanguage, "opendiscord:vietnamese":ODLanguage,
"opendiscord:persian":ODLanguage,
//ADD NEW LANGUAGES HERE!!! //ADD NEW LANGUAGES HERE!!!
} }
+1 -1
View File
@@ -130,7 +130,7 @@ export class ODMain {
constructor(){ constructor(){
this.versions = new ODVersionManager_Default() this.versions = new ODVersionManager_Default()
this.versions.add(ODVersion.fromString("opendiscord:version","v4.0.2")) this.versions.add(ODVersion.fromString("opendiscord:version","v4.0.6"))
this.versions.add(ODVersion.fromString("opendiscord:api","v1.0.0")) this.versions.add(ODVersion.fromString("opendiscord:api","v1.0.0"))
this.versions.add(ODVersion.fromString("opendiscord:transcripts","v2.0.0")) this.versions.add(ODVersion.fromString("opendiscord:transcripts","v2.0.0"))
this.versions.add(ODVersion.fromString("opendiscord:livestatus","v2.0.0")) this.versions.add(ODVersion.fromString("opendiscord:livestatus","v2.0.0"))
+4 -4
View File
@@ -648,8 +648,8 @@ export class ODHTTPGetRequest {
this.throwOnError = throwOnError this.throwOnError = throwOnError
const newConfig = config ?? {} const newConfig = config ?? {}
newConfig.method = "GET" newConfig.method = "GET"
if (newConfig.headers) Object.assign(newConfig.headers,{"User-Agent":"OpenDiscordBots-OpenTicket/4.0.2"}) if (newConfig.headers) Object.assign(newConfig.headers,{"User-Agent":"OpenDiscordBots-OpenTicket/4.0.6"})
else newConfig.headers = {"User-Agent":"OpenDiscordBots-OpenTicket/4.0.2"} else newConfig.headers = {"User-Agent":"OpenDiscordBots-OpenTicket/4.0.6"}
this.config = newConfig this.config = newConfig
} }
@@ -703,8 +703,8 @@ export class ODHTTPPostRequest {
this.throwOnError = throwOnError this.throwOnError = throwOnError
const newConfig = config ?? {} const newConfig = config ?? {}
newConfig.method = "POST" newConfig.method = "POST"
if (newConfig.headers) Object.assign(newConfig.headers,{"User-Agent":"OpenDiscordBots-OpenTicket/4.0.2"}) if (newConfig.headers) Object.assign(newConfig.headers,{"User-Agent":"OpenDiscordBots-OpenTicket/4.0.6"})
else newConfig.headers = {"User-Agent":"OpenDiscordBots-OpenTicket/4.0.2"} else newConfig.headers = {"User-Agent":"OpenDiscordBots-OpenTicket/4.0.6"}
this.config = newConfig this.config = newConfig
} }
+22 -17
View File
@@ -257,7 +257,7 @@ export class ODQuickButton {
/**The id of this button. */ /**The id of this button. */
id: ODId id: ODId
/**The current data of this button */ /**The current data of this button */
data: ODButtonData = { data: Partial<ODButtonData> = {
customId:"", customId:"",
mode:"button", mode:"button",
url:null, url:null,
@@ -267,7 +267,7 @@ export class ODQuickButton {
disabled:false disabled:false
} }
constructor(id:ODValidId,data:ODButtonData){ constructor(id:ODValidId,data:Partial<ODButtonData>){
this.id = new ODId(id) this.id = new ODId(id)
this.data = data this.data = data
} }
@@ -277,7 +277,7 @@ export class ODQuickButton {
try { try {
//create the discord.js button //create the discord.js button
const button = new discord.ButtonBuilder() const button = new discord.ButtonBuilder()
if (this.data.mode == "button") button.setCustomId(this.data.customId) if (this.data.mode == "button") button.setCustomId(this.data.customId ?? "od:unknown-button")
if (this.data.mode == "url") button.setStyle(discord.ButtonStyle.Link) if (this.data.mode == "url") button.setStyle(discord.ButtonStyle.Link)
else if (this.data.color == "gray") button.setStyle(discord.ButtonStyle.Secondary) else if (this.data.color == "gray") button.setStyle(discord.ButtonStyle.Secondary)
else if (this.data.color == "blue") button.setStyle(discord.ButtonStyle.Primary) else if (this.data.color == "blue") button.setStyle(discord.ButtonStyle.Primary)
@@ -287,7 +287,7 @@ export class ODQuickButton {
if (this.data.label) button.setLabel(this.data.label) if (this.data.label) button.setLabel(this.data.label)
if (this.data.emoji) button.setEmoji(this.data.emoji) if (this.data.emoji) button.setEmoji(this.data.emoji)
if (this.data.disabled) button.setDisabled(this.data.disabled) if (this.data.disabled) button.setDisabled(this.data.disabled)
if (!this.data.emoji && !this.data.label) button.setLabel(this.data.customId) if (!this.data.emoji && !this.data.label) button.setLabel(this.data.customId ?? "od:unknown-button")
return {id:this.id,component:button} return {id:this.id,component:button}
}catch(err){ }catch(err){
@@ -564,7 +564,7 @@ export class ODQuickDropdown {
/**The id of this dropdown. */ /**The id of this dropdown. */
id: ODId id: ODId
/**The current data of this dropdown */ /**The current data of this dropdown */
data: ODDropdownData = { data: Partial<ODDropdownData> = {
customId:"", customId:"",
type:"string", type:"string",
placeholder:null, placeholder:null,
@@ -580,7 +580,7 @@ export class ODQuickDropdown {
mentionables:[] mentionables:[]
} }
constructor(id:ODValidId,data:ODDropdownData){ constructor(id:ODValidId,data:Partial<ODDropdownData>){
this.id = new ODId(id) this.id = new ODId(id)
this.data = data this.data = data
} }
@@ -590,8 +590,9 @@ export class ODQuickDropdown {
try{ try{
//create the discord.js dropdown //create the discord.js dropdown
if (this.data.type == "string"){ if (this.data.type == "string"){
if (!this.data.options) throw new ODSystemError("ODQuickDropdown:build(): "+this.id.value+" => Dropdown requires at least 1 option to be present.")
const dropdown = new discord.StringSelectMenuBuilder() const dropdown = new discord.StringSelectMenuBuilder()
dropdown.setCustomId(this.data.customId) dropdown.setCustomId(this.data.customId ?? "od:unknown-dropdown")
dropdown.setOptions(...this.data.options) dropdown.setOptions(...this.data.options)
if (this.data.placeholder) dropdown.setPlaceholder(this.data.placeholder) if (this.data.placeholder) dropdown.setPlaceholder(this.data.placeholder)
if (this.data.minValues) dropdown.setMinValues(this.data.minValues) if (this.data.minValues) dropdown.setMinValues(this.data.minValues)
@@ -601,8 +602,9 @@ export class ODQuickDropdown {
return {id:this.id,component:dropdown} return {id:this.id,component:dropdown}
}else if (this.data.type == "user"){ }else if (this.data.type == "user"){
if (!this.data.users) throw new ODSystemError("ODQuickDropdown:build(): "+this.id.value+" => Dropdown requires at least 1 user option to be present.")
const dropdown = new discord.UserSelectMenuBuilder() const dropdown = new discord.UserSelectMenuBuilder()
dropdown.setCustomId(this.data.customId) dropdown.setCustomId(this.data.customId ?? "od:unknown-dropdown")
if (this.data.users.length > 0) dropdown.setDefaultUsers(...this.data.users.map((u) => u.id)) if (this.data.users.length > 0) dropdown.setDefaultUsers(...this.data.users.map((u) => u.id))
if (this.data.placeholder) dropdown.setPlaceholder(this.data.placeholder) if (this.data.placeholder) dropdown.setPlaceholder(this.data.placeholder)
if (this.data.minValues) dropdown.setMinValues(this.data.minValues) if (this.data.minValues) dropdown.setMinValues(this.data.minValues)
@@ -612,8 +614,9 @@ export class ODQuickDropdown {
return {id:this.id,component:dropdown} return {id:this.id,component:dropdown}
}else if (this.data.type == "role"){ }else if (this.data.type == "role"){
if (!this.data.roles) throw new ODSystemError("ODQuickDropdown:build(): "+this.id.value+" => Dropdown requires at least 1 role option to be present.")
const dropdown = new discord.RoleSelectMenuBuilder() const dropdown = new discord.RoleSelectMenuBuilder()
dropdown.setCustomId(this.data.customId) dropdown.setCustomId(this.data.customId ?? "od:unknown-dropdown")
if (this.data.roles.length > 0) dropdown.setDefaultRoles(...this.data.roles.map((r) => r.id)) if (this.data.roles.length > 0) dropdown.setDefaultRoles(...this.data.roles.map((r) => r.id))
if (this.data.placeholder) dropdown.setPlaceholder(this.data.placeholder) if (this.data.placeholder) dropdown.setPlaceholder(this.data.placeholder)
if (this.data.minValues) dropdown.setMinValues(this.data.minValues) if (this.data.minValues) dropdown.setMinValues(this.data.minValues)
@@ -623,8 +626,9 @@ export class ODQuickDropdown {
return {id:this.id,component:dropdown} return {id:this.id,component:dropdown}
}else if (this.data.type == "channel"){ }else if (this.data.type == "channel"){
if (!this.data.channels) throw new ODSystemError("ODQuickDropdown:build(): "+this.id.value+" => Dropdown requires at least 1 channel option to be present.")
const dropdown = new discord.ChannelSelectMenuBuilder() const dropdown = new discord.ChannelSelectMenuBuilder()
dropdown.setCustomId(this.data.customId) dropdown.setCustomId(this.data.customId ?? "od:unknown-dropdown")
if (this.data.channels.length > 0) dropdown.setDefaultChannels(...this.data.channels.map((c) => c.id)) if (this.data.channels.length > 0) dropdown.setDefaultChannels(...this.data.channels.map((c) => c.id))
if (this.data.placeholder) dropdown.setPlaceholder(this.data.placeholder) if (this.data.placeholder) dropdown.setPlaceholder(this.data.placeholder)
if (this.data.minValues) dropdown.setMinValues(this.data.minValues) if (this.data.minValues) dropdown.setMinValues(this.data.minValues)
@@ -634,6 +638,7 @@ export class ODQuickDropdown {
return {id:this.id,component:dropdown} return {id:this.id,component:dropdown}
}else if (this.data.type == "mentionable"){ }else if (this.data.type == "mentionable"){
if (!this.data.mentionables) throw new ODSystemError("ODQuickDropdown:build(): "+this.id.value+" => Dropdown requires at least 1 mentionable option to be present.")
const dropdown = new discord.MentionableSelectMenuBuilder() const dropdown = new discord.MentionableSelectMenuBuilder()
const values: ({type:discord.SelectMenuDefaultValueType.User,id:string}|{type:discord.SelectMenuDefaultValueType.Role,id:string})[] = [] const values: ({type:discord.SelectMenuDefaultValueType.User,id:string}|{type:discord.SelectMenuDefaultValueType.Role,id:string})[] = []
@@ -645,7 +650,7 @@ export class ODQuickDropdown {
} }
}) })
dropdown.setCustomId(this.data.customId) dropdown.setCustomId(this.data.customId ?? "od:unknown-dropdown")
if (this.data.mentionables.length > 0) dropdown.setDefaultValues(...values) if (this.data.mentionables.length > 0) dropdown.setDefaultValues(...values)
if (this.data.placeholder) dropdown.setPlaceholder(this.data.placeholder) if (this.data.placeholder) dropdown.setPlaceholder(this.data.placeholder)
if (this.data.minValues) dropdown.setMinValues(this.data.minValues) if (this.data.minValues) dropdown.setMinValues(this.data.minValues)
@@ -799,14 +804,14 @@ export class ODQuickFile {
/**The id of this file. */ /**The id of this file. */
id: ODId id: ODId
/**The current data of this file */ /**The current data of this file */
data: ODFileData = { data: Partial<ODFileData> = {
file:"", file:"",
name:"file.txt", name:"file.txt",
description:null, description:null,
spoiler:false spoiler:false
} }
constructor(id:ODValidId,data:ODFileData){ constructor(id:ODValidId,data:Partial<ODFileData>){
this.id = new ODId(id) this.id = new ODId(id)
this.data = data this.data = data
} }
@@ -815,7 +820,7 @@ export class ODQuickFile {
async build(): Promise<ODFileBuildResult> { async build(): Promise<ODFileBuildResult> {
try{ try{
//create the discord.js attachment //create the discord.js attachment
const file = new discord.AttachmentBuilder(this.data.file) const file = new discord.AttachmentBuilder(this.data.file ?? "<empty-file>")
file.setName(this.data.name ? this.data.name : "file.txt") file.setName(this.data.name ? this.data.name : "file.txt")
if (this.data.description) file.setDescription(this.data.description) if (this.data.description) file.setDescription(this.data.description)
if (this.data.spoiler) file.setSpoiler(this.data.spoiler) if (this.data.spoiler) file.setSpoiler(this.data.spoiler)
@@ -1055,7 +1060,7 @@ export class ODQuickEmbed {
/**The id of this embed. */ /**The id of this embed. */
id: ODId id: ODId
/**The current data of this embed */ /**The current data of this embed */
data: ODEmbedData = { data: Partial<ODEmbedData> = {
title:null, title:null,
color:null, color:null,
url:null, url:null,
@@ -1071,7 +1076,7 @@ export class ODQuickEmbed {
timestamp:null timestamp:null
} }
constructor(id:ODValidId,data:ODEmbedData){ constructor(id:ODValidId,data:Partial<ODEmbedData>){
this.id = new ODId(id) this.id = new ODId(id)
this.data = data this.data = data
} }
@@ -1097,7 +1102,7 @@ export class ODQuickEmbed {
if (this.data.image) embed.setImage(this.data.image) if (this.data.image) embed.setImage(this.data.image)
if (this.data.thumbnail) embed.setThumbnail(this.data.thumbnail) if (this.data.thumbnail) embed.setThumbnail(this.data.thumbnail)
if (this.data.timestamp) embed.setTimestamp(this.data.timestamp) if (this.data.timestamp) embed.setTimestamp(this.data.timestamp)
if (this.data.fields.length > 0) embed.setFields(this.data.fields) if (this.data.fields && this.data.fields.length > 0) embed.setFields(this.data.fields)
return {id:this.id,embed} return {id:this.id,embed}
}catch(err){ }catch(err){
+12 -6
View File
@@ -579,8 +579,8 @@ export class ODSlashCommandComparator {
} }
} }
/**Convert a `ODSlashCommandBuilder` to a universal Open Ticket slash command object for comparison. */ /**Convert a `ODSlashCommandBuilder` to a universal Open Ticket slash command object for comparison. */
convertBuilder(builder:ODSlashCommandBuilder,guildId:string|null): ODSlashCommandUniversalCommand { convertBuilder(builder:ODSlashCommandBuilder,guildId:string|null): ODSlashCommandUniversalCommand|null {
if (builder.type != discord.ApplicationCommandType.ChatInput) throw new ODSystemError("ODSlashCommandComparator:convertBuilder() is not supported for other types than 'ChatInput'!") if (builder.type != discord.ApplicationCommandType.ChatInput) return null //throw new ODSystemError("ODSlashCommandComparator:convertBuilder() is not supported for other types than 'ChatInput'!")
const nameLoc = builder.nameLocalizations ?? {} const nameLoc = builder.nameLocalizations ?? {}
const descLoc = builder.descriptionLocalizations ?? {} const descLoc = builder.descriptionLocalizations ?? {}
return { return {
@@ -599,8 +599,8 @@ export class ODSlashCommandComparator {
} }
} }
/**Convert a `discord.ApplicationCommand` to a universal Open Ticket slash command object for comparison. */ /**Convert a `discord.ApplicationCommand` to a universal Open Ticket slash command object for comparison. */
convertCommand(cmd:discord.ApplicationCommand): ODSlashCommandUniversalCommand { convertCommand(cmd:discord.ApplicationCommand): ODSlashCommandUniversalCommand|null {
if (cmd.type != discord.ApplicationCommandType.ChatInput) throw new ODSystemError("ODSlashCommandComparator:convertCommand() is not supported for other types than 'ChatInput'!") if (cmd.type != discord.ApplicationCommandType.ChatInput) return null //throw new ODSystemError("ODSlashCommandComparator:convertCommand() is not supported for other types than 'ChatInput'!")
const nameLoc = cmd.nameLocalizations ?? {} const nameLoc = cmd.nameLocalizations ?? {}
const descLoc = cmd.descriptionLocalizations ?? {} const descLoc = cmd.descriptionLocalizations ?? {}
return { return {
@@ -812,6 +812,10 @@ export class ODSlashCommandManager extends ODManager<ODSlashCommand> {
//command is registered (and may need to be updated) //command is registered (and may need to be updated)
const universalBuilder = this.comparator.convertBuilder(instance.builder,instance.guildId) const universalBuilder = this.comparator.convertBuilder(instance.builder,instance.guildId)
const universalCmd = this.comparator.convertCommand(cmd) const universalCmd = this.comparator.convertCommand(cmd)
//command is not of the type 'chatinput'
if (!universalBuilder || !universalCmd) return
const didChange = !this.comparator.compare(universalBuilder,universalCmd) const didChange = !this.comparator.compare(universalBuilder,universalCmd)
const requiresUpdate = didChange || (instance.requiresUpdate ? instance.requiresUpdate(universalCmd) : false) const requiresUpdate = didChange || (instance.requiresUpdate ? instance.requiresUpdate(universalCmd) : false)
registered.push({instance,cmd:universalCmd,requiresUpdate}) registered.push({instance,cmd:universalCmd,requiresUpdate})
@@ -821,8 +825,10 @@ export class ODSlashCommandManager extends ODManager<ODSlashCommand> {
}) })
cmds.forEach((cmd) => { cmds.forEach((cmd) => {
//command does not exist in the manager //command does not exist in the manager (only append to unused when type == 'chatinput')
unused.push({instance:null,cmd:this.comparator.convertCommand(cmd),requiresUpdate:false}) const universalCmd = this.comparator.convertCommand(cmd)
if (!universalCmd) return
unused.push({instance:null,cmd:universalCmd,requiresUpdate:false})
}) })
return {registered,unregistered,unused} return {registered,unregistered,unused}
+2
View File
@@ -611,6 +611,7 @@ export class ODButtonResponderInstance {
getMessageComponent(type:"button"|"string-dropdown"|"user-dropdown"|"channel-dropdown"|"role-dropdown"|"mentionable-dropdown", id:string|RegExp): discord.ButtonComponent|discord.StringSelectMenuComponent|discord.RoleSelectMenuComponent|discord.ChannelSelectMenuComponent|discord.MentionableSelectMenuComponent|discord.UserSelectMenuComponent|null { getMessageComponent(type:"button"|"string-dropdown"|"user-dropdown"|"channel-dropdown"|"role-dropdown"|"mentionable-dropdown", id:string|RegExp): discord.ButtonComponent|discord.StringSelectMenuComponent|discord.RoleSelectMenuComponent|discord.ChannelSelectMenuComponent|discord.MentionableSelectMenuComponent|discord.UserSelectMenuComponent|null {
let result: discord.ButtonComponent|discord.StringSelectMenuComponent|discord.RoleSelectMenuComponent|discord.ChannelSelectMenuComponent|discord.MentionableSelectMenuComponent|discord.UserSelectMenuComponent|null = null let result: discord.ButtonComponent|discord.StringSelectMenuComponent|discord.RoleSelectMenuComponent|discord.ChannelSelectMenuComponent|discord.MentionableSelectMenuComponent|discord.UserSelectMenuComponent|null = null
this.message.components.forEach((row) => { this.message.components.forEach((row) => {
if (row.type != discord.ComponentType.ActionRow) return
row.components.forEach((component) => { row.components.forEach((component) => {
if (type == "button" && component.type == discord.ComponentType.Button && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component if (type == "button" && component.type == discord.ComponentType.Button && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component
else if (type == "string-dropdown" && component.type == discord.ComponentType.StringSelect && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component else if (type == "string-dropdown" && component.type == discord.ComponentType.StringSelect && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component
@@ -898,6 +899,7 @@ export class ODDropdownResponderInstance {
getMessageComponent(type:"button"|"string-dropdown"|"user-dropdown"|"channel-dropdown"|"role-dropdown"|"mentionable-dropdown", id:string|RegExp): discord.ButtonComponent|discord.StringSelectMenuComponent|discord.RoleSelectMenuComponent|discord.ChannelSelectMenuComponent|discord.MentionableSelectMenuComponent|discord.UserSelectMenuComponent|null { getMessageComponent(type:"button"|"string-dropdown"|"user-dropdown"|"channel-dropdown"|"role-dropdown"|"mentionable-dropdown", id:string|RegExp): discord.ButtonComponent|discord.StringSelectMenuComponent|discord.RoleSelectMenuComponent|discord.ChannelSelectMenuComponent|discord.MentionableSelectMenuComponent|discord.UserSelectMenuComponent|null {
let result: discord.ButtonComponent|discord.StringSelectMenuComponent|discord.RoleSelectMenuComponent|discord.ChannelSelectMenuComponent|discord.MentionableSelectMenuComponent|discord.UserSelectMenuComponent|null = null let result: discord.ButtonComponent|discord.StringSelectMenuComponent|discord.RoleSelectMenuComponent|discord.ChannelSelectMenuComponent|discord.MentionableSelectMenuComponent|discord.UserSelectMenuComponent|null = null
this.message.components.forEach((row) => { this.message.components.forEach((row) => {
if (row.type != discord.ComponentType.ActionRow) return
row.components.forEach((component) => { row.components.forEach((component) => {
if (type == "button" && component.type == discord.ComponentType.Button && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component if (type == "button" && component.type == discord.ComponentType.Button && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component
else if (type == "string-dropdown" && component.type == discord.ComponentType.StringSelect && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component else if (type == "string-dropdown" && component.type == discord.ComponentType.StringSelect && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component
+17 -17
View File
@@ -350,10 +350,10 @@ export class ODOptionSuffixManager extends ODManager<ODOptionSuffix> {
} }
/**Instantly get the suffix from an `ODTicketOption`. */ /**Instantly get the suffix from an `ODTicketOption`. */
getSuffixFromOption(option:ODTicketOption,user:discord.User): string|null { async getSuffixFromOption(option:ODTicketOption,user:discord.User): Promise<string|null> {
const suffix = this.getAll().find((suffix) => suffix.option.id.value == option.id.value) const suffix = this.getAll().find((suffix) => suffix.option.id.value == option.id.value)
if (!suffix) return null if (!suffix) return null
return suffix.getSuffix(user) return await suffix.getSuffix(user)
} }
} }
@@ -374,7 +374,7 @@ export class ODOptionSuffix extends ODManagerData {
} }
/**Get the suffix for a new ticket. */ /**Get the suffix for a new ticket. */
getSuffix(user:discord.User): string { async getSuffix(user:discord.User): Promise<string> {
throw new ODSystemError("Tried to use an unimplemented ODOptionSuffix!") throw new ODSystemError("Tried to use an unimplemented ODOptionSuffix!")
} }
} }
@@ -387,7 +387,7 @@ export class ODOptionSuffix extends ODManagerData {
* Use `getSuffix()` to get the new suffix! * Use `getSuffix()` to get the new suffix!
*/ */
export class ODOptionUserNameSuffix extends ODOptionSuffix { export class ODOptionUserNameSuffix extends ODOptionSuffix {
getSuffix(user:discord.User): string { async getSuffix(user:discord.User): Promise<string> {
return user.username return user.username
} }
} }
@@ -400,7 +400,7 @@ export class ODOptionUserNameSuffix extends ODOptionSuffix {
* Use `getSuffix()` to get the new suffix! * Use `getSuffix()` to get the new suffix!
*/ */
export class ODOptionUserIdSuffix extends ODOptionSuffix { export class ODOptionUserIdSuffix extends ODOptionSuffix {
getSuffix(user:discord.User): string { async getSuffix(user:discord.User): Promise<string> {
return user.id return user.id
} }
} }
@@ -426,11 +426,11 @@ export class ODOptionCounterDynamicSuffix extends ODOptionSuffix {
async #init(){ async #init(){
if (!await this.database.exists("opendiscord:option-suffix-counter",this.option.id.value)) await this.database.set("opendiscord:option-suffix-counter",this.option.id.value,0) if (!await this.database.exists("opendiscord:option-suffix-counter",this.option.id.value)) await this.database.set("opendiscord:option-suffix-counter",this.option.id.value,0)
} }
getSuffix(user:discord.User): string { async getSuffix(user:discord.User): Promise<string> {
const rawCurrentValue = this.database.get("opendiscord:option-suffix-counter",this.option.id.value) const rawCurrentValue = await this.database.get("opendiscord:option-suffix-counter",this.option.id.value)
const currentValue = (typeof rawCurrentValue != "number") ? 0 : rawCurrentValue const currentValue = (typeof rawCurrentValue != "number") ? 0 : rawCurrentValue
const newValue = currentValue+1 const newValue = currentValue+1
this.database.set("opendiscord:option-suffix-counter",this.option.id.value,newValue) await this.database.set("opendiscord:option-suffix-counter",this.option.id.value,newValue)
return newValue.toString() return newValue.toString()
} }
} }
@@ -456,12 +456,12 @@ export class ODOptionCounterFixedSuffix extends ODOptionSuffix {
async #init(){ async #init(){
if (!await this.database.exists("opendiscord:option-suffix-counter",this.option.id.value)) await this.database.set("opendiscord:option-suffix-counter",this.option.id.value,0) if (!await this.database.exists("opendiscord:option-suffix-counter",this.option.id.value)) await this.database.set("opendiscord:option-suffix-counter",this.option.id.value,0)
} }
getSuffix(user:discord.User): string { async getSuffix(user:discord.User): Promise<string> {
const rawCurrentValue = this.database.get("opendiscord:option-suffix-counter",this.option.id.value) const rawCurrentValue = await this.database.get("opendiscord:option-suffix-counter",this.option.id.value)
const currentValue = (typeof rawCurrentValue != "number") ? 0 : rawCurrentValue const currentValue = (typeof rawCurrentValue != "number") ? 0 : rawCurrentValue
const newValue = (currentValue >= 9999) ? 0 : currentValue+1 const newValue = (currentValue >= 9999) ? 0 : currentValue+1
this.database.set("opendiscord:option-suffix-counter",this.option.id.value,newValue) await this.database.set("opendiscord:option-suffix-counter",this.option.id.value,newValue)
if (newValue.toString().length == 1) return "000"+newValue.toString() if (newValue.toString().length == 1) return "000"+newValue.toString()
else if (newValue.toString().length == 2) return "00"+newValue.toString() else if (newValue.toString().length == 2) return "00"+newValue.toString()
else if (newValue.toString().length == 3) return "0"+newValue.toString() else if (newValue.toString().length == 3) return "0"+newValue.toString()
@@ -501,13 +501,13 @@ export class ODOptionRandomNumberSuffix extends ODOptionSuffix {
if (history.includes(number)) return this.#generateUniqueValue(history) if (history.includes(number)) return this.#generateUniqueValue(history)
else return number else return number
} }
getSuffix(user:discord.User): string { async getSuffix(user:discord.User): Promise<string> {
const rawCurrentValues = this.database.get("opendiscord:option-suffix-history",this.option.id.value) const rawCurrentValues = await this.database.get("opendiscord:option-suffix-history",this.option.id.value)
const currentValues = ((Array.isArray(rawCurrentValues)) ? rawCurrentValues : []) as string[] const currentValues = ((Array.isArray(rawCurrentValues)) ? rawCurrentValues : []) as string[]
const newValue = this.#generateUniqueValue(currentValues) const newValue = this.#generateUniqueValue(currentValues)
currentValues.push(newValue) currentValues.push(newValue)
if (currentValues.length > 50) currentValues.shift() if (currentValues.length > 50) currentValues.shift()
this.database.set("opendiscord:option-suffix-history",this.option.id.value,currentValues) await this.database.set("opendiscord:option-suffix-history",this.option.id.value,currentValues)
return newValue return newValue
} }
} }
@@ -539,13 +539,13 @@ export class ODOptionRandomHexSuffix extends ODOptionSuffix {
if (history.includes(hex)) return this.#generateUniqueValue(history) if (history.includes(hex)) return this.#generateUniqueValue(history)
else return hex else return hex
} }
getSuffix(user:discord.User): string { async getSuffix(user:discord.User): Promise<string> {
const rawCurrentValues = this.database.get("opendiscord:option-suffix-history",this.option.id.value) const rawCurrentValues = await this.database.get("opendiscord:option-suffix-history",this.option.id.value)
const currentValues = ((Array.isArray(rawCurrentValues)) ? rawCurrentValues : []) as string[] const currentValues = ((Array.isArray(rawCurrentValues)) ? rawCurrentValues : []) as string[]
const newValue = this.#generateUniqueValue(currentValues) const newValue = this.#generateUniqueValue(currentValues)
currentValues.push(newValue) currentValues.push(newValue)
if (currentValues.length > 50) currentValues.shift() if (currentValues.length > 50) currentValues.shift()
this.database.set("opendiscord:option-suffix-history",this.option.id.value,currentValues) await this.database.set("opendiscord:option-suffix-history",this.option.id.value,currentValues)
return newValue return newValue
} }
} }
+44 -46
View File
@@ -15,7 +15,7 @@ import * as discord from "discord.js"
* *
* The 2 default built-in transcript generators are: `opendiscord:html-compiler` & `opendiscord:text-compiler`. * The 2 default built-in transcript generators are: `opendiscord:html-compiler` & `opendiscord:text-compiler`.
*/ */
export class ODTranscriptManager extends ODManager<ODTranscriptCompiler<any>> { export class ODTranscriptManager extends ODManager<ODTranscriptCompiler<any,null|object>> {
/**The manager responsible for collecting all messages in a channel. */ /**The manager responsible for collecting all messages in a channel. */
collector: ODTranscriptCollector collector: ODTranscriptCollector
/**Alias for the client manager. */ /**Alias for the client manager. */
@@ -31,12 +31,12 @@ export class ODTranscriptManager extends ODManager<ODTranscriptCompiler<any>> {
/**## ODTranscriptCompilerInitFunction `type` /**## ODTranscriptCompilerInitFunction `type`
* This function will initiate/prepare the transcript system for an incoming transcript. * This function will initiate/prepare the transcript system for an incoming transcript.
*/ */
export type ODTranscriptCompilerInitFunction = (ticket:ODTicket, channel:discord.TextChannel, user:discord.User) => (ODTranscriptCompilerInitResult)|Promise<ODTranscriptCompilerInitResult> export type ODTranscriptCompilerInitFunction<InitData extends object|null> = (ticket:ODTicket, channel:discord.TextChannel, user:discord.User) => (ODTranscriptCompilerInitResult<InitData>)|Promise<ODTranscriptCompilerInitResult<InitData>>
/**## ODTranscriptCompilerCompileFunction `type` /**## ODTranscriptCompilerCompileFunction `type`
* This function will generate/compile the transcript itself. * This function will generate/compile the transcript itself.
*/ */
export type ODTranscriptCompilerCompileFunction<Data extends object> = (ticket:ODTicket, channel:discord.TextChannel, user:discord.User) => ODTranscriptCompilerCompileResult<Data>|Promise<ODTranscriptCompilerCompileResult<Data>> export type ODTranscriptCompilerCompileFunction<Data extends object,InitData extends object|null> = (ticket:ODTicket, channel:discord.TextChannel, user:discord.User, initData:InitData) => ODTranscriptCompilerCompileResult<Data>|Promise<ODTranscriptCompilerCompileResult<Data>>
/**## ODTicketClearFilter `type` /**## ODTicketClearFilter `type`
* This function will finish, clear-up & shut-down the transcript system. This will also initiate the sending of the messages to all recipients. * This function will finish, clear-up & shut-down the transcript system. This will also initiate the sending of the messages to all recipients.
@@ -46,13 +46,15 @@ export type ODTranscriptCompilerReadyFunction<Data extends object> = (result:ODT
/**## ODTranscriptCompilerInitResult `interface` /**## ODTranscriptCompilerInitResult `interface`
* This is the result which is returned by the `init()` function. * This is the result which is returned by the `init()` function.
*/ */
export interface ODTranscriptCompilerInitResult { export interface ODTranscriptCompilerInitResult<InitData extends object|null> {
/**Was the initialization successfull? */ /**Was the initialization successfull? */
success:boolean, success:boolean,
/**When not successfull, what was the reason? This will also be shown to the user. */ /**When not successfull, what was the reason? This will also be shown to the user. */
errorReason:string|null, errorReason:string|null,
/**An optional message which will be sent while the transcript is being generated. */ /**An optional message which will be sent while the transcript is being generated. */
pendingMessage:ODMessageBuildResult|null pendingMessage:ODMessageBuildResult|null,
/**An optional object containing data from the init() function which can be used in the compiler. */
initData:InitData,
} }
/**## ODTranscriptCompilerCompileResult `interface` /**## ODTranscriptCompilerCompileResult `interface`
@@ -98,15 +100,15 @@ export interface ODTranscriptCompilerReadyResult {
* *
* These functions should be defined when creating this compiler. Existing compilers already exist for html & text transcripts. * These functions should be defined when creating this compiler. Existing compilers already exist for html & text transcripts.
*/ */
export class ODTranscriptCompiler<Data extends object> extends ODManagerData { export class ODTranscriptCompiler<Data extends object,InitData extends (object|null)> extends ODManagerData {
/*Initialise the system every time a transcript is created. Returns optional "pending" message to display while the transcript is being compiled. */ /*Initialise the system every time a transcript is created. Returns optional "pending" message to display while the transcript is being compiled. */
init: ODTranscriptCompilerInitFunction|null init: ODTranscriptCompilerInitFunction<InitData>|null
/*Compile or create the transcript. Returns data to give to the ready() function for message creation. */ /*Compile or create the transcript. Returns data to give to the ready() function for message creation. */
compile: ODTranscriptCompilerCompileFunction<Data>|null compile: ODTranscriptCompilerCompileFunction<Data,InitData>|null
/*Unload the system & create the final transcript message that will be sent. */ /*Unload the system & create the final transcript message that will be sent. */
ready: ODTranscriptCompilerReadyFunction<Data>|null ready: ODTranscriptCompilerReadyFunction<Data>|null
constructor(id:ODValidId, init?:ODTranscriptCompilerInitFunction, compile?:ODTranscriptCompilerCompileFunction<Data>, ready?:ODTranscriptCompilerReadyFunction<Data>|null){ constructor(id:ODValidId, init?:ODTranscriptCompilerInitFunction<InitData>, compile?:ODTranscriptCompilerCompileFunction<Data,InitData>, ready?:ODTranscriptCompilerReadyFunction<Data>|null){
super(id) super(id)
this.init = init ?? null this.init = init ?? null
this.compile = compile ?? null this.compile = compile ?? null
@@ -119,8 +121,8 @@ export class ODTranscriptCompiler<Data extends object> extends ODManagerData {
* It's used to generate typescript declarations for this class. * It's used to generate typescript declarations for this class.
*/ */
export interface ODTranscriptCompilerIds { export interface ODTranscriptCompilerIds {
"opendiscord:html-compiler":ODTranscriptCompiler<{url:string}>, "opendiscord:html-compiler":ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}>,
"opendiscord:text-compiler":ODTranscriptCompiler<{contents:string}>, "opendiscord:text-compiler":ODTranscriptCompiler<{contents:string},null>,
} }
/**## ODTranscriptManager_Default `default_class` /**## ODTranscriptManager_Default `default_class`
@@ -131,16 +133,16 @@ export interface ODTranscriptCompilerIds {
*/ */
export class ODTranscriptManager_Default extends ODTranscriptManager { export class ODTranscriptManager_Default extends ODTranscriptManager {
get<QuestionId extends keyof ODTranscriptCompilerIds>(id:QuestionId): ODTranscriptCompilerIds[QuestionId] get<QuestionId extends keyof ODTranscriptCompilerIds>(id:QuestionId): ODTranscriptCompilerIds[QuestionId]
get(id:ODValidId): ODTranscriptCompiler<any>|null get(id:ODValidId): ODTranscriptCompiler<any,null|object>|null
get(id:ODValidId): ODTranscriptCompiler<any>|null { get(id:ODValidId): ODTranscriptCompiler<any,null|object>|null {
return super.get(id) return super.get(id)
} }
remove<QuestionId extends keyof ODTranscriptCompilerIds>(id:QuestionId): ODTranscriptCompilerIds[QuestionId] remove<QuestionId extends keyof ODTranscriptCompilerIds>(id:QuestionId): ODTranscriptCompilerIds[QuestionId]
remove(id:ODValidId): ODTranscriptCompiler<any>|null remove(id:ODValidId): ODTranscriptCompiler<any,null|object>|null
remove(id:ODValidId): ODTranscriptCompiler<any>|null { remove(id:ODValidId): ODTranscriptCompiler<any,null|object>|null {
return super.remove(id) return super.remove(id)
} }
@@ -257,6 +259,7 @@ export class ODTranscriptCollector {
const rows: ODTranscriptComponentRowData[] = [] const rows: ODTranscriptComponentRowData[] = []
msg.components.forEach((row) => { msg.components.forEach((row) => {
const components: ODTranscriptComponentRowData["components"] = [] const components: ODTranscriptComponentRowData["components"] = []
if (row.type != discord.ComponentType.ActionRow) return
row.components.forEach((component) => { row.components.forEach((component) => {
if (component.type == discord.ComponentType.Button){ if (component.type == discord.ComponentType.Button){
components.push({ components.push({
@@ -697,7 +700,7 @@ export interface ODTranscriptReactionData extends ODTranscriptEmojiData {
* The structure of the data sent to the Open Ticket HTML Transcripts v2 API. * The structure of the data sent to the Open Ticket HTML Transcripts v2 API.
*/ */
export interface ODTranscriptHtmlV2Data { export interface ODTranscriptHtmlV2Data {
version:"2", version:"2.1",
otversion:string, otversion:string,
language:string, language:string,
style:{ style:{
@@ -733,25 +736,33 @@ export interface ODTranscriptHtmlV2Data {
ticket:{ ticket:{
name:string, name:string,
id:string, id:string,
guildname:string, guildname:string,
guildid:string, guildid:string,
guildinvite:string|false, guildinvite:string|false,
creatorname:string, createdname:string|false,
creatorid:string, createdid:string|false,
closedname:string|false,
closedid:string|false,
claimedname:string|false,
claimedid:string|false,
pinnedname:string|false,
pinnedid:string|false,
deletedname:string|false,
deletedid:string|false,
closedbyname:string, createdpfp:string|false,
closedbyid:string, closedpfp:string|false,
claimedpfp:string|false,
pinnedpfp:string|false,
deletedpfp:string|false,
claimedname:string, createdtime:number|false,
claimedid:string, closedtime:number|false,
claimedtime:number|false,
creatorpfp:string, pinnedtime:number|false,
closedbypfp:string, deletedtime:number|false,
claimedpfp:string,
closedtime:number,
openedtime:number,
components:{ components:{
messages:number, messages:number,
@@ -915,22 +926,9 @@ export interface ODTranscriptHtmlV2Data {
*/ */
export interface ODTranscriptHtmlV2Response { export interface ODTranscriptHtmlV2Response {
status:"success"|"error", status:"success"|"error",
id:string, type:"transcript",
url:string,
availableUntil:number, //UNIMPLEMENTED
time:number, time:number,
estimated:{ id:string
lastdump: number,
processtime:number,
waittime:number
},
transcriptstatus:{
value:2,
data:{
fetchedmsgs:true,
uploaded:true,
inqueue:true,
processed:false,
waiting:false,
available:false
}
}
} }
+16 -1
View File
@@ -13,5 +13,20 @@ export const migrations = [
for (const panel of (await globalDatabase.getCategory("opendiscord:panel-update") ?? [])){ for (const panel of (await globalDatabase.getCategory("opendiscord:panel-update") ?? [])){
globalDatabase.set("opendiscord:panel-message",panel.key,panel.value) globalDatabase.set("opendiscord:panel-message",panel.key,panel.value)
} }
}) }),
//MIGRATE TO v4.0.2
new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.2"),async () => {},async () => {}),
//MIGRATE TO v4.0.3
new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.3"),async () => {},async () => {}),
//MIGRATE TO v4.0.4
new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.4"),async () => {},async () => {}),
//MIGRATE TO v4.0.5
new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.5"),async () => {},async () => {}),
//MIGRATE TO v4.0.6
new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.6"),async () => {},async () => {})
] ]
+1 -1
View File
@@ -441,7 +441,7 @@ export const defaultPanelsStructure = new api.ODCheckerArrayStructure("opendisco
{key:"id",optional:false,priority:0,checker:new api.ODCheckerCustomStructure_UniqueId("opendiscord:panel-id","openticket","panel-ids",{regex:/^[A-Za-z0-9-éèçàêâôûî]+$/,minLength:3,maxLength:40})}, {key:"id",optional:false,priority:0,checker:new api.ODCheckerCustomStructure_UniqueId("opendiscord:panel-id","openticket","panel-ids",{regex:/^[A-Za-z0-9-éèçàêâôûî]+$/,minLength:3,maxLength:40})},
{key:"name",optional:false,priority:0,checker:new api.ODCheckerStringStructure("opendiscord:panel-name",{minLength:3,maxLength:50})}, {key:"name",optional:false,priority:0,checker:new api.ODCheckerStringStructure("opendiscord:panel-name",{minLength:3,maxLength:50})},
{key:"dropdown",optional:false,priority:0,checker:new api.ODCheckerBooleanStructure("opendiscord:panel-dropdown",{})}, {key:"dropdown",optional:false,priority:0,checker:new api.ODCheckerBooleanStructure("opendiscord:panel-dropdown",{})},
{key:"options",optional:false,priority:0,checker:new api.ODCheckerCustomStructure_UniqueIdArray("opendiscord:panel-options","openticket","option-ids","option-ids-used",{allowDoubles:false,maxLength:25})}, {key:"options",optional:false,priority:0,checker:new api.ODCheckerCustomStructure_UniqueIdArray("opendiscord:panel-options","openticket","option-ids","option-ids-used",{allowDoubles:false,minLength:1,maxLength:25})},
//EMBED & TEXT //EMBED & TEXT
{key:"text",optional:false,priority:0,checker:new api.ODCheckerStringStructure("opendiscord:panel-text",{maxLength:4096})}, {key:"text",optional:false,priority:0,checker:new api.ODCheckerStringStructure("opendiscord:panel-text",{maxLength:4096})},
+1
View File
@@ -30,6 +30,7 @@ export const loadAllLanguages = async () => {
opendiscord.languages.add(new api.ODJsonLanguage("opendiscord:russian","russian.json")) opendiscord.languages.add(new api.ODJsonLanguage("opendiscord:russian","russian.json"))
opendiscord.languages.add(new api.ODJsonLanguage("opendiscord:swedish","swedish.json")) opendiscord.languages.add(new api.ODJsonLanguage("opendiscord:swedish","swedish.json"))
opendiscord.languages.add(new api.ODJsonLanguage("opendiscord:vietnamese","vietnamese.json")) opendiscord.languages.add(new api.ODJsonLanguage("opendiscord:vietnamese","vietnamese.json"))
opendiscord.languages.add(new api.ODJsonLanguage("opendiscord:persian","persian.json"))
/** How to add more languages? /** How to add more languages?
* - Register the language to the manager (see above) * - Register the language to the manager (see above)
+140 -60
View File
@@ -5,7 +5,8 @@ const collector = opendiscord.transcripts.collector
const messages = opendiscord.builders.messages const messages = opendiscord.builders.messages
const transcriptConfig = opendiscord.configs.get("opendiscord:transcripts") const transcriptConfig = opendiscord.configs.get("opendiscord:transcripts")
const textConfig = transcriptConfig.data.textTranscriptStyle const textConfig = transcriptConfig.data.textTranscriptStyle
const htmlVersion = Buffer.from("b3BlbnRpY2tldFRSQU5TQ1JJUFQxMjM0","base64").toString("utf8") const htmlVersion = Buffer.from("eW91LXNob3VsZG50LWJlLWxvb2tpbmctYXQtdGhpcy0tLWZvci1tb3JlLWluZm8tY29tbWEtc2VuZC1hLW1lc3NhZ2UtdG8tZGpqMTIzZGo=","base64").toString("utf8")
const htmlDomain = atob("dC5kai1kai5iZQ==")
export const replaceHtmlTranscriptMentions = async (text:string) => { export const replaceHtmlTranscriptMentions = async (text:string) => {
const mainServer = opendiscord.client.mainServer const mainServer = opendiscord.client.mainServer
@@ -34,17 +35,30 @@ export const replaceHtmlTranscriptMentions = async (text:string) => {
return defaultroletext return defaultroletext
} }
/**
* This function is used to authenticate with the HTML Transcript API.
* It is NOT the token of the bot but an internal AUTH TOKEN from the API.
*
* Questions? Visit our discord server: https://discord.dj-dj.be
*/
function transcriptAuth(_A:{salt:number,secret:string}){
const _B = Buffer.from(_A.secret,"hex");const _C = Math["floor"](new Date().getTime()/(30*1000)).toString();const _D = Buffer.from(_C);const _E = Buffer.alloc(_D["length"]);_D.forEach((v,i) => {_E[i] = v ^ _B[i % _B["length"]];});return btoa(JSON.stringify({salt:_A.salt,secret:_A.secret,token:_E.toString("hex")}))
}
export const loadAllTranscriptCompilers = async () => { export const loadAllTranscriptCompilers = async () => {
class ODHTTPHtmlPostRequest extends api.ODHTTPPostRequest { class ODHTTPHtmlPostRequest extends api.ODHTTPPostRequest {
constructor(domain:string, htmlFinal:api.ODTranscriptHtmlV2Data){ constructor(transcriptAuth:string,htmlFinal:api.ODTranscriptHtmlV2Data){
super("https://"+domain+"/transcripts/upload?auth="+htmlVersion+"&version=2",true,{ super("https://"+htmlDomain+"/api/v2/upload?auth="+htmlVersion+"&token="+transcriptAuth,true,{
body:JSON.stringify(htmlFinal) body:JSON.stringify(htmlFinal),
headers:{
"Content-Type":"application/json"
}
}) })
} }
} }
//TEXT COMPILER //TEXT COMPILER
opendiscord.transcripts.add(new api.ODTranscriptCompiler<{contents:string}>("opendiscord:text-compiler",undefined,async (ticket,channel,user) => { opendiscord.transcripts.add(new api.ODTranscriptCompiler<{contents:string},null>("opendiscord:text-compiler",undefined,async (ticket,channel,user) => {
//COMPILE //COMPILE
const rawMessages = await collector.collectAllMessages(ticket) const rawMessages = await collector.collectAllMessages(ticket)
if (!rawMessages) return {ticket,channel,user,success:false,errorReason:"Unable to collect messages! Channel not found!",messages:null,data:null} if (!rawMessages) return {ticket,channel,user,success:false,errorReason:"Unable to collect messages! Channel not found!",messages:null,data:null}
@@ -173,27 +187,51 @@ export const loadAllTranscriptCompilers = async () => {
})) }))
//HTML COMPILER //HTML COMPILER
opendiscord.transcripts.add(new api.ODTranscriptCompiler<{url:string}>("opendiscord:html-compiler",async (ticket,channel,user) => { opendiscord.transcripts.add(new api.ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}|null>("opendiscord:html-compiler",async (ticket,channel,user) => {
//INIT //INIT
const req = new api.ODHTTPGetRequest("https://apis.dj-dj.be/transcripts/status.json",false) const req = new api.ODHTTPGetRequest(atob("aHR0cHM6Ly90LmRqLWRqLmJlL2FwaS92Mi9pbml0"),false)
const res = await req.run() const res = await req.run()
if (!res || res.status != 200 || !res.body){ //PENDING MESSAGE (not required anymore) => await messages.getSafe("opendiscord:transcript-html-progress").build("channel",{guild:channel.guild,channel,user,ticket,compiler:opendiscord.transcripts.get("opendiscord:html-compiler"),remaining:16000})
opendiscord.debugfile.writeNote("HTML Transcripts Error => status: "+res.status+", body:\n"+res.body) if (res.status == 200 && res.body){
process.emit("uncaughtException",new api.ODSystemError("HTML Transcripts INIT_COMMUNICATON error! (check otdebug.txt for details)")) const data: {salt:number,secret:string} = JSON.parse(atob(res.body))
return {success:false,errorReason:"HTML Transcripts are currently unavailable!",pendingMessage:null} return {success:true,errorReason:null,pendingMessage:null,initData:{auth:transcriptAuth(data)}}
}
else{
if (res.status == 503){
opendiscord.debugfile.writeNote("HTML Transcripts Error => status: "+res.status+", body:\n"+res.body)
process.emit("uncaughtException",new api.ODSystemError("HTML Transcripts INIT_COMMUNICATON_503 error! (check otdebug.txt for details)"))
return {success:false,errorReason:"The HTML Transcripts are currently unreachable. Please try again later.",pendingMessage:null,initData:null}
}else if (res.status == 429){
opendiscord.debugfile.writeNote("HTML Transcripts Error => status: "+res.status+", body:\n"+res.body)
process.emit("uncaughtException",new api.ODSystemError("HTML Transcripts INIT_COMMUNICATON_429 error! (check otdebug.txt for details)"))
return {success:false,errorReason:"The HTML Transcripts are currently unreachable because the bot is ratelimited. Please try again in a few minutes.",pendingMessage:null,initData:null}
}else if (res.status == 403){
opendiscord.debugfile.writeNote("HTML Transcripts Error => status: "+res.status+", body:\n"+res.body)
process.emit("uncaughtException",new api.ODSystemError("HTML Transcripts INIT_COMMUNICATON_403 error! (check otdebug.txt for details)"))
return {success:false,errorReason:"The HTML Transcripts are unreachable because the bot has been banned from using the API. If you don't know why, please contact us at https://discord.dj-dj.be",pendingMessage:null,initData:null}
}else if (res.status == 500){
opendiscord.debugfile.writeNote("HTML Transcripts Error => status: "+res.status+", body:\n"+res.body)
process.emit("uncaughtException",new api.ODSystemError("HTML Transcripts INIT_COMMUNICATON_500 error! (check otdebug.txt for details)"))
return {success:false,errorReason:"Something went wrong while compiling the HTML Transcripts, please report this error at https://discord.dj-dj.be",pendingMessage:null,initData:null}
}else if (res.status == 413){
opendiscord.debugfile.writeNote("HTML Transcripts Error => status: "+res.status+", body:\n"+res.body)
process.emit("uncaughtException",new api.ODSystemError("HTML Transcripts INIT_COMMUNICATON_413 error! (check otdebug.txt for details)"))
return {success:false,errorReason:"Unable to upload transcript, file size is too large (Max 5MB)!",pendingMessage:null,initData:null}
}else{
opendiscord.debugfile.writeNote("HTML Transcripts Error => status: "+res.status+", body:\n"+res.body)
process.emit("uncaughtException",new api.ODSystemError("HTML Transcripts INIT_COMMUNICATON_UNKNOWN error! (check otdebug.txt for details)"))
return {success:false,errorReason:"Something went wrong while compiling the HTML Transcripts, please report this error at https://discord.dj-dj.be",pendingMessage:null,initData:null}
} }
try{
const data = JSON.parse(res.body)
if (!data || data["v2"] != "online") return {success:false,errorReason:"HTML Transcripts are currently unavailable due to maintenance!",pendingMessage:null}
}catch{
opendiscord.debugfile.writeNote("HTML Transcripts Error => unable to parse status! body:\n"+res.body)
process.emit("uncaughtException",new api.ODSystemError("HTML Transcripts INIT_STATUS_PARSE error! (check otdebug.txt for details)"))
return {success:false,errorReason:"HTML Transcripts are currently unavailable due to JSON parse error!",pendingMessage:null}
} }
return {success:true,errorReason:null,pendingMessage:await messages.getSafe("opendiscord:transcript-html-progress").build("channel",{guild:channel.guild,channel,user,ticket,compiler:opendiscord.transcripts.get("opendiscord:html-compiler"),remaining:16000})} },async (ticket,channel,user,initData) => {
},async (ticket,channel,user) => {
//COMPILE //COMPILE
if (!initData) return {ticket,channel,user,success:false,errorReason:"Could not authenticate with HTML Transcript API.",messages:null,data:null}
const rawMessages = await collector.collectAllMessages(ticket) const rawMessages = await collector.collectAllMessages(ticket)
if (!rawMessages) return {ticket,channel,user,success:false,errorReason:"Unable to collect messages! Channel not found!",messages:null,data:null} if (!rawMessages) return {ticket,channel,user,success:false,errorReason:"Unable to collect messages! Channel not found!",messages:null,data:null}
const messages = await collector.convertMessagesToTranscriptData(rawMessages) const messages = await collector.convertMessagesToTranscriptData(rawMessages)
@@ -350,18 +388,14 @@ export const loadAllTranscriptCompilers = async () => {
const dsf = transcriptConfig.data.htmlTranscriptStyle.favicon const dsf = transcriptConfig.data.htmlTranscriptStyle.favicon
const creator = await opendiscord.tickets.getTicketUser(ticket,"creator") const creator = await opendiscord.tickets.getTicketUser(ticket,"creator")
const claimer = await opendiscord.tickets.getTicketUser(ticket,"claimer")
const closer = await opendiscord.tickets.getTicketUser(ticket,"closer") const closer = await opendiscord.tickets.getTicketUser(ticket,"closer")
const claimer = await opendiscord.tickets.getTicketUser(ticket,"claimer")
const pinner = await opendiscord.tickets.getTicketUser(ticket,"pinner")
const htmlFinal: api.ODTranscriptHtmlV2Data = { const htmlFinal: api.ODTranscriptHtmlV2Data = {
version:"2", version:"2.1",
otversion:opendiscord.versions.get("opendiscord:version").toString(true), otversion:opendiscord.versions.get("opendiscord:version").toString(true),
bot:{ language:opendiscord.languages.getLanguageMetadata()?.language.toLowerCase() ?? "english",
name:opendiscord.client.client.user.displayName,
id:opendiscord.client.client.user.id,
pfp:opendiscord.client.client.user.displayAvatarURL({extension:"png"}),
},
language:opendiscord.languages.getLanguageMetadata()?.language ?? "english",
style:{ style:{
background:{ background:{
backgroundData:(dsb.backgroundImage == "") ? dsb.backgroundColor : dsb.backgroundImage, backgroundData:(dsb.backgroundImage == "") ? dsb.backgroundColor : dsb.backgroundImage,
@@ -387,30 +421,44 @@ export const loadAllTranscriptCompilers = async () => {
enableCustomFavicon:dsf.enableCustomFavicon enableCustomFavicon:dsf.enableCustomFavicon
} }
}, },
bot:{
name:opendiscord.client.client.user.displayName,
id:opendiscord.client.client.user.id,
pfp:opendiscord.client.client.user.displayAvatarURL({extension:"png"}),
},
ticket:{ ticket:{
name:channel.name, name:channel.name,
id:channel.id, id:channel.id,
guildname:channel.guild.name, guildname:channel.guild.name,
guildid:channel.guild.id, guildid:channel.guild.id,
guildinvite:"", guildinvite:false,
creatorname:(creator ? creator.displayName : "<unknown>"), createdname:(creator ? creator.displayName : false),
creatorid:(creator ? creator.id : "<unknown>"), createdid:(creator ? creator.id : false),
creatorpfp:(creator ? creator.displayAvatarURL() : "https://transcripts.dj-dj.be/favicon.png"), createdpfp:(creator ? creator.displayAvatarURL() : false),
//closer is ticket deleter (small bug) closedname:(closer ? closer.displayName : false),
closedbyname:user.displayName, closedid:(closer ? closer.id : false),
closedbyid:user.id, closedpfp:(closer ? closer.displayAvatarURL() : false),
closedbypfp:user.displayAvatarURL(),
//claiming is currently unused claimedname:(claimer ? claimer.displayName : false),
claimedname:(claimer ? claimer.displayName : "<not-claimed>"), claimedid:(claimer ? claimer.id : false),
claimedid:(claimer ? claimer.id : "<not-claimed>"), claimedpfp:(claimer ? claimer.displayAvatarURL() : false),
claimedpfp:(claimer ? claimer.displayAvatarURL() : "https://transcripts.dj-dj.be/favicon.png"),
closedtime:new Date().getTime(), pinnedname:(pinner ? pinner.displayName : false),
openedtime:ticket.get("opendiscord:opened-on").value ?? new Date().getTime(), pinnedid:(pinner ? pinner.id : false),
pinnedpfp:(pinner ? pinner.displayAvatarURL() : false),
deletedname:user.displayName,
deletedid:user.id,
deletedpfp:user.displayAvatarURL(),
createdtime:ticket.get("opendiscord:opened-on").value ?? false,
closedtime:ticket.get("opendiscord:closed-on").value ?? false,
claimedtime:ticket.get("opendiscord:claimed-on").value ?? false,
pinnedtime:ticket.get("opendiscord:pinned-on").value ?? false,
deletedtime:new Date().getTime(),
//role colors are currently unused //role colors are currently unused
roleColors:[], roleColors:[],
@@ -440,39 +488,71 @@ export const loadAllTranscriptCompilers = async () => {
}, },
customFavicon:{ customFavicon:{
enabled:dsf.enableCustomFavicon, enabled:dsf.enableCustomFavicon,
image:(dsf.imageUrl) ? dsf.imageUrl : "https://transcripts.dj-dj.be/favicon.png" image:(dsf.imageUrl) ? dsf.imageUrl : "https://t.dj-dj.be/favicon.png"
}, },
additionalFlags:[] additionalFlags:[]
} }
} }
const req = new ODHTTPHtmlPostRequest("apis.dj-dj.be",htmlFinal) const req = new ODHTTPHtmlPostRequest(initData.auth,htmlFinal)
const res = await req.run() const res = await req.run()
//check status
if (!res || res.status != 200 || !res.body){
//ratelimit error
if (res.status == 429) return {ticket,channel,user,success:false,errorReason:"Failed to upload HTML Transcripts! (Ratelimit)\nTry again in a few minutes!",messages,data:null}
//unknown status error //check status
opendiscord.debugfile.writeNote("HTML Transcripts Error => status: "+res.status+", body:\n"+res.body) if (res.status == 200 && res.body){
return {ticket,channel,user,success:false,errorReason:"Failed to upload HTML Transcripts! (Unknown Error)",messages,data:null}
}
//check body //check body
try{
var data: api.ODTranscriptHtmlV2Response = JSON.parse(res.body) var data: api.ODTranscriptHtmlV2Response = JSON.parse(res.body)
if (!data || data["status"] != "success"){ if (!data || data["status"] != "success"){
opendiscord.debugfile.writeNote("HTML Transcripts Error => status: "+res.status+", body:\n"+res.body) opendiscord.debugfile.writeNote("HTML Transcripts Error => status: "+res.status+", body:\n"+res.body)
return {ticket,channel,user,success:false,errorReason:"Failed to upload HTML Transcripts! (Server 500 Error)",messages,data:null}} process.emit("uncaughtException",new api.ODSystemError("HTML Transcripts COMPILE_JSON_STATUS error! (check otdebug.txt for details)"))
}catch{ return {ticket,channel,user,success:false,errorReason:"TFailed to read the response of the HTML Transcripts server.",messages:null,data:null}
opendiscord.debugfile.writeNote("HTML Transcripts Error => status: "+res.status+", body:\n"+res.body)
return {ticket,channel,user,success:false,errorReason:"Failed to upload HTML Transcripts! (JSON parse error)",messages,data:null}
} }
const url = "https://transcripts.dj-dj.be/v2/"+data.time+"_"+data.id+".html" return {
return {ticket,channel,user,success:true,errorReason:null,messages,data:{url}} ticket,channel,user,
success:true,
errorReason:null,
messages,
data:{
url:data.url,
availableUntil:new Date(data.availableUntil)
}
}
}else{
if (res.status == 503){
opendiscord.debugfile.writeNote("HTML Transcripts Error => status: "+res.status+", body:\n"+res.body)
process.emit("uncaughtException",new api.ODSystemError("HTML Transcripts COMPILE_COMMUNICATON_503 error! (check otdebug.txt for details)"))
return {ticket,channel,user,success:false,errorReason:"The HTML Transcripts are currently unreachable. Please try again later.",messages:null,data:null}
}else if (res.status == 429){
opendiscord.debugfile.writeNote("HTML Transcripts Error => status: "+res.status+", body:\n"+res.body)
process.emit("uncaughtException",new api.ODSystemError("HTML Transcripts COMPILE_COMMUNICATON_429 error! (check otdebug.txt for details)"))
return {ticket,channel,user,success:false,errorReason:"The HTML Transcripts are currently unreachable because the bot is ratelimited. Please try again in a few minutes.",messages:null,data:null}
}else if (res.status == 403){
opendiscord.debugfile.writeNote("HTML Transcripts Error => status: "+res.status+", body:\n"+res.body)
process.emit("uncaughtException",new api.ODSystemError("HTML Transcripts COMPILE_COMMUNICATON_403 error! (check otdebug.txt for details)"))
return {ticket,channel,user,success:false,errorReason:"The HTML Transcripts are unreachable because the bot has been banned from using the API. If you don't know why, please contact us at https://discord.dj-dj.be",messages:null,data:null}
}else if (res.status == 500){
opendiscord.debugfile.writeNote("HTML Transcripts Error => status: "+res.status+", body:\n"+res.body)
process.emit("uncaughtException",new api.ODSystemError("HTML Transcripts COMPILE_COMMUNICATON_500 error! (check otdebug.txt for details)"))
return {ticket,channel,user,success:false,errorReason:"Something went wrong while compiling the HTML Transcripts, please report this error at https://discord.dj-dj.be",messages:null,data:null}
}else if (res.status == 413){
opendiscord.debugfile.writeNote("HTML Transcripts Error => status: "+res.status+", body:\n"+res.body)
process.emit("uncaughtException",new api.ODSystemError("HTML Transcripts COMPILE_COMMUNICATON_413 error! (check otdebug.txt for details)"))
return {ticket,channel,user,success:false,errorReason:"Unable to upload transcript, file size is too large (Max 5MB)!",messages:null,data:null}
}else{
opendiscord.debugfile.writeNote("HTML Transcripts Error => status: "+res.status+", body:\n"+res.body)
process.emit("uncaughtException",new api.ODSystemError("HTML Transcripts COMPILE_COMMUNICATON_UNKNOWN error! (check otdebug.txt for details)"))
return {ticket,channel,user,success:false,errorReason:"Something went wrong while compiling the HTML Transcripts, please report this error at https://discord.dj-dj.be",messages:null,data:null}
}
}
},async (result) => { },async (result) => {
//READY //READY
await utilities.timer(16000) //wait until transcript is ready //WAIT UNTIL READY (not required anymore) => await utilities.timer(16000)
return { return {
channelMessage:await messages.getSafe("opendiscord:transcript-html-ready").build("channel",{guild:result.channel.guild,channel:result.channel,user:result.user,ticket:result.ticket,result,compiler:opendiscord.transcripts.get("opendiscord:html-compiler")}), channelMessage:await messages.getSafe("opendiscord:transcript-html-ready").build("channel",{guild:result.channel.guild,channel:result.channel,user:result.user,ticket:result.ticket,result,compiler:opendiscord.transcripts.get("opendiscord:html-compiler")}),
creatorDmMessage:await messages.getSafe("opendiscord:transcript-html-ready").build("creator-dm",{guild:result.channel.guild,channel:result.channel,user:result.user,ticket:result.ticket,result,compiler:opendiscord.transcripts.get("opendiscord:html-compiler")}), creatorDmMessage:await messages.getSafe("opendiscord:transcript-html-ready").build("creator-dm",{guild:result.channel.guild,channel:result.channel,user:result.user,ticket:result.ticket,result,compiler:opendiscord.transcripts.get("opendiscord:html-compiler")}),
+1 -1
View File
@@ -20,7 +20,7 @@
INFORMATION: INFORMATION:
============ ============
Open Ticket v4.0.2 - © DJdj Development Open Ticket v4.0.6 - © DJdj Development
support us: https://github.com/sponsors/DJj123dj support us: https://github.com/sponsors/DJj123dj
discord: https://discord.dj-dj.be discord: https://discord.dj-dj.be