Compare commits

..
644 Commits
Author SHA1 Message Date
DJj123dj 8e1fd0266d Update README.md 2026-07-10 21:51:01 +02:00
DJj123dj 91d09a9096 Update package.json 2026-06-14 17:22:35 +02:00
DJj123dj d54a922146 Update package.json 2026-06-03 20:18:26 +02:00
DJj123dj c27733b245 Updated OD Framework to v2.0.4 2026-06-03 18:08:01 +02:00
Jasper 8a2fa0b4ff Open Ticket v4.2.1
Open Ticket v4.2.1
2026-06-01 19:36:43 +02:00
DJj123dj 44561e2690 Updated example plugin 2026-06-01 19:28:20 +02:00
DJj123dj 77ab113fc0 Removed deprecated panel entries in database 2026-06-01 19:16:03 +02:00
DJj123dj 97a7a966c8 File uploads will now be sent as attachments 2026-06-01 19:14:08 +02:00
DJj123dj becf0ee50d Open Ticket v4.2.1: Versioning 2026-05-31 22:41:33 +02:00
DJj123dj 1e66cf9917 OT v4.2.1: Fixed TS bug with shared components 2026-05-31 22:37:54 +02:00
Jasper 2eb6d9e981 Small README improvements + updated example plugin
Small README improvements + updated example plugin
2026-05-31 18:48:09 +02:00
DJj123dj 0245420313 Update README.md 2026-05-31 18:46:28 +02:00
DJj123dj 6555f16012 Transferred sponsors SVG to separate repository 2026-05-31 18:32:55 +02:00
DJj123dj 7f3624bcee Update README.md 2026-05-31 18:06:35 +02:00
DJj123dj 2e6fa61b4f Updated example plugin 2026-05-31 17:15:50 +02:00
Jasper 849c688e56 Open Ticket v4.2
Open Ticket v4.2
2026-05-27 18:51:20 +02:00
Jasper 6babc5e4b8 Open Ticket v4.2 --> Dev Branch
Open Ticket v4.2 --> Dev Branch
2026-05-26 20:45:35 +02:00
DJj123dj 4606ddac3c Open Ticket v4.2 🎉 2026-05-26 20:44:29 +02:00
DJj123dj e6ab09dbbd Added new v4.2 Preview Images 2026-05-26 20:16:58 +02:00
DJj123dj 39427cdbea Update updateTicketTopic.ts 2026-05-26 19:27:49 +02:00
DJj123dj adfcb1c82f Bugfixes 2026-05-25 14:34:21 +02:00
DJj123dj 6c994f6f86 (v4.2.0) Topic change (DM) logs 2026-05-25 12:28:20 +02:00
DJj123dj 4cfde9f5c4 (v4.2.0) Added all v4.2 translations 2026-05-25 12:18:23 +02:00
DJj123dj fd1e0d6bdb (v4.2.0) Added new translation sentences 2026-05-25 11:16:33 +02:00
DJj123dj e7475af694 (v4.2.0) Added /transcripts history command 2026-05-25 10:47:28 +02:00
DJj123dj 9da066e99e Add: Transfer ticket & Priority change (DM) logs 2026-05-24 22:21:01 +02:00
DJj123dj 45f15a2df6 (v4.2.0) Create ticket for another user (admin only) 2026-05-24 21:53:54 +02:00
DJj123dj 58a6bcde45 (v4.2.0) Added priority dropdown 2026-05-24 19:48:46 +02:00
DJj123dj eb44f41d3a (API) Renamed "ODCode" classes to "ODTask" (improved readability) 2026-05-24 09:47:30 +02:00
DJj123dj 66c5bc4565 Docker improvements 2026-05-23 21:52:58 +02:00
Jasper 22d4caf03e chore: update Docker setup (by MauroDruwel)
chore: update Docker setup
2026-05-23 21:04:52 +02:00
DJj123dj 77dde68edc Update build-docker.sh 2026-05-23 21:00:57 +02:00
DJj123dj c8c8a94d6f Merge branch 'dev-v4.2' into pr/208 2026-05-23 20:56:46 +02:00
DJj123dj 6c41aecfa7 Bugfixes & Improvements
Added "maximum buttons per row" in panels. Fixed reaction role reply glitching when replyOnReactionRole was disabled. Panel dropdowns now support reaction role & sub-panel options.
2026-05-23 16:45:01 +02:00
DJj123dj c64220cad4 (v4.2.0) Added sub-panels 2026-05-23 15:53:52 +02:00
DJj123dj 7f02dd5848 (v4.2.0) Added closed ticket channel emoij (#199) 2026-05-23 14:52:57 +02:00
DJj123dj c442e50cb4 (v4.2.0) Panel auto-update now uses message states 2026-05-23 14:32:22 +02:00
DJj123dj 4af9b9e17f (v4.2.0) Added 5 new question types
Added support for dropdown, radio select, checkbox select, file upload & text display question types.
2026-05-23 14:30:56 +02:00
MauroDruwel 98d13c6569 chore: update Dockerfile and rename build script for multi-architecture support 2026-05-23 11:34:54 +02:00
MauroDruwel 345a64f51a chore: update Docker Compose configuration for Open Ticket 2026-05-23 11:22:59 +02:00
MauroDruwel 45080ccd96 chore: update Docker setup
- Replace lowercase dockerfile with proper Dockerfile
- Add .dockerignore for cleaner builds
- Add build.sh script
- Update docker-compose.yml: separate volumes for config, database, plugins; set restart policy to unless-stopped; remove deprecated version field
2026-05-23 11:15:49 +02:00
DJj123dj 87c034d215 (v4.2.0) Large README overhaul (Part 2) 2026-05-22 18:21:32 +02:00
DJj123dj 1b2e38f524 Update README.md 2026-05-20 21:59:24 +02:00
DJj123dj 8f780992aa Update README.md 2026-05-20 21:57:25 +02:00
DJj123dj a28bcd4f8b (v4.2.0) Large README overhaul (Part 1) 2026-05-20 21:55:18 +02:00
Jasper a0b3aff661 Added khmer language (Cambodja) (by yuuslokrobjakkroval)
Added khmer language (Cambodja)
2026-05-20 15:20:01 +02:00
JasperAtSchool 9ca375ee2c Solved merge conflicts 2026-05-20 10:42:17 +02:00
DJj123dj 0f9ae79d49 (v4.2.0) Interactive Setup CLI Bugfixes 2026-05-19 22:20:06 +02:00
DJj123dj dd8d5a12d6 Open Ticket v4.2: Config Update (JSONC) 2026-05-17 22:28:23 +02:00
DJj123dj afd7f80b8d Code Cleanup & Improved channel rename errors 2026-05-15 22:30:24 +02:00
DJj123dj ca5faa3365 (v4.2.0) Reworked ticket channel name logic 2026-05-15 22:01:19 +02:00
DJj123dj cf9ddf58d0 (v4.2.0) Fixed all known bugs 2026-05-15 22:00:55 +02:00
DJj123dj 15ff345948 (v4.2.0) Reworked ticket category logic 2026-05-15 12:30:14 +02:00
DJj123dj 0c45a0ad6a Added labels to verifybars (improved accesibility) 2026-05-14 23:36:21 +02:00
DJj123dj e6f6aa1af4 Code cleanup & bugfixes 2026-05-14 23:13:38 +02:00
DJj123dj 1a530aae4c Finished Message States & Overhauled Verifybars 2026-05-14 21:39:50 +02:00
DJj123dj 67f4417ee6 English Improvements (Part 2) 2026-05-14 21:36:11 +02:00
DJj123dj b5e15921ef Minor Improvements + Code Cleanup 2026-05-09 11:45:52 +02:00
DJj123dj cb8afdf9a6 Message States (Part 2) + Component Modifiers 2026-05-08 21:46:13 +02:00
DJj123dj 7030b7011c Message States (Part 1) 2026-05-08 17:17:59 +02:00
DJj123dj 7dd8a57a83 Implemented ODStates (Message States) 2026-05-06 21:11:53 +02:00
DJj123dj 5763659900 Minor Bugfixes 2026-05-06 20:45:10 +02:00
DJj123dj 65334a8a25 Renamed OT Id Lists to Mappings 2026-05-04 21:44:12 +02:00
DJj123dj 4be54399a6 (v4.2.0) Improved English sentences and language 2026-05-04 21:21:44 +02:00
DJj123dj 1f9fa54344 Implemented ODComponents (Part 2) 2026-05-04 19:24:15 +02:00
DJj123dj e4b4acfd9f Rename: "source" to "origin" for improved readability 2026-05-04 19:05:58 +02:00
DJj123dj 6bfa0e0f10 Implemented ODComponents (Part 1) 2026-05-03 22:05:14 +02:00
DJj123dj 4eb9331bf4 Replaced #func() methods with TS: private func() 2026-05-03 22:04:38 +02:00
DJj123dj 10f5ae9d44 Update package.json 2026-04-19 18:16:29 +02:00
DJj123dj 27a9f04d83 Update codeLoader.ts 2026-04-19 17:46:43 +02:00
DJj123dj 600419f763 Typescript Bugfixes (Switched CJS -> MJS) 2026-04-19 17:43:59 +02:00
yuuslokrobjakkroval a18b19da66 Refactor code structure for improved readability and maintainability 2026-04-19 02:26:08 +07:00
DJj123dj 230ef70d86 Update package.json 2026-04-18 19:13:13 +02:00
DJj123dj 2d9a9b42d4 Moved many utility files to one big "tools" folder 2026-04-03 13:38:12 +02:00
DJj123dj 50c7fc5e90 (v4.2) Open Discord Framework Update (Part 3) 2026-04-03 13:27:20 +02:00
DJj123dj fa8bc0eb6c (v4.2) Open Discord Framework Update (Part 2)
Replaced all "Default" classes & types with ID mappings & improved types. Updated Interactive Setup CLI & certain events, renamed ODStat's to ODStatistics. Moved many classes, types & interfaces to the framework
2026-04-03 11:18:59 +02:00
Jasper f42b70d1b9 Update german.json (by imLudwig)
Update german.json
2026-03-24 20:21:12 +01:00
DJj123dj 4c2a617a51 Removed line ending 2026-03-24 20:19:52 +01:00
Ludwig a1198866f3 Update german.json
`s is no german plural syntax

WARNUNGS -> WARNUNGEN
2026-03-20 07:24:05 +01:00
DJj123dj fe3f2d04a9 Translation: traditional chinese (by me.october) 2026-03-10 20:50:40 +01:00
DJj123dj cb8139b8a0 (v4.2) Open Discord Framework Update (Part 1) 2026-02-16 22:12:25 +01:00
Jasper ddae7b5e46 Open Ticket v4.1.3
Open Ticket v4.1.3
2026-02-16 10:38:43 +01:00
DJj123dj 32c9a6b4f3 Update README.md 2026-02-16 10:30:16 +01:00
DJj123dj 0ad24ba89f (v4.1.3) Finished adding all missing languages 2026-02-16 10:23:14 +01:00
DJj123dj 5412416166 Updated plugin.json format (backwards compatible) 2026-02-15 13:19:48 +01:00
DJj123dj 78a937d4e9 (v4.1.3) Fixed unintended cooldown bug with modals 2026-02-15 13:13:18 +01:00
DJj123dj 5b45dc265b Readme improvements (last time 😄 ) 2026-02-14 16:12:57 +01:00
DJj123dj 4b210fe793 Readme Improvements 2026-02-14 16:11:46 +01:00
DJj123dj 8891320bdf Update README.md 2026-02-14 15:53:43 +01:00
DJj123dj 8ccfd5c4eb (v4.1.3) Added all missing translations from v4.1 2026-02-14 15:52:39 +01:00
DJj123dj 44074004e4 Update pluginLauncher.ts 2026-02-11 20:53:21 +01:00
DJj123dj 2f1c885b4f Update README.md 2026-02-11 20:43:28 +01:00
Jasper c94867280d Merge pull request #193 from SKaranjaN/feature/plugin-json-improvements
feat: improve plugin.json with multiple authors, versions, and pre-compilation dependency checking
2026-02-11 20:40:20 +01:00
DJj123dj 138f7fa2bb Small Improvements for the new plugin.json code 2026-02-11 20:37:28 +01:00
DJj123dj 465eda1c24 (v4.1.3) Updated README + plugin list 2026-02-11 19:54:06 +01:00
DJj123dj c821e7dd6d Fixed typo in LICENSE.md 2026-02-11 18:45:54 +01:00
DJj123dj f9ce496cc5 Update quickSetup.ts 2026-02-11 17:48:35 +01:00
Karanja-Stephen 3989fb5f76 refactor: simplify comments and make them less verbose 2026-02-11 10:44:51 +03:00
Karanja-Stephen 779efca39a feat: improve plugin.json with multiple authors, versions, and pre-compilation dependency checking
- Add support for multiple authors and contributors in plugin.json
- Maintain backwards compatibility with single author (string) format
- Add versions array to specify compatible Open Ticket versions (e.g., OTv4.0.x, ODv1.0.0)
- Implement version compatibility checking during plugin loading
- Read plugin.json files before TypeScript compilation to check npm dependencies
- Warn about missing npm dependencies before compilation starts
- Update example plugin to demonstrate new features

Fixes #162
2026-02-10 13:13:24 +03:00
DJj123dj 4976aa3d45 Added v4.1 Lithuanian translations (by TsgIndrius) 2026-02-08 21:17:34 +01:00
DJj123dj 9cdff2c1de Added v4.1 French translations (by @guillee3 ) 2026-02-08 13:29:04 +01:00
DJj123dj 2e29947ba5 Update README.md 2026-02-08 12:43:53 +01:00
DJj123dj 0aa3dca63b Added v4.1 Italian translations (by imperatorix_17) 2026-02-08 12:26:22 +01:00
Jasper 90851f881d Open Ticket v4.1.2
Open Ticket v4.1.2
2026-02-06 21:25:32 +01:00
DJj123dj b972c97871 Fixed: Unknown interaction when on cooldown 2026-02-06 21:16:30 +01:00
DJj123dj db94f226fb Fixed: Panel embed was replaced with cooldown error 2026-02-06 20:59:36 +01:00
DJj123dj 6a4f40d862 (v4.1.2) Readme updates & general improvements 2026-02-06 20:48:21 +01:00
DJj123dj 1f402a848e (v4.1.2) Massive permission system cleanup 2026-02-06 20:08:55 +01:00
DJj123dj 24d98aeaeb (v4.1.2) Fixed autocomplete bug with many options 2026-02-06 17:45:31 +01:00
DJj123dj b95b8f239e Fixed typescript compilation error 2026-01-01 23:00:29 +01:00
DJj123dj 488b5fce53 Fixed fetch() errors of unknown guild members 2025-12-27 10:42:10 +01:00
DJj123dj c2117a67ed Updated German translation for v4.1 2025-12-03 16:20:17 +01:00
Jasper d31be1bb57 Open Ticket v4.1.1
Open Ticket v4.1.1
2025-11-16 11:44:45 +01:00
DJj123dj 76095bea30 Update README.md 2025-11-16 11:33:16 +01:00
DJj123dj da962c6c2e Major bugfixes & improvements for v4.1 2025-11-16 11:23:15 +01:00
DJj123dj a89d5c2149 Added 7 updated translations for v4.1 2025-11-16 10:43:46 +01:00
DJj123dj 7d5313c77e Open Ticket v4.1.1 2025-11-16 10:11:56 +01:00
Jasper 16f1be32a3 Open Ticket v4.1.0
Open Ticket v4.1.0
2025-11-09 19:11:57 +01:00
DJj123dj e1a6feea6e Updated README.md language list 2025-11-09 19:05:53 +01:00
DJj123dj 9668851a82 Added 9 updated translations for v4.1 2025-11-09 13:04:51 +01:00
DJj123dj 68d6a2df3f Added language merge utility tool 2025-11-09 12:51:18 +01:00
DJj123dj f835850b3f Translated code strings using language manager 2025-11-09 12:50:57 +01:00
Jasper f7fa0998b6 v4.1 Minor Bugfixes
v4.1 Minor Bugfixes
2025-11-05 14:55:05 +01:00
JasperAtSchool 4416736947 Merge branch 'open-discord-bots:dev-v4.1.0' into dev-v4.1.0 2025-11-05 14:53:43 +01:00
JasperAtSchool 5494c1ad8f (v4.1) Minor Bugfixes 2025-11-05 14:53:05 +01:00
DJj123dj 4147658575 README Updates 2025-11-05 14:42:26 +01:00
DJj123dj f7cda48ed6 Improved LICENSE Terminology 2025-11-04 20:07:18 +01:00
DJj123dj 4b485adf82 (v4.1) Additional autoclose/autodelete features 2025-11-04 19:53:40 +01:00
DJj123dj e55438cc67 (v4.1) Added +/-10 Minor Features & Improvements 2025-11-04 19:39:52 +01:00
DJj123dj c7b44232c4 Added transfer command (/transfer) + new stats
With this command you're able to transfer the ticket ownership to another person in the server.
2025-11-02 20:09:38 +01:00
DJj123dj 68a8170570 Minor bugfixes & improvements (priority & topic) 2025-11-02 20:08:57 +01:00
DJj123dj 34ed4edede Added priority commands (/priority get,set) 2025-11-02 18:41:46 +01:00
DJj123dj a40a9b8be8 Added channel topic command (/topic set) 2025-11-02 18:40:49 +01:00
DJj123dj e8f96ef84f Finished channel topic feature 2025-10-28 13:24:08 +01:00
DJj123dj 8413d3c2b7 Started with channel topic auto-update action 2025-10-27 21:19:59 +01:00
DJj123dj 30b6ab4df6 Finished channel topic on ticket creation 2025-10-27 11:41:56 +01:00
DJj123dj 2aef855902 Started working on channel topic again 2025-10-12 22:18:38 +02:00
DJj123dj 4aacdd1607 fix: #122 improved windows OT plugin support
Open Ticket instances with plugins are now also able to exist outside of the default C:\\ drive on windows. This has been fixed by searching for the plugins relative to the bot instead of using an absolute path.
2025-09-21 20:31:47 +02:00
Jasper d66925a450 Added user-nickname channel suffix option 2025-09-14 22:23:42 +02:00
DJj123dj d2cd6be513 Small nickname suffix fixes & discord.js try-catch 2025-09-14 22:22:09 +02:00
DJj123dj 30a0a6c503 (API) Renamed ODPriority --> ODPriorityLevel 2025-09-14 22:09:09 +02:00
DJj123dj 72f84b2566 (API) Class & comment readability improvements 2025-09-14 22:05:30 +02:00
DJj123dj 6ce017b407 Added /topic set command (Part 1, Incomplete) 2025-09-14 22:04:42 +02:00
DJj123dj 415330be21 Added priority system (Part 1, Incomplete) 2025-09-14 22:04:11 +02:00
Steven DUBOIS 21ce2921a1 Add user-nickname option for channel suffixe 2025-09-10 18:38:57 +02:00
DJj123dj b07252151b #181 : Fixed async permission registration issues 2025-08-28 12:46:37 +02:00
DJj123dj 02d37dd177 (API) Implemented opendiscord:reopened in database 2025-08-28 11:25:18 +02:00
DJj123dj 706006e319 Added 9 new statistics in the /stats command
Ticket volume, Average tickets/user, System uptime, Current tickets, Ticket age, Message/Embed/File/Component amount.
2025-08-28 11:20:02 +02:00
DJj123dj 82f2aeaa90 Added autocomplete to panel, ticket & move cmds
Ticket/panel options are now autocompleted instead of being a choice in the slash commands. This also results in the max amount of tickets limit to be increased to infinity.
2025-08-28 09:00:07 +02:00
DJj123dj 793c6f0603 Added: Slow Mode & Updated discord.js 2025-08-28 08:59:16 +02:00
DJj123dj 1ef74f0b6b Custom reason for create-ticket-permissions action
Added support for custom reasons in the opendiscord:create-ticket-permissions action. Now it's easier for plugins to add a custom message when the validation fails.
2025-08-27 14:10:58 +02:00
DJj123dj 337dc3827e Refactor config checker children options
Made the "priority" and "optional" fields in ODCheckerObjectStructure children optional. This improves readability and code simplicity
2025-08-27 11:57:28 +02:00
DJj123dj 810db76e91 Finished adding 10 new config checker validators 2025-08-27 11:46:42 +02:00
DJj123dj f4f6f30fa2 Added: Show global admins in panel message 2025-08-12 14:19:18 +02:00
DJj123dj 8436b19cbf Updated bot versions to v4.1.0 2025-08-05 10:42:35 +02:00
DJj123dj 549c161830 Added all the new config variables for v4.1.0! 2025-08-05 10:42:15 +02:00
DJj123dj adc2433216 Merge branch 'dev' into dev-v4.1.0 2025-06-24 11:05:59 +02:00
Jasper 3b3c0aff96 Open Ticket v4.0.7
Open Ticket v4.0.7
2025-06-24 10:46:44 +02:00
DJj123dj ce6ca6fc09 Update livestatus.json 2025-06-24 10:42:04 +02:00
DJj123dj e3bc985c0c Updated all versions to v4.0.7 2025-06-24 10:38:33 +02:00
DJj123dj ff8568fde7 Added the 8 new languages to the system + readme 2025-06-24 09:05:13 +02:00
DJj123dj 8ec710fa55 Renamed simplified-chinese translation file 2025-06-24 08:49:39 +02:00
Jasper 076fcbcb37 Added 8 new languages by HanumeshGupta (used AI)
Added Language and update Readme
2025-06-24 08:46:56 +02:00
DJj123dj 6df3498cb5 Finished autocomplete & context menu interactions
Autocomplete & context menu interactions have been fully implemented in the Open Discord framework. They have not yet been implemented in the Open Ticket bot code though.
2025-06-24 08:43:57 +02:00
DJj123dj 8116d4d8dd Startscreen plugin list rendering improvements 2025-06-21 22:17:31 +02:00
DJj123dj e987c176b7 Add autocomplete manager + context menu bugfixes 2025-06-21 22:16:50 +02:00
DJj123dj 2ea38cd7a5 (Open Discord) Added support for context menu's 2025-06-20 18:20:27 +02:00
DJj123dj b2f2ef3405 Update quickSetup.ts 2025-06-20 15:59:52 +02:00
DJj123dj c2e6f781b9 Finished Quick Setup CLI 2025-06-19 22:43:38 +02:00
Hanumesh Gupta 8dfd17ddde Added Tamil and updated readme 2025-06-19 22:01:14 +05:30
Hanumesh Gupta 5f077e87f6 Added more Language and edited readme 2025-06-19 15:48:18 +05:30
Hanumesh Gupta 76dc3b1022 Added More Language and Updated Readme 2025-06-19 15:20:22 +05:30
Hanumesh Gupta 93ed56b4ae Added Language and update Readme 2025-06-19 12:46:03 +05:30
DJj123dj 160f89c7cf Improved inline contributor guides
Improved the inline contributor guides for registering new languages, config variables & commands.
2025-06-16 20:11:00 +02:00
DJj123dj 51c4ae0229 Finished Interactive Update CLI Questions
Added all remaining questions including panel configuration, ticket message layout, ticket limits, emoji style & more. Also fixed some smaller bugs.
2025-06-16 20:10:09 +02:00
DJj123dj 2cc2ccc68e Added ODQuickMessage builders 2025-06-16 17:45:28 +02:00
DJj123dj 0a29e13640 Added new questions to quick setup CLI + fixes
Added question 12, 13 & 14 (autoclose, cooldown, close participants policy. Also fixed backFn-bugs and rewrote a few sentences for better spelling. Also added some UI improvements to string-inputs
2025-06-16 15:37:57 +02:00
DJj123dj 31b94718f1 Repositioned + Tested Reaction Role Logs 2025-06-16 14:47:09 +02:00
Jasper 6ac993617e Merge pull #176 from sdehaarte (Reaction Role Logs)
Added Reaction Role Logs
2025-06-16 14:44:08 +02:00
sdehaarte 9f4999b89b Feature Reaction Role Logs. Adds logging functionality for reaction roles. This helps track when users add or remove reaction roles. 2025-06-11 20:06:43 -04:00
DJj123dj dd3c159413 Added new questions to quick setup CLI
Added: channel logs, ticket category, ticket creation count, ticket option configuration (name, descr, button, prefix & suffix)
2025-06-11 21:12:20 +02:00
DJj123dj 72627a7058 Added new config checker utility function
createTemporaryCheckerEnvironment() is able to help you with using `ODCheckerStructure` validators without officially registering them in opendiscord.checkers.
2025-06-11 21:10:29 +02:00
Jasper b683365126 Merge pull request #175 from JasperAtSchool/dev-v4.1.0
(v4.1) Added new string config checker validators (part 1)
2025-06-11 18:51:01 +02:00
JasperAtSchool 03b3495eb2 (v4.1) Added new string config checker validators 2025-06-06 11:14:21 +02:00
Jasper a6be9df213 Fixed validation in UniqueIdArray checker (by guillee3)
Fixed validation in UniqueIdArray checker
2025-06-01 17:58:38 +02:00
guillee3 6b2f291122 Fixed validation in ODCheckerCustomStructure_UniqueIdArray to reject string inputs. 2025-06-01 15:02:46 +02:00
DJj123dj af0dc879c6 Merge branch 'dev' into dev-v4.1.0 2025-05-31 11:07:36 +02:00
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
DJj123dj c243d03216 Merge branch 'dev' into dev-v4.1.0 2025-05-03 21:15:03 +02:00
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
DJj123dj f117943e00 Added 6th, 7th & 8th questions to quick setup CLI 2025-05-02 17:51:52 +02:00
DJj123dj 951aff093a Added 4th & 5th questions to quick setup 2025-05-01 22:01:04 +02:00
DJj123dj 2acd185d6f Merge branch 'dev' into dev-v4.1.0 2025-05-01 14:26:41 +02:00
DJj123dj 2fbef46a53 Merge branch 'dev' of https://github.com/open-discord-bots/open-ticket into dev 2025-05-01 14:14:39 +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 8df13b0d36 Open Ticket v4.1.0 Improvements + Minor Additions
Open Ticket v4.1.0 Improvements + Minor Additions
2025-05-01 13:52:45 +02:00
DJj123dj b5dd7158df Update README.md 2025-04-29 17:56:54 +02:00
DJj123dj 05919bb57e Update README.md 2025-04-29 17:51:39 +02:00
DJj123dj 1d6572aa36 Merge branch 'dev' of https://github.com/open-discord-bots/open-ticket into dev 2025-04-29 17:50:51 +02:00
JasperAtSchool 83080a6e4d Removed openticket -> opendiscord migration utils 2025-04-29 09:58:36 +02:00
JasperAtSchool 35fdafb21d Removed deprecated API classes + properties 2025-04-29 09:54:48 +02:00
JasperAtSchool a0e03be103 Added ordinal numbers to config checker. 2025-04-29 09:47:29 +02:00
Jasper d404f343e0 Sync Dev Branches
* Fixed bug due to discord.js new components

* Updated all versions to v4.0.3

* #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:30:43 +02:00
Jasper adf4acd443 Merge branch 'dev-v4.1.0' into dev 2025-04-28 18:30:21 +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
DJj123dj fd739054fd Added 3th & 4th question to Quick Setup CLI 2025-04-20 12:08:52 +02:00
DJj123dj 2d1724893e Update README.md 2025-04-20 11:14:19 +02:00
DJj123dj 7696202dec Updated Dutch Translations 2025-04-19 21:05:08 +02:00
DJj123dj e36c1992de Added 2nd question in the CLI quick setup 2025-04-17 18:38:54 +02:00
DJj123dj e73c8e9b3b Started with CLI "Quick Setup" feature. 2025-04-16 21:44:23 +02:00
DJj123dj ad623f9650 Finished display names + descriptions (Part 4) 2025-04-16 13:20:07 +02:00
DJj123dj 515b7e1ffc Added more display names + descriptions (Part 3) 2025-04-16 09:18:13 +02:00
DJj123dj 605173e788 Added more display names + descriptions (Part 2) 2025-04-15 22:36:58 +02:00
DJj123dj e129724c12 Added display values for all general.json settings 2025-04-14 14:53:31 +02:00
DJj123dj 49504bc3de Added formatters to all built-in config files.
Added formatters to all built-in JSON config files for the Open Ticket interactive CLI. The new save() feature from the ODJsonConfig class will be using this formatter to save the config to the filesystem.
2025-04-14 14:22:09 +02:00
Jasper f414fd77fc Synced Dev Branches
Sync Dev Branches
2025-04-13 21:11:40 +02:00
DJj123dj 5dcbcbfabc More CLI improvements + layout changes 2025-04-13 21:03:55 +02:00
DJj123dj 6ec228df53 Added 'save()' feature to configs + improvements 2025-04-13 21:03:45 +02:00
DJj123dj 1f3894141a Finished the 'edit config' module from the CLI 2025-04-13 10:33:01 +02:00
DJj123dj 9253377766 CLI improvements 2025-04-12 21:05:52 +02:00
Jasper 6355fb5562 Open Ticket v4.0.2
Open Ticket v4.0.2
2025-04-12 19:19:06 +02:00
DJj123dj 442c201994 Updated all version badges to v4.0.2 2025-04-12 19:02:57 +02:00
DJj123dj b61f9d4d5a Update README.md 2025-04-12 18:57:53 +02:00
DJj123dj 129053b9f5 Fixed autoclose hours showing the wrong number.
Fixed that the ticket message embed shows the wrong amount of hours when used manually with /autoclose enable
2025-04-08 22:06:22 +02:00
DJj123dj 35a0511b97 Merge branch 'dev' of https://github.com/open-discord-bots/open-ticket into dev 2025-04-08 22:01:38 +02:00
DJj123dj bae221056c Fixed #149 Tickets not changing categories 2025-04-08 22:01:36 +02:00
DJj123dj 9c6e4ccde4 Update checkerLoader.ts 2025-04-08 21:59:08 +02:00
Roppl3r ac6845b4d4 Fixed Issue #151 (Max length for option 'name' should be 45, currently set to 50)
Fixed config checker bug related to the name of a ticket option in a dropdown.
2025-04-08 21:58:03 +02:00
DJj123dj 30352b570a Updated Interactive Setup CLI (Unfinished Part 2) 2025-04-08 13:51:01 +02:00
DJj123dj 1fddad1e96 Improved TS interfaces for the config checker 2025-04-08 13:49:59 +02:00
DJj123dj 75770c84b2 Update README.md preview images 2025-04-08 09:03:41 +02:00
DJj123dj 2281d78896 Implemented Vietnamese translations 2025-04-07 18:13:23 +02:00
ngocdiep2006 37cc3b794e Added Vietnamese translation
Create vietnamese.json
2025-04-07 18:07:59 +02:00
DJj123dj d545d21bb1 Update cli.ts 2025-04-07 16:47:57 +02:00
DJj123dj 5f79ae909b Added Interactive Setup CLI (Unfinished)
Added the first part of the interactive setup CLI. You can explore the interface but some parts will not work yet. It will also not save to the config file yet.

The "Quick Setup" & "Manage Plugins" parts of the CLI will arrive later this week.
2025-04-06 19:04:09 +02:00
DJj123dj 831e120093 Finished --silent flag 2025-04-05 22:18:45 +02:00
DJj123dj 376fa23288 Started working on --silent flag 2025-04-04 22:40:15 +02:00
Jasper 9414b96221 Open Ticket v4.0.1
Open Ticket v4.0.1
2025-04-02 14:49:08 +02:00
Jasper 0befd2860e Open Ticket v4.0.1
Open Ticket v4.0.1
2025-04-02 14:35:53 +02:00
DJj123dj 74d4ac24f2 Added new plugins to README.md 2025-04-02 07:34:42 +02:00
DJj123dj 364bf4f702 #144 : Added quick builders for plugins 2025-04-01 20:12:42 +02:00
DJj123dj dd5b76f3d8 Update README.md 2025-03-31 21:36:07 +02:00
DJj123dj a02ba56e9a Updated README.md 2025-03-31 17:54:10 +02:00
DJj123dj 6d5bdc5dd4 #143 : Panels now edit after using dropdown
From now on, all panels will update/edit themselfs after a dropdown has been used. This will reset the dropdown selection in the user client which results in a smoother user experience.
2025-03-29 13:16:27 +01:00
DJj123dj 51bfb1a367 #126 : ODManagers now use Maps instead of Arrays
This results in a minor speed increase within large managers (e.g. builders, tickets, blacklist, ...)
2025-03-29 13:14:59 +01:00
DJj123dj d85d842046 #142 : ODVersion + ODHTTPRequest improvements
Added new methods to ODVersion class & added User-Agent header to ODHTTPRequest classes
2025-03-29 13:13:35 +01:00
DJj123dj 53136e0e6c Fixed .DS_Store bug in plugin launcher 2025-03-29 13:10:58 +01:00
DJj123dj 2031a82523 #141 : Finished type simplifications 2025-03-29 13:10:27 +01:00
DJj123dj 453c48fab5 Update init.ts 2025-03-28 17:36:50 +01:00
DJj123dj fd3bc0e7b9 API: allowCategoryChange param in related actions
Added the 'allowCategoryChange' parameter in related ticket actions (claim, unclaim, close, reopen) to disable the changing of the category. This can be used by plugins not wanting the category of the channel to change.
2025-03-27 16:30:37 +01:00
DJj123dj f316ae83e7 Update CONTENT_CREATORS.md 2025-03-26 15:29:31 +01:00
DJj123dj d2c5cf0fc1 Added extra comments in some places 2025-03-26 15:24:56 +01:00
DJj123dj 45dfc18c1d Updated all file versions to v4.0.1 2025-03-26 15:14:11 +01:00
DJj123dj d81b1e7be3 The 4 new languages can now be used in OTv4.0.1 2025-03-26 15:13:55 +01:00
Jasper 2a82bdebae Added 4 new languages (by NoOneNook)
Added 4 new languages + updated README.md
2025-03-26 14:54:39 +01:00
NoOneNook c9e13b2471 Update README.md 2025-03-25 23:58:45 +01:00
NoOneNook cbeac2fda2 Update README.md 2025-03-25 23:50:12 +01:00
NoOneNook 8b1dd7d27a Update README.md 2025-03-25 23:47:34 +01:00
NoOneNook 9e7cd28c6a Russian language file
I created a Russian language file using AI. This file has been verified in several other places and was also reviewed using ChatGPT afterwards to ensure that everything is correct, properly structured, and contains the necessary translations and messages for the system.

ChatGPT was not used for translation, only to check that the entire file is correctly written in the Russian language
2025-03-25 23:46:52 +01:00
NoOneNook fabe11bfd1 Update README.md 2025-03-25 23:22:26 +01:00
NoOneNook 79187b9995 Add files via upload 2025-03-25 23:21:29 +01:00
NoOneNook a1251cf11c Delete languages/latvian.json
Wrong file!
This language will be translated soon
2025-03-25 22:46:28 +01:00
NoOneNook 1bc8b2b401 Latvian (coming soon)
tarted in a new language. Soon to be finished.
2025-03-25 22:43:51 +01:00
NoOneNook ce727e52b0 Update on swedish.json
Updated 
"translators": ["NoOneNook / ItsNook_"],
to 
"translators": ["NoOneNook"],
2025-03-25 22:13:24 +01:00
NoOneNook 30233df7b0 Update on norwegian.json
Updated "translators": ["NoOneNook"], to "translators": ["NoOneNook"],
2025-03-25 22:10:54 +01:00
NoOneNook 48d3296868 Delete languages/README.md
Deleted README.md from wrong folder
2025-03-25 22:01:09 +01:00
NoOneNook 6b8ef26b4c Remove README.md
Deleted README.md text from wrong folder
2025-03-25 22:00:25 +01:00
NoOneNook 9c992c3dbd name fix
Updated readme below the lines for Norwegian and Swedish
2025-03-25 21:58:19 +01:00
NoOneNook 6feb56c25c Name fix
Fixed lines for Norwegian and Swedish
2025-03-25 21:56:40 +01:00
NoOneNook e29b6afd87 Translate update
Updated readme below the lines for Norwegian and Swedish
2025-03-25 21:54:18 +01:00
NoOneNook d35b7fca99 Add files via upload
Norwegian and Swedish translation complete
2025-03-25 21:49:40 +01:00
DJj123dj 126fada990 Merge branch 'dev' 2025-03-25 18:44:56 +01:00
DJj123dj bd4929f11b Updated all URLs for repository transfer 2025-03-25 17:49:42 +01:00
DJj123dj d28fcf40d7 Fixed broken flag alias using --dev-database 2025-03-22 11:08:09 +01:00
DJj123dj bed4e2a56a Improved CONTRIBUTING.md & SECURITY.md markdown 2025-03-16 18:35:25 +01:00
DJj123dj ba3a35a343 Added official Open Ticket Pterodactyl eggs! 2025-03-16 18:34:43 +01:00
DJj123dj 1e159c9bab Improved dockerfile & compose 2025-03-12 22:13:00 +01:00
DJj123dj e7ad3dd50b Fixed startup crash codes (for Docker) 2025-03-12 22:12:51 +01:00
DJj123dj 177dee7468 Type simplifications (for documentation) 2025-02-27 20:51:59 +01:00
DJj123dj 0d40c23aa8 Fixed HTML Transcripts "member not found" error. 2025-02-19 15:48:37 +01:00
DJj123dj 15eef95fdd Decreased /clear speed to reduce ratelimit chances 2025-02-19 15:43:43 +01:00
DJj123dj c89e93d33d Fixed crash resulting of non-returning statements 2025-02-19 15:29:16 +01:00
DJj123dj e6c413cdf5 Fixed typos in comments 2025-02-18 18:18:10 +01:00
DJj123dj b12556120c Made database migration compatible with plugins 2025-02-17 19:44:18 +01:00
DJj123dj 58674452d8 Added quick setup to README.md 2025-02-15 19:01:53 +01:00
DJj123dj a2f9593d55 Fixed #134 : text transcripts incorrect newlines 2025-02-15 18:22:23 +01:00
DJj123dj 9702c4d97d Fixed stats resetting due to breaking change 2025-02-12 16:27:34 +01:00
DJj123dj f13777e5f3 Update README.md 2025-02-09 11:34:37 +01:00
DJj123dj 9395e9af75 Added 13 new utility events for plugins 2025-02-09 11:19:03 +01:00
DJj123dj b2a5e65fe2 Update README.md 2025-02-09 11:18:24 +01:00
DJj123dj 071c8f953c Update createDocs.js 2025-02-05 17:04:10 +01:00
DJj123dj 9a4e5e2175 Merge branch 'dev' of https://github.com/DJj123dj/open-ticket into dev 2025-02-04 17:42:37 +01:00
DJj123dj 4e709f2a0b Update createDocs.js 2025-02-04 17:42:24 +01:00
Jasper 27e3e78439 Fixed dateString() utility
Fixed dateString() utility
2025-02-03 21:28:51 +01:00
DJj123dj 06e7919162 Fixed panel dropdown bug with empty option label 2025-02-03 21:01:36 +01:00
Roppl3r bf952e3ef7 Fixed month parsing in dateString() utility causing incorrect dates in text transcripts. 2025-02-02 20:23:32 +01:00
DJj123dj a397b66c9e Update createDocs.js 2025-02-01 11:52:02 +01:00
DJj123dj 27f6e3a81f Compiler will now only hash JS & TS files 2025-02-01 11:23:17 +01:00
DJj123dj f2cefae37c database will auto-update for the breaking change 2025-02-01 11:22:49 +01:00
DJj123dj 6acbf74846 BREAKING: changed all ids to "opendiscord:" 2025-02-01 10:29:35 +01:00
DJj123dj 29f8e1452c BREAKING: changed openticket to opendiscord in API 2025-02-01 10:22:27 +01:00
DJj123dj ce242741cd Update README.md 2025-02-01 10:05:26 +01:00
DJj123dj ac587568d3 Update createDocs.js 2025-01-31 17:14:56 +01:00
DJj123dj f5e78949d7 Added typedoc for OT Docs API Reference 2025-01-31 16:03:02 +01:00
DJj123dj 8e7fe4e502 Update README.md 2025-01-29 21:36:26 +01:00
DJj123dj e51cc54090 Fixed polish translation 2025-01-29 19:50:31 +01:00
Jasper dc3515da10 Added Polish Translation
Added Polish Translation
2025-01-29 19:47:25 +01:00
Jasper c57f3397a4 Update checker.ts 2025-01-29 19:46:04 +01:00
Jasper 686b45b0bd Added Polish Translation
Added Polish Language 🇵🇱
2025-01-29 19:43:53 +01:00
DJj123dj 96d6758b4a Update README.md 2025-01-29 19:35:10 +01:00
DanoGlez 52b49ec564 Added Custom Emojis
feat: allow custom emojis by modifying checker
2025-01-28 23:23:18 +00:00
DanoGlez deebd2b758 Added Polish 2025-01-28 23:14:55 +00:00
DJj123dj ed9afffd70 Finished API comments 2025-01-28 18:16:14 +01:00
Jasper 91cad963e5 Added new API comments (part 9-12)
Added new API comments (part 9-12)
2025-01-28 17:50:23 +01:00
JasperAtSchool baa4e35878 Added new API comments (part 12) 2025-01-28 14:33:10 +01:00
JasperAtSchool f6c70fa62a Added new API comments (part 11) 2025-01-28 14:22:26 +01:00
JasperAtSchool 58fb7b7512 Added new API comments (part 10) 2025-01-28 14:16:43 +01:00
JasperAtSchool 5e1cfe7942 Added new API comments (part 9) 2025-01-28 11:21:49 +01:00
DJj123dj 507d254556 Added new API comments (part 8) 2025-01-27 23:37:49 +01:00
DJj123dj 43356fef05 Added Lithuanian translation (by tsgindrius) 2025-01-27 23:15:58 +01:00
DJj123dj bbae139c6b Updated README.md 2025-01-25 23:10:45 +01:00
DJj123dj 6516857866 Fixed deprecation of HTML Transcripts interactions 2025-01-25 22:54:50 +01:00
DJj123dj 213ec32225 Fixed small bugs 2025-01-25 14:06:41 +01:00
DJj123dj 04789d5426 Fixed #121 : Ticket busy will now reset on reboot 2025-01-25 11:47:50 +01:00
DJj123dj 0437af1507 Fixed #120 : Temporarily removed bot status state
Will be added back in a future update, but customisable instead of double text :)
2025-01-25 11:43:13 +01:00
DJj123dj 73d188c5dc Fixed #129 : Improved invalid token error 2025-01-25 11:28:32 +01:00
DJj123dj 057a5fc6ae Fixed #124 : DMs are now sent to ticket creator 2025-01-25 11:18:10 +01:00
DJj123dj d35eb8f8bf Updated issue templates 2025-01-25 10:56:18 +01:00
DJj123dj 19e5902320 Fixed: checker not working correctly using .env
Fixed the config checker not working correctly when parsing the token from the .env file.
2025-01-24 17:34:05 +01:00
DJj123dj 66b0377a2b Update index.ts 2025-01-22 17:11:01 +01:00
DJj123dj 3bd308007c Updated sponsors 2025-01-22 16:58:24 +01:00
DJj123dj 40bd873a33 Added new API comments (part 7) 2025-01-22 15:13:13 +01:00
Jasper 09d9b2d265 Added new API comments (part 6)
Added new API comments (part 6)
2025-01-21 18:51:06 +01:00
JasperAtSchool 7fb169789b Added new API comments (part 6) 2025-01-21 12:05:36 +01:00
DJj123dj 1ab207b4eb Found more missing translations 2025-01-20 20:42:23 +01:00
DJj123dj 5e5ac3e409 Implemented progress bars when loading slash cmds 2025-01-19 15:16:04 +01:00
DJj123dj 7809ffc5c6 Fixed typo's in comments 2025-01-19 15:15:29 +01:00
DJj123dj 9da823aa4b Added new progress bars API & classes 2025-01-19 00:17:39 +01:00
DJj123dj ff23b0e89e Added comment to dump command 2025-01-18 21:53:53 +01:00
DJj123dj c3474fb017 Made built-in cmds compatible with slash update 2025-01-18 20:41:12 +01:00
DJj123dj 03982f644e MAJOR: Full rewrite of slash cmd loading system
The system of detecting, comparing & registering slash cmds has been rewritten and updated for future compatibility. This will break all current plugins (so please wait until they are updated)

=> Increased speed
=> All cmd params are now used when comparing
=> Future compability & removed deprecated functions
=> New universal utility interfaces for slash commands
=> And more!
2025-01-18 20:40:52 +01:00
DJj123dj 3a30152cb2 Improved startup time (5 sec) due to config bug 2025-01-18 20:36:08 +01:00
DJj123dj 334c9dde21 Moved sponsors more to top of README.md 2025-01-14 18:14:23 +01:00
DJj123dj b6985f9d28 Updated LICENSE 2025-01-14 17:56:27 +01:00
DJj123dj 7d30bf24d9 The bot will now only re-compile when changed
The bot will now only re-compile when the plugins or source code changes. (computed using a hash)

This reduces the average startup time by 50%.
2025-01-14 17:53:11 +01:00
DJj123dj 138378ac31 Added new API comments (part 5) 2025-01-14 17:18:47 +01:00
DJj123dj 9a73ee0d01 Fixed bug with option description being empty
Fixed a bug which caused the /panel command to crash when using an option without any description in combination with the "describeOptionsInEmbedFields" mode enabled.
2025-01-14 16:46:22 +01:00
Jasper f26e6f5e99 Added new API comments (part 4)
Added new API comments (part 4)
2025-01-14 16:40:17 +01:00
JasperAtSchool 209041c1e5 Merge branch 'DJj123dj:dev' into dev 2025-01-14 16:38:39 +01:00
JasperAtSchool 499901fbf1 Added new API comments (part 4) 2025-01-14 16:37:43 +01:00
DJj123dj 1a1a3f3b02 Update README.md 2025-01-11 22:27:52 +01:00
DJj123dj dd5374f84c Update plugin.json 2025-01-10 23:01:03 +01:00
DJj123dj 02e8b7d0a1 Added new API comments (part 3) 2025-01-09 19:42:11 +01:00
DJj123dj ce0af7e1e9 Added new API comments (part 2) 2025-01-09 18:34:29 +01:00
Jasper e1fab310a4 Added new API comments (part 1)
Added new API comments (part 1)
2025-01-09 18:03:28 +01:00
JasperAtSchool 0615235780 Added new API comments (part 1) 2025-01-09 17:48:50 +01:00
DJj123dj abd672dd3b Small bug fixes (plugin system) 2025-01-07 19:36:29 +01:00
Jasper f05d2d7d1b Update README.md
Updated v4.0 beta announcement
2025-01-07 18:54:24 +01:00
DJj123dj e65a092bc0 Small bug fixes 2025-01-06 22:29:09 +01:00
DJj123dj 17e1902681 Updated discord.js to v14.17.2 2025-01-06 21:14:41 +01:00
DJj123dj 91657f7519 Fixed ot-sqlite-database plugin stats not working 2025-01-06 20:51:36 +01:00
DJj123dj cfa692b356 Updated README.md year to 2025 😄 2025-01-06 20:51:11 +01:00
Jasper 0604e334ed Open Ticket v3.5.9
**Improved:**
- Updated discord.js to `v14.17.2`

**Fixed:**
- discord.js PermissionOverwrites => `Supplied parameter is not a User nor a Role`
- message `"ephemeral"` is deprecated warning
- A few config checker typos
2025-01-04 09:52:57 +01:00
DJj123dj e9d20c0a14 Improvements + Updated discord.js to v14.17.2 2025-01-04 09:50:17 +01:00
DJj123dj 67465bfdf4 Bugfix: ephemeral in message reply is deprecated 2025-01-04 09:49:52 +01:00
DJj123dj a66d3aad2d Updated to v3.5.9 2025-01-04 09:36:42 +01:00
DJj123dj f2de7fc408 Bugfix: discord.js PermissionOverwrites id invalid 2025-01-04 09:35:48 +01:00
DJj123dj 0cbf991090 Update transcripts.json 2024-12-25 21:05:01 +01:00
DJj123dj 72f7cbce26 Improved default config message descriptions. 2024-12-25 18:21:37 +01:00
DJj123dj 05b4080ac5 Plugins can now use import path shortcuts
Plugins are now able to use import path shortcuts to import all API classes, utilities and the openticket globals. You can now import everything from "#opendiscord" instead of "../../src/index"
2024-12-25 18:20:58 +01:00
DJj123dj 7646b3fc35 Increased HTML Transcript log level 2024-12-15 20:11:39 +01:00
DJj123dj bf13e15d56 Disabled autoclose & delete by default 2024-12-15 19:47:20 +01:00
DJj123dj f0183c319a Added Hindi Translation (by an_developer) 2024-12-15 19:46:40 +01:00
DJj123dj c6e836455c Updated README.md Contributors 2024-12-15 19:46:10 +01:00
DJj123dj 8a6a8e527f Added 6 new plugins to README.md 2024-12-08 18:29:00 +01:00
DJj123dj 4e7d45ea07 Increased button label length to 80 characters 2024-12-08 18:28:49 +01:00
DJj123dj b7f5c7191d Fixed responder TS typo 2024-12-08 18:28:22 +01:00
DJj123dj 106cb0f718 Fixed dropdown not supporting empty emojis
Fixed a bug that caused the bot to crash when spawning a dropdown panel which includes an option without emoji.
2024-12-07 21:46:49 +01:00
DJj123dj 0c2b688862 Fixed English translation typo's 2024-12-07 13:27:24 +01:00
DJj123dj a037d76060 Fixed database ghosted unused-options bug
Fixed a problem where unused ticket options would stay in the options database in certain circumstances. Even when there is no ticket that uses the option anymore.
2024-12-07 00:34:49 +01:00
DJj123dj 1e2321313f Implemented "removeParticipantsOnClose"
Implemented the option "removeParticipantsOnClose" in the config/general.json. It wasn't implemented in the code by accident.
2024-12-06 15:59:08 +01:00
DJj123dj 91ea12a6cc Added Arabic translation 2024-12-06 15:44:58 +01:00
DJj123dj 5d86269743 Fixed stats not displaying with SQLite plugin
Lot's of stats were hidden in the embed when using the ot-sqlite-database plugin. This was caused by a recent API breaking-change that made everything async.

The problem wasn't related to the plugin itself, but the Open Ticket api. Updating the plugin is not required.
2024-12-05 22:10:02 +01:00
DJj123dj 42ff447a94 Added French & Turkish translations 2024-12-05 21:47:17 +01:00
Jasper 7627c07b71 Added French Translation (+ Catalan fixes)
Translations Updates
2024-12-05 21:42:33 +01:00
Guillem Parera Jové 147ebc90da - Fixed Catalan Translation.
- Added French Translation.
2024-12-05 21:03:14 +01:00
DJj123dj e8319cccea Updated README.md 2024-11-25 20:06:11 +01:00
DJj123dj 66ab30bf06 Livestatus source moved to github 2024-11-25 19:46:56 +01:00
DJj123dj d0ef2a9873 Language loading => async + moved livestatus file 2024-11-25 19:43:58 +01:00
DJj123dj 3e928ed06e Bug fixes for new database system 2024-11-25 19:24:48 +01:00
DJj123dj b22f7b2de7 major bug fixes & breaking change in database code
Major bug fixes and improvements have been made. There's also a breaking change for plugins using the database system. All database related functions are now async based.
2024-11-24 23:26:14 +01:00
DJj123dj 6b36b1caf6 Update plugin.json 2024-11-21 23:43:39 +01:00
DJj123dj f8da68607d Update client.ts 2024-11-18 20:50:02 +01:00
DJj123dj a31588f025 Small changes to the plugin loading system 2024-11-18 20:19:25 +01:00
DJj123dj 5a4b45aa3f Added Thai Translation (by ModsHD) 2024-11-14 17:50:06 +01:00
DJj123dj 92aa42fc7c ticket creator bug fix + added danish translation 2024-11-11 21:27:53 +01:00
DJj123dj 4022ae49c2 Major bug fixes + updated contributing guidelines 2024-11-06 20:59:00 +01:00
DJj123dj 319bbe318d Added previews + plugins to README.md 2024-10-28 13:52:14 +01:00
DJj123dj 970807d144 Added 2 new languages + small ODMain improvements 2024-10-28 12:29:33 +01:00
Jasper 929f57721b Added Estonian and Finnish translations (by iamnotmega) 2024-10-28 12:23:05 +01:00
NotMega 3469e61065 Update finnish.json 2024-10-26 19:45:34 +03:00
NotMega 3ddb03a569 Update estonian.json 2024-10-26 19:45:17 +03:00
NotMega 3fa72e07d8 Create finnish.json 2024-10-26 19:42:01 +03:00
NotMega 6423ed4b41 Create estonian.json 2024-10-26 19:41:36 +03:00
Jasper fc8a252e67 Translation Credits
Gives some credit to AI that notmega used while doing his translations
2024-10-21 18:29:12 +02:00
Ronalds ca9fe0aa77 add some credit to ai 2024-10-20 18:16:26 +03:00
DJj123dj 798ab8fab1 Update README.md 2024-10-16 14:22:17 +02:00
DJj123dj 848c968483 Fixed all currently known bugs :) 2024-10-14 20:30:45 +02:00
DJj123dj 330ea47ab9 Updated german & fixed async forEach errors 2024-10-07 22:24:02 +02:00
DJj123dj 4e10cba203 Added docker compatibility 2024-10-06 21:17:32 +02:00
DJj123dj 56e1fb3939 Fixed loopAll() async errors 2024-10-03 20:46:01 +02:00
DJj123dj 7c76be8473 Fixed suffix register error on config reload 2024-10-03 20:16:42 +02:00
DJj123dj 7fa5dca7b3 Updated Italian 2024-10-02 23:28:00 +02:00
DJj123dj 6d3f210612 Added Italian by fraden1mvp 2024-10-02 23:21:20 +02:00
DJj123dj 118161698e Fixed blacklist bug 2024-10-02 22:41:12 +02:00
DJj123dj 6a8a8dd34d languages/config improvements & bug fixes 2024-10-02 17:36:08 +02:00
DJj123dj 28f0d974e5 Fixes "successfully" typo. 2024-09-24 19:32:35 +02:00
DJj123dj 77c486e2b7 Update createTranscript.ts 2024-09-15 17:55:42 +02:00
DJj123dj 20bf25aa98 Small bug fixes + auto cycles are now debug only! 2024-09-12 21:14:26 +02:00
DJj123dj 70048fa399 Added in-code flags support for pterodactyl 2024-09-11 21:08:05 +02:00
DJj123dj 8eae88b1c6 Added 2 new plugins to README.md 2024-09-05 23:27:40 +02:00
DJj123dj 35b02e0a8f Added first plugins 2024-09-05 21:01:36 +02:00
DJj123dj 2a8e41005f Update init.ts 2024-09-05 20:58:57 +02:00
DJj123dj 85026793a4 Added Indonesian by erxg 2024-09-04 20:39:20 +02:00
DJj123dj 55bcff8030 fix ticket cmd perms, updated djs & added dump cmd 2024-09-04 20:13:13 +02:00
DJj123dj 39099a0dfe Fixed small translation mistakes 2024-09-02 16:10:02 +02:00
DJj123dj 504889a83d Fixed config checker emoji count 2024-09-01 21:30:56 +02:00
DJj123dj c1c80fc04d Small improvements 2024-09-01 20:55:50 +02:00
DJj123dj 4e030bf95b Fixed config checker bugs & added new flags 2024-09-01 18:38:08 +02:00
DJj123dj adae64bab9 Romanian & Ukrainian languages are now available! 2024-09-01 17:53:29 +02:00
DJj123dj bfa05297b2 Fixed plugins not loading on windows 2024-09-01 17:30:25 +02:00
DJj123dj 509e961446 Typescript will now be compiled without CLI 2024-09-01 16:27:25 +02:00
DJj123dj 147eae05b3 Testing pterodactyl compile support! 2024-09-01 11:58:16 +02:00
DJj123dj e410ceaa64 Added Ukrainian & Romanian languages 2024-08-31 21:55:52 +02:00
Jasper 51e1ca6fa3 Added Ukrainian by Anderskiy
upload a new language
2024-08-31 21:44:02 +02:00
Anderskiy e67c505e32 Add files via upload 2024-08-31 15:08:14 +03:00
DJj123dj 12885f63d6 Fixed spanish max string length issues 2024-08-23 23:24:59 +02:00
Jasper c49f577f7f Added Spanish by Josuens & Reddishye
Added Spanish Language
2024-08-23 23:21:09 +02:00
DJj123dj d5295a9480 Fixed bugs & added/updated languages! 2024-08-23 23:19:44 +02:00
DJj123dj 177ab95dba Fixed permission error & preparing for win build 2024-08-22 21:22:19 +02:00
DJj123dj 5e2e0417dc Update index.js 2024-08-22 16:17:22 +02:00
DJj123dj b3cd37bb4b Update index.js 2024-08-22 16:13:27 +02:00
DJj123dj 5512bc1134 Pterodactyl panel support part 2 2024-08-22 16:09:29 +02:00
DJj123dj 7dd9bf1ac0 OTv4 is now pterodactyl panel compatible! 2024-08-22 15:45:38 +02:00
Hugo Torres cd7fb7533f Add Spanish Language 2024-08-22 11:39:07 +02:00
DJj123dj 8e730fdfae Tried to fix typescript not working on pterodactyl 2024-08-22 10:28:24 +02:00
DJj123dj 1dd8c0246a Fixed some translation errors & added Catalan! 2024-08-21 22:46:54 +02:00
DJj123dj 0a69efdfe5 Added german translation by benzorich 2024-08-21 14:52:33 +02:00
Jasper 9028eaa16a Update README.md 2024-08-21 14:24:55 +02:00
DJj123dj 0c2aca7039 Open Ticket v4 Beta 2024-08-21 13:24:56 +02:00
DJj123dj 9326d0fae8 v4.0.0 preparations 2024-08-21 11:56:47 +02:00
Jasper e1f4936ae6 Open Ticket v3.5.8
**fixed:**
- updated hungarian translation (by kornel0706)
- updated turkish translation (by 0x15d3)
- updated portuguese translation (by quiradon)
- updated czech translation (by spyeye_)
- fixed "unknown interaction" on ticket creation (in certain situations)
2024-08-02 14:51:17 +02:00
DJj123dj fd3ae39150 v3.5.8 2024-08-02 14:46:53 +02:00
Jasper 1b0da061ba Update czech.json 2024-07-31 11:52:35 +02:00
Jasper 07eb8f34e9 Update turkish by 0x15d3
Update turkish.json
2024-07-31 11:44:27 +02:00
artren 64fef62bf5 Update turkish.json 2024-07-27 23:18:34 +03:00
Jasper b2be76f5b6 Update Portuguese by Quiradon
Update portuguese.json
2024-07-23 20:22:29 +02:00
QuiraDon 856ccc10b9 Update portuguese.json 2024-07-23 14:27:08 -03:00
Jasper 8c6681f025 Open Ticket v3.5.7
Open Ticket v3.5.7
2024-07-02 19:40:06 +02:00
DJj123dj cc21e28470 Open Ticket v3.5.7 (Part 2) 2024-07-02 19:36:42 +02:00
DJj123dj 7815400472 Open Ticket v3.5.7 (Part 1) 2024-07-01 09:46:16 +02:00
Jasper fda8a397d6 Added 8 languages from iamnotmega (Part 2)
Added 8 new languages
2024-07-01 09:39:17 +02:00
mega ae306332bb Update README.md 2024-07-01 10:30:30 +03:00
mega bc46d4ab46 Update checker.js 2024-07-01 10:17:06 +03:00
mega b0b4e21aff Create vietnamese.json 2024-07-01 07:18:19 +03:00
mega fb3764eefb Create finnish.json 2024-07-01 07:17:43 +03:00
mega d5efe06fe5 Delete language/i.json 2024-07-01 07:15:32 +03:00
mega cdb2673217 Create i.json 2024-07-01 07:14:13 +03:00
mega 6018a183fb Create swedish.json 2024-07-01 07:12:06 +03:00
Jasper 73f9f4037f Added 5 languages from iamnotmega (Part 1)
Added 5 new languages
2024-06-30 19:59:59 +02:00
mega b5b537e85e Create japanese.json 2024-06-30 20:19:50 +03:00
mega 6ebeb7a93c Create korean.json 2024-06-30 20:19:06 +03:00
mega 7584c25e93 Create traditionalchinese.json 2024-06-30 20:12:40 +03:00
mega 94b3788cfb Create simplifiedchinese.json 2024-06-30 20:10:59 +03:00
mega e7d9ad374e Update estonian.json 2024-06-30 20:09:00 +03:00
mega 0e597232f0 Create estonian.json 2024-06-30 20:01:53 +03:00
Jasper acc89990c2 Open Ticket v3.5.6
Open Ticket v3.5.6
2024-05-31 16:42:41 +02:00
DJj123dj ee9f8eaca1 v3.5.6 bug fix update 2024-05-31 16:36:08 +02:00
Jasper ae8a8d1b14 v3.5.5 hotfix (instant push)
v3.5.5 hotfix (instant push)
2024-05-12 11:14:40 +02:00
DJj123dj 38afb9c2a6 v3.5.5 hotfix (instant push) 2024-05-12 11:14:02 +02:00
Jasper 5bdb7941b6 Open Ticket v3.5.5
Open Ticket v3.5.5
2024-05-10 14:08:11 +02:00
DJj123dj 01c1f3150e v3.5.5 push 2 2024-05-04 14:36:36 +02:00
DJj123dj e524cccd19 v3.5.5 push 1 2024-05-04 14:22:41 +02:00
Jasper ede102bddf Add Latvian Translation (Part 4) 2024-04-27 11:22:05 +02:00
Jasper ab5d5c06be Latvian Translation (Part 3) 2024-04-27 11:17:31 +02:00
Jasper 355f078ee5 Add Latvian translation (Part 2) 2024-04-27 11:14:30 +02:00
Jasper c207560743 Add Latvian translation (Part 1)
Still requires checker.js validation & testing
2024-04-27 11:12:46 +02:00
Ronalds b29dfaeaae Create latvian.json 2024-04-27 12:06:57 +03:00
Jasper 1710111fcb Open Ticket Sponsoring!
Open Ticket Sponsoring!
2024-04-22 21:25:43 +02:00
Jasper 805c6b8e55 Open Ticket Sponsoring!
Lets goo! Open Ticket has sponsorships!
2024-04-22 21:24:55 +02:00
Jasper d0ab311da4 Fixed readme
Fixed readme
2024-04-08 23:30:21 +02:00
Jasper 92a3671768 Fixed README documentation links 2024-04-08 23:28:53 +02:00
Jasper 71074e1afe Open Ticket v3.5.4
Open Ticket v3.5.4
2024-04-04 15:38:22 +02:00
DJj123dj e80ce1a64a v3.5.4 push 2 2024-04-04 14:06:48 +02:00
DJj123dj 5dfbce1856 v3.5.4 push 1 2024-03-27 14:22:35 +01:00
Jasper 407e56a806 Open Ticket v3.5.3
Open Ticket v3.5.3
2024-02-05 21:34:56 +01:00
DJj123dj e0f42834e5 v3.5.3 push 2 2024-02-05 21:32:02 +01:00
DJj123dj d03abd9eeb v3.5.3 push 1 2024-01-27 20:32:27 +01:00
Jasper 466a4aea81 Open Ticket v3.5.2
Open Ticket v3.5.2
2024-01-10 17:12:37 +01:00
DJj123dj 9d96d11cd3 v3.5.2 2024-01-10 17:11:46 +01:00
Jasper e3b99e656e Open Ticket v3.5.1!
Open Ticket v3.5.1!
2023-12-25 19:01:13 +01:00
DJj123dj 07e2a68d06 v3.5.1 push 2 (fix button color bug) 2023-12-25 18:56:28 +01:00
DJj123dj 795ca4f981 v3.5.1 push 1 (translation update) 2023-12-23 14:19:36 +01:00
Jasper 5231129278 Open Ticket v3.5.0
Open Ticket v3.5.0
2023-12-17 14:13:30 +01:00
DJj123dj f62bc7adf9 v3.5.0 last push 2023-12-17 14:12:22 +01:00
DJj123dj 5de6b1e906 v3.5.0 translation push 2 + improved thai 2023-12-16 18:00:54 +01:00
DJj123dj 62413505d6 v3.5.0 translation push 1 + bug fix 2023-12-16 17:46:34 +01:00
DJj123dj 20b617f6eb v3.5.0 push 5 2023-12-14 21:37:29 +01:00
DJj123dj 94510bbfb0 v3.5.0 push 4 2023-12-13 21:39:18 +01:00
DJj123dj d51511fdb5 v3.5.0 push 3 2023-12-13 12:27:01 +01:00
DJj123dj 3447a37603 v3.5.0 push 2 2023-12-12 21:32:15 +01:00
DJj123dj 4b17aa640f v3.5.0 push 1 2023-11-29 19:29:27 +01:00
Jasper 3b7674f1a5 Open Ticket v3.4.4
v3.4.4
2023-11-09 20:37:10 +01:00
DJj123dj 7de9339da3 v3.4.4 2023-11-09 20:36:21 +01:00
Jasper e2e1e19bc8 Open Ticket v3.4.3
Open Ticket v3.4.3
2023-08-30 17:23:21 +02:00
DJj123dj 5f19adf561 v3.4.3 2023-08-30 17:22:26 +02:00
Jasper 1bb70745ea Open Ticket v3.4.2
Open Ticket v3.4.2
2023-08-11 11:23:50 +02:00
DJj123dj 589bbe5cd5 v3.4.2 2023-08-11 11:22:25 +02:00
Jasper 447fddea56 Open Ticket v3.4.1
Open Ticket v3.4.1
2023-06-17 12:20:40 +02:00
DJj123dj bf7a003799 Update slash.json 2023-06-17 12:18:41 +02:00
DJj123dj 6115ab1cc8 Merge branch 'dev' of https://github.com/DJj123dj/open-ticket into dev 2023-06-17 12:16:26 +02:00
DJj123dj c2307fd1ed bug fix update v3.4.1 2023-06-17 12:16:23 +02:00
Jasper 2a3850c3cc Merge pull request #71 from NoOneNook/dev
Norwegian in slash.json | Dev- branch
2023-06-07 13:01:35 +02:00
NoOneNook 688c40ce7b Update slash.json
Translated slash.json into Norwegian
2023-06-07 03:16:44 +02:00
Jasper dee2a21be9 Update reopen.js 2023-05-19 16:23:12 +02:00
Jasper d7ae040d60 Removed readme warning
Update README.md
2023-05-19 15:03:22 +02:00
Jasper 7b6202985a Update README.md 2023-05-19 15:02:43 +02:00
Jasper a2f2c601a5 Open Ticket 3.4.0!
Open Ticket 3.4.0!
2023-05-19 15:02:09 +02:00
Jasper b27016df2e Merge branch 'main' into dev 2023-05-19 15:00:47 +02:00
DJj123dj 6341f2f71b v3.4.0 last push 2023-05-19 14:55:29 +02:00
DJj123dj 56a5b9c7d0 Merge branch 'dev' of https://github.com/DJj123dj/open-ticket into dev 2023-05-17 21:43:59 +02:00
DJj123dj f608cb71ce v3.4.0 push 2 (html transcripts v2) 2023-05-17 21:43:57 +02:00
Jasper 7c7c325307 temp fix for bugs 2023-05-01 13:11:34 +02:00
Jasper 832021d72a Update russian.json
Update russian.json
2023-04-30 12:23:11 +02:00
Apexo 030554a7f5 Update russian.json 2023-04-30 13:17:08 +03:00
Jasper ada5ea0c5d temp fix for "forEach" bug
This is a temporary fix for the "Cannot read properties of undefined (reading 'forEach')" bug. This will be fixed in a better way in v3.4.0
2023-04-30 12:11:31 +02:00
DJj123dj fb6b891835 v3.4.0 push 1: fixed all currently known bugs 2023-04-29 09:15:56 +02:00
Jasper 739ad81f3f v3.3.3 MAJOR FIX!
v3.3.3 MAJOR FIX!
2023-04-22 16:53:32 +02:00
DJj123dj a6f67a9452 v3.3.3 MAJOR FIX! 2023-04-22 16:52:43 +02:00
Jasper 56a6540663 v3.3.2 extra
v3.3.2 extra
2023-04-19 18:45:55 +02:00
DJj123dj 5f8812d261 v3.3.2 push 2 2023-04-19 18:45:12 +02:00
Jasper 7a3dcf4c42 Open Ticket v3.3.2
Open Ticket v3.3.2
2023-04-19 18:43:38 +02:00
DJj123dj 7cebd4dd6a Merge branch 'dev' of https://github.com/DJj123dj/open-ticket into dev 2023-04-19 18:39:23 +02:00
DJj123dj 27912a0c37 v3.3.2 2023-04-19 18:39:21 +02:00
Jasper 67871d885a Update dev
update dev branch
2023-03-23 14:22:29 +01:00
Jasper 1bd0d013ed Update config.json 2023-03-23 14:21:39 +01:00
Jasper a074a17519 Update issue templates 2023-03-23 14:15:25 +01:00
Jasper 67af96ef5c Update SECURITY.md 2023-03-23 14:10:38 +01:00
Jasper a041f28cf7 Update CONTRIBUTING.md 2023-03-23 14:10:03 +01:00
Jasper a8c9c2ea8d Create SECURITY.md 2023-03-23 13:35:08 +01:00
Jasper 8748301b04 Open Ticket v3.3.1
Open Ticket v3.3.1
2023-03-23 12:51:58 +01:00
DJj123dj 2d7a7b5728 v3.3.1 push 4 2023-03-23 12:46:53 +01:00
DJj123dj 0807ca884c Update ticketAutoclose.js 2023-03-21 20:10:06 +01:00
DJj123dj 0ead037fa8 v3.3.1 push 3 (autoclose spam fix) 2023-03-21 19:49:12 +01:00
DJj123dj 4287c11bf1 v3.3.1 push 2 (fixed dropdown crash) 2023-03-21 17:38:15 +01:00
DJj123dj 69fdc7ccf0 v3.3.1 BUG FIXES! (+ added Slovenian) 2023-03-20 20:01:09 +01:00
Jasper 6c213306b6 Add Slovenian language
add slovenian language
2023-03-19 12:51:12 +01:00
n1kkec 4096e8196d feat(language): add slovenian language 2023-03-19 12:47:24 +01:00
Jasper 94ee890848 Open Ticket v3.3!
Open Ticket v3.3!
2023-03-19 12:34:23 +01:00
DJj123dj 4dced819a3 v3.3 push 7 (added autoclose) 2023-03-19 12:29:24 +01:00
DJj123dj 1159af9fa9 v3.3 push 6 (added ticket claiming) 2023-03-18 11:48:01 +01:00
DJj123dj 67d429c52b v3.3 push 5 2023-03-16 20:58:08 +01:00
DJj123dj f67af805c1 v3.3 push 4 (1 entire afternoon of work)
My TODO list is too big :)
2023-03-15 20:57:14 +01:00
DJj123dj 944032f690 v3.3 push 3 (lots of small changes 😄) 2023-03-13 20:22:23 +01:00
DJj123dj ee248e86bc Merge branch 'dev' of https://github.com/DJj123dj/open-ticket into dev 2023-03-12 11:22:55 +01:00
DJj123dj b171bce62b v3.3 push 2 (added Polish) 2023-03-12 11:22:53 +01:00
Jasper df0bce0189 Delete test.txt 2023-03-01 14:31:36 +01:00
Jasper 2630aa899f Create test.txt 2023-03-01 14:03:50 +01:00
DJj123dj dba370d66e v3.3 push 1 & added turkish language 2023-02-25 21:02:31 +01:00
Jasper d0bcf26b93 Open Ticket v3.2.2
new update :)
2023-02-24 21:58:40 +01:00
DJj123dj 65f82171d3 v3.2.2 push 4 2023-02-24 21:48:59 +01:00
DJj123dj 6e730f058d github files moved to new directory 2023-02-24 15:13:33 +01:00
DJj123dj 4702c633ec v3.2.2 push 2 2023-02-24 15:02:53 +01:00
DJj123dj dc14a39c4e v3.2.2 push 1 2023-02-24 14:49:36 +01:00
Jasper 05c97909d4 Merge pull request #49 from DJj123dj/translation
Translation
2023-02-13 21:18:59 +01:00
Jasper b3c4c2f6e8 Merge pull request #47 from Apexo01/main
Added russian language
2023-02-13 21:01:19 +01:00
Jasper e0e678bee0 Merge pull request #48 from DJj123dj/main
test
2023-02-13 20:59:04 +01:00
Jasper 1b01b1703f Merge branch 'dev' into main 2023-02-13 20:57:43 +01:00
Jasper 26539360c6 Merge pull request #46 from quiradon/patch-2
Update portuguese.json
2023-02-13 20:54:30 +01:00
Apexo 627c461f64 Update README.md 2023-02-13 22:30:18 +03:00
Apexo 2e40dc0468 Added russian language 2023-02-13 22:18:07 +03:00
Jasper fa57b9a93f Update checker.js 2023-02-12 15:09:27 +01:00
QuiraDon 930452155b Update portuguese.json
some fixes on what was missing.
2023-02-09 02:20:09 -03:00
DJj123dj e70f22162d Merge branch 'dev' of https://github.com/DJj123dj/open-ticket into dev 2023-02-08 14:27:40 +01:00
DJj123dj d5b0a0f3c6 /change bugfix 2023-02-08 14:27:39 +01:00
Jasper c43081e05d Merge pull request #45 from quiradon/patch-1 2023-02-08 07:09:44 +01:00
QuiraDon 8c4bf735f1 Update Portugueses Lang
I completed the translation into Portuguese that was missing a few things.
2023-02-07 23:33:26 -03:00
Jasper 3a20c4707b open ticket v3.2.1
Update dev branch
2023-02-07 17:03:22 +01:00
Jasper 9a7e563c57 Update dev branch 2023-02-07 17:02:02 +01:00
Jasper 72b4f43a25 Open Ticket v3.2.1
Bug fix update
2023-02-07 17:01:14 +01:00
DJj123dj 5fec028cc9 Merge branch 'dev' of https://github.com/DJj123dj/open-ticket into dev 2023-02-07 16:59:26 +01:00
DJj123dj 81300303e5 Update danish.json 2023-02-07 16:59:19 +01:00
Jasper 8a1ea1c856 Update README.md 2023-02-06 22:08:11 +01:00
Jasper 8a9d63bf8b Merge pull request #41 from Sank34/patch-2
French Translation New
2023-02-06 22:07:18 +01:00
DJj123dj 208b365276 Update czech.json 2023-02-06 21:49:42 +01:00
Andrei abb64a0575 French Translation New 2023-02-05 23:32:42 +02:00
DJj123dj c930140540 Update german.json 2023-02-05 22:17:19 +01:00
DJj123dj 294c4d3f2b Merge branch 'dev' of https://github.com/DJj123dj/open-ticket into dev 2023-02-05 16:22:47 +01:00
DJj123dj 28e7d48e7e v3.2.1 push 3 2023-02-05 16:22:44 +01:00
Jasper bad278e681 Merge pull request #40 from DJj123dj/readme-edit
Edited readme
2023-02-02 18:16:52 +01:00
Jasper 2e2542d064 added documentation below 2023-02-02 18:15:42 +01:00
Jasper 2c48da45ae readme-update step 1 2023-02-02 18:11:46 +01:00
Jasper e1232a559e Added translation from Sank34/patch-1
Romanian for v3.2.1
2023-01-28 12:18:17 +01:00
Andrei 3d58475461 Update to the new Version 2023-01-28 13:16:17 +02:00
DJj123dj f702b199da v3.2.1 TRANSLATION! 2023-01-28 11:51:10 +01:00
DJj123dj ea1604a805 v3.2.1 push 1 (fixed /change bugs) 2023-01-25 16:28:19 +01:00
DJj123dj f8bc3d9e12 bug fix: tickets couldn't close in some situations 2023-01-19 17:42:44 +01:00
Jasper af35f83291 Open Ticket v3.2.0
Open Ticket v3.2.0
2023-01-18 21:48:13 +01:00
DJj123dj 39fec94ead changed readme.md 2023-01-18 21:47:32 +01:00
DJj123dj 1b8468330e v3.2 last push 2023-01-18 21:44:56 +01:00
DJj123dj b698c89a89 v3.2 push 2 2023-01-17 22:25:20 +01:00
DJj123dj 7ed2d7bcc7 v3.2 push 1 NOT WORKING YET!!! 2023-01-17 17:34:51 +01:00
Jasper f2ddaa5fd4 Merge pull request #36 from DJj123dj/dev
Open Ticket v3.1.0
2022-12-31 11:47:35 +01:00
DJj123dj fc50a8e83f v3.1 last push 2022-12-31 11:42:33 +01:00
DJj123dj 5bece3357d v3.1.0 push 3 2022-12-27 17:41:54 +01:00
Jasper 97d1489558 Delete .DS_Store 2022-12-27 17:37:23 +01:00
Jasper a211cef1f6 Delete database.json 2022-12-27 17:36:52 +01:00
DJj123dj ae002e168b v3.1.0 push 2 2022-12-27 17:35:01 +01:00
DJj123dj 86a5a1a2ca v3.1.0 push 1 2022-12-27 11:38:32 +01:00
Jasper 23ebc14b8b Merge pull request #35 from DJj123dj/dev
Open Ticket v3.0.1
2022-12-10 13:38:08 +01:00
DJj123dj 3a5768a1b1 added new README image 2022-12-10 13:37:02 +01:00
DJj123dj 33c3803ca8 openticket v3.0.1 2022-12-10 12:59:44 +01:00
DJj123dj f3613fb674 update to discord.js 14.7 2022-12-05 19:32:11 +01:00
DJj123dj f1dc8cbcf5 changed some stuff 2022-11-24 21:51:13 +01:00
Jasper a365c4b69f Update issue templates 2022-10-10 20:01:10 +02:00
Jasper 687372481a Update issue templates 2022-10-10 19:54:28 +02:00
Jasper 1bc8bde922 Update issue templates 2022-10-10 19:49:16 +02:00
273 changed files with 51685 additions and 5940 deletions
+13
View File
@@ -0,0 +1,13 @@
# Exclude local build artifacts — these are regenerated inside the container
node_modules/
dist/
.git/
.backup/
.vscode/
devconfig/
devdatabase/
build-docker
otdebug.txt
plugins/*
!plugins/example-plugin/
!plugins/example-plugin/**
+39
View File
@@ -0,0 +1,39 @@
# 🎥 Content Creators
Hi there! We're searching for content creators to create tutorials & setup guides for Open Ticket.
You can get many great rewards from helping us!
You can choose which type of tutorial you want to make. You can create a quick setup, full setup, plugin tutorial or something else!
You are not required to talk in the video, but make sure it has some kind of subtitles instead.
### 📄 Requirements
- 📌 Video length of at least 2 minutes.
- 📌 Provide a link to the Open Ticket repository in the description of the video.
- 📌 Please use the latest version of Open Ticket available at the time of making the video.
- 📌 **(Optional)** Recommended language is English.
- 📌 **(Optional)** Recommended platform is YouTube!
- 📌 **(Optional)** Speech in the video *(AI is allowed)*
### 🎁 Rewards
We won't give out any compensation in money, but we will give you some advantages!
- ✅ Advertisement of tutorial in the [README.md](../README.md)!
- ✅ Advertisement of channel in our [discord server](https://discord.dj-dj.be)!
- ✅ `Content Creator` role in our [discord server](https://discord.dj-dj.be)!
- ✅ Advertisement of tutorial & channel in documentation!
- ✅ Lot's of of views generated from GitHub traffic!
- ✅ A completely free 24/7 hosted Open Ticket bot!
- ✅ We will advertise the video to all our socials!
### 💤 Outdated Content
When a tutorial or setup guide is outdated or no longer applicable,
we will remove it from the `README.md` & documentation.
Your channel will still stay in the list of contributors, so don't worry about that!
You will be noticed at least a month before removal.
This way you can take time to create an updated tutorial if you want.
### 💬 Contact Us
If you've read all these guidelines, requirements & rewards,
you can create a ticket in our [discord server](https://discord.dj-dj.be) to start working on it!
We will try to help you as fast as possible!
+92
View File
@@ -0,0 +1,92 @@
# Contributing Guidelines
<img src="https://apis.dj-dj.be/cdn/openticket/logo.png" alt="Open Ticket Logo" width="500px">
[![discord](https://img.shields.io/badge/discord-support%20server-5865F2.svg?style=flat-square&logo=discord)](https://discord.com/invite/26vT9wt3n3) [![version](https://img.shields.io/badge/version-4.2.1-brightgreen.svg?style=flat-square)](https://github.com/open-discord-bots/open-ticket/releases/tag/v4.2.1) [![Sponsor DJj123dj](https://img.shields.io/badge/sponsor-DJj123dj-ea4aaa?style=flat-square&logo=githubsponsors)](https://github.com/sponsors/DJj123dj)
These are the Contributing Guidelines of Open Ticket!<br>
Here you can find everything you need to know about contributing to Open Ticket.<br>
This includes new features, translations & bug fixes.
### 💬 Translations
#### Step 1: View & Check
1. Check the [`./languages/`](./languages/) folder for existing translations.
2. When it doesn't exist yet, visit **[step 2](#step-2-translation)**.
3. When it does exist, check if it is outdated, incorrect or incomplete.
4. If you match one of these requirements, you can also visit **[step 2](#step-2-translating)**.
#### Step 2: Translation
1. If your language doesn't exist yet, copy the [`english.json`](./../languages/english.json) file and rename it to your language.
2. **(❌ Not Recommended)** You are allowed to use `Google Translate` or `DeepL`, but only when you say it in the pull request and enable the `"automated"` boolean.
3. Only translate existing values in the json file. Don't add or remove any values from the file.
4. You're **NOT REQUIRED** to translate everything! If you only want to translate a part of it, it's okay!
5. If you are unable to translate something, leave it in `English`.
#### Step 3: Metadata
Metadata can be found in the `_TRANSLATION` variable.
|Value |Notes |
|--------------|-------------------------------------------------------------------------------------------------|
|`otversion` |The Open Ticket version of this translation. **❌ DON'T EDIT!** |
|`translators` |The discord usernames from the translators. Add your name to the list when you've contributed. |
|`lastedited` |The last edited date in the `DD/MM/YYYY` format. |
|`language` |The full name of the language with capital letter. |
|`automated` |Enable this boolean when this translation has been made using ChatGPT, Google Translate, ... |
> #### ✅ You are also allowed to add your username to the [`README.md`](./../README.md) translator list!
#### Step 4: Uploading
1. When adding a new language, please mention @DJj123dj. He will add the code required for the language to work.
2. There are currently 3 ways of uploading translations:
- Create a pull request to the [__`dev` branch!__](https://github.com/open-discord-bots/open-ticket/tree/dev)
- Create a ticket in our [discord server](https://discord.dj-dj.be)!
- Send a DM to @DJj123dj on discord!
3. Now you'll need to wait until the next Open Ticket version for it to be added.
#### Step 5: Rewards
Translators get some rewards for translating Open Ticket!
- ✅ Credits in the [`README.md`](./../README.md) translator list!
- ✅ Credits in the changelog!
- ✅ Credits in the documentation!
- ✅ Credits in the translation JSON file!
- ✅ A special role in our [Discord server](https://discord.dj-dj.be)!
### 🧩 Plugins
#### Step 1: Creating Plugins
The documentation for creating plugins will be ready soon!<br>
In the meantime, you can already look at existing plugins or try it at your own!
#### Step 2: Uploading Plugins
Create a pull request in the [**`open-discord-plugins`**](https://odplugins.dj-dj.be/) repository or contact DJj123dj in our [Discord server](https://discord.dj-dj.be)!
### 📦 Features
Feature requests are required to be made in one of the following ways:
- ✅ In our [Discord server](https://discord.dj-dj.be)
- ✅ Create an issue on GitHub
- ✅ Message DJj123dj in DM on Discord
- ✅ Email to support@dj-dj.be
> **We won't accept pull requests for features. Only for bugs, small fixes, translation and plugins!**
### 🕷️ Bug Fixes
You are able to report bugs in one of the following ways:
- ✅ In our [Discord server](https://discord.dj-dj.be)
- ✅ Create an issue on GitHub
- ✅ Message DJj123dj in DM on Discord
- ✅ Email to support@dj-dj.be
📌 **If you want, you can also create a pull request to fix the bug yourself :)**
#### 🔴 Security Vulnerabilities
If you've found a bug which could affect the **SECURITY OF THE BOT** or may be potentially dangerous to the users of the bot,
you are **REQUIRED to send the bug privately via one of the following methods:**
- 🔴 Message DJj123dj in DM on Discord
- 🔴 Email to support@dj-dj.be
> ### Please try to always include the `otdebug.txt` file!
---
<img src="https://apis.dj-dj.be/cdn/openticket/logo.png" alt="Open Ticket Logo" width="170px">
**Contributing Guidelines**<br>
[Changelog](https://otgithub.dj-dj.be/releases) - [Documentation](https://otdocs.dj-dj.be) - [Website](https://openticket.dj-dj.be) - [Support Server](https://discord.dj-dj.be) - [License](./LICENSE.md)<br>
© 2021 - 2026 - [DJdj Development](https://www.dj-dj.be) - [Terms](https://www.dj-dj.be/terms) - [Privacy Policy](https://www.dj-dj.be/privacy) - [Support Us](https://github.com/sponsors/DJj123dj)
+1
View File
@@ -0,0 +1 @@
github: DJj123dj
+30
View File
@@ -0,0 +1,30 @@
---
name: Bug Report
about: Report bugs to help us improve Open Ticket!
title: "Your Bug Name"
---
### Bug Description:
A clear and concise description of what the bug is.
### Steps To Reproduce:
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
> Leave empty when you are unable to reproduce the bug!
### Expected Behaviour:
A clear and concise description of what you expected to happen.
### Screenshots:
If applicable, add screenshots to help explain your problem.
### Files:
Please include the `otdebug.txt` file in your report! With this file, we can take a deep-dive in to the error that happend.
> This file doesn't contain any credentials or sensitive information!
### Additional Notes:
Add any other context about the problem here.
+27
View File
@@ -0,0 +1,27 @@
---
name: Documentation
about: Do you know anything to be improved in the Open Ticket documentation?
title: "Documentation Improvement Name"
labels: "Documentation"
---
### Related Docs/Systems:
Choose related systems/docs for this improvement/change:
- [ ] Guides
- [ ] Developer Guides
- [ ] API Reference
- [ ] Blog
- [ ] System (Docusaurus & Javascript)
- [ ] Assets (images)
- [ ] Other
### Improvement Description:
A clear and concise description of the improvement.
> Please explain it as detailed as possible!
### Screenshots:
If applicable, add screenshots to help explain your request.
### Additional Notes:
Add any other context about the request here.
+27
View File
@@ -0,0 +1,27 @@
---
name: Feature Request
about: Do you have a great idea for Open Ticket? Let us know using this issue!
title: "Your Feature Name"
labels: "Concept"
---
### Feature Description:
A clear and concise description of what the feature is.
### Affected Systems
Systems which are affected, improved or modified:
- (example) Slash command registration...
- (example) API embed builders...
- Scroll down to '....'
- See error
> Leave empty when you don't know which parts this feature affects!
### Advantages & Use Cases:
What advantages & use cases do you think this feature would result in?
### Screenshots:
If applicable, add screenshots to help explain your feature request.
### Additional Notes:
Add any other context about the request here.
@@ -0,0 +1,20 @@
---
name: HTML Transcripts
about: Found a bug related to the HTML Transcripts? Or do you have a feature request?
title: "Your Bug/Improvement Name"
labels: "HTML Transcripts"
---
### Feature/Bug Description:
A clear and concise description of what the feature/bug report is.
### Screenshots:
If applicable, add screenshots to help explain your feature request or bug report.
### Files:
Please include the `otdebug.txt` file in your report! With this file, we can take a deep-dive in to the error that happend.
> #### Include this file for bug reports!
> This file doesn't contain any credentials or sensitive information!
### Additional Notes:
Add any other context about the problem here.
+30
View File
@@ -0,0 +1,30 @@
---
name: New Language
about: Do you want to add a new language to Open Ticket?
title: "Language Name"
labels: "New Translation"
---
### Language Name
The name of the new language.
### Language Description/Details:
A clear and concise description of the translation/language.
### Checklist
Before the language is fully implemented, the following checklist must be met:
- [ ] **📌 Created a language file in the `./languages/` directory.**
- [ ] **📌 The translation file uses the `<lowercase-language-name>.json` format.**
- [ ] **📌 The `"_TRANSLATION"` metadata in the language file is correctly configured.**
- [ ] The `"otversion"` is correct.
- [ ] The `"translators"` list is up to date has the discord/github usernames from all translators.
- [ ] The `"lastedited"` variable is the last edited date in the following format: `DD/MM/YYYY`.
- [ ] The `"language"` variable is the name of the language in English.
- [ ] `"automated"` is enabled when `Google Translate`, `DeepL`, `ChatGPT` or any other kind of translation tools were used.
- [ ] **📌 The language has been added to the `README.md` list.**
- [ ] **📌 The language counters have been updated in the `README.md`.**
- [ ] **📌 The language has been added to the list in the `ODLanguageManagerIds_Default` interface in (`./src/core/api/defaults/language.ts`).**
- [ ] **📌 The language has been added to the list in `./src/data/languageLoader.ts`.**
### Additional Notes:
Add any other context about the problem here.
+20
View File
@@ -0,0 +1,20 @@
---
name: Plugin Request
about: Do you have an idea for an Open Ticket plugin?
title: "Your Plugin Name"
labels: "Plugin"
---
### Plugin Description:
A clear and concise description of what the plugin is & does.
> Please explain the plugin as detailed as possible!
### Advantages & Use Cases:
What advantages & use cases do you think this plugin would result in?
### Screenshots:
If applicable, add screenshots to help explain your plugin request.
### Additional Notes:
Add any other context about the request here.
+28
View File
@@ -0,0 +1,28 @@
---
name: Question
about: Do you have a question about Open Ticket?
title: "My Question"
labels: "Question"
---
### Question:
A clear and concise description of the question.
> Please explain the question as detailed as possible!
### Screenshots:
If applicable, add screenshots to help explain your plugin request.
### Checklist:
Before creating this question, the following checklist must be met:
- [ ] **📌 I've read the docs (https://otdocs.dj-dj.be) and I didn't found the solution.**
- [ ] **📌 I've asked other people & they didn't know the solution.**
- [ ] **📌 The question is not related to the following subjects: (If so, ask it in our discord server: https://discord.dj-dj.be)**
- Configuring the bot
- Hosting the bot (24/7)
- Updating the bot
- [ ] **📌 I know that this issue is publicly visible for everyone and I haven't shared any private info.**
### Additional Notes:
Add any other context about the request here.
@@ -0,0 +1,24 @@
---
name: Updated Language
about: Do you want to update/improve an existing language in Open Ticket?
title: "Language Name"
labels: "Updated Translation"
---
### Language Name
The name of the existing language.
### Language Description/Details:
A clear and concise description of the translation/language changes.
### Checklist
Before the language is updated, the following checklist must be met:
- [ ] **📌 The `"_TRANSLATION"` metadata in the language file is correctly configured.**
- [ ] The `"otversion"` is correct.
- [ ] The `"translators"` list is up to date has the discord/github usernames from all translators.
- [ ] The `"lastedited"` variable is the last edited date in the following format: `DD/MM/YYYY`.
- [ ] The `"language"` variable is the name of the language in English.
- [ ] `"automated"` is enabled when `Google Translate`, `DeepL`, `ChatGPT` or any other kind of translation tools were used.
### Additional Notes:
Add any other context about the problem here.
+53
View File
@@ -0,0 +1,53 @@
# Security Policy
<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.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>
Here you can find a list of all supported & deprecated versions of the bot.<br>
You will also find some guidelines about how to report vulnerabilities, bugs & errors.
### 📦 Supported Versions
Below, you can find a list with the status of every Open Ticket version.<br>
This list will be updated on every release.
- 🟦 In Development **(ideas, bugs, support, html transcripts)**
- ✅ Supported **(features, bugs, support, docs, html transcripts)**
- 🚧 Maintenance **(support, docs, html transcripts)**
- 🟧 Deprecated **(docs only)**
- ❌ Fully Deprecated
| Version | Supported | Notes |
|------------|-----------|---------------------------------------------------------------|
| 4.2.x | 🟦 | In Development |
| 4.2.2 | 🟦 | In Development |
| 4.2.1 | ✅ | |
| 4.2.0 | ✅ | |
| 4.1.3 | ✅ | (LTS) Long-Term-Support, Until September 2026 |
| 4.1.2 | 🚧 | |
| 4.1.1 | 🚧 | |
| 4.1.0 | 🚧 | |
| 4.0.7 | 🟧 | Deprecated |
| < 4.0.7 | ❌ | |
### 🕷️ Reporting Vulnerabilities
You can report vulnerabilities, errors & bugs using one of the following methods:
- Create an issue on GitHub!
- Create a ticket in our [discord server](https://discord.dj-dj.be)!
- Message @DJj123dj in DM on discord!
- Send an E-mail to [support@dj-dj.be](mailto:support@dj-dj.be)!
When you report a problem, please **give a small description** about what & how it happend.<br>
Try to explain the issue in as much detail as possible.
If possible, try to provide screenshots!
### Please upload the `otdebug.txt` file together with your bug report!
---
<img src="https://apis.dj-dj.be/cdn/openticket/logo.png" alt="Open Ticket Logo" width="170px">
**Security Policy**<br>
[Changelog](https://otgithub.dj-dj.be/releases) - [Documentation](https://otdocs.dj-dj.be) - [Website](https://openticket.dj-dj.be) - [Support Server](https://discord.dj-dj.be) - [License](./LICENSE.md)<br>
© 2021 - 2026 - [DJdj Development](https://www.dj-dj.be) - [Terms](https://www.dj-dj.be/terms) - [Privacy Policy](https://www.dj-dj.be/privacy) - [Support Us](https://github.com/sponsors/DJj123dj)
+53
View File
@@ -0,0 +1,53 @@
# Pterodactyl Eggs
<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.2.1-brightgreen.svg?style=flat-square)](https://github.com/open-discord-bots/open-ticket/releases/tag/v4.2.1)
[![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)
Hi there! Open Ticket provides **official eggs** for the Pterodactyl & Pelican panels!<br>
There are different eggs for different versions of Open Ticket.
Please choose the one that fits your needs the most.
If you encounter any issues while installing these eggs, please head to our [**discord server**](https://discord.dj-dj.be) for further assistance!
### Requirements
It's recommended to provide at least `1GB` of **Memory/RAM** and `5GB` of **disk space** for Open Ticket to work correctly.
### Egg Variants
[**`openticket-egg-main.json` (Recommended)**](openticket-egg-main.json)
- This egg will use the `main` branch of Open Ticket.
[**`openticket-egg-v4.2.0.json`**](openticket-egg-v4.2.0.json)
- This egg will always use Open Ticket `v4.2.0`. Open Ticket updates will not have an effect on this egg.
[**`openticket-egg-v4.1.3.json`**](openticket-egg-v4.1.3.json)
- This egg will always use Open Ticket `v4.1.3`. Open Ticket updates will not have an effect on this egg.
[**`openticket-egg-v4.1.2.json`**](openticket-egg-v4.1.2.json)
- This egg will always use Open Ticket `v4.1.2`. Open Ticket updates will not have an effect on this egg.
[**`openticket-egg-v4.1.1.json`**](openticket-egg-v4.1.1.json)
- This egg will always use Open Ticket `v4.1.1`. Open Ticket updates will not have an effect on this egg.
[**`openticket-egg-v4.1.0.json`**](openticket-egg-v4.1.0.json)
- This egg will always use Open Ticket `v4.1.0`. Open Ticket updates will not have an effect on this egg.
[**`openticket-egg-v4.0.7.json`**](openticket-egg-v4.0.7.json)
- This egg will always use Open Ticket `v4.0.7`. Open Ticket updates will not have an effect on this egg.
[**`openticket-egg-v3.5.9.json`**](openticket-egg-v3.5.9.json)
- This egg will always use Open Ticket `v3.5.9`. Open Ticket updates will not have an effect on this egg.
[**`openticket-egg-dev.json` (Not Recommended)**](openticket-egg-dev.json)
- This egg will use the `dev` branch of Open Ticket.
---
<img src="https://apis.dj-dj.be/cdn/openticket/logo.png" alt="Open Ticket Logo" width="170px">
**Pterodactyl Eggs**<br>
[Changelog](https://otgithub.dj-dj.be/releases) - [Documentation](https://otdocs.dj-dj.be) - [Website](https://openticket.dj-dj.be) - [Support Server](https://discord.dj-dj.be) - [License](./LICENSE.md)<br>
© 2021 - 2026 - [DJdj Development](https://www.dj-dj.be) - [Terms](https://www.dj-dj.be/terms) - [Privacy Policy](https://www.dj-dj.be/privacy) - [Support Us](https://github.com/sponsors/DJj123dj)
@@ -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:21+01:00",
"name": "Open Ticket (Experimental)",
"author": "support@dj-dj.be",
"description": "This is the experimental Pterodactyl egg for Open Ticket, the most advanced & customisable discord ticket bot that you will ever find! DO NOT USE IN PRODUCTION!",
"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 (dev)\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=\"dev\"\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"
}
]
}
@@ -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:20+01:00",
"name": "Open Ticket (Latest)",
"author": "support@dj-dj.be",
"description": "This is the official Pterodactyl egg for Open Ticket, 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 (main)\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=\"main\"\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"
}
]
}
@@ -0,0 +1,62 @@
{
"_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PTERODACTYL PANEL - PTERODACTYL.IO",
"meta": {
"version": "PTDL_v2",
"update_url": null
},
"exported_at": "2025-03-16T18:10:18+01:00",
"name": "Open Ticket (v4.1.3)",
"author": "support@dj-dj.be",
"description": "This is the official Pterodactyl egg for Open Ticket v4.1.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.1.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.1.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"
}
]
}
@@ -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.2.0)",
"author": "support@dj-dj.be",
"description": "This is the official Pterodactyl egg for Open Ticket v4.2.0, the most advanced & customisable discord ticket bot that you will ever find! You can customise up to 300+ variables! This includes Html Transcripts, Advanced Plugins, Custom Embeds, Questions\/Modals, Stats & more!",
"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.2.0)\r\n# Inspired by: Node.js Installation Script\r\n# \u00a9 DJdj Development\r\n\r\necho -e \"[OT INSTALLER] installing dependencies. please wait...\"\r\napt update\r\napt install -y git curl\r\n\r\necho -e \"[OT INSTALLER] updating npm. please wait...\"\r\nnpm install npm@latest --location=global\r\n\r\nmkdir -p \/mnt\/server\r\ncd \/mnt\/server\r\n\r\nBRANCH=\"v4.2.0\"\r\n\r\nif [ \"$(ls -A \/mnt\/server)\" ]; then\r\n echo -e \"[OT INSTALLER] \/mnt\/server directory is not empty.\"\r\n if [ -d .git ]; then\r\n echo -e \"[OT INSTALLER] .git directory exists\"\r\n if [ -f .git\/config ]; then\r\n echo -e \"[OT INSTALLER] loading info from git config\"\r\n ORIGIN=$(git config --get remote.origin.url)\r\n else\r\n echo -e \"[OT INSTALLER] files found with no git config\"\r\n echo -e \"[OT INSTALLER] closing out without touching things to not break anything\"\r\n exit 10\r\n fi\r\n fi\r\n\r\n if [ \"${ORIGIN}\" == \"https:\/\/github.com\/open-discord-bots\/open-ticket.git\" ]; then\r\n echo \"pulling latest from github\"\r\n git pull\r\n fi\r\nelse\r\n echo -e \"[OT INSTALLER] \/mnt\/server is empty.\"\r\n echo -e \"[OT INSTALLER] cloning files into repo.\"\r\n if [ -z ${BRANCH} ]; then\r\n echo -e \"[OT INSTALLER] cloning default branch\"\r\n git clone https:\/\/github.com\/open-discord-bots\/open-ticket.git .\r\n else\r\n echo -e \"[OT INSTALLER] cloning ${BRANCH}'\"\r\n git clone --single-branch --branch ${BRANCH} https:\/\/github.com\/open-discord-bots\/open-ticket.git .\r\n fi\r\nfi\r\n\r\necho -e \"[OT INSTALLER] installing Open Ticket node.js packages.\"\r\nif [ -f \/mnt\/server\/package.json ]; then\r\n \/usr\/local\/bin\/npm install --omit=dev\r\nfi\r\n\r\necho -e \"[OT INSTALLER] installing custom node.js packages.\"\r\nif [[ ! -z ${NODE_PACKAGES} ]]; then\r\n \/usr\/local\/bin\/npm install ${NODE_PACKAGES}\r\nfi\r\n\r\necho -e \"[OT INSTALLER] install complete!\"\r\nexit 0",
"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"
}
]
}
@@ -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.2.1)",
"author": "support@dj-dj.be",
"description": "This is the official Pterodactyl egg for Open Ticket v4.2.1, the most advanced & customisable discord ticket bot that you will ever find! You can customise up to 300+ variables! This includes Html Transcripts, Advanced Plugins, Custom Embeds, Questions\/Modals, Stats & more!",
"features": null,
"docker_images": {
"ghcr.io\/parkervcp\/yolks:nodejs_20": "ghcr.io\/parkervcp\/yolks:nodejs_20"
},
"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.2.1)\r\n# Inspired by: Node.js Installation Script\r\n# \u00a9 DJdj Development\r\n\r\necho -e \"[OT INSTALLER] installing dependencies. please wait...\"\r\napt update\r\napt install -y git curl\r\n\r\necho -e \"[OT INSTALLER] updating npm. please wait...\"\r\nnpm install npm@latest --location=global\r\n\r\nmkdir -p \/mnt\/server\r\ncd \/mnt\/server\r\n\r\nBRANCH=\"v4.2.1\"\r\n\r\nif [ \"$(ls -A \/mnt\/server)\" ]; then\r\n echo -e \"[OT INSTALLER] \/mnt\/server directory is not empty.\"\r\n if [ -d .git ]; then\r\n echo -e \"[OT INSTALLER] .git directory exists\"\r\n if [ -f .git\/config ]; then\r\n echo -e \"[OT INSTALLER] loading info from git config\"\r\n ORIGIN=$(git config --get remote.origin.url)\r\n else\r\n echo -e \"[OT INSTALLER] files found with no git config\"\r\n echo -e \"[OT INSTALLER] closing out without touching things to not break anything\"\r\n exit 10\r\n fi\r\n fi\r\n\r\n if [ \"${ORIGIN}\" == \"https:\/\/github.com\/open-discord-bots\/open-ticket.git\" ]; then\r\n echo \"pulling latest from github\"\r\n git pull\r\n fi\r\nelse\r\n echo -e \"[OT INSTALLER] \/mnt\/server is empty.\"\r\n echo -e \"[OT INSTALLER] cloning files into repo.\"\r\n if [ -z ${BRANCH} ]; then\r\n echo -e \"[OT INSTALLER] cloning default branch\"\r\n git clone https:\/\/github.com\/open-discord-bots\/open-ticket.git .\r\n else\r\n echo -e \"[OT INSTALLER] cloning ${BRANCH}'\"\r\n git clone --single-branch --branch ${BRANCH} https:\/\/github.com\/open-discord-bots\/open-ticket.git .\r\n fi\r\nfi\r\n\r\necho -e \"[OT INSTALLER] installing Open Ticket node.js packages.\"\r\nif [ -f \/mnt\/server\/package.json ]; then\r\n \/usr\/local\/bin\/npm install --omit=dev\r\nfi\r\n\r\necho -e \"[OT INSTALLER] installing custom node.js packages.\"\r\nif [[ ! -z ${NODE_PACKAGES} ]]; then\r\n \/usr\/local\/bin\/npm install ${NODE_PACKAGES}\r\nfi\r\n\r\necho -e \"[OT INSTALLER] install complete!\"\r\nexit 0",
"container": "node:latest",
"entrypoint": "bash"
}
},
"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"
}
]
}
+23 -13
View File
@@ -1,16 +1,26 @@
node_modules/ node_modules/
package-lock.json package-lock.json
devConfig.json
devConfig1.json
devConfig2.json
devConfig3.json
devConfig4.json
devConfig5.json
.DS_Store
openticketdebug.txt
developerChangelog.md
storage/dynamicDB/
storage/.DS_Store
.vscode/ .vscode/
livestatus.json
test.js devconfig/
devdatabase/
plugins/*
!plugins/example-plugin/
database/openticket.sqlite
dist/
otdebug.txt
.DS_Store
*/.DS_Store
*/*/.DS_Store
*/*/*/.DS_Store
**/.DS_Store
.backup/*
.tools/*
!.tools/createSponsors.ts
!.tools/createContributors.ts
!.tools/mergeTranslations.ts
!.tools/docker-compose.yml
!.tools/build-docker.sh
+37
View File
@@ -0,0 +1,37 @@
#!/usr/bin/env bash
# build.sh — Build Open Ticket Docker images for all supported architectures.
#
# Usage: ./build.sh <image> [--no-push]
# image Full image name, e.g. djj123dj/open-ticket
#
# Example: ./build.sh djj123dj/open-ticket --no-push
set -euo pipefail
cd "$(dirname "$0")/.."
echo "✅ Switched working directory to Open Ticket root"
pwd
IMAGE="${1:?Usage: ./build-docker.sh <image> [--no-push]}"
PLATFORMS="linux/amd64,linux/arm64" # linux/arm/v6,linux/arm/v7,linux/s390x are taking too long to build, so we'll skip them for now
VERSION=$(node -p "require('./package.json').version")
# Create a multi-arch builder if it doesn't exist yet
docker buildx inspect ot-builder &>/dev/null \
|| docker buildx create --name ot-builder --driver docker-container --bootstrap --use
docker buildx use ot-builder
PUSH_FLAG="--push"
[[ "${2:-}" == "--no-push" ]] && PUSH_FLAG=""
docker buildx build \
--platform "$PLATFORMS" \
--tag "${IMAGE}:v${VERSION}" \
--tag "${IMAGE}:latest" \
--load \
$PUSH_FLAG \
.
[[ -n "$PUSH_FLAG" ]] \
&& echo "✅ Pushed ${IMAGE}:v${VERSION} and ${IMAGE}:latest" \
|| echo "✅ Built ${IMAGE}:v${VERSION} (not pushed)"
+14
View File
@@ -0,0 +1,14 @@
# Docker Compose for Open Ticket
services:
openticket:
image: djj123dj/open-ticket:latest
volumes:
- config:/home/container/config
- database:/home/container/database
- plugins:/home/container/plugins
restart: unless-stopped
container_name: open-ticket
volumes:
config:
database:
plugins:
+671
View File
@@ -0,0 +1,671 @@
/// <reference types="node"/>
import fjs from "formatted-json-stringify"
import fs from "fs"
const formatter = new fjs.ObjectFormatter(null,true,[
new fjs.ObjectFormatter("_TRANSLATION",true,[
new fjs.PropertyFormatter("otversion"),
new fjs.ArrayFormatter("translators",false,new fjs.PropertyFormatter(null)),
new fjs.PropertyFormatter("lastedited"),
new fjs.PropertyFormatter("language"),
new fjs.PropertyFormatter("automated"),
]),
new fjs.ObjectFormatter("checker",true,[
new fjs.ObjectFormatter("system",true,[
new fjs.PropertyFormatter("typeError"),
new fjs.PropertyFormatter("headerOpenTicket"),
new fjs.PropertyFormatter("typeWarning"),
new fjs.PropertyFormatter("typeInfo"),
new fjs.PropertyFormatter("headerConfigChecker"),
new fjs.PropertyFormatter("headerDescription"),
new fjs.PropertyFormatter("footerError"),
new fjs.PropertyFormatter("footerWarning"),
new fjs.PropertyFormatter("footerSupport"),
new fjs.PropertyFormatter("compactInformation"),
new fjs.PropertyFormatter("dataPath"),
new fjs.PropertyFormatter("dataDocs"),
new fjs.PropertyFormatter("dataMessages"),
]),
new fjs.ObjectFormatter("messages",true,[
new fjs.PropertyFormatter("stringTooShort"),
new fjs.PropertyFormatter("stringTooLong"),
new fjs.PropertyFormatter("stringLengthInvalid"),
new fjs.PropertyFormatter("stringStartsWith"),
new fjs.PropertyFormatter("stringEndsWith"),
new fjs.PropertyFormatter("stringContains"),
new fjs.PropertyFormatter("stringChoices"),
new fjs.PropertyFormatter("stringRegex"),
new fjs.PropertyFormatter("stringInvertedContains"),
new fjs.PropertyFormatter("stringLowercase"),
new fjs.PropertyFormatter("stringUppercase"),
new fjs.PropertyFormatter("stringSpecialCharacters"),
new fjs.PropertyFormatter("stringNoSpaces"),
new fjs.PropertyFormatter("stringCapitalWord"),
new fjs.PropertyFormatter("stringCapitalSentence"),
new fjs.PropertyFormatter("stringPunctuation"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("numberTooShort"),
new fjs.PropertyFormatter("numberTooLong"),
new fjs.PropertyFormatter("numberLengthInvalid"),
new fjs.PropertyFormatter("numberTooSmall"),
new fjs.PropertyFormatter("numberTooLarge"),
new fjs.PropertyFormatter("numberNotEqual"),
new fjs.PropertyFormatter("numberStep"),
new fjs.PropertyFormatter("numberStepOffset"),
new fjs.PropertyFormatter("numberStartsWith"),
new fjs.PropertyFormatter("numberEndsWith"),
new fjs.PropertyFormatter("numberContains"),
new fjs.PropertyFormatter("numberChoices"),
new fjs.PropertyFormatter("numberFloat"),
new fjs.PropertyFormatter("numberNegative"),
new fjs.PropertyFormatter("numberPositive"),
new fjs.PropertyFormatter("numberZero"),
new fjs.PropertyFormatter("numberNan"),
new fjs.PropertyFormatter("numberInvertedContains"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("booleanTrue"),
new fjs.PropertyFormatter("booleanFalse"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("arrayEmptyDisabled"),
new fjs.PropertyFormatter("arrayEmptyRequired"),
new fjs.PropertyFormatter("arrayTooShort"),
new fjs.PropertyFormatter("arrayTooLong"),
new fjs.PropertyFormatter("arrayLengthInvalid"),
new fjs.PropertyFormatter("arrayInvalidTypes"),
new fjs.PropertyFormatter("arrayDouble"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("discordInvalidId"),
new fjs.PropertyFormatter("discordInvalidIdOptions"),
new fjs.PropertyFormatter("discordInvalidToken"),
new fjs.PropertyFormatter("colorInvalid"),
new fjs.PropertyFormatter("emojiTooShort"),
new fjs.PropertyFormatter("emojiTooLong"),
new fjs.PropertyFormatter("emojiCustom"),
new fjs.PropertyFormatter("emojiInvalid"),
new fjs.PropertyFormatter("urlInvalid"),
new fjs.PropertyFormatter("urlInvalidHttp"),
new fjs.PropertyFormatter("urlInvalidProtocol"),
new fjs.PropertyFormatter("urlInvalidHostname"),
new fjs.PropertyFormatter("urlInvalidExtension"),
new fjs.PropertyFormatter("urlInvalidPath"),
new fjs.PropertyFormatter("idNotUnique"),
new fjs.PropertyFormatter("idNonExistent"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("invalidType"),
new fjs.PropertyFormatter("propertyMissing"),
new fjs.PropertyFormatter("propertyOptional"),
new fjs.PropertyFormatter("objectDisabled"),
new fjs.PropertyFormatter("nullInvalid"),
new fjs.PropertyFormatter("switchInvalidType"),
new fjs.PropertyFormatter("objectSwitchInvalid"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("invalidLanguage"),
new fjs.PropertyFormatter("invalidButton"),
new fjs.PropertyFormatter("unusedOption"),
new fjs.PropertyFormatter("unusedQuestion"),
new fjs.PropertyFormatter("dropdownOption"),
new fjs.PropertyFormatter("customInvalidVersion"),
]),
]),
new fjs.ObjectFormatter("actions",true,[
new fjs.ObjectFormatter("buttons",true,[
new fjs.PropertyFormatter("create"),
new fjs.PropertyFormatter("close"),
new fjs.PropertyFormatter("delete"),
new fjs.PropertyFormatter("reopen"),
new fjs.PropertyFormatter("claim"),
new fjs.PropertyFormatter("unclaim"),
new fjs.PropertyFormatter("pin"),
new fjs.PropertyFormatter("unpin"),
new fjs.PropertyFormatter("clear"),
new fjs.PropertyFormatter("helpSwitchSlash"),
new fjs.PropertyFormatter("helpSwitchText"),
new fjs.PropertyFormatter("helpPage"),
new fjs.PropertyFormatter("withReason"),
new fjs.PropertyFormatter("withoutTranscript"),
new fjs.PropertyFormatter("blacklistAdd"),
new fjs.PropertyFormatter("blacklistRemove"),
]),
new fjs.ObjectFormatter("titles",true,[
new fjs.PropertyFormatter("created"),
new fjs.PropertyFormatter("close"),
new fjs.PropertyFormatter("delete"),
new fjs.PropertyFormatter("reopen"),
new fjs.PropertyFormatter("claim"),
new fjs.PropertyFormatter("unclaim"),
new fjs.PropertyFormatter("pin"),
new fjs.PropertyFormatter("unpin"),
new fjs.PropertyFormatter("rename"),
new fjs.PropertyFormatter("move"),
new fjs.PropertyFormatter("add"),
new fjs.PropertyFormatter("remove"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("help"),
new fjs.PropertyFormatter("statsReset"),
new fjs.PropertyFormatter("blacklistAdd"),
new fjs.PropertyFormatter("blacklistRemove"),
new fjs.PropertyFormatter("blacklistGet"),
new fjs.PropertyFormatter("blacklistView"),
new fjs.PropertyFormatter("blacklistAddDm"),
new fjs.PropertyFormatter("blacklistRemoveDm"),
new fjs.PropertyFormatter("clear"),
new fjs.PropertyFormatter("clearTickets"),
new fjs.PropertyFormatter("roles"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("autoclose"),
new fjs.PropertyFormatter("autocloseEnabled"),
new fjs.PropertyFormatter("autocloseDisabled"),
new fjs.PropertyFormatter("autodelete"),
new fjs.PropertyFormatter("autodeleteEnabled"),
new fjs.PropertyFormatter("autodeleteDisabled"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("topicSet"),
new fjs.PropertyFormatter("prioritySet"),
new fjs.PropertyFormatter("priorityGet"),
new fjs.PropertyFormatter("transfer"),
new fjs.PropertyFormatter("transcripts"),
]),
new fjs.ObjectFormatter("descriptions",true,[
new fjs.PropertyFormatter("create"),
new fjs.PropertyFormatter("close"),
new fjs.PropertyFormatter("delete"),
new fjs.PropertyFormatter("reopen"),
new fjs.PropertyFormatter("claim"),
new fjs.PropertyFormatter("unclaim"),
new fjs.PropertyFormatter("pin"),
new fjs.PropertyFormatter("unpin"),
new fjs.PropertyFormatter("rename"),
new fjs.PropertyFormatter("move"),
new fjs.PropertyFormatter("add"),
new fjs.PropertyFormatter("remove"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("helpExplanation"),
new fjs.PropertyFormatter("statsReset"),
new fjs.PropertyFormatter("statsError"),
new fjs.PropertyFormatter("blacklistAdd"),
new fjs.PropertyFormatter("blacklistRemove"),
new fjs.PropertyFormatter("blacklistGetSuccess"),
new fjs.PropertyFormatter("blacklistGetEmpty"),
new fjs.PropertyFormatter("blacklistViewEmpty"),
new fjs.PropertyFormatter("blacklistViewTip"),
new fjs.PropertyFormatter("clearVerify"),
new fjs.PropertyFormatter("clearReady"),
new fjs.PropertyFormatter("rolesEmpty"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("autocloseLeave"),
new fjs.PropertyFormatter("autocloseTimeout"),
new fjs.PropertyFormatter("autodeleteLeave"),
new fjs.PropertyFormatter("autodeleteTimeout"),
new fjs.PropertyFormatter("autocloseEnabled"),
new fjs.PropertyFormatter("autocloseDisabled"),
new fjs.PropertyFormatter("autodeleteEnabled"),
new fjs.PropertyFormatter("autodeleteDisabled"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("ticketMessageLimit"),
new fjs.PropertyFormatter("ticketMessageAutoclose"),
new fjs.PropertyFormatter("ticketMessageAutodelete"),
new fjs.PropertyFormatter("panelReady"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("topicSet"),
new fjs.PropertyFormatter("prioritySet"),
new fjs.PropertyFormatter("priorityGet"),
new fjs.PropertyFormatter("transfer"),
]),
new fjs.ObjectFormatter("modal",true,[
new fjs.PropertyFormatter("closePlaceholder"),
new fjs.PropertyFormatter("deletePlaceholder"),
new fjs.PropertyFormatter("reopenPlaceholder"),
new fjs.PropertyFormatter("claimPlaceholder"),
new fjs.PropertyFormatter("unclaimPlaceholder"),
new fjs.PropertyFormatter("pinPlaceholder"),
new fjs.PropertyFormatter("unpinPlaceholder"),
]),
new fjs.ObjectFormatter("logs",true,[
new fjs.PropertyFormatter("createLog"),
new fjs.PropertyFormatter("closeLog"),
new fjs.PropertyFormatter("closeDm"),
new fjs.PropertyFormatter("deleteLog"),
new fjs.PropertyFormatter("deleteDm"),
new fjs.PropertyFormatter("reopenLog"),
new fjs.PropertyFormatter("reopenDm"),
new fjs.PropertyFormatter("claimLog"),
new fjs.PropertyFormatter("claimDm"),
new fjs.PropertyFormatter("unclaimLog"),
new fjs.PropertyFormatter("unclaimDm"),
new fjs.PropertyFormatter("pinLog"),
new fjs.PropertyFormatter("pinDm"),
new fjs.PropertyFormatter("unpinLog"),
new fjs.PropertyFormatter("unpinDm"),
new fjs.PropertyFormatter("renameLog"),
new fjs.PropertyFormatter("renameDm"),
new fjs.PropertyFormatter("moveLog"),
new fjs.PropertyFormatter("moveDm"),
new fjs.PropertyFormatter("addLog"),
new fjs.PropertyFormatter("addDm"),
new fjs.PropertyFormatter("removeLog"),
new fjs.PropertyFormatter("removeDm"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("blacklistAddLog"),
new fjs.PropertyFormatter("blacklistRemoveLog"),
new fjs.PropertyFormatter("blacklistAddDm"),
new fjs.PropertyFormatter("blacklistRemoveDm"),
new fjs.PropertyFormatter("clearLog"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("transferLog"),
new fjs.PropertyFormatter("transferDm"),
new fjs.PropertyFormatter("prioritySetLog"),
new fjs.PropertyFormatter("prioritySetDm"),
new fjs.PropertyFormatter("roleUpdateLog"),
new fjs.PropertyFormatter("roleUpdateDm"),
new fjs.PropertyFormatter("topicSetLog"),
new fjs.PropertyFormatter("topicSetDm"),
]),
]),
new fjs.ObjectFormatter("transcripts",true,[
new fjs.ObjectFormatter("success",true,[
new fjs.PropertyFormatter("visit"),
new fjs.PropertyFormatter("ready"),
new fjs.PropertyFormatter("textFileDescription"),
new fjs.PropertyFormatter("htmlProgress"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("createdChannel"),
new fjs.PropertyFormatter("createdCreator"),
new fjs.PropertyFormatter("createdParticipant"),
new fjs.PropertyFormatter("createdActiveAdmin"),
new fjs.PropertyFormatter("createdEveryAdmin"),
new fjs.PropertyFormatter("createdOther"),
]),
new fjs.ObjectFormatter("errors",true,[
new fjs.PropertyFormatter("retry"),
new fjs.PropertyFormatter("continue"),
new fjs.PropertyFormatter("backup"),
new fjs.PropertyFormatter("error"),
new fjs.PropertyFormatter("title"),
new fjs.PropertyFormatter("noHistory"),
new fjs.PropertyFormatter("historyNotSupported"),
]),
new fjs.ObjectFormatter("text",true,[
new fjs.PropertyFormatter("messagesTitle"),
new fjs.PropertyFormatter("embedTitle"),
new fjs.PropertyFormatter("fileTitle"),
new fjs.PropertyFormatter("fieldsTitle"),
new fjs.PropertyFormatter("reactionsTitle"),
new fjs.PropertyFormatter("statsTitle"),
new fjs.PropertyFormatter("emptyContent"),
new fjs.PropertyFormatter("noTitle"),
new fjs.PropertyFormatter("noDesc"),
]),
]),
new fjs.ObjectFormatter("errors",true,[
new fjs.ObjectFormatter("titles",true,[
new fjs.PropertyFormatter("internalError"),
new fjs.PropertyFormatter("optionMissing"),
new fjs.PropertyFormatter("optionInvalid"),
new fjs.PropertyFormatter("unknownCommand"),
new fjs.PropertyFormatter("noPermissions"),
new fjs.PropertyFormatter("unknownTicket"),
new fjs.PropertyFormatter("deprecatedTicket"),
new fjs.PropertyFormatter("unknownOption"),
new fjs.PropertyFormatter("unknownPanel"),
new fjs.PropertyFormatter("notInGuild"),
new fjs.PropertyFormatter("channelRename"),
new fjs.PropertyFormatter("channelCategory"),
new fjs.PropertyFormatter("busy"),
new fjs.PropertyFormatter("permissionError"),
]),
new fjs.ObjectFormatter("descriptions",true,[
new fjs.PropertyFormatter("askForInfo"),
new fjs.PropertyFormatter("askForInfoResolve"),
new fjs.PropertyFormatter("internalError"),
new fjs.PropertyFormatter("optionMissing"),
new fjs.PropertyFormatter("optionInvalid"),
new fjs.PropertyFormatter("optionInvalidChoose"),
new fjs.PropertyFormatter("unknownCommand"),
new fjs.PropertyFormatter("noPermissions"),
new fjs.PropertyFormatter("noPermissionsList"),
new fjs.PropertyFormatter("noPermissionsCooldown"),
new fjs.PropertyFormatter("noPermissionsBlacklist"),
new fjs.PropertyFormatter("noPermissionsLimitGlobal"),
new fjs.PropertyFormatter("noPermissionsLimitGlobalUser"),
new fjs.PropertyFormatter("noPermissionsLimitOption"),
new fjs.PropertyFormatter("noPermissionsLimitOptionUser"),
new fjs.PropertyFormatter("unknownTicket"),
new fjs.PropertyFormatter("deprecatedTicket"),
new fjs.PropertyFormatter("notInGuild"),
new fjs.PropertyFormatter("channelRename"),
new fjs.PropertyFormatter("channelCategory"),
new fjs.PropertyFormatter("channelRenameSource"),
new fjs.PropertyFormatter("busy"),
new fjs.PropertyFormatter("closeBeforeMessage"),
new fjs.PropertyFormatter("closeBeforeAdminMessage"),
new fjs.PropertyFormatter("unableToCreateTicket"),
new fjs.PropertyFormatter("messageMissing"),
new fjs.PropertyFormatter("stateExpired"),
new fjs.PropertyFormatter("panelStateExpired"),
]),
new fjs.ObjectFormatter("optionInvalidReasons",true,[
new fjs.PropertyFormatter("stringRegex"),
new fjs.PropertyFormatter("stringMinLength"),
new fjs.PropertyFormatter("stringMaxLength"),
new fjs.PropertyFormatter("numberInvalid"),
new fjs.PropertyFormatter("numberMin"),
new fjs.PropertyFormatter("numberMax"),
new fjs.PropertyFormatter("numberDecimal"),
new fjs.PropertyFormatter("numberNegative"),
new fjs.PropertyFormatter("numberPositive"),
new fjs.PropertyFormatter("numberZero"),
new fjs.PropertyFormatter("channelNotFound"),
new fjs.PropertyFormatter("userNotFound"),
new fjs.PropertyFormatter("roleNotFound"),
new fjs.PropertyFormatter("memberNotFound"),
new fjs.PropertyFormatter("mentionableNotFound"),
new fjs.PropertyFormatter("channelType"),
new fjs.PropertyFormatter("notInGuild"),
]),
new fjs.ObjectFormatter("permissions",true,[
new fjs.PropertyFormatter("developer"),
new fjs.PropertyFormatter("owner"),
new fjs.PropertyFormatter("admin"),
new fjs.PropertyFormatter("moderator"),
new fjs.PropertyFormatter("support"),
new fjs.PropertyFormatter("member"),
new fjs.PropertyFormatter("discord-administrator"),
]),
new fjs.ObjectFormatter("actionInvalid",true,[
new fjs.PropertyFormatter("close"),
new fjs.PropertyFormatter("reopen"),
new fjs.PropertyFormatter("claim"),
new fjs.PropertyFormatter("unclaim"),
new fjs.PropertyFormatter("pin"),
new fjs.PropertyFormatter("unpin"),
new fjs.PropertyFormatter("add"),
new fjs.PropertyFormatter("remove"),
]),
]),
new fjs.ObjectFormatter("params",true,[
new fjs.ObjectFormatter("uppercase",true,[
new fjs.PropertyFormatter("ticket"),
new fjs.PropertyFormatter("tickets"),
new fjs.PropertyFormatter("reason"),
new fjs.PropertyFormatter("creator"),
new fjs.PropertyFormatter("remaining"),
new fjs.PropertyFormatter("added"),
new fjs.PropertyFormatter("removed"),
new fjs.PropertyFormatter("filter"),
new fjs.PropertyFormatter("method"),
new fjs.PropertyFormatter("type"),
new fjs.PropertyFormatter("blacklisted"),
new fjs.PropertyFormatter("panel"),
new fjs.PropertyFormatter("command"),
new fjs.PropertyFormatter("system"),
new fjs.PropertyFormatter("true"),
new fjs.PropertyFormatter("false"),
new fjs.PropertyFormatter("syntax"),
new fjs.PropertyFormatter("originalName"),
new fjs.PropertyFormatter("newName"),
new fjs.PropertyFormatter("originalCategory"),
new fjs.PropertyFormatter("newCategory"),
new fjs.PropertyFormatter("until"),
new fjs.PropertyFormatter("validOptions"),
new fjs.PropertyFormatter("validPanels"),
new fjs.PropertyFormatter("autoclose"),
new fjs.PropertyFormatter("autodelete"),
new fjs.PropertyFormatter("startupDate"),
new fjs.PropertyFormatter("version"),
new fjs.PropertyFormatter("name"),
new fjs.PropertyFormatter("role"),
new fjs.PropertyFormatter("status"),
new fjs.PropertyFormatter("claimed"),
new fjs.PropertyFormatter("pinned"),
new fjs.PropertyFormatter("creationDate"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("noone"),
new fjs.PropertyFormatter("open"),
new fjs.PropertyFormatter("closed"),
new fjs.PropertyFormatter("priority"),
new fjs.PropertyFormatter("participants"),
new fjs.PropertyFormatter("yes"),
new fjs.PropertyFormatter("no"),
new fjs.PropertyFormatter("accept"),
new fjs.PropertyFormatter("cancel"),
new fjs.PropertyFormatter("option"),
new fjs.PropertyFormatter("topic"),
new fjs.PropertyFormatter("uptime"),
new fjs.PropertyFormatter("messages"),
new fjs.PropertyFormatter("embeds"),
new fjs.PropertyFormatter("files"),
new fjs.PropertyFormatter("components"),
new fjs.PropertyFormatter("cooldown"),
new fjs.PropertyFormatter("maxTickets"),
new fjs.PropertyFormatter("admins"),
new fjs.PropertyFormatter("roles"),
new fjs.PropertyFormatter("size"),
]),
new fjs.ObjectFormatter("lowercase",true,[
new fjs.PropertyFormatter("text"),
new fjs.PropertyFormatter("html"),
new fjs.PropertyFormatter("command"),
new fjs.PropertyFormatter("modal"),
new fjs.PropertyFormatter("button"),
new fjs.PropertyFormatter("dropdown"),
new fjs.PropertyFormatter("method"),
]),
]),
new fjs.ObjectFormatter("commands",true,[
new fjs.PropertyFormatter("reason"),
new fjs.PropertyFormatter("help"),
new fjs.PropertyFormatter("panel"),
new fjs.PropertyFormatter("panelId"),
new fjs.PropertyFormatter("panelAutoUpdate"),
new fjs.PropertyFormatter("ticket"),
new fjs.PropertyFormatter("ticketId"),
new fjs.PropertyFormatter("ticketOtherUser"),
new fjs.PropertyFormatter("close"),
new fjs.PropertyFormatter("delete"),
new fjs.PropertyFormatter("deleteNoTranscript"),
new fjs.PropertyFormatter("reopen"),
new fjs.PropertyFormatter("claim"),
new fjs.PropertyFormatter("claimUser"),
new fjs.PropertyFormatter("unclaim"),
new fjs.PropertyFormatter("pin"),
new fjs.PropertyFormatter("unpin"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("move"),
new fjs.PropertyFormatter("moveId"),
new fjs.PropertyFormatter("rename"),
new fjs.PropertyFormatter("renameName"),
new fjs.PropertyFormatter("add"),
new fjs.PropertyFormatter("addUser"),
new fjs.PropertyFormatter("remove"),
new fjs.PropertyFormatter("removeUser"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("blacklist"),
new fjs.PropertyFormatter("blacklistView"),
new fjs.PropertyFormatter("blacklistAdd"),
new fjs.PropertyFormatter("blacklistRemove"),
new fjs.PropertyFormatter("blacklistGet"),
new fjs.PropertyFormatter("blacklistGetUser"),
new fjs.PropertyFormatter("stats"),
new fjs.PropertyFormatter("statsReset"),
new fjs.PropertyFormatter("statsGlobal"),
new fjs.PropertyFormatter("statsUser"),
new fjs.PropertyFormatter("statsUserUser"),
new fjs.PropertyFormatter("statsTicket"),
new fjs.PropertyFormatter("statsTicketTicket"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("clear"),
new fjs.PropertyFormatter("clearFilter"),
new fjs.ObjectFormatter("clearFilters",true,[
new fjs.PropertyFormatter("all"),
new fjs.PropertyFormatter("open"),
new fjs.PropertyFormatter("close"),
new fjs.PropertyFormatter("claim"),
new fjs.PropertyFormatter("unclaim"),
new fjs.PropertyFormatter("pin"),
new fjs.PropertyFormatter("unpin"),
new fjs.PropertyFormatter("autoclose"),
]),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("autoclose"),
new fjs.PropertyFormatter("autocloseDisable"),
new fjs.PropertyFormatter("autocloseEnable"),
new fjs.PropertyFormatter("autocloseEnableTime"),
new fjs.PropertyFormatter("autodelete"),
new fjs.PropertyFormatter("autodeleteDisable"),
new fjs.PropertyFormatter("autodeleteEnable"),
new fjs.PropertyFormatter("autodeleteEnableTime"),
new fjs.TextFormatter(""),
new fjs.PropertyFormatter("topic"),
new fjs.PropertyFormatter("topicSet"),
new fjs.PropertyFormatter("topicValue"),
new fjs.PropertyFormatter("topicList"),
new fjs.PropertyFormatter("priority"),
new fjs.PropertyFormatter("prioritySet"),
new fjs.PropertyFormatter("priorityValue"),
new fjs.PropertyFormatter("priorityGet"),
new fjs.PropertyFormatter("priorityList"),
new fjs.PropertyFormatter("transfer"),
new fjs.PropertyFormatter("transferUser"),
new fjs.PropertyFormatter("transcripts"),
new fjs.PropertyFormatter("transcriptsUser"),
]),
new fjs.ObjectFormatter("helpMenu",true,[
new fjs.PropertyFormatter("help"),
new fjs.PropertyFormatter("ticket"),
new fjs.PropertyFormatter("close"),
new fjs.PropertyFormatter("delete"),
new fjs.PropertyFormatter("reopen"),
new fjs.PropertyFormatter("pin"),
new fjs.PropertyFormatter("unpin"),
new fjs.PropertyFormatter("move"),
new fjs.PropertyFormatter("rename"),
new fjs.PropertyFormatter("claim"),
new fjs.PropertyFormatter("unclaim"),
new fjs.PropertyFormatter("add"),
new fjs.PropertyFormatter("remove"),
new fjs.PropertyFormatter("panel"),
new fjs.PropertyFormatter("blacklistView"),
new fjs.PropertyFormatter("blacklistAdd"),
new fjs.PropertyFormatter("blacklistRemove"),
new fjs.PropertyFormatter("blacklistGet"),
new fjs.PropertyFormatter("statsGlobal"),
new fjs.PropertyFormatter("statsTicket"),
new fjs.PropertyFormatter("statsUser"),
new fjs.PropertyFormatter("statsReset"),
new fjs.PropertyFormatter("autocloseDisable"),
new fjs.PropertyFormatter("autocloseEnable"),
new fjs.PropertyFormatter("autodeleteDisable"),
new fjs.PropertyFormatter("autodeleteEnable"),
new fjs.ObjectFormatter("categories",true,[
new fjs.PropertyFormatter("general"),
new fjs.PropertyFormatter("basicTicket"),
new fjs.PropertyFormatter("advancedTicket"),
new fjs.PropertyFormatter("userTicket"),
new fjs.PropertyFormatter("admin"),
new fjs.PropertyFormatter("advanced"),
new fjs.PropertyFormatter("extra"),
])
]),
new fjs.ObjectFormatter("stats",true,[
new fjs.ObjectFormatter("scopes",true,[
new fjs.PropertyFormatter("global"),
new fjs.PropertyFormatter("system"),
new fjs.PropertyFormatter("user"),
new fjs.PropertyFormatter("ticket"),
new fjs.PropertyFormatter("participants"),
new fjs.PropertyFormatter("messages"),
]),
new fjs.ObjectFormatter("properties",true,[
new fjs.PropertyFormatter("ticketsCreated"),
new fjs.PropertyFormatter("ticketsClosed"),
new fjs.PropertyFormatter("ticketsDeleted"),
new fjs.PropertyFormatter("ticketsReopened"),
new fjs.PropertyFormatter("ticketsAutoclosed"),
new fjs.PropertyFormatter("ticketsClaimed"),
new fjs.PropertyFormatter("ticketsPinned"),
new fjs.PropertyFormatter("ticketsMoved"),
new fjs.PropertyFormatter("usersBlacklisted"),
new fjs.PropertyFormatter("transcriptsCreated"),
new fjs.PropertyFormatter("ticketsAutodeleted"),
new fjs.PropertyFormatter("ticketsTransferred"),
new fjs.PropertyFormatter("ticketVolume"),
new fjs.PropertyFormatter("averageTickets"),
new fjs.PropertyFormatter("currentTickets"),
new fjs.PropertyFormatter("age"),
new fjs.PropertyFormatter("responseTime"),
new fjs.PropertyFormatter("resolutionTime"),
new fjs.PropertyFormatter("createdOn"),
new fjs.PropertyFormatter("createdBy"),
new fjs.PropertyFormatter("closedOn"),
new fjs.PropertyFormatter("closedBy"),
new fjs.PropertyFormatter("claimedOn"),
new fjs.PropertyFormatter("claimedBy"),
new fjs.PropertyFormatter("pinnedOn"),
new fjs.PropertyFormatter("pinnedBy"),
new fjs.PropertyFormatter("deletedOn"),
new fjs.PropertyFormatter("deletedBy"),
]),
new fjs.ObjectFormatter("roles",true,[
new fjs.PropertyFormatter("developer"),
new fjs.PropertyFormatter("serverOwner"),
new fjs.PropertyFormatter("serverAdmin"),
new fjs.PropertyFormatter("moderator"),
new fjs.PropertyFormatter("support"),
new fjs.PropertyFormatter("member"),
])
]),
new fjs.ObjectFormatter("panel",true,[
new fjs.PropertyFormatter("selectTicket"),
new fjs.PropertyFormatter("selectRole"),
new fjs.PropertyFormatter("selectOption"),
new fjs.PropertyFormatter("selectPriorityLevel"),
]),
new fjs.ObjectFormatter("priorities",true,[
new fjs.PropertyFormatter("urgent"),
new fjs.PropertyFormatter("veryHigh"),
new fjs.PropertyFormatter("high"),
new fjs.PropertyFormatter("normal"),
new fjs.PropertyFormatter("low"),
new fjs.PropertyFormatter("veryLow"),
new fjs.PropertyFormatter("none"),
]),
])
for (const language of fs.readdirSync(".tools/languages/")){
if (!fs.existsSync("./languages/"+language)){
console.log("language:",language,"does not exist yet in the primary ./languages/ folder. Unable to merge!")
continue
}
console.log("merging "+language+"...")
const original = JSON.parse(fs.readFileSync("./languages/"+language).toString())
const newSentences = JSON.parse(fs.readFileSync(".tools/languages/"+language).toString())
for (const key of Object.keys(newSentences)){
if (key.startsWith("_")) continue
try{
const splitted = key.split(".")
let currentObject = original
splitted.forEach((property,index) => {
let shouldBeObject = (splitted.length-1 !== index)
if (shouldBeObject && typeof currentObject[property] == "object"){
currentObject = currentObject[property]
}else if (shouldBeObject && typeof currentObject[property] == "undefined"){
currentObject[property] = {}
currentObject = currentObject[property]
}else if (typeof currentObject[property] == "string" || typeof currentObject[property] == "undefined"){
currentObject[property] = newSentences[key]
}else{
console.log("Failed to merge key:",key,"in file:",language,"--> Invalid type:",typeof currentObject[property])
}
})
}catch(err){
console.log("Failed to merge key:",key,"in file:",language)
}
}
original["_TRANSLATION"]["lastedited"] = new Date().toLocaleDateString("nl-BE",{day:"2-digit",month:"2-digit",year:"numeric"})
original["_TRANSLATION"]["otversion"] = "v"+JSON.parse(fs.readFileSync("./package.json").toString()).version
const finalText = formatter.stringify(original)
fs.writeFileSync("./languages/"+language,finalText)
}
-3
View File
@@ -1,3 +0,0 @@
# comming soon
For now on, you can create a ticket in our server:
https://discord.dj-dj.be
+21
View File
@@ -0,0 +1,21 @@
# Docker File for Open Ticket
FROM node:22-alpine
# /home/container keeps Pterodactyl panel compatibility
# chown the workdir so node user can create/remove subdirectories
RUN mkdir -p /home/container && chown node:node /home/container
WORKDIR /home/container
# Install dependencies
COPY --chown=node:node package*.json ./
RUN npm install
# Copy app source
COPY --chown=node:node . .
ENV NODE_ENV=production
# Run as the built-in non-root node user
USER node
CMD ["node", "index.js"]
+42 -3
View File
@@ -1,7 +1,17 @@
<!-- omit from toc -->
# Open Ticket (License)
© 2021 - 2026 - DJj123dj & Contributors
#### Table Of Contents
- [General License](#general-license)
- [Additional Terms for Open Ticket](#additional-terms-for-open-ticket)
### General License
```
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007 Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> Copyright (C) 2026 DJdj Development. <https://www.dj-dj.be/>
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
@@ -70,7 +80,7 @@ modification follow.
TERMS AND CONDITIONS TERMS AND CONDITIONS
0. Definitions. 1. Definitions.
"This License" refers to version 3 of the GNU General Public License. "This License" refers to version 3 of the GNU General Public License.
@@ -671,4 +681,33 @@ into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>. <https://www.gnu.org/licenses/why-not-lgpl.html>.
```
### Additional Terms for Open Ticket
#### Terminology:
1. **“Software”**
Refers to the Open Ticket source code, documentation, and any associated files distributed under this license, including any modifications or derivative works thereof.
1. **“Public Discord Bot**
A Discord bot that is made publicly available for use by multiple, unrelated Discord servers or users, where the bot’s functionality is provided as a service rather than for private or personal use.
1. **“Monetized Service”**
Refers to any service or deployment that generates direct or indirect revenue through the use of the Software. This includes, but is not limited to, subscriptions, premium features, paid hosting, advertisements.
1. **“For-Profit Discord Server”**
Means a Discord server that generates income, revenue, or other material benefits, whether through memberships, donations, or other monetization strategies.
1. **“Private Use”**
Refers to using the Software on a limited number of Discord servers controlled or operated by a single individual or organization, not made available as a public service to multiple unrelated users.
#### Additional Terms:
The following additional terms apply to the use of this software:
1. This software may not be used as (or part of) a public Discord bot that is monetized (e.g., generating revenue through subscriptions, donations, or other forms of payment) without the prior written permission of the original author.
2. This software may not be used as (or part of) a public Discord bot on multiple Discord servers without attribution to the original author.
3. You are allowed to use this bot in a Discord server that makes money or is for-profit, provided that the income is not generated directly from the ticket bot or its functionality.
These additional terms are an extension to the GNU GPL v3 and must be followed alongside the original license terms. In case of any conflict between these additional terms and the GNU GPL v3, the additional terms shall take precedence.
+176 -46
View File
@@ -1,59 +1,189 @@
# Open Ticket <p align="center">
[![discord](https://img.shields.io/badge/discord-join%20our%20server-5865F2.svg?style=flat-square&logo=discord)](https://discord.com/invite/26vT9wt3n3) [![version](https://img.shields.io/badge/version-3.0.0-brightgreen.svg?style=flat-square)](https://github.com/DJj123dj/open-ticket/releases/tag/v3.0.0) [![discord.js](https://img.shields.io/badge/discord.js-v14-CB3837.svg?style=flat-square&logo=npm)]() [![license](https://img.shields.io/badge/license-GPL%203.0-important.svg?style=flat-square)](https://github.com/DJj123dj/open-ticket/blob/main/LICENSE) [![documentation](https://img.shields.io/badge/documentation-Click%20Here-yellow.svg?style=flat-square)](https://docs.openticket.dj-dj.be) <img src="https://apis.dj-dj.be/cdn/openticket/logo.png" alt="Open Ticket" width="650px"><br>
<span align="center"><b>The most advanced self-hosted ticket bot for Discord</b></span><br>
<sub align="center">Related Projects:</sub><br>
<a href="https://odplugins.dj-dj.be"><img src="https://apis.dj-dj.be/cdn/opendiscord/logo.png" alt="Open Discord" height="55px"></a><br><br>
<a href="https://discord.com/invite/26vT9wt3n3"><img alt="Discord Invite Link" src="https://img.shields.io/badge/discord-support%20server-5865F2.svg?style=flat-square&logo=discord"></img></a>
<a href="https://github.com/open-discord-bots/open-ticket/releases/tag/v4.2.1"><img alt="Open Ticket Version" src="https://img.shields.io/badge/version-4.2.1-brightgreen.svg?style=flat-square"></img></a>
<a href="https://otdocs.dj-dj.be"><img alt="Open Ticket Documentation" src="https://img.shields.io/badge/discord.js-v14-CB3837.svg?style=flat-square&logo=npm"></img></a>
<a href="https://github.com/open-discord-bots/open-ticket/blob/main/LICENSE"><img alt="Open Ticket License" src="https://img.shields.io/badge/license-GPL%203.0-important.svg?style=flat-square"></img></a>
<a href="https://otdocs.dj-dj.be"><img alt="Open Ticket Stars" src="https://img.shields.io/github/stars/djj123dj/open-ticket?color=yellow&label=stars&logo=github&style=flat-square"></img></a>
<a href="https://github.com/sponsors/DJj123dj"><img alt="Sponsor DJj123dj" src="https://img.shields.io/badge/sponsor-DJj123dj-ea4aaa?style=flat-square&logo=githubsponsors"></img></a>
<a href="https://hub.docker.com/repository/docker/djj123dj/open-ticket"><img alt="Open Ticket supports Docker!" src="https://img.shields.io/badge/docker-supported-2496ED?style=flat-square&logo=docker"></img></a>
<a href=".github/pterodactyl-eggs/README.md"><img alt="Open Ticket supports Pterodactyl Eggs!" src="https://img.shields.io/badge/pterodactyl-supported-10539F?style=flat-square&logo=pterodactyl"></img></a>
</p>
Open ticket is the most configurable open-source ticket bot for discord! Made with the newest technologies. Like: Slash commands, transcripts, multiple ticket types, buttons & dropdowns! <p align="center">
Start using it now, you can do anything! Open Ticket is the most <b>advanced and customizable</b> Discord ticket bot available right now. It features more than <b>350+ configurable settings</b> to control almost every aspect of your ticket system.
From <code>HTML transcripts</code> and <code>Advanced Plugins</code> to <code>Claiming & Pinning</code>, <code>Modal Questions & Limits</code>, <code>Detailed Statistics</code>, and much more.
The bot is fully translated into <b>38+ languages</b> and has been battle-tested in large Discord servers. Need help or want to get involved? Feel free to join our <a href="https://discord.dj-dj.be"><b>Discord server</b></a>.
</p>
*We love to hear suggestions for more features!* <h3 align="center"><b>⭐️ Support Open Ticket’s growth by starring this repo! ⭐️</b></h3>
<p align="center"><sup>❤️ Love Open Ticket? <a href="https://github.com/sponsors/DJj123dj">Sponsorships</a> help fuel our HTML transcript servers and future features! ❤️</sup><br>
<img align="center" src="https://raw.githubusercontent.com/open-discord-bots/hall-of-fame/refs/heads/main/svg/SPONSORS_YELLOW.svg" alt="A list of Open Ticket Sponsors" width="800px">
</p>
<img src="logo.png" alt="Open Ticket logo" style="height: 200px; width:200px;"/> ---
> **[-> Navigate to (⏱️ Quick Setup)](#️-quick-start)**
> **[-> Navigate to (📚 Documentation)](https://otdocs.dj-dj.be)**
> **[-> Navigate to (📞 Support Server)](https://discord.dj-dj.be)**
> **[-> Navigate to (🧩 Plugins/Addons)](https://odplugins.dj-dj.be)**
> **[-> Navigate to (🦇 Pterodactyl Eggs)](.github/pterodactyl-eggs/README.md)**
[![wiki](https://img.shields.io/badge/documentation-click%20here-blue.svg?style=flat-square)](https://www.github.com/DJj123dj/open-ticket/wiki) ### 📌 Features
#### Core Features
- <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/core-management.svg"></img> **Ticket Management** - Close, reopen, delete, claim or pin tickets with ease.
- <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/core-commands.svg"></img> **Powerful Commands** - Manage your support system with **30+ commands** for staff & users.
- <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/core-questions.svg"></img> **Modal Questions** - Ask users **custom questions** before a ticket is created.
- <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/core-priorities.svg"></img> **Priorities** - Assign **priority levels** to tickets to highlight urgent requests.
- <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/core-participants.svg"></img> **Participants** - Add or remove participants & transfer ownership from one user to another.
- <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/core-adjustments.svg"></img> **Adjustments** - Rename tickets, change ticket types or transfer ownership.
- <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/core-blacklist.svg"></img> **Blacklist & Limits** - Prevent users from creating tickets and set per-user or global ticket limits.
- <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/core-customisable.svg"></img> **Highly Customisable** - Configure **350+ settings** covering appearance and behaviour.
### Thanks to these people: #### Ticket Automation & Workflows
- DJ-Lite: for doing the administration - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/automation-unlimited.svg"></img> **Unlimited Possibilities** - Create unlimited tickets, panels & question flows.
- Sanke: for translation & new ideas - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/automation-autoclose.svg"></img> **Autoclose Tickets** - Automatically **close tickets** after predefined conditions.
- Everyone that reported a bug - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/automation-autodelete.svg"></img> **Autodelete Tickets** - Automatically **delete closed tickets** to keep channels clean.
#### And our translators! - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/automation-categories.svg"></img> **Category Routing** - Move tickets between categories based on claim or close state.
- ExothDE
- 1x1
- Redactado
- t0miiis
- josuens14
- M4
- David.
- Maurizio
## features #### Transcripts & Insights
- discord interaction buttons - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/insights-transcripts.svg"></img> **HTML Transcripts** - Generate beautiful, easy-to-read **HTML transcripts** for every ticket.
- slash & text commands - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/insights-stats.svg"></img> **Detailed Statistics** - Track **50+ statistics** for tickets, users and server activity.
- close, delete & re-open tickets - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/insights-logs.svg"></img> **Ticket Logs** - Track **all ticket events** such as creation, closures, and staff actions.
- translation in 10 different languages
- transcripts
- add/remove users from a ticket
- a lot of customisation options.
- tickets, reaction roles & links are all possible!
- choose between buttons or dropdowns!
- discord.js v14
- everyting is configurable
- custom API + plugins
- unlimited tickets spread over multiple messages
- close with reason
*comming soon* #### User Experience
- share transcripts - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/ux-translated.svg"></img> **Fully Translated** - Available in **38+ languages**, translated and maintained by the community.
- view transcripts in html - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/ux-interactions.svg"></img> **Modern Interactions** - Full support for buttons, dropdowns, slash/text commands & modals.
- <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/ux-panels.svg"></img> **Panels** - Create messages with buttons or a dropdown for users to open tickets.
- <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/ux-sub-panels.svg"></img> **Sub-Panels** - One panel not enough? Use multiple panels to offer more choices.
## quick start #### Plugins & Ecosystem
[Click here to start your adventure!](https://docs.openticket.dj-dj.be/quick-start) - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/ecosystem-plugins.svg"></img> **Plugin System** - Use custom plugins to **add new features** or **modify existing behavior** of the bot.
- <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/ecosystem-community.svg"></img> **Community Plugins** - Use and share plugins built by the community.
- <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/ecosystem-api.svg"></img> **Advanced API** - Build advanced plugins with access to ticket events and internal systems.
- <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/ecosystem-integrations.svg"></img> **Integrations** - Connect Open Ticket with external services to automate workflows across platforms.
- <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/ecosystem-bonus.svg"></img> **Bonus Features** - Somehow, we included Reaction Roles and URL Button support as well.
## documentation #### Deployment
[Official Documentation](https://docs.openticket.dj-dj.be) - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/deployment-quick.svg"></img> **Quick Setup** - Easy **5-minute configuration** using the Interactive Setup CLI.
- <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/deployment-scale.svg"></img> **Scalable & Reliable** - Battle-tested in servers with **100k+ members**.
- <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/deployment-secure.svg"></img> **Private & Secure** - Used by thousands of servers with respect for security & privacy.
- <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/deployment-pterodactyl.svg"></img> **Pterodactyl Support** - 100% compatible with Pterodactyl panels. [(Download official eggs)](.eggs/README.md)
- <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/deployment-docker.svg"></img> **Docker Support** - Deploy Open Ticket in minutes with Docker containers.
## information #### Extend functionality even more with our [pre-made community plugins](https://github.com/open-discord-bots/plugins)!
> - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/plugin-reviews.svg"></img> **Reviews** - Create and manage a support review system for tickets.
> - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/plugin-tags.svg"></img> **Tags** - Define keywords that automatically trigger predefined responses.
> - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/plugin-reminders.svg"></img> **Reminders** - Create and manage custom reminders for users or staff.
> - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/plugin-ai.svg"></img> **AI Integrations** - Connect to AI providers such as ChatGPT, Claude, or Gemini.
> - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/plugin-display.svg"></img> **Channel Display** - Create voice channels that display real-time ticket system statistics.
> - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/plugin-forms.svg"></img> **Forms** - Build advanced forms for collecting structured information from users.
> - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/plugin-embeds.svg"></img> **Custom Embeds** - Create and send custom embeds via commands.
> - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/core-customisable.svg"></img> **Customization Tools** - Additional configuration options for advanced behavior and styling.
> - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/plugin-dashboard.svg"></img> **Web Dashboard** - Configure and manage the bot through a remote web dashboard.
> - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/plugin-feedback.svg"></img> **Feedback** - Collect user feedback after ticket deletion using forms.
> - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/plugin-sqlite.svg"></img> **SQLite Database** - Use an SQLite backend for improved performance and lightweight storage.
> - <img align="top" src="https://apis.dj-dj.be/cdn/openticket/readme-icons/plugin-more.svg"></img> **And more** - Additional community plugins are available and actively expanding.
_v3.0.0_ ## ⏱️ Quick Start
> 1. Download the [latest version of Open Ticket](https://github.com/open-discord-bots/open-ticket/releases/latest).
> 2. Make sure you have installed Node.js on your system (check using `node -v`, minimum `v20`).
> 3. Install any required dependencies using `npm install`.
> 4. Configure the bot in one of the following ways:
> - Method 1 (Easy): Start the **Quick Setup CLI** using `npm run setup`.
> - Method 2 (Hard): Manual **JSON configuration** in `./config/...`
> 5. If using the **Quick Setup CLI**, click on `> ⏱️ Quick Setup` and follow the instructions.
> 6. Start the bot using `npm start` or `node index.js`
> - If any config errors occur, the bot will give you a report of how to solve them.
> - Follow the instructions and restart the bot.
> 7. Enjoy using Open Ticket!
> 8. Install plugins from the [**Official Plugin Repository**](https://github.com/open-discord-bots/plugins)
>
> #### 🚦 Next Steps
> **[-> Navigate to (📚 Documentation)](https://otdocs.dj-dj.be)**
> **[-> Navigate to (📞 Support Server)](https://discord.dj-dj.be)**
> **[-> Navigate to (🧩 Plugins/Addons)](https://odplugins.dj-dj.be)**
> **[-> Navigate to (🦇 Pterodactyl Eggs)](.github/pterodactyl-eggs/README.md)**
>
> #### 🖥️ Recommended Hosting
> - **A VPS (Virtual Private Server)** - Extra customisation & more stability. Recommended for most servers.
> - **Any Pterodactyl-Based Panel** - Easy installation & configuration.
changelog: [click here](https://docs.openticket.dj-dj.be/other/changelog) ## 📸 Previews
<img alt="Preview of: Advanced Ticket Management" src="https://apis.dj-dj.be/cdn/openticket/ot-previews/preview-1.png">
<img alt="Preview of: Customisable Ticket Panels" src="https://apis.dj-dj.be/cdn/openticket/ot-previews/preview-2.png">
<img alt="Preview of: Modal Questions & Forms" src="https://apis.dj-dj.be/cdn/openticket/ot-previews/preview-3.png">
<img alt="Preview of: Detailed Statistics & Insights" src="https://apis.dj-dj.be/cdn/openticket/ot-previews/preview-4.png">
<img alt="Preview of: 30+ Powerful Commands" src="https://apis.dj-dj.be/cdn/openticket/ot-previews/preview-5.png">
<img alt="Preview of: Buttons, Transcripts, Limits & More!" src="https://apis.dj-dj.be/cdn/openticket/ot-previews/preview-6.png">
© 2022 - DJdj Development | [website](https://www.dj-dj.be) | [discord](https://discord.dj-dj.be) | [terms of service](https://www.dj-dj.be/terms) ## 💬 Translations
With the amazing support of our translators, we've been able to translate Open Ticket in more than **38 languages**!
#### Categories: 🟢 Available - 🤖 Partially Made Using AI - 🟠 Incomplete - 🔴 Unavailable/Outdated
|🔍 |Languages (38) |Config Value |Maintainers (Github/Discord) |
|----|----------------------|------------------------|--------------------------------|
|🟢 |🇬🇧 English |`"english"` |djj123dj |
|🟢 |🇳🇱 Dutch |`"dutch"` |djj123dj |
|🟢 |🇩🇪 German |`"german"` |benzorich |
|🟢 |🇫🇷 French |`"french"` |guillee.3 |
|🟢 |🇪🇸 Spanish |`"spanish"` |Reddishye & josuens |
|🟢 |🇵🇹 Portuguese |`"portuguese"` |quiradon |
|🟢 |🇮🇹 Italian |`"italian"` |fraden1mvp. & imperatorix_17 |
|🟢 |🇸🇪 Swedish |`"swedish"` |NoOneNook |
|🟢 |🇳🇴 Norwegian |`"norwegian"` |NoOneNook |
|🟢 |🇹🇭 Thai |`"thai"` |modshd |
|🟢 |🇮🇳 Hindi |`"hindi"` |challenger_nova |
|🟢 |🇭🇺 Hungarian |`"hungarian"` |kornel0706 |
|🟢 |🇮🇩 Indonesian |`"indonesian"` |erxg |
|🟢 |🇱🇹 Lithuanian |`"lithuanian"` |tsgindrius |
|🟢 |🇺🇦 Ukrainian |`"ukrainian"` |anderskiy |
|🟢 |🇨🇿 Czech |`"czech"` |spyeye_ |
|🟢 |🇷🇴 Romanian |`"romanian"` |sankedev |
|🟢 |🇩🇰 Danish |`"danish"` |the_gamer |
|🟢 |🇹🇷 Turkish |`"turkish"` |palestinian |
|🟢 |🇦🇪 Arabic |`"arabic"` |palestinian |
|🟢 |🇵🇱 Polish |`"polish"` |danoglez |
|🟢 |🇮🇷 Persian |`"persian"` |dysashop & zhavis |
|🟢 |🇧🇩 Bengali |`"bengali"` |HanumeshGupta |
|🟢 |❓ Catalan |`"catalan"` |guillee3 |
|🟢 |🇨🇳 Traditional Chinese|`"traditional-chinese"` |me.october |
|🟢 |🇰🇭 Khmer (Cambodia) |`"khmer"` |yuuslokrobjakkroval |
|🤖 |🇪🇪 Estonian |`"estonian"` |iamnotmega |
|🤖 |🇫🇮 Finnish |`"finnish"` |iamnotmega |
|🤖 |🇯🇵 Japanese |`"japanese"` |HanumeshGupta |
|🤖 |🇬🇷 Greek |`"greek"` |HanumeshGupta |
|🤖 |🇸🇮 Slovenian |`"slovenian"` |HanumeshGupta |
|🤖 |🇰🇷 Korean |`"korean"` |HanumeshGupta |
|🤖 |🇮🇳 Tamil |`"tamil"` |HanumeshGupta |
|🤖 |❓ Kurdish |`"kurdish"` |HanumeshGupta |
|🤖 |🇷🇺 Russian |`"russian"` |NoOneNook |
|🤖 |🇱🇻 Latvian |`"latvian"` |NoOneNook |
|🤖 |🇻🇳 Vietnamese |`"vietnamese"` |ngocdiep2006 |
|🤖 |🇨🇳 Simplified Chinese |`"simplified-chinese"` |HanumeshGupta |
<!--[⭐ Contribute!](.github/CONTRIBUTING.md) -->
## 😎 Hall Of Fame
<img alt="The full list of contributors for Open Ticket and Open Discord." src="https://raw.githubusercontent.com/open-discord-bots/hall-of-fame/refs/heads/main/svg/CONTRIBUTORS.svg">
## ⭐️ Star History
If you enjoy using Open ticket, **consider starring** our repository.
This will help us grow and reach even more people!
<a href="https://star-history.com/#open-discord-bots/open-ticket&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=open-discord-bots/open-ticket&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=open-discord-bots/open-ticket&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=open-discord-bots/open-ticket&type=Date" />
</picture>
</a>
---
<img src="https://apis.dj-dj.be/cdn/openticket/logo.png" alt="Open Ticket Logo" width="170px">
**README.md**<br>
[Changelog](https://otgithub.dj-dj.be/releases) - [Documentation](https://otdocs.dj-dj.be) - [Website](https://openticket.dj-dj.be) - [Support Server](https://discord.dj-dj.be) - [License](./LICENSE.md)<br>
© 2021 - 2026 - [DJdj Development](https://www.dj-dj.be) - [Terms](https://www.dj-dj.be/terms) - [Privacy Policy](https://www.dj-dj.be/privacy) - [Support Us](https://github.com/sponsors/DJj123dj)
-79
View File
@@ -1,79 +0,0 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events")
const DISABLE = require("../core/api/api.json").disable
module.exports = () => {
bot.errorLog.log("debug","COMMANDS: loaded add.js")
if (!DISABLE.commands.text.add) client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix+"add")) return
var user = msg.mentions.users.first()
if (!user) return msg.channel.send({embeds:[bot.errorLog.invalidArgsMessage(l.errors.missingArgsDescription+" `<user>`:\n`"+config.prefix+"add <user>`")]})
if (!msg.guild) return
if (!permsChecker.command(msg.author.id,msg.guild.id)){
permsChecker.sendUserNoPerms(msg.author)
return
}
msg.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
msg.channel.permissionOverwrites.create(user.id, { ViewChannel:true, AddReactions:true,AttachFiles:true, EmbedLinks:true, SendMessages:true})
msg.channel.send({embeds:[bot.embeds.commands.addEmbed(user,msg.author)]})
var loguser = msg.mentions.users.first()
log("command","someone used the 'add' command",[{key:"user",value:msg.author.tag}])
log("system","user added to ticket",[{key:"user",value:msg.author.tag},{key:"ticket",value:msg.channel.name},{key:"added_user",value:loguser.tag}])
const ticketData = require("../core/utils/configParser").getTicketById(ticketId,true)
APIEvents.onTicketAdd(msg.author,loguser,msg.channel,msg.guild,new Date(),{status:"open",name:msg.channel.name,ticketOptions:ticketData})
APIEvents.onCommand("add",permsChecker.command(msg.author.id,msg.guild.id),msg.author,msg.channel,msg.guild,new Date())
})
})
if (!DISABLE.commands.slash.add) client.on("interactionCreate",(interaction) => {
if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "add") return
const user = interaction.options.getUser("user")
if (!interaction.guild) return
if (!permsChecker.command(interaction.user.id,interaction.guild.id)){
permsChecker.sendUserNoPerms(interaction.user)
return
}
interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
interaction.channel.permissionOverwrites.create(user.id, { ViewChannel:true, AddReactions:true,AttachFiles:true, EmbedLinks:true, SendMessages:true})
interaction.reply({embeds:[bot.embeds.commands.addEmbed(user,interaction.user)]})
var loguser = user
log("command","someone used the 'add' command",[{key:"user",value:interaction.user.tag}])
log("system","user added to ticket",[{key:"user",value:interaction.user.tag},{key:"ticket",value:interaction.channel.name},{key:"added_user",value:loguser.tag}])
const ticketData = require("../core/utils/configParser").getTicketById(ticketId,true)
APIEvents.onTicketAdd(interaction.user,loguser,interaction.channel,interaction.guild,new Date(),{status:"open",name:interaction.channel.name,ticketOptions:ticketData})
APIEvents.onCommand("add",permsChecker.command(interaction.user.id,interaction.guild.id),interaction.user,interaction.channel,interaction.guild,new Date())
})
})
}
-80
View File
@@ -1,80 +0,0 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events")
const DISABLE = require("../core/api/api.json").disable
module.exports = () => {
bot.errorLog.log("debug","COMMANDS: loaded claim.js")
if (!DISABLE.commands.text.claim) client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix+"claim")) return
var user = msg.mentions.users.first()
const claimingUser = user ? user : msg.author
if (!msg.guild) return
if (!permsChecker.command(msg.author.id,msg.guild.id)){
permsChecker.sendUserNoPerms(msg.author)
return
}
msg.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
//msg.channel.send({embeds:[bot.embeds.commands.claimEmbed(claimingUser,msg.author)]})
msg.channel.send({embeds:[bot.errorLog.warning("Coming soon!","This feature isn't ready yet!\nIt will become active in the next update!")]})
var loguser = claimingUser
log("command","someone used the 'claim' command",[{key:"user",value:msg.author.tag}])
log("system","user claimed to ticket",[{key:"user",value:msg.author.tag},{key:"ticket",value:msg.channel.name},{key:"claimed_user",value:claimingUser.tag}])
const ticketData = require("../core/utils/configParser").getTicketById(ticketId,true)
//APIEvents.onTicketAdd(msg.author,loguser,msg.channel,msg.guild,new Date(),{status:"open",name:msg.channel.name,ticketOptions:ticketData})
//APIEvents.onCommand("add",permsChecker.command(msg.author.id,msg.guild.id),msg.author,msg.channel,msg.guild,new Date())
})
})
if (!DISABLE.commands.slash.claim) client.on("interactionCreate",(interaction) => {
if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "claim") return
const user = interaction.options.getUser("user",false) ? interaction.options.getUser("user",true) : interaction.user
if (!interaction.guild) return
if (!permsChecker.command(interaction.user.id,interaction.guild.id)){
permsChecker.sendUserNoPerms(interaction.user)
return
}
interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
//interaction.reply({embeds:[bot.embeds.commands.claimEmbed(user,interaction.user)]})
interaction.reply({embeds:[bot.errorLog.warning("Coming soon!","This feature isn't ready yet!\nIt will become active in the next update!")]})
var loguser = user
log("command","someone used the 'claim' command",[{key:"user",value:interaction.user.tag}])
log("system","user claimed to ticket",[{key:"user",value:interaction.user.tag},{key:"ticket",value:interaction.channel.name},{key:"claimed_user",value:loguser.tag}])
const ticketData = require("../core/utils/configParser").getTicketById(ticketId,true)
//APIEvents.onTicketAdd(interaction.user,loguser,interaction.channel,interaction.guild,new Date(),{status:"open",name:interaction.channel.name,ticketOptions:ticketData})
//APIEvents.onCommand("add",permsChecker.command(interaction.user.id,interaction.guild.id),interaction.user,interaction.channel,interaction.guild,new Date())
})
})
}
-92
View File
@@ -1,92 +0,0 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events")
const DISABLE = require("../core/api/api.json").disable
module.exports = () => {
bot.errorLog.log("debug","COMMANDS: loaded close.js")
if (!DISABLE.commands.text.close) client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix+"close")) return
const args = msg.content.substring((config.prefix+"close").length).split(" ")
args.shift()
/**@type {String|false} */
var tempreason = args.join(" ")
if (!tempreason || tempreason == " " || tempreason == " "){
tempreason = false
}
const reason = tempreason
msg.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
if (hiddendata.data.find(h => h.key == "pendingdelete")) return msg.channel.send({embeds:[bot.errorLog.warning("Warning!","You can't close a ticket while it's being deleted!")]})
const descriptionReason = reason ? "**"+l.messages.reason+":** "+reason : false
msg.channel.send({embeds:[bot.embeds.commands.closeEmbed(msg.author,descriptionReason)],components:[bot.buttons.close.closeCommandRow]})
var name = msg.channel.name
var prefix = ""
const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
}
})
require("../core/ticketActions/ticketCloser").NEWcloseTicket(msg.member,msg.channel,prefix,"close",reason,true)
log("command","someone used the 'close' command",[{key:"user",value:msg.author.tag}])
APIEvents.onCommand("close",true,msg.author,msg.channel,msg.guild,new Date())
})
})
if (!DISABLE.commands.slash.close) client.on("interactionCreate",(interaction) => {
if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "close") return
//interaction.deferReply()
const reason = interaction.options.getString("reason") ? interaction.options.getString("reason") : false
interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
if (hiddendata.data.find(h => h.key == "pendingdelete")) return interaction.reply({embeds:[bot.errorLog.warning("Warning!","You can't close a ticket while it's being deleted!")]})
const descriptionReason = reason ? "**"+l.messages.reason+":** "+reason : false
interaction.reply({embeds:[bot.embeds.commands.closeEmbed(interaction.user,descriptionReason)],components:[bot.buttons.close.closeCommandRow]})
var name = interaction.channel.name
var prefix = ""
const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
}
})
require("../core/ticketActions/ticketCloser").NEWcloseTicket(interaction.member,interaction.channel,prefix,"close",false,true)
log("command","someone used the 'close' command",[{key:"user",value:interaction.user.tag}])
APIEvents.onCommand("close",true,interaction.user,interaction.channel,interaction.guild,new Date())
})
})
}
-86
View File
@@ -1,86 +0,0 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events")
const DISABLE = require("../core/api/api.json").disable
module.exports = () => {
bot.errorLog.log("debug","COMMANDS: loaded delete.js")
if (!DISABLE.commands.text.delete) client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix+"delete")) return
if (!msg.guild) return
if (!permsChecker.command(msg.author.id,msg.guild.id)){
permsChecker.sendUserNoPerms(msg.author)
return
}
msg.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
msg.channel.send({embeds:[bot.embeds.commands.deleteEmbed(msg.author)]})
var name = msg.channel.name
var prefix = ""
const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
}
})
require("../core/ticketActions/ticketCloser").NEWcloseTicket(msg.member,msg.channel,prefix,"delete",false,true)
log("command","someone used the 'delete' command",[{key:"user",value:msg.author.tag}])
APIEvents.onCommand("delete",permsChecker.command(msg.author.id,msg.guild.id),msg.author,msg.channel,msg.guild,new Date())
})
})
if (!DISABLE.commands.slash.delete) client.on("interactionCreate",(interaction) => {
if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "delete") return
//interaction.deferReply()
if (!interaction.guild) return
if (!permsChecker.command(interaction.user.id,interaction.guild.id)){
permsChecker.sendUserNoPerms(interaction.user)
return interaction.reply({embeds:[bot.errorLog.noPermsDelete(interaction.user)]})
}
interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
interaction.reply({embeds:[bot.embeds.commands.deleteEmbed(interaction.user)]})
var name = interaction.channel.name
var prefix = ""
const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
}
})
require("../core/ticketActions/ticketCloser").NEWcloseTicket(interaction.member,interaction.channel,prefix,"delete",false,true)
log("command","someone used the 'delete' command",[{key:"user",value:interaction.user.tag}])
APIEvents.onCommand("delete",permsChecker.command(interaction.user.id,interaction.guild.id),interaction.user,interaction.channel,interaction.guild,new Date())
})
})
}
-56
View File
@@ -1,56 +0,0 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const l = bot.language
const APIEvents = require("../core/api/modules/events")
const DISABLE = require("../core/api/api.json").disable
module.exports = () => {
bot.errorLog.log("debug","COMMANDS: loaded help.js")
const msgName = config.system.showSlashcmdsInHelp ? "message" : "msg"
const prefix = config.system.showSlashcmdsInHelp ? "/" : config.prefix
const helpEmbed = new discord.EmbedBuilder()
.setColor(config.main_color)
.setTitle("❔ "+l.helpMenu.title)
const header = config.system.ticket_channel ? l.helpMenu.header1.replace("{0}","<#"+config.system.ticket_channel+">") : l.helpMenu.header2
helpEmbed.setDescription(header+"`"+prefix+msgName+" <id>` ➜ _"+l.helpMenu.msgCmd+"_\n\n`"+prefix+"rename <name>` ➜ _"+l.helpMenu.renameCmd+"_\n`"+prefix+"close` ➜ _"+l.helpMenu.closeCmd+"_\n`"+prefix+"delete` ➜ _"+l.helpMenu.deleteCmd+"_\n`"+prefix+"reopen` ➜ _"+l.helpMenu.reopenCmd+"_\n\n`"+prefix+"add <user>` ➜ _"+l.helpMenu.addCmd+"_\n`"+prefix+"remove <user>` ➜ _"+l.helpMenu.removeCmd+"_")
if (config.credits) helpEmbed.setFooter({text:"Open-Ticket by DJdj Development | view on github for source code",iconURL:"https://raw.githubusercontent.com/DJj123dj/open-ticket/main/logo.png"})
var otherprefix = prefix.endsWith(" ") ? prefix.substring(0,prefix.length-1) : prefix
if (!DISABLE.commands.text.help) client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix)) return
var args = msg.content.split(config.prefix)
if (msg.content == config.prefix || msg.content == config.prefix+" " || msg.content == otherprefix){
msg.channel.send({embeds:[helpEmbed]})
log("command","someone used the 'help' command",[{key:"user",value:msg.author.tag}])
APIEvents.onCommand("help",true,msg.author,msg.channel,msg.guild,new Date())
return
}
if (args[1]){
if (!args[1].startsWith("close") && !args[1].startsWith("delete") && !args[1].startsWith("remove") && !args[1].startsWith("add") && !args[1].startsWith("msg") && !args[1].startsWith("remove") && !args[1].startsWith("rename") && !args[1].startsWith("reopen")){
msg.channel.send({embeds:[helpEmbed]})
log("command","someone used the 'help' command",[{key:"user",value:msg.author.tag}])
APIEvents.onCommand("help",true,msg.author,msg.channel,msg.guild,new Date())
}
}
})
if (!DISABLE.commands.slash.help) client.on("interactionCreate",(interaction) => {
if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "help") return
interaction.reply({embeds:[helpEmbed]})
log("command","someone used the 'help' command",[{key:"user",value:interaction.user.tag}])
APIEvents.onCommand("help",true,interaction.user,interaction.channel,interaction.guild,new Date())
})
}
-77
View File
@@ -1,77 +0,0 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events")
const DISABLE = require("../core/api/api.json").disable
module.exports = () => {
bot.errorLog.log("debug","COMMANDS: loaded remove.js")
if (!DISABLE.commands.text.remove) client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix+"remove")) return
var user = msg.mentions.users.first()
if (!user) return msg.channel.send({embeds:[bot.errorLog.invalidArgsMessage(l.errors.missingArgsDescription+" `<user>`:\n`"+config.prefix+"remove <user>`")]})
if (!msg.guild) return
if (!permsChecker.command(msg.author.id,msg.guild.id)){
permsChecker.sendUserNoPerms(msg.author)
return
}
msg.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
msg.channel.permissionOverwrites.delete(user.id)
msg.channel.send({embeds:[bot.embeds.commands.removeEmbed(user,msg.author)]})
var loguser = msg.mentions.users.first()
log("command","someone used the 'remove' command",[{key:"user",value:msg.author.tag}])
log("system","user removed from ticket",[{key:"user",value:msg.author.tag},{key:"ticket",value:msg.channel.name},{key:"removed_user",value:loguser.tag}])
const ticketData = require("../core/utils/configParser").getTicketById(ticketId,true)
APIEvents.onTicketRemove(msg.author,loguser,msg.channel,msg.guild,new Date(),{status:"open",name:msg.channel.name,ticketOptions:ticketData})
APIEvents.onCommand("remove",permsChecker.command(msg.author.id,msg.guild.id),msg.author,msg.channel,msg.guild,new Date())
})
})
if (!DISABLE.commands.slash.remove) client.on("interactionCreate",async (interaction) => {
if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "remove") return
const user = interaction.options.getUser("user")
if (!interaction.guild) return
if (!permsChecker.command(interaction.user.id,interaction.guild.id)){
permsChecker.sendUserNoPerms(interaction.user)
return
}
await interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
interaction.channel.permissionOverwrites.delete(user.id)
interaction.reply({embeds:[bot.embeds.commands.removeEmbed(user,interaction.user)]})
var loguser = user
log("command","someone used the 'remove' command",[{key:"user",value:interaction.user.tag}])
log("system","user removed from ticket",[{key:"user",value:interaction.user.tag},{key:"ticket",value:interaction.channel.name},{key:"removed_user",value:loguser.tag}])
const ticketData = require("../core/utils/configParser").getTicketById(ticketId,true)
APIEvents.onTicketRemove(interaction.user,loguser,interaction.channel,interaction.guild,new Date(),{status:"open",name:interaction.channel.name,ticketOptions:ticketData})
APIEvents.onCommand("remove",permsChecker.command(interaction.user.id,interaction.guild.id),interaction.user,interaction.channel,interaction.guild,new Date())
})
})
}
-95
View File
@@ -1,95 +0,0 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events")
const DISABLE = require("../core/api/api.json").disable
module.exports = () => {
bot.errorLog.log("debug","COMMANDS: loaded rename.js")
if (!DISABLE.commands.text.rename) client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix+"rename")) return
if (!msg.guild) return
if (!permsChecker.command(msg.author.id,msg.guild.id)){
permsChecker.sendUserNoPerms(msg.author)
return
}
msg.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
var newname = msg.content.split(config.prefix+"rename")[1].substring(1)
if (!newname) return msg.channel.send({embeds:[bot.errorLog.invalidArgsMessage(l.errors.missingArgsDescription+" `<name>`:\n`"+config.prefix+"rename <name>`")]})
var name = msg.channel.name
var prefix = ""
const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
}
})
if (!prefix) prefix = "noprefix-"
msg.channel.setName(prefix+newname)
msg.channel.send({embeds:[bot.embeds.commands.renameEmbed(msg.author,prefix+newname)]})
log("command","someone used the 'rename' command",[{key:"user",value:msg.author.tag}])
log("system","ticket renamed",[{key:"user",value:msg.author.tag},{key:"ticket",value:name},{key:"newname",value:newname}])
APIEvents.onCommand("rename",permsChecker.command(msg.author.id,msg.guild.id),msg.author,msg.channel,msg.guild,new Date())
})
})
if (!DISABLE.commands.slash.rename) client.on("interactionCreate",(interaction) => {
if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "rename") return
if (!interaction.guild) return
if (!permsChecker.command(interaction.user.id,interaction.guild.id)){
permsChecker.sendUserNoPerms(interaction.user)
return
}
//interaction.deferReply()
interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
var newname = interaction.options.getString("name")
var name = interaction.channel.name
var prefix = ""
const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
}
})
if (!prefix) prefix = "noprefix-"
interaction.channel.setName(prefix+newname)
interaction.reply({embeds:[bot.embeds.commands.renameEmbed(interaction.user,prefix+newname)]})
log("command","someone used the 'rename' command",[{key:"user",value:interaction.user.tag}])
log("system","ticket renamed",[{key:"user",value:interaction.user.tag},{key:"ticket",value:name},{key:"newname",value:newname}])
APIEvents.onCommand("rename",permsChecker.command(interaction.user.id,interaction.guild.id),interaction.user,interaction.channel,interaction.guild,new Date())
})
})
}
-60
View File
@@ -1,60 +0,0 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events")
const DISABLE = require("../core/api/api.json").disable
module.exports = () => {
bot.errorLog.log("debug","COMMANDS: loaded reopen.js")
if (!DISABLE.commands.text.reopen) client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix+"reopen")) return
msg.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
if (hiddendata.data.find(h => h.key == "pendingdelete")) return msg.channel.send({embeds:[bot.errorLog.warning("Warning!","You can't re-open a ticket while it's being deleted!")]})
msg.channel.send({embeds:[bot.embeds.commands.reopenEmbed(msg.author)],components:[bot.buttons.close.openRowNormal]})
require("../core/ticketActions/ticketReopener").reopenTicket(msg.guild,msg.channel,msg.author)
log("command","someone used the 'reopen' command",[{key:"user",value:msg.author.tag}])
APIEvents.onCommand("reopen",true,msg.author,msg.channel,msg.guild,new Date())
})
})
if (!DISABLE.commands.slash.reopen) client.on("interactionCreate",async (interaction) => {
if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "reopen") return
//interaction.deferReply()
interaction.channel.messages.fetchPinned().then(async msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
if (hiddendata.data.find(h => h.key == "pendingdelete")) return interaction.reply({embeds:[bot.errorLog.warning("Warning!","You can't re-open a ticket while it's being deleted!")]})
await interaction.reply({embeds:[bot.embeds.commands.reopenEmbed(interaction.user)],components:[bot.buttons.close.openRowNormal]})
require("../core/ticketActions/ticketReopener").reopenTicket(interaction.guild,interaction.channel,interaction.user)
log("command","someone used the 'reopen' command",[{key:"user",value:interaction.user.tag}])
APIEvents.onCommand("reopen",true,interaction.user,interaction.channel,interaction.guild,new Date())
})
})
}
-70
View File
@@ -1,70 +0,0 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events")
const DISABLE = require("../core/api/api.json").disable
module.exports = () => {
bot.errorLog.log("debug","COMMANDS: loaded ticket.js")
/**@type {String[]} */
var msgIds = []
config.messages.forEach((msg) => {
msgIds.push(msg.id)
})
if (!DISABLE.commands.text.msg) client.on("messageCreate", msg => {
if (msg.content.startsWith(config.prefix+"msg"||config.prefix+"message")){
if (!msg.guild) return
if (!permsChecker.command(msg.author.id,msg.guild.id)){
permsChecker.sendUserNoPerms(msg.author)
return
}
const id = msg.content.split(config.prefix+"msg")[1].substring(1) ? msg.content.split(config.prefix+"msg")[1].substring(1) : false
if (!id) return msg.channel.send({embeds:[bot.errorLog.invalidArgsMessage(l.errors.missingArgsDescription+" `<id>`:\n`"+config.prefix+"msg <id>`")]})
if (!msgIds.includes(id)) return msg.channel.send({embeds:[bot.errorLog.invalidIdChooseFromList(msgIds)]})
const {embed,componentRows} = require("../core/utils/getEmbed").createEmbed(id)
msg.channel.send({embeds:[embed],components:componentRows})
log("command","someone used the 'message' command",[{key:"user",value:msg.author.tag},{key:"id",value:id}])
APIEvents.onCommand("message",permsChecker.command(msg.author.id,msg.guild.id),msg.author,msg.channel,msg.guild,new Date())
}
})
if (!DISABLE.commands.slash.msg) client.on("interactionCreate", (interaction) => {
if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "message") return
if (!interaction.guild) return
if (!permsChecker.command(interaction.user.id,interaction.guild.id)){
permsChecker.sendUserNoPerms(interaction.user)
return
}
const id = interaction.options.getString("id")
if (!msgIds.includes(id)) return interaction.reply({embeds:[bot.errorLog.invalidIdChooseFromList(msgIds)]})
const {embed,componentRows} = require("../core/utils/getEmbed").createEmbed(id)
interaction.reply({content:l.commands.ticketWarning})
interaction.channel.send({embeds:[embed],components:componentRows})
log("command","someone used the 'message' command",[{key:"user",value:interaction.user.tag},{key:"id",value:id}])
APIEvents.onCommand("message",permsChecker.command(interaction.user.id,interaction.guild.id),interaction.user,interaction.channel,interaction.guild,new Date())
})
}
-77
View File
@@ -1,77 +0,0 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events")
const DISABLE = require("../core/api/api.json").disable
module.exports = () => {
bot.errorLog.log("debug","COMMANDS: loaded unclaim.js")
if (!DISABLE.commands.text.unclaim) client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix+"unclaim")) return
if (!msg.guild) return
if (!permsChecker.command(msg.author.id,msg.guild.id)){
permsChecker.sendUserNoPerms(msg.author)
return
}
msg.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
//msg.channel.send({embeds:[bot.embeds.commands.unclaimEmbed(msg.author)]})
msg.channel.send({embeds:[bot.errorLog.warning("Coming soon!","This feature isn't ready yet!\nIt will become active in the next update!")]})
var loguser = msg.author
log("command","someone used the 'unclaim' command",[{key:"user",value:msg.author.tag}])
log("system","user unclaimed from ticket",[{key:"user",value:msg.author.tag},{key:"ticket",value:msg.channel.name},{key:"unclaimed_user",value:msg.author.tag}])
const ticketData = require("../core/utils/configParser").getTicketById(ticketId,true)
//APIEvents.onTicketAdd(msg.author,loguser,msg.channel,msg.guild,new Date(),{status:"open",name:msg.channel.name,ticketOptions:ticketData})
//APIEvents.onCommand("add",permsChecker.command(msg.author.id,msg.guild.id),msg.author,msg.channel,msg.guild,new Date())
})
})
if (!DISABLE.commands.slash.unclaim) client.on("interactionCreate",(interaction) => {
if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "unclaim") return
const user = interaction.user
if (!interaction.guild) return
if (!permsChecker.command(interaction.user.id,interaction.guild.id)){
permsChecker.sendUserNoPerms(interaction.user)
return
}
interaction.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
//interaction.reply({embeds:[bot.embeds.commands.unclaimEmbed(interaction.user)]})
interaction.reply({embeds:[bot.errorLog.warning("Coming soon!","This feature isn't ready yet!\nIt will become active in the next update!")]})
var loguser = user
log("command","someone used the 'unclaim' command",[{key:"user",value:interaction.user.tag}])
log("system","user unclaimed from ticket",[{key:"user",value:interaction.user.tag},{key:"ticket",value:interaction.channel.name},{key:"unclaimed_user",value:loguser.tag}])
const ticketData = require("../core/utils/configParser").getTicketById(ticketId,true)
//APIEvents.onTicketAdd(interaction.user,loguser,interaction.channel,interaction.guild,new Date(),{status:"open",name:interaction.channel.name,ticketOptions:ticketData})
//APIEvents.onCommand("add",permsChecker.command(interaction.user.id,interaction.guild.id),interaction.user,interaction.channel,interaction.guild,new Date())
})
})
}
-108
View File
@@ -1,108 +0,0 @@
{
"main_color":"#ffffff",
"server_id":"server id (for slash cmds)",
"auth_token":"auth token",
"main_adminroles":["discord role id"],
"prefix":"!ticket ",
"languagefile":"english",
"credits":true,
"status":{
"enabled":true,
"type":"PLAYING",
"text":"!ticket help"
},
"system":{
"ticket_channel":"channel id",
"max_allowed_tickets":3,
"enable_DM_Messages":true,
"has@everyoneaccess":false,
"member_role":"member role (doesn't have access to tickets)",
"closeMode":"adminonly|normal",
"enable_transcript":false,
"enable_DM_transcript":false,
"transcript_channel":"channel id",
"showSlashcmdsInHelp":false
},
"options":[
{
"id":"general",
"name":"Question",
"description":"Create this ticket if you have a question.",
"icon":"🎫",
"label":"question",
"type":"ticket",
"color":"gray",
"adminroles":["role id"],
"channelprefix":"question-",
"category":"category id",
"message":"You created a ticket!",
"enableDmOnOpen":true,
"ticketmessage":"The staff will help you soon!\n\n*Click on the button below to close the ticket!*",
"thumbnail":{
"enable":false,
"url":"https://www.example.com/catmemes/cat.png"
},
"closedCategory":{
"enable":false,
"id":"category id"
}
},
{
"id":"website",
"name":"Website",
"description":"Go to our website.",
"icon":"✅",
"label":"click here",
"type":"website",
"url":"https://www.dj-dj.be"
},
{
"id":"role",
"name":"Verify",
"description":"Click here to get the verify role.",
"icon":"👮🏼",
"label":"get a role",
"type":"role",
"color":"red",
"roles":["discord role id"],
"mode":"add&remove|remove|add",
"enableDmOnOpen":true
}
],
"messages":[
{
"id":"1",
"name":"Choose Your Ticket",
"description":"You can click one of the buttons below!",
"dropdown":false,
"enableFooter":false,
"footer":"Open Ticket v3.0.0 - I'm a footer!",
"enableThumbnail":false,
"thumbnail":"https://www.example.com/catmemes/cat.png",
"enableCustomColor":false,
"color":"#ffffff",
"options":["general","apply"],
"enableTicketExplaination":true,
"enableMaxTicketsWarning":true
}
]
}
+175
View File
@@ -0,0 +1,175 @@
/*
* Hi there! Thank you for installing Open Ticket.
* ----------------------------------------------
* If you need any assistance with configuring the bot,
* feel free to use the documentation or join our Discord server:
* https://otdocs.dj-dj.be
* https://discord.dj-dj.be
* ----------------------------------------------
* SETUP:
* 1. Install the required dependencies using the command: "npm install"
* 2. Configure the bot in one of the following ways:
* a. (easy) Using the Quick Setup CLI Tool
* b. (difficult) Using the JSON files in `./config/`
*
* Start the Quick Setup CLI Tool using the command: "npm run setup"
* After configuration, start the bot using the command: "npm start"
*
* Good luck! DJj123dj & contributors
*/
{
"_CONFIG_VERSION":"open-ticket-v4.2.1",
/* Load the bot token from .env or the "token" field below. Leave "token" empty if using "tokenFromENV". */
"token":"INSERT_BOT_TOKEN",
"tokenFromENV":false,
"mainColor":"#f8ba00", //Hex color used in most embeds
"language":"english", //Visit README.md for list
"prefix":"!ticket ", //Prefix used in text commands
"serverId":"DISCORD_SERVER_ID",
"globalAdmins":["DISCORD_ROLE_ID"], //Have access to all commands
/* Enable/disable text or slash commands. */
"slashCommands":true,
"textCommands":true,
/* Configure the status of the bot. */
"status":{
"enabled":true,
"type":"listening", //Choices: listening, watching, playing, custom
"mode":"online", //Choices: online, invisible, idle, dnd
"text":"/help",
"state":"" //Additional text (Leave empty to disable)
},
/* Send ticket logs to a channel or in DM of the ticket creator. */
"logs":{
"enabled":false,
"channel":"DISCORD_CHANNEL_ID",
"logMessages":{
"creation":{"dm":false,"logs":true},
"closing":{"dm":false,"logs":true},
"deleting":{"dm":false,"logs":true},
"reopening":{"dm":false,"logs":true},
"claiming":{"dm":false,"logs":true},
"pinning":{"dm":false,"logs":true},
"adding":{"dm":false,"logs":true},
"removing":{"dm":false,"logs":true},
"renaming":{"dm":false,"logs":true},
"moving":{"dm":false,"logs":true},
"blacklisting":{"dm":false,"logs":true},
"transferring":{"dm":false,"logs":true},
"topicChange":{"dm":false,"logs":true},
"priorityChange":{"dm":false,"logs":true},
"reactionRole":{"dm":false,"logs":true}
}
},
/* A large collection of settings for the ticket system. */
"ticketSystem":{
"preferSlashOverText":true, //Show slashcmds in help menu's
"sendErrorOnUnknownCommand":true, //Send error when command not found
"questionFieldsInCodeBlock":true, //Put question answers in code blocks
"displayFieldsWithQuestions":false, //Display embed fields together with question answers
"showGlobalAdminsInPanelRoles":false, //Include "globalAdmins" in panel admin lists
"disableVerifyBars":false, //Disable the (❌/✅) buttons
"useRedErrorEmbeds":true, //Make errors embeds always red
"alwaysShowReason":false, //Show reason even if none is provided
"emojiStyle":"before", //The style of emoji's in embeds. Choices: before, after, double, disabled
"pinEmoji":"📌", //Channel emoji of pinned tickets (Leave empty to disable)
"closeEmoji":"", //Channel emoji of closed tickets (Leave empty to disable)
"replyOnTicketCreation":true, //Reply with a msg when a ticket is created
"replyOnReactionRole":true, //Reply with a msg when a reaction role is used
"askPriorityOnTicketCreation":true, //Show a dropdown to select priority
"removeParticipantsOnClose":false, //Remove non-admins when ticket is closed
"disableAutocloseAfterReopen":true, //Disable autoclose after ticket got reopened
"autodeleteRequiresClosedTicket":true, //A ticket must be closed before autodelete works
"adminOnlyDeleteWithoutTranscript":true, //Only allow "globalAdmins" to delete a ticket without transcript
"allowCloseBeforeMessage":false, //Allow closing before a message is sent
"allowCloseBeforeAdminMessage":true, //Allow closing before an admin has sent a message
"useTranslatedConfigChecker":true, //Translate config errors in the console
"pinFirstTicketMessage":true, //Pin the ticket message to the channel
/* Enable/disable certain buttons & features of the bot. */
"enableTicketClaimButtons":true,
"enableTicketCloseButtons":true,
"enableTicketPinButtons":true,
"enableTicketDeleteButtons":true,
"enableTicketActionWithReason":true,
"enableDeleteWithoutTranscript":true, //Allow deleting tickets without transcript
"enableCreateTicketForOtherUser":true, //Allow creating tickets for other users
/* Set the maximum amount of simultaneous tickets. */
"limits":{
"enabled":true,
"globalMaximum":50,
"userMaximum":3
},
/* Choose which data is shown in the channel topic. */
"channelTopic":{
"showOptionName":true,
"showOptionDescription":false,
"showOptionTopic":true,
"showPriority":false,
"showClosed":true,
"showClaimed":false,
"showPinned":false,
"showCreator":false,
"showParticipants":false
},
/* Move closed tickets to a separate category. */
"closedCategory":{
"enabled":false,
"categoryId":"DISCORD_CATEGORY_ID"
},
/* Create tickets in a backup category when the original category exceeds 50 channels. */
"backupCategory":{
"enabled":false,
"categoryId":"DISCORD_CATEGORY_ID"
},
/* Move claimed tickets to a matching category of the user that claimed the ticket. Set to empty list [] to disable. */
"claimedCategories":[
{"user":"DISCORD_USER_ID","category":"DISCORD_CATEGORY_ID"}
]
},
/*
* Set permissions for each individual command, button or action.
* CHOICES:
* >> "none" -> Command disabled
* >> "everyone" -> Allowed for everyone
* >> "admin" -> Global & ticket admins only
* >> "DISCORD_ROLE_ID" -> Custom role only
*/
"permissions":{
"help":"everyone",
"panel":"admin",
"ticket":"none",
"close":"everyone",
"delete":"admin",
"reopen":"everyone",
"claim":"admin",
"unclaim":"admin",
"pin":"admin",
"unpin":"admin",
"move":"admin",
"rename":"admin",
"add":"admin",
"remove":"admin",
"blacklist":"admin",
"stats":"everyone",
"clear":"admin",
"autoclose":"admin",
"autodelete":"admin",
"transfer":"admin",
"topic":"admin",
"priority":"admin",
"transcripts":"admin"
}
}
+165
View File
@@ -0,0 +1,165 @@
/*
* OPEN TICKET BUTTON OPTIONS
* ----------------------------------------------
* Create customizable ticket, website, reaction-role or sub-panel button options.
* Up to 25 options can be added to each panel in (config/panels.jsonc)
* There are 4 types of options available: ticket, website, role, sub-panel
*
* TIP: Create new options by copying everything between and including the {...} brackets of an option. Paste it after the last option and make sure that they are seperated by a comma.
*/
[
{
/* A ticket option creates a button to open a ticket. */
"id":"example-ticket",
"name":"Question",
"description":"Want to tell us something? Create this ticket for general questions for our support team.", //Leave empty to disable
"type":"ticket",
"button":{
/* Configure the button style of this option. At least one of "emoji" or "label" must be provided. */
"emoji":"🎫",
"label":"Question",
"color":"gray" //Choices: gray, red, green, blue
},
/* Add up to 5 modal questions IDs from (config/questions.jsonc). */
"questions":["example-question-1","example-question-2"],
"ticketAdmins":["DISCORD_ROLE_ID"],
"readonlyAdmins":["DISCORD_ROLE_ID"],
"allowCreationByBlacklistedUsers":false,
"channel":{
/* Configure the name, topic and category of the ticket option. */
"prefix":"question-",
"suffix":"user-name", //Choices: user-name, user-id, random-number, random-hex, counter-dynamic, counter-fixed
"category":"DISCORD_CATEGORY_ID", //Leave empty to disable
"topic":"The ticket topic shown in the channel." //Leave empty to disable
},
"dmMessage":{
/* Send a customisable message in DM when creating a ticket. */
"enabled":false,
"text":"", //Leave empty to disable
"embed":{
"enabled":false,
"title":"Question Ticket", //Leave empty to disable
"description":"Thank you for creating a ticket in our server. We will try to help you as soon as possible.", //Leave empty to disable
"customColor":"#f8ab00", //Leave empty to use default color
"image":"", //Image URL. Leave empty to disable
"thumbnail":"", //Image URL. Leave empty to disable
/* Embed fields. Set to empty list [] to disable. */
"fields":[
{"name":"FIELD_NAME","value":"FIELD_VALUE","inline":false}
],
"timestamp":false
}
},
"ticketMessage":{
/* Send a customisable message in the ticket with close, claim, delete, ... buttons. */
"enabled":true,
"text":"", //Leave empty to disable
"embed":{
"enabled":true,
"title":"Question Ticket", //Leave empty to disable
"description":"Thank you for creating a ticket in our server.\nOur support team will assist you as soon as possible.", //Leave empty to disable
"customColor":"#f8ab00", //Leave empty to use default color
"image":"", //Image URL. Leave empty to disable
"thumbnail":"", //Image URL. Leave empty to disable
/* Embed fields. Set to empty list [] to disable. */
"fields":[
{"name":"FIELD_NAME","value":"FIELD_VALUE","inline":false}
],
"timestamp":false
},
"ping":{
/* Customise the user & role mentions of this ticket message. */
"@here":true,
"@everyone":false,
"custom":["DISCORD_ROLE_ID"]
}
},
"autoclose":{
/* Autoclose this ticket after a period of inactivity or when the creator leaves the server. */
"enableInactiveHours":false,
"inactiveHours":24,
"enableUserLeave":false,
"disableOnClaim":false
},
"autodelete":{
/* Autodelete this ticket after a period of inactivity or when the creator leaves the server. */
"enableInactiveDays":false,
"inactiveDays":7,
"enableUserLeave":false,
"disableOnClaim":false
},
"cooldown":{
/* Users must wait a certain period before being able to create another ticket of this type. */
"enabled":false,
"cooldownMinutes":10
},
"limits":{
/* Set the maximum amount of simultaneous tickets of this option. */
"enabled":false,
"globalMaximum":20,
"userMaximum":3
},
"slowMode":{
/* Enable slow-mode in the ticket channel. */
"enabled":false,
"slowModeSeconds":20
}
},
{
/* A website option creates a button with a URL to an external website. */
"id":"example-website",
"name":"Website",
"description":"Take a look at our amazing website.", //Leave empty to disable
"type":"website",
"button":{
/* Configure the button style of this option. At least one of "emoji" or "label" must be provided. */
"emoji":"😃",
"label":"Visit Website"
},
"url":"https://www.dj-dj.be"
},
{
/* A reaction-role option creates a button for members to choose roles. */
"id":"example-role",
"name":"Update Ping",
"description":"Receive notifications about updates in our server.", //Leave empty to disable
"type":"role",
"button":{
/* Configure the button style of this option. At least one of "emoji" or "label" must be provided. */
"emoji":"📢",
"label":"Update Ping",
"color":"gray" //Choices: gray, red, green, blue
},
"roles":["DISCORD_ROLE_ID"],
"mode":"add&remove OR remove OR add", //What to do with the roles. Choices: add&remove, add, remove
"removeRolesOnAdd":["DISCORD_ROLE_ID"], //Remove these old roles when new roles are added.
"addOnMemberJoin":false //Add these roles automatically when joining the server.
},
{
/* A sub-panel option creates a button which sends another panel for additional options. */
"id":"example-sub-panel",
"name":"Example Sub-Panel",
"description":"This is an example of how to implement a sub-panel in Open Ticket.", //Leave empty to disable
"type":"sub-panel",
"button":{
/* Configure the button style of this option. At least one of "emoji" or "label" must be provided. */
"emoji":"📋",
"label":"Sub-Panel Example",
"color":"gray" //Choices: gray, red, green, blue
},
"subPanelId":"example-panel" //Choose a panel ID from (config/panels.jsonc)
}
]
+57
View File
@@ -0,0 +1,57 @@
/*
* OPEN TICKET PANELS
* ----------------------------------------------
* Create customizable panel messages with buttons or a dropdown.
* Add up to 25 options to this panel from (config/options.jsonc)
* Panels can be customised with text, images, colors and more.
*
* Spawn the panel in Discord using: /panel <id>
*
* TIP: Create new panels by copying everything between and including the {...} brackets of an panel. Paste it after the last panel and make sure that they are seperated by a comma.
*/
[
{
/* A panel is creates a message with up to 25 options as buttons or dropdown. */
"id":"example-panel",
"name":"Example Panel",
"dropdown":false,
/* Add up to 5 option IDs from (config/options.jsonc). */
"options":["example-ticket","example-website","example-role"],
"text":"", //Leave empty to disable
"embed":{
"enabled":true,
"title":"Tickets:", //Leave empty to disable
"description":"Create a ticket by selecting one of the options below. Once selected, a private ticket will be created for you and our support team will be able to assist you directly.", //Leave empty to disable
"customColor":"#f8ab00", //Leave empty to use default color
"url":"", //URL. Leave empty to disable
"image":"", //Image URL. Leave empty to disable
"thumbnail":"", //Image URL. Leave empty to disable
"footer":"Open Ticket v4.2.1", //Leave empty to disable
/* Embed fields. Set to empty list [] to disable. */
"fields":[
{"name":"Field name","value":"Field value","inline":false}
],
"timestamp":false
},
"settings":{
"dropdownPlaceholder":"Create a ticket...", //Leave empty to use default.
"maximumButtonsPerRow":5,
/* Display the maximum amount of tickets per user. */
"enableMaxTicketsWarningInText":false,
"enableMaxTicketsWarningInEmbed":true,
/* Automatically generate option descriptions from (config/options.jsonc). */
"describeOptionsLayout":"normal", //Choices: simple, normal, detailed
"describeOptionsCustomTitle":"",
"describeOptionsInText":false,
"describeOptionsInEmbedFields":true,
"describeOptionsInEmbedDescription":false
}
}
]
+102
View File
@@ -0,0 +1,102 @@
/*
* OPEN TICKET MODAL QUESTIONS
* ----------------------------------------------
* Create customizable modal questions that will be shown before creating a ticket.
* Each ticket option (config/options.jsonc) can contain a maximum of 5 questions.
* There are 6 types of questions available: short, paragraph, dropdown, radio-select, checkbox-select, text-display
*
* TIP: Create new questions by copying everything between and including the {...} brackets of a question. Paste it after the last question and make sure that they are seperated by a comma.
*/
[
{
/* A short text input modal question. */
"id":"example-question-1",
"name":"Example Question 1",
"description":"", //Leave empty to disable
"type":"short",
"required":true,
"placeholder":"Insert answer...",
"length":{
/* Configure length limits for the answer. */
"enabled":false,
"min":0,
"max":1000
}
},
{
/* A paragraph text input modal question. */
"id":"example-question-2",
"name":"Example Question 2",
"description":"", //Leave empty to disable
"type":"paragraph",
"required":false,
"placeholder":"Insert answer...",
"length":{
/* Configure length limits for the answer. */
"enabled":false,
"min":0,
"max":1000
}
},
{
/* A dropdown menu input modal question with up to 25 choices. "emoji" & "description" fields are optional. */
"id":"example-question-3",
"name":"Example Question 3",
"description":"This is a dropdown question.", //Leave empty to disable
"type":"dropdown",
"required":false,
"placeholder":"Choose your answer...",
"choices":[
{"title":"Choice A","description":"Apple","emoji":"🍎"},
{"title":"Choice B","description":"Banana","emoji":"🍌"},
{"title":"Choice C","description":"Orange","emoji":"🍊"},
{"title":"Choice D","description":"Kiwi","emoji":"🥝"}
]
},
{
/* A radio select input modal question with up to 10 choices. */
"id":"example-question-4",
"name":"Example Question 4",
"description":"This is a radio select question.", //Leave empty to disable
"type":"radio-select",
"required":true,
"choices":[
{"title":"Choice A","description":"Up","selectedByDefault":false},
{"title":"Choice B","description":"Down","selectedByDefault":false},
{"title":"Choice C","description":"Left","selectedByDefault":false},
{"title":"Choice D","description":"Right","selectedByDefault":false}
]
},
{
/* A checkbox select input modal question with up to 10 choices. */
"id":"example-question-5",
"name":"Example Question 5",
"description":"This is a checkbox select question.", //Leave empty to disable
"type":"checkbox-select",
"required":true,
"limits":{
/* Configure checkbox amount limits for the answer. */
"enabled":false,
"min":0,
"max":10
},
"choices":[
{"title":"Choice A","description":"Happiness","selectedByDefault":false},
{"title":"Choice B","description":"Anger","selectedByDefault":false},
{"title":"Choice C","description":"Sadness","selectedByDefault":false},
{"title":"Choice D","description":"Fear","selectedByDefault":false}
]
},
{
/* Show text in a modal to provide extra details or explain questions. */
"id":"example-text-display",
"type":"text-display",
"textContents":"This is a text display. It isn't a question, but allows you to display additional details."
}
]
+70
View File
@@ -0,0 +1,70 @@
/*
* OPEN TICKET TRANSCRIPTS
* ----------------------------------------------
* Enable transcript creation when tickets are deleted. There are 2 available transcript types: HTML & Text
*
* HTML Transcripts (recommended):
* Generate transcripts as HTML files to view in the browser. No server or domain required. HTML Transcripts use an external service to process and host the transcripts.
*
* Text Transcripts:
* Generate transcripts as simple .txt files with limited details. Processing happens fully local.
*/
{
"general":{
"enabled":false,
/* Choose which users and channel get the generated transcript. */
"enableChannel":false,
"enableCreatorDM":false,
"enableParticipantDM":false,
"enableActiveAdminDM":false,
"enableEveryAdminDM":false,
"channel":"DISCORD_CHANNEL_ID", //Where to send transcripts. Leave empty when disabled.
"mode":"html" //The type of transcript to use. Choices: html, text
},
"embedSettings":{
/* Customise the embed which contains the generated transcript file or URL. */
"customColor":"#f8ab00", //Leave empty to use default color
"listAllParticipants":false,
"includeTicketStats":false
},
"textTranscriptStyle":{
/* Customise layout of the text transcripts. */
"layout":"normal", //Choices: simple, normal, detailed
"includeStats":true,
"includeIds":false,
"includeEmbeds":true,
"includeFiles":true,
"includeBotMessages":true,
"fileMode":"custom", //How to name the transcript file? Choices: custom, channel-name, channel-id, user-name, user-id
"customFileName":"transcript" //Custom filename without extension
},
"htmlTranscriptStyle":{
/* Customise layout of the HTML transcripts. */
"background":{
"enableCustomBackground":false,
"backgroundColor":"#f8ba00", //Leave empty to use Open Ticket color (#f8ba00)
"backgroundImage":"https://www.example.com/image.png" //Image URL to fill entire background. Leave empty to disable
},
"header":{
"enableCustomHeader":false,
"backgroundColor":"#202225",
"decoColor":"#f8ba00",
"textColor":"#ffffff"
},
"stats":{
"enableCustomStats":false,
"backgroundColor":"#202225",
"keyTextColor":"#737373",
"valueTextColor":"#ffffff",
"hideBackgroundColor":"#40444a",
"hideTextColor":"#ffffff"
},
"favicon":{
"enableCustomFavicon":false,
"imageUrl":"https://t.dj-dj.be/favicon.png"
}
}
}
-18
View File
@@ -1,18 +0,0 @@
//base
const bot = require("../../index")
exports.client = bot.client
exports.config = bot.config
exports.utils = {
log:bot.errorLog.log(),
storage:bot.storage
}
//events
const events = require("./modules/events").events
exports.events = events
//actions
const actions = require("./modules/actions").actions
//comming soon
//exports.actions = actions
-57
View File
@@ -1,57 +0,0 @@
{
"version":"1.0.0",
"enableAPIdebug":false,
"enableAPIconsolelogs":false,
"info":"If you turn these switches to true, then the feature will be turned OFF!",
"info2":"You can use this to disable some features you don't want!",
"disable":{
"messages":{
"DISCLAIMER":"the messages part doesn't work yet!",
"ticketCreated":false,
"ticketClosed":false,
"ticketDeleted":false,
"ticketReopened":false
},
"transcripts":{
"server":false,
"dm":false
},
"commands":{
"text":{
"help":false,
"msg":false,
"close":false,
"delete":false,
"reopen":false,
"new":false,
"add":false,
"remove":false,
"rename":false,
"claim":false,
"unclaim":false
},
"slash":{
"help":false,
"msg":false,
"close":false,
"delete":false,
"reopen":false,
"new":false,
"add":false,
"remove":false,
"rename":false,
"claim":false,
"unclaim":false
}
},
"checkerjs":{
"token":false,
"all":false
},
"debug":{
"all":false,
"debuglogs":false
}
}
}
-7
View File
@@ -1,7 +0,0 @@
//ACTIONS:
//EXPORT ACTIONS:
exports.actions = {
}
-8
View File
@@ -1,8 +0,0 @@
/** FOR DEVELOPERS ONLY!!
* Don't change anything in this file before reading the documentation!
* visit the api documentation at https://docs.openticket.dj-dj.be
*/
exports.embeddedMode = false
exports.clientLocation = require("../../../index").client
-361
View File
@@ -1,361 +0,0 @@
const discord = require('discord.js')
const bot = require('../../../index')
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const l = bot.language
const storage = bot.storage
//EVENT API:
const ticketOpenListeners = []
const ticketCloseListeners = []
const ticketDeleteListeners = []
const ticketReopenListeners = []
const ticketAddListeners = []
const ticketRemoveListeners = []
const transcriptCreationListeners = []
const commandListeners = []
const reactionRoleListeners = []
const errorListeners = []
/**
*
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata
*/
exports.onTicketOpen = (user,channel,guild,date,ticketdata) => {
//system
bot.errorLog.log("api","new ticket created",[{key:"userid",value:user.id},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id},{key:"ticketdata",value:JSON.stringify(ticketdata)}])
ticketOpenListeners.forEach((func) => {
try {
func(user,channel,guild,date,ticketdata)
}catch{}
})
}
/**
*
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata
* @param {String} reason
*/
exports.onTicketClose = (user,channel,guild,date,ticketdata,reason) => {
//system
bot.errorLog.log("api","ticket closed",[{key:"userid",value:user.id},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id},{key:"ticketdata",value:JSON.stringify(ticketdata)},{key:"reason",value:reason}])
ticketCloseListeners.forEach((func) => {
try {
func(user,channel,guild,date,ticketdata,reason)
}catch{}
})
}
/**
*
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata
*/
exports.onTicketDelete = (user,channel,guild,date,ticketdata) => {
//system
bot.errorLog.log("api","ticket deleted",[{key:"userid",value:user.id},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id},{key:"ticketdata",value:JSON.stringify(ticketdata)}])
ticketDeleteListeners.forEach((func) => {
try {
func(user,channel,guild,date,ticketdata)
}catch{}
})
}
/**
*
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata
*/
exports.onTicketReopen = (user,channel,guild,date,ticketdata) => {
//system
bot.errorLog.log("api","ticket reopened",[{key:"userid",value:user.id},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id},{key:"ticketdata",value:JSON.stringify(ticketdata)}])
ticketReopenListeners.forEach((func) => {
try {
func(user,channel,guild,date,ticketdata)
}catch{}
})
}
/**
*
* @param {discord.User} user
* @param {discord.User} editeduser
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata
*/
exports.onTicketAdd = (user,editeduser,channel,guild,date,ticketdata) => {
//system
bot.errorLog.log("api","user added to ticket",[{key:"userid",value:user.id},{key:"editeduser",value:editeduser.id},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id},{key:"ticketdata",value:JSON.stringify(ticketdata)}])
ticketAddListeners.forEach((func) => {
try {
func(user,editeduser,channel,guild,date,ticketdata)
}catch{}
})
}
/**
*
* @param {discord.User} user
* @param {discord.User} editeduser
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata
*/
exports.onTicketRemove = (user,editeduser,channel,guild,date,ticketdata) => {
//system
bot.errorLog.log("api","user removed from ticket",[{key:"userid",value:user.id},{key:"editeduser",value:editeduser.id},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id},{key:"ticketdata",value:JSON.stringify(ticketdata)}])
ticketRemoveListeners.forEach((func) => {
try {
func(user,editeduser,channel,guild,date,ticketdata)
}catch{}
})
}
/**
*
* @param {discord.Message[]} messages
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
*/
exports.onTranscriptCreation = (messages,channel,guild,date) => {
//system
bot.errorLog.log("api","transcript created",[{key:"messages",value:JSON.stringify(messages)},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id}])
transcriptCreationListeners.forEach((func) => {
try {
func(messages,channel,guild,date)
}catch{}
})
}
/**@typedef {"help"|"message"|"close"|"delete"|"reopen"|"rename"|"add"|"remove"} OTCommandType */
/**
*
* @param {OTCommandType} type
* @param {Boolean} hasPerms
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
*/
exports.onCommand = (type,hasPerms,user,channel,guild,date) => {
const newguild = guild ? guild : false
//system
bot.errorLog.log("api","someone used a command",[{key:"type",value:type},{key:"hasPerms",value:hasPerms},{key:"userid",value:user},{key:"channelid",value:channel.id},{key:"guildid",value:newguild.id}])
commandListeners.forEach((func) => {
try {
func(type,hasPerms,user,channel,newguild,date)
}catch{}
})
}
/**@typedef {"add"|"remove"|"add&remove"} OTReactionRoleType */
/**@typedef {"add"|"remove"} OTReactionRoleMode */
/**
* @param {OTReactionRoleMode} mode
* @param {OTReactionRoleType} type
* @param {discord.Role} role
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
*/
exports.onReactionRole = (mode,type,role,user,channel,guild,date) => {
//system
bot.errorLog.log("api","someone used a reaction role",[{key:"mode",value:mode},{key:"type",value:type},{key:"roleid",value:role.id},{key:"userid",value:user},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id}])
reactionRoleListeners.forEach((func) => {
try {
func(mode,type,role,user,channel,guild,date)
}catch{}
})
}
/**
* @param {String} err
* @param {Date} date
*/
exports.onError = (err,date) => {
//system
bot.errorLog.log("api","there is an error",[{key:"error",value:err}])
errorListeners.forEach((func) => {
try {
func(err,date)
}catch{}
})
}
//EVENT CALLBACKS:
/**
* @callback TicketActionEvent
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata
*/
/**
* @callback TicketCloseEvent
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata
* @param {String} reason
*/
/**
* @callback TranscriptCreationEvent
* @param {discord.Message[]} messages
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
*/
/**
* @callback TicketUserChangeEvent
* @param {discord.User} user
* @param {discord.User} editeduser
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata
*/
/**
* @callback CommandEvent
* @param {OTCommandType} type
* @param {Boolean} hasPerms
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild|false} guild
* @param {Date} date
*/
/**
* @callback ReactionRoleEvent
* @param {OTReactionRoleMode} mode
* @param {OTReactionRoleType} type
* @param {discord.Role} role
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
*/
/**
* @callback ErrorEvent
* @param {String} error
* @param {Date} date
*/
//EVENT EXPORT:
/**@param {TicketActionEvent} callback */
const onTicketOpen = (callback) => {
ticketOpenListeners.push(callback)
}
/**@param {TicketCloseEvent} callback */
const onTicketClose = (callback) => {
ticketCloseListeners.push(callback)
}
/**@param {TicketActionEvent} callback */
const onTicketDelete = (callback) => {
ticketDeleteListeners.push(callback)
}
/**@param {TicketActionEvent} callback */
const onTicketReopen = (callback) => {
ticketReopenListeners.push(callback)
}
/**@param {TicketUserChangeEvent} callback */
const onTicketAdd = (callback) => {
ticketAddListeners.push(callback)
}
/**@param {TicketUserChangeEvent} callback */
const onTicketRemove = (callback) => {
ticketRemoveListeners.push(callback)
}
/**@param {TranscriptCreationEvent} callback */
const onTranscriptCreation = (callback) => {
transcriptCreationListeners.push(callback)
}
/**@param {CommandEvent} callback */
const onCommand = (callback) => {
commandListeners.push(callback)
}
/**@param {ReactionRoleEvent} callback */
const onReactionRole = (callback) => {
commandListeners.push(callback)
}
/**@param {ErrorEvent} callback */
const onError = (callback) => {
errorListeners.push(callback)
}
exports.events = {
onTicketOpen,
onTicketClose,
onTicketDelete,
onTicketReopen,
onTicketAdd,
onTicketRemove,
onTranscriptCreation,
onCommand,
onReactionRole,
onError
}
-33
View File
@@ -1,33 +0,0 @@
const fs = require("fs")
const bot = require("../../index")
const log = bot.errorLog.log
module.exports = () => {
const files = fs.readdirSync("./plugins")
const api = require("./api.json")
var totalcount = 0
var successcount = 0
var failcount = 0
files.forEach((file) => {
if (file.endsWith(".plugin.js")){
try {
require("../../plugins/"+file)()
successcount++
totalcount++
}catch(err){
/**@type {Error} */
const theError = err
if (api.enableAPIdebug){
const data = fs.readFileSync("./apiDebug.txt")
const newData = data ? data.toString() : ""
fs.writeFileSync("./apiDebug.txt",newData+"ERROR: "+theError.name+": "+theError.message+"\n"+theError.stack+"\n\n")
}
failcount++
totalcount++
}
}
})
log("info","loaded plugins",[{key:"success",value:successcount},{key:"error",value:failcount},{key:"total",value:totalcount}])
}
-463
View File
@@ -1,463 +0,0 @@
exports.checker = async () => {
const chalk = await (await import("chalk")).default
if (process.argv.some((v) => v == "--nochecker")) return
if (process.argv.some((v) => v == "--devconfig")){
//console.log(chalk.blue("=> used dev config instead of normal config"))
try{
var tempconfig = require("../devConfig.json")
}catch(err){console.log(err);var tempconfig = require("../config.json")}
}else{
var tempconfig = require("../config.json")
}
const config = tempconfig
var errorList = []
var isError = false
var warnList = []
var isWarn = false
const createError = (message) => {
isError = true
errorList.push("open-ticket CONFIG ERROR: "+message)
}
const createWarn = (message) => {
isWarn = true
warnList.push("open-ticket CONFIG WARNING: "+message)
}
//validators
/**@param {"userid"|"roleid"|"channelid"|"serverid"|"categoryid"} mode @param {String} value @param {String} path */
const checkDiscord = (mode,value,path) => {
if (mode == "userid"){
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+"' | this user id is invalid")
}
}else if (mode == "channelid"){
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+"' | this channel id is invalid")
}
}else if (mode == "roleid"){
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+"' | this role id is invalid")
}
}else if (mode == "serverid"){
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+"' | this server id is invalid")
}
}else if (mode == "categoryid"){
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+"' | this category id is invalid")
}
}
}
/**@param {String} value */
const checkToken = (value) => {
if (value.length < 40){
createError("'auth_token' | your token is invalid")
}
if (value.includes(" ")) createError("'auth_token' | your token includes spaces!")
}
/**@param {String} value @param {String} path */
const checkHexColor = (value,path) => {
if (!/^#[a-fA-F0-9]{3,6}$/.test(value)){
if (value.length < 4) return createError("'"+path+"' | hex color too short! (example: #123abc)")
if (value.length > 7) return createError("'"+path+"' | hex color too long! (example: #123abc)")
createError("'"+path+"' | invalid color! (example: #123abc)")
}
}
/**@param {String} value @param {String} path */
const checkEmbedColor = (value,path) => {
if (!['DEFAULT','WHITE','AQUA','GREEN','BLUE','YELLOW','PURPLE','LUMINOUS_VIVID_PINK','FUCHSIA','GOLD','ORANGE','RED','GREY','DARKER_GREY','NAVY','DARK_AQUA','DARK_GREEN','DARK_BLUE','DARK_PURPLE','DARK_VIVID_PINK','DARK_GOLD','DARK_ORANGE','DARK_RED','DARK_GREY','LIGHT_GREY','DARK_NAVY','BLURPLE','GREYPLE','DARK_BUT_NOT_BLACK','NOT_QUITE_BLACK','RANDOM'].includes(value)){
return createError("'"+path+"' | invalid color, must be a hex code or default color (more info in the wiki)")
}
}
/**@param {String} value @param {String} path @param {Number} minLength @param {Number} maxLength @param {String} name */
const checkString = (value,minLength,maxLength,path,name) => {
if (value.length < minLength){
createError("'"+path+"' | "+name+" is too short!")
}else if (value.length > maxLength){
createError("'"+path+"' | "+name+" is too long!")
}
}
/**@param {"userid"|"roleid"|"channelid"|"serverid"} mode @param {String[]} arrayValue @param {String} path */
const checkDiscordArray = (mode,arrayValue,path) => {
if (mode == "userid"){
arrayValue.forEach((value,index) => {
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+":"+index+"' | this user id is invalid")
}
})
}else if (mode == "channelid"){
arrayValue.forEach((value,index) => {
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+":"+index+"' | this channel id is invalid")
}
})
}else if (mode == "roleid"){
arrayValue.forEach((value,index) => {
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+":"+index+"' | this role id is invalid")
}
})
}else if (mode == "serverid"){
arrayValue.forEach((value,index) => {
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
createError("'"+path+":"+index+"' | this server id is invalid")
}
})
}
}
/**@param {String} value @param {"string"|"boolean"|"number"} type */
const checkType = (value,type,path) => {
if (type == "boolean"){
if (typeof value != "boolean"){
createError("'"+path+"' | invalid type, this must be a boolean!")
}
}else if (type == "number"){
if (typeof value != "number"){
createError("'"+path+"' | invalid type, this must be a number!")
}
}else if (type == "string"){
if (typeof value != "string"){
createError("'"+path+"' | invalid type, this must be a string!")
}
}
}
const checkButtonColor = (value,path) => {
if (value != "none" && value != "grey" && value != "gray" && value != "black" && value != "red" && value != "green" && value != "blue" && value != "blurple"){
createError("'"+path+"' | invalid color, it must be one of these: none, gray, red, green, blue!")
}
}
const configParser = require("./utils/configParser")
/**
* @param {configParser.OTAllOptions} option
* @param {String} path
*/
const checkOption = (option,path) => {
//id
checkType(option.id,"string",path+"/id")
if (option.id.includes(" ")){
createError("'"+path+"/id' | option id can't contain space characters!")
}
if (option.id.length > 20){
createError("'"+path+"/id' | option id max lenght is 20!")
}
//name
checkType(option.name,"string",path+"/name")
if (option.name.length > 100){
createWarn("'"+path+"/name' | if your name is too long it maybe doesn't look so good!")
}else if (option.name.length < 1){
createError("'"+path+"/name' | there is no name!")
}
//description
checkType(option.description,"string",path+"/description")
//icon
const emojiRegex = /(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])/gi;
if (option.icon.length > 0){
const isEmoji = emojiRegex.test(option.icon)
if (isEmoji == false){
createError("'"+path+"/icon' | invalid emoji or custom discord emoji")
}
}
checkType(option.icon,"string",path+"/icon")
//label
checkType(option.label,"string",path+"/label")
if (option.label.length < 1 && option.icon.length < 1){
createError("'"+path+"' | you need at least one of these: label, icon!")
}
//type
checkType(option.type,"string",path+"/type")
if (option.type != "ticket" && option.type != "website" && option.type != "role"){
createError("'"+path+"/type' | the type must be one of these: ticket, website, role!")
}
/**@type {"ticket"|"website"|"role"} */
const type = option.type
if (type == "ticket"){
//color
checkType(option.color,"string",path+"/color")
checkButtonColor(option.color,path+"/color")
//adminroles
checkDiscordArray("roleid",option.adminroles,path+"/adminroles")
//channelprefix
checkType(option.channelprefix,"string",path+"/channelprefix")
if (option.channelprefix.includes(" ")){
createWarn("'"+path+"/channelprefix' | this prefix can't contain spaces!")
}
//category
checkType(option.category,"string",path+"/category")
if (option.category.length > 0){
checkDiscord("categoryid",option.category,path+"/category")
}
//message
checkType(option.message,"string",path+"/message")
//enableDmOnOpen
checkType(option.enableDmOnOpen,"boolean",path+"/enableDmOnOpen")
//ticketmessage
checkType(option.ticketmessage,"string",path+"/ticketmessage")
//thumbnail
checkType(option.thumbnail.enable,"boolean",path/"/thumbnail/enable")
checkType(option.thumbnail.url,"string",path/"/thumbnail/url")
//closedCategory
checkType(option.closedCategory.enable,"boolean",path/"/closedCategory/enable")
checkType(option.closedCategory.id,"string",path/"/closedCategory/id")
if (option.closedCategory.enable){
checkDiscord("roleid",option.closedCategory.id,path+"/closedCategory/id")
}
}else if (type == "website"){
//url
checkType(option.url,"string",path+"/url")
if (option.url.includes(" ")){
createWarn("'"+path+"/url' | a url can't contain spaces")
}
if (option.url.length < 1){
createError("'"+path+"/url' | there is no url!")
}
if (!option.url.startsWith("https://") && !option.url.startsWith("http://") && !option.url.startsWith("discord://")){
createWarn("'"+path+"/url' | your url doesn't start with https or http!")
}
if (option.url.startsWith("http://")){
createWarn("'"+path+"/url' | your url is not a HTTPS link! discord can block this url!")
}
}else if (type == "role"){
//color
checkType(option.color,"string",path+"/color")
checkButtonColor(option.color,path+"/color")
//roles
checkDiscordArray("roleid",option.roles,path+"/roles")
//mode
checkType(option.mode,"string",path+"/mode")
if (option.mode != "add&remove" && option.mode != "add" && option.mode != "remove"){
createError("'"+path+"/mode' | mode must be one of these: add, remove, add&remove")
}
//enableDmOnOpen
checkType(option.enableDmOnOpen,"boolean",path+"/enableDmOnOpen")
}
}
/**
*
* @param {configParser.OTConfigMessage} input
* @param {String} path
*/
const checkMessage = (input,path) => {
//id
if (!input.id) createError("'"+path+"/id' | this embed doesn't have an id!")
if (input.id.length > 50) createError("'"+path+"/id' | the id can't be longer than 50")
if (input.id.includes(" ") || input.id.includes("\n")) createError("'"+path+"/id' | the id can't contain spaces!")
//name
if (input.name.length < 1){
createWarn("'"+path+"/name' | this embed has no name!")
}else if (input.name.length > 99) {
createError("'"+path+"/name' | the name can't be longer than 100")
}
//description
if (input.description.length < 0){
createWarn("'"+path+"/description' | this embed doesn't have a description!")
}
//dropdown
checkType(input.dropdown,"boolean",path+"/dropdown")
//footer
checkType(input.enableFooter,"boolean",path+"/enableFooter")
if (input.enableFooter){
if (input.footer.length < 1) createError("'"+path+"/footer' | no footer!")
if (input.footer.length > 200) createError("'"+path+"/footer' | footer length can't be more than 200!")
}
//thumbnail
checkType(input.enableThumbnail,"boolean",path+"/enableThumbnail")
if (input.enableThumbnail){
if (input.thumbnail.length < 1) createError("'"+path+"/thumbnail' | no thumbnail url!")
}
//customColor
checkType(input.enableCustomColor,"boolean",path+"/enableCustomColor")
if (input.enableCustomColor){
if (input.color.length < 1) createError("'"+path+"/color' | no color!")
checkHexColor(input.color,path+"/color")
}
//ticket explaination & max tickets warning
checkType(input.enableTicketExplaination,"boolean",path+"/enableTicketExplaination")
checkType(input.enableMaxTicketsWarning,"boolean",path+"/enableMaxTicketsWarning")
//OPTIONS!!!
var counter = 0
input.options.forEach((option) => {if (!configParser.optionExists(option)){counter++}})
if (counter == input.options.length){
createWarn("'"+path+"/options' | insert the option ids here!")
}else{
input.options.forEach((option,index) => {
if (!configParser.optionExists(option)){
createWarn("'"+path+"/options:"+index+"' | this option doesnt exist!")
}
})
}
}
//--------------------------|
//--------------------------|
//checker => START HERE |
//--------------------------|
//--------------------------|
var configArray = ["main_color","server_id","auth_token","main_adminroles","prefix","languagefile","credits","status","system","options","messages"]
configArray.forEach((item) => {
if (config[item] == undefined){
throw new Error("\n\nMAIN ERROR: the item '"+item+"' doesn't exist in config.json")
}
})
checkHexColor(config.main_color,"main_color")
checkDiscord("serverid",config.server_id,"server_id")
if (!require("./api/api.json").disable.checkerjs.token) checkToken(config.auth_token)
checkDiscordArray("roleid",config.main_adminroles,"main_adminroles")
checkString(config.prefix,1,15,"prefix","prefix")
//languagefile
checkType(config.languagefile,"string","languagefile")
const lf = config.languagefile
if (!lf.startsWith("custom") && !lf.startsWith("english") && !lf.startsWith("dutch") && !lf.startsWith("romanian") && !lf.startsWith("german") && !lf.startsWith("arabic") && !lf.startsWith("spanish") && !lf.startsWith("portuguese") && !lf.startsWith("french") && !lf.startsWith("italian")){
createError("'languagefile' | invalid language, more info in the wiki")
}
checkType(config.credits,"boolean","credits")
//status:
checkType(config.status.enabled,"boolean","status/enabled")
if (config.status.enabled){
if (config.status.type != "PLAYING" && config.status.type != "LISTENING" && config.status.type != "WATCHING"){
createError("'status/type' | not a valid status type! (LISTENING,WATCHING,PLAYING)")
}
if (config.status.text.length < 1){
createError("'status/text' | there is no status text!")
}
if (config.status.text.length > 50) createError("'status/text' | text too long!")
}
//system:
if (config.system.ticket_channel){
if (config.system.ticket_channel.length < 16 || config.system.ticket_channel.length > 20 || !/^\d+$/.test(config.system.ticket_channel)){
createError("'system/ticket_channel' | this channel id is invalid")
}
}else createWarn("'"+path+"' | you have no ticket channel selected!")
checkType(config.system.max_allowed_tickets,"number","system/max_allowed_tickets")
checkType(config.system.enable_DM_Messages,"boolean","system/enable_DM_Messages")
checkType(config.system["has@everyoneaccess"],"boolean","system/has@everyoneaccess")
if (config.system.member_role != "" && config.system.member_role != " " && config.system.member_role != "false" && config.system.member_role != "null" && config.system.member_role != "0"){
checkDiscord("roleid",config.system.member_role,"system/member_role")
}else{
createWarn("'system/member_role' | You don't have a member role, but it's recommended!")
}
checkType(config.system.closeMode,"string","system/closeMode")
if (!["normal","adminonly"].includes(config.system.closeMode)){
createError("'system/closeMode' | the close mode must be adminonly or normal")
}
checkType(config.system.enable_transcript,"boolean","system/enable_transcript")
checkType(config.system.enable_DM_transcript,"boolean","system/enable_DM_transcript")
if (config.system.enable_transcript){
checkDiscord("channelid",config.system.transcript_channel,"system/transcript_channel")
}
checkType(config.system.showSlashcmdsInHelp,"boolean","system/showSlashcmdsInHelp")
//options
config.options.forEach((option,index) => {
checkOption(option,"options/"+index)
})
//messages
config.messages.forEach((message,index) => {
checkMessage(message,"messages/"+index)
})
//discord check
/**
const discord = require("discord.js")
const {GatewayIntentBits,Partials} = discord
const client = new discord.Client({
intents:[
GatewayIntentBits.DirectMessages,
GatewayIntentBits.GuildInvites,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.Guilds,
GatewayIntentBits.MessageContent
],
partials:[Partials.Channel,Partials.Message]
})
await client.guilds.fetch()
if (!client.guilds.cache.find(g => g.id == config.server_id)){
createError("'server_id' | i'm not in a server with this id!")
}
*/
//the end
if (errorList.length > 0 || warnList.length > 0){
console.log("REPORT:\n===========================")
}
warnList.forEach((w) => {
const splitw = w.split("'")
if (splitw.length > 1){
var splitstring = chalk.yellow(splitw[0])+chalk.blue("'"+splitw[1]+"'")+chalk.yellow(splitw[2])
}else {var splitstring = chalk.yellow(splitw[0])}
console.log(splitstring)
})
errorList.forEach((e) => {
const splite = e.split("'")
if (splite.length > 1){
var splitstring = chalk.red(splite[0])+chalk.blue("'"+splite[1]+"'")+chalk.red(splite[2])
}else {var splitstring = chalk.red(splite[0])}
console.log(splitstring)
})
if (isError){
console.log("===========================")
console.log("=> "+chalk.bgRed("your bot doesn't work if you don't fix the above errors!"))
if (isWarn){
console.log("\n=> "+chalk.bgYellow("if you ignore warns, some things may work differently than expected!"))
}
process.exit(0)
}else if (isWarn == true && isError == false){
console.log("===========================")
console.log("=> "+chalk.bgYellow("if you ignore warns, some things may work differently than expected!"))
}
}
-53
View File
@@ -1,53 +0,0 @@
const fs = require('fs')
const readline = require("readline")
const rl = readline.createInterface({
input:process.stdin,
output:process.stdout,
terminal:true
})
const ask = async () => {
const chalk = await (await import("chalk")).default
rl.question(chalk.yellow("WARNING: are you sure that there are",chalk.red("no tickets open"),"at the moment? ")+chalk.green("(yes/no)")+"\n",(answer) => {
if (answer != "1" && !answer.toLowerCase().startsWith("yes")){
console.log(chalk.red("invalid answer"))
ask()
return
}
console.log(chalk.green("clearing data..."))
runClear()
rl.close()
})
}
ask()
const runClear = async () => {
const chalk = await (await import("chalk")).default
//console.log(chalk.blue("You can get a node.js warning below, just ignore that, it's not important!"))
const dataPaths = ["./storage/dynamicDB"]
var index = 0
dataPaths.forEach((path) => {
try {
fs.rmSync(path,{recursive:true,force:true})
}catch{
//console.log(path,"doesn't exist")
}
setTimeout(() => {
try{
fs.mkdirSync(path)
}catch{
//console.log(path,"already exists")
}
index++
},500)
})
setInterval(() => {
if (index >= 1){
console.log(chalk.bgGreen("All local data is cleared!"))
process.exit(1)
}
},500)
}
@@ -1,39 +0,0 @@
const localstorage = require("node-localstorage")
const ls = new localstorage.LocalStorage("./storage/dynamicDB")
/**
*
* @param {String} category
* @param {String} id
* @param {String} value
* @returns {Boolean}
*/
exports.set = (category,id,value) => {
ls.setItem(category+"--"+id,value.toString())
return true
}
/**
*
* @param {String} category
* @param {String} id
* @returns {String|false}
*/
exports.get = (category,id) => {
const result = ls.getItem(category+"--"+id)
if (!result) return false
return result
}
/**
*
* @param {String} category
* @param {String} id
* @returns {Boolean}
*/
exports.delete = (category,id) => {
ls.removeItem(category+"--"+id)
return true
}
-13
View File
@@ -1,13 +0,0 @@
//Do not change this without knowing what you are doing!!
const databaseFile = "local"
//Do not change this without knowing what you are doing!!
try {
var db = require("./dynamicfiles/local")
}catch{
console.log("I couldn't find the database file! (location: ./core/dynamicdatabase/storage.js:2)")
process.exit(1)
}
module.exports = db
-140
View File
@@ -1,140 +0,0 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const l = bot.language
const loadChalk = async () => {
return await (await import("chalk")).default
}
const embed = discord.EmbedBuilder
const c = discord.Colors
/**@param {discord.User} user*/
exports.noPermsMessage = (user) => {
return new embed()
.setColor(c.Red)
.setTitle(":x: "+l.errors.noPermsTitle)
.setDescription(l.errors.noPermsDescription)
.setFooter({iconURL:user.displayAvatarURL(),text:user.tag})
}
/**@param {discord.User} user*/
exports.noPermsDelete = (user) => {
return new embed()
.setColor(c.Red)
.setTitle(":x: "+l.errors.noPermsTitle)
.setDescription(l.errors.noPermsDelete)
.setFooter({iconURL:user.displayAvatarURL(),text:user.tag})
}
/**@param {String} message */
exports.invalidArgsMessage = (message) => {
var x = new embed()
.setColor(c.Red)
.setTitle(":x: "+l.errors.missingArgsTitle)
.setDescription(message)
return x
}
/**@param {String} message */
exports.serverError = (message) => {
var x = new embed()
.setColor(c.Orange)
.setTitle(":warning: "+l.errors.boterror)
.setDescription(message)
return x
}
/**@param {String[]} list */
exports.invalidIdChooseFromList = (list) => {
var x = new embed()
.setColor(c.Red)
.setTitle(":x: "+l.errors.chooseFromListTitle)
.setDescription(l.errors.chooseFromListDescription+"\n`"+list.join("`\n`")+"`")
return x
}
exports.notInATicket = new embed()
.setColor(c.Red)
.setTitle(":x: "+l.errors.notInTicketTitle)
.setDescription(l.errors.notInTicketDescription)
/**@param {String} message @param {String} title */
exports.success = (title,message) => {
var x = new embed()
.setColor(config.main_color)
.setTitle(":white_check_mark: "+title)
.setDescription(message)
return x
}
/**@param {String} message @param {String} title */
exports.warning = (title,message) => {
var x = new embed()
.setColor(c.Orange)
.setTitle(":warning: "+title)
.setDescription(message)
return x
}
/**@param {String} message the message @param {String} title the title @param {String} emoji an discord emoji @param {discord.ColorResolvable} color the embed color*/
exports.custom = (title,message,emoji,color) => {
var x = new embed()
.setColor(color)
.setTitle(emoji+" "+title)
.setDescription(message)
return x
}
const normalLog = (debugString) => {
const fs = require("fs")
const content = fs.existsSync("./openticketdebug.txt") ? fs.readFileSync("./openticketdebug.txt").toString() : "==========================\n<OPEN TICKET DEBUG FILE:>\n=========================="
fs.writeFileSync("./openticketdebug.txt",content+"\nSYSTEM: "+debugString)
}
/**
*
* @param {"system"|"command"|"info"|"api"|"debug"} type
* @param {String} message
* @param {[{key:String,value:String}]} params
*/
exports.log = async (type,message,params) => {
var ptype = type
const chalk = await loadChalk()
var paramstring = ""
if (params){
if (params.length > 0){
params.forEach((p) => {
paramstring = paramstring+p.key+": "+p.value+" "
})
}
}
const parameters = params ? "("+paramstring+")" : " "
if (ptype == "command"){
console.log(chalk.green("[command] ")+message+" "+chalk.yellow(parameters))
}else if (ptype == "info"){
console.log(chalk.blue("[info] ")+message+" "+chalk.yellow(parameters))
}else if (ptype == "system"){
console.log(chalk.green("[system] ")+message+" "+chalk.yellow(parameters))
}else if (ptype == "api"){
if (require("./api/api.json").enableAPIconsolelogs == true){
console.log(chalk.red("[api v"+require("./api/api.json").version+"] ")+message+" "+chalk.yellow(parameters))
}
ptype = "api v"+require("./api/api.json").version
}else if (ptype == "debug"){
if (!process.argv.some((v) => v == "--debug")) return
console.log(chalk.redBright("[DEBUG] ")+message+" "+chalk.yellow(parameters))
}
const cd = new Date()
const months = ["January","February","March","April","May","June","July","August","September","October","November","December"]
normalLog("["+cd.getDate()+" "+months[cd.getMonth()-1]+" "+cd.getFullYear()+" - "+cd.getSeconds()+":"+cd.getMinutes()+":"+cd.getHours()+"] ["+ptype+"] "+message+" "+parameters)
}
-77
View File
@@ -1,77 +0,0 @@
const discord = require('discord.js')
const bot = require('../../../index')
const client = bot.client
const config = bot.config
const l = bot.language
const log = bot.errorLog.log
const hiddendata = bot.hiddenData
const embed = discord.EmbedBuilder
const mc = config.main_color
const button = discord.ButtonBuilder
const arb = discord.ActionRowBuilder
const bs = discord.ButtonStyle
exports.closeCommandRow = new arb()
.addComponents(
new button()
.setCustomId("OTdeleteTicket1")
.setDisabled(false)
.setStyle(bs.Danger)
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
.addComponents(
new button()
.setCustomId("OTsendTranscript")
.setDisabled(false)
.setStyle(bs.Secondary)
.setLabel(l.buttons.sendTranscript)
.setEmoji("📄")
)
.addComponents(
new button()
.setCustomId("OTreopenTicket")
.setDisabled(false)
.setStyle(bs.Success)
.setLabel(l.buttons.reopen)
.setEmoji("✔")
)
exports.openRowNormal = new arb()
.addComponents(
new button()
.setCustomId("OTcloseTicket")
.setDisabled(false)
.setStyle(bs.Secondary)
.setLabel(l.buttons.close)
.setEmoji("🔒")
)
.addComponents(
new button()
.setCustomId("OTdeleteTicket")
.setDisabled(false)
.setStyle(bs.Danger)
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
exports.openRowDisabled = new arb()
.addComponents(
new button()
.setCustomId("OTcloseTicket")
.setDisabled(true)
.setStyle(bs.Secondary)
.setLabel(l.buttons.close)
.setEmoji("🔒")
)
.addComponents(
new button()
.setCustomId("OTdeleteTicket")
.setDisabled(true)
.setStyle(bs.Danger)
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
@@ -1,51 +0,0 @@
const discord = require('discord.js')
const bot = require('../../../index')
const client = bot.client
const config = bot.config
const l = bot.language
const log = bot.errorLog.log
const hiddendata = bot.hiddenData
const embed = discord.EmbedBuilder
const mc = config.main_color
const button = discord.ButtonBuilder
const arb = discord.ActionRowBuilder
const bs = discord.ButtonStyle
exports.firstmsgRowNormal = new arb()
.addComponents(
new button()
.setCustomId("OTcloseTicket")
.setDisabled(false)
.setStyle(bs.Secondary)
.setLabel(l.buttons.close)
.setEmoji("🔒")
)
.addComponents(
new button()
.setCustomId("OTdeleteTicket")
.setDisabled(false)
.setStyle(bs.Danger)
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
exports.firstmsgRowDisabled = new arb()
.addComponents(
new button()
.setCustomId("OTcloseTicket")
.setDisabled(true)
.setStyle(bs.Secondary)
.setLabel(l.buttons.close)
.setEmoji("🔒")
)
.addComponents(
new button()
.setCustomId("OTdeleteTicket")
.setDisabled(true)
.setStyle(bs.Danger)
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
@@ -1,71 +0,0 @@
const discord = require('discord.js')
const bot = require('../../../index')
const client = bot.client
const config = bot.config
const l = bot.language
const log = bot.errorLog.log
const hiddendata = bot.hiddenData
const embed = discord.EmbedBuilder
const mc = config.main_color
const button = discord.ButtonBuilder
const arb = discord.ActionRowBuilder
const bs = discord.ButtonStyle
exports.closeVerifyBar = new arb()
.addComponents(
new button()
.setCustomId("OTcloseTicketReason")
.setDisabled(false)
.setStyle(bs.Primary)
.setEmoji("💬")
.setLabel(l.buttons.closeWithReason)
)
.addComponents(
new button()
.setCustomId("OTcloseTicketTrue")
.setDisabled(false)
.setStyle(bs.Secondary)
.setEmoji("✅")
)
.addComponents(
new button()
.setCustomId("OTcloseTicketFalse")
.setDisabled(false)
.setStyle(bs.Secondary)
.setEmoji("❌")
)
exports.deleteVerifyBar = new arb()
.addComponents(
new button()
.setCustomId("OTdeleteTicketTrue")
.setDisabled(false)
.setStyle(bs.Secondary)
.setEmoji("✅")
)
.addComponents(
new button()
.setCustomId("OTdeleteTicketFalse")
.setDisabled(false)
.setStyle(bs.Secondary)
.setEmoji("❌")
)
exports.delete1VerifyBar = new arb()
.addComponents(
new button()
.setCustomId("OTdeleteTicketTrue1")
.setDisabled(false)
.setStyle(bs.Secondary)
.setEmoji("✅")
)
.addComponents(
new button()
.setCustomId("OTdeleteTicketFalse1")
.setDisabled(false)
.setStyle(bs.Secondary)
.setEmoji("❌")
)
-139
View File
@@ -1,139 +0,0 @@
const discord = require('discord.js')
const bot = require('../../../index')
const client = bot.client
const config = bot.config
const l = bot.language
const log = bot.errorLog.log
const hiddendata = bot.hiddenData
const embed = discord.EmbedBuilder
const mc = config.main_color
/**
*
* @param {discord.User} addedUser
* @param {discord.User} adder
* @returns {discord.EmbedBuilder}
*/
exports.addEmbed = (addedUser,adder) => {
return new embed()
.setTitle("⬆️ "+l.commands.userAddedTitle.replace("{0}",addedUser.username))
.setColor(mc)
.setFooter({text:adder.tag,iconURL:adder.displayAvatarURL()})
.setThumbnail(addedUser.displayAvatarURL({extension:"png"}))
}
/**
*
* @param {discord.User} removedUser
* @param {discord.User} remover
* @returns {discord.EmbedBuilder}
*/
exports.removeEmbed = (removedUser,remover) => {
return new embed()
.setTitle("⬇️ "+l.commands.userRemovedTitle.replace("{0}",removedUser.username))
.setColor(mc)
.setFooter({text:remover.tag,iconURL:remover.displayAvatarURL()})
.setThumbnail(removedUser.displayAvatarURL({extension:"png"}))
}
/**
*
* @param {discord.User} closer
* @param {String} description
* @returns {discord.EmbedBuilder}
*/
exports.closeEmbed = (closer,description) => {
const embd = new embed()
.setTitle("🔒 "+l.commands.closeTitle)
.setColor(mc)
.setFooter({text:closer.tag,iconURL:closer.displayAvatarURL()})
if (description) embd.setDescription(description)
return embd
}
/**
*
* @param {discord.User} deleter
* @returns {discord.EmbedBuilder}
*/
exports.deleteEmbed = (deleter) => {
return new embed()
.setTitle("❌ "+l.commands.deleteTitle)
.setColor(mc)
.setFooter({text:deleter.tag,iconURL:deleter.displayAvatarURL()})
}
/**
*
* @param {discord.User} renamer
* @param {String} newname
* @returns {discord.EmbedBuilder}
*/
exports.renameEmbed = (renamer,newname) => {
return new embed()
.setTitle("🔄 "+l.commands.renameTitle.replace("{0}",newname))
.setColor(mc)
.setFooter({text:renamer.tag,iconURL:renamer.displayAvatarURL()})
}
/**
*
* @param {discord.User} reopener
* @returns {discord.EmbedBuilder}
*/
exports.reopenEmbed = (reopener) => {
return new embed()
.setTitle("🔓 "+l.commands.reopenTitle)
.setColor(mc)
.setFooter({text:reopener.tag,iconURL:reopener.displayAvatarURL()})
}
/**
*
* @param {discord.User} claimer
* @param {discord.User} user
* @returns {discord.EmbedBuilder}
*/
exports.claimEmbed = (claimer,user) => {
return new embed()
.setTitle("📌 "+l.commands.claimTitle.replace("{0}",claimer.username))
.setColor(mc)
.setFooter({text:user.tag,iconURL:user.displayAvatarURL()})
}
/**
*
* @param {discord.User} unclaimer
* @returns {discord.EmbedBuilder}
*/
exports.unclaimEmbed = (unclaimer) => {
return new embed()
.setTitle("🆓 "+l.commands.unclaimTitle)
.setColor(mc)
.setFooter({text:unclaimer.tag,iconURL:unclaimer.displayAvatarURL()})
}
/**
*
* @param {Boolean} done
* @param {discord.TextChannel} channel
* @param {discord.User} author
* @returns {discord.EmbedBuilder}
*/
exports.sendTranscriptEmbed = (done,channel,author) => {
if (done){
return new embed()
.setTitle("📄 "+l.messages.hereIsTheTranscript)
.setColor(mc)
.setDescription("Ticket: "+channel.name)
.setFooter({text:author.tag,iconURL:author.displayAvatarURL()})
}else{
return new embed()
.setTitle("📄 "+l.messages.hereIsTheTranscript)
.setColor(mc)
.setDescription("Loading...")
.setFooter({text:author.tag,iconURL:author.displayAvatarURL()})
}
}
@@ -1,61 +0,0 @@
const discord = require('discord.js')
const bot = require('../../../../index')
const client = bot.client
const config = bot.config
const l = bot.language
const log = bot.errorLog.log
const permissionChecker = require("../../../utils/permisssionChecker")
const storage = bot.storage
const hiddendata = bot.hiddenData
const embed = discord.EmbedBuilder
const mc = config.main_color
const button = discord.ButtonBuilder
const arb = discord.ActionRowBuilder
const bs = discord.ButtonStyle
module.exports = () => {
//CLOSE
var closeTicketButtonChecker = false
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "OTcloseTicketTrue") return
interaction.deferUpdate()
if (closeTicketButtonChecker == true) return
closeTicketButtonChecker = true
const firstcomponents = interaction.message.components
if (config.system.closeMode == "adminonly"){
if (!permissionChecker.command(interaction.user.id,interaction.guild.id)){
if (!permissionChecker.sendUserNoPerms(interaction.user)){
permissionChecker.sendChannelNoPerms(interaction.channel,interaction.user)
}
interaction.message.edit({components:[firstcomponents]})
closeTicketButtonChecker = false
return
}
}
interaction.message.edit({components:[bot.buttons.close.openRowDisabled]})
/**
* @type {String}
*/
const name = interaction.channel.name
var prefix = ""
const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
}
})
interaction.channel.send({embeds:[bot.embeds.commands.closeEmbed(interaction.user)],components:[bot.buttons.close.closeCommandRow]})
await require("../../../ticketActions/ticketCloser").NEWcloseTicket(interaction.member,interaction.channel,prefix,"close",false,true)
closeTicketButtonChecker = false
})
}
@@ -1,99 +0,0 @@
const discord = require('discord.js')
const bot = require('../../../../index')
const client = bot.client
const config = bot.config
const l = bot.language
const log = bot.errorLog.log
const permissionChecker = require("../../../utils/permisssionChecker")
const storage = bot.storage
const hiddendata = bot.hiddenData
const embed = discord.EmbedBuilder
const mc = config.main_color
const button = discord.ButtonBuilder
const arb = discord.ActionRowBuilder
const bs = discord.ButtonStyle
const modal = discord.ModalBuilder
const tis = discord.TextInputStyle
const tib = discord.TextInputBuilder
module.exports = () => {
//theModal
const reasonModal = new modal()
.setTitle(l.buttons.closeWithReason)
.setCustomId("OTCloseReasonModal")
const reasonInput = new arb()
.addComponents([
new tib()
.setCustomId('OTreasonInput')
.setLabel(l.messages.modalreason)
.setStyle(tis.Short)
.setMaxLength(100)
.setRequired(true)
.setValue("")
.setPlaceholder("reason")
])
reasonModal.addComponents(reasonInput)
//CLOSE WITH REASON
var closeTicketButtonChecker = false
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "OTcloseTicketReason") return
if (closeTicketButtonChecker == true) return interaction.deferUpdate()
closeTicketButtonChecker = true
const firstcomponents = interaction.message.components
if (config.system.closeMode == "adminonly"){
if (!permissionChecker.command(interaction.user.id,interaction.guild.id)){
if (!permissionChecker.sendUserNoPerms(interaction.user)){
permissionChecker.sendChannelNoPerms(interaction.channel,interaction.user)
}
interaction.message.edit({components:[firstcomponents]})
closeTicketButtonChecker = false
return interaction.deferUpdate()
}
}
interaction.message.edit({components:[bot.buttons.close.openRowDisabled]})
await interaction.showModal(reasonModal)
})
client.on("interactionCreate",async (interaction) => {
if (interaction.type != discord.InteractionType.ModalSubmit) return
if (interaction.customId != "OTCloseReasonModal") return
interaction.reply({embeds:[bot.embeds.commands.closeEmbed(interaction.user)],components:[bot.buttons.close.closeCommandRow]})
const reason = interaction.fields.getTextInputValue("OTreasonInput")
/**
* @type {String}
*/
const name = interaction.channel.name
var prefix = ""
const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
}
})
//interaction.channel.send({embeds:[bot.embeds.commands.closeEmbed(interaction.user)],components:[bot.buttons.close.closeCommandRow]})
await require("../../../ticketActions/ticketCloser").NEWcloseTicket(interaction.member,interaction.channel,prefix,"close",reason,true)
closeTicketButtonChecker = false
})
}
@@ -1,97 +0,0 @@
const discord = require('discord.js')
const bot = require('../../../../index')
const client = bot.client
const config = bot.config
const l = bot.language
const log = bot.errorLog.log
const permissionChecker = require("../../../utils/permisssionChecker")
const storage = bot.storage
const hiddendata = bot.hiddenData
const embed = discord.EmbedBuilder
const mc = config.main_color
const button = discord.ButtonBuilder
const arb = discord.ActionRowBuilder
const bs = discord.ButtonStyle
module.exports = () => {
//DELETE
var deleteTicketButtonChecker = false
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "OTdeleteTicketTrue") return
interaction.deferUpdate()
if (deleteTicketButtonChecker == true) return
deleteTicketButtonChecker = true
const firstcomponents = bot.buttons.close.openRowNormal
if (!permissionChecker.command(interaction.user.id,interaction.guild.id)){
if (!permissionChecker.sendUserNoDelete(interaction.user)){
permissionChecker.sendChannelNoDelete(interaction.channel,interaction.user)
}
await interaction.message.edit({components:[firstcomponents]})
deleteTicketButtonChecker = false
return
}
/**
* @type {String}
*/
const name = interaction.channel.name
var prefix = ""
const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
}
})
interaction.channel.send({embeds:[bot.embeds.commands.deleteEmbed(interaction.user)]})
await interaction.message.edit({components:[bot.buttons.close.openRowDisabled]})
await require("../../../ticketActions/ticketCloser").NEWcloseTicket(interaction.member,interaction.channel,prefix,"delete",false,true)
deleteTicketButtonChecker = false
})
//DELETE NO TRANSCRIPT
var deleteTicketButtonChecker1 = false
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "OTdeleteTicketTrue1") return
interaction.deferUpdate()
if (deleteTicketButtonChecker1 == true) return
deleteTicketButtonChecker1 = true
const firstcomponents = bot.buttons.close.closeCommandRow
if (!permissionChecker.command(interaction.user.id,interaction.guild.id)){
if (!permissionChecker.sendUserNoDelete(interaction.user)){
permissionChecker.sendChannelNoDelete(interaction.channel,interaction.user)
}
await interaction.message.edit({components:[firstcomponents]})
deleteTicketButtonChecker1 = false
return
}
/**
* @type {String}
*/
const name = interaction.channel.name
var prefix = ""
const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
}
})
interaction.channel.send({embeds:[bot.embeds.commands.deleteEmbed(interaction.user)]})
await require("../../../ticketActions/ticketCloser").NEWcloseTicket(interaction.member,interaction.channel,prefix,"deletenotranscript",false,true)
deleteTicketButtonChecker1 = false
})
}
@@ -1,28 +0,0 @@
const discord = require('discord.js')
const bot = require('../../../../index')
const client = bot.client
const config = bot.config
const l = bot.language
const log = bot.errorLog.log
const permissionChecker = require("../../../utils/permisssionChecker")
const storage = bot.storage
const hiddendata = bot.hiddenData
const embed = discord.EmbedBuilder
const mc = config.main_color
const button = discord.ButtonBuilder
const arb = discord.ActionRowBuilder
const bs = discord.ButtonStyle
module.exports = () => {
//REOPEN
client.on("interactionCreate",(interaction) => {
if (!interaction.isButton()) return
if (interaction.customId != "OTreopenTicket") return
interaction.deferUpdate()
interaction.message.edit({embeds:[bot.embeds.commands.reopenEmbed(interaction.user)],components:[bot.buttons.close.openRowNormal]})
require("../../../ticketActions/ticketReopener").reopenTicket(interaction.guild,interaction.channel,interaction.user)
})
}
@@ -1,20 +0,0 @@
const discord = require('discord.js')
const bot = require('../../../index')
const client = bot.client
const config = bot.config
const l = bot.language
const log = bot.errorLog.log
const storage = bot.storage
const hiddendata = bot.hiddenData
const embed = discord.EmbedBuilder
const mc = config.main_color
const button = discord.ButtonBuilder
const arb = discord.ActionRowBuilder
const bs = discord.ButtonStyle
module.exports = () => {
}
@@ -1,11 +0,0 @@
module.exports = () => {
require("./firstmsg")()
require("./sendTranscript")()
require("./verifyBars")()
//accepted
require("./accepted/closing")()
require("./accepted/reopening")()
require("./accepted/deleting")()
require("./accepted/closingReason")()
}
@@ -1,44 +0,0 @@
const discord = require('discord.js')
const bot = require('../../../index')
const client = bot.client
const config = bot.config
const l = bot.language
const log = bot.errorLog.log
const storage = bot.storage
const hiddendata = bot.hiddenData
const embed = discord.EmbedBuilder
const mc = config.main_color
const button = discord.ButtonBuilder
const arb = discord.ActionRowBuilder
const bs = discord.ButtonStyle
module.exports = () => {
client.on("interactionCreate",async (interaction) => {
if (!interaction.isButton()) return
if (interaction.customId != "OTsendTranscript") return
interaction.deferUpdate()
const tsmsg = await interaction.channel.send({embeds:[bot.embeds.commands.sendTranscriptEmbed(false,interaction.channel,interaction.user)]})
const channelmessages = await interaction.channel.messages.fetch()
channelmessages.sweep((msgSweep) => {
return msgSweep.author.id == client.user.id
})
var fileattachment = await require("../../transcript").createTranscript(channelmessages,interaction.channel)
if (fileattachment == false){
log("system","internal error: transcript is not created!")
tsmsg.edit({embeds:[bot.errorLog.serverError(l.errors.somethingWentWrongTranscript)]})
return
}
try {
tsmsg.edit({embeds:[bot.embeds.commands.sendTranscriptEmbed(true,interaction.channel,interaction.user)],files:[fileattachment]})
}catch{}
})
}
@@ -1,68 +0,0 @@
const discord = require('discord.js')
const bot = require('../../../index')
const client = bot.client
const config = bot.config
const l = bot.language
const log = bot.errorLog.log
const storage = bot.storage
const hiddendata = bot.hiddenData
const embed = discord.EmbedBuilder
const mc = config.main_color
const button = discord.ButtonBuilder
const arb = discord.ActionRowBuilder
const bs = discord.ButtonStyle
module.exports = () => {
//CLOSE
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "OTcloseTicket") return
interaction.deferUpdate()
interaction.message.edit({components:[bot.buttons.verifybars.closeVerifyBar]})
})
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "OTcloseTicketFalse") return
interaction.deferUpdate()
interaction.message.edit({components:[bot.buttons.close.openRowNormal]})
})
//DELETE
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "OTdeleteTicket") return
interaction.deferUpdate()
interaction.message.edit({components:[bot.buttons.verifybars.deleteVerifyBar]})
})
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "OTdeleteTicketFalse") return
interaction.deferUpdate()
interaction.message.edit({components:[bot.buttons.close.openRowNormal]})
})
//DELETE NO TRANSCRIPT
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "OTdeleteTicket1") return
interaction.deferUpdate()
interaction.message.edit({components:[bot.buttons.verifybars.delete1VerifyBar]})
})
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "OTdeleteTicketFalse1") return
interaction.deferUpdate()
interaction.message.edit({components:[bot.buttons.close.closeCommandRow]})
})
}
-42
View File
@@ -1,42 +0,0 @@
const index = require("../index")
if (index.developerConfig){
var config = require("../devConfig.json")
}else{var config = require("../config.json")}
var localLanguage = require("../language/english.json")
if (config.languagefile.startsWith("custom")) localLanguage = require("../language/custom.json")
else if (config.languagefile.startsWith("dutch")) localLanguage = require("../language/dutch.json")
else if (config.languagefile.startsWith("english")) localLanguage = require("../language/english.json")
else if (config.languagefile.startsWith("german")) localLanguage = require("../language/german.json")
else if (config.languagefile.startsWith("french")) localLanguage = require("../language/french.json")
else if (config.languagefile.startsWith("romanian")) localLanguage = require("../language/romanian.json")
else if (config.languagefile.startsWith("arabic")) localLanguage = require("../language/arabic.json")
else if (config.languagefile.startsWith("spanish")) localLanguage = require("../language/spanish.json")
else if (config.languagefile.startsWith("portuguese")) localLanguage = require("../language/portuguese.json")
else if (config.languagefile.startsWith("italian")) localLanguage = require("../language/italian.json")
const errorLog = async () => {
const chalk = await (await import("chalk")).default
console.log(chalk.red("Something went wrong when loading the language!")+"\nCheck the config file or create a ticket in our server!")
}
const successLog = async (language) => {
const chalk = await (await import("chalk")).default
console.log(chalk.green("loaded language "+language+"..."))
}
if (!localLanguage){
const runError = async () => {
await errorLog()
process.exit(1)
}
runError()
}else{
exports.language = localLanguage
successLog(config.languagefile)
}
-75
View File
@@ -1,75 +0,0 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const l = bot.language
const storage = bot.storage
const APIEvents = require("./api/modules/events")
module.exports = async () => {
const chalk = await (await import("chalk")).default
client.on("interactionCreate",(interaction) => {
if (!interaction.isButton()) return
if (!interaction.customId.startsWith("newR")) return
interaction.deferUpdate()
if (interaction.customId.startsWith("newR")){
const optionid = interaction.customId.split("newR")[1]
if (!optionid){
interaction.reply({embeds:[bot.errorLog.serverError(l.errors.roleDoesntExist)]})
return
}
try {
const option = require("./utils/getButton").getOption(optionid)
/**@type {"add"|"remove"|"add&remove"} */
const mode = option.mode
const user = interaction.member
if (mode == "add"){
option.roles.forEach((role) => {
interaction.guild.members.cache.find(u => u.id == user.id).roles.add(role)
log("system","added role (reaction roles)",[{key:"user",value:interaction.user.tag},{key:"role",value:role}])
const apirole = interaction.guild.roles.cache.find(r => r.id == role)
APIEvents.onReactionRole("add","add",apirole,interaction.user,interaction.channel,interaction.guild,new Date())
})
}else if (mode == "remove"){
option.roles.forEach((role) => {
interaction.guild.members.cache.find(u => u.id == user.id).roles.remove(role)
log("system","removed role (reaction roles)",[{key:"user",value:interaction.user.tag},{key:"role",value:role}])
const apirole = interaction.guild.roles.cache.find(r => r.id == role)
APIEvents.onReactionRole("remove","remove",apirole,interaction.user,interaction.channel,interaction.guild,new Date())
})
}else if (mode == "add&remove"){
option.roles.forEach((role) => {
if (interaction.guild.members.cache.find(u => u.id == user.id).roles.cache.has(role)){
interaction.guild.members.cache.find(u => u.id == user.id).roles.remove(role)
log("system","added role (reaction roles)",[{key:"user",value:interaction.user.tag},{key:"role",value:role}])
const apirole = interaction.guild.roles.cache.find(r => r.id == role)
APIEvents.onReactionRole("add","add&remove",apirole,interaction.user,interaction.channel,interaction.guild,new Date())
}else {
interaction.guild.members.cache.find(u => u.id == user.id).roles.add(role)
log("system","removed role (reaction roles)",[{key:"user",value:interaction.user.tag},{key:"role",value:role}])
const apirole = interaction.guild.roles.cache.find(r => r.id == role)
APIEvents.onReactionRole("remove","add&remove",apirole,interaction.user,interaction.channel,interaction.guild,new Date())
}
})
}
}catch{
interaction.channel.send({embeds:[bot.errorLog.serverError(l.errors.somethingWentWrong)]})
}
}
})
}
-23
View File
@@ -1,23 +0,0 @@
const discord = require("discord.js")
const bot = require("../../index")
const client = require("../../index").client
const config = bot.config
module.exports = async () => {
const chalk = (await import("chalk")).default
console.log(chalk.red("\nINSTRUCTIONS:\n\n1: Run the command you want to delete in discord.\n2: You get the message 'This command is now deleted!'\n3: There is also a message in the console that says the command is deleted.\n4: reload your discord."))
client.on("interactionCreate",(interaction) => {
if (!interaction.isChatInputCommand()) return console.log("this isn't a command!")
interaction.reply({content:"This command is now deleted!"})
try {
client.application.commands.delete(interaction.commandId,interaction.guild.id).then(() => {
console.log("deleted the command",chalk.blue(interaction.commandName),"(id:",interaction.commandId+")")
})
}catch{
console.log(chalk.red("something went wrong by the deleting of this command!"))
}
})
}
-246
View File
@@ -1,246 +0,0 @@
const discord = require("discord.js")
const bot = require("../../index")
const client = require("../../index").client
const config = bot.config
const configParser = require("../utils/configParser")
const act = discord.ApplicationCommandType
const acot = discord.ApplicationCommandOptionType
module.exports = async () => {
const chalk = (await import("chalk")).default
const sid = config.server_id
const ids = configParser.getTicketValuesArray("id")
/**@type {[{name:String,value:String}]} */
var choices = []
ids.forEach((id) => {
const option = configParser.getTicketById(id)
if (option){
choices.push({name:option.name,value:option.id})
}
})
/**@type {[{name:String,value:String}]} */
var msgchoices = []
config.messages.forEach((msg) => {
msgchoices.push({name:msg.id,value:msg.id})
})
var readystats = 0
//process.stdout.write("[status] there are "+chalk.blue("0 out of 10")+" commands ready! (this can take up to 40 seconds)")
setInterval(() => {
process.stdout.cursorTo(0)
process.stdout.write("[status] there are "+chalk.blue(readystats+" out of 12")+" commands ready! (this can take up to 40 seconds)")
if (readystats >= 12){
console.log(chalk.green("\nready!"))
console.log(chalk.blue("you can now start the bot with "+chalk.bgBlue("'npm start'")+"!"))
process.exit(1)
}
},100)
//slashtranslation
const ST = require("../../language/slashcmds/slash.json").data
//create a ticket (/new or /ticket)
client.application.commands.create({
name:"ticket",
description:"Create a ticket!",
descriptionLocalizations:ST.newticket,
defaultPermission:true,
type:act.ChatInput,
options:[
{
type:acot.String,
name:"type",
description:"The type of ticket.",
required:true,
choices:choices
}
]
},sid).then(() => {
readystats++
})
client.application.commands.create({
name:"new",
description:"Create a ticket!",
defaultPermission:true,
type:act.ChatInput,
descriptionLocalizations:ST.newticket,
options:[
{
type:acot.String,
name:"type",
description:"The type of ticket.",
required:true,
choices:choices
}
]
},sid).then(() => {
readystats++
})
//help
client.application.commands.create({
name:"help",
description:"View the available commands.",
defaultPermission:true,
descriptionLocalizations:ST.help,
type:act.ChatInput
},sid).then(() => {
readystats++
})
//close
client.application.commands.create({
name:"close",
description:"Close the current ticket.",
defaultPermission:true,
descriptionLocalizations:ST.close,
type:act.ChatInput,
options:[{
name:"reason",
type:discord.ApplicationCommandOptionType.String,
required:false,
description:"The reason to close this ticket.",
maxLength:100
}]
},sid).then(() => {
readystats++
})
//delete
client.application.commands.create({
name:"delete",
description:"Delete the current ticket.",
defaultPermission:true,
descriptionLocalizations:ST.delete,
type:act.ChatInput
},sid).then(() => {
readystats++
})
//msg
client.application.commands.create({
name:"message",
description:"Create a ticket message.",
defaultPermission:true,
descriptionLocalizations:ST.message,
type:act.ChatInput,
options:[
{
type:acot.String,
name:"id",
description:"The message id.",
required:true,
choices:msgchoices,
max_length:30
}
]
},sid).then(() => {
readystats++
})
//add
client.application.commands.create({
name:"add",
description:"Add people to this ticket.",
defaultPermission:true,
descriptionLocalizations:ST.add,
type:act.ChatInput,
options:[
{
type:acot.User,
name:"user",
description:"The user to add.",
required:true
}
]
},sid).then(() => {
readystats++
})
//remove
client.application.commands.create({
name:"remove",
description:"Remove people from this ticket.",
defaultPermission:true,
descriptionLocalizations:ST.remove,
type:act.ChatInput,
options:[
{
type:acot.User,
name:"user",
description:"The user to remove.",
required:true
}
]
},sid).then(() => {
readystats++
})
//rename
client.application.commands.create({
name:"rename",
description:"Rename this ticket.",
defaultPermission:true,
descriptionLocalizations:ST.rename,
type:act.ChatInput,
options:[
{
type:acot.String,
name:"name",
description:"The new name (without prefix).",
required:true
}
]
},sid).then(() => {
readystats++
})
//reopen
client.application.commands.create({
name:"reopen",
description:"Reopen this ticket.",
defaultPermission:true,
descriptionLocalizations:ST.reopen,
type:act.ChatInput
},sid).then(() => {
readystats++
})
//claim
client.application.commands.create({
name:"claim",
description:"Claim this ticket / claim it for someone else.",
defaultPermission:true,
type:act.ChatInput,
options:[
{
name:"user",
type:acot.User,
required:false,
description:"The user to claim for."
}
]
},sid).then(() => {
readystats++
})
//unclaim
client.application.commands.create({
name:"unclaim",
description:"Unclaim this ticket.",
defaultPermission:true,
type:act.ChatInput
},sid).then(() => {
readystats++
})
}
-345
View File
@@ -1,345 +0,0 @@
const discord = require('discord.js')
const bot = require('../../index')
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const l = bot.language
const storage = bot.storage
const permsChecker = require("../utils/permisssionChecker")
const pendingDelete = []
/**
*
* @param {discord.GuildMember} member
* @param {discord.TextChannel} channel
* @param {String} prefix
* @param {"delete"|"close"|"deletenotranscript"} mode
* @param {Boolean} nomessage
* @param {String} reason only when closing, not when deleting!
*/
exports.NEWcloseTicket = async (member,channel,prefix,mode,reason,nomessage) => {
const guild = channel.guild
const user = member.user
const chalk = await (await import("chalk")).default
const channelmessages = await channel.messages.fetch()
const newReason = reason ? reason : l.messages.none
//start code
//FIX CHANNEL COULD BE CLOSED AFTER DELETE:
if (pendingDelete.includes(channel.id)) return false
//remove ot bot from transcript
channelmessages.sweep((msgSweep) => {return msgSweep.author.id == client.user.id})
/**@type {String}*/
const channelname = channel.name
const ticketOpenerChannelName = channelname.split(prefix)[1]
//get user that opened the ticket
var getuserID = storage.get("userTicketStorage",channel.id)
try {
var ticketOpener = client.users.cache.find(u => u.id === getuserID)
var isDatabaseError = false
}catch{var isDatabaseError = true}
if (!ticketOpener){
console.log(chalk.red("[database error]"),"something went wrong when getting the data in the database.\nNo panic, this error fixes itself!")
var isDatabaseError = true
}
var enableTranscript = true
var deleteRequired = false
if (mode == "delete"){
//delete
//check perms
if (!guild) return
if (!permsChecker.command(user.id,guild.id)){
permsChecker.sendUserNoPerms(user)
return
}
//start delete proccess
deleteRequired = true
if (!nomessage){
await channel.send({content:"**"+l.messages.gettingdeleted+"**"})
}
log("system","deleted a ticket",[{key:"user",value:user.tag},{key:"ticket",value:channel.name}])
pendingDelete.push(channel.id)
if (!isDatabaseError) storage.set("ticketStorage",getuserID,Number(storage.get("ticketStorage",getuserID)) - 1)
//getID & send DM & send api event
await channel.messages.fetchPinned().then(async msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return false
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value.value
const ticketData = require("../utils/configParser").getTicketById(ticketId,true)
require("../api/modules/events").onTicketDelete(user,channel,guild,new Date(),{name:channel.name,status:"deleted",ticketOptions:ticketData})
const id = hiddendata.data.find(d => d.key == "openerid").value
const sphd = bot.hiddenData.removeHiddenData(firstmsg.embeds[0].description)
sphd.hiddenData.data.push({key:"pendingdelete",value:"true"})
const newEmbed = new discord.EmbedBuilder(firstmsg.embeds[0].data)
newEmbed.setDescription(sphd.description + bot.hiddenData.writeHiddenData(sphd.hiddenData.type,sphd.hiddenData.data))
await firstmsg.edit({embeds:[newEmbed]})
if (!id) return false
try{
if (config.system.enable_DM_Messages){
member.send({embeds:[bot.errorLog.custom(l.messages.deletedTicketDmTitle,l.messages.deletedTicketDmDescription,":ticket:",config.main_color)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
})
}else if (mode == "close"){
//close
//check perms
if (config.system.closeMode == "adminonly"){
if (!guild) return
if (!permsChecker.command(user.id,guild.id)){
permsChecker.sendUserNoPerms(user)
return
}
}
//set new permissions
var permissionArray = []
const pfb = discord.PermissionFlagsBits
if (!isDatabaseError) permissionArray.push({
id:ticketOpener,
type:"member",
allow:[pfb.ViewChannel],
deny:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages]
})
permissionArray.push({
id:guild.roles.everyone,
type:"role",
deny:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
})
//add main adminroles
config.main_adminroles.forEach((role,index) => {
try {
const adminrole = guild.roles.cache.find(r => r.id == role)
if (!adminrole) return
permissionArray.push({
id:adminrole,
type:"role",
allow:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
})
}catch{
log("system","invalid role! At 'config.json => main_adminroles:"+index)
}
})
//add ticket adminroles
await channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return false
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
const ticketData = require("../utils/configParser").getTicketById(ticketId,true)
if (!ticketData) return
if (ticketData.closedCategory.enable){
/**@type {discord.CategoryChannel} */
const category = guild.channels.cache.find(c => c.id == ticketData.closedCategory.id && c.type == discord.ChannelType.GuildCategory)
try {
channel.setParent(category)
}catch{
bot.errorLog.log("system","failed to move channel to new category!")
}
}
/**
* @type {String[]}
*/
const ticketadmin = ticketData.adminroles
ticketadmin.forEach((role,index) => {
if (!config.main_adminroles.includes(role)){
try {
const adminrole = guild.roles.cache.find(r => r.id == role)
if (!adminrole) return
permissionArray.push({
id:adminrole,
type:"role",
allow:[pfb.AddReactions,pfb.ViewChannel],
deny:[pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages]
})
}catch{
log("system","invalid role! At 'config.json => options/ticket/...:"+index)
}
}
})
})
channel.permissionOverwrites.set(permissionArray)
if (!nomessage){
//message
var closeButtonRow = new discord.ActionRowBuilder()
.addComponents(
new discord.ButtonBuilder()
.setCustomId("OTdeleteTicket1")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Danger)
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("OTsendTranscript")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setLabel(l.buttons.sendTranscript)
.setEmoji("📄")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("OTreopenTicket")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Success)
.setLabel(l.buttons.reopen)
.setEmoji("✔")
)
const embed = new discord.EmbedBuilder()
.setColor(config.main_color)
.setTitle(":lock: "+l.messages.closedTitle+" :lock:")
.setDescription(l.messages.closedDescription)
channel.send({embeds:[embed],components:[closeButtonRow]})
}
log("system","closed a ticket",[{key:"user",value:user.tag},{key:"ticket",value:channel.name}])
//getID & send DM & send api event
await channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return false
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
const ticketData = require("../utils/configParser").getTicketById(ticketId,true)
require("../api/modules/events").onTicketClose(user,channel,guild,new Date(),{name:channel.name,status:"closed",ticketOptions:ticketData},newReason)
const id = hiddendata.data.find(d => d.key == "openerid").value
if (!id) return false
try{
if (config.system.enable_DM_Messages){
member.send({embeds:[bot.errorLog.custom(l.messages.closedTicketDmTitle,l.messages.closedTicketDmDescription+"\n\n**reason:** "+newReason,":ticket:",config.main_color)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
})
}else if (mode == "deletenotranscript"){
//delete with no transcript
//check perms
if (!guild) return
if (!permsChecker.command(user.id,guild.id)){
permsChecker.sendUserNoPerms(user)
return
}
//start delete proccess
enableTranscript = false
deleteRequired = true
if (!nomessage){
await channel.send({content:"**"+l.messages.gettingdeleted+"**"})
}
log("system","deleted a ticket",[{key:"user",value:user.tag},{key:"ticket",value:channel.name}])
if (!isDatabaseError) storage.set("ticketStorage",getuserID,Number(storage.get("ticketStorage",getuserID)) - 1)
//getID & send DM & send api event
await channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return false
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type").value
const ticketData = require("../utils/configParser").getTicketById(ticketId,true)
require("../api/modules/events").onTicketDelete(user,channel,guild,new Date(),{name:channel.name,status:"deleted",ticketOptions:ticketData})
const id = hiddendata.data.find(d => d.key == "openerid").value
if (!id) return false
try{
if (config.system.enable_DM_Messages){
member.send({embeds:[bot.errorLog.custom(l.messages.deletedTicketDmTitle,l.messages.deletedTicketDmDescription,":ticket:",config.main_color)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
})
}
if (enableTranscript == true && mode != "deletenotranscript"){
const transcriptReason = (mode == "close") ? "**"+l.messages.reason+":** "+newReason : "**"+l.messages.reason+":** "+l.messages.none
const closedByPrefix = (mode.startsWith("delete")) ? l.messages.deletedby : l.messages.closedby
if (config.system.enable_transcript || config.system.enable_DM_transcript){
var fileattachment = await require("../transcript").createTranscript(channelmessages,channel)
if (fileattachment == false){log("system","internal error: transcript is not created!");return}
}
if (config.system.enable_transcript && !require("../api/api.json").disable.transcripts.server){
const transcriptEmbed = new discord.EmbedBuilder()
.setColor(config.main_color)
.setTitle("📄 "+l.messages.newTranscriptTitle)
.setDescription(transcriptReason)
.setFooter({text:closedByPrefix+": "+user.tag+" | ticket: "+channelname,iconURL:user.displayAvatarURL()})
guild.channels.cache.find(c => c.id == config.system.transcript_channel).send({
embeds:[transcriptEmbed],
files:[fileattachment]
})
}
if (config.system.enable_DM_transcript && !require("../api/api.json").disable.transcripts.dm){
const transcriptEmbed = new discord.EmbedBuilder()
.setColor(config.main_color)
.setTitle("📄 "+l.messages.newTranscriptTitle)
.setDescription(transcriptReason)
.setFooter({text:closedByPrefix+": "+user.tag+" | ticket: "+channelname,iconURL:user.displayAvatarURL()})
if (!isDatabaseError) ticketOpener.send({
embeds:[transcriptEmbed],
files:[fileattachment]
})
}
}
if (deleteRequired){
//const timer = () => {return new Promise((resolve,reject) => {
// setTimeout(() => {resolve(true)},7000)
//})}
//await timer()
setTimeout(async () => {
pendingDelete.shift()
await channel.delete()
},6000)
}
}
-214
View File
@@ -1,214 +0,0 @@
const discord = require('discord.js')
const bot = require('../../index')
const client = bot.client
const config = bot.config
const l = bot.language
const log = bot.errorLog.log
const configParser = require("../utils/configParser")
const storage = bot.storage
module.exports = () => {
//dropdown placeholder
client.on("interactionCreate",(interaction) => {
if (!interaction.isSelectMenu()) return
if (interaction.customId != "OTdropdownMenu") return
if (interaction.values.includes("OTChooseTicket")) interaction.deferUpdate()
})
var closeButton = bot.buttons.firstmsg.firstmsgRowNormal
//ticket button click / create ticket
client.on("interactionCreate",async (interaction) => {
if (interaction.isChatInputCommand() && (interaction.commandName == "new" || interaction.commandName == "ticket")){
var customId = "OTnewT"+interaction.options.getString("type")
}else if (interaction.isButton()){
var customId = interaction.customId
}else if (interaction.isSelectMenu() && (interaction.customId == "OTdropdownMenu")){
var customId = interaction.values[0]
}else return
if (interaction.isButton()){
if (interaction.customId.startsWith("OTnewT")){
const optionid = interaction.customId.split("OTnewT")[1]
if (!optionid){
interaction.reply({embeds:[bot.errorLog.serverError(l.errors.ticketDoesntExist)]})
return
}
}
}
if (configParser.getTicketValuesArray("id").includes(customId)){
//ticketoptions from config
const currentTicketOptions = configParser.getTicketById(customId)
if (currentTicketOptions == false) return interaction.reply({embeds:[bot.errorLog.serverError(l.errors.anotherOption)]})
if (interaction.isButton()){
interaction.deferUpdate()
}else if (interaction.isChatInputCommand()){
interaction.reply({embeds:[bot.errorLog.success(l.messages.createdTitle,l.messages.createdDescription)]})
}else if (interaction.isSelectMenu()){
await interaction.deferUpdate()
}
if (storage.get("ticketStorage",interaction.member.id) == null || storage.get("ticketStorage",interaction.member.id) == "false"|| Number(storage.get("ticketStorage",interaction.member.id)) < config.system.max_allowed_tickets){
try{
if (config.system.enable_DM_Messages){
interaction.member.send({embeds:[bot.errorLog.custom(l.messages.newTicketDmTitle,currentTicketOptions.message,":ticket:",config.main_color)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
//update storage
storage.set("ticketStorage",interaction.member.id,Number(storage.get("ticketStorage",interaction.member.id))+1)
var ticketNumber = interaction.member.user.username
//set ticketName
var ticketName = currentTicketOptions.channelprefix+ticketNumber
var logsname = currentTicketOptions.name
//category
if (currentTicketOptions.category.length < 16 || currentTicketOptions.category.length > 20){
var newTicketCategory = null
}else{
var newTicketCategory = currentTicketOptions.category
}
var permissionsArray = []
const pfb = discord.PermissionFlagsBits
const guild = client.guilds.cache.find(g => g.id == interaction.guild.id)
//set everyone allowed
if (config.system['has@everyoneaccess']){
var everyoneAllowPerms = [pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
var everyoneDenyPerms = []
}else{
var everyoneAllowPerms = []
var everyoneDenyPerms = [pfb.ViewChannel]
}
permissionsArray.push({
id:interaction.guild.roles.everyone,
type:"role",
allow:everyoneAllowPerms,
deny:everyoneDenyPerms
})
//add the user that created the ticket
permissionsArray.push({
id:interaction.member.user,
type:"member",
allow:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
})
//add main adminroles
config.main_adminroles.forEach((role,index) => {
try {
const adminrole = guild.roles.cache.find(r => r.id == role)
if (!adminrole) return
permissionsArray.push({
id:adminrole,
type:"role",
allow:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
})
}catch{
log("system","invalid role! At 'config.json => main_adminroles:"+index)
}
})
//add ticket adminroles
/**
* @type {String[]}
*/
const ticketadmin = currentTicketOptions.adminroles
ticketadmin.forEach((role,index) => {
if (!config.main_adminroles.includes(role)){
try {
const adminrole = guild.roles.cache.find(r => r.id == role)
if (!adminrole) return
permissionsArray.push({
id:adminrole,
type:"role",
allow:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
})
}catch{
log("system","invalid role! At 'config.json => options/ticket/...:"+index)
}
}
})
//add member role
if (config.system.member_role != "" && config.system.member_role != " " && config.system.member_role != "false" && config.system.member_role != "null" && config.system.member_role != "0"){
try {
const userrole = guild.roles.cache.find(r => r.id == config.system.member_role)
if (!userrole) return
permissionsArray.push({
id:userrole,
type:"role",
deny:[pfb.ViewChannel]
})
}catch{
log("system","invalid role! At 'config.json => system/member_role")
}
}
//create the channel
interaction.guild.channels.create({
name:ticketName,
type:discord.ChannelType.GuildText,
parent:newTicketCategory,
reason:"A new ticket is created",
permissionOverwrites:permissionsArray
}).then((ticketChannel) => {
storage.set("userTicketStorage",ticketChannel.id,interaction.member.id)
const hiddendata = bot.hiddenData.writeHiddenData("ticketdata",[{key:"type",value:currentTicketOptions.id},{key:"openerid",value:interaction.user.id},{key:"createdms",value:new Date().getTime()}])
var ticketEmbed = new discord.EmbedBuilder()
//.setAuthor({name:interaction.user.id})
.setColor(config.main_color)
.setTitle(currentTicketOptions.name)
//.setFooter({text:"Ticket Type: "+currentTicketOptions.id})
if (currentTicketOptions.ticketmessage.length > 0){
ticketEmbed.setDescription(currentTicketOptions.ticketmessage+hiddendata)
}else{
ticketEmbed.setDescription(hiddendata)
}
if (currentTicketOptions.thumbnail.enable) ticketEmbed.setThumbnail(currentTicketOptions.thumbnail.url)
ticketChannel.send({
content:"<@"+interaction.member.id+"> @here",
embeds:[ticketEmbed],
components:[closeButton]
}).then(firstmsg => {
firstmsg.pin()
})
log("system","created new ticket",[{key:"ticket",value:ticketName},{key:"user",value:interaction.user.tag}])
require("../api/modules/events").onTicketOpen(interaction.user,ticketChannel,interaction.guild,new Date(),{name:ticketName,status:"open",ticketOptions:currentTicketOptions})
})
}else{
try {
if (config.system.enable_DM_Messages){
interaction.member.send({embeds:[bot.errorLog.warning(l.errors.maxAmountTitle,l.errors.maxAmountDescription)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
}
}
})
}
-52
View File
@@ -1,52 +0,0 @@
const discord = require('discord.js')
const bot = require('../../index')
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const l = bot.language
const storage = bot.storage
const pfb = discord.PermissionFlagsBits
/**
*
* @param {discord.Guild} guild
* @param {discord.TextBasedChannel} channel
* @param {discord.User} user
* @returns
*/
const reopenTicket = (guild,channel,user) => {
log("system","re-opened a ticket",[{key:"ticket",value:channel.name},{key:"user",value:user.tag}])
var permissionsArray = []
//set everyone allowed
if (config.system['has@everyoneaccess']){
var everyoneAllowPerms = [pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
var everyoneDenyPerms = []
}else{
var everyoneAllowPerms = []
var everyoneDenyPerms = [pfb.ViewChannel]
}
permissionsArray.push({
id:guild.roles.everyone,
type:"role",
allow:everyoneAllowPerms,
deny:everyoneDenyPerms
})
channel.permissionOverwrites.cache.forEach((p) => {
if (p.type == 1){
permissionsArray.push({
id:p.id,
type:"member",
allow:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel],
deny:[]
})
}
})
channel.permissionOverwrites.set(permissionsArray)
require("../api/modules/events").onTicketReopen(user,channel,guild,new Date(),{name:channel.name,status:"reopened",ticketOptions:false})
}
exports.reopenTicket = reopenTicket
-75
View File
@@ -1,75 +0,0 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const l = bot.language
/** @param {discord.TextBasedChannel} channel @returns {Promise<{ticketname:String,ticketopener:{discordjsuser:discord.User,name:String,id:String}>} */
const getUserInfo = (channel) => {
return new Promise((promiseresolve,reject) => {
//getID
var result = {
ticketopener:{
discordjsuser:"",
id:"/",
name:"/"
},
ticketname:"/"
}
channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return false
const hiddendata = bot.hiddenData.readHiddenData(firstmsg.embeds[0].description)
const ticketId = hiddendata.data.find(d => d.key == "type")
const id = hiddendata.data.find(d => d.key == "openerid").value
result.ticketopener.id = id
const ticketopener = client.users.cache.find(u => u.id == id)
const name = ticketopener.tag
const channelname = channel.name
promiseresolve({ticketname:channelname,ticketopener:{discordjsuser:ticketopener,name:name,id:id}})
})
})
}
/**
*
* @param {discord.Message[]} messagecollection
* @param {discord.Channel} channel
* @returns new `discord.attachmentBuilder`
*/
exports.createTranscript = async (messagecollection,channel) => {
const ticketuserdata = await getUserInfo(channel)
require("./api/modules/events").onTranscriptCreation(messagecollection,channel,channel.guild,new Date())
try {
const cd = new Date()
const months = ["January","February","March","April","May","June","July","August","September","October","November","December"]
const dateString = cd.getDate()+" "+months[cd.getMonth()-1]+" "+cd.getFullYear()+" - "+cd.getHours()+":"+cd.getMinutes()+":"+cd.getSeconds()
const filearray = ["open ticket transcript:\ntranscript creation: "+dateString+"\nticket name: "+ticketuserdata.ticketname+"\nticket opener: "+ticketuserdata.ticketopener.name,"\nTRANSCRIPT START:"]
messagecollection.reverse()
messagecollection.forEach((msg) => {
const timestamp = new Date(msg.createdTimestamp)
if (msg.content){var content = msg.content}else{var content = "*empty message*"}
const msgstats = "files: "+msg.attachments.size+", embeds: "+msg.embeds.length
filearray.push("["+timestamp.getDate()+"/"+timestamp.getMonth()+"/"+timestamp.getFullYear()+", "+timestamp.getHours()+":"+timestamp.getMinutes()+":"+timestamp.getSeconds()+"|"+msg.author.tag+"] ["+msgstats+"]\n"+content+"\n")
})
if (filearray.length < 2) filearray.push("transcript is empty")
const filestring = filearray.join("\n")
const filebuff = Buffer.from(filestring,"utf-8")
return new discord.AttachmentBuilder(filebuff,{name:"transcript_"+ticketuserdata.ticketname+".txt",description:"An Open Ticket transcript"})
}catch(err){
console.log("[error] "+err)
return false
}
}
-187
View File
@@ -1,187 +0,0 @@
const bot = require("../../index")
const config = bot.config
const l = bot.language
//TYPEDEFS:
//==================
//OTTicketOptions
/**@typedef {{id: String,name: String,description: String,icon: String,label: String,type: "ticket"|"role"|"website",color: "red"|"green"|"blue"|"gray",adminroles: String[],channelprefix: String,category: String,message: String,enableDmOnOpen: Boolean,ticketmessage: String, thumbnail:{enable:Boolean,url:String}, closedCategory:{enable:Boolean,id:String}}} OTTicketOptions */
//OTRoleOptions
/**@typedef {{id: String,name: String,description: String,icon: String,label: String,type: "ticket"|"role"|"website",color:"red"|"green"|"blue"|"gray"|"none",roles:String[],mode:"add&remove"|"remove"|"add",enableDmOnOpen:Boolean}} OTRoleOptions */
//OTWebsiteOptions
/**@typedef {{id: String,name: String,description: String,icon: String,label: String,type: "ticket"|"role"|"website",url:String}} OTWebsiteOptions */
//OTConfigMessage
/**@typedef {{id: string, name: string, description: string, dropdown: boolean, enableFooter: boolean, footer: string, enableThumbnail: boolean, thumbnail: string, enableCustomColor: boolean, color: string, options: string[], enableTicketExplaination: boolean, enableMaxTicketsWarning: boolean}} OTConfigMessage*/
//StringOptions
/**@typedef {"id"|"name"|"description"|"icon"|"label"|"type"|"color"|"adminroles"|"channelprefix"|"category"|"message"|"enableDmOnOpen"|"ticketmessage"|"thumbnail"|"closedCategory"} OTTicketStringOptions */
/**@typedef {"id"|"name"|"description"|"icon"|"label"|"type"|"color"|"roles"|"mode"|"enableDmOnOpen"} OTRoleStringOptions */
/**@typedef {"id"|"name"|"description"|"icon"|"label"|"type"|"url"} OTWebsiteStringOptions */
//FUNCTIONS:
//==================
/** @param {String} id the id of the embed @returns {OTConfigMessage}*/
exports.getConfigMessage = (id) => {
var returned = config.messages.find(a => a.id == id)
if (returned){
return returned
}
var result = config.messages[0]
if (!result){
throw new Error("'messages' object in config.json is empty")
return
}
return result
}
/**
*
* @param {String} id
* @param {Boolean} withoutOTnewT
* @returns {OTTicketOptions|false}
*/
exports.getTicketById = (id,withoutOTnewT) => {
var result = false
if (withoutOTnewT){
config.options.forEach((option) => {
if (option.id == id && option.type == "ticket"){
result = option
}
})
}else{
config.options.forEach((option) => {
if ("OTnewT"+option.id == id && option.type == "ticket"){
result = option
}
})
}
return result
}
/**
*
* @param {String} id
* @param {Boolean} withoutOTnewR
* @returns {OTRoleOptions|false}
*/
exports.getRoleById = (id,withoutOTnewR) => {
var result = false
if (withoutOTnewR){
config.options.forEach((option) => {
if (option.id == id && option.type == "role"){
result = option
}
})
}else{
config.options.forEach((option) => {
if ("OTnewR"+option.id == id && option.type == "role"){
result = option
}
})
}
return result
}
/**
*
* @param {String} id
* @returns {OTWebsiteOptions|false}
*/
exports.getWebsiteById = (id) => {
var result = false
config.options.forEach((option) => {
if (option.id == id && option.type == "website"){
result = option
}
})
return result
}
/**
* @param {OTTicketStringOptions} value
* @returns {String[]}
*/
exports.getTicketValuesArray = (value,idWithoutOTnewT) => {
var result = []
const prefix = idWithoutOTnewT ? "" : "OTnewT"
config.options.forEach((opt) => {
if (opt.type == "ticket"){
if (value == "id"){
result.push(prefix+opt[value])
}else{
result.push(opt[value])
}
}
})
return result
}
/**
* @param {OTRoleStringOptions} value
* @returns {String[]}
*/
exports.getRoleValuesArray = (value,idWithoutOTnewR) => {
var result = []
const prefix = idWithoutOTnewR ? "" : "OTnewR"
config.options.forEach((opt) => {
if (o.type == "role"){
if (value == "id"){
result.push(prefix+opt[value])
}else{
result.push(opt[value])
}
}
})
return result
}
/**
* @param {OTWebsiteStringOptions} value
* @returns {String[]}
*/
exports.getWebsiteValuesArray = (value) => {
var result = []
config.options.forEach((opt) => {
if (o.type == "website"){
result.push(opt[value])
}
})
return result
}
/**@type {OTTicketOptions} */
this.ticketType = {}
/**@type {OTRoleOptions} */
this.roleType = {}
/**@type {OTWebsiteOptions} */
this.websiteType = {}
/**@type {OTConfigMessage} */
this.messageType = {}
//OTAllOptions
/**@typedef {{id: String,name: String,description: String,icon: String,label: String,type: "ticket"|"role"|"website",color:"red"|"green"|"blue"|"gray"|"none",roles:String[],mode:"add&remove"|"remove"|"add",adminroles: String[],channelprefix: String,category: String,message: String,enableDmOnOpen: Boolean,ticketmessage: String, thumbnail:{enable:Boolean,url:String}, url:String, closedCategory:{enable:Boolean,id:String}}} OTAllOptions */
/**
*
* @param {String} id
* @returns {Boolean}
*/
exports.optionExists = (id) => {
var result = false
config.options.forEach((option) => {
if (option.id == id){
result = true
}
})
return result
}
-94
View File
@@ -1,94 +0,0 @@
const discord = require("discord.js")
const bot = require("../../index")
const config = bot.config
const l = bot.language
/**@returns {"DANGER"|"SUCCESS"|"PRIMARY"|"SECONDARY"} */
const getColor = (color) => {
const b = discord.ButtonStyle
if (color.toLowerCase() == "red"){
return b.Danger
}else if (color.toLowerCase() == "green"){
return b.Success
}else if (color.toLowerCase() == "blue" || color.toLowerCase() == "blurple"){
return b.Primary
}else if (color.toLowerCase() == "black" || color.toLowerCase() == "gray" || color.toLowerCase() == "grey"){
return b.Secondary
}else if (color == "DANGER" || color == "SECONDARY" || color == "SUCCESS" || color == "PRIMARY"){
return color
}else if (color.toLowerCase() == "none" || color.toLowerCase() == "false" || color.toLowerCase() == ""){
return b.Secondary
}else return b.Secondary
}
const getOption = (id) => {
const result = config.options.find((option) => option.id == id)
if (!result){return false}else return result
}
exports.getOption = getOption
/**
*
* @param {String} id
* @returns {discord.ButtonBuilder|false}
*/
exports.getButton = (id) => {
const option = getOption(id)
if (!option) return false
if (option.type == "ticket"){
var button = new discord.ButtonBuilder()
.setCustomId("OTnewT"+option.id)
.setDisabled(false)
.setStyle(getColor(option.color))
if (option.label){button.setLabel(option.label)}
if (option.icon){button.setEmoji(option.icon)}
if (!option.label && !option.icon){button.setLabel("no label or emoji")}
}else if (option.type == "website"){
var button = new discord.ButtonBuilder()
.setDisabled(false)
.setStyle(discord.ButtonStyle.Link)
.setURL(option.url)
if (option.label){button.setLabel(option.label)}
if (option.icon){button.setEmoji(option.icon)}
if (!option.label && !option.icon){button.setLabel("no label or emoji")}
}else if (option.type == "role"){
var button = new discord.ButtonBuilder()
.setCustomId("newR"+option.id)
.setDisabled(false)
.setStyle(getColor(option.color))
if (option.label){button.setLabel(option.label)}
if (option.icon){button.setEmoji(option.icon)}
if (!option.label && !option.icon){button.setLabel("no label or emoji")}
}
return button
}
exports.rawButtonData = class {
constructor() {
this.id = ""
this.name = ""
this.description = ""
this.icon = ""
this.label = ""
this.type = ""
this.color = ""
this.enableDmOnOpen = true
this.url = ""
this.roles = ["",""]
this.mode = ""
this.adminroles = ["",""]
this.channelprefix = ""
this.category = ""
this.message = ""
this.ticketmessage = ""
}
}
-46
View File
@@ -1,46 +0,0 @@
const discord = require("discord.js")
const bot = require("../../index")
const config = bot.config
const l = bot.language
const configParser = require("./configParser")
/**
*
* @param {String[]} ids
* @returns {discord.SelectMenuBuilder|false}
*/
exports.getDropdown = (ids) => {
const dropdown = new discord.SelectMenuBuilder()
.setCustomId("OTdropdownMenu")
.setDisabled(false)
.setMaxValues(1)
.setMinValues(1)
.setPlaceholder(l.messages.chooseATicket)
.addOptions(
new discord.SelectMenuOptionBuilder()
.setDefault(true)
.setLabel(l.messages.chooseATicket)
.setValue("OTChooseTicket")
)
ids.forEach((id) => {
const option = configParser.getTicketById(id,true)
if (option){
const selectComponent = new discord.SelectMenuOptionBuilder()
.setDefault(false)
.setValue("OTnewT"+option.id)
if (!option.label && !option.icon){
selectComponent.setLabel("OT ERROR: no description/emoji")
}else{
if (option.label) selectComponent.setLabel(option.label)
if (option.icon) selectComponent.setEmoji(option.icon)
}
dropdown.addOptions(selectComponent)
}
})
return dropdown
}
-111
View File
@@ -1,111 +0,0 @@
const discord = require('discord.js')
const bot = require('../../index')
const client = bot.client
const config = bot.config
const getButton = require("./getButton")
const l = bot.language
/**
*
* @param {String} id the id from an open-ticket embed
* @returns {{embed:discord.EmbedBuilder,componentRows:discord.MessageActionRow[]}} discord embed
*/
exports.createEmbed = (id) => {
//-----------------------------------
//general importing
const data = require("./configParser").getConfigMessage(id)
/**@type {discord.ButtonBuilder[]}*/
var buttons = []
/**@type {getButton.rawButtonData[]} */
var buttonData = []
data.options.forEach((option) => {
var button = getButton.getButton(option)
var localButtonData = getButton.getOption(option)
if (button) buttons.push(button)
if (localButtonData) buttonData.push(localButtonData)
})
//-----------------------------------
//-----------------------------------
//create the embed
const embed = new discord.EmbedBuilder()
.setTitle(data.name)
if (data.enableFooter) embed.setFooter({text:data.footer})
if (data.enableThumbnail) embed.setThumbnail(data.thumbnail)
if (data.enableCustomColor){
embed.setColor(data.color)
}else{
embed.setColor(config.main_color)
}
var description = data.description
if (data.enableTicketExplaination){
description = description+"\n\n__"+l.messages.chooseCategory+"__\n"
var ticketExplainations = []
buttonData.forEach((button) => {
var explaination = button.icon+" **"+button.name+":**\n"+button.description
ticketExplainations.push(explaination)
})
description = description+ticketExplainations.join("\n\n")
}
if (data.enableMaxTicketsWarning){
description = description+"\n\n"+l.commands.maxTicketWarning.replace("{0}",config.system.max_allowed_tickets)
}
if (description) embed.setDescription(description)
//-----------------------------------
//-----------------------------------
//create the components IF DROPDOWN IS FALSE
if (!data.dropdown){
var AmountOfRows = Math.ceil(buttons.length / 4)
var currentRow = 0
/**
* @type {discord.MessageActionRow[]}
*/
var componentRows = []
for (let i = AmountOfRows; i > 0; i--){
componentRows.push(new discord.ActionRowBuilder())
}
buttons.forEach((button,index) => {
componentRows[currentRow].addComponents([button])
if (index == 3 || index == 7 || index == 11 || index == 15 || index == 19 || index == 23 || index == 27 || index == 31 || index == 35 || index == 39){
currentRow = currentRow + 1
}
})
//create the component IF DROPDOWN is true
}else{
const ids = data.options
const dropdown = require("./getDropdown").getDropdown(ids)
var componentRows = [
new discord.ActionRowBuilder()
.setComponents(dropdown)
]
}
//-----------------------------------
//return everything
/**
* @type {{embed:discord.EmbedBuilder,componentRows:discord.MessageActionRow[]}}
*/
const returnedData = {embed:embed,componentRows:componentRows}
return returnedData
}
-66
View File
@@ -1,66 +0,0 @@
/**@typedef {{type:String,data:[{key:String,value:String}]}} hiddenData */
/**
*
* @param {String} messageContent
* @returns {hiddenData}
*/
exports.readHiddenData = (messageContent) => {
//ticketdata//type:123|userid:456)
const rawhidden = messageContent.split("[ ](OTDATA|")[1]
const rawhidden2 = rawhidden.split("//")
const datatype = rawhidden2[0]
var rawhiddendata = rawhidden2[1]
var rawhiddendataArray = rawhiddendata.split("")
rawhiddendataArray.pop()
rawhiddendata = rawhiddendataArray.join("")
const splittedData = rawhiddendata.split("|")
const resultData = []
splittedData.forEach((data) => {
// type:123
const dataresult = data.split(":")
resultData.push({key:dataresult[0],value:dataresult[1]})
})
return {type:datatype,data:resultData}
}
/**
*
* @param {String} type
* @param {[{key:String,value:String}]} data
* @returns {String}
*/
exports.writeHiddenData = (type,data) => {
const dataValues = []
data.forEach((d) => {
dataValues.push(d.key+":"+d.value)
})
const datastring = dataValues.join("|")
const result = "[ ](OTDATA|"+type+"//"+datastring+")"
return result
}
/**
*
* @param {String} description
* @returns {{description:String,hiddenData:hiddenData}}
*/
exports.removeHiddenData = (description) => {
const hiddenData = this.readHiddenData(description)
const splitted = description.split("[ ](OTDATA")
const original = splitted[0]
return {description:original,hiddenData:hiddenData}
}
-15
View File
@@ -1,15 +0,0 @@
const discord = require('discord.js')
const bot = require('../../index')
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const loadChalk = async () => {
return await (await import("chalk")).default
}
module.exports = async () => {
const chalk = await loadChalk()
//LIVESTATUS SOON
}
-107
View File
@@ -1,107 +0,0 @@
const discord = require('discord.js')
const bot = require('../../index')
const client = bot.client
const config = bot.config
const log = bot.errorLog.log
const l = bot.language
const storage = bot.storage
/**
*
* @param {String} memberid
* @param {String} guildid
* @returns {Boolean} has permissions?
*/
exports.command = (memberid,guildid) => {
const permsmember = client.guilds.cache.find(g => g.id == guildid).members.cache.find(m => m.id == memberid)
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("Administrator") && !permsmember.permissions.has("ManageGuild")){
return false
}else {return true}
}
/**
*
* @param {discord.User} user
* @returns {Boolean}
*/
exports.sendUserNoPerms = (user) => {
try {
user.send({embeds:[bot.errorLog.noPermsMessage(user)]})
return true
}catch{
return false
}
}
/**
*
* @param {discord.User} user
* @returns {Boolean}
*/
exports.sendUserNoTicket = (user) => {
try {
user.send({embeds:[bot.errorLog.notInATicket]})
return true
}catch{
return false
}
}
/**
*
* @param {discord.User} user
* @returns {Boolean}
*/
exports.sendUserNoDelete = (user) => {
try {
user.send({embeds:[bot.errorLog.noPermsDelete(user)]})
return true
}catch{
return false
}
}
/**
*
* @param {discord.TextChannel} channel
* @param {discord.User} user
* @returns {Boolean}
*/
exports.sendChannelNoPerms = (channel,user) => {
try {
channel.send({embeds:[bot.errorLog.noPermsMessage(user)]})
return true
}catch{
return false
}
}
/**
*
* @param {discord.TextChannel} channel
* @param {discord.User} user
* @returns {Boolean}
*/
exports.sendChannelNoTicket = (channel,user) => {
try {
channel.send({embeds:[bot.errorLog.notInATicket]})
return true
}catch{
return false
}
}
/**
*
* @param {discord.TextChannel} channel
* @param {discord.User} user
* @returns {Boolean}
*/
exports.sendChannelNoDelete = (channel,user) => {
try {
channel.send({embeds:[bot.errorLog.noPermsDelete(user)]})
return true
}catch{
return false
}
}
+1
View File
@@ -0,0 +1 @@
[]
+1
View File
@@ -0,0 +1 @@
[]
+1
View File
@@ -0,0 +1 @@
[]
+1
View File
@@ -0,0 +1 @@
[]
+1
View File
@@ -0,0 +1 @@
[]
+1
View File
@@ -0,0 +1 @@
[]
+27 -239
View File
@@ -1,243 +1,31 @@
// __________ __________ ___________ ____ ____ /////////////// STARTUP FLAGS ///////////////
// / ____ \ / ______ \ / | | \ | | const flags = [
// | / \ | | | | | | |_______| | \ | | // Edit flags here when being unable to use the flags in the command prompt.
// | | | | | |____| | | | | |\ \ | | //PTERODACTYL PANEL
// | | | | | ________/ | |______ | | \ \ | | //add startup flags here (e.g. "--no-compile") when running via the panel
// | | | | | | | _____| | | \ \ | | ]
// | | | | | | | | | | \ \ | | /////////////// STARTUP FLAGS ///////////////
// | | | | | | | |________ | | \ \| |
// | \____/ | | | | | | | \ |
// \__________/ |__| \__________| |__| \___|
const discord = require("discord.js") /*
const fs = require('fs') ██████╗ ██████╗ ███████╗███╗ ██╗ ████████╗██╗ ██████╗██╗ ██╗███████╗████████╗
const {GatewayIntentBits,Partials} = discord ██╔═══██╗██╔══██╗██╔════╝████╗ ██║ ╚══██╔══╝██║██╔════╝██║ ██╔╝██╔════╝╚══██╔══╝
const APIBase = require("./core/api/modules/base") ██║ ██║██████╔╝█████╗ ██╔██╗ ██║ ██║ ██║██║ █████╔╝ █████╗ ██║
if (APIBase.embeddedMode){ ██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║ ██║ ██║██║ ██╔═██╗ ██╔══╝ ██║
var tempClient = APIBase.clientLocation ╚██████╔╝██║ ███████╗██║ ╚████║ ██║ ██║╚██████╗██║ ██╗███████╗ ██║
}else{ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═╝
var tempClient = new discord.Client({ v4.2.1 - Made by DJj123dj & Contributors
intents:[
GatewayIntentBits.DirectMessages,
GatewayIntentBits.GuildInvites,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.Guilds,
GatewayIntentBits.MessageContent
],
partials:[Partials.Channel,Partials.Message]
})
}
/**@type {discord.Client} */
const client = tempClient
exports.client = client
client.setMaxListeners(50)
if (process.argv.some((v) => v == "--debug")) console.log("[TEMP_DEBUG]","created client")
var tempconfig = require("./config.json") Discord: https://discord.dj-dj.be
/**@type {Boolean} */ Docs: https://otdocs.dj-dj.be
var isDevConfig = false Support Us: https://github.com/sponsors/DJj123dj/
*/
if (process.argv.some((v) => v == "--devconfig")){ ///////////////////////////////////////////
async function logFLAGS(){ ////////// COMPILATION + STARTUP //////////
const chalk = await (await import("chalk")).default ///////////////////////////////////////////
console.log(chalk.blue("[FLAGS] => used dev config instead of normal config"))
}; logFLAGS()
isDevConfig = true
try{
tempconfig = require("./devConfig.json")
}catch{tempconfig = require("./config.json")}
}else{
tempconfig = require("./config.json")
}
if (process.argv.some((v) => v == "--nochecker")){
async function logFLAGS(){
const chalk = await (await import("chalk")).default
console.log(chalk.blue("[FLAGS] => disabled checker.js"))
}; logFLAGS()
}
if (process.argv.some((v) => v == "--debug")){
async function logFLAGS(){
const chalk = await (await import("chalk")).default
console.log(chalk.blue("[FLAGS] => enabled DEBUG mode"))
}; logFLAGS()
}
if (process.argv.some((v) => v == "--debug")) console.log("[TEMP_DEBUG]","loaded flags")
exports.developerConfig = isDevConfig import { frameworkStartup } from "@open-discord-bots/framework"
const language = require("./core/languageManager").language frameworkStartup(flags,"openticket",async () => {
exports.language = language await import("./dist/src/index.js")
if (process.argv.some((v) => v == "--debug")) console.log("[TEMP_DEBUG]","loaded language") })
const config = tempconfig
exports.config = config
if (process.argv.some((v) => v == "--debug")) console.log("[TEMP_DEBUG]","loaded config")
exports.storage = require('./core/dynamicdatabase/storage')
if (process.argv.some((v) => v == "--debug")) console.log("[TEMP_DEBUG]","loaded storage")
exports.errorLog = require("./core/errorLogSystem")
const log = this.errorLog.log
if (process.argv.some((v) => v == "--debug")) console.log("[TEMP_DEBUG]","LOADED LOGGING SYSTEM")
if (process.argv.some((v) => v == "--debug")) console.log("[TEMP_DEBUG]","switching to new logs")
this.errorLog.log("debug","loaded new logs")
exports.hiddenData = require("./core/utils/hiddendata")
this.errorLog.log("debug","loaded hiddendataTM")
exports.embeds = {
commands:require("./core/interactionHandlers/embeds/commands")
}
exports.buttons = {
close:require("./core/interactionHandlers/buttons/close"),
firstmsg:require("./core/interactionHandlers/buttons/firstmsg"),
verifybars:require("./core/interactionHandlers/buttons/verifyBars")
}
this.errorLog.log("debug","loaded buttons & embeds")
client.on('ready',async () => {
this.errorLog.log("debug","client logged in")
var statusSet = false
const setStatus = (type,text) => {
if (statusSet == true) return
const getTypeEnum = (text) => {
if (text.toLowerCase() == "playing") return discord.ActivityType.Playing
else if (text.toLowerCase() == "listening") return discord.ActivityType.Listening
else if (text.toLowerCase() == "watching") return discord.ActivityType.Watching
else return discord.ActivityType.Listening
}
client.user.setActivity(text,{type:getTypeEnum(type)})
statusSet = true
log("system","loaded status",[{key:"type",value:type},{key:"text",value:text}])
}
this.errorLog.log("debug","bot status loaded")
const chalk = await (await import("chalk")).default
if (!process.argv[2]){
console.log(chalk.red("WELCOME TO OPEN TICKET!"))
this.errorLog.log("debug","loaded console interface")
log("info","open ticket ready",[{key:"version",value:require("./package.json").version},{key:"language",value:config.languagefile}])
require("./core/utils/liveStatus")()
console.log(chalk.blue("\n\nlogs:")+"\n============")
if (config.status.enabled){
setStatus(config.status.type,config.status.text)
}
log("system","bot logged in!")
await client.guilds.cache.find((g) => g.id == config.server_id).members.fetch()
return
}
if (process.argv[2] == "d"){
if (config.status.enabled){
setStatus(config.status.type,config.status.text)
}
}
if (!process.argv[2].startsWith("slash")){
console.log(chalk.red("WELCOME TO OPEN TICKET!"))
this.errorLog.log("debug","loaded console interface")
log("info","open ticket ready",[{key:"version",value:require("./package.json").version},{key:"language",value:config.languagefile}])
require("./core/utils/liveStatus")()
console.log(chalk.blue("\n\nlogs:")+"\n============")
if (config.status.enabled){
setStatus(config.status.type,config.status.text)
}
log("system","bot logged in!")
await client.guilds.cache.find((g) => g.id == config.server_id).members.fetch()
}else{
console.log(chalk.red("STARTING IN ")+chalk.blue("SLASH MODE")+chalk.red("..."))
this.errorLog.log("debug","slashmode activated")
console.log("logs:\n================")
console.log("client logged in...")
console.log("loading files...")
if (process.argv[3] == "enable"){
console.log(chalk.green("switching to slashEnable.js"))
require("./core/slashSystem/slashEnable")()
}else if (process.argv[3] == "disable"){
console.log(chalk.green("switching to slashDisable.js"))
require("./core/slashSystem/slashDisable")()
}else{
console.log(chalk.red("Internal Error: unknown slash mode!"))
process.exit(1)
}
}
//load plugins
require("./core/api/pluginlauncher")()
this.errorLog.log("debug","loading plugins")
})
if (!require("./core/api/api.json").disable.checkerjs.all) require("./core/checker").checker()
this.errorLog.log("debug","loading checker.js")
this.errorLog.log("debug","checking config...")
if (process.argv[2] && process.argv[2].startsWith("slash")){
//do nothing
}else{
this.errorLog.log("debug","LOADING COMMANDS")
//commands
require('./commands/ticket')()
require("./commands/help")()
require("./commands/close")()
require("./commands/delete")()
require("./commands/rename")()
require("./commands/add")()
require("./commands/remove")()
require("./commands/reopen")()
require("./commands/claim")()
require("./commands/unclaim")()
this.errorLog.log("debug","LOADING CORE")
//core
require('./core/ticketActions/ticketOpener')()
require("./core/reactionRoles")()
this.errorLog.log("debug","LOADING INTERACTION HANDLERS")
//InteractionHandlers
require("./core/interactionHandlers/handlers/handlers")()
//require("./test")()
}
this.errorLog.log("debug","loading api")
const APIEvents = require("./core/api/modules/events")
const APIConfig = require("./core/api/api.json")
const debugLog = (debugString) => {
if (!APIConfig.disable.debug.all && !APIConfig.disable.debug.debuglogs){
const content = fs.existsSync("./openticketdebug.txt") ? fs.readFileSync("./openticketdebug.txt").toString() : "==========================\n<OPEN TICKET DEBUG FILE:>\n=========================="
fs.writeFileSync("./openticketdebug.txt",content+"\nDEBUG: "+debugString)
}
}
const errorLog = (errorString,stack) => {
if (!APIConfig.disable.debug.all){
const content = fs.existsSync("./openticketdebug.txt") ? fs.readFileSync("./openticketdebug.txt").toString() : "==========================\n<OPEN TICKET DEBUG FILE:>\n=========================="
fs.writeFileSync("./openticketdebug.txt",content+"\nERROR: "+errorString+" STACK: "+stack)
}
}
this.errorLog.log("debug","OT error system loaded successfully")
client.on("debug", async (message) => {
if (message.startsWith("Provided token:")){
debugLog("Provided token: ***********bot token is invisible**************...")
return
}
debugLog(message)
});
process.on("uncaughtException",async (error,origin) => {
const chalk = await (await import("chalk")).default
console.log(chalk.red("\nOPEN TICKET ERROR: ")+error+"\n"+chalk.green("\nCreate a ticket in our support server for more information!\nIf you do this, you might help us to avoid a future bug!\n"))
errorLog(error.name+": "+error.message+" | origin: "+origin,error.stack)
APIEvents.onError(error.name+": "+error.message,new Date())
})
if (!APIBase.embeddedMode) client.login(config.auth_token)
this.errorLog.log("debug","login with token")
-83
View File
@@ -1,83 +0,0 @@
{
"errors": {
"missingArgsTitle": "قيمة غير صالحة!",
"missingArgsDescription": "قيمة مفقودة",
"noPermsTitle": "ليس لديك برمشنات !",
"noPermsDescription": "أنت بحاجة الى برمشن `ADMINISTRATOR` او أن تكون في قائمة المسموح بهم!",
"noPermsDelete": "فقط الإداريين يمكنهم حذف التكت!",
"chooseFromListTitle": "Invalid ID",
"chooseFromListDescription": "قم بأختيار أحد من الأيديات من الأسفل:",
"boterror": "خلل في البوت !",
"notInTicketTitle": "انت لست في تكت!",
"notInTicketDescription": "هذا الأمر لا يعمل خارج التكت!",
"ticketDoesntExist": "هذا التكت لم يعد فعال!",
"roleDoesntExist": "خطاً ,لم تعد الرتبة موجوده!",
"anotherOption": "هذا الخيار ليس التكت و لكنه شيء أخر!",
"maxAmountTitle": "خطأ , تم الوصول الى الحد الأقصى!",
"maxAmountDescription": "لقد وصلت الى الحد الأقصى لعدد التكتات المسموحة بها!\nSo لا يمكنك فتح واحدة أخرى!",
"somethingWentWrong": "**هناك خطاً!**\nأعد المحاولة لاحقاً!",
"somethingWentWrongTranscript": "هناك خطاً في محاولة طبع التكت!**\nأعد المحاولة لاحقاً!"
},
"commands": {
"userAddedTitle": "تم أضافة {0} من المستخدمين في التكت!",
"userRemovedTitle": "تم أزالة {0} من المستخدمين من التكت!",
"renameTitle": "تم تغيير أسم التكت الى {0}!",
"closeTitle": "تم أغلاق التكت!",
"deleteTitle": " جاري حذف التكت...",
"reopenTitle": "إعادة فتح التكت!",
"claimTitle":"This ticket is now claimed to {0}",
"unclaimTitle":"This ticket isn't claimed anymore!",
"ticketWarning": "هذا الأمبد موجود بالفعل في الرسالة بالأسفل!",
"maxTicketWarning": "**تحذير:** _يمكنك فقط فتح {0} تكت في الوقت!_"
},
"helpMenu": {
"title": "الأوامر المتاحة:",
"header1": "**أذهب الى {0} لإنشاء تذكرة!**\n\n",
"header2": "**قم بكتابة أمر `/new` او `/ticket` لفتح تكت!**\n\n",
"msgCmd": "أنشاء أيمبد مع الأزرار. (الأداريين فقط)",
"renameCmd": "إعادة تسمية التكت. (بدون مسافات)",
"closeCmd": "أغلاق التكت.",
"deleteCmd": "حذف التكت.",
"addCmd": "إضافة مستخدم الى التكت.",
"removeCmd": "إزالة مستخدم من التكت.",
"reopenCmd": "إعادة فتح تكت بعد إغلاقة."
},
"buttons": {
"close": "إغلاق التكت",
"delete": "حذف التكت",
"reopen": "إعادة فتح التكت",
"sendTranscript": "طبع التكت",
"closeWithReason":"close with reason"
},
"messages": {
"reopenTitle": "تم إعادة فتح التكت بنجاح!",
"reopenDescription": "لا تتردد في فتح التكت مرة أخرى , حظاً موفقاً!",
"closedTitle": "تم إغلاق التكت!",
"closedDescription": "فقط الأداريين يمكنهم التحدث في هذا التكت الأن!\n\n*أضغط على الزر بالأسفل لحذف التكت او إعادة فتحة مجدداً!*",
"createdTitle": "تم إنشاء تكت!",
"createdDescription": "تم أنشاء تكت , قم بأنتظار الدعم في الطريق!",
"newTicketDmTitle": "تكت جديد!",
"closedTicketDmTitle": "تم إغلاق التكت!",
"deletedTicketDmTitle": "تم حذف التكت!",
"closedTicketDmDescription": "تم أغلاق تذكرتك من قبل إداري",
"deletedTicketDmDescription": "تم حذف تذكرتك من قبل إداري!",
"reopenTicketDmTitle": "تم إعادة فتح تذكرتك!",
"reopenTicketDmDescription": "تم إعادة فتح التكت!",
"newTranscriptTitle": "توجد نسخة تكت جديدة هنا!",
"hereIsTheTranscript": "هذا هي النسخة:",
"chooseCategory": "أختر الكتقاجوري:",
"gettingdeleted": "يتم حذف التكت...",
"none": "لا يوجد",
"reason": "سبب",
"deletedby":"deleted by",
"closedby":"closed by",
"modalreason":"What is the reason for closing this ticket?",
"chooseATicket": "Choose a ticket"
}
}
-83
View File
@@ -1,83 +0,0 @@
{
"errors":{
"missingArgsTitle":"Invalid Arguments!",
"missingArgsDescription":"Missing Argument",
"noPermsTitle":"No Permissions!",
"noPermsDescription":"You need the `ADMINISTRATOR` permission or be in the list of allowed roles!",
"noPermsDelete":"Only admins can delete a ticket!",
"chooseFromListTitle":"Invalid ID",
"chooseFromListDescription":"Choose one of the id's below:",
"boterror":"Bot Error!",
"notInTicketTitle":"You are not in a ticket!",
"notInTicketDescription":"This command doesn't work outside tickets!",
"ticketDoesntExist":"This ticket doesn't exist anymore!",
"roleDoesntExist":"This role doesn't exist anymore!",
"anotherOption":"This option is not a ticket but another type!",
"maxAmountTitle":"Max amount reached!",
"maxAmountDescription":"You reached the maximum number of tickets allowed!\nSo you can't create a new one!",
"somethingWentWrong":"**Something went wrong!**\nPlease try again another time!",
"somethingWentWrongTranscript":"Something went wrong while making the transcript!**\nPlease try again another time!"
},
"commands":{
"userAddedTitle":"Added {0} to this ticket!",
"userRemovedTitle":"Removed {0} from this ticket!",
"renameTitle":"Changed the name to {0}!",
"closeTitle":"Closed this ticket!",
"deleteTitle":"Deleting this ticket...",
"reopenTitle":"Re-Opened this ticket!",
"claimTitle":"This ticket is now claimed to {0}",
"unclaimTitle":"This ticket isn't claimed anymore!",
"ticketWarning":"The embed is in the message below!",
"maxTicketWarning":"**Warning:** _You can only create {0} ticket(s) at a time!_"
},
"helpMenu":{
"title":"Available Commands:",
"header1":"**Go to {0} to create a ticket!**\n\n",
"header2":"**Run the command `/new` or `/ticket` to create a ticket!**\n\n",
"msgCmd":"Spawn an embed with buttons. (admins only)",
"renameCmd":"Rename a ticket. (no spaces)",
"closeCmd":"Close a ticket.",
"deleteCmd":"Delete a ticket.",
"addCmd":"Add a user to the ticket.",
"removeCmd":"Remove a user from the ticket.",
"reopenCmd":"Re-Open a ticket after it was closed."
},
"buttons":{
"close":"Close Ticket",
"delete":"Delete Ticket",
"reopen":"Re-Open Ticket",
"sendTranscript":"Transcript",
"closeWithReason":"close with reason"
},
"messages":{
"reopenTitle":"Re-Opened this ticket!",
"reopenDescription":"Feel free to talk again!",
"closedTitle":"Closed this ticket!",
"closedDescription":"Only admins can talk in this ticket now!\n\n*Click on the button below to delete or to re-open this ticket!*",
"createdTitle":"Ticket Created!",
"createdDescription":"Your ticket is created, you can detect it by a ping!",
"newTicketDmTitle":"New Ticket!",
"closedTicketDmTitle":"Ticket Closed!",
"deletedTicketDmTitle":"Ticket Deleted!",
"closedTicketDmDescription":"Your ticket is closed!",
"deletedTicketDmDescription":"Your ticket is deleted!",
"reopenTicketDmTitle":"Ticket Re-opened!",
"reopenTicketDmDescription":"Your ticket is re-opened!",
"newTranscriptTitle":"A new transcript is here!",
"hereIsTheTranscript":"Here is the transcript:",
"chooseCategory":"choose a category:",
"gettingdeleted":"Ticket is getting deleted...",
"none":"none",
"reason":"reason",
"deletedby":"deleted by",
"closedby":"closed by",
"modalreason":"What is the reason for closing this ticket?",
"chooseATicket": "Choose a ticket"
}
}
-83
View File
@@ -1,83 +0,0 @@
{
"errors":{
"missingArgsTitle":"Neplatné argumenty",
"missingArgsDescription":"Chybí argumenty",
"noPermsTitle":"Nemáš práva!",
"noPermsDescription":"Nemáš dostatečné práva na tento příkaz!\n Potřebuješ ADMINISTRATOR aby jsi mohl provést příkaz!",
"noPermsDelete":"Pouze admin může smazat ticket!",
"chooseFromListTitle":"Neplatné ID",
"chooseFromListDescription":"Vyber si z těchto ID:",
"boterror":"Error!",
"notInTicketTitle":"Nejsi v ticketu!",
"notInTicketDescription":"Tento příkaz nefunguje mimo tickety!",
"ticketDoesntExist":"Tento ticket už bohužel neexistuje!",
"roleDoesntExist":"Tato role bohužel neexistuje!",
"anotherOption":"Tato možnost není ticket ale něco jiného!",
"maxAmountTitle":"Maximální počet ticketů dosažen!",
"maxAmountDescription":"Dosáhl jsi maximálního povoleného počtu ticketů!\n Nemůžeš si vytvořit nový!",
"somethingWentWrong":"**Něco je špatně**\nProsím zkus to příště znovu!",
"somethingWentWrongTranscript":"Něco je špatně s transcriptem!**\nProsím zkus to příště znovu!"
},
"commands":{
"userAddedTitle":"{0} byl přidán do ticketu!",
"userRemovedTitle":"{0} byl odebrám z ticketu!",
"renameTitle":"Jméno bylo změněno!",
"closeTitle":"Zavři tento ticket!",
"deleteTitle":"Smaž tento ticket!",
"reopenTitle":"Znovu otevři ticket!",
"claimTitle":"This ticket is now claimed to {0}",
"unclaimTitle":"This ticket isn't claimed anymore!",
"ticketWarning":"The embed is in the message below!",
"maxTicketWarning":"**Varovaní:** _Můžeš si vytvořit použe {0} ticket(s) v jednu chvíli!_"
},
"helpMenu":{
"title":"Příkazy:",
"header1":"**Běž {0} vytvořit si ticket!**\n\n",
"header2":"**Použij příkaz `/new` nebo `/ticket` k vytvoření ticketu!**\n\n",
"msgCmd":"Vytvoř možnost otevírat tickety přes tlačítko. (ADMIN)",
"renameCmd":"Přejmenovat ticket. (Žádné mezery)",
"closeCmd":"Zavři ticket.",
"deleteCmd":"Smaž ticket.",
"addCmd":"Přidej člena do ticketu.",
"removeCmd":"Odebere člena z ticketu.",
"reopenCmd":"Znovu otevři ticket po uzavření."
},
"buttons":{
"close":"Zavři ticket",
"delete":"Smaž ticket",
"reopen":"Znovu otevři ticket",
"sendTranscript":"Odešli log ticketu",
"closeWithReason":"close with reason"
},
"messages":{
"reopenTitle":"Ticket znovu otevřen!",
"reopenDescription":"Cítím se skvěle že si můžeme zase povídat!",
"closedTitle":"Zavřený ticket!",
"closedDescription":"Pouze admin team zde může nyní komunikovat!\n\n*Klikni na tlačítko níže pro smazání nebo znovu otevření ticketu!*",
"createdTitle":"Ticket vytvořen!",
"createdDescription":"Váš tiket je vytvořen, můžete ho zjistit pomocí pingu!",
"newTicketDmTitle":"Nový ticket!",
"closedTicketDmTitle":"Ticket uzavřen!",
"deletedTicketDmTitle":"Ticket smazán!",
"closedTicketDmDescription":"Tvůj ticket byl uzavřen!",
"deletedTicketDmDescription":"Tvůj ticket byl smazán!",
"reopenTicketDmTitle":"Ticket znovu otevřen!",
"reopenTicketDmDescription":"Tvůj ticket byl znovu otevřen!",
"newTranscriptTitle":"Nový log ticketu je zde!",
"hereIsTheTranscript":"Zde je log:",
"chooseCategory":"Vyber kategorii:",
"gettingdeleted":"Ticket bude smazán",
"none":"nic",
"reason":"důvod",
"deletedby":"deleted by",
"closedby":"closed by",
"modalreason":"What is the reason for closing this ticket?",
"chooseATicket": "Choose a ticket"
}
}
-83
View File
@@ -1,83 +0,0 @@
{
"errors":{
"missingArgsTitle":"Onjuiste parameters!",
"missingArgsDescription":"Er missen parameters",
"noPermsTitle":"Geen permissies!",
"noPermsDescription":"Je hebt de `ADMINISTRATOR` permissie nodig of je moet in de lijst van toegestane users staan!",
"noPermsDelete":"Alleen admins kunnen een ticket verwijderen!",
"chooseFromListTitle":"Onjuist ID",
"chooseFromListDescription":"Kies een van de id's hier onder:",
"boterror":"Bot Error!",
"notInTicketTitle":"Je bent niet in een ticket!",
"notInTicketDescription":"Deze command werkt niet buiten tickets!",
"ticketDoesntExist":"Dit ticket bestaat niet meer!",
"roleDoesntExist":"Deze rol bestaat niet meer!",
"anotherOption":"Deze optie is niet een ticket, maar een ander type!",
"maxAmountTitle":"Maximum numer bereikt!",
"maxAmountDescription":"Je hebt het maximum aantal openstaande tickets bereikt!\nDus je kan geen nieuwe meer maken!",
"somethingWentWrong":"**Iets ging fout!**\nProbeer een andere keer opnieuw!",
"somethingWentWrongTranscript":"Iets ging fout terwijl het transcript gemaakt werd!**\nProbeer een andere keer opnieuw!"
},
"commands":{
"userAddedTitle":"{0} is toegevoegd aan dit ticket!",
"userRemovedTitle":"{0} is verwijderd van dit ticket!",
"renameTitle":"De naam is veranderd naar {0}!",
"closeTitle":"Ticket gesloten!",
"deleteTitle":"Ticket aan het verwijderen...",
"reopenTitle":"Ticket heropend!",
"claimTitle":"This ticket is now claimed to {0}",
"unclaimTitle":"This ticket isn't claimed anymore!",
"ticketWarning":"De embed is in het bericht hier onder!",
"maxTicketWarning":"**Waarschuwing:** _Je kan maar {0} ticket(s) tegelijkertijd maken!_"
},
"helpMenu":{
"title":"Beschikbare Commands:",
"header1":"**Ga naar {0} om een ticket te maken!**\n\n",
"header2":"**Run de command `/new` of `/ticket` om een ticket te maken!**\n\n",
"msgCmd":"Spawn een embed met knoppen. (alleen admins)",
"renameCmd":"Hernoem een ticket. (geen spaties)",
"closeCmd":"Sluit een ticket.",
"deleteCmd":"Verijder een ticket.",
"addCmd":"Voeg een user aan een ticket.",
"removeCmd":"Verwijder een user van een ticket.",
"reopenCmd":"Heropen een ticket nadat het gesloten is."
},
"buttons":{
"close":"Sluit Ticket",
"delete":"Verwijder Ticket",
"reopen":"Heropen Ticket",
"sendTranscript":"Transcript",
"closeWithReason":"sluit met reden"
},
"messages":{
"reopenTitle":"Ticket heropend!",
"reopenDescription":"Voel vrij om weer te praten!",
"closedTitle":"Ticket gesloten!",
"closedDescription":"Alleen admins kunnen nog praten.\n\n*Klik op de knoppen hieronder voor meer acties!*",
"createdTitle":"Ticket Aangemaakt!",
"createdDescription":"U ticket is gemaakt, je kan het detecteren bij een ping!",
"newTicketDmTitle":"Nieuw Ticket!",
"closedTicketDmTitle":"Ticket Gesloten!",
"deletedTicketDmTitle":"Ticket Verwijderd!",
"closedTicketDmDescription":"Je ticket is gesloten!",
"deletedTicketDmDescription":"Je ticket is verwijderd!",
"reopenTicketDmTitle":"Ticket Heropend!",
"reopenTicketDmDescription":"Je ticket is heropend!",
"newTranscriptTitle":"Er is een nieuw transcript!",
"hereIsTheTranscript":"Hier is het transcript:",
"chooseCategory":"kies een categorie:",
"gettingdeleted":"Ticket wordt verwijderd...",
"none":"geen",
"reason":"reden",
"deletedby":"verwijderd door",
"closedby":"gesloten door",
"modalreason":"Wat is de reden om dit ticket te sluiten?",
"chooseATicket": "Kies een ticket"
}
}
-83
View File
@@ -1,83 +0,0 @@
{
"errors":{
"missingArgsTitle":"Invalid Arguments!",
"missingArgsDescription":"Missing Argument",
"noPermsTitle":"No Permissions!",
"noPermsDescription":"You need the `ADMINISTRATOR` permission or be in the list of allowed roles!",
"noPermsDelete":"Only admins can delete a ticket!",
"chooseFromListTitle":"Invalid ID",
"chooseFromListDescription":"Choose one of the id's below:",
"boterror":"Bot Error!",
"notInTicketTitle":"You are not in a ticket!",
"notInTicketDescription":"This command doesn't work outside tickets!",
"ticketDoesntExist":"This ticket doesn't exist anymore!",
"roleDoesntExist":"This role doesn't exist anymore!",
"anotherOption":"This option is not a ticket but another type!",
"maxAmountTitle":"Max amount reached!",
"maxAmountDescription":"You reached the maximum number of tickets allowed!\nSo you can't create a new one!",
"somethingWentWrong":"**Something went wrong!**\nPlease try again another time!",
"somethingWentWrongTranscript":"Something went wrong while making the transcript!**\nPlease try again another time!"
},
"commands":{
"userAddedTitle":"Added {0} to this ticket!",
"userRemovedTitle":"Removed {0} from this ticket!",
"renameTitle":"Changed the name to {0}!",
"closeTitle":"Closed this ticket!",
"deleteTitle":"Deleting this ticket...",
"reopenTitle":"Re-Opened this ticket!",
"claimTitle":"This ticket is now claimed to {0}",
"unclaimTitle":"This ticket isn't claimed anymore!",
"ticketWarning":"The embed is in the message below!",
"maxTicketWarning":"**Warning:** _You can only create {0} ticket(s) at a time!_"
},
"helpMenu":{
"title":"Available Commands:",
"header1":"**Go to {0} to create a ticket!**\n\n",
"header2":"**Run the command `/new` or `/ticket` to create a ticket!**\n\n",
"msgCmd":"Spawn an embed with buttons. (admins only)",
"renameCmd":"Rename a ticket. (no spaces)",
"closeCmd":"Close a ticket.",
"deleteCmd":"Delete a ticket.",
"addCmd":"Add a user to the ticket.",
"removeCmd":"Remove a user from the ticket.",
"reopenCmd":"Re-Open a ticket after it was closed."
},
"buttons":{
"close":"Close Ticket",
"delete":"Delete Ticket",
"reopen":"Re-Open Ticket",
"sendTranscript":"Transcript",
"closeWithReason":"close with reason"
},
"messages":{
"reopenTitle":"Re-Opened this ticket!",
"reopenDescription":"Feel free to talk again!",
"closedTitle":"Closed this ticket!",
"closedDescription":"Only admins can talk in this ticket now!\n\n*Click on the button below to delete or to re-open this ticket!*",
"createdTitle":"Ticket Created!",
"createdDescription":"Your ticket is created, you can detect it by a ping!",
"newTicketDmTitle":"New Ticket!",
"closedTicketDmTitle":"Ticket Closed!",
"deletedTicketDmTitle":"Ticket Deleted!",
"closedTicketDmDescription":"Your ticket is closed!",
"deletedTicketDmDescription":"Your ticket is deleted!",
"reopenTicketDmTitle":"Ticket Re-opened!",
"reopenTicketDmDescription":"Your ticket is re-opened!",
"newTranscriptTitle":"A new transcript is here!",
"hereIsTheTranscript":"Here is the transcript:",
"chooseCategory":"choose a category:",
"gettingdeleted":"Ticket is getting deleted...",
"none":"none",
"reason":"reason",
"deletedby":"deleted by",
"closedby":"closed by",
"modalreason":"What is the reason for closing this ticket?",
"chooseATicket": "Choose a ticket"
}
}
-83
View File
@@ -1,83 +0,0 @@
{
"errors":{
"missingArgsTitle":"Arguments invalides!",
"missingArgsDescription":"Argument manquant",
"noPermsTitle":"Pas de permissions!",
"noPermsDescription":"Vous avez besoin de la permission `ADMINISTRATOR` ou être dans la liste des rôles autorisés!",
"noPermsDelete":"Seuls les administrateurs peuvent supprimer un ticket!",
"chooseFromListTitle":"Invalid ID",
"chooseFromListDescription":"Choisissez l'un des identifiants ci-dessous:",
"boterror":"Bot Error!",
"notInTicketTitle":"Vous n'êtes pas dans un ticket!",
"notInTicketDescription":"Cette commande ne fonctionne pas en dehors des tickets!",
"ticketDoesntExist":"Ce ticket n'existe plus!",
"roleDoesntExist":"Ce rôle n'existe plus!",
"anotherOption":"Cette option n'est pas un ticket mais un autre type!",
"maxAmountTitle":"Montant maximum atteint!",
"maxAmountDescription":"Vous avez atteint le nombre maximum de tickets autorisés!\nVous ne pouvez donc pas en créer un nouveau!",
"somethingWentWrong":"**Quelque chose s'est mal passé!**\nVeuillez réessayer une autre fois!",
"somethingWentWrongTranscript":"Une erreur s'est produite lors de la création de la transcription!**\nVeuillez réessayer une autre fois!"
},
"commands":{
"userAddedTitle":"{0} a été ajouté à ce ticket!",
"userRemovedTitle":"Supprimé {0} de ce ticket!",
"renameTitle":"Changement du nom en {0}!",
"closeTitle":"Fermé ce ticket!",
"deleteTitle":"Suppression de ce ticket...",
"reopenTitle":"A rouvert ce ticket!",
"claimTitle":"This ticket is now claimed to {0}",
"unclaimTitle":"This ticket isn't claimed anymore!",
"ticketWarning":"L'intégration est dans le message ci-dessous!",
"maxTicketWarning":"**Attention :** _Vous ne pouvez créer que {0} ticket(s) à la fois !_"
},
"helpMenu":{
"title":"Commandes disponibles :",
"header1":"**Allez à {0} pour créer un ticket !**\n\n",
"header2":"**Exécutez la commande `/new` ou `/ticket` pour créer un ticket !**\n\n",
"msgCmd":"Faire apparaître une intégration avec des boutons. (administrateurs uniquement)",
"renameCmd":"Renommer un ticket. (sans espaces)",
"closeCmd":"Fermer un ticket.",
"deleteCmd":"Supprimer un billet.",
"addCmd":"Ajouter un utilisateur au ticket.",
"removeCmd":"Supprimer un utilisateur du ticket.",
"reopenCmd":"Rouvrir un ticket après sa clôture."
},
"buttons":{
"close":"Fermer le ticket",
"delete":"Supprimer le billet",
"reopen":"Billet de réouverture",
"sendTranscript":"Transcript",
"closeWithReason":"fermer avec une raison"
},
"messages":{
"reopenTitle":"A rouvert ce ticket!",
"reopenDescription":"N'hésitez pas à reparler!",
"closedTitle":"Fermé ce ticket!",
"closedDescription":"Seuls les administrateurs peuvent parler dans ce ticket maintenant !\n\n*Cliquez sur le bouton ci-dessous pour supprimer ou rouvrir ce ticket !*",
"createdTitle":"Ticket créé !",
"createdDescription":"Votre ticket est créé, vous pouvez le détecter par un ping !",
"newTicketDmTitle":"Nouveau billet!",
"closedTicketDmTitle":"Billet fermé!",
"deletedTicketDmTitle":"Billet supprimé !",
"closedTicketDmDescription":"Votre billet est fermé !",
"deletedTicketDmDescription":"Votre billet est supprimé !",
"reopenTicketDmTitle":"Billet rouvert!",
"reopenTicketDmDescription":"Votre billet est rouvert !",
"newTranscriptTitle":"Une nouvelle transcription est ici!",
"hereIsTheTranscript":"Voici la transcription :",
"chooseCategory":"choisissez une catégorie:",
"gettingdeleted":"Le ticket est en cours de suppression...",
"none":"rien",
"reason":"raison",
"deletedby":"supprimé par",
"closedby":"fermé par",
"modalreason":"Qu’elle est la raison pour fermer ce ticket?",
"chooseATicket": "Choisir un ticket"
}
}
-83
View File
@@ -1,83 +0,0 @@
{
"errors":{
"missingArgsTitle":"Ungültiges Argument!",
"missingArgsDescription":"Fehlendes Argument!",
"noPermsTitle":"Du hast keine Rechte!",
"noPermsDescription":"You need the `ADMINISTRATOR` permission or be in the list of allowed roles!",
"noPermsDelete":"Only admins can delete a ticket!",
"chooseFromListTitle":"Ungültige ID",
"chooseFromListDescription":"Wählen Sie eine der folgenden ID:",
"boterror":"Bot Fehler!",
"notInTicketTitle":"Du bist ein kein Ticket!",
"notInTicketDescription":"Der Befehl funktioniert nicht außerhalb eines Tickets!",
"ticketDoesntExist":"Das Ticket Exisitert nicht mehr!",
"roleDoesntExist":"Die Rolle Exisitiert nicht mehr!",
"anotherOption":"Diese Option ist kein Ticket, sondern eine andere Art!",
"maxAmountTitle":"Das Limit wurde erreicht!",
"maxAmountDescription":"Sie haben die maximal zulässige Anzahl von Tickets erreicht!\nSie können also keine neue erstellen.!",
"somethingWentWrong":"**Etwas ist schief gelaufen!**\nBitte versuchen Sie es ein anderes Mal!",
"somethingWentWrongTranscript":"Bei der Erstellung der Transcript ist etwas schief gelaufen!**\nBitte versuchen Sie es ein anderes Mal!"
},
"commands":{
"userAddedTitle":"Added {0} to this ticket!",
"userRemovedTitle":"Removed {0} from this ticket!",
"renameTitle":"Changed the name to {0}!",
"closeTitle":"Closed this ticket!",
"deleteTitle":"Deleting this ticket...",
"reopenTitle":"Re-Opened this ticket!",
"claimTitle":"This ticket is now claimed to {0}",
"unclaimTitle":"This ticket isn't claimed anymore!",
"ticketWarning":"The embed is in the message below!",
"maxTicketWarning":"**Warning:** _You can only create {0} ticket(s) at a time!_"
},
"helpMenu":{
"title":"Available Commands:",
"header1":"**Gehe zu {0} um ein Ticket zu erstellen!**\n\n",
"header2":"**Führen Sie den Befehl `/new` oder `/ticket` um ein Ticket zu erstellen!**\n\n",
"msgCmd":"Eine Einbettung mit Schaltflächen erzeugen. (nur admins)",
"renameCmd":"Ein Ticket umbenennen. (keine Leerzeichen)",
"closeCmd":"Schließen Sie ein Ticket.",
"deleteCmd":"Ein Ticket löschen.",
"addCmd":"Fügen Sie dem Ticket einen Benutzer hinzu.",
"removeCmd":"Entfernen eines Benutzers aus dem Ticket.",
"reopenCmd":"Öffnen Sie ein Ticket erneut, nachdem es geschlossen wurde."
},
"buttons":{
"close":"Ticket schließen",
"delete":"Ticket löschen",
"reopen":"Ticket wieder öffnen",
"sendTranscript":"Transcript-Datei senden",
"closeWithReason":"Geschlossen mit dem Grund"
},
"messages":{
"reopenTitle":"Dieses Ticket wiedereröffnet!",
"reopenDescription":"Sie können gerne weiterreden!",
"closedTitle":"Dieses Ticket geschlossen!",
"closedDescription":"Nur Admins können jetzt in diesem Ticket sprechen!\n\n*Klicken Sie auf die Schaltfläche unten, um dieses Ticket zu löschen oder erneut zu öffnen!*",
"createdTitle":"Ticket erstellt!",
"createdDescription":"Ihr Ticket ist erstellt, Sie können es durch einen Ping erkennen!",
"newTicketDmTitle":"Neues Ticket!",
"closedTicketDmTitle":"Ticket schließen!",
"deletedTicketDmTitle":"Ticket löschen!",
"closedTicketDmDescription":"Ihr Ticket ist geschlossen!",
"deletedTicketDmDescription":"Ihr Ticket ist gelöscht!",
"reopenTicketDmTitle":"Ticket neu Eröffnen!",
"reopenTicketDmDescription":"Dein Ticket ist Neu eröffnet!",
"newTranscriptTitle":"Eine neue Transscript finden Sie hier!",
"hereIsTheTranscript":"Hier ist das Transscript:",
"chooseCategory":"Wähle eine Kategorie:",
"gettingdeleted":"Ticket wird gelöscht...",
"none":"none",
"reason":"reason",
"deletedby":"Gelöscht von",
"closedby":"Geschlossen von",
"modalreason":"Was ist der Grund für das schließen des Tickets?",
"chooseATicket": "Wähle ein Ticket"
}
}
-83
View File
@@ -1,83 +0,0 @@
{
"errors":{
"missingArgsTitle":"Argomenti non validi!",
"missingArgsDescription":"Argomento mancante",
"noPermsTitle":"Permessi mancanti!",
"noPermsDescription":"Hai bisogno del permesso `ADMINISTRATOR` e essere nella lista dei ruoli accettati!",
"noPermsDelete":"Solo gli amministratori possono chiudere un ticket!",
"chooseFromListTitle":"ID non valido",
"chooseFromListDescription":"Scegli uno degli ID sotto:",
"boterror":"Errore del bot!",
"notInTicketTitle":"Non sei in un ticket!",
"notInTicketDescription":"Questo comando non funziona fuori da un ticket!",
"ticketDoesntExist":"Questo ticket non esiste più!",
"roleDoesntExist":"Questo ruolo non esiste più!",
"anotherOption":"Questa opzione non è di un ticket!",
"maxAmountTitle":"Massimo numero raggiunto!",
"maxAmountDescription":"Hai raggiunto il massimo numero di ticket consentiti!\nNon puoi crearne altri!",
"somethingWentWrong":"**Qualcosa è andato storto!**\nPerfavore riprova un'altra volta!",
"somethingWentWrongTranscript":"Qualcosa è andata storta durante la trascrizione!**\nPerfavore riprova un'altra volta!"
},
"commands":{
"userAddedTitle":"Aggiunto {0} al ticket!",
"userRemovedTitle":"Rimosso {0} da questo ticket!",
"renameTitle":"Cambia il nome in {0}!",
"closeTitle":"Chiudo questo ticket!",
"deleteTitle":"Eliminando questo ticket...",
"reopenTitle":"Ri-Aperto questo ticket!",
"claimTitle":"This ticket is now claimed to {0}",
"unclaimTitle":"This ticket isn't claimed anymore!",
"ticketWarning":"L'embed è nel messaggio sotto!",
"maxTicketWarning":"**Attenzione:** _Tu puoi creare solo {0} ticket(s) per volta!_"
},
"helpMenu":{
"title":"Comandi disponibili:",
"header1":"**Vai a {0} per creare un ticket!**\n\n",
"header2":"**Esegui il comando `/new` o `/ticket` per creare un ticket!**\n\n",
"msgCmd":"Crea un embed con pulsanti. (solo amministratori)",
"renameCmd":"Rinomina un ticket. (senza spazi)",
"closeCmd":"Chiudi un ticket.",
"deleteCmd":"Elimina un ticket.",
"addCmd":"Aggiungi un membro al ticket.",
"removeCmd":"Rimuovi un membro dal ticket.",
"reopenCmd":"Riapri un ticket dopo averlo chiuso."
},
"buttons":{
"close":"Chiudi il ticket",
"delete":"Elimina il ticket",
"reopen":"Riapri il ticket",
"sendTranscript":"Trascrizione",
"closeWithReason":"chiudi con un motivo"
},
"messages":{
"reopenTitle":"Riaperto questo ticket!",
"reopenDescription":"Sentiti libero di parlare di nuovo!",
"closedTitle":"Chiudo questo ticket!",
"closedDescription":"Solo gli amministratori possono parlare in questo ticket ora!\n\n*Clicca sul bottone sotto per chiudere o riaprire questo ticket!*",
"createdTitle":"Ticket creato!",
"createdDescription":"Il tuo ticket è stato creato, puoi capirlo dal ping!",
"newTicketDmTitle":"Nuovo ticket!",
"closedTicketDmTitle":"Ticket chiuso!",
"deletedTicketDmTitle":"Ticket eliminato!",
"closedTicketDmDescription":"Il tuo ticket è chiuso!",
"deletedTicketDmDescription":"Il tuo ticket è stato eliminato!",
"reopenTicketDmTitle":"Ticket riaperto!",
"reopenTicketDmDescription":"Il tuo ticket è stato riaperto!",
"newTranscriptTitle":"Un nuova trascrizione è qui!",
"hereIsTheTranscript":"Qui è la trascrizione:",
"chooseCategory":"scegli una categoria:",
"gettingdeleted":"Il ticket sta per essere chiuso...",
"none":"nessuno",
"reason":"motivo",
"deletedby":"eliminato da",
"closedby":"chiuso da",
"modalreason":"Quale'è il motivo per chiudere il ticket?",
"chooseATicket": "Scegli un ticket"
}
}
-83
View File
@@ -1,83 +0,0 @@
{
"errors":{
"missingArgsTitle":"Argumentos inválidos!",
"missingArgsDescription":"Argumento ausente",
"noPermsTitle":"Sem permissões!",
"noPermsDescription":"Você precisa da permissão `ADMINISTRATOR` ou estar na lista de funções permitidas!",
"noPermsDelete":"Somente administradores podem deletar um ticket!",
"chooseFromListTitle":"ID inválido",
"chooseFromListDescription":"Escolha um dos IDs abaixo:",
"boterror":"Erro de bot!",
"notInTicketTitle":"Você não está em um ticket!",
"notInTicketDescription":"Este comando não funciona fora dos tickets!",
"ticketDoesntExist":"Este ticket não existe mais!",
"roleDoesntExist":"Esta função não existe mais!",
"anotherOption":"Esta opção não é um ticket, mas sim outro tipo!",
"maxAmountTitle":"Quantidade máxima atingida!",
"maxAmountDescription":"Você atingiu o número máximo de tickets permitidos!\nEntão você não pode criar um novo!",
"somethingWentWrong":"**Algo deu errado!**\nPor favor, tente novamente outra vez!",
"somethingWentWrongTranscript":"Algo deu errado ao fazer a transcrição!**\nPor favor, tente novamente outra vez!"
},
"commands":{
"userAddedTitle":"Adicionado {0} a este ticket!",
"userRemovedTitle":"Removido {0} deste ticket!",
"renameTitle":"Mudou o nome para {0}!",
"closeTitle":"Fechado este ticket!",
"deleteTitle":"Excluindo este ticket...",
"reopenTitle":"Reabriu este ticket!",
"claimTitle":"This ticket is now claimed to {0}",
"unclaimTitle":"This ticket isn't claimed anymore!",
"ticketWarning":"A incorporação está na mensagem abaixo!",
"maxTicketWarning":"**Cuidado:** _Você só pode criar {0} ticket(s) de cada vez!!_"
},
"helpMenu":{
"title":"Comandos Disponíveis:",
"header1":"**Vá para {0} para criar um ticket!**\n\n",
"header2":"**Execute o comando `/new` ou `/ticket` para criar um ticket!**\n\n",
"msgCmd":"Gerar uma incorporação com botões. (somente administradores)",
"renameCmd":"Renomear um ticket. (sem espaços)",
"closeCmd":"Fechar um ticket.",
"deleteCmd":"Excluir um ticket.",
"addCmd":"Adicionar um usuário ao ticket.",
"removeCmd":"Remover um usuário do ticket.",
"reopenCmd":"Reabra um ticket depois que ele foi fechado."
},
"buttons":{
"close":"Fechar Ticket",
"delete":"Excluir Ticket",
"reopen":"Reabrir Ticket",
"sendTranscript":"Transcrição",
"closeWithReason":"close with reason"
},
"messages":{
"reopenTitle":"Reabriu este ticket!",
"reopenDescription":"Sinta-se à vontade para falar novamente!",
"closedTitle":"Fechado este ticket!",
"closedDescription":"Somente administradores podem falar neste ticket agora!\n\n*Clique no botão abaixo para excluir ou reabrir este ticket!*",
"createdTitle":"Ticket criado!",
"createdDescription":"Seu ticket foi criado, você pode detectá-lo com um ping!",
"newTicketDmTitle":"Novo Ticket!",
"closedTicketDmTitle":"Ticket fechado!",
"deletedTicketDmTitle":"Ticket excluído!",
"closedTicketDmDescription":"Seu ticket está fechado!",
"deletedTicketDmDescription":"Seu bilhete foi excluído!",
"reopenTicketDmTitle":"Ticket reaberto!",
"reopenTicketDmDescription":"Seu ticket foi reaberto!",
"newTranscriptTitle":"Uma nova transcrição está aqui!",
"hereIsTheTranscript":"Aqui está a transcrição:",
"chooseCategory":"Escolha a categoria:",
"gettingdeleted":"Ticket está sendo deletado...",
"none":"none",
"reason":"reason",
"deletedby":"deleted by",
"closedby":"closed by",
"modalreason":"What is the reason for closing this ticket?",
"chooseATicket": "Choose a ticket"
}
}
-83
View File
@@ -1,83 +0,0 @@
{
"errors":{
"missingArgsTitle":"Argumente Invalide",
"missingArgsDescription":"Argument Lipsa",
"noPermsTitle":"Nu ai permisiunea necesara!",
"noPermsDescription":"Ai nevoie de permisiunea de `ADMINISTRATOR`!",
"noPermsDelete":"Doar adminii pot inchide un ticket!",
"chooseFromListTitle":"Invalid ID",
"chooseFromListDescription":"Alege unul dintre id-urile urmatoare:",
"boterror":"Eroare bot!",
"notInTicketTitle":"Nu esti intr-un ticket!",
"notInTicketDescription":"Aceasta comanda nu merge inafara unui ticket!",
"ticketDoesntExist":"Acest ticket nu mai exista!",
"roleDoesntExist":"Acest rol nu mai exista!",
"anotherOption":"Aceasta optiune este altceva decat un tip de ticket!",
"maxAmountTitle":"Limita atinsa!",
"maxAmountDescription":"Ai atins limita de tickets!\nAsa ca nu mai poti creea altele noi!",
"somethingWentWrong":"**Ceva nu a mers bine!**\nTe rugam sa incerci mai tarziu!",
"somethingWentWrongTranscript":"Ceva nu aa mers bine in timpul creeari transcript-ului!**\nTe rugam sa incerci mai tarziu!"
},
"commands":{
"userAddedTitle":"{0} a fost adaugat in acest ticket!",
"userRemovedTitle":"{0} a fost scos din acest ticket!",
"renameTitle":"Nume schimbat in {0}!",
"closeTitle":"Ticket inchis!",
"deleteTitle":"Se sterge ticket-ul...",
"reopenTitle":"Ticket Re-deschis!",
"claimTitle":"This ticket is now claimed to {0}",
"unclaimTitle":"This ticket isn't claimed anymore!",
"ticketWarning":"Embed-ul se afla in mesajul de mai jos!",
"maxTicketWarning":"**Avertizare:** _Poti creea doar {0} tickete active!_"
},
"helpMenu":{
"title":"Comenzi disponibile:",
"header1":"**Mergi la {0} pentru a creea un ticket!**\n\n",
"header2":"**Ruleaza comanda `/new` ori `/ticket` pentru a creea un ticket!**\n\n",
"msgCmd":"Trimite embed-ul cu tickete. (doar admini)",
"renameCmd":"Redenumeste un ticket. (fara spatii)",
"closeCmd":"Inchide un ticket.",
"deleteCmd":"Sterge un ticket.",
"addCmd":"Adauga un utilizator in ticket.",
"removeCmd":"Sterge un utilizator din ticket.",
"reopenCmd":"Re-deschide un ticket dupa ce a fost deschis."
},
"buttons":{
"close":"Inchide ticket-ul",
"delete":"Sterge ticket-ul",
"reopen":"Re-deschide un ticket",
"sendTranscript":"Transcript",
"closeWithReason":"Inchide cu motiv"
},
"messages":{
"reopenTitle":"Ticket Re-deschis!",
"reopenDescription":"Poti vorbi din nou!",
"closedTitle":"Ticket inchis!",
"closedDescription":"Doar adminii pot vorbi in acest ticket acum!\n\n*Apasa pe butonul de mai jos pentru a re-deschide ori sterge ticket-ul!*",
"createdTitle":"Ticket Creat!",
"createdDescription":"Ticket-ul tau a fost creat, poti sa il vezi in canalul pe care ai fost mentionat!",
"newTicketDmTitle":"Ticket nou!",
"closedTicketDmTitle":"Ticket Inchis!",
"deletedTicketDmTitle":"Ticket Sters!",
"closedTicketDmDescription":"Ticket-ul tau este inchis!",
"deletedTicketDmDescription":"Ticket-ul tau este sters!",
"reopenTicketDmTitle":"Ticket Re-deschis!",
"reopenTicketDmDescription":"Ticket-ul tau este re-deschis!",
"newTranscriptTitle":"Un nou transcript este aici!",
"hereIsTheTranscript":"Aici este transcriptul:",
"chooseCategory":"Alege o categorie:",
"gettingdeleted":"Ticket-ul se sterge...",
"none":"niciunul",
"reason":"Motiv",
"deletedby":"Sters de",
"closedby":"Inchis de",
"modalreason":"Care este motivul pentru inchiderea acestui ticket?",
"chooseATicket": "Alege un ticket"
}
}
-139
View File
@@ -1,139 +0,0 @@
{
"examples":{
"en-GB":"english",
"en-US":"english",
"nl":"dutch",
"ro":"romanian",
"de":"german",
"cs":"czech",
"fr":"french",
"es-ES":"spanish",
"it":"italian",
"MISSING":"arabic,portuguese",
"NOTAVAILABLE":"arabic,portuguese,czech"
},
"data":{
"help":{
"en-GB":"A list of the available commands.",
"en-US":"A list of the available commands.",
"nl":"Een lijst met de beschikbare commands.",
"ro":"O lista a comenzilor disponibile.",
"de":"Eine Liste der verfügbaren Befehle.",
"cs":"A list of the available commands",
"fr":"Une liste des commandes.",
"es-ES":"Una lista de los comandos disponibles.",
"it":"Una lista di tutti i comandi disponibili."
},
"message":{
"en-GB":"Spawn an embed with buttons.",
"en-US":"Spawn an embed with buttons.",
"nl":"Spawn een embed met knoppen.",
"ro":"Deschide un embed cu butoane.",
"de":"Sendet ein Embed mit Knöpfen.",
"cs":"Spawn an embed with buttons.",
"fr":"Créer un embed avec des boutons.",
"es-ES":"Genera un embed con botones.",
"it":"Genera un embed con un pulsante."
},
"close":{
"en-GB":"Close a ticket.",
"en-US":"Close a ticket.",
"nl":"Sluit een ticket",
"ro":"Inchide un ticket.",
"de":"Schließe ein Ticket.",
"cs":"Close a ticket.",
"fr":"Fermer un ticket.",
"es-ES":"Cierra un ticket.",
"it":"Chiudi un ticket."
},
"delete":{
"en-GB":"Delete a ticket.",
"en-US":"Delete a ticket.",
"nl":"Verwijder een ticket",
"ro":"Sterge un ticket.",
"de":"Lösche ein Ticket.",
"cs":"Delete a ticket.",
"fr":"Supprimer un ticket.",
"es-ES":"Elimina un ticket.",
"it":"Elimina un ticket."
},
"reopen":{
"en-GB":"Re-Open a ticket.",
"en-US":"Re-Open a ticket.",
"nl":"Heropen een ticket.",
"ro":"Re-deschide un ticket.",
"de":"Wiedereröffnung eines Tickets.",
"cs":"Re-Open a ticket.",
"fr":"Re-ouvrir un ticket.",
"es-ES":"Re-abre un ticket.",
"it":"Ri-Apri un ticket."
},
"add":{
"en-GB":"Add another user to a ticket.",
"en-US":"Add another user to a ticket.",
"nl":"Voeg een andere user toe aan een ticket.",
"ro":"Adauga un utilizator la acest ticket.",
"de":"Füge einen anderen Nutzer zum Ticket hinzu.",
"cs":"Add another user to a ticket.",
"fr":"Ajouter un utilisateur au ticket.",
"es-ES":"Agrega otro usuario al ticket.",
"it":"Aggiungi un membro al ticket"
},
"remove":{
"en-GB":"Remove a user from a ticket.",
"en-US":"Remove a user from a ticket.",
"nl":"Verwijder een user van een ticket.",
"ro":"Sterge un utilizator dintr-un ticket.",
"de":"Entferne einen Nutzer von dem Ticket.",
"cs":"Remove a user from a ticket.",
"fr":"Enlever quelqu’un du ticket.",
"es-ES":"Elimina otro usuario del ticket.",
"it":"Rimuovi un membro dal ticket"
},
"newticket":{
"en-GB":"Create a ticket",
"en-US":"Create a ticket",
"nl":"Maak een ticket aan",
"ro":"Creeaza un ticket.",
"de":"Erstelle ein Ticket.",
"cs":"Create a ticket",
"fr":"Créer un ticket",
"es-ES":"Crear un ticket.",
"it":"Crea un ticket"
},
"rename":{
"en-GB":"Rename a ticket channel.",
"en-US":"Rename a ticket channel.",
"nl":"Hernoem een ticket channel.",
"ro":"Redenumeste un ticket.",
"de":"Benenne einen Ticket Channel.",
"cs":"Rename a ticket channel",
"fr":"Renommer un ticket.",
"es-ES":"Renombrar un canal de ticket.",
"it":"Rinomina il canale di un ticket."
},
"claim":{
"en-GB":"",
"en-US":"",
"nl":"",
"ro":"",
"de":"",
"cs":"",
"fr":"",
"es-ES":"",
"it":""
},
"unclaim":{
"en-GB":"",
"en-US":"",
"nl":"",
"ro":"",
"de":"",
"cs":"",
"fr":"",
"es-ES":"",
"it":""
}
}
}

Some files were not shown because too many files have changed in this diff Show More