Compare commits

...
141 Commits
Author SHA1 Message Date
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
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
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
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
263 changed files with 40795 additions and 9217 deletions
+41
View File
@@ -0,0 +1,41 @@
# 🎥 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 helpin 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
- 📌 At least 2k subscribers!
- 📌 A little bit of channel activity! *(minimum 2 uploads/month)*
- 📌 Video length of at least 3 minutes!
- 📌 Provide a clear link to the Open Ticket repository!
- 📌 Recommended language is English!
- 📌 Recommended platform is YouTube!
- 📌 Must be for the latest version of Open Ticket!
- 📌 **(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!
+84 -34
View File
@@ -1,42 +1,92 @@
# Contributing # Contributing Guidelines
## Translation <img src="https://apis.dj-dj.be/cdn/openticket/logo.png" alt="Open Ticket Logo" width="500px">
### Step 1: checking
1. [Check if the language isn't already in open ticket!](/language/)
2. Check if the current translation is up-to-date!
3. Can you edit/write JSON?
If there is translation missing & you can write json, then go to the next step! [![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.0-brightgreen.svg?style=flat-square)](https://github.com/DJj123dj/open-ticket/releases/tag/v4.0.0)
### Step 2: translating These are the Contributing Guidelines of Open Ticket!<br>
**RULES:** Here you can find everything you need to know about contributing to Open Ticket.<br>
- Always upload to the [__`dev` branch!__](https://github.com/DJj123dj/open-ticket/tree/dev) This includes new features, translations & bug fixes.
- Don't change anything else, except the translation you are adding!
- Translations are checked before uploading, so don't write things that aren't specified in the json file
- Always start translating from `english.json` or `custom.json`! Never from another language.
If you translate, you need to change 2 files! The first one is required, the other one is optional & will be added by us if you don't do it! ### 💬 Translations
1. add `yourlanguage.json` to the `/language/` directory #### Step 1: View & Check
2. (OPTIONAL) add your discord name & tag in the translator table in `README.md` 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 3: waiting #### Step 2: Translation
Translations will always be added in the **next version** of Open Ticket! They will never be added to the `main` branch directly without anything else! This means that it can take some time before your translation is in the official version! 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`.
## Writing plugins #### Step 3: Metadata
We are going to create an official repository for plugins soon! Metadata can be found in the `_TRANSLATION` variable.
But don't worry! You can already write some plugins! |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, ... |
**RULES:** > #### ✅ You are also allowed to add your username to the [`README.md`](./../README.md) translator list!
- Always specify the versions that the plugin is compatible with!
- If extra npm dependencies are needed, then they also need to be specified!
- If there are errors while you write a plugin/edit the code in some way. Then we can't help you with fixing the bug. We only fix bugs that are part of an unedited version of Open Ticket!
## Other versions of contributing #### Step 4: Uploading
If you want to contribute in another way, feel free to join [our discord server](https://discord.dj-dj.be) & talk about how you are going to do it. We will always help you! 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/DJj123dj/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.
<br> #### Step 5: Rewards
CONTRIBUTING GUIDELINES - Last updated: 23/3/2023<br> Translators get some rewards for translating Open Ticket!
© DJdj Development<br><br> - ✅ Credits in the [`README.md`](./../README.md) translator list!
Website: https://www.dj-dj.be <br> - ✅ Credits in the changelog!
Discord: https://discord.dj-dj.be <br> - ✅ Credits in the documentation!
Email: support@dj-dj.be <br> - ✅ Credits in the translation JSON file!
Open Ticket website: https://openticket.dj-dj.be - ✅ 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) - [tutorial](https://www.youtube.com/watch?v=2jK9kAf6ASU) - [website](https://openticket.dj-dj.be) - [discord](https://discord.dj-dj.be)<br>
© 2024 - [DJdj Development](https://www.dj-dj.be) - [Terms](https://www.dj-dj.be/terms#terms) - [Privacy Policy](https://www.dj-dj.be/terms#privacy)
+1
View File
@@ -0,0 +1 @@
github: DJj123dj
+13 -18
View File
@@ -1,37 +1,32 @@
--- ---
name: Bug report name: Bug Report
about: Report bugs to help us improve open ticket! about: Report bugs to help us improve Open Ticket!
title: "[BUG] your bug" title: "[BUG] Your Bug"
labels: bug labels: bug
assignees: DJj123dj assignees: DJj123dj
--- ---
**Describe the bug** ### Bug Description:
A clear and concise description of what the bug is. A clear and concise description of what the bug is.
**To Reproduce** ### Steps To Reproduce:
Steps to reproduce the behavior: Steps to reproduce the behavior:
1. Go to '...' 1. Go to '...'
2. Click on '....' 2. Click on '....'
3. Scroll down to '....' 3. Scroll down to '....'
4. See error 4. See error
**Expected behavior** > Leave empty when you are unable to reproduce the bug!
### Expected Behaviour:
A clear and concise description of what you expected to happen. A clear and concise description of what you expected to happen.
**Screenshots** ### Screenshots:
If applicable, add screenshots to help explain your problem. If applicable, add screenshots to help explain your problem.
**Device:** ### Files:
- Device: [e.g. Macbook pro, raspberry pi, HP Probook] Please include the `otdebug.txt` file in your report! With this file, we can take a deep-dive in to the error that happend.
- OS: [e.g. MacOS, Ubuntu, Windows,...] > This file doesn't contain any credentials or sensitive information!
- Node.js version:
- Open Ticket Version:
**Files:** ### Additional Notes:
Please include the `openticketdebug.txt` file in your report!
This is a file that we can see what happend!
**Additional context**
Add any other context about the problem here. Add any other context about the problem here.
-29
View File
@@ -1,29 +0,0 @@
---
name: Plugin
about: Show your plugin to the developers from open ticket!
title: "[PLUGIN] your plugin"
labels: plugin
assignees: DJj123dj
---
**Plugin Name:**
What's the name of your plugin?
**Description:**
Tell a little bit about what the plugin does!
Also tell how to use the plugin, like if there is additional setup needed!
**NPM libraries:**
List all the libraries needed for this plugin to work!
*The default open ticket libraries are not required!*
**Author:**
- github account [e.g. DJj123dj]
- discord account [e.g. Wumpus#1234]
**Compatible versions:**
[e.g. from v2.2.1 until v3.0.1]
**File:**
Please attach the plugin file to this issue!
+38 -30
View File
@@ -1,41 +1,49 @@
# Security Policy # Security Policy
<img src="https://apis.dj-dj.be/cdn/openticket/logo.png" alt="Open Ticket Logo" width="500px">
## Supported Versions [![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.0-brightgreen.svg?style=flat-square)](https://github.com/DJj123dj/open-ticket/releases/tag/v4.0.0)
Support for Open Ticket is only available for the versions specified below! 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 ### 📦 Supported Versions
🟧 Partially Supported Below, you can find a list with the status of every Open Ticket version.<br>
❌ Not Supported This list will be updated on every release.
| Version | Supported | - 🟦 Early Access **(ideas, bugs, support, html transcripts)**
| ------- | ------------------ | - ✅ Supported **(features, bugs, support, docs, html transcripts)**
| 3.4.0 | :white_check_mark: | - 🚧 Maintenance **(support, docs, html transcripts)**
| 3.3.0 | 🟧 | - 🟧 Deprecated **(docs)**
| 3.2.2 | 🟧 | - ❌ Fully Deprecated
| < 3.2.2 | :x: |
## Reporting a Vulnerability | Version | Supported | Notes |
|------------|-----------|--------------------------------|
| 4.0.0-beta | 🟦 | For v4.0.0 Full Release |
| 3.5.8 | ✅ | Supported until October 2024 |
| 3.5.7 | ✅ | Supported until September 2024 |
| 3.5.6 | 🟧 | Documentation Only |
| < 3.5.6 | 🟧 | Documentation Only |
| < 3.5.0 | ❌ | |
You can report Vulnerabilities, errors & bugs in the following ways: ### 🕷️ 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)!
- Creating an issue on github When you report a problem, please **give a small description** about what & how it happend.<br>
- Creating a ticket in our discord server Try to explain the issue in as much detail as possible.
- Reporting the bug in DM on discord (DJj123dj#1706)
- Emailing support@dj-dj.be
If your report an error, be clear about what is going on. If possible, try to provide screenshots!
Specify the version & language of the bot together with when the error happend. (for example: when I click the close button)
Send screenshots from the error if possible, and send openticketdebug.txt (or a screenshot of it) to us.
Don't just report the error and never reply again! It can be possible that we need you for more information!
## Contributing ### Please upload the `otdebug.txt` file together with your bug report!
Visit [Contributing.md](/.github/CONTRIBUTING.md) for rules about translating & adding features!
<br> ---
SECURITY POLICY - Last updated: 23/3/2023<br> <img src="https://apis.dj-dj.be/cdn/openticket/logo.png" alt="Open Ticket Logo" width="170px">
© DJdj Development<br><br>
Website: https://www.dj-dj.be <br> **Security Policy**<br>
Discord: https://discord.dj-dj.be <br> [changelog](https://otgithub.dj-dj.be/releases) - [documentation](https://otdocs.dj-dj.be) - [tutorial](https://www.youtube.com/watch?v=2jK9kAf6ASU) - [website](https://openticket.dj-dj.be) - [discord](https://discord.dj-dj.be)<br>
Email: support@dj-dj.be <br>
Open Ticket website: https://openticket.dj-dj.be © 2024 - [DJdj Development](https://www.dj-dj.be) - [Terms](https://www.dj-dj.be/terms#terms) - [Privacy Policy](https://www.dj-dj.be/terms#privacy)
+11 -17
View File
@@ -1,22 +1,16 @@
node_modules/ node_modules/
package-lock.json package-lock.json
devconfig.json devconfig/
devconfig1.json devdatabase/
devconfig2.json otdebug.txt
devconfig3.json
devconfig4.json
devconfig5.json
.DS_Store .DS_Store
openticketdebug.txt */.DS_Store
developerChangelog.md */*/.DS_Store
storage/dynamicDB/ */*/*/.DS_Store
storage/slashcmdEnabled.txt **/.DS_Store
storage/database.json TEMP/
storage/tsdatabase.json
storage/.DS_Store
.vscode/ .vscode/
livestatus.json
test.js
devtsconfig.json
plugins/* plugins/*
!plugins/example.plugin.js !plugins/example-plugin/
dist/
database/openticket.sqlite
+156 -59
View File
@@ -1,72 +1,169 @@
<img src="https://www.dj-dj.be/wp-content/uploads/2023/02/open-ticket-cropped.png" alt="Open Ticket" width="600px"> > ### 🎥 Content Creators 🎥
> Hey there! We're searching for content creators that would want to create a tutorial or setup guide for Open Ticket!<br>
> [📌 More Information](.github/CONTENT_CREATORS.md)
---
[![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.4.0-brightgreen.svg?style=flat-square)](https://github.com/DJj123dj/open-ticket/releases/tag/v3.4.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) [![stars](https://img.shields.io/github/stars/djj123dj/open-ticket?color=yellow&label=stars&logo=github&style=flat-square)](https://docs.openticket.dj-dj.be) <p align="center">
<img src="https://apis.dj-dj.be/cdn/openticket/logo.png" alt="Open Ticket" width="650px">
<br>Powered By<br>
<img src="https://apis.dj-dj.be/cdn/opendiscord/logo.png" alt="Open Ticket" width="170px"><br>
<a href="https://discord.com/invite/26vT9wt3n3"><img alt="Discord Invite Link" src="https://img.shields.io/badge/discord-support%20server-5865F2.svg?style=flat-square&logo=discord"></img></a>
<a href="https://github.com/DJj123dj/open-ticket/releases/tag/v4.0.0"><img alt="Open Ticket Version" src="https://img.shields.io/badge/version-4.0.0-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/DJj123dj/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>
</p>
### Open Ticket <p align="center">
Open Ticket is of the most customisable discord ticket bots of all time! Open Ticket is the most advanced & customisable discord ticket bot that you will ever find! You can customise up to 300+ variables! This includes <code>Html Transcripts</code>, <code>Advanced Plugins</code>, <code>Custom Embeds</code>, <code>Questions/Modals</code>, <code>Stats</code> & more!
You have more than +100 options to customise in the config! This includes html transcripts, unlimited tickets, custom embeds & more! You're also able to customise every little aspect of the bot! From embeds to transcripts. Open Ticket is also translated in more than <code>19 Languages</code>! If you need any help, feel free to join our <a href="https://discord.dj-dj.be">discord server</a>!
We also have a great support service, we can solve every question you have about open ticket! We even provide free 24/7 hosting if you want! </p>
Take a look at all the features and discover the possibilities! <p align="center"><b>⭐️ Help us grow by giving a star! ⭐️</b></p>
### [Documentation](https://docs.openticket.dj-dj.be/quick-start)
## Features > [!WARNING]
- **🎉 NEW! html transcripts V2!** > Open Ticket v4 is still in beta! Please report all bugs in our [discord server](https://discord.dj-dj.be)!<br>
- 🔒 close, ❌ delete & ✅ re-open tickets > The translation count may not be accurate!
- 🇬🇧 translation in 18 different languages
- 📄 very advanced customisation
- 🆗 buttons or 🔽 dropdowns!
- 🆒 plugins
- ∞ unlimited tickets & unlimited messages
- ➕➖ add/remove users from a ticket
- /slash & text commands
<details> ### 📌 Features
<summary><b>Click here for even more features!</b></summary> - **💩 no bloat/credits** - Your Open Ticket bot doesn't contain any form of bloat or credits!
- **📈 scalable** - Open Ticket is made to handle huge servers! Even if your server contains more than 100k members!
- **📄 html transcripts** - Make use of the most customisable, beautiful and easy-to-use HTML Transcripts!
- **✅ ticket actions** - Close, Reopen, Delete, Rename & Move all your tickets!
- **🇬🇧 translation** - Open Ticket has been translated in more than **16 languages** by our community!
- **🎨 customisation** - Open Ticket has been created around customisation, everything can be customised!
- **🖥️ interactions** - The bot has full support for Buttons, Dropdowns, Slash Commands and Modals!
- **∞ unlimited everywhere** - Create an infinite amount of tickets & panels!
- **📝 advanced plugins** - Create the most advanced plugins that you want or use premade ones by our community!
- **👥 user management** - Add & Remove users from all tickets!
- **📊 detailed stats** - Open Ticket has ticket, user & global staticstics available for everyone!
- **🚫 blacklist** - Blacklist users to prevent them from creating a ticket!
- **❓ questions** - Let users answer questions in a modal before the ticket is created!
- **📦 commands** - Open Ticket supports both slash & text commands!
- **📥 extra types** - The bot also supports Reaction Roles & Url Buttons, because why not ¯\\_(ツ)_/¯
- **🎛️ dependencies** - We try to use as little external dependencies as needed!
- **📢 commands** - The bot contains more than 25 commands! And it's expandable with plugins!
> ### 📦 Resources
> Resources might not be accurate yet! *(because v4 is still in beta)*<br>
> <a href="https://www.youtube.com/watch?v=2jK9kAf6ASU"><img src="https://apis.dj-dj.be/cdn/openticket/open-ticket-tutorial.png" alt="Open Ticket Tutorial" width="180px"></a>
> <a href="https:/otdocs.dj-dj.be"><img src="https://apis.dj-dj.be/cdn/openticket/open-ticket-docs.png" alt="Open Ticket Docs" width="180px"></a>
> <a href="https://github.com/DJj123dj/open-discord-plugins"><img src="https://apis.dj-dj.be/cdn/openticket/open-ticket-plugins.png" alt="Open Ticket Plugins" width="180px"></a>
## 📸 Preview
<img alt="Ticket Message" width="550px" src="https://apis.dj-dj.be/cdn/openticket/preview-v4/ticket.png">
<img alt="Ticket Stats Message" width="550px" src="https://apis.dj-dj.be/cdn/openticket/preview-v4/stats.png">
<img alt="Example Panel 1" width="550px" src="https://apis.dj-dj.be/cdn/openticket/preview-v4/panel-1.png">
<img alt="Example Panel 2" width="550px" src="https://apis.dj-dj.be/cdn/openticket/preview-v4/panel-2.png">
## 🧩 Plugins
View all available Open Ticket plugins in our [Official Plugin Repository](https://github.com/DJj123dj/open-discord-plugins)!
### 📦 Official *(made by DJdj Development)*
|Name |Category |Description |
|---------------------------------------------------------------------|----------------------------|-------------------------|
|[`example-plugin`](https://github.com/DJj123dj/open-discord-plugins/tree/main/open-ticket/example-plugin/) |Example |This is just an example plugin for people that want to create their own plugin. |
|[`example-command`](https://github.com/DJj123dj/open-discord-plugins/tree/main/open-ticket/example-command/) |Example |Sample custom command using the Open Discord system. |
|[`ot-jump-to-top`](https://github.com/DJj123dj/open-discord-plugins/tree/main/open-ticket/ot-jump-to-top/) |Command |Add a simple command to jump to the top of the ticket. |
|[`ot-kill-switch`](https://github.com/DJj123dj/open-discord-plugins/tree/main/open-ticket/ot-kill-switch/) |Command |Temporarily disable the ticket system using a kill switch. |
|[`ot-rename-keep-prefix`](https://github.com/DJj123dj/open-discord-plugins/tree/main/open-ticket/ot-rename-keep-prefix/) |Channel Management |Simple plugin to keep the channel prefix when using the /rename command. |
|[`ot-no-slash-clear`](https://github.com/DJj123dj/open-discord-plugins/tree/main/open-ticket/ot-no-slash-clear/) |Development |Disable the automatic removal of slash commands that aren't used by Open Ticket. |
|[`ot-better-status`](https://github.com/DJj123dj/open-discord-plugins/tree/main/open-ticket/ot-better-status/) |Client Activity |An advanced status plugin to rotate between states. It also allows for the use of variables. |
|[`ot-sqlite-database`](https://github.com/DJj123dj/open-discord-plugins/tree/main/open-ticket/ot-sqlite-database/) |Database |With this plugin, the database will be an SQLite file. It's a must-have for large servers! |
|[`ot-ticket-message-extras`](https://github.com/DJj123dj/open-discord-plugins/tree/main/open-ticket/ot-ticket-message-extras/) |Customisation |A plugin which adds a few little features to the ticket message. |
- very customisable ### ✅ Verified *(made by community)*
- close tickets with reason |Name |Author |Category |Description |
- also includes reaction roles! |---------------------------------------------------------------------|----------------------------|----------------------------|-------------------------|
- discord interaction buttons |[`ot-config-reload`](https://github.com/DJj123dj/open-discord-plugins/tree/main/open-ticket/ot-config-reload/) |guillee.3 |Config |This plugin adds a new command that allows reloading the Open Ticket config files without the need for a restart. |
- discord.js 14 |[`ot-feedback`](https://github.com/DJj123dj/open-discord-plugins/tree/main/open-ticket/ot-feedback/) |an_developer |Feedback System |A plugin to gather feedback of your support service. |
</details>
## preview ## 🛠️ Contributors
Images coming soon<br> ### 🖥️ Team
You can already see some images at our [documentation!](https://docs.openticket.dj-dj.be) The team behind Open Ticket!
<table>
<tr>
<td><img src="https://github.com/DJj123dj.png" alt="Profile Picture" width="80px"></td>
<td><img src="https://github.com/Sank34.png" alt="Profile Picture" width="80px"></td>
</tr>
<tr>
<th><a href="https://github.com/DJj123dj">DJj123dj</a></th>
<th><a href="https://github.com/Sank34">Sanke</a></th>
</tr>
</table>
### ❤️ Sponsors
A big thanks to all our sponsors! Without them, it wouldn't be possible to create this project!
## credits <table>
DJdj Development Team <tr>
|Main Developer|Developer|Support Team|Designer| <td><img src="https://github.com/roppl3r.png" alt="Profile Picture" width="80px"></td>
|--------------|---------|-----------|---------| </tr>
|DJj123dj |Sanke |DJ-Lite |vuur_draak| <tr>
<th><a href="https://github.com/roppl3r">roppl3r</a></th>
</tr>
</table>
Translators **Past Sponsors:**<br>
|Language |Translator | <a href="https://github.com/sponsors/DJj123dj">
|--------------|-------------------------| <img src="https://github.com/SpyEye2.png" alt="SpyEye" width="40px">
|Dutch |DJj123dj#1706 | <img src="https://github.com/mods-hd.png" alt="Mods HD" width="40px">
|Romanian |Sanke#6086 | <img src="https://github.com/DOSEV5.png" alt="DOSEV5" width="40px">
|French |Sanke#6086 | </a>
|Spanish |Redactado#1673 & josuens14#5267|
|German |david.#8276 |
|Italian |Maurizio#0268 |
|Czech |t0miiis#3022 |
|Arabic |ChilledBroke#9986 & M4#5882|
|Danish |the_gamer#5095 |
|Portuguese |QuirAddon#9778 |
|Russian |Apexo#0723 |
|Turkish |Hydrâelčhâvø#1575 |
|Polish |MKevas#8311 |
|Slovenian |n1kkec#5341 |
|Thai |Mods HD#0661 |
|Norwegian |NoOneNook#0266 |
|Greek |ꙅoᴎɒᎸɘƚꙅ#3744 |
## links ### 💬 Translators
current version: _v3.4.0_ |Language |Maintainer (discord name) |Status |
</br>changelog: [click here](https://docs.openticket.dj-dj.be/other/changelog) |---------------------|--------------------------|-----------------------------|
</br>documentation: [click here](https://docs.openticket.dj-dj.be/quick-start) |🇬🇧 English |djj123dj |🟢 Up To Date |
|🇳🇱 Dutch |djj123dj |🟢 Up To Date |
|🇩🇪 German |benzorich |🟢 Up To Date |
|🇪🇸 Spanish |redactado & josuens |🟢 Up To Date |
|🇵🇹 Portuguese |quiradon |🟢 Up To Date |
|❓ Catalan |guillee3 |🟢 Up To Date |
|🇨🇿 Czech |spyeye_ |🟢 Up To Date |
|🇭🇺 Hungarian |kornel0706 |🟢 Up To Date |
|🇷🇴 Romanian |sankedev |🟢 Up To Date |
|🇺🇦 Ukrainian |anderskiy |🟢 Up To Date |
|🇮🇩 Indonesian |erxg |🟢 Up To Date |
|🇮🇹 Italian |fraden1mvp. |🟢 Up To Date |
|🇩🇰 Danish |the_gamer |🟢 Up To Date |
|🇹🇭 Thai |modshd |🟢 Up To Date |
|🇹🇷 Turkish |palestinian |🟢 Up To Date |
|🇫🇷 French |guillee.3 |🟢 Up To Date |
|🇦🇪 Arabic |palestinian |🟢 Up To Date |
|🇪🇪 Estonian |iamnotmega |🔵 Up To Date (ChatGPT) |
|🇫🇮 Finnish |iamnotmega |🔵 Up To Date (ChatGPT) |
|🇷🇺 Russian |apexo & ander |🟠 Temporary Outdated (beta) |
|🇵🇱 Polish |mkevas |🟠 Temporary Outdated (beta) |
|🇳🇴 Norwegian |noonenook |🟠 Temporary Outdated (beta) |
|❓ Kurdish |raze.hama |🟠 Temporary Outdated (beta) |
|❓ Persian |sasanwm |🟠 Temporary Outdated (beta) |
|🇱🇻 Latvian |ronalds1398 |🟠 Temporary Outdated (beta) |
|🇯🇵 Japanese |iamnotmega |🟠 Temporary Outdated (beta) |
|🇰🇷 Korean |iamnotmega |🟠 Temporary Outdated (beta) |
|🇨🇳 Simplified Chinese |iamnotmega |🟠 Temporary Outdated (beta) |
|🇨🇳 Traditional Chinese|iamnotmega |🟠 Temporary Outdated (beta) |
|🇸🇪 Swedish |iamnotmega |🟠 Temporary Outdated (beta) |
|🇻🇳 Vietnamese |iamnotmega |🟠 Temporary Outdated (beta) |
|🇸🇮 Slovenian |n1kkec |🔴 Outdated |
|🇬🇷 Greek |stefanos |🔴 Outdated |
© 2023 - DJdj Development | [website](https://www.dj-dj.be) | [discord](https://discord.dj-dj.be) | [terms of service](https://www.dj-dj.be/terms) ## ⭐️ Star History
Please help us grow by giving a star! It would help us a lot!
<a href="https://star-history.com/#DJj123dj/open-ticket&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=DJj123dj/open-ticket&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=DJj123dj/open-ticket&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=DJj123dj/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) - [tutorial](https://www.youtube.com/watch?v=2jK9kAf6ASU) - [website](https://openticket.dj-dj.be) - [discord](https://discord.dj-dj.be)<br>
© 2024 - [DJdj Development](https://www.dj-dj.be) - [Terms](https://www.dj-dj.be/terms#terms) - [Privacy Policy](https://www.dj-dj.be/terms#privacy)
-72
View File
@@ -1,72 +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
}
const hiddendata = bot.hiddenData.readHiddenData(msg.channel.id)
if (hiddendata.length < 1) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.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",async (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
}
await interaction.deferReply()
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.editReply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
interaction.channel.permissionOverwrites.create(user.id, { ViewChannel:true, AddReactions:true,AttachFiles:true, EmbedLinks:true, SendMessages:true})
interaction.editReply({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())
})
}
-118
View File
@@ -1,118 +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 change.js")
if (!DISABLE.commands.text.change) client.on("messageCreate", async msg => {
if (!msg.content.startsWith(config.prefix+"change")) return
if (!msg.guild) return
if (!permsChecker.command(msg.author.id,msg.guild.id)){
permsChecker.sendUserNoPerms(msg.author)
return
}
const hiddendata = bot.hiddenData.readHiddenData(msg.channel.id)
if (hiddendata.length < 1) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
const list = []
config.options.forEach((o) => list.push(o.id))
var newtype = msg.content.split(config.prefix+"change")[1].substring(1)
if (!newtype) return msg.channel.send({embeds:[bot.errorLog.invalidIdChooseFromList(list,l.errors.missingArgsDescription+" `<type>`:\n`"+config.prefix+"change <type>`")]})
const newTicket = require("../core/utils/configParser").getTicketById(newtype)
if (!newTicket) return msg.channel.send({embeds:[bot.errorLog.invalidIdChooseFromList(list,l.errors.missingArgsDescription+" `<type>`:\n`"+config.prefix+"change <type>`")]})
/**@type {String} */
var chName = msg.channel.name
const splitted = chName.split("-")
const prefix = splitted.shift()
const name = (splitted.length > 0) ? splitted.join("-") : prefix
if (newTicket.category){
const parent = await msg.guild.channels.fetch(newTicket.category,{cache:true})
if (parent && parent.type == discord.ChannelType.GuildCategory) msg.channel.setParent(parent)
}
msg.channel.setName(newTicket.channelprefix+name)
msg.channel.send({embeds:[bot.embeds.commands.changeEmbed(msg.author,newtype)]})
log("command","someone used the 'change' command",[{key:"user",value:msg.author.tag}])
log("system","ticket type changed",[{key:"user",value:msg.author.tag},{key:"ticket",value:name},{key:"newtype",value:newtype}])
APIEvents.onCommand("change",permsChecker.command(msg.author.id,msg.guild.id),msg.author,msg.channel,msg.guild,new Date())
})
if (!DISABLE.commands.slash.change) client.on("interactionCreate",async (interaction) => {
if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "change") return
if (!interaction.guild) return
if (!permsChecker.command(interaction.user.id,interaction.guild.id)){
permsChecker.sendUserNoPerms(interaction.user)
return
}
await interaction.deferReply()
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.editReply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
const list = []
config.options.forEach((o) => list.push(o.id))
var newtype = interaction.options.getString("type",true)
const newTicket = require("../core/utils/configParser").getTicketById(newtype,true)
if (!newTicket) return interaction.editReply({embeds:[bot.errorLog.invalidIdChooseFromList(list,l.errors.missingArgsDescription+" `<type>`:\n`"+config.prefix+"change <type>`")]})
/**@type {discord.PermissionOverwriteManager} */
const prePermsManager = interaction.channel.permissionOverwrites
const prePerms = prePermsManager.cache
/**@type {String} */
var chName = interaction.channel.name
const splitted = chName.split("-")
const prefix = splitted.shift()
const name = (splitted.length > 0) ? splitted.join("-") : prefix
if (newTicket.category){
const parent = await interaction.guild.channels.fetch(newTicket.category,{cache:true})
if (parent && parent.type == discord.ChannelType.GuildCategory) interaction.channel.setParent(parent)
}
await prePermsManager.set(prePerms)
interaction.channel.setName(newTicket.channelprefix+name)
var newHiddendata = hiddendata.data
newHiddendata.find((value,index) => {
if (value.key == "type"){
newHiddendata[index] = {key:"type",value:newtype}
}
})
const prevDescription = bot.hiddenData.removeHiddenData(firstmsg.embeds[0].description).description
const newData = bot.hiddenData.writeHiddenData("ticketdata",newHiddendata)
const newDescription = prevDescription+newData
const newEmbed = new discord.EmbedBuilder(firstmsg.embeds[0].data)
.setDescription(newDescription)
firstmsg.edit({embeds:[newEmbed]})
interaction.editReply({embeds:[bot.embeds.commands.changeEmbed(interaction.user,newtype)]})
log("command","someone used the 'change' command",[{key:"user",value:interaction.user.tag}])
log("system","ticket type changed",[{key:"user",value:interaction.user.tag},{key:"ticket",value:name},{key:"newtype",value:newtype}])
APIEvents.onCommand("change",permsChecker.command(interaction.user.id,interaction.guild.id),interaction.user,interaction.channel,interaction.guild,new Date())
})
}
-100
View File
@@ -1,100 +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 embed = discord.EmbedBuilder
const storage = bot.storage
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
}
const hiddendata = bot.hiddenData.readHiddenData(msg.channel.id)
if (hiddendata.length < 1) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
hiddendata.push({key:"claimedby",value:claimingUser.id})
bot.hiddenData.writeHiddenData(msg.channel.id,hiddendata)
storage.set("claimData",msg.channel.id,claimingUser.id)
const newEmbed = new embed(firstmsg.embeds[0].data)
.setFooter({text:"claimed by: "+msg.author.tag,iconURL:msg.author.displayAvatarURL()})
if (firstmsg.components[0].components[1] && firstmsg.components[0].components[1].disabled){
firstmsg.edit({components:[bot.buttons.firstmsg.firstmsgRowDisabledNoClaim],embeds:[newEmbed]})
}else{
firstmsg.edit({components:[bot.buttons.firstmsg.firstmsgRowNormalNoClaim],embeds:[newEmbed]})
}
msg.channel.send({embeds:[bot.embeds.commands.claimEmbed(claimingUser,msg.author)]})
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.onTicketClaim(msg.author,loguser,msg.channel,msg.guild,new Date(),{status:"open",name:msg.channel.name,ticketOptions:ticketData})
APIEvents.onCommand("claim",permsChecker.command(msg.author.id,msg.guild.id),msg.author,msg.channel,msg.guild,new Date())
})
if (!DISABLE.commands.slash.claim) client.on("interactionCreate",async (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.reply({content:":x: "+l.errors.noPermsTitle,ephemeral:true})
}
await interaction.deferReply()
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.editReply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
hiddendata.push({key:"claimedby",value:user.id})
bot.hiddenData.writeHiddenData(interaction.channel.id,hiddendata)
storage.set("claimData",interaction.channel.id,user.id)
interaction.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 newEmbed = new embed(firstmsg.embeds[0].data)
.setFooter({text:"claimed by: "+user.tag,iconURL:user.displayAvatarURL()})
if (firstmsg.components[0].components[1] && firstmsg.components[0].components[1].disabled){
firstmsg.edit({components:[bot.buttons.firstmsg.firstmsgRowDisabledNoClaim],embeds:[newEmbed]})
}else{
firstmsg.edit({components:[bot.buttons.firstmsg.firstmsgRowNormalNoClaim],embeds:[newEmbed]})
}
})
interaction.editReply({embeds:[bot.embeds.commands.claimEmbed(user,interaction.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:user.tag}])
const ticketData = require("../core/utils/configParser").getTicketById(ticketId,true)
APIEvents.onTicketClaim(interaction.user,user,interaction.channel,interaction.guild,new Date(),{status:"open",name:interaction.channel.name,ticketOptions:ticketData})
APIEvents.onCommand("claim",permsChecker.command(interaction.user.id,interaction.guild.id),interaction.user,interaction.channel,interaction.guild,new Date())
})
}
-85
View File
@@ -1,85 +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
const hiddendata = bot.hiddenData.readHiddenData(msg.channel.id)
if (hiddendata.length < 1) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
if (hiddendata.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").closeManager(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",async(interaction) => {
if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "close") return
//interaction.deferReply()
const reason = interaction.options.getString("reason") ? interaction.options.getString("reason") : false
await interaction.deferReply()
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.editReply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
if (hiddendata.find(h => h.key == "pendingdelete")) return interaction.editReply({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.editReply({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").closeManager(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())
})
}
-78
View File
@@ -1,78 +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
}
const hiddendata = bot.hiddenData.readHiddenData(msg.channel.id)
if (hiddendata.length < 1) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.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").closeManager(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",async (interaction) => {
if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "delete") return
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)]})
}
await interaction.deferReply()
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.editReply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
interaction.editReply({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").closeManager(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())
})
}
-57
View File
@@ -1,57 +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.color)
.setTitle("❔ "+l.helpMenu.title)
const header = l.helpMenu.header2
helpEmbed.setDescription(header+"`"+prefix+msgName+" <id>` ➜ _"+l.helpMenu.msgCmd+"_\n\n`"+prefix+"rename <name>` ➜ _"+l.helpMenu.renameCmd+"_\n`"+prefix+"close [reason]` ➜ _"+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+"_\n\n`"+prefix+"change <newtype>` ➜ _"+l.helpMenu.changeCmd+"_\n`"+prefix+"claim [user]` ➜ _"+l.helpMenu.claimCmd+"_\n`"+prefix+"unclaim` ➜ _"+l.helpMenu.unclaimCmd+"_")
helpEmbed.addFields([
{name:"Autoclose",value:l.helpMenu.autocloseCmd+"\n`"+prefix+"autoclose enable <inactive time>`\n`"+prefix+"autoclose disable`"}
])
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())
})
}
-72
View File
@@ -1,72 +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
}
const hiddendata = bot.hiddenData.readHiddenData(msg.channel.id)
if (hiddendata.length < 1) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.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.deferReply()
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.editReply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
interaction.channel.permissionOverwrites.delete(user.id)
interaction.editReply({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())
})
}
-87
View File
@@ -1,87 +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
}
const hiddendata = bot.hiddenData.readHiddenData(msg.channel.id)
if (hiddendata.length < 1) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.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",async (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
}
await interaction.deferReply()
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.editReply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.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.editReply({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())
})
}
-51
View File
@@ -1,51 +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
const hiddendata = bot.hiddenData.readHiddenData(msg.channel.id)
if (hiddendata.length < 1) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
if (hiddendata.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
await interaction.deferReply()
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.editReply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
if (hiddendata.data.find(h => h.key == "pendingdelete")) return interaction.editReply({embeds:[bot.errorLog.warning("Warning!","You can't re-open a ticket while it's being deleted!")]})
await interaction.editReply({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.invalidIdChooseFromList(msgIds,l.errors.missingArgsDescription+" `<id>`:\n`"+config.prefix+"msg <id>`")]})
if (!msgIds.includes(id)) return msg.channel.send({embeds:[bot.errorLog.invalidIdChooseFromList(msgIds,l.errors.missingArgsDescription+" `<id>`:\n`"+config.prefix+"msg <id>`")]})
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())
})
}
-123
View File
@@ -1,123 +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 embed = discord.EmbedBuilder
const storage = bot.storage
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
}
const unclaimuser = storage.get("claimData",msg.channel.id)
if (!unclaimuser || unclaimuser == "false") return msg.channel.send({embeds:[bot.errorLog.serverError("This ticket isn't claimed yet!")]})
const hiddendata = bot.hiddenData.readHiddenData(msg.channel.id)
if (hiddendata.length < 1) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
hiddendata.push({key:"claimedby",value:"false"})
bot.hiddenData.writeHiddenData(msg.channel.id,hiddendata)
storage.set("claimData",msg.channel.id,"false")
msg.channel.messages.fetchPinned().then(msglist => {
/**@type {discord.Message} */
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const newEmbed = new embed(firstmsg.embeds[0].data)
const ticketData = require("../core/utils/configParser").getTicketById(ticketId,true)
if (ticketData && ticketData.autoclose.enable){
const footerText = l.commands.autocloseTitle.replace("{0}",ticketData.autoclose.inactiveHours+"h")
newEmbed.setFooter({text:footerText})
}else{
newEmbed.setFooter(null)
}
if (firstmsg.components[0].components[1] && firstmsg.components[0].components[1].disabled){
firstmsg.edit({components:[bot.buttons.firstmsg.firstmsgRowDisabled],embeds:[newEmbed]})
}else{
firstmsg.edit({components:[bot.buttons.firstmsg.firstmsgRowNormal],embeds:[newEmbed]})
}
msg.channel.send({embeds:[bot.embeds.commands.unclaimEmbed(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:unclaimuser}])
APIEvents.onTicketUnclaim(msg.author,msg.channel,msg.guild,new Date(),{status:"open",name:msg.channel.name,ticketOptions:ticketData})
APIEvents.onCommand("unclaim",permsChecker.command(msg.author.id,msg.guild.id),msg.author,msg.channel,msg.guild,new Date())
})
})
if (!DISABLE.commands.slash.unclaim) client.on("interactionCreate",async (interaction) => {
if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "unclaim") return
if (!interaction.guild) return
if (!permsChecker.command(interaction.user.id,interaction.guild.id)){
permsChecker.sendUserNoPerms(interaction.user)
interaction.reply({content:":x: "+l.errors.noPermsTitle,ephemeral:true})
return
}
await interaction.deferReply()
const unclaimuser = storage.get("claimData",interaction.channel.id)
if (!unclaimuser || unclaimuser == "false") return interaction.editReply({embeds:[bot.errorLog.serverError("This ticket isn't claimed yet!")]})
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.editReply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
hiddendata.push({key:"claimedby",value:"false"})
bot.hiddenData.writeHiddenData(interaction.channel.id,hiddendata)
storage.set("claimData",interaction.channel.id,"false")
interaction.channel.messages.fetchPinned().then(msglist => {
/**@type {discord.Message} */
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.editReply({embeds:[bot.errorLog.notInATicket]})
const newEmbed = new embed(firstmsg.embeds[0].data)
const ticketData = require("../core/utils/configParser").getTicketById(ticketId,true)
if (ticketData && ticketData.autoclose.enable){
const footerText = l.commands.autocloseTitle.replace("{0}",ticketData.autoclose.inactiveHours+"h")
newEmbed.setFooter({text:footerText})
}else{
newEmbed.setFooter(null)
}
if (firstmsg.components[0].components[1] && firstmsg.components[0].components[1].disabled){
firstmsg.edit({components:[bot.buttons.firstmsg.firstmsgRowDisabled],embeds:[newEmbed]})
}else{
firstmsg.edit({components:[bot.buttons.firstmsg.firstmsgRowNormal],embeds:[newEmbed]})
}
interaction.editReply({embeds:[bot.embeds.commands.unclaimEmbed(interaction.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:unclaimuser}])
APIEvents.onTicketUnclaim(interaction.user,interaction.channel,interaction.guild,new Date(),{status:"open",name:interaction.channel.name,ticketOptions:ticketData})
APIEvents.onCommand("unclaim",permsChecker.command(interaction.user.id,interaction.guild.id),interaction.user,interaction.channel,interaction.guild,new Date())
})
})
}
-149
View File
@@ -1,149 +0,0 @@
{
"color":"#ffffff",
"serverId":"server id (for slash cmds)",
"token":{
"value":"insert your bot token here",
"fromENV":false
},
"adminRoles":["discord role id"],
"prefix":"!ticket ",
"languageFile":"english",
"status":{
"enabled":true,
"type":"PLAYING",
"text":"!ticket help"
},
"system":{
"maxAmountOfTickets":3,
"dmMessages":false,
"memberRole":"member role (leave empty if you have no member role)",
"closeMode":"adminonly OR normal (select one!)",
"transcripts":"!!!! ALL SETTINGS FOR TRANSCRIPTS ARE LOCATED IN: transcriptconfig.json !!!!",
"showSlashcmdsInHelp":false,
"answerInEphemeralOnOpen":true
},
"SUPPORT":"Take look at our wiki: https://docs.openticket.dj-dj.be or join our discord server: https://discord.dj-dj.be if you need support!",
"options":[
{
"id":"general",
"name":"Question",
"description":"Create this ticket if you have a question.",
"icon":"🎫",
"label":"question",
"type":"ticket",
"color":"gray",
"adminroles":["role id"],
"readonlyAdminroles":["role id"],
"channelprefix":"question-",
"category":"category id (or leave empty)",
"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"
},
"image":{
"enable":false,
"url":"https://www.dj-dj.be/wp-content/uploads/2022/09/pfp-cropped.png"
},
"closedCategory":{
"enable":false,
"id":"category id"
},
"autoclose":{
"enable":false,
"inactiveHours":24
},
"ping":{
"@here":true,
"@everyone":false,
"custom":{
"enable":false,
"roleId":"012345678910"
}
}
},
{
"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.4.0 - I'm a footer!",
"enableFooterImage":false,
"footerImage":"https://www.example.com/catmemes/cat.png",
"enableThumbnail":false,
"thumbnail":"https://www.example.com/catmemes/cat.png",
"enableImage":false,
"image":"https://www.example.com/catmemes/cat.png",
"enableCustomColor":false,
"color":"#ffffff",
"options":["general","apply"],
"other":{
"enableTicketExplaination":true,
"enableMaxTicketsWarning":true,
"customDropdownPlaceholder":{
"enable":false,
"text":"Choose a ticket"
},
"customCategoryText":{
"enable":false,
"text":"choose a category:"
},
"embedTitleURL":{
"enable":false,
"url":"https://www.dj-dj.be/projects/open-ticket"
}
}
}
]
}
+95
View File
@@ -0,0 +1,95 @@
{
"_INFO":{
"support":"https://otdocs.dj-dj.be",
"discord":"https://discord.dj-dj.be",
"version":"open-ticket-v4.0.0"
},
"token":"your bot token here! Or leave empty when you use tokenFromENV",
"tokenFromENV":false,
"mainColor":"#f8ba00",
"language":"english",
"prefix":"!ticket ",
"serverId":"discord server id",
"globalAdmins":["discord role id"],
"slashCommands":true,
"textCommands":true,
"status":{
"enabled":true,
"type":"listening OR watching OR playing OR custom",
"text":"/help",
"status":"online OR invisible OR idle OR dnd"
},
"system":{
"removeParticipantsOnClose":false,
"replyOnTicketCreation":true,
"replyOnReactionRole":true,
"useTranslatedConfigChecker":true,
"preferSlashOverText":true,
"sendErrorOnUnknownCommand":true,
"questionFieldsInCodeBlock":true,
"disableVerifyBars":false,
"useRedErrorEmbeds":true,
"emojiStyle":"before (OR after OR double OR disabled)",
"enableTicketClaimButtons":true,
"enableTicketCloseButtons":true,
"enableTicketPinButtons":true,
"enableTicketDeleteButtons":true,
"enableTicketActionWithReason":true,
"enableDeleteWithoutTranscript":true,
"logs":{
"enabled":false,
"channel":"discord channel id"
},
"limits":{
"enabled":true,
"globalMaximum":50,
"userMaximum":3
},
"permissions":{
"help":"everyone (OR admin OR none OR role id)",
"panel":"admin (OR everyone OR none OR role id)",
"ticket":"none (OR admin OR everyone OR role id)",
"close":"everyone (OR admin OR none OR role id)",
"delete":"admin (OR everyone OR none OR role id)",
"reopen":"everyone (OR admin OR none OR role id)",
"claim":"admin (OR everyone OR none OR role id)",
"unclaim":"admin (OR everyone OR none OR role id)",
"pin":"admin (OR everyone OR none OR role id)",
"unpin":"admin (OR everyone OR none OR role id)",
"move":"admin (OR everyone OR none OR role id)",
"rename":"admin (OR everyone OR none OR role id)",
"add":"admin (OR everyone OR none OR role id)",
"remove":"admin (OR everyone OR none OR role id)",
"blacklist":"admin (OR everyone OR none OR role id)",
"stats":"everyone (OR admin OR none OR role id)",
"clear":"admin (OR everyone OR none OR role id)",
"autoclose":"admin (OR everyone OR none OR role id)",
"autodelete":"admin (OR everyone OR none OR role id)"
},
"messages":{
"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},
"roleAdding":{"dm":false, "logs":true},
"roleRemoving":{"dm":false, "logs":true}
}
}
}
+122
View File
@@ -0,0 +1,122 @@
[
{
"id":"example-ticket",
"name":"Question",
"description":"Create this ticket if you have a question! (or leave empty)",
"type":"ticket",
"button":{
"emoji":"🎫 (or leave empty)",
"label":"question (or leave empty)",
"color":"gray OR red OR green OR blue"
},
"ticketAdmins":["discord role id"],
"readonlyAdmins":["discord role id"],
"allowCreationByBlacklistedUsers":false,
"questions":["example-question-1","example-question-2"],
"channel":{
"prefix":"question-",
"suffix":"user-name OR user-id OR random-number OR random-hex OR counter-dynamic OR counter-fixed",
"category":"category id (or leave empty)",
"closedCategory":"category id (or leave empty)",
"backupCategory":"category id (or leave empty)",
"claimedCategory":[
{"user":"user id","category":"category id"}
],
"description":"This is a question ticket (or leave empty)"
},
"dmMessage":{
"enabled":false,
"text":"Thanks for creating a ticket in our server! (or leave empty)",
"embed":{
"enabled":false,
"title":"Embed Title! (or leave empty)",
"description":"Description (or leave empty)",
"customColor":"#f8ab00 (or leave empty)",
"image":"https://www.example.com/image.png (or leave empty)",
"thumbnail":"https://www.example.com/image.png (or leave empty)",
"fields":[
{"name":"field name","value":"field value","inline":false}
],
"timestamp":false
}
},
"ticketMessage":{
"enabled":true,
"text":"",
"embed":{
"enabled":true,
"title":"Question Ticket",
"description":"Thanks for creating a 'Question' ticket in our server!\nOur support team will help you soon!",
"customColor":"#f8ab00 (or leave empty)",
"image":"https://www.example.com/image.png (or leave empty)",
"thumbnail":"https://www.example.com/image.png (or leave empty)",
"fields":[
{"name":"field name","value":"field value","inline":false}
],
"timestamp":false
},
"ping":{
"@here":true,
"@everyone":false,
"custom":["discord role id"]
}
},
"autoclose":{
"enableInactiveHours":false,
"inactiveHours":24,
"enableUserLeave":true,
"disableOnClaim":false
},
"autodelete":{
"enableInactiveDays":false,
"inactiveDays":7,
"enableUserLeave":true,
"disableOnClaim":false
},
"cooldown":{
"enabled":false,
"cooldownMinutes":10
},
"limits":{
"enabled":false,
"globalMaximum":20,
"userMaximum":3
}
},
{
"id":"example-website",
"name":"Website",
"description":"Go to our website.",
"type":"website",
"button":{
"emoji":"😃",
"label":"Visit our website"
},
"url":"https://www.dj-dj.be"
},
{
"id":"example-role",
"name":"Update Ping",
"description":"Click here to get notified on updates!",
"type":"role",
"button":{
"emoji":"📢",
"label":"Update Ping",
"color":"gray OR red OR green OR blue"
},
"roles":["discord role id"],
"mode":"add&remove OR remove OR add",
"removeRolesOnAdd":["discord role id"],
"addOnMemberJoin":false
}
]
+39
View File
@@ -0,0 +1,39 @@
[
{
"id":"example-embed",
"name":"Example Embed",
"dropdown":false,
"options":["example-ticket","example-website","example-role"],
"text":"",
"embed":{
"enabled":true,
"title":"Tickets:",
"description":"Create a ticket by clicking one of the buttons below!",
"customColor":"#f8ab00 (or leave empty)",
"url":"https://openticket.dj-dj.be (or leave empty)",
"image":"https://www.example.com/image.png (or leave empty)",
"thumbnail":"https://www.example.com/image.png (or leave empty)",
"footer":"Open Ticket v4.0.0 (or leave empty)",
"fields":[
{"name":"field name","value":"field value","inline":false}
],
"timestamp":false
},
"settings":{
"dropdownPlaceholder":"Create a ticket!",
"enableMaxTicketsWarningInText":false,
"enableMaxTicketsWarningInEmbed":true,
"describeOptionsLayout":"simple OR normal OR detailed",
"describeOptionsCustomTitle":"",
"describeOptionsInText":false,
"describeOptionsInEmbedFields":true,
"describeOptionsInEmbedDescription":false
}
}
]
+28
View File
@@ -0,0 +1,28 @@
[
{
"id":"example-question-1",
"name":"Example Question 1",
"type":"short",
"required":true,
"placeholder":"Insert your short answer here!",
"length":{
"enabled":false,
"min":0,
"max":1000
}
},
{
"id":"example-question-2",
"name":"Example Question 2",
"type":"paragraph",
"required":false,
"placeholder":"Insert your long answer here!",
"length":{
"enabled":false,
"min":0,
"max":1000
}
}
]
+57
View File
@@ -0,0 +1,57 @@
{
"general":{
"enabled":false,
"enableChannel":false,
"enableCreatorDM":false,
"enableParticipantDM":false,
"enableActiveAdminDM":false,
"enableEveryAdminDM":false,
"channel":"transcript channel id (or leave empty)",
"mode":"html OR text"
},
"embedSettings":{
"customColor":"#f8ab00 (or leave empty)",
"listAllParticipants":false,
"includeTicketStats":false
},
"textTranscriptStyle":{
"layout":"simple OR normal OR detailed",
"includeStats":true,
"includeIds":false,
"includeEmbeds":true,
"includeFiles":true,
"includeBotMessages":true,
"fileMode":"custom OR channel-name OR channel-id OR user-name OR user-id",
"customFileName":"this-is-a-transcript (or leave empty)"
},
"htmlTranscriptStyle":{
"background":{
"enableCustomBackground":false,
"backgroundColor":"#f8ba00 (or leave empty)",
"backgroundImage":"https://www.example.com/image.png (or leave empty)"
},
"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://transcripts.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
-59
View File
@@ -1,59 +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,
"change":false
},
"slash":{
"help":false,
"msg":false,
"close":false,
"delete":false,
"reopen":false,
"new":false,
"add":false,
"remove":false,
"rename":false,
"claim":false,
"unclaim":false,
"change":false
}
},
"checkerjs":{
"token":false,
"all":false
},
"debug":{
"all":false,
"debuglogs":false
}
}
}
-7
View File
@@ -1,7 +0,0 @@
//ACTIONS:
//EXPORT ACTIONS:
exports.actions = {
}
-454
View File
@@ -1,454 +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 configParser = require("../../utils/configParser")
//EVENT API:
const ticketOpenListeners = []
const ticketCloseListeners = []
const ticketDeleteListeners = []
const ticketReopenListeners = []
const ticketAddListeners = []
const ticketRemoveListeners = []
const ticketClaimListeners = []
const ticketUnclaimListeners = []
const ticketChangeListeners = []
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:configParser.OTTicketOptions}} 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:configParser.OTTicketOptions}} 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:configParser.OTTicketOptions}} 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:configParser.OTTicketOptions}} 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:configParser.OTTicketOptions}} 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.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:configParser.OTTicketOptions}} ticketdata
*/
exports.onTicketClaim = (user,channel,guild,date,ticketdata) => {
//system
bot.errorLog.log("api","user claimed a ticket",[{key:"userid",value:user.id},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id},{key:"ticketdata",value:JSON.stringify(ticketdata)}])
ticketClaimListeners.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:configParser.OTTicketOptions}} ticketdata
*/
exports.onTicketUnclaim = (user,channel,guild,date,ticketdata) => {
//system
bot.errorLog.log("api","user unclaimed a ticket",[{key:"userid",value:user.id},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id},{key:"ticketdata",value:JSON.stringify(ticketdata)}])
ticketUnclaimListeners.forEach((func) => {
try {
func(user,channel,guild,date,ticketdata)
}catch{}
})
}
/**
* @param {String} newtype
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:configParser.OTTicketOptions}} ticketdata
*/
exports.onTicketChange = (newtype,user,channel,guild,date,ticketdata) => {
//system
bot.errorLog.log("api","user changed ticket type",[{key:"newtype",value:newtype},{key:"userid",value:user.id},{key:"channelid",value:channel.id},{key:"guildid",value:guild.id},{key:"ticketdata",value:JSON.stringify(ticketdata)}])
ticketChangeListeners.forEach((func) => {
try {
func(newtype,user,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"|"claim"|"unclaim"|"change"} 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:configParser.OTTicketOptions}} 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:configParser.OTTicketOptions}} 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:configParser.OTTicketOptions}} ticketdata
*/
/**
* @callback TicketTypeChangeEvent
* @param {String} newtype
* @param {discord.User} user
* @param {discord.TextChannel} channel
* @param {discord.Guild} guild
* @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:configParser.OTTicketOptions}} 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 {TicketActionEvent} callback */
const onTicketClaim = (callback) => {
ticketClaimListeners.push(callback)
}
/**@param {TicketActionEvent} callback */
const onTicketUnclaim = (callback) => {
ticketUnclaimListeners.push(callback)
}
/**@param {TicketTypeChangeEvent} callback */
const onTicketChange = (callback) => {
ticketChangeListeners.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,
onTicketClaim,
onTicketUnclaim,
onTicketChange,
onTranscriptCreation,
onCommand,
onReactionRole,
onError
}
-37
View File
@@ -1,37 +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){
try {
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")
}catch{
fs.writeFileSync("./apiDebug.txt","ERROR: "+theError.name+": "+theError.message+"\n"+theError.stack+"\n\n")
}
}
failcount++
totalcount++
}
}
})
require("../startscreen").headerDataPlugins({total:totalcount,success:successcount,error:failcount})
}
-516
View File
@@ -1,516 +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("'token/value' | your token is invalid")
}
if (value.includes(" ")) createError("'token/value' | 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 (!Array.isArray(arrayValue)){
return createError("'"+path+"' | this needs to be an Array!")
}
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"|"array"|"object"} type */
const checkType = (value,type,path) => {
if (type == "boolean"){
if (typeof value != "boolean"){
createError("'"+path+"' | invalid type, this must be a boolean!")
return true
}else return false
}else if (type == "number"){
if (typeof value != "number"){
createError("'"+path+"' | invalid type, this must be a number!")
return true
}else return false
}else if (type == "string"){
if (typeof value != "string"){
createError("'"+path+"' | invalid type, this must be a string!")
return true
}else return false
}else if (type == "array"){
if (!Array.isArray(value)){
createError("'"+path+"' | invalid type, this must be an array!")
return true
}else return false
}else if (type == "object"){
if (typeof value != "object"){
createError("'"+path+"' | invalid type, this must be an object!")
return true
}else return false
}else return false
}
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
checkType(option.adminroles,"array",path+"/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
if (option.thumbnail){
checkType(option.thumbnail.enable,"boolean",path+"/thumbnail/enable")
checkType(option.thumbnail.url,"string",path+"/thumbnail/url")
}else{
createError("'"+path+"/thumbnail' | there is no thumbnail object!")
}
//image
if (option.image){
checkType(option.image.enable,"boolean",path+"/image/enable")
checkType(option.image.url,"string",path+"/image/url")
}else{
createError("'"+path+"/image' | there is no image object!")
}
//closedCategory
if (option.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{
createError("'"+path+"/closedCategory' | there is no closedCategory object!")
}
//autoclose
if (option.autoclose){
checkType(option.autoclose.enable,"boolean",path/"/autoclose/enable")
checkType(option.autoclose.inactiveHours,"number",path/"/autoclose/id")
}else{
createError("'"+path+"/autoclose' | there is no autoclose object!")
}
}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")
}
//OPTIONS!!!
if (checkType(input.options,"array",path+"/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!")
}
})
}
}
//other
//ticket explaination & max tickets warning
if (typeof input.other != "object"){
createError("'"+path+"/other' | this object doesn't exist!")
}else{
checkType(input.other.enableTicketExplaination,"boolean",path+"/other/enableTicketExplaination")
checkType(input.other.enableMaxTicketsWarning,"boolean",path+"/other/enableMaxTicketsWarning")
//customDropdownPlaceholder
if (typeof input.other.customDropdownPlaceholder != "object"){
createError("'"+path+"/other/customDropdownPlaceholder' | this object doesn't exist!")
}else{
checkType(input.other.customDropdownPlaceholder.enable,"boolean",path+"/other/customDropdownPlaceholder/enable")
checkType(input.other.customDropdownPlaceholder.text,"string",path+"/other/customDropdownPlaceholder/text")
if (input.other.customDropdownPlaceholder.enable && input.other.customDropdownPlaceholder.text.length < 1){createError("'"+path+"/other/customDropdownPlaceholder/text' | there is no placeholder text!")}
}
//customCategoryText
if (typeof input.other.customCategoryText != "object"){
createError("'"+path+"/other/customCategoryText' | this object doesn't exist!")
}else{
checkType(input.other.customCategoryText.enable,"boolean",path+"/other/customCategoryText/enable")
checkType(input.other.customCategoryText.text,"string",path+"/other/customCategoryText/text")
if (input.other.customCategoryText.enable && input.other.customCategoryText.text.length < 1){createError("'"+path+"/other/customCategoryText/text' | there is no category text!")}
}
//embedTitleURL
if (typeof input.other.embedTitleURL != "object"){
createError("'"+path+"/other/embedTitleURL' | this object doesn't exist!")
}else{
checkType(input.other.embedTitleURL.enable,"boolean",path+"/other/embedTitleURL/enable")
checkType(input.other.embedTitleURL.url,"string",path+"/other/embedTitleURL/text")
if (input.other.embedTitleURL.enable && input.other.embedTitleURL.url.length < 1){createError("'"+path+"/other/embedTitleURL/url' | there is no url!")}
}
}
}
//--------------------------|
//--------------------------|
//checker => START HERE |
//--------------------------|
//--------------------------|
var configArray = ["color","serverId","token","adminRoles","prefix","languageFile","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.color,"main_color")
checkDiscord("serverid",config.serverId,"server_id")
if (!require("./api/api.json").disable.checkerjs.token && !config.token.fromENV) checkToken(config.token.value)
checkType(config.adminRoles,"array","/main_adminroles")
checkDiscordArray("roleid",config.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") && !lf.startsWith("czech") && !lf.startsWith("danish") && !lf.startsWith("russian") && !lf.startsWith("turkish") && !lf.startsWith("polish") && !lf.startsWith("slovenian") && !lf.startsWith("thai") && !lf.startsWith("norwegian") && !lf.startsWith("greek")){
createError("'languagefile' | invalid language, more info in the wiki")
}
//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:
//max tickets
checkType(config.system.maxAmountOfTickets,"number","system/maxAmountOfTickets")
//enableDMmessages
checkType(config.system.dmMessages,"boolean","system/dmMessages")
//memberRole
checkType(config.system.memberRole,"string","system/memberRole")
if (config.system.memberRole && ![" ","0","false","null","undefined"].includes(config.system.memberRole)){
checkDiscord("roleid",config.system.memberRole,"system/memberRole")
}else{
createWarn("'system/memberRole' | You don't have a member role, but it's recommended!")
}
//closemode
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.showSlashcmdsInHelp,"boolean","system/showSlashcmdsInHelp")
checkType(config.system.answerInEphemeralOnOpen,"boolean","system/answerInEphemeralOnOpen")
//options
config.options.forEach((option,index) => {
checkOption(option,"options/"+index)
})
//messages
config.messages.forEach((message,index) => {
checkMessage(message,"messages/"+index)
})
//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])
if (splitw[3]){splitstring = splitstring+chalk.yellow(splitw[3])}
if (splitw[4]){splitstring = splitstring+chalk.yellow(splitw[4])}
if (splitw[5]){splitstring = splitstring+chalk.yellow(splitw[5])}
}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,82 +0,0 @@
const fs = require("fs")
const location = "./storage/database.json"
/**@returns {[{category:String, key:String, value:String}]}*/
function getData(){
if (fs.existsSync(location)){
return JSON.parse(fs.readFileSync(location).toString())
}else{
fs.writeFileSync(location,"[]")
return []
}
}
/**@param {[{category:String, key:String, value:String}]} data*/
function setData(data){
fs.writeFileSync(location,JSON.stringify(data,null,"\t"))
}
exports.set = (category,key,value) => {
const currentData = getData()
const exists = currentData.find((d) => (d.category == category) && (d.key == key)) ? true : false
var newData = []
if (exists){
currentData.forEach((d,i) => {
if (d.category == category && d.key == key){
newData.push({category,key,value})
}else{
newData.push(d)
}
})
}else{
currentData.push({category,key,value})
newData = currentData
}
setData(newData)
return exists
}
/**
* @param {String} category
* @param {String} key
* @returns {String|false}
*/
exports.get = (category,key) => {
const currentData = getData()
const tempresult = currentData.find((d) => (d.category == category) && (d.key == key))
const result = tempresult ? tempresult.value : false
return result
}
/**
* @param {String} category
* @returns {[{key:String,value:String}]|false}
*/
exports.getCategory = (category) => {
const currentData = getData()
const result = currentData.filter((v) => v.category == category)
return result
}
/**
* @param {String} category
* @param {String} key
* @param {String} value
*/
exports.delete = (category,key) => {
const currentData = getData()
const exists = currentData.find((d) => (d.category == category) && (d.key == key)) ? true : false
var newData = []
if (exists){
currentData.forEach((d,i) => {
if (!(d.category == category && d.key == key)){
newData.push(d)
}
})
}else{
newData = currentData
}
setData(newData)
return exists
}
@@ -1,43 +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
}
this.set("category","key","value")
this.get("category","key",)
this.delete("category","key")
-19
View File
@@ -1,19 +0,0 @@
/**
==================================================================
ALL DATABASE FILES NEED TO EXPORT THE FOLLOWING FUNCTIONS:
- get(category:String,key:String) => String (value)
- set(category:String,key:String,value:String) => Boolean (success)
- delete(category:String,key:String) => Boolean (success)
- getCategory(category:String) => Array[{key:String,value:String}] (key,value)
==================================================================
*/
try {
var db = require("./dynamicfiles/database")
}catch(err){
console.log(err)
console.log("I couldn't find the database file! (location: ./core/dynamicdatabase/storage.js:2)")
process.exit(1)
}
module.exports = db
-155
View File
@@ -1,155 +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 @param {String|undefined} message */
exports.invalidIdChooseFromList = (list,message) => {
const beforemsg = message ? message+"\n\n" : ""
var x = new embed()
.setColor(c.Red)
.setTitle(":x: "+l.errors.chooseFromListTitle)
.setDescription(beforemsg+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.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
}
exports.clearDebugFile = () => {
const fs = require("fs")
if (!fs.existsSync("./openticketdebug.txt")) return
const content = fs.readFileSync("./openticketdebug.txt").toString().split("\n")
if (content.length < 5000) return
for (let i = 0; i < 4000; i++) {
content.shift()
}
const newContent = "==========================\n<OPEN TICKET DEBUG FILE:>\n=========================="+content.join("\n")
fs.writeFileSync("./openticketdebug.txt",newContent)
}
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)
this.clearDebugFile()
}
/**
*
* @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)
}
-87
View File
@@ -1,87 +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.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("OTreopenTicket")
.setDisabled(false)
.setStyle(bs.Success)
.setLabel(l.buttons.reopen)
.setEmoji("✔")
)
exports.closeCommandRowDisabled = new arb()
.addComponents(
new button()
.setCustomId("OTdeleteTicket1")
.setDisabled(true)
.setStyle(bs.Danger)
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
.addComponents(
new button()
.setCustomId("OTreopenTicket")
.setDisabled(true)
.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,115 +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.color
const button = discord.ButtonBuilder
const arb = discord.ActionRowBuilder
const bs = discord.ButtonStyle
exports.firstmsgRowNormal = new arb()
.addComponents(
new button()
.setCustomId("OTclaimTicket")
.setDisabled(false)
.setStyle(bs.Success)
.setLabel("Claim Ticket")
)
.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("OTclaimTicket")
.setDisabled(false)
.setStyle(bs.Success)
.setLabel("Claim Ticket")
)
.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("✖️")
)
exports.firstmsgRowNormalNoClaim = new arb()
.addComponents(
new button()
.setCustomId("OTclaimTicket")
.setDisabled(true)
.setStyle(bs.Secondary)
.setLabel("Claim Ticket")
)
.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.firstmsgRowDisabledNoClaim = new arb()
.addComponents(
new button()
.setCustomId("OTclaimTicket")
.setDisabled(true)
.setStyle(bs.Secondary)
.setLabel("Claim Ticket")
)
.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.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("❌")
)
-144
View File
@@ -1,144 +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.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} closer
* @param {Number} time
* @returns {discord.EmbedBuilder}
*/
exports.autocloseSignalEmbed = (closer,time) => {
const embd = new embed()
.setTitle("⏰ This ticket got closed by Autoclose!")
.setColor(mc)
.setFooter({text:closer.tag,iconURL:closer.displayAvatarURL()})
.setDescription("This ticket has been inactive for `"+time+"h`!")
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 {discord.User} changer
* @param {String} newtype
* @returns {discord.EmbedBuilder}
*/
exports.changeEmbed = (changer,newtype) => {
return new embed()
.setTitle("🔄 "+l.commands.changeTitle.replace("{0}",newtype))
.setColor(mc)
.setFooter({text:changer.tag,iconURL:changer.displayAvatarURL()})
}
@@ -1,59 +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 embed = discord.EmbedBuilder
const mc = config.color
const permsChecker = require("../../../utils/permisssionChecker")
const button = discord.ButtonBuilder
const arb = discord.ActionRowBuilder
const bs = discord.ButtonStyle
module.exports = () => {
//CLAIM
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "OTclaimTicket") return
try {
await interaction.deferUpdate()
}catch{}
if (!interaction.guild) return
if (!permsChecker.command(interaction.user.id,interaction.guild.id)){
permsChecker.sendUserNoPerms(interaction.user)
return
}
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.editReply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
hiddendata.push({key:"claimedby",value:interaction.user.id})
bot.hiddenData.writeHiddenData(interaction.channel.id,hiddendata)
storage.set("claimData",interaction.channel.id,interaction.user.id)
interaction.channel.messages.fetchPinned().then(msglist => {
/**@type {discord.Message} */
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.editReply({embeds:[bot.errorLog.notInATicket]})
const newEmbed = new embed(firstmsg.embeds[0].data)
.setFooter({text:"claimed by: "+interaction.user.tag,iconURL:interaction.user.displayAvatarURL()})
if (firstmsg.components[0].components[1] && firstmsg.components[0].components[1].disabled){
firstmsg.edit({components:[bot.buttons.firstmsg.firstmsgRowDisabledNoClaim],embeds:[newEmbed]})
}else{
firstmsg.edit({components:[bot.buttons.firstmsg.firstmsgRowNormalNoClaim],embeds:[newEmbed]})
}
interaction.channel.send({embeds:[bot.embeds.commands.claimEmbed(interaction.user,interaction.user)]})
})
})
}
@@ -1,72 +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.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
try {
await interaction.deferUpdate()
} catch{}
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
}
}
if (interaction.message.pinned && interaction.message.author.id == client.user.id){
const claimdata = storage.get("claimData",interaction.channel.id)
if (claimdata && claimdata != "false"){
interaction.message.edit({components:[bot.buttons.firstmsg.firstmsgRowDisabledNoClaim]})
}else{
interaction.message.edit({components:[bot.buttons.firstmsg.firstmsgRowDisabled]})
}
}else{
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").closeManager(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.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").closeManager(interaction.member,interaction.channel,prefix,"close",reason,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.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
await 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
}
})
await interaction.message.edit({components:[bot.buttons.close.openRowDisabled]})
await interaction.channel.send({embeds:[bot.embeds.commands.deleteEmbed(interaction.user)]})
await require("../../../ticketActions/ticketCloser").closeManager(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
await 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
}
})
await interaction.message.edit({components:[bot.buttons.close.closeCommandRowDisabled]})
await interaction.channel.send({embeds:[bot.embeds.commands.deleteEmbed(interaction.user)]})
await require("../../../ticketActions/ticketCloser").closeManager(interaction.member,interaction.channel,prefix,"delete",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.color
const button = discord.ButtonBuilder
const arb = discord.ActionRowBuilder
const bs = discord.ButtonStyle
module.exports = () => {
//REOPEN
client.on("interactionCreate",async (interaction) => {
if (!interaction.isButton()) return
if (interaction.customId != "OTreopenTicket") return
await 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.color
const button = discord.ButtonBuilder
const arb = discord.ActionRowBuilder
const bs = discord.ButtonStyle
module.exports = () => {
}
@@ -1,11 +0,0 @@
module.exports = () => {
require("./firstmsg")()
require("./verifyBars")()
//accepted
require("./accepted/closing")()
require("./accepted/reopening")()
require("./accepted/deleting")()
require("./accepted/closingReason")()
require("./accepted/claiming")()
}
@@ -1,100 +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.color
const button = discord.ButtonBuilder
const arb = discord.ActionRowBuilder
const bs = discord.ButtonStyle
module.exports = () => {
//CLOSE
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "OTcloseTicket") return
try {
await interaction.deferUpdate()
} catch{}
interaction.message.edit({components:[bot.buttons.verifybars.closeVerifyBar]})
})
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "OTcloseTicketFalse") return
try {
await interaction.deferUpdate()
} catch{}
if (interaction.message.pinned && interaction.message.author.id == client.user.id){
const claimdata = storage.get("claimData",interaction.channel.id)
if (claimdata && claimdata != "false"){
interaction.message.edit({components:[bot.buttons.firstmsg.firstmsgRowNormalNoClaim]})
}else{
interaction.message.edit({components:[bot.buttons.firstmsg.firstmsgRowNormal]})
}
}else{
interaction.message.edit({components:[bot.buttons.close.openRowNormal]})
}
})
//DELETE
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "OTdeleteTicket") return
try {
await interaction.deferUpdate()
} catch{}
interaction.message.edit({components:[bot.buttons.verifybars.deleteVerifyBar]})
})
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "OTdeleteTicketFalse") return
try {
await interaction.deferUpdate()
} catch{}
if (interaction.message.pinned && interaction.message.author.id == client.user.id){
const claimdata = storage.get("claimData",interaction.channel.id)
if (claimdata && claimdata != "false"){
interaction.message.edit({components:[bot.buttons.firstmsg.firstmsgRowNormalNoClaim]})
}else{
interaction.message.edit({components:[bot.buttons.firstmsg.firstmsgRowNormal]})
}
}else{
interaction.message.edit({components:[bot.buttons.close.openRowNormal]})
}
})
//DELETE NO TRANSCRIPT
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "OTdeleteTicket1") return
try {
await interaction.deferUpdate()
} catch{}
interaction.message.edit({components:[bot.buttons.verifybars.delete1VerifyBar]})
})
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "OTdeleteTicketFalse1") return
try {
await interaction.deferUpdate()
} catch{}
interaction.message.edit({components:[bot.buttons.close.closeCommandRow]})
})
}
-39
View File
@@ -1,39 +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")
const fs = require("fs")
const lfexists = fs.existsSync("./language/"+config.languageFile+".json")
if (lfexists) localLanguage = require("../language/"+config.languageFile+".json")
const errorLog = async () => {
const chalk = await (await import("chalk")).default
require("./startscreen").headerDataLanguage("Something went wrong when loading the language!",true)
}
const successLog = async (language) => {
const chalk = await (await import("chalk")).default
require("./startscreen").headerDataLanguage("sucessfully loaded language "+language,false)
index.actionRecorder.push({
category:"ot.managers.language",
file:"./core/languageManager.js",
time:new Date().getTime(),
type:"language.success"
})
}
if (!localLanguage){
const runError = async () => {
await errorLog()
process.exit(1)
}
runError()
}else{
exports.language = localLanguage
successLog(config.languageFile)
}
-7
View File
@@ -1,7 +0,0 @@
██████╗ ██████╗ ███████╗███╗ ██╗ ████████╗██╗ ██████╗██╗ ██╗███████╗████████╗
██╔═══██╗██╔══██╗██╔════╝████╗ ██║ ╚══██╔══╝██║██╔════╝██║ ██╔╝██╔════╝╚══██╔══╝
██║ ██║██████╔╝█████╗ ██╔██╗ ██║ ██║ ██║██║ █████╔╝ █████╗ ██║
██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║ ██║ ██║██║ ██╔═██╗ ██╔══╝ ██║
╚██████╔╝██║ ███████╗██║ ╚████║ ██║ ██║╚██████╗██║ ██╗███████╗ ██║
╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═╝
-104
View File
@@ -1,104 +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",async (interaction) => {
if (!interaction.isButton() && !interaction.isStringSelectMenu()) return
if (interaction.isButton() && !interaction.customId.startsWith("newR")) return
if (interaction.isStringSelectMenu() && !(interaction.customId == "OTdropdownMenu")) return
bot.actionRecorder.push({
category:"ot.managers.reactionroles",
file:"./core/reactionRoles.js",
time:new Date().getTime(),
type:"reactionRoles.interactionCreated"
})
const optionidRaw = interaction.isStringSelectMenu() ? interaction.values[0] : interaction.customId
if (!optionidRaw.includes("newR")) return
const optionid = optionidRaw.split("newR")[1]
if (!optionid){
interaction.reply({embeds:[bot.errorLog.serverError(l.errors.roleDoesntExist)]})
return
}else{
try {
await interaction.deferUpdate()
} catch{}
}
try {
const option = require("./utils/getButton").getOption(optionid)
/**@type {"add"|"remove"|"add&remove"} */
const mode = option.mode
const user = interaction.member
if (mode == "add"){
bot.actionRecorder.push({
category:"ot.managers.reactionroles",
file:"./core/reactionRoles.js",
time:new Date().getTime(),
type:"reactionRoles.type.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"){
bot.actionRecorder.push({
category:"ot.managers.reactionroles",
file:"./core/reactionRoles.js",
time:new Date().getTime(),
type:"reactionRoles.type.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"){
bot.actionRecorder.push({
category:"ot.managers.reactionroles",
file:"./core/reactionRoles.js",
time:new Date().getTime(),
type:"reactionRoles.type.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.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&remove",apirole,interaction.user,interaction.channel,interaction.guild,new Date())
}else {
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","add&remove",apirole,interaction.user,interaction.channel,interaction.guild,new Date())
}
})
}
}catch{
interaction.channel.send({embeds:[bot.errorLog.serverError(l.errors.somethingWentWrong)]})
}
})
}
-87
View File
@@ -1,87 +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 sid = config.serverId
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})
})
//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)
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)
//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)
}
-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!"))
}
})
}
-271
View File
@@ -1,271 +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
/**@param {Boolean|undefined} invisible*/
module.exports = async (invisible) => {
const chalk = (await import("chalk")).default
const sid = config.serverId
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)")
if (!invisible){
setInterval(() => {
process.stdout.cursorTo(0)
process.stdout.write("[status] there are "+chalk.blue(readystats+" out of 13")+" commands ready! (this can take up to 40 seconds)")
if (readystats >= 13){
console.log(chalk.green("\nready!"))
console.log(chalk.blue("you can now start the bot with "+chalk.bgBlue("'npm start'")+"!"))
process.exit(1)
}
},100)
}
const fs = require("fs")
fs.writeFileSync("./storage/slashcmdEnabled.txt",require("../../package.json").version)
//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++
})
//category
client.application.commands.create({
name:"change",
description:"Change ticket type.",
defaultPermission:true,
type:act.ChatInput,
options:[
{
type:acot.String,
name:"type",
description:"The new ticket type.",
required:true,
choices:choices
}
]
},sid).then(() => {
readystats++
})
}
-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 l = bot.language
const log = bot.errorLog.log
const logo = require("fs").readFileSync("./core/logo.txt").toString()
/**@param {import('chalk').ChalkInstance} chalk */
const showFlags = async (chalk) => {
var isFlag = false
if (process.argv.some((v) => v == "--devconfig")) console.log(chalk.blue("[FLAGS] => used dev config instead of normal config")); isFlag = true
if (process.argv.some((v) => v == "--nochecker")) console.log(chalk.blue("[FLAGS] => disabled checker.js")); isFlag = true
if (process.argv.some((v) => v == "--tsoffline")) console.log(chalk.blue("[FLAGS] => offline check for html transcripts disabled!")); isFlag = true
if (process.argv.some((v) => v == "--debug")) console.log(chalk.blue("[FLAGS] => enabled DEBUG mode")); isFlag = true
if (process.argv.some((v) => v == "--noslash")) console.log(chalk.blue("[FLAGS] => slash commands disabled")); isFlag = true
if (process.argv.some((v) => v == "--localstatus")) console.log(chalk.blue("[FLAGS] => using local livestatus.json")); isFlag = true
if (process.argv.some((v) => v == "--noerrorupload")) console.log(chalk.blue("[FLAGS] => not uploading errors to liveStatus")); isFlag = true
if (!isFlag) console.log(chalk.blue("no flags!"))
}
exports.run = async () => {
const chalk = await (await import("chalk")).default
console.log(chalk.hex("f8ba00")(logo))
const version = require("../package.json").version
var headertext = "v"+version+" - Support: https://discord.dj-dj.be - Language: "+config.languageFile
const spaceamount = (84-headertext.length)/2
var i = 0
while (i < spaceamount){
headertext = " "+headertext
i++
}
console.log(chalk.bold(headertext+"\n"))
console.log(chalk.bold(chalk.underline("FLAGS:")))
showFlags(chalk)
}
/**
* @param {import('chalk').ChalkInstance} chalk
* @param {{type:String,text:String,enabled:Boolean}} status
* @param {Boolean} updatingslash
* @param {Boolean} slashmode
*
*/
exports.headerDataReady = (chalk,status,updatingslash,slashmode) => {
console.log("\n"+chalk.bold(chalk.underline("STARTUP INFO:")))
if (status.enabled) console.log(chalk.hex("f8ba00")("status: ")+chalk.bold(status.type.toLowerCase())+" "+status.text)
if (slashmode){
console.log("\n\n"+chalk.red(chalk.underline("STARTING IN SLASH CMD CONFIGURATION MODE!")))
return
}
console.log(chalk.hex("f8ba00")("updating slash cmds: ")+chalk.bold(updatingslash))
}
var languageMSG = ""
var languageErr = false
/**
* @param {String} message
* @param {Boolean} err
*/
exports.headerDataLanguage = async (message,err) => {
languageMSG = message
languageErr = err
}
/**@param {{total:Number,error:Number,success:Number}} plugins*/
exports.headerDataPlugins = async (plugins) => {
const chalk = await (await import("chalk")).default
const lmsg = languageErr ? chalk.red(languageMSG) : languageMSG
console.log(chalk.hex("f8ba00")("language: ")+lmsg)
console.log(chalk.hex("f8ba00")("plugins loaded: ")+chalk.bold(plugins.total+" total ")+"("+plugins.success+"✅ "+plugins.error+"❌)")
console.log("\n"+chalk.bold(chalk.underline("LIVESTATUS:")))
await require("./utils/liveStatus").run(plugins)
console.log("\n"+chalk.bold(chalk.underline("LOGS:")))
}
-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 storage = bot.storage
module.exports = () => {
setInterval(async () => {
try{
const tickets = storage.getCategory("autocloseTickets")
if (!tickets) return
tickets.forEach(async (t) => {
if (t.value == "false" || t.value == 0 || typeof t.value != "number") return
try{
const channel = await client.channels.fetch(t.key,{cache:true})
if (!channel || !channel.isTextBased()) return
const message = (await channel.messages.fetch({limit:10})).first()
if (!message) return
const secondsSLM = Math.round((new Date().getTime() - message.createdTimestamp)/1000)
const hoursSLM = secondsSLM/3600
if (hoursSLM > t.value){
/**@type {discord.Guild|false} */
const guild = client.guilds.cache.find((g) => g.id == channel.guild.id)
if (!guild) return
const clientMember = guild.members.cache.find((m) => m.id == client.user.id)
if (!clientMember) return
var name = channel.name
var prefix = ""
const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
}
})
require("./ticketCloser").closeManager(clientMember,channel,prefix,"close","OTautoclose",true)
storage.delete("autocloseTickets",channel.id)
channel.send({embeds:[bot.embeds.commands.autocloseSignalEmbed(client.user,t.value)],components:[bot.buttons.close.closeCommandRow]})
}
}catch{
log("system","can't find autoclose channel with ID: "+t.key)
storage.delete("autocloseTickets",t.key)
}
})
}catch{}
},120000)
}
-234
View File
@@ -1,234 +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.closeManager = async (member,channel,prefix,mode,reason,nomessage) => {
const guild = channel.guild
const user = member.user
const chalk = await (await import("chalk")).default
const newReason = reason ? reason : l.messages.none
//start code
//FIX CHANNEL COULD BE CLOSED AFTER DELETE:
if (pendingDelete.includes(channel.id)) return false
/**@type {String}*/
const channelname = channel.name
const ticketOpenerChannelName = channelname.split(prefix)[1]
//get user that opened the ticket
var getuserID = storage.get("userFromChannel",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" || mode == "deletenotranscript"){
//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("amountOfUserTickets",getuserID,Number(storage.get("amountOfUserTickets",getuserID)) - 1)
storage.delete("userFromChannel",channel.id)
storage.delete("claimData",channel.id)
storage.delete("autocloseTickets",channel.id)
if (Number(storage.get("amountOfUserTickets",getuserID)) < 0) storage.set("amountOfUserTickets",getuserID,0)
//getID & send DM & send api event
const hiddendata = bot.hiddenData.readHiddenData(channel.id)
if (hiddendata.length < 1) return channel.send({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.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})
hiddendata.push({key:"pendingdelete",value:"true"})
bot.hiddenData.writeHiddenData(channel.id,hiddendata)
}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.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],
deny:[]
})
}catch{
log("system","invalid role! At 'config.json => main_adminroles:"+index)
}
})
//ticketinfo error
const ticketInfoError = bot.errorLog.serverError("Unable to detect ticket information.\n*(First message that this bot sends)*\n\n__**Possible reasons:**__\n- you unpinned the first message\n- the first message is deleted\n- it has been unpinned & repinned after another message has been pinned.\n\n__**Possible solutions:**__\n- unpin all messages in this channel & repin the first message that this bot sent.\nIf this doesn't work, just delete the ticket manually!")
//add ticket adminroles
const hiddendata = bot.hiddenData.readHiddenData(channel.id)
if (hiddendata.length < 1) return channel.send({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.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!")
}
}
ticketData.adminroles.forEach((role,index) => {
if (!config.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,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages],
deny:[]
})
}catch{
log("system","invalid role! At 'config.json => options/ticket/...:"+index)
}
}
})
channel.permissionOverwrites.set(permissionArray)
if (!nomessage){
//message
const embed = new discord.EmbedBuilder()
.setColor(config.color)
.setTitle(":lock: "+l.commands.closeTitle+" :lock:")
.setDescription(l.messages.closedDescription)
channel.send({embeds:[embed],components:[bot.buttons.close.closeCommandRow]})
}
log("system","closed a ticket",[{key:"user",value:user.tag},{key:"ticket",value:channel.name}])
//send api event
require("../api/modules/events").onTicketClose(user,channel,guild,new Date(),{name:channel.name,status:"closed",ticketOptions:ticketData},newReason)
}
/**
*
* @param {discord.TextChannel} channel
* @param {Number} limit
* @returns
*/
const getmessages = async (channel,limit) => {
const final = []
var lastId = ""
while (true) {
const options = {limit:100}
if (lastId) options.before = lastId
const messages = await channel.messages.fetch(options)
messages.forEach(msg => {final.push(msg)})
lastId = messages.last().id
if (messages.size != 100 || final >= limit) {
break
}
}
return final
}
const transcriptHandler = async () => {
if (!bot.tsconfig.sendTranscripts.enableChannel && !bot.tsconfig.sendTranscripts.enableDM) return false
const APIEvents = require("../api/modules/events")
const messages = await getmessages(channel,5000)
await require("../transcriptSystem/manager")(messages,guild,channel,user,reason)
APIEvents.onTranscriptCreation(messages,channel,guild,new Date())
}
const deleteHandler = async () => {
if (deleteRequired){
pendingDelete.shift()
//delete HIDDENDATA
storage.delete("HIDDENDATA",channel.id)
await channel.delete()
}
}
if (mode == "delete" || mode == "deletenotranscript") await transcriptHandler()
deleteHandler()
}
-245
View File
@@ -1,245 +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",async (interaction) => {
if (!interaction.isStringSelectMenu()) return
if (interaction.customId != "OTdropdownMenu") return
if (interaction.values.includes("OTChooseTicket")){
await 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.isStringSelectMenu() && (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){
await 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()){
try {
await interaction.deferReply({ephemeral:config.system.answerInEphemeralOnOpen})
} catch{}
}else if (interaction.isChatInputCommand()){
await interaction.deferReply({ephemeral:config.system.answerInEphemeralOnOpen})
}else if (interaction.isStringSelectMenu()){
try {
await interaction.deferUpdate()
} catch{}
}
if (storage.get("amountOfUserTickets",interaction.member.id) == null || storage.get("amountOfUserTickets",interaction.member.id) == "false"|| Number(storage.get("amountOfUserTickets",interaction.member.id)) < config.system.maxAmountOfTickets){
//update storage
storage.set("amountOfUserTickets",interaction.member.id,Number(storage.get("amountOfUserTickets",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 no ticket access
permissionsArray.push({
id:interaction.guild.roles.everyone,
type:"role",
allow:[],
deny:[pfb.ViewChannel]
})
//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.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{}
})
//add ticket adminroles
/**
* @type {String[]}
*/
const ticketadmin = currentTicketOptions.adminroles
ticketadmin.forEach((role,index) => {
if (!config.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{}
}
})
//add ticket adminroles
if (currentTicketOptions.readonlyAdminroles){
currentTicketOptions.readonlyAdminroles.forEach((role,index) => {
if (!config.adminRoles.includes(role) && !currentTicketOptions.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.ViewChannel],
deny:[pfb.SendMessages,pfb.AttachFiles,pfb.EmbedLinks]
})
}catch{}
}
})
}
//add member role
if (config.system.memberRole && ![" ","0","false","null","undefined"].includes(config.system.memberRole)){
try {
const userrole = guild.roles.cache.find(r => r.id == config.system.memberRole)
if (userrole){
permissionsArray.push({
id:userrole,
type:"role",
deny:[pfb.ViewChannel]
})
}
}catch{}
}
//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("userFromChannel",ticketChannel.id,interaction.member.id)
if (currentTicketOptions.autoclose.enable) storage.set("autocloseTickets",ticketChannel.id,currentTicketOptions.autoclose.inactiveHours)
bot.hiddenData.writeHiddenData(ticketChannel.id,[{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.color)
.setTitle(currentTicketOptions.name)
//.setFooter({text:"Ticket Type: "+currentTicketOptions.id})
if (currentTicketOptions.autoclose.enable){
const footerText = l.commands.autocloseTitle.replace("{0}",currentTicketOptions.autoclose.inactiveHours+"h")
ticketEmbed.setFooter({text:footerText})
}
if (currentTicketOptions.ticketmessage.length > 0){
ticketEmbed.setDescription(currentTicketOptions.ticketmessage)
}
if (currentTicketOptions.thumbnail.enable) ticketEmbed.setThumbnail(currentTicketOptions.thumbnail.url)
if (currentTicketOptions.image.enable) ticketEmbed.setImage(currentTicketOptions.image.url)
const herePing = currentTicketOptions.ping['@here'] ? " @here" : ""
const everyonePing = currentTicketOptions.ping['@everyone'] ? " @everyone" : ""
const customPing = currentTicketOptions.ping.custom.enable ? " <@&"+currentTicketOptions.ping.custom.roleId+">" : ""
ticketChannel.send({
content:"<@"+interaction.member.id+">"+herePing+everyonePing+customPing,
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})
const channelbutton = new discord.ActionRowBuilder()
.addComponents([
new discord.ButtonBuilder()
.setStyle(discord.ButtonStyle.Link)
.setDisabled(false)
.setEmoji("🎫")
.setLabel(l.commands.goToTicket)
.setURL(ticketChannel.url)
])
try{
if (currentTicketOptions.enableDmOnOpen) interaction.member.send({embeds:[bot.errorLog.custom(l.messages.newTicketDmTitle,currentTicketOptions.message,":ticket:",config.color)],components:[channelbutton]})
}
catch{log("system","failed to send DM")}
if ((interaction.isButton() && config.system.answerInEphemeralOnOpen) || interaction.isChatInputCommand()) interaction.editReply({embeds:[bot.errorLog.success(l.messages.createdTitle,l.messages.createdDescription)],components:[channelbutton]})
})
}else{
try {
if (config.system.dmMessages){
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")}
}
}
})
}
-54
View File
@@ -1,54 +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 no ticket access
permissionsArray.push({
id:guild.roles.everyone,
type:"role",
allow:[],
deny:[pfb.ViewChannel]
})
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:[]
})
}else{
if (p.id != guild.roles.everyone){
permissionsArray.push({
id:p.id,
type:"role",
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
@@ -1,123 +0,0 @@
const discord = require('discord.js')
const bot = require("../../../index")
const tsconfig = bot.tsconfig
const tsembeds = require("../embeds")
const tsdb = require("../tsdb")
const otversion = require("../../../package.json").version
const version = require("../info.json").version
/**@typedef {{style:{enableCustomBackground:Boolean, backgroundModus:"color"|"image", backgroundData:String, titleColor:String}, bot:{name:String, id:Number, pfp:String}, ticket:{creatorname:String, creatorid:Number, closedtime:Number, openedtime:Number}}} OThtsDataOption */
/**==========================================================
=============================================================
================THIS FILE ISN'T USED ANYMORE!!===============
This file is for html transcripts V1!
Visit compileJsonV2.js for the current version!
=============================================================
===========================================================*/
/**
*
* @param {discord.Guild} guild
* @param {discord.Channel} channel
* @param {discord.User} user
* @param {discord.Message[]} messagesInv
* @param {OThtsDataOption} data
*/
exports.compile = (guild,channel,user,messagesInv,data) => {
const messages = messagesInv.reverse()
var invisibleMessages = 0
const rawfiles = messages.filter((m) => Array.from(m.attachments).length > 0)
var fileAmount = 0
rawfiles.forEach((msg) => {
fileAmount = fileAmount + Array.from(msg.attachments).length
})
const messagesArray = []
messages.forEach((msg) => {
if (msg.content || msg.embeds.length > 0 || msg.attachments.toJSON().length > 0){
const embedArray = []
const fileArray = []
msg.attachments.forEach((file) => {
fileArray.push({
name:file.name,
type:file.contentType,
size:file.size.toString()+" bytes",
url:file.url
})
})
msg.embeds.forEach((embed) => {
embedArray.push({
title:embed.title || false,
description:embed.description ? embed.description : false,
authorimg:((embed.author && embed.author.iconURL) ? embed.author.iconURL : false),
authortext:(embed.author ? embed.author.name : false),
footerimg:((embed.footer && embed.footer.iconURL) ? embed.footer.iconURL : false),
footertext:(embed.footer ? embed.footer.text : false),
color:embed.hexColor,
image:((embed.image && embed.image.url) ? embed.image.url : false),
thumbnail:((embed.thumbnail && embed.thumbnail.url) ? embed.thumbnail.url : false),
url:(embed.url ? embed.url : false)
})
})
const memberColor = msg.member ? msg.member.displayHexColor : "#ffffff"
messagesArray.push({
author:{
name:msg.author.tag,
id:Number(msg.author.id),
color:memberColor,
pfp:msg.author.displayAvatarURL()
},
content:msg.content || "",
timestamp:msg.createdTimestamp,
embeds:embedArray,
files:fileArray
})
}else {invisibleMessages++}
})
const result = {
version,otversion,
style:{
backgroundData:data.style.backgroundData || "",
backgroundModus:data.style.backgroundModus || "",
enableCustomBackground:data.style.enableCustomBackground || false,
titleColor:data.style.titleColor || "#F8BA00"
},
bot:{
name:data.bot.name || "Open Ticket",
id:Number(data.bot.id) || 0,
pfp:data.bot.pfp || "dj-dj.be/wp-content/uploads/2022/07/profielfoto-blauw-wit.png?size=128"
},
ticket:{
name:channel.name,
id:Number(channel.id),
guildname:guild.name,
guildid:Number(guild.id),
creatorname:data.ticket.creatorname,
creatorid:Number(data.ticket.creatorid),
closedbyname:user.tag,
closedbyid:Number(user.id),
closedtime:data.ticket.closedtime,
openedtime:data.ticket.openedtime,
messages:Array.from(messages).length-invisibleMessages,
files:fileAmount
},
messages:messagesArray
}
return result
}
@@ -1,394 +0,0 @@
const discord = require('discord.js')
const bot = require("../../../index")
const tsconfig = bot.tsconfig
const tsembeds = require("../embeds")
const tsdb = require("../tsdb")
const otversion = require("../../../package.json").version
const version = require("../info.json").version
const mentions = require("./mentions").replacementions
/**@typedef {{background:{enableCustomBackground:Boolean, backgroundModus:"color"|"image", backgroundData:String}, header:{enableCustomHeader:Boolean, decoColor:String, backgroundColor:String, textColor:String}, stats:{enableCustomStats:Boolean, backgroundColor:String, keyTextColor:String, valueTextColor:String, hideBackgroundColor:String, hideTextColor:String}} OTTranscriptStyle} */
/**@typedef {{name:String, id:String, pfp:String}} OTTranscriptBot */
/**@typedef {{name:String, id:String, guildname:String, guildid:String, guildinvite:String|false, creatorname:String, creatorid:String, closedbyname:String, closedbyid:String, claimedname:String, claimedid:String, creatorpfp:String, closedbypfp:String, claimedpfp:String, closedtime:Number, openedtime:Number, components:{messages:1, files:1, embeds:1, reactions:1, interactions:{dropdowns:1, buttons:1, total:1}, attachments:{invites:1, images:1, gifs:1, stickers:1}}, roleColors:[{id:String,color:String}] }} OTTranscriptTicket */
/**@typedef {{author:{name:String, id:String, color:String, pfp:String, bot:Boolean, verifiedBot:Boolean, system:Boolean}, content:String|false, timestamp:Number, type:"normal", important:Boolean, edited:Boolean, embeds:[{title:String|false, description:String|false, authorimg:String|false, authortext:String|false, footerimg:String|false, footertext:String|false, color:String, image:String|false, thumbnail:String|false, url:String|false, fields:[{name:String,value:String,inline:Boolean}]}], attachments:[{type:"FILE", name:String, fileType:String, size:String, url:String}, {type:"FILE:image", name:String, fileType:String, size:String, url:String}, {type:"URL:invite", guildId:String, guildName:String, guildSize:Number, guildOnline:Number, image:String, url:String}, {type:"URL:gif", url:String}, {type:"BUILDIN:sticker", name:String, url:String}], components:[{type:"buttons", buttons:[{type:"interaction"|"url", label:String|false, icon:String|false, color:"gray"|"green"|"red"|"blue", id:String|false, url:String|false, disabled:Boolean}]}, {type:"dropdown", placeholder:String|false, options:[{label:String|false, icon:String|false, description:String|false, id:String|false}]}, {type:"reactions", reactions:[{amount:1, emoji:String, type:"svg"|"image"|"gif"}]}], reply:{type:"reply"|"command"|false, user:{name:String, id:String, color:String, pfp:String, bot:Boolean, verifiedBot:Boolean, system:Boolean}, replyOptions:{content:String, messageId:String, channelId:String, guildId:String}, commandOptions:{interactionName:String, interactionId:String}}}} OTTranscriptMessage */
/**@typedef {{enabled:Boolean,premiumToken:String, customCredits:{enable:Boolean, replaceText:String, replaceURL:String, enableReportBug:Boolean},customHeaderUrl:{enabled:Boolean, url:String, text:String}, customTranscriptUrl:{enabled:Boolean, name:String}, customFavicon:{enabled:Boolean, image:String},additionalFlags:String[]}} OTTranscriptPremium */
/**@typedef {{version:"2", otversion:String, language:String, style:OTTranscriptStyle, bot:OTTranscriptBot, ticket:OTTranscriptTicket, messages:OTTranscriptMessage[], premium:OTTranscriptPremium}} OTTranscriptCompileInput */
/**@typedef {{style:OTTranscriptStyle,bot:OTTranscriptBot,ticket:OTTranscriptTicket,premium:OTTranscriptPremium}} OTHTMLDataOption */
/**@param {discord.ButtonStyle} buttonstyle */
const buttonStyleToColor = (buttonstyle) => {
if (buttonstyle == discord.ButtonStyle.Primary){
return "blue"
}else if (buttonstyle == discord.ButtonStyle.Secondary){
return "gray"
}else if (buttonstyle == discord.ButtonStyle.Danger){
return "red"
}else if (buttonstyle == discord.ButtonStyle.Success){
return "green"
}else{
return "gray"
}
}
/**
*
* @param {discord.Guild} guild
* @param {discord.Channel} channel
* @param {discord.User} user
* @param {discord.Message[]} messagesInv
* @param {OTHTMLDataOption} data
*/
exports.compile = (guild,channel,user,messagesInv,data) => {
const messages = messagesInv.reverse()
var invisibleMessages = 0
//MESSAGE STATS COUNTS
var messageAmount = messages.length
var fileAmount = 0
var embedAmount = 0
var reactionsAmount = 0
var interactionAmount = 0
messages.forEach((msg) => {
fileAmount = fileAmount + Array.from(msg.attachments).length
embedAmount = embedAmount + msg.embeds.length
msg.reactions.cache.forEach(reaction => {
reactionsAmount = reactionsAmount + reaction.count
})
if (msg.components && msg.components.length > 0){
msg.components.forEach((component) => {
if (component.components.length > 0){
interactionAmount = interactionAmount + component.components.length
}else{
interactionAmount = interactionAmount+1
}
})
}
})
/**@type {OTTranscriptMessage[]} */
const messagesArray = []
messages.forEach((msg) => {
if (msg.content || msg.embeds.length > 0 || msg.attachments.toJSON().length > 0 || msg.components.length > 0 || msg.reactions.cache.size > 0){
const embedArray = []
const attachmentArray = []
const componentsArray = []
msg.attachments.forEach((file) => {
attachmentArray.push({
type:"FILE",
name:file.name,
fileType:file.contentType,
size:Math.round(file.size/1000)+" kb",
url:file.url
})
})
msg.embeds.forEach((embed) => {
embedArray.push({
title:embed.title || false,
description:embed.description ? mentions(embed.description,guild) : false,
authorimg:((embed.author && embed.author.iconURL) ? embed.author.iconURL : false),
authortext:(embed.author ? embed.author.name : false),
footerimg:((embed.footer && embed.footer.iconURL) ? embed.footer.iconURL : false),
footertext:(embed.footer ? embed.footer.text : false),
color:embed.hexColor,
image:((embed.image && embed.image.url) ? embed.image.url : false),
thumbnail:((embed.thumbnail && embed.thumbnail.url) ? embed.thumbnail.url : false),
url:(embed.url ? embed.url : false),
fields:embed.fields
})
})
const tempreactions = []
msg.reactions.cache.forEach((reaction) => {
const count = reaction.count
const emoji = reaction.emoji
if (emoji instanceof discord.GuildEmoji){
//custom emoji
tempreactions.push({
amount:count,
emoji:(emoji.url) ? emoji.url : "",
type:(emoji.animated) ? "gif" : "image"
})
}else if (emoji instanceof discord.ReactionEmoji){
//build-in emoji
tempreactions.push({
amount:count,
emoji:emoji.name,
type:"svg"
})
}
})
componentsArray.push({
type: "reactions",
reactions:tempreactions
})
msg.components.forEach((actionrow) => {
var isdropdown = false
var actioncomponents = []
actionrow.components.forEach((comp) => {
if (comp.type == discord.ComponentType.ActionRow || comp.type == discord.ComponentType.TextInput) return
/**
* type: "buttons";
buttons: [{
type: "interaction" | "url";
label: string | false;
icon: string | false;
color: "gray" | "green" | "red" | "blue";
id: string | false;
url: string | false;
disabled: boolean;
}];
}, {
type: "dropdown";
placeholder: string | false;
options: [{
label: string | false;
icon: string | false;
description: string | false;
id: string | false;
}];
},
*/
if (comp.type == discord.ComponentType.Button){
actioncomponents.push({
type: (comp.style == discord.ButtonStyle.Link) ? "url" : "interaction",
label: (comp.label) ? comp.label : false,
icon: (comp.emoji) ? comp.emoji.name : false,
color: buttonStyleToColor(comp.style),
id: comp.customId ? comp.customId : false,
url: (comp.url) ? comp.url : false,
disabled: false
})
}else{
isdropdown = true
var drpdwnoptions = []
/**@type {discord.APISelectMenuOption[]} */
const dropdownoptions = comp.options
dropdownoptions.forEach((opt) => {
drpdwnoptions.push({
label: opt.label,
icon: (opt.emoji) ? opt.emoji : false,
description: (opt.description) ? opt.description : false,
id: "hello world :)"
})
})
componentsArray.push({
type:"dropdown",
placeholder:false,
options:drpdwnoptions
})
}
})
if (!isdropdown){
componentsArray.push({
type:"buttons",
buttons:actioncomponents
})
}
})
const important = msg.guild ? (msg.content.includes("<@"+msg.guild.id+">") || msg.content.includes("<@everyone") || msg.content.includes("@here")): false
const replytype = (msg.interaction) ? "command" : ((msg.reference) ? "reply" : false)
if (replytype == "command"){
const replycolorRAW = msg.guild.members.cache.find((m) => m.id == msg.interaction.user.id)
const replycolor = (replycolorRAW) ? replycolorRAW.displayHexColor.replace("#000000","#ffffff") : "#ffffff"
var reply = {
type:replytype,
commandOptions:{
interactionId:msg.interaction.id,
interactionName:msg.interaction.commandName
},
user:{
name:msg.interaction.user.username,
id:msg.interaction.user.id,
color:replycolor,
pfp:msg.interaction.user.displayAvatarURL(),
bot:msg.interaction.user.bot,
system:msg.interaction.user.system,
verifiedBot:msg.interaction.user.flags.has(discord.UserFlags.VerifiedBot)
}
}
}else if (replytype == "reply"){
var replycontentRAW = messages.find((msg2) => msg2.id == msg.reference.messageId)
var replycontent = (replycontentRAW && replycontentRAW.content) ? replycontentRAW.content.slice(0,(60-replycontentRAW.author.username.length)) : "deleted this message"
const replycolorRAW = (replycontentRAW) ? msg.guild.members.cache.find((m) => m.id == replycontentRAW.author.id) : false
const replycolor = (replycolorRAW) ? replycolorRAW.displayHexColor.replace("#000000","#ffffff") : "#ffffff"
var user = (replycontentRAW && replycontentRAW.content) ? {
name:(replycontentRAW) ? replycontentRAW.author.username : "undefined",
id:(replycontentRAW) ? replycontentRAW.author.id : "undefined",
color:replycolor,
pfp:(replycontentRAW) ? replycontentRAW.author.username : "",
bot:(replycontentRAW) ? replycontentRAW.author.bot : false,
system:(replycontentRAW) ? replycontentRAW.author.system : false,
verifiedBot:(replycontentRAW) ? replycontentRAW.author.flags.has(discord.UserFlags.VerifiedBot) : false,
} : {
name:"someone",
id:"undefined",
color:"#ffffff",
pfp:"https://raw.githubusercontent.com/twitter/twemoji/master/assets/72x72/1f5d1.png",
bot:false,
system:false,
verifiedBot:false,
}
var reply = {
type:replytype,
replyOptions:{
content:replycontent,
messageId: msg.reference.messageId,
channelId: msg.reference.channelId,
guildId: msg.reference.guildId
},
user:user
}
}else{var reply = {type:replytype}}
const authorColor = msg.member ? msg.member.displayHexColor.replace("#000000","#ffffff") : "#ffffff"
messagesArray.push({
author:{
name:msg.author.tag,
id:msg.author.id,
color:authorColor,
pfp:msg.author.displayAvatarURL(),
bot:msg.author.bot,
system:msg.author.system,
verifiedBot:msg.author.flags.has(discord.UserFlags.VerifiedBot)
},
content:mentions(msg.content,guild) || "",
timestamp:msg.createdTimestamp,
embeds:embedArray,
attachments:attachmentArray,
edited: (typeof msg.editedTimestamp == "number"),
type:"normal",
important:important,
reply:reply,
components:componentsArray
})
}else {invisibleMessages++}
})
const dsb = data.style.background
const dsh = data.style.header
const dss = data.style.stats
/**@type {OTTranscriptCompileInput} */
const result = {
version,otversion,
language:bot.config.languageFile,
style:{
background:{
backgroundData:dsb.backgroundData || "",
backgroundModus:dsb.backgroundModus || "",
enableCustomBackground:dsb.enableCustomBackground || false,
},
header:{
backgroundColor:dsh.backgroundColor || "#202225",
decoColor:dsh.decoColor || "#F8BA00",
textColor:dsh.textColor || "#ffffff",
enableCustomHeader:dsh.enableCustomHeader || false
},
stats:{
backgroundColor:dss.backgroundColor || "#202225",
keyTextColor:dss.keyTextColor || "#737373",
valueTextColor:dss.valueTextColor || "#ffffff",
hideBackgroundColor:dss.hideBackgroundColor || "#40444a",
hideTextColor:dss.hideTextColor || "#ffffff",
enableCustomStats:dss.enableCustomStats || false
}
},
bot:{
name:data.bot.name || "Open Ticket",
id:data.bot.id || 0,
pfp:data.bot.pfp || "dj-dj.be/wp-content/uploads/2022/07/profielfoto-blauw-wit.png?size=128"
},
ticket:{
name:channel.name,
id:channel.id,
guildname:guild.name,
guildid:guild.id,
guildinvite:"",
creatorname:data.ticket.creatorname,
creatorid:data.ticket.creatorid,
creatorpfp:data.ticket.creatorpfp,
closedbyname:user.tag,
closedbyid:user.id,
closedbypfp:user.displayAvatarURL(),
claimedid:"",
claimedname:"",
claimedpfp:"",
closedtime:data.ticket.closedtime,
openedtime:data.ticket.openedtime,
roleColors:[],
components:{
messages:messageAmount,
embeds:embedAmount,
files:fileAmount,
interactions:{
buttons:0,
dropdowns:0,
total:interactionAmount
},
reactions:reactionsAmount,
attachments:{
gifs:0,
images:0,
stickers:0,
invites:0
}
}
},
messages:messagesArray,
premium:{
enabled:false,
premiumToken:"",
customCredits:{
enable:false,
replaceText:"Powered By Open Ticket!",
replaceURL:"https://openticket.dj-dj.be",
enableReportBug:true
},
customHeaderUrl:{
enabled:false,
url:"https://openticket.dj-dj.be",
text:"Hello!"
},
customTranscriptUrl:{
enabled:false,
name:"test-server"
},
customFavicon:{
enabled:false,
image:"https://openticket.dj-dj.be"
},
additionalFlags:[]
}
}
return result
}
@@ -1,29 +0,0 @@
const axios = require("axios").default
const discord = require('discord.js')
const bot = require("../../../index")
const tsconfig = bot.tsconfig
const tsembeds = require("../embeds")
const tsdb = require("../tsdb")
/**@typedef {{status:"success"|"error", id:String, time:Number, estimated:{lastdump: Number, processtime:Number,waittime:Number}, transcriptstatus:{value:2, data:{fetchedmsgs:true, uploaded:true, inqueue:true, processed:false, waiting:false, available:false}}}} OTuploadResponse */
/**
* @param {Object} json
* @returns {Promise<OTuploadResponse|false>}
*/
exports.upload = async (json) => {
return new Promise(async (resolve,reject) => {
const data = encodeURIComponent(JSON.stringify(json))
try {
const res = await axios.post("https://transcripts.dj-dj.be/api/upload?auth=openticketTRANSCRIPT1234&version=2",JSON.stringify(json))
if (res.status != 200) resolve(false)
resolve(res.data)
}catch(err){
console.log("failed transcript upload!",err.response)
resolve(false)
}
})
}
@@ -1,57 +0,0 @@
const discord = require('discord.js')
const bot = require("../../../index")
const tsconfig = bot.tsconfig
const tsembeds = require("../embeds")
const tsdb = require("../tsdb")
/**
*
* @param {String} text
* @param {discord.Guild} guild
*/
exports.replacementions = (text,guild) => {
const userregex = /<@([0-9]+)>(\s)?/g
const usertext = text.replace(userregex,(x) => {
var res = userregex.exec(x)
userregex.lastIndex = 0
var member = guild.members.cache.find((m) => m.id == res[1])
var text = member ? member.user.username.replace(/\s/g,"&nbsp;") : res[1]
return "<@"+text+"> "
})
const channelregex = /<#([0-9]+)>(\s)?/g
const channeltext = usertext.replace(channelregex,(x) => {
var res = channelregex.exec(x)
channelregex.lastIndex = 0
var channel = guild.channels.cache.find((c) => c.id == res[1])
var text = channel ? channel.name.replace(/\s/g,"&nbsp;") : res[1]
return "<#"+text+"> "
})
const roleregex = /<@&([0-9]+)>(\s)?/g
const roletext = channeltext.replace(roleregex,(x) => {
var res = roleregex.exec(x)
roleregex.lastIndex = 0
var role = guild.roles.cache.find((r) => r.id == res[1])
var text = role ? role.name.replace(/\s/g,"&nbsp;") : res[1]
var color = role ? ((role.hexColor == "#000000") ? "regular" : role.hexColor) : "regular"
return "<@&"+text+"::"+color+"> "
})
const defaultroleregex = /@(everyone|here)(\s)?/g
const defaultroletext = roletext.replace(defaultroleregex,(x) => {
var res = defaultroleregex.exec(x)
defaultroleregex.lastIndex = 0
var text = res[1]
return "<@&"+text+"::regular> "
})
return defaultroletext
}
-78
View File
@@ -1,78 +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 tsconfig = bot.tsconfig
/**
*
* @param {String} name
* @param {String} id
* @param {Number} rawprocesstime milliseconds
* @param {discord.User} user
*/
exports.beingprocessed = (name,id,rawprocesstime,user) => {
const newtime = rawprocesstime
const processtime = "<t:"+newtime.getTime().toString().substring(0,newtime.getTime().toString().length-3)+":R>"
const embed = new discord.EmbedBuilder()
.setTitle("🧾 "+l.transcripts.title)
.setColor(config.color)
.setAuthor({name:user.tag,iconURL:user.displayAvatarURL()})
.setFooter({text:name})
.setDescription("`"+l.transcripts.processed+"...`\n"+l.transcripts.wait+"\n\n"+l.transcripts.estimated+": "+processtime)
return embed
}
/**
*
* @param {String} name
* @param {String} id
* @param {String} url
* @param {discord.User} user
*/
exports.tsready = (name,id,url,user) => {
const embed = new discord.EmbedBuilder()
.setTitle("🧾 "+l.transcripts.title)
.setColor(config.color)
.setAuthor({name:user.tag,iconURL:user.displayAvatarURL()})
.setFooter({text:name})
if (url){
embed.setURL(url)
embed.setDescription("\n["+l.transcripts.available+"]("+url+")\n")
}else{
embed.setDescription("\n"+l.transcripts.available+"\n")
}
return embed
}
/**
*
* @param {String} name
* @param {String} id
* @param {discord.User} user
* @param {undefined|String} err
*/
exports.tserror = (name,id,user,err) => {
const embed = new discord.EmbedBuilder()
.setTitle("❌ "+l.transcripts.title)
.setColor(discord.Colors.Red)
.setAuthor({name:user.tag,iconURL:user.displayAvatarURL()})
.setFooter({text:name})
const errDesc = (typeof err == "string") ? "\n"+err : ""
embed.setDescription("Something went wrong while creating the HTML transcript.\n\n[possible reasons](https://docs.openticket.dj-dj.be/the-system/transcripts/transcript-errors)"+errDesc)
return embed
}
-3
View File
@@ -1,3 +0,0 @@
{
"version":"2"
}
-176
View File
@@ -1,176 +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 tsconfig = bot.tsconfig
const tsembeds = require("./embeds")
const tsdb = require("./tsdb")
const checkAvailability = async () => {
if (process.argv.some((v) => v == "--tsoffline")) return true
const axios = require("axios").default
try{
const res = await axios.get("https://transcripts.dj-dj.be/api/status.json")
if (!res || !(res.status == 200) || !res.data) return false
if (res.data && res.data["v2"] == "online") return true
else return false
}catch{
return false
}
}
/**
*
* @param {discord.Message[]} messages
* @param {discord.Guild} guild
* @param {discord.TextChannel} channel
* @param {discord.User} user
* @param {String|false} reason
*/
module.exports = async (messages,guild,channel,user,reason) => {
require("../api/modules/events").onTranscriptCreation(messages,channel,guild,new Date())
const msglist = await channel.messages.fetchPinned()
const chName = channel.name
const chId = channel.id
const asyncmanager = async () => {
const hiddendata = bot.hiddenData.readHiddenData(channel.id)
if (hiddendata.length < 1) return
const ticketId = hiddendata.find(d => d.key == "type").value
const ticketData = require("../utils/configParser").getTicketById(ticketId,true)
const id = hiddendata.find(d => d.key == "openerid").value
const opentime = new Date(Number(hiddendata.find(d => d.key == "createdms").value))
const ticketopener = client.users.cache.find(u => u.id == id)
if (tsconfig.sendTranscripts.useHTMLtranscripts){
const tsb = tsconfig.style.background
const tsh = tsconfig.style.header
const tss = tsconfig.style.stats
const JSONDATA = require("./communication/compileJsonV2").compile(guild,channel,user,messages,{
style:{
background:{
enableCustomBackground:tsb.enableCustomBackground,
backgroundModus:tsb.backgroundModus,
backgroundData:tsb.backgroundData
},
header:{
enableCustomHeader:tsh.enableCustomHeader,
backgroundColor:tsh.backgroundColor,
decoColor:tsh.decoColor,
textColor:tsh.textColor
},
stats:{
enableCustomStats:tss.enableCustomStats,
backgroundColor:tss.backgroundColor,
keyTextColor:tss.keyTextColor,
valueTextColor:tss.valueTextColor,
hideBackgroundColor:tss.hideBackgroundColor,
hideTextColor:tss.hideTextColor
}
},
bot:{
name:client.user.username,
id:client.user.id,
pfp:client.user.displayAvatarURL(),
},
ticket:{
creatorid:ticketopener.id,
creatorname:ticketopener.tag,
creatorpfp:ticketopener.displayAvatarURL(),
openedtime:opentime.getTime(),
closedtime:new Date().getTime()
}
})
if (!await checkAvailability()){
const attachment = await require("./oldTranscript").createTranscript(messages,channel)
const errembed = tsembeds.tserror(chName,chId,user)
if (tsconfig.sendTranscripts.enableChannel){
/**@type {discord.TextChannel|undefined} */
const tc = guild.channels.cache.find((c) => c.id == tsconfig.sendTranscripts.channel)
if (!tc) return
tc.send({embeds:[errembed],files:[attachment]})
}
return
}
const TSdata = await require("./communication/index").upload(JSONDATA)
if (!TSdata) return false
if (TSdata.status == "success"){
//MAKE THIS COMPATIBLE WITH PREMIUM "customTranscriptUrl" IN FUTURE VERSIONS!!
const url = "https://transcripts.dj-dj.be/v2/"+TSdata.time+"_"+TSdata.id+".html"
//calculate estimated time
//const lastDumpTime = (new Date(TSdata.estimated.lastdump).getTime())
//const dumpLoopTime = 15000
//const nextDump = new Date(lastDumpTime+dumpLoopTime)
//const processtime = TSdata.estimated.processtime+6000 //6sec extra time for overflow
const duration = TSdata.estimated.waittime
const finaltime = new Date(new Date().getTime()+duration)
//waiting
if (tsconfig.sendTranscripts.enableChannel){
/**@type {discord.TextChannel|undefined} */
const tc = guild.channels.cache.find((c) => c.id == tsconfig.sendTranscripts.channel)
if (!tc) return
const embed = tsembeds.beingprocessed(chName,chId,finaltime,user)
var msg = await tc.send({embeds:[embed]})
}else {var msg = false}
//ready
setTimeout(() => {
if (msg){
msg.edit({embeds:[tsembeds.tsready(chName,chId,url,user)]})
}
if (tsconfig.sendTranscripts.enableDM){
if (!user) return
const embed = tsembeds.tsready(chName,chId,url,user)
try {
ticketopener.send({embeds:[embed]})
}catch{}
}
},duration)
}else{
const attachment = await require("./oldTranscript").createTranscript(messages,channel)
const errembed = tsembeds.tserror(chName,chId,user,"`error type: transcript API error`")
if (tsconfig.sendTranscripts.enableChannel){
/**@type {discord.TextChannel|undefined} */
const tc = guild.channels.cache.find((c) => c.id == tsconfig.sendTranscripts.channel)
if (!tc) return
tc.send({embeds:[errembed],files:[attachment]})
}
}
}else{
const attachment = await require("./oldTranscript").createTranscript(messages,channel)
const embed = tsembeds.tsready(chName,chId,false,user)
if (tsconfig.sendTranscripts.enableChannel){
/**@type {discord.TextChannel|undefined} */
const tc = guild.channels.cache.find((c) => c.id == tsconfig.sendTranscripts.channel)
if (!tc) return
tc.send({embeds:[embed],files:[attachment]})
}
}
}
asyncmanager()
}
-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 l = bot.language
/**
*
* @param {discord.Message[]} messagecollection
* @param {discord.TextChannel} channel
* @param {Boolean} backup
* @returns new `discord.attachmentBuilder`
*/
exports.createTranscript = async (messagecollection,channel,backup) => {
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()
let backuptitle = backup ? "BACKUP " : ""
let backupfilename = backup ? "backup" : ""
const filearray = [backuptitle+"TRANSCRIPT:\n"]
messagecollection.reverse()
messagecollection.forEach((msg) => {
const timestamp = new Date(msg.createdTimestamp)
//empty message handling
if (msg.content){
var content = msg.content
}else if (msg.embeds.length > 0 && msg.attachments.length > 0){
var content = "*this message only has embeds & files*"
}else if (msg.embeds.length > 0){
var content = "*this message only has embeds*"
}else if (msg.attachments.length > 0){
var content = "*this message only has files*"
}else{
var content = "*empty message*"
}
const fileurls = []
const rawfiles = Array.from(msg.attachments)
rawfiles.forEach((file) => {
fileurls.push("attachment: "+file[1].url)
})
const filestring = fileurls.length > 0 ? fileurls.join("\n")+"\n" : ""
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"+filestring)
})
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:backupfilename+"transcript.txt",description:"Open Ticket transcript"})
}catch{
return false
}
}
-71
View File
@@ -1,71 +0,0 @@
const fs = require("fs")
const location = "./storage/tsdatabase.json"
/**@returns {[{category:String, key:String, value:String}]}*/
function getData(){
if (fs.existsSync(location)){
return JSON.parse(fs.readFileSync(location).toString())
}else{
fs.writeFileSync(location,"[]")
return []
}
}
/**@param {[{category:String, key:String, value:String}]} data*/
function setData(data){
fs.writeFileSync(location,JSON.stringify(data,null,"\t"))
}
exports.set = (category,key,value) => {
const currentData = getData()
const exists = currentData.find((d) => (d.category == category) && (d.key == key)) ? true : false
var newData = []
if (exists){
currentData.forEach((d,i) => {
if (d.category == category && d.key == key){
newData.push({category,key,value})
}else{
newData.push(d)
}
})
}else{
currentData.push({category,key,value})
newData = currentData
}
setData(newData)
return exists
}
/**
* @param {String} category
* @param {String} key
* @returns {String|false}
*/
exports.get = (category,key) => {
const currentData = getData()
const tempresult = currentData.find((d) => (d.category == category) && (d.key == key))
const result = tempresult ? tempresult.value : false
return result
}
/**
* @param {String} category
* @param {String} key
* @param {String} value
*/
exports.delete = (category,key) => {
const currentData = getData()
const exists = currentData.find((d) => (d.category == category) && (d.key == key)) ? true : false
var newData = []
if (exists){
currentData.forEach((d,i) => {
if (!(d.category == category && d.key == key)){
newData.push(d)
}
})
}else{
newData = currentData
}
setData(newData)
return exists
}
-188
View File
@@ -1,188 +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[], readonlyAdminroles: String[], channelprefix: String,category: String,message: String,enableDmOnOpen: Boolean,ticketmessage: String, thumbnail:{enable:Boolean,url:String}, image:{enable:Boolean,url:String}, closedCategory:{enable:Boolean,id:String}, autoclose:{enable:Boolean,inactiveHours:Number}, ping:{"@here":Boolean, "@everyone":Boolean, custom:{enable:Boolean, roleId: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, enableFooterImage: boolean, footerImage: string, enableThumbnail: boolean, thumbnail: string, enableImage: boolean, image: string, enableCustomColor: boolean, color: string, options: string[], other:{enableTicketExplaination: boolean, enableMaxTicketsWarning: boolean, customDropdownPlaceholder:{enable:Boolean,text:String}, customCategoryText:{enable:Boolean,text:String}, embedTitleURL:{enable:Boolean,url:String} } }} OTConfigMessage*/
//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}, image:{enable:Boolean,url:String}, url:String, closedCategory:{enable:Boolean,id:String}, autoclose:{enable:Boolean,inactiveHours:Number}, readonlyAdminroles: String[]}} OTAllOptions */
//StringOptions
/**@typedef {"id"|"name"|"description"|"icon"|"label"|"type"|"color"|"adminroles"|"channelprefix"|"category"|"message"|"enableDmOnOpen"|"ticketmessage"|"thumbnail"|"image"|"closedCategory"|"adminroles"|"autoclose"|"ping"} 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 = {}
/**
*
* @param {String} id
* @returns {Boolean}
*/
exports.optionExists = (id) => {
var result = false
config.options.forEach((option) => {
if (option.id == id){
result = true
}
})
return result
}
-76
View File
@@ -1,76 +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) => {
bot.actionRecorder.push({
category:"ot.managers.utils",
file:"./core/utils/getButton.js",
time:new Date().getTime(),
type:"getbutton"
})
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
}
-70
View File
@@ -1,70 +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
* @param {String|undefined|false} placeholder
* @returns {discord.StringSelectMenuBuilder|false}
*/
exports.getDropdown = (ids,placeholder) => {
bot.actionRecorder.push({
category:"ot.managers.utils",
file:"./core/utils/getDropdown.js",
time:new Date().getTime(),
type:"getdropdown"
})
const dropdown = new discord.StringSelectMenuBuilder()
.setCustomId("OTdropdownMenu")
.setDisabled(false)
.setMaxValues(1)
.setMinValues(1)
.setPlaceholder(placeholder || l.messages.chooseATicket)
.addOptions(
new discord.StringSelectMenuOptionBuilder()
.setDefault(true)
.setLabel(placeholder || l.messages.chooseATicket)
.setValue("OTChooseTicket")
)
ids.forEach((id) => {
const option = configParser.getTicketById(id,true)
const roleoption = configParser.getRoleById(id,true)
if (option){
const selectComponent = new discord.StringSelectMenuOptionBuilder()
.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)
if (option.description) selectComponent.setDescription(option.description)
}
dropdown.addOptions(selectComponent)
}else if (roleoption){
const selectComponent = new discord.StringSelectMenuOptionBuilder()
.setDefault(false)
.setValue("OTnewR"+roleoption.id)
if (!roleoption.label && !roleoption.icon){
selectComponent.setLabel("OT ERROR: no description/emoji")
}else{
if (roleoption.label) selectComponent.setLabel(roleoption.label)
if (roleoption.icon) selectComponent.setEmoji(roleoption.icon)
}
dropdown.addOptions(selectComponent)
}
})
return dropdown
}
-138
View File
@@ -1,138 +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) => {
bot.actionRecorder.push({
category:"ot.managers.utils",
file:"./core/utils/getEmbed.js",
time:new Date().getTime(),
type:"getembed"
})
//-----------------------------------
//general importing
const data = require("./configParser").getConfigMessage(id)
/**@type {discord.ButtonBuilder[]}*/
var buttons = []
/**@type {import('./configParser').OTAllOptions[]} */
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)
try {
const footerimg = (data.enableFooter && data.enableFooterImage) ? data.footerImage : undefined
if (data.enableFooter) embed.setFooter({text:data.footer,iconURL:footerimg})
}catch{
bot.errorLog.log("info","FOOTER FAILED TO LOAD, probably invalid url!")
}
try {
if (data.enableThumbnail) embed.setThumbnail(data.thumbnail)
}catch{
bot.errorLog.log("info","THUMBNAIL FAILED TO LOAD, probably invalid url!")
}
try {
if (data.enableImage) embed.setImage(data.image)
}catch{
bot.errorLog.log("info","IMAGE FAILED TO LOAD, probably invalid url!")
}
if (data.enableCustomColor){
embed.setColor(data.color)
}else{
embed.setColor(config.color)
}
if (data.other.embedTitleURL.enable) embed.setURL(data.other.embedTitleURL.url)
var description = data.description
if (data.other.enableTicketExplaination){
const chooseCategoryMSG = data.other.customCategoryText.enable ? data.other.customCategoryText.text : l.messages.chooseATicket
description = description+"\n\n__"+chooseCategoryMSG+"__\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.other.enableMaxTicketsWarning){
description = description+"\n\n"+l.commands.maxTicketWarning.replace("{0}",config.system.maxAmountOfTickets)
}
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 customPlaceholder = data.other.customDropdownPlaceholder.enable ? data.other.customDropdownPlaceholder.text : false
const dropdown = require("./getDropdown").getDropdown(ids,customPlaceholder)
var componentRows = [
new discord.ActionRowBuilder()
.setComponents(dropdown)
]
}
//-----------------------------------
//return everything
/**
* @type {{embed:discord.EmbedBuilder,componentRows:discord.MessageActionRow[]}}
*/
const returnedData = {embed:embed,componentRows:componentRows}
return returnedData
}
-49
View File
@@ -1,49 +0,0 @@
const storage = require("../../index").storage
/**@typedef {[{key:String,value:String}]} hiddenData */
/**
*
* @param {String} channelid
* @returns {hiddenData}
*/
exports.readHiddenData = (channelid) => {
const content = storage.get("HIDDENDATA",channelid)
if (!content) return {type:"",data:[],status:false}
try {
return JSON.parse(content)
} catch {
return []
}
}
/**
*
* @param {String} channelid
* @param {[{key:String,value:String}]} data
* @returns {Boolean}
*/
exports.writeHiddenData = (channelid,data) => {
try {
storage.set("HIDDENDATA",channelid,JSON.stringify(data))
return true
} catch {
return false
}
}
/**
*
* @param {String} channelid
* @returns {Boolean}
*/
exports.deleteHiddenData = (channelid) => {
try {
storage.delete("HIDDENDATA",channelid)
return true
} catch {
return false
}
}
-211
View File
@@ -1,211 +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 axios = require("axios").default
const fs = require("fs")
const loadChalk = async () => {
return await (await import("chalk")).default
}
//OTLiveStatus
/**@typedef {[{style:[{title:String,titleColor:"normal"|"red"|"green"|"blue"|"yellow"|"white"|"gray"|"magenta"|"cyan",description:String,descriptionColor:"normal"|"red"|"green"|"blue"|"yellow"|"white"|"gray"|"magenta"|"cyan"}],active:{versions:String[],languages:String[],usingPlugins:["yes"|"no"|"both"],usingSlashCommands:["yes"|"no"|"both"],transcripts:["html"|"text"|"both"]}}]} OTLiveStatus */
//OTLiveStatusError
/**@typedef {{bot:{id:String,pfp:String,name:String}, openticket:{version:String,language:String, slashcmds:Boolean,transcripts:false|"text"|"html",config:{system:{},options:{},messages:{},transcripts:{}},plugins:String[],pluginload:{success:Number,error:Number,total:Number}}, details:{actions:[{type:String,category:String,file:String,time:Number}],errortime:Number}, error:String}} OTLiveStatusError */
/**@type {[{type:String, category:String, file:String, time:Number}]} */
exports.actionRecorder = []
//================================================================
//=========================FUNCTIONS==============================
//================================================================
const getSlashEnabled = () => {
if (!fs.existsSync("./storage/slashcmdEnabled.txt")) return false
if (fs.readFileSync("./storage/slashcmdEnabled.txt").toString() == require("../../package.json").version){
return true
}else return false
}
/**
* @param {Boolean} [local=false]
* @returns {Promise<OTLiveStatus|false>}
*/
const getLivestatus = (local) => {
return new Promise((resolve,reject) => {
if (local){
try {
const livestatus = require("../../livestatus.json")
if (!livestatus) return resolve(false)
resolve(livestatus)
}catch{
return resolve(false)
}
}else{
try {
axios.get("https://livestatus.dj-dj.be/openticket.json").then((res) => {
const livestatus = res.data
if (!Array.isArray(livestatus)) return resolve(false)
if (!livestatus) return resolve(false)
resolve(livestatus)
})
}catch{
return resolve(false)
}
}
})
}
var globalPluginData = {total:0,error:0,success:0}
//announcer
/**@param {{total:Number,error:Number,success:Number}} pluginData*/
exports.run = async (pluginData) => {
const chalk = await loadChalk()
globalPluginData = pluginData
const res = await getLivestatus(process.argv.some((v) => v == "--localstatus"))
if (!res) return false
if (res.length == 0) return
/**@type {[{title:String,titleColor:"normal"|"red"|"green"|"blue"|"yellow"|"white"|"gray"|"magenta"|"cyan",description:String,descriptionColor:"normal"|"red"|"green"|"blue"|"yellow"|"white"|"gray"|"magenta"|"cyan"}]} */
const activeStyles = []
res.forEach((announcement) => {
const a = announcement.active
const isLanguage = a.languages.includes(config.languageFile) || a.languages.includes("all")
const isVersion = a.versions.includes(require("../../package.json").version)
var tsenabled = (bot.tsconfig.sendTranscripts.enableChannel || bot.tsconfig.sendTranscripts.enableDM)
var tsmode = bot.tsconfig.sendTranscripts.useHTMLtranscripts ? "html" : "text"
const isTranscript = (a.transcripts.includes("html") && tsmode == "html" && tsenabled) || (a.transcripts.includes("text") && tsmode == "text" && tsenabled) || (a.transcripts.includes("both") && tsenabled)
const isPlugins = (a.usingPlugins.includes("yes") && pluginData.total > 0) || (a.usingPlugins.includes("no") && pluginData.total == 0) || (a.usingPlugins.includes("both"))
const isSlashCMD = (a.usingSlashCommands.includes("yes") && getSlashEnabled()) || (a.usingSlashCommands.includes("no") && !getSlashEnabled()) || (a.usingSlashCommands.includes("both"))
if (!isLanguage || !isVersion || !isTranscript || !isPlugins || !isSlashCMD) return
announcement.style.forEach((s) => activeStyles.push(s))
})
const final = []
activeStyles.forEach((style) => {
const dc = style.descriptionColor
const tempd = style.description.split("\n")
const tc = style.titleColor
const t = "["+style.title+"]"
const tempd2 = []
tempd.forEach((tmpd,i) => {
if (i > 0){
var newtext = tmpd
var i2 = 0
while(i2 < t.length+1){
newtext = " "+newtext
i2++
}
tempd2.push(newtext)
}else{
tempd2.push(tmpd)
}
})
const d = tempd2.join("\n")
var fd = d
if (dc == "normal" || dc == "white") fd = chalk.white(d)
if (dc == "red") fd = chalk.red(d)
if (dc == "yellow") fd = chalk.yellow(d)
if (dc == "green") fd = chalk.green(d)
if (dc == "blue") fd = chalk.blue(d)
if (dc == "gray") fd = chalk.gray(d)
if (dc == "magenta") fd = chalk.magenta(d)
if (dc == "cyan") fd = chalk.cyan(d)
var ft = t
if (tc == "normal" || tc == "white") ft = chalk.white(t)
if (tc == "red") ft = chalk.red(t)
if (tc == "yellow") ft = chalk.yellow(t)
if (tc == "green") ft = chalk.green(t)
if (tc == "blue") ft = chalk.blue(t)
if (tc == "gray") ft = chalk.gray(t)
if (tc == "magenta") ft = chalk.magenta(t)
if (tc == "cyan") ft = chalk.cyan(t)
final.push(ft+" "+fd)
})
console.log(final.join("\n\n"))
}
var waitTime = new Date().getTime()
var waitTimeEnabled = false
/**@param {OTLiveStatusError} options @returns {Promise<Boolean>} */
const uploadLiveStatus = (options) => {
return new Promise((resolve,reject) => {
if (process.argv.some((v) => v == "--noerrorupload")) return resolve(true)
try {
var data = encodeURIComponent(JSON.stringify(options))
axios.get("https://livestatus.dj-dj.be/openticket?auth=openticketLIVESTATUS1234&data="+data).then((res) => {
if (res.status == 200) resolve(true)
else resolve(false)
})
}catch{
resolve(false)
}
})
}
/**@param {String} err @returns {Promise<Boolean>}*/
exports.liveStatusUploadManager = async (err) => {
return new Promise(async (resolve) => {
if (process.argv.some((v) => v == "--noerrorupload")) return resolve(true)
else{
var tsenabled = (bot.tsconfig.sendTranscripts.enableChannel || bot.tsconfig.sendTranscripts.enableDM)
var tsmode = bot.tsconfig.sendTranscripts.useHTMLtranscripts ? "html" : "text"
const transcriptMode = tsenabled ? tsmode : false
const slashMode = getSlashEnabled()
try {
if (waitTimeEnabled){
if (new Date().getTime() < waitTime){
waitTimeEnabled = false
return resolve(false)
}
}
const result = await uploadLiveStatus({
bot:{
id:client.user.id,
name:client.user.tag,
pfp:client.user.displayAvatarURL()
},
error:err,
openticket:{
config:{
messages:config.messages,
options:config.options,
transcripts:bot.tsconfig,
system:config.system
},
language:config.languageFile,
version:"3.4.0",
slashcmds:slashMode,
transcripts:transcriptMode,
plugins:fs.readdirSync("./plugins"),
pluginload:globalPluginData
},
details:{
errortime:new Date().getTime(),
actions:this.actionRecorder,
database:fs.readFileSync("./storage/database.json").toString()
}
})
if (!result){
waitTime = new Date().getTime()+30000
waitTimeEnabled = true
}
resolve(result)
}catch{resolve(false)}
}
})
}
-149
View File
@@ -1,149 +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) => {
bot.actionRecorder.push({
category:"ot.managers.permissionChecker",
file:"./core/permissionChecker.js",
time:new Date().getTime(),
type:"command"
})
const permsmember = client.guilds.cache.find(g => g.id == guildid).members.cache.find(m => m.id == memberid)
if (config.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) => {
bot.actionRecorder.push({
category:"ot.managers.permissionChecker",
file:"./core/permissionChecker.js",
time:new Date().getTime(),
type:"sendusernoperms"
})
try {
user.send({embeds:[bot.errorLog.noPermsMessage(user)]})
return true
}catch{
return false
}
}
/**
*
* @param {discord.User} user
* @returns {Boolean}
*/
exports.sendUserNoTicket = (user) => {
bot.actionRecorder.push({
category:"ot.managers.permissionChecker",
file:"./core/permissionChecker.js",
time:new Date().getTime(),
type:"sendusernoticket"
})
try {
user.send({embeds:[bot.errorLog.notInATicket]})
return true
}catch{
return false
}
}
/**
*
* @param {discord.User} user
* @returns {Boolean}
*/
exports.sendUserNoDelete = (user) => {
bot.actionRecorder.push({
category:"ot.managers.permissionChecker",
file:"./core/permissionChecker.js",
time:new Date().getTime(),
type:"sendusernodelete"
})
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) => {
bot.actionRecorder.push({
category:"ot.managers.permissionChecker",
file:"./core/permissionChecker.js",
time:new Date().getTime(),
type:"sendchannelnoperms"
})
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) => {
bot.actionRecorder.push({
category:"ot.managers.permissionChecker",
file:"./core/permissionChecker.js",
time:new Date().getTime(),
type:"sendchannelnoticket"
})
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) => {
bot.actionRecorder.push({
category:"ot.managers.permissionChecker",
file:"./core/permissionChecker.js",
time:new Date().getTime(),
type:"sendchannelnodelete"
})
try {
channel.send({embeds:[bot.errorLog.noPermsDelete(user)]})
return true
}catch{
return false
}
}
+7
View File
@@ -0,0 +1,7 @@
[
{"category":"openticket:last-version","key":"openticket:version","value":"v4.0.0"},
{"category":"openticket:last-version","key":"openticket:api","value":"v1.0.0"},
{"category":"openticket:last-version","key":"openticket:transcripts","value":"v2.0.0"},
{"category":"openticket:last-version","key":"openticket:livestatus","value":"v2.0.0"},
{"category":"openticket:last-version","key":"openticket:last-version","value":"v4.0.0"}
]
+1
View File
@@ -0,0 +1 @@
[]
+1
View File
@@ -0,0 +1 @@
[]
+1
View File
@@ -0,0 +1 @@
[]
+1
View File
@@ -0,0 +1 @@
[]
+9
View File
@@ -0,0 +1,9 @@
# Docker Compose for Open Ticket v4
version: '3'
services:
openticket:
build: .
volumes:
- .:/app
environment: NODE_ENV=production
restart: unless-stopped
+18
View File
@@ -0,0 +1,18 @@
# Docker File for Open Ticket v4
# Use the official Node.js 18 image from Docker Hub
FROM node:18-alpine
# Set a different working directory inside the container
WORKDIR /usr/src/openticket
# Copy package.json and package-lock.json into the container
COPY package*.json ./
# Install dependencies
RUN npm install
# Copy the rest of your app's source code into the container
COPY . .
# Run the bot from index.js
CMD ["node", "index.js"]
+42 -370
View File
@@ -1,385 +1,57 @@
/** const fs = require("fs")
____ _____ ______ _ _ _______ _____ _____ _ ________ _______ const ts = require("typescript")
/ __ \| __ \| ____| \ | | |__ __|_ _/ ____| |/ / ____|__ __| const nodepath = require('path')
| | | | |__) | |__ | \| | | | | || | | ' /| |__ | |
| | | | ___/| __| | . ` | | | | || | | < | __| | |
| |__| | | | |____| |\ | | | _| || |____| . \| |____ | |
\____/|_| |______|_| \_| |_| |_____\_____|_|\_\______| |_|
Hey! we are looking for you! /////////////// STARTUP FLAGS ///////////////
Do you speak a language that isn't yet in our /languages directory const flags = [
or do you speak one that isn't up-to-date? Open Ticket needs //PTERODACTYL PANEL
translators for lots of different languages! //add startup flags here (e.g. "--no-compile") when running via the panel
Feel free to join our translator team and help us improve Open Ticket! ]
process.argv.push(...flags)
/////////////// STARTUP FLAGS ///////////////
if (!process.argv.includes("--no-compile")){
//REMOVE EXISTING BUILDS
console.log("OT: Removing Prebuilds...")
fs.rmSync("./dist",{recursive:true,force:true})
//COMPILE TYPESCRIPT
console.log("OT: Compiling Typescript...")
const configPath = nodepath.resolve('./tsconfig.json')
const configFile = ts.readConfigFile(configPath,ts.sys.readFile)
//check for tsconfig errors
SUGGESTING NEW FEATURES: if (configFile.error){
===================== const message = ts.formatDiagnosticsWithColorAndContext([configFile.error],ts.createCompilerHost({}))
Open Ticket is a community project. This means that console.error(message)
almost all feature ideas come from our community. process.exit(1)
Are you missing something you want in open ticket?
Then join our Discord server and we will add it (if possible)
Did you know that 80% of all features in OT were ideas from our community?
INFORMATION:
============
Open Ticket v3.4.0 - © DJdj Development
discord: https://discord.dj-dj.be
website: https://www.dj-dj.be
github: https://openticket.dj-dj.be
support e-mail: support@dj-dj.be
Config files:
./config.json
./transcriptconfig.json
Send ./openticketdebug.txt when there are errors!
*/
const discord = require("discord.js")
const fs = require('fs')
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]
})
exports.client = client
client.setMaxListeners(50)
if (process.argv.some((v) => v == "--debug")) console.log("[TEMP_DEBUG]","created client")
var tempconfig = require("./config.json")
/**@type {Boolean} */
var isDevConfig = false
if (process.argv.some((v) => v == "--devconfig")){
isDevConfig = true
try{
tempconfig = require("./devconfig.json")
}catch{tempconfig = require("./config.json")}
}else{
tempconfig = require("./config.json")
} }
if (process.argv.some((v) => v == "--debug")) console.log("[TEMP_DEBUG]","loaded flags")
exports.developerConfig = isDevConfig //parse tsconfig file
const parsedConfig = ts.parseJsonConfigFileContent(configFile.config,ts.sys,nodepath.dirname(configPath))
const config = tempconfig //create program/compiler
exports.config = config const program = ts.createProgram({
rootNames:parsedConfig.fileNames,
const tsconfig = isDevConfig ? require("./devtsconfig.json") : require("./transcriptconfig.json") options:parsedConfig.options
exports.tsconfig = tsconfig
const language = require("./core/languageManager").language
exports.language = language
if (process.argv.some((v) => v == "--debug")) console.log("[TEMP_DEBUG]","loaded language")
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")
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.actionRecorder = require("./core/utils/liveStatus").actionRecorder
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")
this.actionRecorder.push({
category:"ot.managers.djs",
file:"index.js",
time:new Date().getTime(),
type:"client.loggedin.success"
})
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
}
this.errorLog.log("debug","bot status loaded")
this.actionRecorder.push({
category:"ot.managers.djs",
file:"index.js",
time:new Date().getTime(),
type:"client.setstatus.success"
}) })
const chalk = await (await import("chalk")).default //emit all compiled files
const emitResult = program.emit()
require("./core/startscreen").run() //print emit errors/warnings (type errors)
this.actionRecorder.push({ const allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics)
category:"ot.managers.main", const formattedDiagnostics = ts.formatDiagnosticsWithColorAndContext(allDiagnostics, ts.createCompilerHost(parsedConfig.options))
file:"index.js", console.log(formattedDiagnostics)
time:new Date().getTime(),
type:"startscreen.success"
})
if (!process.argv[2] || (process.argv[2] && !process.argv[2].startsWith("slash"))){ if (emitResult.emitSkipped || allDiagnostics.find((d) => d.category == ts.DiagnosticCategory.Error || d.category == ts.DiagnosticCategory.Warning)){
//normal start console.log("OT: Compilation Failed!")
this.errorLog.log("debug","loaded console interface")
if (config.status.enabled){
setStatus(config.status.type,config.status.text)
}
this.actionRecorder.push({
category:"ot.managers.main",
file:"index.js",
time:new Date().getTime(),
type:"startmode.normal"
})
var updatingSlash = false
if (fs.existsSync("./storage/slashcmdEnabled.txt")){
/**@type {"true"|"false"|String} */
const data = fs.readFileSync("./storage/slashcmdEnabled.txt").toString()
if (data === require("./package.json").version){
require("./core/slashSystem/autoSlashUpdate")()
updatingSlash = true
}else if ((data != require("./package.json").version) && (data != "false")){
require("./core/slashSystem/slashEnable")(true)
updatingSlash = true
}
}else{
if (process.argv.some((v) => v == "--noslash")){
fs.writeFileSync("./storage/slashcmdEnabled.txt","false")
}else{
fs.writeFileSync("./storage/slashcmdEnabled.txt",require("./package.json").version)
require("./core/slashSystem/slashEnable")(true)
updatingSlash = true
}
}
this.actionRecorder.push({
category:"ot.managers.main",
file:"index.js",
time:new Date().getTime(),
type:"slashcmd.autoupdate.success"
})
try {
await client.guilds.cache.find((g) => g.id == config.serverId).members.fetch()
}catch{
this.errorLog.log("info","tried to cache user information, failed!")
}
require("./core/startscreen").headerDataReady(chalk,config.status,updatingSlash,false)
}else{
//slash command activation using node index.js slash (enable|disable)
require("./core/startscreen").headerDataReady(chalk,config.status,updatingSlash,true)
this.errorLog.log("debug","slashmode activated")
if (process.argv[3] == "enable"){
console.log(chalk.green("switching to slashEnable.js"))
this.actionRecorder.push({
category:"ot.managers.main",
file:"index.js",
time:new Date().getTime(),
type:"startmode.slash.enable"
})
require("./core/slashSystem/slashEnable")()
}else if (process.argv[3] == "disable"){
console.log(chalk.green("switching to slashDisable.js"))
this.actionRecorder.push({
category:"ot.managers.main",
file:"index.js",
time:new Date().getTime(),
type:"startmode.slash.disable"
})
require("./core/slashSystem/slashDisable")()
}else{
console.log(chalk.bgRed("[SLASH CMD MANAGER]: unknown slash command action!"))
process.exit(1) process.exit(1)
} }
} }
//load plugins //START BOT
this.actionRecorder.push({ console.log("OT: Compilation Succeeded!")
category:"ot.managers.plugins", if (process.argv.includes("--compile-only")) process.exit(0) //exit when only compile is required!
file:"./core/api/pluginlauncher.js", console.log("OT: Starting Bot!")
time:new Date().getTime(), require("./dist/src/index.js")
type:"plugins.loading"
})
require("./core/api/pluginlauncher")()
this.actionRecorder.push({
category:"ot.managers.plugins",
file:"./core/api/pluginlauncher.js",
time:new Date().getTime(),
type:"plugins.success"
})
this.errorLog.log("debug","loading plugins")
})
if (!require("./core/api/api.json").disable.checkerjs.all){
this.actionRecorder.push({
category:"ot.managers.main",
file:"./core/checker.js",
time:new Date().getTime(),
type:"checker.loading"
})
require("./core/checker").checker()
this.errorLog.log("debug","loading checker.js")
this.errorLog.log("debug","checking config...")
this.actionRecorder.push({
category:"ot.managers.main",
file:"./core/checker.js",
time:new Date().getTime(),
type:"checker.success"
})
}
if (process.argv[2] && process.argv[2].startsWith("slash")){
//do nothing
}else{
this.actionRecorder.push({
category:"ot.managers.loader",
file:"./index.js",
time:new Date().getTime(),
type:"commands.loading"
})
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")()
require("./commands/change")()
this.actionRecorder.push({
category:"ot.managers.loader",
file:"./index.js",
time:new Date().getTime(),
type:"commands.success"
})
this.actionRecorder.push({
category:"ot.managers.loader",
file:"./index.js",
time:new Date().getTime(),
type:"core.loading"
})
this.errorLog.log("debug","LOADING CORE")
//core
require('./core/ticketActions/ticketOpener')()
require("./core/reactionRoles")()
require("./core/ticketActions/ticketAutoclose")()
this.errorLog.log("debug","LOADING INTERACTION HANDLERS")
//InteractionHandlers
require("./core/interactionHandlers/handlers/handlers")()
this.actionRecorder.push({
category:"ot.managers.loader",
file:"./index.js",
time:new Date().getTime(),
type:"core.success"
})
}
this.actionRecorder.push({
category:"ot.managers.loader",
file:"./index.js",
time:new Date().getTime(),
type:"api.loading"
})
this.errorLog.log("debug","loading api")
const APIEvents = require("./core/api/modules/events")
const APIConfig = require("./core/api/api.json")
this.actionRecorder.push({
category:"ot.managers.loader",
file:"./index.js",
time:new Date().getTime(),
type:"api.success"
})
this.actionRecorder.push({
category:"ot.managers.loader",
file:"./index.js",
time:new Date().getTime(),
type:"debugsystem.loading"
})
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)
}
this.errorLog.clearDebugFile()
}
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.clearDebugFile()
}
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())
//TEMPORARY INTEGRATION FOR LIVESTATUS ERROR UPLOADER:
await require("./core/utils/liveStatus").liveStatusUploadManager(error.name+": "+error.message+" | origin: "+origin+"\n"+error.stack)
})
this.actionRecorder.push({
category:"ot.managers.loader",
file:"./index.js",
time:new Date().getTime(),
type:"debugsystem.success"
})
const token = config.token.fromENV ? process.env.TOKEN : config.token.value
client.login(token)
this.errorLog.log("debug","login with token")
-101
View File
@@ -1,101 +0,0 @@
{
"_CREDITS":"ChilledBroke#9986 & M4#5882",
"_INFO":"This file is a translation for open ticket 3.4.0",
"errors": {
"missingArgsTitle": "قيمة غير صالحة!",
"missingArgsDescription": "قيمة مفقودة",
"noPermsTitle": "ليس لديك برمشنات !",
"noPermsDescription": "أنت بحاجة الى برمشن `ADMINISTRATOR` او أن تكون في قائمة المسموح بهم!",
"noPermsDelete": "فقط الإداريين يمكنهم حذف التكت!",
"chooseFromListTitle": "Invalid ID",
"chooseFromListDescription": "قم بأختيار أحد من الأيديات من الأسفل:",
"boterror": "خلل في البوت !",
"notInTicketTitle": "انت لست في تكت!",
"notInTicketDescription": "هذا الأمر لا يعمل خارج التكت!",
"ticketDoesntExist": "هذا التكت لم يعد فعال!",
"roleDoesntExist": "خطاً ,لم تعد الرتبة موجوده!",
"anotherOption": "هذا الخيار ليس التكت و لكنه شيء أخر!",
"maxAmountTitle": "خطأ , تم الوصول الى الحد الأقصى!",
"maxAmountDescription": "لقد وصلت الى الحد الأقصى لعدد التكتات المسموحة بها!\nSo لا يمكنك فتح واحدة أخرى!",
"somethingWentWrong": "**هناك خطاً!**\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!",
"changeTitle":"Changed ticket type to {0}!",
"statsTitle":"Here are the stats for {0}!",
"autocloseTitle":"This ticket will be closed automatically after {0}!",
"autocloseRejectTitle":"This ticket will no longer be closed automatically!",
"autocloseWarn":"This only affects inactive tickets!",
"goToTicket":"go to ticket",
"ticketWarning": "هذا الأمبد موجود بالفعل في الرسالة بالأسفل!",
"maxTicketWarning": "**تحذير:** _يمكنك فقط فتح {0} تكت في الوقت!_"
},
"helpMenu": {
"title": "الأوامر المتاحة:",
"header1": "**أذهب الى {0} لإنشاء تذكرة!**\n\n",
"header2": "**قم بكتابة أمر `/new` او `/ticket` لفتح تكت!**\n\n",
"msgCmd": "أنشاء أيمبد مع الأزرار. (الأداريين فقط)",
"renameCmd": "إعادة تسمية التكت. (بدون مسافات)",
"closeCmd": "أغلاق التكت.",
"deleteCmd": "حذف التكت.",
"addCmd": "إضافة مستخدم الى التكت.",
"removeCmd": "إزالة مستخدم من التكت.",
"reopenCmd": "إعادة فتح تكت بعد إغلاقة.",
"changeCmd":"Change ticket type.",
"claimCmd":"Claim a ticket.",
"unclaimCmd":"Unclaim a ticket.",
"statsCmd":"View ticket stats.",
"autocloseCmd":"Set timer to automatically close ticket"
},
"buttons": {
"close": "إغلاق التكت",
"delete": "حذف التكت",
"reopen": "إعادة فتح التكت",
"closeWithReason":"close with reason"
},
"messages": {
"closedDescription": "فقط الأداريين يمكنهم التحدث في هذا التكت الأن!\n\n*أضغط على الزر بالأسفل لحذف التكت او إعادة فتحة مجدداً!*",
"createdTitle": "تم إنشاء تكت!",
"createdDescription": "تم أنشاء تكت , قم بأنتظار الدعم في الطريق!",
"newTicketDmTitle": "تكت جديد!",
"closedTicketDmTitle": "تم إغلاق التكت!",
"deletedTicketDmTitle": "تم حذف التكت!",
"closedTicketDmDescription": "تم أغلاق تذكرتك من قبل إداري",
"deletedTicketDmDescription": "تم حذف تذكرتك من قبل إداري!",
"reopenTicketDmTitle": "تم إعادة فتح تذكرتك!",
"reopenTicketDmDescription": "تم إعادة فتح التكت!",
"chooseCategory": "أختر الكتقاجوري:",
"gettingdeleted": "يتم حذف التكت...",
"none": "لا يوجد",
"reason": "سبب",
"createdat":"created at",
"openedby":"opened by",
"deletedby":"deleted by",
"closedby":"closed by",
"modalreason":"What is the reason for closing this ticket?",
"chooseATicket": "Choose a ticket"
},
"transcripts":{
"title":"Transcript",
"processed":"This transcript is being processed",
"wait":"Please wait!",
"estimated":"Estimated time",
"available":"The transcript is available here"
}
}
-101
View File
@@ -1,101 +0,0 @@
{
"_CREDITS":"DJdj Development",
"_INFO":"This file is a translation for open ticket 3.4.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!"
},
"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 claimed to {0}",
"unclaimTitle":"This ticket isn't claimed anymore!",
"changeTitle":"Changed ticket type to {0}!",
"statsTitle":"Here are the stats for {0}!",
"autocloseTitle":"This ticket will be closed automatically after {0}!",
"autocloseRejectTitle":"This ticket will no longer be closed automatically!",
"autocloseWarn":"This only affects inactive tickets!",
"goToTicket":"go to ticket",
"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.",
"changeCmd":"Change ticket type.",
"claimCmd":"Claim a ticket.",
"unclaimCmd":"Unclaim a ticket.",
"statsCmd":"View ticket stats.",
"autocloseCmd":"Set timer to automatically close ticket"
},
"buttons":{
"close":"Close Ticket",
"delete":"Delete Ticket",
"reopen":"Re-Open Ticket",
"closeWithReason":"close with reason"
},
"messages":{
"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!",
"chooseCategory":"choose a category:",
"gettingdeleted":"Ticket is getting deleted...",
"none":"none",
"reason":"reason",
"createdat":"created at",
"openedby":"opened by",
"deletedby":"deleted by",
"closedby":"closed by",
"modalreason":"What is the reason for closing this ticket?",
"chooseATicket": "Choose a ticket"
},
"transcripts":{
"title":"Transcript",
"processed":"This transcript is being processed",
"wait":"Please wait!",
"estimated":"Estimated time",
"available":"The transcript is available here"
}
}
-101
View File
@@ -1,101 +0,0 @@
{
"_CREDITS":"t0miiis#3022",
"_INFO":"This file is a translation for open ticket 3.4.0",
"errors":{
"missingArgsTitle":"Neplatny Argument!",
"missingArgsDescription":"Chybí Argument",
"noPermsTitle":"Nemáš práva!",
"noPermsDescription":"Potřebujes `ADMINISTRATOR`roli nebo byt v listině povolenych roli!",
"noPermsDelete":"Pouze Admini muůřou mazat ticket!",
"chooseFromListTitle":"Neplatný ID",
"chooseFromListDescription":"Vyber si jedno z ID níže:",
"boterror":"Bot Chyba!",
"notInTicketTitle":"Nejsi v ticketu!",
"notInTicketDescription":"Tenhle příkaz nefunguje mimo ticket!",
"ticketDoesntExist":"Tenhle ticket už neexistuje !",
"roleDoesntExist":"Tenhle role už neexistuje!",
"anotherOption":"This option is not a ticket but another type!",
"maxAmountTitle":"Max počet byl dosáhnut!",
"maxAmountDescription":"Dosáhl jsi max počet povolených ticketu!\nSo nemůžeš si vytvořit nový!",
"somethingWentWrong":"**Něco se pokazilo!**\nProsím zkus to jindy!"
},
"commands":{
"userAddedTitle":"Přidat {0} do tohohle ticketu!",
"userRemovedTitle":"Odstranit {0} z tohohle ticketu!",
"renameTitle":"Změnit jmeno na {0}!",
"closeTitle":"Zavři tenhle ticket!",
"deleteTitle":"Mažu ticket...",
"reopenTitle":"Znovu otevíram ticket",
"claimTitle":"Ticket nyní převzal {0}",
"unclaimTitle":"Ticket už není převzaný",
"changeTitle":"Změněn typ ticketu {0}!",
"statsTitle":"Tady je info o ticketu {0}!",
"autocloseTitle":"Tento ticketu bude automaticky uzavřen za {0}!",
"autocloseRejectTitle":"Tento ticketu už nebude automaticky uzavřen!",
"autocloseWarn":"Toto zavře pouze neaktivní tickety!",
"goToTicket":"běž do ticketu",
"ticketWarning":"The embed is in the message below!",
"maxTicketWarning":"**Warning:** _Můžeš vytvořit pouze {0} v tuhle chvíli!_"
},
"helpMenu":{
"title":"Dostupné příkazy:",
"header1":"**Běž do {0} pro vytvoření ticketi!**\n\n",
"header2":"**Použíj příkaz `/nový` nebo `/ticket` pro vytvoření ticketu**\n\n",
"msgCmd":"Vytvoř embed s tlačíky. (admins only)",
"renameCmd":"Přejmenovat ticket. (no spaces)",
"closeCmd":"Zavřít ticket.",
"deleteCmd":"Odstranit ticket.",
"addCmd":"Pridat uživatele do ticketu.",
"removeCmd":"Odebrat uživatele z ticketu.",
"reopenCmd":"Re-Open a ticket after it was closed.",
"changeCmd":"Změnit typ ticketu.",
"claimCmd":"Převzi ticket.",
"unclaimCmd":"Uvolnit ticket.",
"statsCmd":"Zobrazit info o ticketu.",
"autocloseCmd":"Nastavit automatické uzavření ticketu"
},
"buttons":{
"close":"Zavřit ticket",
"delete":"Vymazat ticket",
"reopen":"Znovu otevřít ticket",
"closeWithReason":"zavřít s důvodem"
},
"messages":{
"closedDescription":"Pouze admini muzou zde psát ted!\n\n*Klikni na tlačítko níže pro smazání nebo pro znovu otevření tohohle ticketu!*",
"createdTitle":"Ticket otevřen!",
"createdDescription":"Tvůj ticket je vytvořem, můžeš si ho všimnout pomocí pingu!",
"newTicketDmTitle":"Nový ticket!",
"closedTicketDmTitle":"Ticket Zavřený!",
"deletedTicketDmTitle":"Ticket Odstranen!",
"closedTicketDmDescription":"Tvuj ticket je uzavřen!",
"deletedTicketDmDescription":"Tvuj ticket byl smazan!",
"reopenTicketDmTitle":"Ticket je znovu otevřený!",
"reopenTicketDmDescription":"Tvuj ticket byl znovu ovetřený!",
"chooseCategory":"Vyber si kategorii:",
"gettingdeleted":"Ticket bude vymazan...",
"none":"žádný",
"reason":"důvod",
"createdat":"otevřeno v",
"openedby":"otevřel",
"deletedby":"smazano uzivatelem",
"closedby":"zavreno uzivatelem",
"modalreason":"Jakž byl důvod k zavření toho ticketu?",
"chooseATicket": "Vyber ticket"
},
"transcripts":{
"title":"Přepis",
"processed":"Tento přepis se zpracoval",
"wait":"Prosím počkej!",
"estimated":"Odhadovaný čas",
"available":"Záloha je uložena zde!"
}
}
-101
View File
@@ -1,101 +0,0 @@
{
"_CREDITS":"the_gamer#5095",
"_INFO":"This file is a translation for open ticket 3.4.0",
"errors": {
"missingArgsTitle": "Ugyldigt Argument!",
"missingArgsDescription": "Manglende Argument",
"noPermsTitle": "Ikke tilladelse!",
"noPermsDescription": "Du skal have tilladelsen `ADMINISTRATOR` eller være på listen over tilladte roller!",
"noPermsDelete": "Kun administratorer kan slette en ticket!",
"chooseFromListTitle": "Ugyldigt ID",
"chooseFromListDescription": "Vælg et af id'erne nedenfor:",
"boterror": "Bot Fejl!",
"notInTicketTitle": "Du er ikke i en ticket!",
"notInTicketDescription": "Denne kommando virker ikke udenfor tickets!",
"ticketDoesntExist": "Denne ticket findes ikke længere!",
"roleDoesntExist": "Denne rolle eksisterer ikke længere!",
"anotherOption": "Denne mulighed er ikke en ticket, men en anden type!",
"maxAmountTitle": "Maks. mængde opnået!",
"maxAmountDescription": "Du har nået det maksimale antal tilladte tickets!\nSå du kan ikke oprette en ny!",
"somethingWentWrong": "**Noget gik galt!**\nPrøv venligst igen en anden gang!"
},
"commands": {
"userAddedTitle": "Føjede {0} til denne ticket!",
"userRemovedTitle": "Fjernede {0} fra denne ticket!",
"renameTitle": "Ændrede navnet til {0}!",
"closeTitle": "Lukket denne ticket!",
"deleteTitle": "Sletter denne ticket...",
"reopenTitle": "Genåbnede denne ticket!",
"claimTitle": "Denne ticket bliver nu håndteret af {0}",
"unclaimTitle": "Denne ticket bliver ikke håndteret længere!",
"changeTitle": "Ændrede ticket-type til {0}!",
"statsTitle": "Her er statestikerne til {0}!",
"autocloseTitle": "Denne ticket lukker automatisk om {0}!",
"autocloseRejectTitle": "Denne ticket lukker ikke længere automatisk!",
"autocloseWarn": "Dette har kun effekt på inaktive tickets!",
"goToTicket": "gå til ticket",
"ticketWarning": "Embedet er i meddelelsen nedenfor!",
"maxTicketWarning": "**Warning:** _Du kan kun oprette {0} ticket(s) ad gangen!_"
},
"helpMenu": {
"title": "Tilgængelige kommandoer:",
"header1": "**Gå til {0} for at oprette en ticket!**\n\n",
"header2": "**Kør kommandoen `/new` eller `/ticket` for at oprette en billet!**\n\n",
"msgCmd": "Lav et embed med buttons. (kun administratorer)",
"renameCmd": "Omdøb en ticket. (Ingen Mellemrum!!)",
"closeCmd": "Luk en ticket.",
"deleteCmd": "Slet en ticket.",
"addCmd": "Tilføj en bruger til ticketen.",
"removeCmd": "Fjern en bruger fra ticketen.",
"reopenCmd": "Genåbn en ticket, efter at den var lukket.",
"changeCmd": "Skift ticket type.",
"claimCmd": "Håndter en ticket.",
"unclaimCmd": "Afhåndter en ticket.",
"statsCmd": "Se ticket statestiker.",
"autocloseCmd": "Angiv tiden til automatisk at lukke en ticket"
},
"buttons": {
"close": "Luk Ticket",
"delete": "Slet Ticket",
"reopen": "Genåben Ticket",
"closeWithReason": "Luk med grundlag"
},
"messages": {
"closedDescription": "Kun administratorer kan tale i denne billet nu!\n\n*Klik på knappen nedenfor for at slette eller genåbne denne billet!",
"createdTitle": "Ticket Oprettet!",
"createdDescription": "Din ticket er oprettet, du kan registrere den ved et ping!",
"newTicketDmTitle": "Nt Ticket!",
"closedTicketDmTitle": "Ticket Lukket!",
"deletedTicketDmTitle": "Ticket Slettet!",
"closedTicketDmDescription": "Din ticket er lukket!",
"deletedTicketDmDescription": "Din ticket er slettet!",
"reopenTicketDmTitle": "Ticket Genåbnet!",
"reopenTicketDmDescription": "Din ticket er genåbnet!",
"chooseCategory": "vælg en kategori:",
"gettingdeleted": "Ticketen bliver slettet...",
"none": "intet",
"reason": "grundlag",
"createdat": "lavet af",
"openedby": "åbnet af",
"deletedby": "slettet af",
"closedby": "lukket af",
"modalreason": "Hvad er grunden til at lukke denne ticket?",
"chooseATicket": "Vælg en ticket"
},
"transcripts": {
"title": "Transcript",
"processed": "Dette transcript er under behandling",
"wait": "Vent venligst!",
"estimated": "Estimeret tid",
"available": "Transcriptet er tilgængelig her"
}
}
-101
View File
@@ -1,101 +0,0 @@
{
"_CREDITS":"DJj123dj#1706",
"_INFO":"This file is a translation for open ticket 3.4.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!"
},
"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":"Dit ticket is geclaimed door {0}",
"unclaimTitle":"Dit ticket is niet meer geclaimed!",
"changeTitle":"Ticket type veranderd naar {0}!",
"statsTitle":"Hier zijn de stats voor {0}!",
"autocloseTitle":"Dit ticket wordt automatisch gesloten na {0}!",
"autocloseRejectTitle":"Dit ticket wordt niet langer automatisch gesloten!",
"autocloseWarn":"Dit geldt alleen voor inactieve tickets!",
"goToTicket":"ga naar ticket",
"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.",
"changeCmd":"Verander ticket type.",
"claimCmd":"Claim een ticket.",
"unclaimCmd":"Unclaim een ticket.",
"statsCmd":"Bekijk ticket stats.",
"autocloseCmd":"Zet een timer om het ticket automatisch te sluiten"
},
"buttons":{
"close":"Sluit Ticket",
"delete":"Verwijder Ticket",
"reopen":"Heropen Ticket",
"closeWithReason":"sluit met reden"
},
"messages":{
"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!",
"chooseCategory":"kies een categorie:",
"gettingdeleted":"Ticket wordt verwijderd...",
"none":"geen",
"reason":"reden",
"createdat":"gecreëerd op",
"openedby":"geopend door",
"deletedby":"verwijderd door",
"closedby":"gesloten door",
"modalreason":"Wat is de reden om dit ticket te sluiten?",
"chooseATicket": "Kies een ticket"
},
"transcripts":{
"title":"Transcript",
"processed":"Dit transcript wordt verwerkt",
"wait":"Gelieve te wachten!",
"estimated":"Geschatte tijd",
"available":"Het transcript is hier beschikbaar"
}
}
-101
View File
@@ -1,101 +0,0 @@
{
"_CREDITS":"DJdj Development",
"_INFO":"This file is a translation for open ticket 3.4.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!"
},
"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 claimed to {0}",
"unclaimTitle":"This ticket isn't claimed anymore!",
"changeTitle":"Changed ticket type to {0}!",
"statsTitle":"Here are the stats for {0}!",
"autocloseTitle":"This ticket will be closed automatically after {0}!",
"autocloseRejectTitle":"This ticket will no longer be closed automatically!",
"autocloseWarn":"This only affects inactive tickets!",
"goToTicket":"go to ticket",
"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.",
"changeCmd":"Change ticket type.",
"claimCmd":"Claim a ticket.",
"unclaimCmd":"Unclaim a ticket.",
"statsCmd":"View ticket stats.",
"autocloseCmd":"Set timer to automatically close ticket"
},
"buttons":{
"close":"Close Ticket",
"delete":"Delete Ticket",
"reopen":"Re-Open Ticket",
"closeWithReason":"close with reason"
},
"messages":{
"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!",
"chooseCategory":"choose a category:",
"gettingdeleted":"Ticket is getting deleted...",
"none":"none",
"reason":"reason",
"createdat":"created at",
"openedby":"opened by",
"deletedby":"deleted by",
"closedby":"closed by",
"modalreason":"What is the reason for closing this ticket?",
"chooseATicket": "Choose a ticket"
},
"transcripts":{
"title":"Transcript",
"processed":"This transcript is being processed",
"wait":"Please wait!",
"estimated":"Estimated time",
"available":"The transcript is available here"
}
}
-101
View File
@@ -1,101 +0,0 @@
{
"_CREDITS":"Sanke#6086",
"_INFO":"This file is a translation for open ticket 3.4.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!"
},
"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":"Ce ticket est maintenant réclamé à {0}",
"unclaimTitle":"Ce ticket n'est pas réclamé!",
"changeTitle":"Modification du type de ticket en {0}!",
"statsTitle":"Voici les statistiques pour {0}!",
"autocloseTitle":"Ce ticket sera automatiquement clôturé après {0}!",
"autocloseRejectTitle":"Ce ticket ne sera plus clôturé automatiquement!",
"autocloseWarn":"Cela n'affecte que les tickets inactifs!",
"goToTicket":"Aller au ticket",
"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.",
"changeCmd":"Changer le type de ticket.",
"claimCmd":"Réclamer un billet",
"unclaimCmd":"Annuler la réclamation d'un ticket.",
"statsCmd":"Afficher les statistiques des tickets.",
"autocloseCmd":"Définir une minuterie pour fermer automatiquement le ticket"
},
"buttons":{
"close":"Fermer le ticket",
"delete":"Supprimer le billet",
"reopen":"Billet de réouverture",
"closeWithReason":"fermer avec une raison"
},
"messages":{
"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 !",
"chooseCategory":"choisissez une catégorie:",
"gettingdeleted":"Le ticket est en cours de suppression...",
"none":"rien",
"reason":"raison",
"createdat":"Créé à",
"openedby":"Ouvert par",
"deletedby":"supprimé par",
"closedby":"fermé par",
"modalreason":"Qu’elle est la raison pour fermer ce ticket?",
"chooseATicket": "Choisir un ticket"
},
"transcripts":{
"title":"Transcript",
"processed":"Cette transcript est en cours de traitement",
"wait":"S'il vous plait, attendez...",
"estimated":"Temps estime:",
"available":"La transcript est disponible ici"
}
}
-101
View File
@@ -1,101 +0,0 @@
{
"_CREDITS":"david.#8276 ",
"_INFO":"This file is a translation for open ticket 3.4.0",
"errors":{
"missingArgsTitle":"Ungültiges Argument!",
"missingArgsDescription":"Fehlendes Argument!",
"noPermsTitle":"Du hast keine Rechte!",
"noPermsDescription":"Du benötigst die `ADMINISTRATOR` Rechte oder die erlaubte Rolle",
"noPermsDelete":"Nur Administratoren können ein Ticket löschen!",
"chooseFromListTitle":"Ungültige ID",
"chooseFromListDescription":"Wählen Sie eine der folgenden ID's:",
"boterror":"Bot Fehler!",
"notInTicketTitle":"Du bist in keinem Ticket!",
"notInTicketDescription":"Der Befehl funktioniert außerhalb eines Tickets nicht!",
"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 neuen erstellen.!",
"somethingWentWrong":"**Etwas ist schief gelaufen!**\nBitte versuchen Sie es ein anderes Mal!"
},
"commands":{
"userAddedTitle":"User geaddet!",
"userRemovedTitle":"User entfernt!",
"renameTitle":"Der Name wurde geändert!",
"closeTitle":"Dieses Ticket schließen!",
"deleteTitle":"Löschen Sie dieses Ticket!",
"reopenTitle":"Öffne dieses Ticket erneut!",
"claimTitle":"Dieses Ticket wurde beansprucht von {0}",
"unclaimTitle":"Dieses Ticket wird nichtmehr beansprucht.",
"changeTitle":"Ticket Typ wurde geändert zu {0}!",
"statsTitle":"Hier sind die Stats für {0}!",
"autocloseTitle":"Dieses Ticket wird automatisch geschlossen in {0}!",
"autocloseRejectTitle":"Dieses Ticket wird nichtmehr automatisch geschlossen",
"autocloseWarn":"Dies betrifft nur inaktive Tickets!",
"goToTicket":"Geh zu deinem Ticket",
"ticketWarning":"Die Einbettung befindet sich in der Nachricht unten!",
"maxTicketWarning":"**Warnung:** _Es können maximal {0} Tickets zur gleichen Zeit geöffnet sein!_"
},
"helpMenu":{
"title":"Hilfe Menu:",
"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.",
"changeCmd":"Ticket Typ ändern",
"claimCmd":"Ticket beanspruchen",
"unclaimCmd":"Ticket nicht mehr beanspruchen.",
"statsCmd":"Ticket Stats",
"autocloseCmd":"Timer wurde gesetzt auf automatisches schließen des Tickets"
},
"buttons":{
"close":"Ticket schließen",
"delete":"Ticket löschen",
"reopen":"Ticket wieder öffnen",
"closeWithReason":"Geschlossen mit dem Grund"
},
"messages":{
"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!",
"newTranscriptTitle":"Eine neue Transcript finden Sie hier!",
"hereIsTheTranscript":"Hier ist das Transcript:",
"chooseCategory":"Wähle eine Kategorie:",
"gettingdeleted":"Ticket wird gelöscht...",
"none":"none",
"reason":"Grund",
"createdat":"Erstellt um",
"openedby":"Geöffnet um",
"deletedby":"Gelöscht von",
"closedby":"Geschlossen von",
"modalreason":"Was ist der Grund?",
"chooseATicket": "Wähle ein passendes Thema!"
},
"transcripts":{
"title":"Transcript",
"processed":"Das Transcript wird erstellt",
"wait":"Bitte warten!",
"estimated":"Verbleibende Zeit",
"available":"Das Transcript ist hier verfügbar"
}
}
-101
View File
@@ -1,101 +0,0 @@
{
"_CREDITS":"ꙅoᴎɒᎸɘƚꙅ#3744",
"_INFO":"This file is a translation for open ticket 3.4.0",
"errors":{
"missingArgsTitle":"Invalid Arguments!",
"missingArgsDescription":"Missing Argument",
"noPermsTitle":"Δεν έχεις άδεια για να τρέξεις αυτή την εντολή!",
"noPermsDescription":"Χρειάζεσε άδεια διαχειριστή για να τρέξεις αυτή την εντολή.",
"noPermsDelete":"Μόνο οι διαχειριστές μπορούν να διαγράψουν τα εισιτήρια!",
"chooseFromListTitle":"Μη έγκυρο id.",
"chooseFromListDescription":"Διάλεξε ενα απο τα παρακάτω id:",
"boterror":"Υπάρχει κάποιο πρόβλημα!",
"notInTicketTitle":"Δεν είσε στο κανάλι του εισιτηρίου!",
"notInTicketDescription":"Δεν μπορείς να τρέξεις αυτή την εντολή εκτός του εισιτηρίου",
"ticketDoesntExist":"Αυτο το εισιτήριο δεν υπάρχει!",
"roleDoesntExist":"Αυτός ο ρόλος δεν υπάρχει!",
"anotherOption":"Διάλεξε άλλο λόγο για εισιτήριο!",
"maxAmountTitle":"Έχεις ανοίξει πολλά εισιτήρια για την ώρα.",
"maxAmountDescription":"Έχεις υπερβεί το όριο των εισιτηρίον!\nΔεν μπορείς να ανοίξεις καινούργιο.!",
"somethingWentWrong":"**Κάτι πήγε λάθος!**\nΔοκίμασε ξανά αργότερα!"
},
"commands":{
"userAddedTitle":"Ο {0} προσθέθηκε στο εισιτήριο",
"userRemovedTitle":"Ο {0} αφαιρέθηκε απο το εισιτήριο!",
"renameTitle":"Το όνομα άλλαξε σε {0}!",
"closeTitle":"Το εισιτήριο έκλεισε!",
"deleteTitle":"Διαγράφω το εισιτήριο...",
"reopenTitle":"Το εισιτήριο ξανά άνοιξε!",
"claimTitle":"Το εισιτήριο διεκδικήθεικε απο τον {0}",
"unclaimTitle":"Το εισιτήριο δεν είναι πλέον διεκδικημένο!",
"changeTitle":"Ο τύπος του εισιτηρίου άλλαξε σε {0}!",
"statsTitle":"Εδώ είναι τα στατιστικά για το {0}!",
"autocloseTitle":"Αυτό το εισιτήριο θα κλείσε σε {0}!",
"autocloseRejectTitle":"Αυτό το εισιτήριο δεν θα κλέισε αυτόματα!",
"autocloseWarn":"Αυτό ισχύει μονο για μή ενεργά εισιτήρια!",
"goToTicket":"Μεταφορά στο εισιτήριο.",
"ticketWarning":"Το εισιτήριο είναι στο παρακάτω μήνυμα!",
"maxTicketWarning":"**Προειδοποίηση:** _Μπορείς να φτιάξεις μόνο {0} εισιτήριο/εισιτήρια για την ώρα!_"
},
"helpMenu":{
"title":"Διαθέσιμες εντολές:",
"header1":"**Πηγαινε στο {0} για να φτιάξεις ενα νέο εισιτήριο!**\n\n",
"header2":"**Τρέχα την εντολή `/new` ή `/ticket` για να φτιάξεις ένα εισιτήριο!**\n\n",
"msgCmd":"Εμφάνισε ένα embed με κουμπιά. (admins only)",
"renameCmd":"Μετονόμασε το εισιτήριο. (όχι κενά)",
"closeCmd":"Κλέισε το εισιτήριο.",
"deleteCmd":"Διέγραψε το εισιτήριο.",
"addCmd":"Πρόσθεσε κάποιον στο εισιτήριο.",
"removeCmd":"Αφαίρεσε κάποιον απο το εισιτήριο.",
"reopenCmd":"Ξανά άνοιξε το εισιτήριο.",
"changeCmd":"Άλλαξε τον τύπο του εισιτηρίου.",
"claimCmd":"Διεκδίκησε το εισιτήριο.",
"unclaimCmd":"Unclaim a ticket.",
"statsCmd":"Δές τα στατιστικά του εισιτηρίου.",
"autocloseCmd":"Βάλε χρονόμετρο για να κλείσει το εισιτήριο"
},
"buttons":{
"close":"κλείσε το εισιτήριο",
"delete":"Διέγραψε το εισιτήριο",
"reopen":"Ξανά άνοιξε το εισιτήριο",
"closeWithReason":"Κλείσε με αιτιολόγιση"
},
"messages":{
"closedDescription":"Μονο οι διαχειριστές μπορουν να διαγράψουν τα εισιτήρια!\n\n*Πάτα το παρακάτω κουμπί για να ξανά ανοίξεις το εισιτήριο!*",
"createdTitle":"Το εισιτήριο δημιουργήθηκε!",
"createdDescription":"Το εισιτήριο σου δημιουργήθηκε μπορείς να το βρείς με την αναφορά που έγινε στο κανάλι του εισιτηρίου!",
"newTicketDmTitle":"Νέο εισιτήριο!",
"closedTicketDmTitle":"Το εισιτήριο έκλεισε!",
"deletedTicketDmTitle":"Tο εισιτήριο διεγράφη!",
"closedTicketDmDescription":"Το εισιτήριο σου είναι κλειστό!",
"deletedTicketDmDescription":"Το εισιτήριο σου διεγράφη!",
"reopenTicketDmTitle":"Tο εισιτήριο ξανά άνοιξε!",
"reopenTicketDmDescription":"Το εισιτήριο σου ξανά άνοιξε!",
"chooseCategory":"Διάλεξε μία κατηγορία:",
"gettingdeleted":"Το εισιτήριο διαγράφεται...",
"none":"Κανένας",
"reason":"Λόγος",
"createdat":"Δημιουργήθηκε",
"openedby":"Ανοίχτηκε από",
"deletedby":"Διεγράφη απο",
"closedby":"Έκλεισε από",
"modalreason":"Ποιός είναι ο λόγος για να κλείσει το εισιτήριο?",
"chooseATicket": "Δίαλεξε ενα εισιτήριο"
},
"transcripts":{
"title":"Αντίγραφο",
"processed":"Το αντίγραφο ετοιμάζεται!",
"wait":"Παρακαλώ περιμένετε!",
"estimated":"Ώρα αναμονής",
"available":"Το αντίγραφο είναι ανοιχτώ εδώ!"
}
}
-101
View File
@@ -1,101 +0,0 @@
{
"_CREDITS":"Maurizio#0268",
"_INFO":"This file is a translation for open ticket 3.4.0",
"errors":{
"missingArgsTitle":"Argomenti non validi!",
"missingArgsDescription":"Argomenti mancanti",
"noPermsTitle":"Non hai i permessi sufficienti!",
"noPermsDescription":"Hai bisogno del permesso `ADMINISTRATOR` o essere nella lista dei ruoli consentiti!",
"noPermsDelete":"Solo gli amministratori possono eliminare i ticket!",
"chooseFromListTitle":"ID non valido",
"chooseFromListDescription":"Scegli uno degli id sottostanti:",
"boterror":"Errore del bot!",
"notInTicketTitle":"Non sei in un ticket!",
"notInTicketDescription":"Questo comando non funziona al di fuori di un ticket!",
"ticketDoesntExist":"Questo ticket non esiste!",
"roleDoesntExist":"Questo ruolo non esiste!",
"anotherOption":"Questa opzione non è un ticket ma un'altra!",
"maxAmountTitle":"Massimo ammontare raggiunto!",
"maxAmountDescription":"Hai raggiunto il massimo di ticket aperti!\nNon puoi creare altri!",
"somethingWentWrong":"*Qualcosa è andato storto!*\nPerfavore riprova un'altra volta!"
},
"commands":{
"userAddedTitle":"Aggiunti {0} a questo ticket!",
"userRemovedTitle":"Rimossi {0} da questo ticket!",
"renameTitle":"Cambiato il nome a {0}!",
"closeTitle":"Ticket chiuso!",
"deleteTitle":"Eliminando questo ticket...",
"reopenTitle":"Ri-aperto questo ticket!",
"claimTitle":"Questo ticket adesso è gestito da {0}",
"unclaimTitle":"Questo ticket non è più gestito!",
"changeTitle":"Ticket cambiato in {0}!",
"statsTitle":"Queste sono le stats per {0}!",
"autocloseTitle":"Questo ticket sarà eliminato direttamente dopo {0}!",
"autocloseRejectTitle":"Questo ticket non sarà più chiuso automaticamente!",
"autocloseWarn":"Questo vale solo per i ticket inattivi!",
"goToTicket":"vai al ticket",
"ticketWarning":"L'embed è nel messaggio sotto!",
"maxTicketWarning":"*Attenzione:* Tu puoi creare solo {0} ticket alla 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 bottoni. (solo amministratori)",
"renameCmd":"Rinomina un ticket. (senza spazi)",
"closeCmd":"Chiudi un ticket.",
"deleteCmd":"Elimina un ticket.",
"addCmd":"Aggiungi un utente al ticket.",
"removeCmd":"Rimuovi un utente da un ticket.",
"reopenCmd":"Ri-apri un ticket dopo averlo chiuso.",
"changeCmd":"Cambia tipo di ticket.",
"claimCmd":"Gestisci un ticket.",
"unclaimCmd":"Lascia la gestione del ticket.",
"statsCmd":"Vedi le statistiche dei ticket.",
"autocloseCmd":"Imposta il timer dell'autochiusura dei ticket"
},
"buttons":{
"close":"Chiudi",
"delete":"Elimini",
"reopen":"Ri-apri un ticket",
"closeWithReason":"chiudi con motivo"
},
"messages":{
"closedDescription":"Solo gli amministratori possono parlare in questo ticket ora!\n\n*Clicca sul pulsante sotto per eliminare o ri-aprire 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 è eliminato!",
"reopenTicketDmTitle":"Ticket ri-aperto!",
"reopenTicketDmDescription":"Il tuo ticket è stato ri-aperto!",
"chooseCategory":"scegli una categoria:",
"gettingdeleted":"Il ticket sta per essere chiuso...",
"none":"nessuno",
"reason":"motivo",
"createdat":"creato il",
"openedby":"aperto da",
"deletedby":"eliminato da",
"closedby":"chiuso da",
"modalreason":"Quale è il motivo per chiudere questo ticket?",
"chooseATicket": "Scegli un ticket"
},
"transcripts":{
"title":"Trascrizione",
"processed":"Questo ticket sta per essere processato",
"wait":"Perfavore attendi!",
"estimated":"Tempo estimato",
"available":"La trascrizione è disponibile qui"
}
}
-101
View File
@@ -1,101 +0,0 @@
{
"_CREDITS":"NoOneNook#0266",
"_INFO":"This file is a translation for open ticket 3.4.0",
"errors":{
"missingArgsTitle":"Ugyldige argumenter!",
"missingArgsDescription":"Manglende argument",
"noPermsTitle":"Ingen rettigheter",
"noPermsDescription":"Du trenger administrator eller moderator rettigheter",
"noPermsDelete":"Bare staff kan slette en ticket!",
"chooseFromListTitle":"Ugyldig ID",
"chooseFromListDescription":"Velg en av ID-ene nedenfor:",
"boterror":"Bot Error!",
"notInTicketTitle":"Du er ikke i en ticket!",
"notInTicketDescription":"Du kan ikke bruke denne command utenfor en ticket.",
"ticketDoesntExist":"Ticket finnes ikke lenger!",
"roleDoesntExist":"Rollen eksisterer ikke lenger!",
"anotherOption":"Dette alternativet er ikke en ticket!",
"maxAmountTitle":"Maks antall er nådd!",
"maxAmountDescription":"Du har nådd maksimalt antall tillatte ticket's\nSå du kan ikke lage en ny før de andre er lukket!",
"somethingWentWrong":"**Noe gikk galt!**\nVennligst prøv igjen senere!"
},
"commands":{
"userAddedTitle":"{0} har blitt lagt til i ticket!",
"userRemovedTitle":"Fjernet {0} fra ticket!",
"renameTitle":"Endret navn til {0}!",
"closeTitle":"Ticket er blitt lukket!",
"deleteTitle":"Sletter ticket...",
"reopenTitle":"Ticket er gjenåpnet",
"claimTitle":"{0} har tatt over denne saken!",
"unclaimTitle":"Denne ticket er blitt ledig igjen!",
"changeTitle":"Endret ticket-type til {0}!",
"statsTitle":"Her er statistikken for {0}!",
"autocloseTitle":"Denne ticket stenges automatisk etter kl {0}!",
"autocloseRejectTitle":"Denne ticket vil ikke lenger stenges automatisk!",
"autocloseWarn":"Dette påvirker kun inaktive tickets!",
"goToTicket":"DIN TICKET",
"ticketWarning":"Embed er i meldingen nedenfor!",
"maxTicketWarning":"**Advarsel:** _Du kan bare opprette {0}ticket(s) om gangen!_"
},
"helpMenu":{
"title":"Tilgjengelige Commands:",
"header1":"**Gå til {0} for å opprette en ticket!**\n\n",
"header2":"**Skriv kommandoen `/new` eller `/ticket` for å lage en ticket!**\n\n",
"msgCmd":"Lag en embed med knapper. (admins only)",
"renameCmd":"Gi nytt navn til en ticket. (ingen mellomrom)",
"closeCmd":"Lukk en ticket.",
"deleteCmd":"Slett en ticket.",
"addCmd":"Legg til en bruker i ticket.",
"removeCmd":"Fjern en bruker fra ticket.",
"reopenCmd":"Åpne en ticket på nytt etter at den ble avsluttet.",
"changeCmd":"Endre ticket kategori",
"claimCmd":"Ta over ticket.",
"unclaimCmd":"Frigjør den fra ticket.",
"statsCmd":"Se ticket stats.",
"autocloseCmd":"Still inn når ticket lukkes automatisk etter den ble åpnet"
},
"buttons":{
"close":"Lukk Ticket",
"delete":"Slett Ticket",
"reopen":"Gjenåpne Ticket",
"closeWithReason":"Legg til årsak"
},
"messages":{
"closedDescription":"Bare staff medlemmer kan snakke i denne ticket nå!\n\n*Klikk på knappen nedenfor for å slette eller åpne ticket på nytt!*",
"createdTitle":"Ticket er laget!",
"createdDescription":"__Du finner den ved å trykke på knappen under__",
"newTicketDmTitle":"New Ticket!",
"closedTicketDmTitle":"Ticket Åpnet!",
"deletedTicketDmTitle":"Ticket Slettet!",
"closedTicketDmDescription":"Din ticket er lukket!",
"deletedTicketDmDescription":"Din ticket er slettet!",
"reopenTicketDmTitle":"Ticket gjenåpnet!",
"reopenTicketDmDescription":"Din icket er gjenåpnet!",
"chooseCategory":"Velg en kategori:",
"gettingdeleted":"Ticket slettes....",
"none":"Ingen",
"reason":"Grunnlag",
"createdat":"Laget",
"openedby":"Laget av",
"deletedby":"Slettet av",
"closedby":"Lukket av",
"modalreason":"Grunnlag for lukking!",
"chooseATicket": "Velg en ticket"
},
"transcripts":{
"title":"Ticket logg",
"processed":"Logg fil lages, snart klar!",
"wait":"Vennligst vent!",
"estimated":"Beregnet tid",
"available":"Loggfil er tilgjengelig over denne meldingen!"
}
}
-101
View File
@@ -1,101 +0,0 @@
{
"_CREDITS":"MKevas#8311",
"_INFO":"This file is a translation for open ticket 3.4.0",
"errors":{
"missingArgsTitle":"Nieprawidłowe argumenty!",
"missingArgsDescription":"Brakujący argument",
"noPermsTitle":"Brak permisji!",
"noPermsDescription":"Musisz mieć uprawnienia `ADMINISTRATOR` lub być na liście dozwolonych ról!",
"noPermsDelete":"Tylko administratorzy mogą usunąć zgłoszenie!",
"chooseFromListTitle":"Błędne ID",
"chooseFromListDescription":"Wybierz jeden z poniższych identyfikatorów:",
"boterror":"Błąd bota!",
"notInTicketTitle":"Nie jesteś w tickecie!",
"notInTicketDescription":"To polecenie nie działa poza ticketami!",
"ticketDoesntExist":"Ten ticket już nie istnieje!",
"roleDoesntExist":"Ta rola już nie istnieje!",
"anotherOption":"Ta opcja nie jest ticketem, ale innym typem!",
"maxAmountTitle":"Maksymalna liczba osiągnięta!",
"maxAmountDescription":"Osiągnąłeś maksymalną dozwoloną liczbę ticketów!\nWięc nie możesz stworzyć nowego!",
"somethingWentWrong":"**Coś poszło nie tak!**\nSpróbuj ponownie innym razem!"
},
"commands":{
"userAddedTitle":"Dodano {0} do tego ticketa!",
"userRemovedTitle":"Usunięto {0} z tego ticketa!",
"renameTitle":"Zmieniono nazwę na {0}!",
"closeTitle":"Zamknięto ten ticket!",
"deleteTitle":"Usuwanie tego zgłoszenia..",
"reopenTitle":"Ponownie otwarto ten ticket!",
"claimTitle":"Ten ticket został odebrany przez {0}",
"unclaimTitle":"Nie można już odebrać tego biletu!",
"changeTitle":"Changed ticket type to {0}!",
"statsTitle":"Oto statystyki dotyczące {0}!",
"autocloseTitle":"Ten ticket zostanie automatycznie zamknięty po {0}!",
"autocloseRejectTitle":"Ten ticket nie będzie już automatycznie zamykany!",
"autocloseWarn":"Dotyczy to tylko nieaktywnych biletów!",
"goToTicket":"Przejdź do ticketa",
"ticketWarning":"Osadzenie znajduje się w wiadomości poniżej!",
"maxTicketWarning":"**Ostrzeżenie:** _Możesz utworzyć tylko {0} bilet(ów) na raz!_"
},
"helpMenu":{
"title":"Dostępne polecenia:",
"header1":"**Przejdź do {0}, aby utworzyć zgłoszenie!**\n\n",
"header2":"**Uruchom polecenie `/new` lub `/ticket`, aby utworzyć zgłoszenie!**\n\n",
"msgCmd":"Odradzaj osadzanie za pomocą przycisków. (tylko administratorzy)",
"renameCmd":"Zmień nazwę zgłoszenia. (bez spacji)",
"closeCmd":"Zamknij ticket.",
"deleteCmd":"Skasuj ticket.",
"addCmd":"Dodaj użytkownika do zgłoszenia.",
"removeCmd":"Usuń użytkownika ze zgłoszenia.",
"reopenCmd":"Otwórz ponownie ticket po jego zamknięciu.",
"changeCmd":"Zmień typ ticketa.",
"claimCmd":"Odbierz ticket.",
"unclaimCmd":"Zrezygnuj z ticketa.",
"statsCmd":"Pokaż statystyki zgłoszenia.",
"autocloseCmd":"Ustaw timer, aby automatycznie zamykał ticket."
},
"buttons":{
"close":"Zamknij",
"delete":"Skasuj",
"reopen":"Otworz ponownie",
"closeWithReason":"Zamknij z powodem"
},
"messages":{
"closedDescription":"Tylko admini mogą teraz rozmawiać w tym zgłoszeniu!\n\n*Kliknij przycisk poniżej, aby usunąć lub ponownie otworzyć ten ticket!*",
"createdTitle":"Ticket Created!",
"createdDescription":"Twój ticket został utworzony, możesz go wykryć za pomocą pingu!",
"newTicketDmTitle":"Nowy Ticket!",
"closedTicketDmTitle":"Ticket Zamknięty!",
"deletedTicketDmTitle":"Ticket Skasowany!",
"closedTicketDmDescription":"Twój ticket jest zamknięty!",
"deletedTicketDmDescription":"Twój ticket został skasowany!",
"reopenTicketDmTitle":"Ticket otwarty!",
"reopenTicketDmDescription":"Twój ticket został ponownie otwarty!",
"chooseCategory":"Wybierz kategorię:",
"gettingdeleted":"Ticket jest usuwany..",
"none":"brak",
"reason":"powód",
"createdat":"utworzony",
"openedby":"otwarte przez",
"deletedby":"skasowane przez",
"closedby":"zamknięte przez",
"modalreason":"Jaki jest powód zamknięcia tego zgłoszenia?",
"chooseATicket": "Wybierz zgłoszenie"
},
"transcripts":{
"title":"Transkrypcja",
"processed":"Ta transkrypcja jest przetwarzana",
"wait":"Proszę czekać!",
"estimated":"Szacowany czas",
"available":"Transkrypcja jest dostępna tutaj"
}
}
-101
View File
@@ -1,101 +0,0 @@
{
"_CREDITS":"QuirAddon#9778",
"_INFO":"This file is a translation for open ticket 3.4.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!"
},
"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":"Esse ticket foi reinvidicado {0}",
"unclaimTitle":"Esse ticket não foi reinvidicado!",
"changeTitle":"Tipo de ticket alterado para {0}!",
"statsTitle":"Aqui estão as estatísticas para {0}!",
"autocloseTitle":"Este ticket vai fechar altomaticamente após {0}!",
"autocloseRejectTitle":"Este ticket não será mais fechado automaticamente!",
"autocloseWarn":"Isso apenas afeta tickets inativos!",
"goToTicket":"ir para ticket",
"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.",
"changeCmd":"Mudar tipo de ticket",
"claimCmd":"Resgatar Ticket",
"unclaimCmd":"Desresgatar Ticket",
"statsCmd":"Olhar status do ticket",
"autocloseCmd":"Definir tempo para fechar ticket automaticamente."
},
"buttons":{
"close":"Fechar Ticket",
"delete":"Excluir Ticket",
"reopen":"Reabrir Ticket",
"closeWithReason":"fechado com motivo"
},
"messages":{
"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!",
"chooseCategory":"Escolha a categoria:",
"gettingdeleted":"Ticket está sendo deletado...",
"none":"vazio",
"reason":"motivo",
"createdat":"Criado por:",
"openedby":"Aberto por:",
"deletedby":"deletado por",
"closedby":"fechado por",
"modalreason":"Qual o motivo de fechar o ticket?",
"chooseATicket": "Fechar Ticket"
},
"transcripts":{
"title":"Transcrever",
"processed":"A Transcrição está em andamento",
"wait":"Por favor espere!",
"estimated":"Tempo estimado",
"available":"A Transcrição está disponível aqui"
}
}
-101
View File
@@ -1,101 +0,0 @@
{
"_CREDITS":"Sanke#6086",
"_INFO":"This file is a translation for open ticket 3.4.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!"
},
"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":"Acest ticket a primit claim de la {0}",
"unclaimTitle":"Acest ticket nu mai este detinut!",
"changeTitle":"A fost schimbat tipul ticket-ului la {0}!",
"statsTitle":"Acestea sunt informatiile pentru {0}!",
"autocloseTitle":"Acest ticket va fi inchis automat dupa {0}!",
"autocloseRejectTitle":"Acest ticket nu va mai fi inchis automat!",
"autocloseWarn":"Aceasta optiune afecteaza numai ticketele inactive!",
"goToTicket":"Mergi la ticket",
"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.",
"changeCmd":"Schimba categoria ticket-ului.",
"claimCmd":"Revendica un ticket",
"unclaimCmd":"Anuleaza revendicarea unui ticket.",
"statsCmd":"Afiseasa informatiile ticket-ului.",
"autocloseCmd":"Seteaza un cronometru pentru inchiderea ticket-ului."
},
"buttons":{
"close":"Inchide ticket-ul",
"delete":"Sterge ticket-ul",
"reopen":"Re-deschide un ticket",
"closeWithReason":"Inchide cu motiv"
},
"messages":{
"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!",
"chooseCategory":"Alege o categorie:",
"gettingdeleted":"Ticket-ul se sterge...",
"none":"niciunul",
"reason":"Motiv",
"createdat":"Creat la",
"openedby":"Deschis de",
"deletedby":"Sters de",
"closedby":"Inchis de",
"modalreason":"Care este motivul pentru inchiderea acestui ticket?",
"chooseATicket": "Alege un ticket"
},
"transcripts":{
"title":"Transcript",
"processed":"Transcript in curs de procesare...",
"wait":"Te rugam sa astepti!",
"estimated":"Timp estimat",
"available":"Transcriptul este disponibil aici"
}
}
-101
View File
@@ -1,101 +0,0 @@
{
"_CREDITS":"Apexo#0723",
"_INFO":"This file is a translation for open ticket 3.4.0",
"errors":{
"missingArgsTitle":"Неверные аргументы!",
"missingArgsDescription":"Отсутствует аргумент",
"noPermsTitle":"Недостаточно прав!",
"noPermsDescription":"Вы должны иметь права `ADMINISTRATOR` или быть в списке разрешённых ролей!",
"noPermsDelete":"Только админы могут удалить тикет!",
"chooseFromListTitle":"Неверный ID",
"chooseFromListDescription":"Выберите один из id ниже:",
"boterror":"Ошибка бота!",
"notInTicketTitle":"Вы не в тикете!",
"notInTicketDescription":"Эта команда не работает вне тикетов!",
"ticketDoesntExist":"Этого тикета больше не существует!",
"roleDoesntExist":"Этой роли больше не существует!",
"anotherOption":"Эта опция не является тикетом, а представляет собой другой тип!",
"maxAmountTitle":"Максимальное количество достигнуто!",
"maxAmountDescription":"Вы достигли максимальное количество разрешённых тикетов!\nТеперь вы не можете создать ещё один!",
"somethingWentWrong":"**Что-то пошло не так!**\nПожайлуста, попробуйте в другой раз!"
},
"commands":{
"userAddedTitle":"Добавлено {0} в этот тикет!",
"userRemovedTitle":"Удалено {0} из этого тикета!",
"renameTitle":"Изменено имя на {0}!",
"closeTitle":"Закрыл этот тикет!",
"deleteTitle":"Удаляем этот тикет...",
"reopenTitle":"Открываем заново этот тикет!",
"claimTitle":"Этот тикет теперь взят {0}",
"unclaimTitle":"Этот тикет никем не взят!",
"changeTitle":"Изменён тип тикета на {0}!",
"statsTitle":"Здесь статистика для {0}!",
"autocloseTitle":"Этот тикет будет закрыт автоматически после {0}!",
"autocloseRejectTitle":"Этот тикет больше не будет закрыт автоматически!",
"autocloseWarn":"Это касается только неактивных тикетов!",
"goToTicket":"перейти в тикет",
"ticketWarning":"embed ниже сообщения!",
"maxTicketWarning":"**Предупреждение:** _Вы можете создать только {0} тикет(а/ов) в этот раз!_"
},
"helpMenu":{
"title":"Доступные команды:",
"header1":"**Перейдите в {0}, чтобы создать тикет!**\n\n",
"header2":"**Выполните команду `/new` или `/ticket` для создания тикета!**\n\n",
"msgCmd":"Создать embed с кнопками. (только админам)",
"renameCmd":"Переименовать тикет. (без пробелов)",
"closeCmd":"Закрыть тикет.",
"deleteCmd":"Удалить тикет.",
"addCmd":"Добавить пользователя в тикет.",
"removeCmd":"Удалить пользователя из тикета.",
"reopenCmd":"Открыть заново тикет после того, как он был закрыт.",
"changeCmd":"Поменять тип тикета.",
"claimCmd":"Взять тикет.",
"unclaimCmd":"Снять тикет.",
"statsCmd":"Посмотреть статистику тикета.",
"autocloseCmd":"Установить таймер, чтобы автоматически закрыть тикет"
},
"buttons":{
"close":"Закрыть тикет",
"delete":"Удалить тикет",
"reopen":"Открыть заново тикет",
"closeWithReason":"закрыть с причиной"
},
"messages":{
"closedDescription":"Только админы теперь могут писать в этом тикете!\n\n*Нажмите на кнопку ниже, чтобы удалить или заново окрыть тикет!*",
"createdTitle":"Тикет создан!",
"createdDescription":"Ваш тикет создан, вы можете обнаружить его по пингу!",
"newTicketDmTitle":"Новый тикет!",
"closedTicketDmTitle":"Тикет закрыт!",
"deletedTicketDmTitle":"Тикет удалён!",
"closedTicketDmDescription":"Ваш тикет закрыт!",
"deletedTicketDmDescription":"Ваш тикет удалён!",
"reopenTicketDmTitle":"Тикет открыт заново!",
"reopenTicketDmDescription":"Ваш тикет открыт заново!",
"chooseCategory":"выберите категорию:",
"gettingdeleted":"Тикет будет удалён...",
"none":"отсутствует",
"reason":"причина",
"createdat":"создан",
"openedby":"открыт",
"deletedby":"удалён",
"closedby":"закрыт",
"modalreason":"Какая причина закрытия этого тикета?",
"chooseATicket": "Выберите тикет"
},
"transcripts":{
"title":"Транскрипт",
"processed":"Этот транскрипт находится в процессе обработки",
"wait":"Пожайлуста подождите!",
"estimated":"Оценочное время",
"available":"Транскрипт здесь доступен"
}
}
-176
View File
@@ -1,176 +0,0 @@
{
"examples":{
"en-GB":"english",
"en-US":"english",
"nl":"dutch",
"ro":"romanian",
"de":"german",
"cs":"czech",
"fr":"french",
"es-ES":"spanish",
"it":"italian",
"ru":"russian",
"tr": "Türkçe",
"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.",
"ru":"Список доступных команд",
"tr": "Kullanılabilir komutların listesi."
},
"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.",
"ru":"Создать embed с кнопками",
"tr": "Butonlar ile bir yerleştirme oluşturun."
},
"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.",
"ru":"Закрыть тикет",
"tr": "Bileti kapat."
},
"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.",
"ru":"Удалить тикет",
"tr": "Bileti sil."
},
"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.",
"ru":"Открыть заново тикет",
"tr": "Bileti yeniden aç."
},
"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",
"ru":"Добавить другого пользователя в тикет",
"tr": "Bilete başka bir kullanıcı ekle."
},
"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",
"ru":"Удалить пользователя из тикета",
"tr": "Kullanıcıyı bir biletten kaldır."
},
"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",
"ru":"Создать тикет",
"tr": "Bilet oluştur"
},
"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.",
"ru":"Переименовать канал тикета",
"tr": "Bilet kanalını yeniden adlandır."
},
"claim":{
"en-GB":"Claim a ticket.",
"en-US":"Claim a ticket.",
"nl":"Claim een ticket.",
"ro":" ",
"de":" ",
"cs":" ",
"fr":" ",
"es-ES":" ",
"it":" ",
"ru":"Взять тикет",
"tr":"Bilet talep et."
},
"unclaim":{
"en-GB":"Un-claim a ticket.",
"en-US":"Un-claim a ticket.",
"nl":"Ontclaim een ticket.",
"ro":" ",
"de":" ",
"cs":" ",
"fr":" ",
"es-ES":" ",
"it":" ",
"ru":"Снять тикет",
"tr":"Bileti iptal et."
},
"category":{
"en-GB":"Change ticket type.",
"en-US":"Change ticket type.",
"nl":"Verander ticket type.",
"ro":" ",
"de":" ",
"cs":" ",
"fr":" ",
"es-ES":" ",
"it":" ",
"ru":"Изменить тип тикета",
"tr":"Bilet türünü değiştir."
}
}
}
-101
View File
@@ -1,101 +0,0 @@
{
"_CREDITS":"n1kkec#5341",
"_INFO":"This file is a translation for open ticket 3.4.0",
"errors":{
"missingArgsTitle":"Napačen argument!",
"missingArgsDescription":"Argument manka",
"noPermsTitle":"Nimas dovoljenja!",
"noPermsDescription":"Potrebuješ dovoljenje `ADMINISTRATOR` ali pa biti v listi dovoljenih role!",
"noPermsDelete":"Samo admini lahko izbrišejo ticket!",
"chooseFromListTitle":"Napačen ID",
"chooseFromListDescription":"Izberi eden izmed ID-jev:",
"boterror":"NAPAKA Bota!",
"notInTicketTitle":"Nisi v ticketu!",
"notInTicketDescription": "Ta ukaz ne deluje zunaj ticket-ov!",
"ticketDoesntExist": "Ta ticket ne obstaja več!",
"roleDoesntExist": "Ta vloga ne obstaja več!",
"anotherOption": "Ta možnost ni ticket, ampak druga vrsta!",
"maxAmountTitle": "Najvišji doseženi znesek!",
"maxAmountDescription": "Dosegli ste največje dovoljeno število ticket-ov!\nTako da ne morete ustvariti nove!",
"somethingWentWrong": "**Nekaj je šlo narobe!**\nProsimo, poskusite znova drugič!"
},
"commands":{
"userAddedTitle": "Dodan {0} v ta ticket!",
"userRemovedTitle": "Odstranjeo {0} iz tega ticket-!",
"renameTitle": "Spremenjeno ime na {0}!",
"closeTitle": "Zaprl ta ticket!",
"deleteTitle": "Brisanje ticketa...",
"reopenTitle": "Ponovno odprl ta ticket!",
"claimTitle":"Ticket je claimal {0}",
"unclaimTitle":"Ticket ni več claiman!",
"changeTitle":"Changed ticket type to {0}!",
"statsTitle":"Statistike za {0}!",
"autocloseTitle":"Ticket so avtomatsko zapru po {0}!",
"autocloseRejectTitle":"Ticket se nebo avtomatsko zapru!",
"autocloseWarn":"To ima efekt samo na inactive ticketih!",
"goToTicket":"pojdi v ticket",
"ticketWarning": "Opozorilo je v spodnjem sporočilu!",
"maxTicketWarning": "**Opozorilo:** _Naenkrat lahko ustvarite le {0} ticketov!_"
},
"helpMenu":{
"title": "Razpoložljivi ukazi:",
"header1": "**Izberite {0} in ustvarite ticket!**\n\n",
"header2": "**Zaženi ukaz `/new` ali `/ticket` za ustvarjanje ticket-a!**\n\n",
"msgCmd": "Ustvari vstavek z gumbi. (samo za administratorje)",
"renameCmd": "Preimenujte ticket. (brez presledkov)",
"closeCmd": "Zapri ticket.",
"deleteCmd": "Izbriši ticket.",
"addCmd": "Dodaj uporabnika v ticket.",
"removeCmd": "Odstrani uporabnika z ticket-a.",
"reopenCmd": "Ponovno odprite ticket, ko je bila zaprta.",
"changeCmd":"Spremeni tip ticketa.",
"claimCmd":"Claimaj ticket.",
"unclaimCmd":"Unclaimaj ticket.",
"statCmds":"Statistike ticketa.",
"autocloseCmd":"Nastavi timer da avtomatsko zapre ticket"
},
"buttons":{
"close":"Zapri Ticket",
"delete":"Izbrisi Ticket",
"reopen":"Odpri Ticket",
"closeWithReason":"Zapri z razlogom"
},
"messages":{
"closedDescription": "V tem ticket-u lahko zdaj govorijo samo administratorji!\n\n*Kliknite na spodnji gumb za brisanje ali ponovno odprtje te ticket!*",
"createdTitle": "Ticket ustvarjen!",
"createdDescription": "Vaš ticket je ustvarjen, lahko jo odkrijete s pingom!",
"newTicketDmTitle": "Nov ticket!",
"closedTicketDmTitle": "Ticket zaprt!",
"deletedTicketDmTitle": "Izbrisan ticket!",
"closedTicketDmDescription": "Vaš ticket je zaprta!",
"deletedTicketDmDescription": "Vaš ticket je izbrisan!",
"reopenTicketDmTitle": "Ticket je ponovno odprt!",
"reopenTicketDmDescription": "Vaš ticket je ponovno odprt!",
"chooseCategory": "izberite kategorijo:",
"gettingdeleted": "Ticket se briše...",
"none": "ni",
"reason": "razlog",
"createdat":"ustvarjeno ob",
"openedby":"odprto od",
"deletedby": "izbrisano s",
"closedby": "zaprl",
"modalreason": "Kakšen je razlog za zaprtje tega ticket?",
"chooseATicket": "Izberi ticket"
},
"transcripts":{
"naslov": "Transkript",
"obdelano": "Ta prepis se obdeluje",
"wait": "Počakajte!",
"estimated": "Predvideni čas",
"available": "Prepis je na voljo tukaj"
}
}

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