Compare commits

...
152 Commits
Author SHA1 Message Date
Jasper 407e56a806 Open Ticket v3.5.3
Open Ticket v3.5.3
2024-02-05 21:34:56 +01:00
DJj123dj e0f42834e5 v3.5.3 push 2 2024-02-05 21:32:02 +01:00
DJj123dj d03abd9eeb v3.5.3 push 1 2024-01-27 20:32:27 +01:00
Jasper 466a4aea81 Open Ticket v3.5.2
Open Ticket v3.5.2
2024-01-10 17:12:37 +01:00
DJj123dj 9d96d11cd3 v3.5.2 2024-01-10 17:11:46 +01:00
Jasper e3b99e656e Open Ticket v3.5.1!
Open Ticket v3.5.1!
2023-12-25 19:01:13 +01:00
DJj123dj 07e2a68d06 v3.5.1 push 2 (fix button color bug) 2023-12-25 18:56:28 +01:00
DJj123dj 795ca4f981 v3.5.1 push 1 (translation update) 2023-12-23 14:19:36 +01:00
Jasper 5231129278 Open Ticket v3.5.0
Open Ticket v3.5.0
2023-12-17 14:13:30 +01:00
DJj123dj f62bc7adf9 v3.5.0 last push 2023-12-17 14:12:22 +01:00
DJj123dj 5de6b1e906 v3.5.0 translation push 2 + improved thai 2023-12-16 18:00:54 +01:00
DJj123dj 62413505d6 v3.5.0 translation push 1 + bug fix 2023-12-16 17:46:34 +01:00
DJj123dj 20b617f6eb v3.5.0 push 5 2023-12-14 21:37:29 +01:00
DJj123dj 94510bbfb0 v3.5.0 push 4 2023-12-13 21:39:18 +01:00
DJj123dj d51511fdb5 v3.5.0 push 3 2023-12-13 12:27:01 +01:00
DJj123dj 3447a37603 v3.5.0 push 2 2023-12-12 21:32:15 +01:00
DJj123dj 4b17aa640f v3.5.0 push 1 2023-11-29 19:29:27 +01:00
Jasper 3b7674f1a5 Open Ticket v3.4.4
v3.4.4
2023-11-09 20:37:10 +01:00
DJj123dj 7de9339da3 v3.4.4 2023-11-09 20:36:21 +01:00
Jasper e2e1e19bc8 Open Ticket v3.4.3
Open Ticket v3.4.3
2023-08-30 17:23:21 +02:00
DJj123dj 5f19adf561 v3.4.3 2023-08-30 17:22:26 +02:00
Jasper 1bb70745ea Open Ticket v3.4.2
Open Ticket v3.4.2
2023-08-11 11:23:50 +02:00
DJj123dj 589bbe5cd5 v3.4.2 2023-08-11 11:22:25 +02:00
Jasper 447fddea56 Open Ticket v3.4.1
Open Ticket v3.4.1
2023-06-17 12:20:40 +02:00
DJj123dj bf7a003799 Update slash.json 2023-06-17 12:18:41 +02:00
DJj123dj 6115ab1cc8 Merge branch 'dev' of https://github.com/DJj123dj/open-ticket into dev 2023-06-17 12:16:26 +02:00
DJj123dj c2307fd1ed bug fix update v3.4.1 2023-06-17 12:16:23 +02:00
Jasper 2a3850c3cc Merge pull request #71 from NoOneNook/dev
Norwegian in slash.json | Dev- branch
2023-06-07 13:01:35 +02:00
NoOneNook 688c40ce7b Update slash.json
Translated slash.json into Norwegian
2023-06-07 03:16:44 +02:00
Jasper dee2a21be9 Update reopen.js 2023-05-19 16:23:12 +02:00
Jasper d7ae040d60 Removed readme warning
Update README.md
2023-05-19 15:03:22 +02:00
Jasper 7b6202985a Update README.md 2023-05-19 15:02:43 +02:00
Jasper a2f2c601a5 Open Ticket 3.4.0!
Open Ticket 3.4.0!
2023-05-19 15:02:09 +02:00
Jasper b27016df2e Merge branch 'main' into dev 2023-05-19 15:00:47 +02:00
DJj123dj 6341f2f71b v3.4.0 last push 2023-05-19 14:55:29 +02:00
DJj123dj 56a5b9c7d0 Merge branch 'dev' of https://github.com/DJj123dj/open-ticket into dev 2023-05-17 21:43:59 +02:00
DJj123dj f608cb71ce v3.4.0 push 2 (html transcripts v2) 2023-05-17 21:43:57 +02:00
Jasper 7c7c325307 temp fix for bugs 2023-05-01 13:11:34 +02:00
Jasper 832021d72a Update russian.json
Update russian.json
2023-04-30 12:23:11 +02:00
Apexo 030554a7f5 Update russian.json 2023-04-30 13:17:08 +03:00
Jasper ada5ea0c5d temp fix for "forEach" bug
This is a temporary fix for the "Cannot read properties of undefined (reading 'forEach')" bug. This will be fixed in a better way in v3.4.0
2023-04-30 12:11:31 +02:00
DJj123dj fb6b891835 v3.4.0 push 1: fixed all currently known bugs 2023-04-29 09:15:56 +02:00
Jasper 739ad81f3f v3.3.3 MAJOR FIX!
v3.3.3 MAJOR FIX!
2023-04-22 16:53:32 +02:00
DJj123dj a6f67a9452 v3.3.3 MAJOR FIX! 2023-04-22 16:52:43 +02:00
Jasper 56a6540663 v3.3.2 extra
v3.3.2 extra
2023-04-19 18:45:55 +02:00
DJj123dj 5f8812d261 v3.3.2 push 2 2023-04-19 18:45:12 +02:00
Jasper 7a3dcf4c42 Open Ticket v3.3.2
Open Ticket v3.3.2
2023-04-19 18:43:38 +02:00
DJj123dj 7cebd4dd6a Merge branch 'dev' of https://github.com/DJj123dj/open-ticket into dev 2023-04-19 18:39:23 +02:00
DJj123dj 27912a0c37 v3.3.2 2023-04-19 18:39:21 +02:00
Jasper 67871d885a Update dev
update dev branch
2023-03-23 14:22:29 +01:00
Jasper 1bd0d013ed Update config.json 2023-03-23 14:21:39 +01:00
Jasper a074a17519 Update issue templates 2023-03-23 14:15:25 +01:00
Jasper 67af96ef5c Update SECURITY.md 2023-03-23 14:10:38 +01:00
Jasper a041f28cf7 Update CONTRIBUTING.md 2023-03-23 14:10:03 +01:00
Jasper a8c9c2ea8d Create SECURITY.md 2023-03-23 13:35:08 +01:00
Jasper 8748301b04 Open Ticket v3.3.1
Open Ticket v3.3.1
2023-03-23 12:51:58 +01:00
DJj123dj 2d7a7b5728 v3.3.1 push 4 2023-03-23 12:46:53 +01:00
DJj123dj 0807ca884c Update ticketAutoclose.js 2023-03-21 20:10:06 +01:00
DJj123dj 0ead037fa8 v3.3.1 push 3 (autoclose spam fix) 2023-03-21 19:49:12 +01:00
DJj123dj 4287c11bf1 v3.3.1 push 2 (fixed dropdown crash) 2023-03-21 17:38:15 +01:00
DJj123dj 69fdc7ccf0 v3.3.1 BUG FIXES! (+ added Slovenian) 2023-03-20 20:01:09 +01:00
Jasper 6c213306b6 Add Slovenian language
add slovenian language
2023-03-19 12:51:12 +01:00
n1kkec 4096e8196d feat(language): add slovenian language 2023-03-19 12:47:24 +01:00
Jasper 94ee890848 Open Ticket v3.3!
Open Ticket v3.3!
2023-03-19 12:34:23 +01:00
DJj123dj 4dced819a3 v3.3 push 7 (added autoclose) 2023-03-19 12:29:24 +01:00
DJj123dj 1159af9fa9 v3.3 push 6 (added ticket claiming) 2023-03-18 11:48:01 +01:00
DJj123dj 67d429c52b v3.3 push 5 2023-03-16 20:58:08 +01:00
DJj123dj f67af805c1 v3.3 push 4 (1 entire afternoon of work)
My TODO list is too big :)
2023-03-15 20:57:14 +01:00
DJj123dj 944032f690 v3.3 push 3 (lots of small changes 😄) 2023-03-13 20:22:23 +01:00
DJj123dj ee248e86bc Merge branch 'dev' of https://github.com/DJj123dj/open-ticket into dev 2023-03-12 11:22:55 +01:00
DJj123dj b171bce62b v3.3 push 2 (added Polish) 2023-03-12 11:22:53 +01:00
Jasper df0bce0189 Delete test.txt 2023-03-01 14:31:36 +01:00
Jasper 2630aa899f Create test.txt 2023-03-01 14:03:50 +01:00
DJj123dj dba370d66e v3.3 push 1 & added turkish language 2023-02-25 21:02:31 +01:00
Jasper d0bcf26b93 Open Ticket v3.2.2
new update :)
2023-02-24 21:58:40 +01:00
DJj123dj 65f82171d3 v3.2.2 push 4 2023-02-24 21:48:59 +01:00
DJj123dj 6e730f058d github files moved to new directory 2023-02-24 15:13:33 +01:00
DJj123dj 4702c633ec v3.2.2 push 2 2023-02-24 15:02:53 +01:00
DJj123dj dc14a39c4e v3.2.2 push 1 2023-02-24 14:49:36 +01:00
Jasper 05c97909d4 Merge pull request #49 from DJj123dj/translation
Translation
2023-02-13 21:18:59 +01:00
Jasper b3c4c2f6e8 Merge pull request #47 from Apexo01/main
Added russian language
2023-02-13 21:01:19 +01:00
Jasper e0e678bee0 Merge pull request #48 from DJj123dj/main
test
2023-02-13 20:59:04 +01:00
Jasper 1b01b1703f Merge branch 'dev' into main 2023-02-13 20:57:43 +01:00
Jasper 26539360c6 Merge pull request #46 from quiradon/patch-2
Update portuguese.json
2023-02-13 20:54:30 +01:00
Apexo 627c461f64 Update README.md 2023-02-13 22:30:18 +03:00
Apexo 2e40dc0468 Added russian language 2023-02-13 22:18:07 +03:00
Jasper fa57b9a93f Update checker.js 2023-02-12 15:09:27 +01:00
QuiraDon 930452155b Update portuguese.json
some fixes on what was missing.
2023-02-09 02:20:09 -03:00
DJj123dj e70f22162d Merge branch 'dev' of https://github.com/DJj123dj/open-ticket into dev 2023-02-08 14:27:40 +01:00
DJj123dj d5b0a0f3c6 /change bugfix 2023-02-08 14:27:39 +01:00
Jasper c43081e05d Merge pull request #45 from quiradon/patch-1 2023-02-08 07:09:44 +01:00
QuiraDon 8c4bf735f1 Update Portugueses Lang
I completed the translation into Portuguese that was missing a few things.
2023-02-07 23:33:26 -03:00
Jasper 3a20c4707b open ticket v3.2.1
Update dev branch
2023-02-07 17:03:22 +01:00
Jasper 9a7e563c57 Update dev branch 2023-02-07 17:02:02 +01:00
Jasper 72b4f43a25 Open Ticket v3.2.1
Bug fix update
2023-02-07 17:01:14 +01:00
DJj123dj 5fec028cc9 Merge branch 'dev' of https://github.com/DJj123dj/open-ticket into dev 2023-02-07 16:59:26 +01:00
DJj123dj 81300303e5 Update danish.json 2023-02-07 16:59:19 +01:00
Jasper 8a1ea1c856 Update README.md 2023-02-06 22:08:11 +01:00
Jasper 8a9d63bf8b Merge pull request #41 from Sank34/patch-2
French Translation New
2023-02-06 22:07:18 +01:00
DJj123dj 208b365276 Update czech.json 2023-02-06 21:49:42 +01:00
Andrei abb64a0575 French Translation New 2023-02-05 23:32:42 +02:00
DJj123dj c930140540 Update german.json 2023-02-05 22:17:19 +01:00
DJj123dj 294c4d3f2b Merge branch 'dev' of https://github.com/DJj123dj/open-ticket into dev 2023-02-05 16:22:47 +01:00
DJj123dj 28e7d48e7e v3.2.1 push 3 2023-02-05 16:22:44 +01:00
Jasper bad278e681 Merge pull request #40 from DJj123dj/readme-edit
Edited readme
2023-02-02 18:16:52 +01:00
Jasper 2e2542d064 added documentation below 2023-02-02 18:15:42 +01:00
Jasper 2c48da45ae readme-update step 1 2023-02-02 18:11:46 +01:00
Jasper e1232a559e Added translation from Sank34/patch-1
Romanian for v3.2.1
2023-01-28 12:18:17 +01:00
Andrei 3d58475461 Update to the new Version 2023-01-28 13:16:17 +02:00
DJj123dj f702b199da v3.2.1 TRANSLATION! 2023-01-28 11:51:10 +01:00
DJj123dj ea1604a805 v3.2.1 push 1 (fixed /change bugs) 2023-01-25 16:28:19 +01:00
DJj123dj f8bc3d9e12 bug fix: tickets couldn't close in some situations 2023-01-19 17:42:44 +01:00
Jasper af35f83291 Open Ticket v3.2.0
Open Ticket v3.2.0
2023-01-18 21:48:13 +01:00
DJj123dj 39fec94ead changed readme.md 2023-01-18 21:47:32 +01:00
DJj123dj 1b8468330e v3.2 last push 2023-01-18 21:44:56 +01:00
DJj123dj b698c89a89 v3.2 push 2 2023-01-17 22:25:20 +01:00
DJj123dj 7ed2d7bcc7 v3.2 push 1 NOT WORKING YET!!! 2023-01-17 17:34:51 +01:00
Jasper f2ddaa5fd4 Merge pull request #36 from DJj123dj/dev
Open Ticket v3.1.0
2022-12-31 11:47:35 +01:00
DJj123dj fc50a8e83f v3.1 last push 2022-12-31 11:42:33 +01:00
DJj123dj 5bece3357d v3.1.0 push 3 2022-12-27 17:41:54 +01:00
Jasper 97d1489558 Delete .DS_Store 2022-12-27 17:37:23 +01:00
Jasper a211cef1f6 Delete database.json 2022-12-27 17:36:52 +01:00
DJj123dj ae002e168b v3.1.0 push 2 2022-12-27 17:35:01 +01:00
DJj123dj 86a5a1a2ca v3.1.0 push 1 2022-12-27 11:38:32 +01:00
Jasper 23ebc14b8b Merge pull request #35 from DJj123dj/dev
Open Ticket v3.0.1
2022-12-10 13:38:08 +01:00
DJj123dj 3a5768a1b1 added new README image 2022-12-10 13:37:02 +01:00
DJj123dj 33c3803ca8 openticket v3.0.1 2022-12-10 12:59:44 +01:00
DJj123dj f3613fb674 update to discord.js 14.7 2022-12-05 19:32:11 +01:00
DJj123dj f1dc8cbcf5 changed some stuff 2022-11-24 21:51:13 +01:00
Jasper a365c4b69f Update issue templates 2022-10-10 20:01:10 +02:00
Jasper 687372481a Update issue templates 2022-10-10 19:54:28 +02:00
Jasper 1bc8bde922 Update issue templates 2022-10-10 19:49:16 +02:00
Jasper 4b8074c520 Merge pull request #29 from DJj123dj/dev
Open ticket 3.0!
2022-10-07 16:36:20 +02:00
Jasper 1d5830975f Merge branch 'main' into dev 2022-10-07 16:35:58 +02:00
DJj123dj 95bc1f4fbf 3.0 update! 2022-10-07 16:32:29 +02:00
DJj123dj bfc02611c7 Create slash.json 2022-10-05 20:38:06 +02:00
DJj123dj e4c1e2559e 3.0 public beta 4 2022-10-05 20:25:35 +02:00
DJj123dj 69b669956e 3.0 public beta 3 2022-10-01 12:08:42 +02:00
DJj123dj 893a7c5b1f 3.0 public beta 2 2022-10-01 11:14:37 +02:00
DJj123dj ed9c98e2f0 3.0 update first beta 2022-09-24 08:56:34 +02:00
Jasper 62d950b1a6 Update checker.js 2022-09-14 20:49:20 +02:00
DJj123dj 69de612d1e added close with reason 2022-09-03 13:20:00 +02:00
Jasper 5494e112c0 Create CONTRIBUTING.md 2022-08-30 15:55:08 +02:00
Jasper cd2c08303e Merge pull request #28 from DJj123dj/add-code-of-conduct
Create CODE_OF_CONDUCT.md
2022-08-30 15:50:58 +02:00
Jasper a8619e448a Create CODE_OF_CONDUCT.md 2022-08-30 15:49:57 +02:00
DJj123dj c990257c02 v2.5.1 2022-08-16 13:00:17 +02:00
Jasper e7f05b4ed5 Merge pull request #26 from DJj123dj/dev
Update 2.5!
2022-08-15 15:03:37 +02:00
DJj123dj 697594b311 added french & czech translation 2022-08-15 14:55:34 +02:00
DJj123dj 6823b96114 fixed the last bugs & added czech translation 2022-08-14 22:13:51 +02:00
DJj123dj 0845390569 v2.5 (added translation for 2 new languages) 2022-08-14 21:23:04 +02:00
DJj123dj 568b2c9bee v2.5.0 push 2 2022-08-12 11:20:42 +02:00
DJj123dj 034247ea99 v2.5.0 first push 2022-08-10 19:35:10 +02:00
108 changed files with 9204 additions and 2650 deletions
+128
View File
@@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
support@dj-dj.be.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
+43
View File
@@ -0,0 +1,43 @@
# Contributing
## Translation
### 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!
### Step 2: translating
**RULES:**
- Always upload or create a pull request to the [__`dev` branch!__](https://github.com/DJj123dj/open-ticket/tree/dev)
- 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 2 are optional & will be added by us if you don't do it!
1. add `yourlanguage.json` to the `/language/` directory
2. add your username to the `_CREDITS` part of `yourlanguage.json`!
3. add your discord username in the translator table in `README.md`
### Step 3: waiting
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!
## Writing plugins
We are going to create an official repository for plugins soon!
But don't worry! You can already write some plugins!
**RULES:**
- 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 the original unedited version of Open Ticket!
## Other versions of contributing
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 further!
<br>
CONTRIBUTING GUIDELINES - Last updated: 23/3/2023<br>
© DJdj Development<br><br>
Website: https://www.dj-dj.be <br>
Discord: https://discord.dj-dj.be <br>
Email: support@dj-dj.be <br>
Open Ticket website: https://openticket.dj-dj.be
+37
View File
@@ -0,0 +1,37 @@
---
name: Bug report
about: Report bugs to help us improve open ticket!
title: "[BUG] your bug"
labels: bug
assignees: DJj123dj
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Device:**
- Device: [e.g. Macbook pro, raspberry pi, HP Probook]
- OS: [e.g. MacOS, Ubuntu, Windows,...]
- Node.js version:
- Open Ticket Version:
**Files:**
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.
+29
View File
@@ -0,0 +1,29 @@
---
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!
+41
View File
@@ -0,0 +1,41 @@
# Security Policy
## Supported Versions
Below, you can find a list with the status of every open ticket version. This list will change every update!
- ✅ Supported **(bugs, errors, discord support, documentation, html transcripts)**
- 🟧 Deprecated / Partially Supported **(discord support, documentation, html transcripts)**
- ❌ Fully Deprecated / Not Supported **(sometimes documentation)**
| Version | Supported | Until |
|-----------|-----------|-----------------------------|
| 3.5.3 | ✅ | |
| 3.5.2 | ✅ | April 2024 |
| 3.5.1 | 🟧 | Next Update |
| 3.5.0 | 🟧 | Next Update |
| < 3.5.0 | ❌ | |
## Reporting a Vulnerability
You can report Vulnerabilities, Errors & Bugs using one of the methods below:
- Create an issue on github
- Create a ticket in our [discord server](https://discord.dj-dj.be)
- Report the bug in DM on discord (djj123dj)
- Email [support@dj-dj.be](mailto:support@dj-dj.be)
While reporting your problem, please be clear about what the problem is.
We would like to know the issue in as much detail as possible.
If possible, try to provide screenshots!
The `openticketdebug.txt` file would also be handy to upload!<br>
**Always specify the version of open ticket that you are working with and if you have modified it or not!**
## Contributing
Visit [Contributing.md](/.github/CONTRIBUTING.md) for rules about translating & adding features!
<br>
SECURITY POLICY - Last updated: 14/12/2023<br>
© DJdj Development<br><br>
Website: https://www.dj-dj.be <br>
Discord: https://discord.dj-dj.be <br>
Email: support@dj-dj.be <br>
Open Ticket website: https://openticket.dj-dj.be
+17 -7
View File
@@ -1,13 +1,23 @@
node_modules/ node_modules/
package-lock.json package-lock.json
devConfig.json devconfig.json
devConfig1.json devconfig1.json
devConfig2.json devconfig2.json
devConfig3.json devconfig3.json
devConfig4.json devconfig4.json
devConfig5.json devconfig5.json
.DS_Store .DS_Store
openticketdebug.txt openticketdebug.txt
developerChangelog.md developerChangelog.md
storage/dynamicDB/ storage/dynamicDB/
storage/.DS_Store storage/slashcmdEnabled.txt
storage/database.json
storage/tsdatabase.json
storage/stats.json
storage/.DS_Store
.vscode/
livestatus.json
test.js
devtsconfig.json
plugins/*
!plugins/example.plugin.js
+73 -75
View File
@@ -1,87 +1,85 @@
## We need translators! # Coming Soon: OPEN TICKET v4.0 🎉
If you know a language that isn't already in open ticket and you can write json, Open Ticket v4 will be the first fully rewritten version of Open Ticket!
then is this the job for you! There will be massive improvements for more stability & features! But the best part of all is that the API will be 50x more advanced than the current API! This way, you can write every plugin you ever imagined!
<hr>
make a ticket in our server to start! <img src="https://apis.dj-dj.be/cdn/openticket/logo.png" alt="Open Ticket" width="600px">
*if you translate, you will come in the credits* [![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.5.3-brightgreen.svg?style=flat-square)](https://github.com/DJj123dj/open-ticket/releases/tag/v3.5.3) [![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)
# open-ticket ### Open Ticket
[![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-2.4.0%20stable-brightgreen.svg?style=flat-square)](https://github.com/DJj123dj/open-ticket/releases/tag/v2.4.0) [![npm](https://img.shields.io/badge/npm-external%20libraries%20needed-CB3837.svg?style=flat-square&logo=npm)](#packages) [![license](https://img.shields.io/badge/license-GPL%203.0-important.svg?style=flat-square)](https://github.com/DJj123dj/open-ticket/blob/main/LICENSE) Open Ticket is the most customisable discord ticket bot that you will ever find! There are more than 150 options to customise in the config! This includes html transcripts, unlimited amount of tickets, custom embeds & more! Did you know that even the html transcripts are highly customisable? Don't wait and check it out! If you're having trouble setting the bot up, feel free to join our support server and we will help you further!
This is an open-source discord ticket bot, you can configure it and it comes with cool features like transcripts & custom options! Take a look at all the features and discover the possibilities!
### [Visit the Documentation!](https://docs.openticket.dj-dj.be/quick-start)
<img src="logo.png" alt="Open Ticket logo" style="height: 200px; width:200px;"/> ## Features
- **🎉 advanced html transcripts!**
- 🔒 close, ❌ delete & ✅ re-open tickets
- 🇬🇧 translation in 19 different languages
- 📄 very advanced customisation
- 🆗 buttons or 🔽 dropdowns!
- 🆒 plugins
- ∞ unlimited tickets & unlimited messages
- ➕➖ add/remove users from a ticket
- 📊 ticket, user & global staticstics
- /slash & text commands
[![wiki](https://img.shields.io/badge/documentation-click%20here-blue.svg?style=flat-square)](https://www.github.com/DJj123dj/open-ticket/wiki) <details>
<summary><b>But wait, there are even more features! Click here to discover!</b></summary>
- fully customisable embeds & buttons
- close tickets with reason
- reaction roles (or verification system)
- discord interaction buttons
- discord.js v14
</details>
### Thanks to these people: ## preview
- DJ-Lite: for doing the administration <img src="https://apis.dj-dj.be/cdn/openticket/message_buttons.png" alt="Message with buttons" width="350px">
- Sanke: for translation & new ideas <img src="https://apis.dj-dj.be/cdn/openticket/message_dropdown.png" alt="Message with dropdown" width="350px">
- Everyone that reported a bug <br>
#### And our translators! <img src="https://apis.dj-dj.be/cdn/openticket/firstmsg.png" alt="Ticket start message" width="350px">
- ExothDE: for translation <img src="https://apis.dj-dj.be/cdn/openticket/command_close.png" alt="Ticket start message" width="350px">
- 1x1: for translation
- R0JO: for translation
- t0miiis for translation
## features
- discord interaction buttons
- slash & text commands
- close, delete & re-open tickets
- translation in 8 different languages
- dynamic database system
- transcripts
- add/remove users from a ticket
- custom colors & name for embeds
- customise your ticket
- create url buttons for websites
- create reaction roles
- build with discord.js v14
- configure everything per ticket
- remove credits if you want :(
- unlimited tickets spread over multiple messages
*comming soon:* ## credits
- dashboard ### Developer Team
- view transcripts in dashboard |Role |User (discord name)|
- share transcripts |-----------------|-------------------|
- close with reason |Lead Developer |djj123dj |
- more translation |Developer |sankedev |
|Support Team |lover_catss |
|Designer |vuur_draak |
## installation ### Translators
**You need `node.js 16` to run this project!** |Language |Maintainer (discord name) |Status |
|-------------------|--------------------------|--------------------------------|
|English |djj123dj |🟢 Up To Date |
|Dutch |djj123dj |🟢 Up To Date |
|French |sankedev & tostam |🟢 Up To Date |
|Romanian |sankedev |🟢 Up To Date |
|Spanish |redactado & josuens |🟢 Up To Date |
|German |david.3 |🟢 Up To Date |
|Italian |maurizio26 |🟢 Up To Date |
|Czech |spyeye_ |🟢 Up To Date |
|Arabic |deqressing |🟢 Up To Date |
|Danish |.the_gamer |🟢 Up To Date |
|Portuguese |quiradon |🔴 Outdated |
|Russian |apexo & ander |🟢 Up To Date |
|Ukrainian |ander |🟢 Up To Date |
|Turkish |Hydra#0009 |🔴 Outdated |
|Polish |mkevas |🟢 Up To Date |
|Slovenian |n1kkec |🔴 Outdated |
|Thai |modshd |🟢 Up To Date |
|Norwegian |noonenook |🟢 Up To Date |
|Greek |stefanos__. |🔴 Outdated |
|Indonesian |erxg |🟢 Up To Date |
### packages ## links
- chalk => version `latest` current version: _v3.5.3_
- discord.js => version `latest` </br>changelog: [click here](https://otgithub.dj-dj.be/releases)
- express => version `latest` </br>documentation: [click here](https://docs.openticket.dj-dj.be/quick-start)
- node-localstorage => version `latest`
- axios => version `latest`
You can install all of them by running `npm install` © 2023 - DJdj Development | [website](https://www.dj-dj.be) | [discord](https://discord.dj-dj.be) | [terms of service](https://www.dj-dj.be/terms)
## running
you can run `node index.js` but i would recommend you to use `npm start`
if there are any errors, you can open an **issue on github** or **contact me in our discord server**.
### config
Our config documentation is moved to another file:
[click here to view](https://www.github.com/DJj123dj/open-ticket/wiki/config-v2.4.0)
### intents & permissions
In the discord developer portal in the "bot" panel you will find 3 switches under the title "Gateaway Intents". The following switches should always be turned on
- `SERVER MEMBERS INTENT`
- `MESSAGE CONTENT INTENT`
To work the best, the bot needs `ADMINISTRATOR` permissions.
You can also configure your own permissions
## information
_v2.4.0 stable_
changelog: [click here](https://www.github.com/DJj123dj/open-ticket/wiki/Changelog)
© 2022 - DJdj Development | [website](https://www.dj-dj.be) | [discord](https://discord.dj-dj.be) | [terms of service](https://www.dj-dj.be/terms)
+34 -38
View File
@@ -7,72 +7,68 @@ const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker") const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events") const APIEvents = require("../core/api/modules/events")
const DISABLE = require("../core/api/api.json").disable
module.exports = () => { module.exports = () => {
client.on("messageCreate",msg => { 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 if (!msg.content.startsWith(config.prefix+"add")) return
var user = msg.mentions.users.first() 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 (!user) return msg.channel.send({embeds:[bot.errorLog.invalidArgsMessage(l.errors.missingArgsDescription+" `<user>`:\n`"+config.prefix+"add <user>`")]})
if (!msg.guild) return if (!msg.guild) return
if (!permsChecker.command(msg.author.id,msg.guild.id)){
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 (!permsChecker.ticket(msg.author.id,msg.guild.id,ticketId)){
permsChecker.sendUserNoPerms(msg.author) permsChecker.sendUserNoPerms(msg.author)
return return
} }
msg.channel.messages.fetchPinned().then(msglist => { msg.channel.permissionOverwrites.create(user.id, { ViewChannel:true, AddReactions:true,AttachFiles:true, EmbedLinks:true, SendMessages:true})
var firstmsg = msglist.last() msg.channel.send({embeds:[bot.embeds.commands.addEmbed(user,msg.author)]})
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]}) var loguser = msg.mentions.users.first()
log("command","someone used the 'add' command",[{key:"user",value:msg.author.username}])
log("system","user added to ticket",[{key:"user",value:msg.author.username},{key:"ticket",value:msg.channel.name},{key:"added_user",value:loguser.username}])
msg.channel.permissionOverwrites.create(user.id, { VIEW_CHANNEL:true, ADD_REACTIONS:true,ATTACH_FILES:true, EMBED_LINKS:true, SEND_MESSAGES:true}) const ticketData = require("../core/utils/configParser").getTicketById(ticketId,true)
msg.channel.send({embeds:[bot.errorLog.success(l.commands.userAddedTitle,l.commands.userAddedDescription.replace("{0}",user.tag))]}) APIEvents.onTicketAdd(msg.author,loguser,msg.channel,msg.guild,new Date(),{status:"open",name:msg.channel.name,ticketOptions:ticketData})
var loguser = msg.mentions.users.first() APIEvents.onCommand("add",permsChecker.ticket(msg.author.id,msg.guild.id,ticketId),msg.author,msg.channel,msg.guild,new Date())
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 ticketId = firstmsg.embeds[0].footer.text.split("Ticket Type: ")[1]
const ticketData = require("../core/getoptions").getOptionsById("newT"+ticketId)
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())
})
}) })
client.on("interactionCreate",(interaction) => { if (!DISABLE.commands.slash.add) client.on("interactionCreate",async (interaction) => {
if (!interaction.isChatInputCommand()) return if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "add") return if (interaction.commandName != "add") return
const user = interaction.options.getUser("user") const user = interaction.options.getUser("user")
if (!interaction.guild) return if (!interaction.guild) return
if (!permsChecker.command(interaction.user.id,interaction.guild.id)){
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
if (!permsChecker.ticket(interaction.user.id,interaction.guild.id,ticketId)){
permsChecker.sendUserNoPerms(interaction.user) permsChecker.sendUserNoPerms(interaction.user)
return return
} }
interaction.deferReply() await interaction.deferReply()
interaction.channel.messages.fetchPinned().then(msglist => { interaction.channel.permissionOverwrites.create(user.id, { ViewChannel:true, AddReactions:true,AttachFiles:true, EmbedLinks:true, SendMessages:true})
var firstmsg = msglist.last() interaction.editReply({embeds:[bot.embeds.commands.addEmbed(user,interaction.user)]})
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]}) var loguser = user
log("command","someone used the 'add' command",[{key:"user",value:interaction.user.username}])
interaction.channel.permissionOverwrites.create(user.id, { VIEW_CHANNEL:true, ADD_REACTIONS:true,ATTACH_FILES:true, EMBED_LINKS:true, SEND_MESSAGES:true}) log("system","user added to ticket",[{key:"user",value:interaction.user.username},{key:"ticket",value:interaction.channel.name},{key:"added_user",value:loguser.username}])
interaction.reply({embeds:[bot.errorLog.success(l.commands.userAddedTitle,l.commands.userAddedDescription.replace("{0}",user.tag))]})
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 ticketId = firstmsg.embeds[0].footer.text.split("Ticket Type: ")[1]
const ticketData = require("../core/getoptions").getOptionsById("newT"+ticketId)
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())
})
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.ticket(interaction.user.id,interaction.guild.id,ticketId),interaction.user,interaction.channel,interaction.guild,new Date())
}) })
} }
+134
View File
@@ -0,0 +1,134 @@
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.channel.isTextBased()) return
if (!msg.guild) 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 (!permsChecker.ticket(msg.author.id,msg.guild.id,ticketId)){
permsChecker.sendUserNoPerms(msg.author)
return
}
const list = []
config.options.forEach((o) => {
if (o.type == "ticket") 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,true)
if (!newTicket) return msg.channel.send({embeds:[bot.errorLog.invalidIdChooseFromList(list,l.errors.missingArgsDescription+" `<type>`:\n`"+config.prefix+"change <type>`")]})
/**@type {discord.PermissionOverwriteManager} */
const prePermsManager = msg.channel.permissionOverwrites
const prePerms = prePermsManager.cache
/**@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)
}
prePermsManager.set(prePerms)
msg.channel.setName(newTicket.channelprefix+name).catch(() => {
msg.channel.send({embeds:[bot.errorLog.failedRenameChannel]})
})
hiddendata.find((value,index) => {
if (value.key == "type"){
hiddendata[index] = {key:"type",value:newtype}
}
})
msg.channel.send({embeds:[bot.embeds.commands.changeEmbed(msg.author,newtype)]})
log("command","someone used the 'change' command",[{key:"user",value:msg.author.username}])
log("system","ticket type changed",[{key:"user",value:msg.author.username},{key:"ticket",value:name},{key:"newtype",value:newtype}])
APIEvents.onCommand("change",permsChecker.ticket(msg.author.id,msg.guild.id,ticketId),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.channel.isTextBased()) return
if (!interaction.guild) return
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
if (!permsChecker.ticket(interaction.user.id,interaction.guild.id,ticketId)){
permsChecker.sendUserNoPerms(interaction.user)
return
}
await interaction.deferReply()
const list = []
config.options.forEach((o) => {
if (o.type == "ticket") 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)
}
prePermsManager.set(prePerms)
interaction.channel.setName(newTicket.channelprefix+name).catch(() => {
interaction.channel.send({embeds:[bot.errorLog.failedRenameChannel]})
})
hiddendata.find((value,index) => {
if (value.key == "type"){
hiddendata[index] = {key:"type",value:newtype}
}
})
interaction.editReply({embeds:[bot.embeds.commands.changeEmbed(interaction.user,newtype)]})
log("command","someone used the 'change' command",[{key:"user",value:interaction.user.username}])
log("system","ticket type changed",[{key:"user",value:interaction.user.username},{key:"ticket",value:name},{key:"newtype",value:newtype}])
APIEvents.onCommand("change",permsChecker.ticket(interaction.user.id,interaction.guild.id,ticketId),interaction.user,interaction.channel,interaction.guild,new Date())
})
}
+107
View File
@@ -0,0 +1,107 @@
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", async 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
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 (!permsChecker.ticket(msg.author.id,msg.guild.id,ticketId)){
permsChecker.sendUserNoPerms(msg.author)
return
}
hiddendata.push({key:"claimedby",value:claimingUser.id})
bot.hiddenData.writeHiddenData(msg.channel.id,hiddendata)
storage.set("claimData",msg.channel.id,claimingUser.id)
await msg.channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const newEmbed = new embed(firstmsg.embeds[0].data)
.setFooter({text:"claimed by: "+msg.author.username,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.username}])
log("system","user claimed to ticket",[{key:"user",value:msg.author.username},{key:"ticket",value:msg.channel.name},{key:"claimed_user",value:claimingUser.username}])
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.ticket(msg.author.id,msg.guild.id,ticketId),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
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
if (!permsChecker.ticket(interaction.user.id,interaction.guild.id,ticketId)){
permsChecker.sendUserNoPerms(interaction.user)
return interaction.reply({content:":x: "+l.errors.noPermsTitle,ephemeral:true})
}
await interaction.deferReply()
hiddendata.push({key:"claimedby",value:user.id})
bot.hiddenData.writeHiddenData(interaction.channel.id,hiddendata)
storage.set("claimData",interaction.channel.id,user.id)
await 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.username,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.username}])
log("system","user claimed to ticket",[{key:"user",value:interaction.user.username},{key:"ticket",value:interaction.channel.name},{key:"claimed_user",value:user.username}])
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.ticket(interaction.user.id,interaction.guild.id,ticketId),interaction.user,interaction.channel,interaction.guild,new Date())
})
}
+56 -36
View File
@@ -7,61 +7,81 @@ const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker") const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events") const APIEvents = require("../core/api/modules/events")
const DISABLE = require("../core/api/api.json").disable
module.exports = () => { module.exports = () => {
client.on("messageCreate",msg => { 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 if (!msg.content.startsWith(config.prefix+"close")) return
const args = msg.content.substring((config.prefix+"close").length).split(" ")
args.shift()
/**@type {String|false} */
var tempreason = args.join(" ")
if (!tempreason || tempreason == " " || tempreason == " "){
tempreason = false
}
const reason = tempreason
msg.channel.messages.fetchPinned().then(msglist => { const hiddendata = bot.hiddenData.readHiddenData(msg.channel.id)
var firstmsg = msglist.last() if (hiddendata.length < 1) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]}) 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 closebutton = new discord.ActionRowBuilder()
.addComponents([
new discord.ButtonBuilder()
.setCustomId("closeTicketTrue1")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setEmoji("🔒")
])
msg.channel.send({embeds:[bot.errorLog.success(l.commands.closeTitle,l.commands.closeDescription)],components:[closebutton]}) const descriptionReason = reason ? "**"+l.messages.reason+":** "+reason : false
msg.channel.send({embeds:[bot.embeds.commands.closeEmbed(msg.author,descriptionReason)],components:[bot.buttons.close.closeCommandRow]})
log("command","someone used the 'close' command",[{key:"user",value:msg.author.tag}]) var name = msg.channel.name
APIEvents.onCommand("close",true,msg.author,msg.channel,msg.guild,new Date()) 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.username}])
APIEvents.onCommand("close",true,msg.author,msg.channel,msg.guild,new Date())
}) })
client.on("interactionCreate",(interaction) => { if (!DISABLE.commands.slash.close) client.on("interactionCreate",async(interaction) => {
if (!interaction.isChatInputCommand()) return if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "close") return if (interaction.commandName != "close") return
interaction.deferReply() //interaction.deferReply()
interaction.channel.messages.fetchPinned().then(msglist => { const reason = interaction.options.getString("reason") ? interaction.options.getString("reason") : false
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const closebutton = new discord.ActionRowBuilder()
.addComponents([
new discord.ButtonBuilder()
.setCustomId("closeTicketTrue1")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setEmoji("🔒")
])
interaction.reply({embeds:[bot.errorLog.success(l.commands.closeTitle,l.commands.closeDescription)],components:[closebutton]}) const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
log("command","someone used the 'close' command",[{key:"user",value:interaction.user.tag}]) if (hiddendata.find(h => h.key == "pendingdelete")) return interaction.reply({embeds:[bot.errorLog.warning("Warning!","You can't close a ticket while it's being deleted!")]})
APIEvents.onCommand("close",true,interaction.user,interaction.channel,interaction.guild,new Date())
await interaction.deferReply()
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.username}])
APIEvents.onCommand("close",true,interaction.user,interaction.channel,interaction.guild,new Date())
}) })
} }
+45 -42
View File
@@ -7,71 +7,74 @@ const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker") const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events") const APIEvents = require("../core/api/modules/events")
const DISABLE = require("../core/api/api.json").disable
module.exports = () => { module.exports = () => {
client.on("messageCreate",msg => { 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.content.startsWith(config.prefix+"delete")) return
if (!msg.guild) return if (!msg.guild) return
if (!permsChecker.command(msg.author.id,msg.guild.id)){
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 (!permsChecker.ticket(msg.author.id,msg.guild.id,ticketId)){
permsChecker.sendUserNoPerms(msg.author) permsChecker.sendUserNoPerms(msg.author)
return return
} }
msg.channel.messages.fetchPinned().then(msglist => { msg.channel.send({embeds:[bot.embeds.commands.deleteEmbed(msg.author)]})
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]}) var name = msg.channel.name
var prefix = ""
const closebutton = new discord.ActionRowBuilder() const tickets = config.options
.addComponents([ tickets.forEach((ticket) => {
new discord.ButtonBuilder() if (name.startsWith(ticket.channelprefix)){
.setCustomId("deleteTicketTrue") prefix = ticket.channelprefix
.setDisabled(false) }
.setStyle(discord.ButtonStyle.Secondary)
.setEmoji("❌")
])
msg.channel.send({embeds:[bot.errorLog.success(l.commands.deleteTitle,l.commands.deleteDescription)],components:[closebutton]})
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())
}) })
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.username}])
APIEvents.onCommand("delete",permsChecker.ticket(msg.author.id,msg.guild.id,ticketId),msg.author,msg.channel,msg.guild,new Date())
}) })
client.on("interactionCreate",(interaction) => { if (!DISABLE.commands.slash.delete) client.on("interactionCreate",async (interaction) => {
if (!interaction.isChatInputCommand()) return if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "delete") return if (interaction.commandName != "delete") return
interaction.deferReply()
if (!interaction.guild) return if (!interaction.guild) return
if (!permsChecker.command(interaction.user.id,interaction.guild.id)){
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
if (!permsChecker.ticket(interaction.user.id,interaction.guild.id,ticketId)){
permsChecker.sendUserNoPerms(interaction.user) permsChecker.sendUserNoPerms(interaction.user)
return return interaction.reply({embeds:[bot.errorLog.noPermsDelete(interaction.user)]})
} }
interaction.channel.messages.fetchPinned().then(msglist => { await interaction.deferReply()
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]}) interaction.editReply({embeds:[bot.embeds.commands.deleteEmbed(interaction.user)]})
const closebutton = new discord.ActionRowBuilder()
.addComponents([
new discord.ButtonBuilder()
.setCustomId("deleteTicketTrue")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setEmoji("❌")
])
interaction.reply({embeds:[bot.errorLog.success(l.commands.deleteTitle,l.commands.deleteDescription)],components:[closebutton]}) var name = interaction.channel.name
var prefix = ""
log("command","someone used the 'close' command",[{key:"user",value:interaction.user.tag}]) const tickets = config.options
APIEvents.onCommand("delete",permsChecker.command(interaction.user.id,interaction.guild.id),interaction.user,interaction.channel,interaction.guild,new Date()) 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.username}])
APIEvents.onCommand("delete",permsChecker.ticket(interaction.user.id,interaction.guild.id,ticketId),interaction.user,interaction.channel,interaction.guild,new Date())
}) })
} }
+26 -17
View File
@@ -6,44 +6,53 @@ const log = bot.errorLog.log
const l = bot.language const l = bot.language
const APIEvents = require("../core/api/modules/events") const APIEvents = require("../core/api/modules/events")
const DISABLE = require("../core/api/api.json").disable
module.exports = () => { 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() const helpEmbed = new discord.EmbedBuilder()
.setColor(config.main_color) .setColor(config.color)
.setTitle(l.helpMenu.title) .setTitle("❔ "+l.helpMenu.title)
const prefix = config.prefix const header = l.helpMenu.header2
const header = config.system.ticket_channel ? l.helpMenu.header1.replace("{0}","<#"+config.system.ticket_channel+">") : l.helpMenu.header2 helpEmbed.setDescription(header+"`"+prefix+msgName+" <id>` ➜ _"+l.helpMenu.msgCmd+"_\n\n`"+prefix+"rename <name>` ➜ _"+l.helpMenu.renameCmd+"_\n`"+prefix+"close [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.setDescription(header+"`"+prefix+"msg <id>` ➜ _"+l.helpMenu.msgCmd+"_\n\n`"+prefix+"rename <name>` ➜ _"+l.helpMenu.renameCmd+"_\n`"+prefix+"close` ➜ _"+l.helpMenu.closeCmd+"_\n`"+prefix+"delete` ➜ _"+l.helpMenu.deleteCmd+"_\n`"+prefix+"reopen` ➜ _"+l.helpMenu.reopenCmd+"_\n\n`"+prefix+"add <user>` ➜ _"+l.helpMenu.addCmd+"_\n`"+prefix+"remove <user>` ➜ _"+l.helpMenu.removeCmd+"_`") helpEmbed.addFields([
{name:"Autoclose",value:l.helpMenu.autocloseCmd+"\n`"+prefix+"autoclose enable <inactive time>`\n`"+prefix+"autoclose disable`"},
{name:"Stats",value:"Get statistics from the bot"+"\n`"+prefix+"stats global`\n`"+prefix+"stats ticket`\n`"+prefix+"stats user [user]`"}
])
if (config.credits) helpEmbed.setFooter({text:"Open-Ticket by DJdj Development | view on github for source code",iconURL:"https://raw.githubusercontent.com/DJj123dj/open-ticket/main/logo.png"}) var otherprefix = prefix.endsWith(" ") ? prefix.substring(0,prefix.length-1) : prefix
if (!DISABLE.commands.text.help) client.on("messageCreate",msg => {
client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix)) return if (!msg.content.startsWith(config.prefix)) return
var args = msg.content.split(config.prefix) var args = msg.content.split(config.prefix)
if (!args[1]){ if (msg.content == config.prefix || msg.content == config.prefix+" " || msg.content == otherprefix){
msg.channel.send({embeds:[helpEmbed]}) msg.channel.send({embeds:[helpEmbed]})
log("command","someone used the 'help' command",[{key:"user",value:msg.author.tag}]) log("command","someone used the 'help' command",[{key:"user",value:msg.author.username}])
APIEvents.onCommand("help",true,msg.author,msg.channel,msg.guild,new Date()) APIEvents.onCommand("help",true,msg.author,msg.channel,msg.guild,new Date())
return return
} }
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")){ 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") && !args[1].startsWith("change") && !args[1].startsWith("claim") && !args[1].startsWith("unclaim") && !args[1].startsWith("stats")){
msg.channel.send({embeds:[helpEmbed]}) msg.channel.send({embeds:[helpEmbed]})
log("command","someone used the 'help' command",[{key:"user",value:msg.author.tag}]) log("command","someone used the 'help' command",[{key:"user",value:msg.author.username}])
APIEvents.onCommand("help",true,msg.author,msg.channel,msg.guild,new Date()) APIEvents.onCommand("help",true,msg.author,msg.channel,msg.guild,new Date())
}
} }
}) })
client.on("interactionCreate",(interaction) => { if (!DISABLE.commands.slash.help) client.on("interactionCreate",(interaction) => {
if (!interaction.isChatInputCommand()) return if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "help") return if (interaction.commandName != "help") return
interaction.reply({embeds:[helpEmbed]}) interaction.reply({embeds:[helpEmbed]})
log("command","someone used the 'help' command",[{key:"user",value:interaction.user.tag}]) log("command","someone used the 'help' command",[{key:"user",value:interaction.user.username}])
APIEvents.onCommand("help",true,interaction.user,interaction.channel,interaction.guild,new Date()) APIEvents.onCommand("help",true,interaction.user,interaction.channel,interaction.guild,new Date())
}) })
} }
+38 -44
View File
@@ -7,74 +7,68 @@ const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker") const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events") const APIEvents = require("../core/api/modules/events")
const DISABLE = require("../core/api/api.json").disable
module.exports = () => { module.exports = () => {
client.on("messageCreate",msg => { 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 if (!msg.content.startsWith(config.prefix+"remove")) return
var user = msg.mentions.users.first() 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 (!user) return msg.channel.send({embeds:[bot.errorLog.invalidArgsMessage(l.errors.missingArgsDescription+" `<user>`:\n`"+config.prefix+"remove <user>`")]})
if (!msg.guild) return if (!msg.guild) return
if (!permsChecker.command(msg.author.id,msg.guild.id)){
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 (!permsChecker.ticket(msg.author.id,msg.guild.id,ticketId)){
permsChecker.sendUserNoPerms(msg.author) permsChecker.sendUserNoPerms(msg.author)
return return
} }
interaction.deferReply() msg.channel.permissionOverwrites.delete(user.id)
msg.channel.send({embeds:[bot.embeds.commands.removeEmbed(user,msg.author)]})
msg.channel.messages.fetchPinned().then(msglist => { var loguser = msg.mentions.users.first()
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
msg.channel.permissionOverwrites.delete(user.id)
msg.channel.send({embeds:[bot.errorLog.success(l.commands.userRemovedTitle,l.commands.userRemovedDescription.replace("{0}",user.tag))]})
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 ticketId = firstmsg.embeds[0].footer.text.split("Ticket Type: ")[1]
const ticketData = require("../core/getoptions").getOptionsById("newT"+ticketId)
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())
})
log("command","someone used the 'remove' command",[{key:"user",value:msg.author.username}])
log("system","user removed from ticket",[{key:"user",value:msg.author.username},{key:"ticket",value:msg.channel.name},{key:"removed_user",value:loguser.username}])
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.ticket(msg.author.id,msg.guild.id,ticketId),msg.author,msg.channel,msg.guild,new Date())
}) })
client.on("interactionCreate",(interaction) => { if (!DISABLE.commands.slash.remove) client.on("interactionCreate",async (interaction) => {
if (!interaction.isChatInputCommand()) return if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "remove") return if (interaction.commandName != "remove") return
const user = interaction.options.getUser("user") const user = interaction.options.getUser("user")
if (!interaction.guild) return if (!interaction.guild) return
if (!permsChecker.command(interaction.user.id,interaction.guild.id)){
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
if (!permsChecker.ticket(interaction.user.id,interaction.guild.id,ticketId)){
permsChecker.sendUserNoPerms(interaction.user) permsChecker.sendUserNoPerms(interaction.user)
return return
} }
await interaction.deferReply()
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.username}])
log("system","user removed from ticket",[{key:"user",value:interaction.user.username},{key:"ticket",value:interaction.channel.name},{key:"removed_user",value:loguser.username}])
const ticketData = require("../core/utils/configParser").getTicketById(ticketId,true)
interaction.channel.messages.fetchPinned().then(msglist => { APIEvents.onTicketRemove(interaction.user,loguser,interaction.channel,interaction.guild,new Date(),{status:"open",name:interaction.channel.name,ticketOptions:ticketData})
var firstmsg = msglist.last() APIEvents.onCommand("remove",permsChecker.ticket(interaction.user.id,interaction.guild.id,ticketId),interaction.user,interaction.channel,interaction.guild,new Date())
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
interaction.channel.permissionOverwrites.delete(user.id)
interaction.reply({embeds:[bot.errorLog.success(l.commands.userRemovedTitle,l.commands.userRemovedDescription.replace("{0}",user.tag))]})
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 ticketId = firstmsg.embeds[0].footer.text.split("Ticket Type: ")[1]
const ticketData = require("../core/getoptions").getOptionsById("newT"+ticketId)
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())
})
}) })
} }
+57 -59
View File
@@ -7,84 +7,82 @@ const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker") const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events") const APIEvents = require("../core/api/modules/events")
const DISABLE = require("../core/api/api.json").disable
module.exports = () => { module.exports = () => {
client.on("messageCreate",msg => { 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.content.startsWith(config.prefix+"rename")) return
msg.channel.messages.fetchPinned().then(msglist => { if (!msg.guild) return
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]}) const hiddendata = bot.hiddenData.readHiddenData(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 (!msg.guild) return if (!permsChecker.ticket(msg.author.id,msg.guild.id,ticketId)){
if (!permsChecker.command(msg.author.id,msg.guild.id)){ permsChecker.sendUserNoPerms(msg.author)
permsChecker.sendUserNoPerms(msg.author) return
return }
}
var newname = msg.content.split(config.prefix+"rename")[1].substring(1) 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>`")]}) 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 name = msg.channel.name
var prefix = "" var prefix = ""
const tickets = config.options const tickets = config.options
tickets.forEach((ticket) => { tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){ if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix prefix = ticket.channelprefix
} }
})
if (!prefix) prefix = "noprefix-"
msg.channel.setName(prefix+newname)
msg.channel.send({embeds:[bot.errorLog.success(l.commands.renameTitle,l.commands.renameWarning)]})
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 (!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.username}])
log("system","ticket renamed",[{key:"user",value:msg.author.username},{key:"ticket",value:name},{key:"newname",value:newname}])
APIEvents.onCommand("rename",permsChecker.ticket(msg.author.id,msg.guild.id,ticketId),msg.author,msg.channel,msg.guild,new Date())
}) })
client.on("interactionCreate",(interaction) => { if (!DISABLE.commands.slash.rename) client.on("interactionCreate",async (interaction) => {
if (!interaction.isChatInputCommand()) return if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "rename") return if (interaction.commandName != "rename") return
interaction.deferReply() if (!interaction.guild) return
interaction.channel.messages.fetchPinned().then(msglist => { const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
var firstmsg = msglist.last() if (hiddendata.length < 1) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
if (firstmsg == undefined || firstmsg.author.id != client.user.id)return interaction.reply({embeds:[bot.errorLog.notInATicket]}) if (!permsChecker.ticket(interaction.user.id,interaction.guild.id,ticketId)){
permsChecker.sendUserNoPerms(interaction.user)
return
}
await interaction.deferReply()
if (!interaction.guild) return var newname = interaction.options.getString("name")
if (!permsChecker.command(interaction.user.id,interaction.guild.id)){ var name = interaction.channel.name
permsChecker.sendUserNoPerms(interaction.user) var prefix = ""
return const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
} }
var newname = interaction.options.getString("name")
var name = interaction.channel.name
var prefix = ""
const tickets = config.options
tickets.forEach((ticket) => {
if (name.startsWith(ticket.channelprefix)){
prefix = ticket.channelprefix
}
})
if (!prefix) prefix = "noprefix-"
interaction.channel.setName(prefix+newname)
interaction.reply({embeds:[bot.errorLog.success(l.commands.renameTitle,l.commands.renameWarning)]})
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())
}) })
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.username}])
log("system","ticket renamed",[{key:"user",value:interaction.user.username},{key:"ticket",value:name},{key:"newname",value:newname}])
APIEvents.onCommand("rename",permsChecker.ticket(interaction.user.id,interaction.guild.id,ticketId),interaction.user,interaction.channel,interaction.guild,new Date())
}) })
} }
+25 -36
View File
@@ -7,56 +7,45 @@ const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker") const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events") const APIEvents = require("../core/api/modules/events")
const DISABLE = require("../core/api/api.json").disable
module.exports = () => { module.exports = () => {
var reopenCommandBar = new discord.ActionRowBuilder() bot.errorLog.log("debug","COMMANDS: loaded reopen.js")
.addComponents(
new discord.ButtonBuilder() if (!DISABLE.commands.text.reopen) client.on("messageCreate",msg => {
.setCustomId("reopenTicket1")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setEmoji("🔓")
)
client.on("messageCreate",msg => {
if (!msg.content.startsWith(config.prefix+"reopen")) return if (!msg.content.startsWith(config.prefix+"reopen")) return
msg.channel.messages.fetchPinned().then(msglist => { const hiddendata = bot.hiddenData.readHiddenData(msg.channel.id)
var firstmsg = msglist.last() if (hiddendata.length < 1) return msg.channel.send({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]}) 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.errorLog.success(l.commands.reopenTitle,l.commands.reopenDescription)],components:[reopenCommandBar]}) 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())
})
log("command","someone used the 'reopen' command",[{key:"user",value:msg.author.username}])
APIEvents.onCommand("reopen",true,msg.author,msg.channel,msg.guild,new Date())
}) })
client.on("interactionCreate",async (interaction) => { if (!DISABLE.commands.slash.reopen) client.on("interactionCreate",async (interaction) => {
if (!interaction.isChatInputCommand()) return if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "reopen") return if (interaction.commandName != "reopen") return
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
if (hiddendata.find(h => h.key == "pendingdelete")) return interaction.reply({embeds:[bot.errorLog.warning("Warning!","You can't re-open a ticket while it's being deleted!")]})
await interaction.deferReply() await interaction.deferReply()
interaction.channel.messages.fetchPinned().then(async msglist => { await interaction.editReply({embeds:[bot.embeds.commands.reopenEmbed(interaction.user)],components:[bot.buttons.close.openRowNormal]})
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return msg.channel.send({embeds:[bot.errorLog.notInATicket]}) require("../core/ticketActions/ticketReopener").reopenTicket(interaction.guild,interaction.channel,interaction.user)
try { log("command","someone used the 'reopen' command",[{key:"user",value:interaction.user.username}])
await interaction.reply({embeds:[bot.errorLog.success(l.commands.reopenTitle,l.commands.reopenDescription)],components:[reopenCommandBar]}) APIEvents.onCommand("reopen",true,interaction.user,interaction.channel,interaction.guild,new Date())
}catch{
await interaction.editReply({embeds:[bot.errorLog.success(l.commands.reopenTitle,l.commands.reopenDescription)],components:[reopenCommandBar]})
}
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())
})
}) })
} }
+103
View File
@@ -0,0 +1,103 @@
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 stats.js")
if (!DISABLE.commands.text.stats) client.on("messageCreate",async (msg) => {
if (!msg.content.startsWith(config.prefix+"stats global") && !msg.content.startsWith(config.prefix+"stats ticket") && !msg.content.startsWith(config.prefix+"stats user")) return
if (!msg.guild) return
/**@type {"global"|"ticket"|"user"} */
const mode = msg.content.split(config.prefix+"stats ")[1]
if (mode == "global"){
//send global stats
msg.channel.send({embeds:[await bot.statsManager.createGlobalStatsEmbed()]})
}else if (mode == "user"){
//send user stats
const mention = msg.mentions.users.first()
if (mention){
//get user from mention
if (!bot.statsManager.existStats("user","TICKETS_CREATED",mention.id)){
msg.channel.send({embeds:[bot.errorLog.serverError(l.stats.errorUserNotFound)]})
return
}
msg.channel.send({embeds:[await bot.statsManager.createUserStatsEmbed(msg.guild,mention,msg.channel.id)]})
}else{
//use author as user
if (!bot.statsManager.existStats("user","TICKETS_CREATED",msg.author.id)){
msg.channel.send({embeds:[bot.errorLog.serverError(l.stats.errorUserNotFound)]})
return
}
msg.channel.send({embeds:[await bot.statsManager.createUserStatsEmbed(msg.guild,msg.author,msg.channel.id)]})
}
}else if (mode == "ticket"){
//send ticket stats
if (!bot.statsManager.existStats("ticket","STATUS",msg.channel.id)){
msg.channel.send({embeds:[bot.errorLog.notInATicket]})
return
}
msg.channel.send({embeds:[await bot.statsManager.createTicketStatsEmbed(msg.guild,msg.channel.id)]})
}
log("command","someone used the 'stats' command",[{key:"user",value:msg.author.username},{key:"mode",value:mode}])
APIEvents.onCommand("stats",true,msg.author,msg.channel,msg.guild,new Date())
})
if (!DISABLE.commands.slash.stats) client.on("interactionCreate",async (interaction) => {
if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "stats") return
if (!interaction.guild) return
/**@type {"global"|"ticket"|"user"} */
const mode = interaction.options.getSubcommand(true)
await interaction.deferReply()
if (mode == "global"){
//send global stats
interaction.editReply({embeds:[await bot.statsManager.createGlobalStatsEmbed()]})
}else if (mode == "user"){
//send user stats
const mention = interaction.options.getUser("user",false)
if (mention){
//get user from mention
if (!bot.statsManager.existStats("user","TICKETS_CREATED",mention.id)){
interaction.editReply({embeds:[bot.errorLog.serverError(l.stats.errorUserNotFound)]})
return
}
interaction.editReply({embeds:[await bot.statsManager.createUserStatsEmbed(interaction.guild,mention,interaction.channel.id)]})
}else{
//use author as user
if (!bot.statsManager.existStats("user","TICKETS_CREATED",interaction.user.id)){
interaction.editReply({embeds:[bot.errorLog.serverError(l.stats.errorUserNotFound)]})
return
}
interaction.editReply({embeds:[await bot.statsManager.createUserStatsEmbed(interaction.guild,interaction.user,interaction.channel.id)]})
}
}else if (mode == "ticket"){
//send ticket stats
if (!bot.statsManager.existStats("ticket","STATUS",interaction.channel.id)){
interaction.editReply({embeds:[bot.errorLog.notInATicket]})
return
}
interaction.editReply({embeds:[await bot.statsManager.createTicketStatsEmbed(interaction.guild,interaction.channel.id)]})
}
log("command","someone used the 'stats' command",[{key:"user",value:interaction.user.username},{key:"mode",value:mode}])
APIEvents.onCommand("stats",true,interaction.user,interaction.channel,interaction.guild,new Date())
})
}
+15 -12
View File
@@ -7,8 +7,11 @@ const l = bot.language
const permsChecker = require("../core/utils/permisssionChecker") const permsChecker = require("../core/utils/permisssionChecker")
const APIEvents = require("../core/api/modules/events") const APIEvents = require("../core/api/modules/events")
const DISABLE = require("../core/api/api.json").disable
module.exports = () => { module.exports = () => {
bot.errorLog.log("debug","COMMANDS: loaded ticket.js")
/**@type {String[]} */ /**@type {String[]} */
var msgIds = [] var msgIds = []
config.messages.forEach((msg) => { config.messages.forEach((msg) => {
@@ -16,36 +19,36 @@ module.exports = () => {
}) })
client.on("messageCreate", msg => { if (!DISABLE.commands.text.msg) client.on("messageCreate", msg => {
if (msg.content.startsWith(config.prefix+"msg"||config.prefix+"message")){ if (msg.content.startsWith(config.prefix+"msg"||config.prefix+"message")){
if (!msg.guild) return if (!msg.guild) return
if (!permsChecker.command(msg.author.id,msg.guild.id)){ if (!permsChecker.global(msg.author.id,msg.guild.id)){
permsChecker.sendUserNoPerms(msg.author) permsChecker.sendUserNoPerms(msg.author)
return return
} }
const id = msg.content.split(config.prefix+"msg")[1].substring(1) ? msg.content.split(config.prefix+"msg")[1].substring(1) : false const id = msg.content.split(config.prefix+"msg")[1].substring(1) ? msg.content.split(config.prefix+"msg")[1].substring(1) : false
if (!id) return msg.channel.send({embeds:[bot.errorLog.invalidArgsMessage(l.errors.missingArgsDescription+" `<id>`:\n`"+config.prefix+"msg <id>`")]}) if (!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)]}) 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/ticketMessageEmbed").createEmbed(id) const {embed,componentRows} = require("../core/utils/getEmbed").createEmbed(id)
msg.channel.send({embeds:[embed],components:componentRows}) msg.channel.send({embeds:[embed],components:componentRows})
log("command","someone used the 'message' command",[{key:"user",value:msg.author.tag},{key:"id",value:id}]) log("command","someone used the 'message' command",[{key:"user",value:msg.author.username},{key:"id",value:id}])
APIEvents.onCommand("message",permsChecker.command(msg.author.id,msg.guild.id),msg.author,msg.channel,msg.guild,new Date()) APIEvents.onCommand("message",permsChecker.global(msg.author.id,msg.guild.id),msg.author,msg.channel,msg.guild,new Date())
} }
}) })
client.on("interactionCreate", (interaction) => { if (!DISABLE.commands.slash.msg) client.on("interactionCreate", (interaction) => {
if (!interaction.isChatInputCommand()) return if (!interaction.isChatInputCommand()) return
if (interaction.commandName != "message") return if (interaction.commandName != "message") return
if (!interaction.guild) return if (!interaction.guild) return
if (!permsChecker.command(interaction.user.id,interaction.guild.id)){ if (!permsChecker.global(interaction.user.id,interaction.guild.id)){
permsChecker.sendUserNoPerms(interaction.user) permsChecker.sendUserNoPerms(interaction.user)
return return
} }
@@ -54,14 +57,14 @@ module.exports = () => {
if (!msgIds.includes(id)) return interaction.reply({embeds:[bot.errorLog.invalidIdChooseFromList(msgIds)]}) if (!msgIds.includes(id)) return interaction.reply({embeds:[bot.errorLog.invalidIdChooseFromList(msgIds)]})
const {embed,componentRows} = require("../core/ticketMessageEmbed").createEmbed(id) const {embed,componentRows} = require("../core/utils/getEmbed").createEmbed(id)
interaction.reply({content:l.commands.ticketWarning}) interaction.reply({content:l.commands.ticketWarning})
interaction.channel.send({embeds:[embed],components:componentRows}) interaction.channel.send({embeds:[embed],components:componentRows})
log("command","someone used the 'message' command",[{key:"user",value:interaction.user.tag},{key:"id",value:id}]) log("command","someone used the 'message' command",[{key:"user",value:interaction.user.username},{key:"id",value:id}])
APIEvents.onCommand("message",permsChecker.command(interaction.user.id,interaction.guild.id),interaction.user,interaction.channel,interaction.guild,new Date()) APIEvents.onCommand("message",permsChecker.global(interaction.user.id,interaction.guild.id),interaction.user,interaction.channel,interaction.guild,new Date())
}) })
} }
+125
View File
@@ -0,0 +1,125 @@
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
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 (!permsChecker.ticket(msg.author.id,msg.guild.id,ticketId)){
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!")]})
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.username}])
log("system","user unclaimed from ticket",[{key:"user",value:msg.author.username},{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.ticket(msg.author.id,msg.guild.id,ticketId),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
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.reply({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
if (!permsChecker.ticket(interaction.user.id,interaction.guild.id,ticketId)){
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!")]})
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.username}])
log("system","user unclaimed from ticket",[{key:"user",value:interaction.user.username},{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.ticket(interaction.user.id,interaction.guild.id,ticketId),interaction.user,interaction.channel,interaction.guild,new Date())
})
})
}
+77 -23
View File
@@ -1,12 +1,14 @@
{ {
"main_color":"#ffffff", "color":"#ffffff",
"server_id":"server id (for slash cmds)", "serverId":"server id (for slash cmds)",
"auth_token":"auth token", "token":{
"main_adminroles":["discord role id"], "value":"insert your bot token here",
"fromENV":false
},
"adminRoles":["discord role id"],
"prefix":"!ticket ", "prefix":"!ticket ",
"languagefile":"english", "languageFile":"english",
"credits":true,
"status":{ "status":{
"enabled":true, "enabled":true,
"type":"PLAYING", "type":"PLAYING",
@@ -14,19 +16,19 @@
}, },
"system":{ "system":{
"ticket_channel":"channel id", "maxAmountOfTickets":3,
"max_allowed_tickets":3, "dmMessages":false,
"enable_DM_Messages":true,
"has@everyoneaccess":false, "memberRole":"member role (leave empty if you have no member role)",
"member_role":"member role (doesn't have access to tickets)", "closeMode":"adminonly OR normal (select one!)",
"closeMode":"adminonly|normal",
"enable_transcript":false, "transcripts":"!!!! ALL SETTINGS FOR TRANSCRIPTS ARE LOCATED IN: transcriptconfig.json !!!!",
"enable_DM_transcript":false,
"transcript_channel":"channel id" "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":[ "options":[
{ {
"id":"general", "id":"general",
@@ -38,11 +40,40 @@
"color":"gray", "color":"gray",
"adminroles":["role id"], "adminroles":["role id"],
"readonlyAdminroles":["role id"],
"channelprefix":"question-", "channelprefix":"question-",
"category":"category id", "category":"category id (or leave empty)",
"message":"You created a ticket!", "message":"You created a ticket!",
"enableDMMessage":true, "enableDmOnOpen":true,
"ticketmessage":"The staff will help you soon!\n\n*Click on the button below to close the ticket!*" "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.example.com/catmemes/cat.png"
},
"closedCategory":{
"enable":false,
"id":"category id"
},
"autoclose":{
"enable":false,
"inactiveHours":24
},
"ping":{
"@here":true,
"@everyone":false,
"custom":{
"enable":false,
"roleId":"012345678910"
}
}
}, },
{ {
@@ -67,7 +98,7 @@
"color":"red", "color":"red",
"roles":["discord role id"], "roles":["discord role id"],
"mode":"add&remove|remove|add", "mode":"add&remove|remove|add",
"enableDMMessage":true "enableDmOnOpen":true
} }
], ],
@@ -77,19 +108,42 @@
"id":"1", "id":"1",
"name":"Choose Your Ticket", "name":"Choose Your Ticket",
"description":"You can click one of the buttons below!", "description":"You can click one of the buttons below!",
"dropdown":false,
"enableFooter":false, "enableFooter":false,
"footer":"Open Ticket v2.4.0 - I'm a footer!", "footer":"Open Ticket v3.5.3 - I'm a footer!",
"enableFooterImage":false,
"footerImage":"https://www.example.com/catmemes/cat.png",
"enableThumbnail":false, "enableThumbnail":false,
"thumbnail":"https://www.example.com/catmemes/cat.png", "thumbnail":"https://www.example.com/catmemes/cat.png",
"enableImage":false,
"image":"https://www.example.com/catmemes/cat.png",
"enableCustomColor":false, "enableCustomColor":false,
"color":"#ffffff", "color":"#ffffff",
"options":["general","apply"], "options":["general","apply"],
"enableTicketExplaination":true,
"enableMaxTicketsWarning":true "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"
}
}
} }
] ]
} }
+19 -4
View File
@@ -1,10 +1,13 @@
{ {
"version":"1.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!",
"disclaimer":"DISABLE doesn't work yet! Below this message!", "info2":"You can use this to disable some features you don't want!",
"disable":{ "disable":{
"messages":{ "messages":{
"DISCLAIMER":"the messages part doesn't work yet!",
"ticketCreated":false, "ticketCreated":false,
"ticketClosed":false, "ticketClosed":false,
"ticketDeleted":false, "ticketDeleted":false,
@@ -24,7 +27,11 @@
"new":false, "new":false,
"add":false, "add":false,
"remove":false, "remove":false,
"rename":false "rename":false,
"claim":false,
"unclaim":false,
"change":false,
"stats":false
}, },
"slash":{ "slash":{
"help":false, "help":false,
@@ -35,12 +42,20 @@
"new":false, "new":false,
"add":false, "add":false,
"remove":false, "remove":false,
"rename":false "rename":false,
"claim":false,
"unclaim":false,
"change":false,
"stats":false
} }
}, },
"checkerjs":{ "checkerjs":{
"token":false, "token":false,
"all":false "all":false
},
"debug":{
"all":false,
"debuglogs":false
} }
} }
} }
-28
View File
@@ -1,28 +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
/** FOR DEVELOPERS ONLY!!
* Don't change anything in this file, read the api documentation first!
* look into "api docs.md" for the docs!
*/
//used when creating plugins!
exports.enableApiLogs = false
//DOESN'T WORK YET
//this is used when embedding open ticket into another bot
exports.embeddedMode = false
exports.clientLocation = require("../../../index").client
/** !! WARNING !!
* Only edit or extend the code when you know what you are doing!
* If open ticket crashes while you change the code, then we can't help you!
*
* DO IT ON YOUR OWN RISK!
*/
+122 -17
View File
@@ -4,7 +4,8 @@ const client = bot.client
const config = bot.config const config = bot.config
const log = bot.errorLog.log const log = bot.errorLog.log
const l = bot.language const l = bot.language
const storage = bot.storage
const configParser = require("../../utils/configParser")
//EVENT API: //EVENT API:
@@ -16,6 +17,10 @@ const ticketReopenListeners = []
const ticketAddListeners = [] const ticketAddListeners = []
const ticketRemoveListeners = [] const ticketRemoveListeners = []
const ticketClaimListeners = []
const ticketUnclaimListeners = []
const ticketChangeListeners = []
const transcriptCreationListeners = [] const transcriptCreationListeners = []
const commandListeners = [] const commandListeners = []
@@ -48,15 +53,16 @@ exports.onTicketOpen = (user,channel,guild,date,ticketdata) => {
* @param {discord.TextChannel} channel * @param {discord.TextChannel} channel
* @param {discord.Guild} guild * @param {discord.Guild} guild
* @param {Date} date * @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata * @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:configParser.OTTicketOptions}} ticketdata
* @param {String} reason
*/ */
exports.onTicketClose = (user,channel,guild,date,ticketdata) => { exports.onTicketClose = (user,channel,guild,date,ticketdata,reason) => {
//system //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)}]) 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) => { ticketCloseListeners.forEach((func) => {
try { try {
func(user,channel,guild,date,ticketdata) func(user,channel,guild,date,ticketdata,reason)
}catch{} }catch{}
}) })
@@ -68,7 +74,7 @@ exports.onTicketClose = (user,channel,guild,date,ticketdata) => {
* @param {discord.TextChannel} channel * @param {discord.TextChannel} channel
* @param {discord.Guild} guild * @param {discord.Guild} guild
* @param {Date} date * @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata * @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:configParser.OTTicketOptions}} ticketdata
*/ */
exports.onTicketDelete = (user,channel,guild,date,ticketdata) => { exports.onTicketDelete = (user,channel,guild,date,ticketdata) => {
//system //system
@@ -88,7 +94,7 @@ exports.onTicketDelete = (user,channel,guild,date,ticketdata) => {
* @param {discord.TextChannel} channel * @param {discord.TextChannel} channel
* @param {discord.Guild} guild * @param {discord.Guild} guild
* @param {Date} date * @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata * @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:configParser.OTTicketOptions}} ticketdata
*/ */
exports.onTicketReopen = (user,channel,guild,date,ticketdata) => { exports.onTicketReopen = (user,channel,guild,date,ticketdata) => {
//system //system
@@ -109,7 +115,7 @@ exports.onTicketReopen = (user,channel,guild,date,ticketdata) => {
* @param {discord.TextChannel} channel * @param {discord.TextChannel} channel
* @param {discord.Guild} guild * @param {discord.Guild} guild
* @param {Date} date * @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata * @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:configParser.OTTicketOptions}} ticketdata
*/ */
exports.onTicketAdd = (user,editeduser,channel,guild,date,ticketdata) => { exports.onTicketAdd = (user,editeduser,channel,guild,date,ticketdata) => {
//system //system
@@ -130,7 +136,7 @@ exports.onTicketAdd = (user,editeduser,channel,guild,date,ticketdata) => {
* @param {discord.TextChannel} channel * @param {discord.TextChannel} channel
* @param {discord.Guild} guild * @param {discord.Guild} guild
* @param {Date} date * @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata * @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:configParser.OTTicketOptions}} ticketdata
*/ */
exports.onTicketRemove = (user,editeduser,channel,guild,date,ticketdata) => { exports.onTicketRemove = (user,editeduser,channel,guild,date,ticketdata) => {
//system //system
@@ -144,6 +150,66 @@ exports.onTicketRemove = (user,editeduser,channel,guild,date,ticketdata) => {
} }
/**
*
* @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.Message[]} messages
@@ -163,7 +229,7 @@ exports.onTranscriptCreation = (messages,channel,guild,date) => {
} }
/**@typedef {"help"|"message"|"close"|"delete"|"reopen"|"rename"|"add"|"remove"} OTCommandType */ /**@typedef {"help"|"message"|"close"|"delete"|"reopen"|"rename"|"add"|"remove"|"claim"|"unclaim"|"change"|"stats"} OTCommandType */
/** /**
* *
@@ -175,15 +241,16 @@ exports.onTranscriptCreation = (messages,channel,guild,date) => {
* @param {Date} date * @param {Date} date
*/ */
exports.onCommand = (type,hasPerms,user,channel,guild,date) => { exports.onCommand = (type,hasPerms,user,channel,guild,date) => {
const newguild = guild ? guild : false
//system //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:guild.id}]) 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) => { commandListeners.forEach((func) => {
try { try {
func(type,hasPerms,user,channel,guild,date) func(type,hasPerms,user,channel,newguild,date)
}catch{} }catch{}
}) })
} }
/**@typedef {"add"|"remove"|"add&remove"} OTReactionRoleType */ /**@typedef {"add"|"remove"|"add&remove"} OTReactionRoleType */
@@ -235,7 +302,17 @@ exports.onCommand = (type,hasPerms,user,channel,guild,date) => {
* @param {discord.TextChannel} channel * @param {discord.TextChannel} channel
* @param {discord.Guild} guild * @param {discord.Guild} guild
* @param {Date} date * @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata * @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
*/ */
/** /**
@@ -253,7 +330,17 @@ exports.onCommand = (type,hasPerms,user,channel,guild,date) => {
* @param {discord.TextChannel} channel * @param {discord.TextChannel} channel
* @param {discord.Guild} guild * @param {discord.Guild} guild
* @param {Date} date * @param {Date} date
* @param {{name:String,status:"open"|"closed"|"deleted"|"reopened",ticketOptions:Object|false}} ticketdata * @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
*/ */
/** /**
@@ -262,7 +349,7 @@ exports.onCommand = (type,hasPerms,user,channel,guild,date) => {
* @param {Boolean} hasPerms * @param {Boolean} hasPerms
* @param {discord.User} user * @param {discord.User} user
* @param {discord.TextChannel} channel * @param {discord.TextChannel} channel
* @param {discord.Guild} guild * @param {discord.Guild|false} guild
* @param {Date} date * @param {Date} date
*/ */
@@ -290,7 +377,7 @@ const onTicketOpen = (callback) => {
ticketOpenListeners.push(callback) ticketOpenListeners.push(callback)
} }
/**@param {TicketActionEvent} callback */ /**@param {TicketCloseEvent} callback */
const onTicketClose = (callback) => { const onTicketClose = (callback) => {
ticketCloseListeners.push(callback) ticketCloseListeners.push(callback)
} }
@@ -315,6 +402,21 @@ const onTicketRemove = (callback) => {
ticketRemoveListeners.push(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 */ /**@param {TranscriptCreationEvent} callback */
const onTranscriptCreation = (callback) => { const onTranscriptCreation = (callback) => {
transcriptCreationListeners.push(callback) transcriptCreationListeners.push(callback)
@@ -342,6 +444,9 @@ exports.events = {
onTicketReopen, onTicketReopen,
onTicketAdd, onTicketAdd,
onTicketRemove, onTicketRemove,
onTicketClaim,
onTicketUnclaim,
onTicketChange,
onTranscriptCreation, onTranscriptCreation,
onCommand, onCommand,
onReactionRole, onReactionRole,
+21 -4
View File
@@ -3,24 +3,41 @@ const bot = require("../../index")
const log = bot.errorLog.log const log = bot.errorLog.log
module.exports = () => { module.exports = () => {
const files = fs.readdirSync("./plugins") const args = process.argv
const debugMode = args.includes("--debug")
const files = fs.readdirSync("./plugins")
const api = require("./api.json")
var totalcount = 0 var totalcount = 0
var successcount = 0 var successcount = 0
var failcount = 0 var failcount = 0
files.forEach((file) => { files.forEach((file) => {
if (file.endsWith(".plugin.js")){ if (file.endsWith(".plugin.js")){
try { try {
require("../../plugins/"+file)() require("../../plugins/" + file)()
successcount++ successcount++
totalcount++ totalcount++
}catch{ }catch(err){
/**@type {Error} */
const theError = err
if (api.enableAPIdebug || debugMode) {
console.error(theError)
}
try {
const data = fs.readFileSync("./openticketdebug.txt")
const newData = data ? data.toString() : ""
fs.writeFileSync("./openticketdebug.txt", newData + "\nPLUGIN "+file+" ERROR: " + theError.name + ": " + theError.message + "\n" + theError.stack + "\n\n")
} catch {
fs.writeFileSync("./openticketdebug.txt", "\nPLUGIN "+file+" ERROR: " + theError.name + ": " + theError.message + "\n" + theError.stack + "\n\n")
}
failcount++ failcount++
totalcount++ totalcount++
} }
} }
}) })
log("info","loaded plugins",[{key:"success",value:successcount},{key:"error",value:failcount},{key:"total",value:totalcount}]) require("../startscreen").headerDataPlugins({ total: totalcount, success: successcount, error: failcount })
} }
+219 -69
View File
@@ -1,6 +1,17 @@
exports.checker = async () => { exports.checker = async () => {
const chalk = await (await import("chalk")).default const chalk = await (await import("chalk")).default
const config = require("../config.json")
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 errorList = []
var isError = false var isError = false
var warnList = [] var warnList = []
@@ -41,9 +52,10 @@ exports.checker = async () => {
} }
/**@param {String} value */ /**@param {String} value */
const checkToken = (value) => { const checkToken = (value) => {
if (value.includes(" ") || value.length < 40 || value.length > 90){ if (value.length < 40){
createError("'auth_token' | your token is invalid") createError("'token/value' | your token is invalid")
} }
if (value.includes(" ")) createError("'token/value' | your token includes spaces!")
} }
/**@param {String} value @param {String} path */ /**@param {String} value @param {String} path */
@@ -73,6 +85,9 @@ exports.checker = async () => {
/**@param {"userid"|"roleid"|"channelid"|"serverid"} mode @param {String[]} arrayValue @param {String} path */ /**@param {"userid"|"roleid"|"channelid"|"serverid"} mode @param {String[]} arrayValue @param {String} path */
const checkDiscordArray = (mode,arrayValue,path) => { const checkDiscordArray = (mode,arrayValue,path) => {
if (!Array.isArray(arrayValue)){
return createError("'"+path+"' | this needs to be an Array!")
}
if (mode == "userid"){ if (mode == "userid"){
arrayValue.forEach((value,index) => { arrayValue.forEach((value,index) => {
if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){ if (value.length < 16 || value.length > 20 || !/^\d+$/.test(value)){
@@ -99,21 +114,34 @@ exports.checker = async () => {
}) })
} }
} }
/**@param {String} value @param {"string"|"boolean"|"number"} type */ /**@param {String} value @param {"string"|"boolean"|"number"|"array"|"object"} type */
const checkType = (value,type,path) => { const checkType = (value,type,path) => {
if (type == "boolean"){ if (type == "boolean"){
if (typeof value != "boolean"){ if (typeof value != "boolean"){
createError("'"+path+"' | invalid type, this must be a boolean!") createError("'"+path+"' | invalid type, this must be a boolean!")
} return true
}else return false
}else if (type == "number"){ }else if (type == "number"){
if (typeof value != "number"){ if (typeof value != "number"){
createError("'"+path+"' | invalid type, this must be a number!") createError("'"+path+"' | invalid type, this must be a number!")
} return true
}else return false
}else if (type == "string"){ }else if (type == "string"){
if (typeof value != "string"){ if (typeof value != "string"){
createError("'"+path+"' | invalid type, this must be a 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) => { const checkButtonColor = (value,path) => {
@@ -122,8 +150,12 @@ exports.checker = async () => {
} }
} }
const getButtonClass = require("./utils/getButton").rawButtonData const configParser = require("./utils/configParser")
/**@param {getButtonClass} option */ /**
* @param {configParser.OTAllOptions} option
* @param {String} path
*/
const checkOption = (option,path) => { const checkOption = (option,path) => {
//id //id
@@ -147,7 +179,7 @@ exports.checker = async () => {
checkType(option.description,"string",path+"/description") checkType(option.description,"string",path+"/description")
//icon //icon
const emojiRegex = /(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])/gi; const emojiRegex = /(?:\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])|(?:<a?:[^:]*:[0-9]+>)/gi
if (option.icon.length > 0){ if (option.icon.length > 0){
const isEmoji = emojiRegex.test(option.icon) const isEmoji = emojiRegex.test(option.icon)
@@ -178,6 +210,7 @@ exports.checker = async () => {
checkButtonColor(option.color,path+"/color") checkButtonColor(option.color,path+"/color")
//adminroles //adminroles
checkType(option.adminroles,"array",path+"/adminroles")
checkDiscordArray("roleid",option.adminroles,path+"/adminroles") checkDiscordArray("roleid",option.adminroles,path+"/adminroles")
//channelprefix //channelprefix
@@ -195,12 +228,47 @@ exports.checker = async () => {
//message //message
checkType(option.message,"string",path+"/message") checkType(option.message,"string",path+"/message")
//enableDMmessage //enableDmOnOpen
checkType(option.enableDMMessage,"boolean",path+"/enableDMMessage") checkType(option.enableDmOnOpen,"boolean",path+"/enableDmOnOpen")
//ticketmessage //ticketmessage
checkType(option.ticketmessage,"string",path+"/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"){ }else if (type == "website"){
//url //url
checkType(option.url,"string",path+"/url") checkType(option.url,"string",path+"/url")
@@ -208,13 +276,13 @@ exports.checker = async () => {
createWarn("'"+path+"/url' | a url can't contain spaces") createWarn("'"+path+"/url' | a url can't contain spaces")
} }
if (option.url.length < 1){ if (option.url.length < 1){
createError("'"+path+"/url' | you have no url in this button") createError("'"+path+"/url' | there is no url!")
} }
if (!option.url.startsWith("https://") && !option.url.startsWith("http://") && !option.url.startsWith("discord://")){ 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!") createWarn("'"+path+"/url' | your url doesn't start with https or http!")
} }
if (option.url.startsWith("http://")){ if (option.url.startsWith("http://")){
createWarn("'"+path+"/url' | your url is not a HTTPS link! discord maybe blocks this url!") createWarn("'"+path+"/url' | your url is not a HTTPS link! discord can block this url!")
} }
}else if (type == "role"){ }else if (type == "role"){
//color //color
@@ -230,13 +298,108 @@ exports.checker = async () => {
createError("'"+path+"/mode' | mode must be one of these: add, remove, add&remove") createError("'"+path+"/mode' | mode must be one of these: add, remove, add&remove")
} }
//enableDMmessage //enableDmOnOpen
checkType(option.enableDMMessage,"boolean",path+"/enableDMMessage") checkType(option.enableDmOnOpen,"boolean",path+"/enableDmOnOpen")
} }
} }
/**
*
* @param {configParser.OTConfigMessage} input
* @param {String} path
*/
const checkMessage = (input,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!")}
}
}
} }
//--------------------------| //--------------------------|
@@ -245,63 +408,65 @@ exports.checker = async () => {
//--------------------------| //--------------------------|
//--------------------------| //--------------------------|
var configArray = ["main_color","server_id","auth_token","main_adminroles","prefix","languagefile","credits","status","system","options","messages"] var configArray = ["color","serverId","token","adminRoles","prefix","languageFile","status","system","options","messages"]
configArray.forEach((item) => { configArray.forEach((item) => {
if (config[item] == undefined){ if (config[item] == undefined){
throw new Error("\n\nMAIN ERROR: the item '"+item+"' doesn't exist in config.json") throw new Error("\n\nMAIN ERROR: the item '"+item+"' doesn't exist in config.json")
} }
}) })
checkHexColor(config.main_color,"main_color") checkHexColor(config.color,"main_color")
checkDiscord("serverid",config.server_id,"server_id") checkDiscord("serverid",config.serverId,"server_id")
checkToken(config.auth_token)
checkDiscordArray("roleid",config.main_adminroles,"main_adminroles") 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") checkString(config.prefix,1,15,"prefix","prefix")
//languagefile //languagefile
checkType(config.languagefile,"string","languagefile") checkType(config.languageFile,"string","languagefile")
const lf = config.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")){
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") && !lf.startsWith("ukrainian") && !lf.startsWith("hungarian") && !lf.startsWith("indonesian")){
createError("'languagefile' | invalid language, more info in the wiki") createError("'languagefile' | invalid language, more info in the wiki")
} }
checkType(config.credits,"boolean","credits")
//status: //status:
checkType(config.status.enabled,"boolean","status/enabled") checkType(config.status.enabled,"boolean","status/enabled")
if (config.status.enabled){ if (config.status.enabled){
if (config.status.type != "PLAYING" && config.status.type != "LISTENING" && config.status.type != "WATCHING"){ if (config.status.type != "PLAYING" && config.status.type != "LISTENING" && config.status.type != "WATCHING" && config.status.type != "CUSTOM"){
createError("'status/type' | not a valid status type!") createError("'status/type' | not a valid status type! (LISTENING,WATCHING,PLAYING)")
} }
if (config.status.text.length < 1 || config.status.text.length > 40){ if (config.status.text.length < 1){
createError("'status/text' | text too long or short!") createError("'status/text' | there is no status text!")
} }
if (config.status.text.length > 50) createError("'status/text' | text too long!")
} }
//system: //system:
if (config.system.ticket_channel){ //max tickets
if (config.system.ticket_channel.length < 16 || config.system.ticket_channel.length > 20 || !/^\d+$/.test(config.system.ticket_channel)){ checkType(config.system.maxAmountOfTickets,"number","system/maxAmountOfTickets")
createError("'system/ticket_channel' | this channel id is invalid")
} //enableDMmessages
}else createWarn("'"+path+"' | you have no ticket channel selected!") checkType(config.system.dmMessages,"boolean","system/dmMessages")
checkType(config.system.max_allowed_tickets,"number","system/max_allowed_tickets")
checkType(config.system.enable_DM_Messages,"boolean","system/enable_DM_Messages") //memberRole
checkType(config.system["has@everyoneaccess"],"boolean","system/has@everyoneaccess") checkType(config.system.memberRole,"string","system/memberRole")
if (config.system.member_role != "" && config.system.member_role != " " && config.system.member_role != "false" && config.system.member_role != "null" && config.system.member_role != "0"){ if (config.system.memberRole && ![" ","0","false","null","undefined"].includes(config.system.memberRole)){
checkDiscord("roleid",config.system.member_role,"system/member_role") checkDiscord("roleid",config.system.memberRole,"system/memberRole")
}else{ }else{
createWarn("'system/member_role' | You don't have a member role, but it's recommended!") createWarn("'system/memberRole' | You don't have a member role, but it's recommended!")
} }
//closemode
checkType(config.system.closeMode,"string","system/closeMode") checkType(config.system.closeMode,"string","system/closeMode")
if (!["normal","adminonly"].includes(config.system.closeMode)){ if (!["normal","adminonly"].includes(config.system.closeMode)){
createError("'system/closeMode' | the close mode must be adminonly or normal") createError("'system/closeMode' | the close mode must be adminonly or normal")
} }
checkType(config.system.enable_transcript,"boolean","system/enable_transcript") checkType(config.system.showSlashcmdsInHelp,"boolean","system/showSlashcmdsInHelp")
checkType(config.system.enable_DM_transcript,"boolean","system/enable_DM_transcript") checkType(config.system.answerInEphemeralOnOpen,"boolean","system/answerInEphemeralOnOpen")
if (config.system.enable_transcript){
checkDiscord("channelid",config.system.transcript_channel,"system/transcript_channel")
}
//options //options
@@ -309,29 +474,11 @@ exports.checker = async () => {
checkOption(option,"options/"+index) checkOption(option,"options/"+index)
}) })
//messages
//discord check config.messages.forEach((message,index) => {
/** checkMessage(message,"messages/"+index)
const discord = require("discord.js")
const {GatewayIntentBits,Partials} = discord
const client = new discord.Client({
intents:[
GatewayIntentBits.DirectMessages,
GatewayIntentBits.GuildInvites,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.Guilds,
GatewayIntentBits.MessageContent
],
partials:[Partials.Channel,Partials.Message]
}) })
await client.guilds.fetch()
if (!client.guilds.cache.find(g => g.id == config.server_id)){
createError("'server_id' | i'm not in a server with this id!")
}
*/
//the end //the end
if (errorList.length > 0 || warnList.length > 0){ if (errorList.length > 0 || warnList.length > 0){
@@ -341,6 +488,9 @@ exports.checker = async () => {
const splitw = w.split("'") const splitw = w.split("'")
if (splitw.length > 1){ if (splitw.length > 1){
var splitstring = chalk.yellow(splitw[0])+chalk.blue("'"+splitw[1]+"'")+chalk.yellow(splitw[2]) 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])} }else {var splitstring = chalk.yellow(splitw[0])}
console.log(splitstring) console.log(splitstring)
}) })
@@ -363,4 +513,4 @@ exports.checker = async () => {
console.log("=> "+chalk.bgYellow("if you ignore warns, some things may work differently than expected!")) console.log("=> "+chalk.bgYellow("if you ignore warns, some things may work differently than expected!"))
} }
} }
-331
View File
@@ -1,331 +0,0 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const l = bot.language
module.exports = () => {
//closebar
var closeBar = new discord.ActionRowBuilder()
.addComponents(
new discord.ButtonBuilder()
.setCustomId("closeTicketTrue")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setEmoji("✅")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("closeTicketFalse")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setEmoji("❌")
)
var deleteBar = new discord.ActionRowBuilder()
.addComponents(
new discord.ButtonBuilder()
.setCustomId("deleteTicketTrue")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setEmoji("✅")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("deleteTicketFalse")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setEmoji("❌")
)
var deleteBar1 = new discord.ActionRowBuilder()
.addComponents(
new discord.ButtonBuilder()
.setCustomId("deleteTicketTrue1")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setEmoji("✅")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("deleteTicketFalse1")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setEmoji("❌")
)
//closebutton
var closeRowNormal = new discord.ActionRowBuilder()
.addComponents(
new discord.ButtonBuilder()
.setCustomId("closeTicket")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setLabel(l.buttons.close)
.setEmoji("🔒")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("deleteTicket")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Danger)
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
var closeRowClosed = new discord.ActionRowBuilder()
.addComponents(
new discord.ButtonBuilder()
.setCustomId("deleteTicket1")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Danger)
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("sendTranscript")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setLabel(l.buttons.sendTranscript)
.setEmoji("📄")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("reopenTicket")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Success)
.setLabel(l.buttons.reopen)
.setEmoji("✔")
)
var closeRowDisabled = new discord.ActionRowBuilder()
.addComponents(
new discord.ButtonBuilder()
.setCustomId("closeTicket")
.setDisabled(true)
.setStyle(discord.ButtonStyle.Secondary)
.setLabel(l.buttons.close)
.setEmoji("🔒")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("deleteTicket")
.setDisabled(true)
.setStyle(discord.ButtonStyle.Danger)
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
//NORMAL CLOSE
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "closeTicket") return
interaction.deferUpdate()
interaction.message.edit({components:[closeBar]})
})
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "closeTicketFalse") return
interaction.deferUpdate()
interaction.message.edit({components:[closeRowNormal]})
})
var closeTicketButtonChecker = false
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "closeTicketTrue") return
interaction.deferUpdate()
if (closeTicketButtonChecker == true) return
closeTicketButtonChecker = true
if (config.system.closeMode == "adminonly"){
const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id)
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("Administrator") && !permsmember.permissions.has("ManageGuild")){
try {
return msg.member.send({embeds:[bot.errorLog.noPermsMessage]})
}catch{
return msg.channel.send({embeds:[bot.errorLog.noPermsMessage]})
}
}
}
interaction.message.edit({components:[closeRowDisabled]})
/**
* @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 require("./ticketCloser").NEWcloseTicket(interaction.member,interaction.channel,prefix,"close")
closeTicketButtonChecker = false
})
var closeTicket1ButtonChecker = false
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "closeTicketTrue1") return
interaction.deferUpdate()
if (closeTicket1ButtonChecker == true) return
closeTicket1ButtonChecker = true
if (config.system.closeMode == "adminonly"){
const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id)
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("Administrator") && !permsmember.permissions.has("ManageGuild")){
try {
return interaction.member.send({embeds:[bot.errorLog.noPermsMessage]})
}catch{
return interaction.channel.send({embeds:[bot.errorLog.noPermsMessage]})
}
}
}
const closedButtonDisabled = new discord.ActionRowBuilder()
.addComponents([
new discord.ButtonBuilder()
.setCustomId("closeTicketTrue1")
.setDisabled(true)
.setStyle(discord.ButtonStyle.Secondary)
.setEmoji("🔒")
])
interaction.message.edit({components:[closedButtonDisabled]})
interaction.channel.messages.fetchPinned().then((messages) => {
messages.first().edit({components:[closeRowDisabled]})
})
/**
* @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 require("./ticketCloser").NEWcloseTicket(interaction.member,interaction.channel,prefix,"close")
closeTicket1ButtonChecker = false
})
//NORMAL DELETE
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "deleteTicket") return
interaction.deferUpdate()
interaction.message.edit({components:[deleteBar]})
})
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "deleteTicketFalse") return
interaction.deferUpdate()
interaction.message.edit({components:[closeRowNormal]})
})
var deleteTicketButtonChecker = false
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "deleteTicketTrue") return
interaction.deferUpdate()
if (deleteTicketButtonChecker == true) return
deleteTicketButtonChecker = true
const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id)
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("Administrator") && !permsmember.permissions.has("ManageGuild")){
try {
return interaction.member.send({embeds:[bot.errorLog.noPermsMessage]})
}catch{
return interaction.channel.send({embeds:[bot.errorLog.noPermsMessage]})
}
}
/**
* @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 require("./ticketCloser").NEWcloseTicket(interaction.member,interaction.channel,prefix,"delete")
deleteTicketButtonChecker = false
})
//CLOSED DELETE
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "deleteTicket1") return
interaction.deferUpdate()
interaction.message.edit({components:[deleteBar1]})
})
client.on("interactionCreate",interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "deleteTicketFalse1") return
interaction.deferUpdate()
interaction.message.edit({components:[closeRowClosed]})
})
var deleteTicket1ButtonChecker = false
client.on("interactionCreate",async interaction => {
if (!interaction.isButton()) return
if (interaction.customId != "deleteTicketTrue1") return
interaction.deferUpdate()
if (deleteTicket1ButtonChecker == true) return
deleteTicket1ButtonChecker = true
const permsmember = client.guilds.cache.find(g => g.id == interaction.guild.id).members.cache.find(m => m.id == interaction.member.id)
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("Administrator") && !permsmember.permissions.has("ManageGuild")){
try {
return interaction.member.send({embeds:[bot.errorLog.noPermsMessage]})
}catch{
return interaction.channel.send({embeds:[bot.errorLog.noPermsMessage]})
}
}
/**
* @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 require("./ticketCloser").NEWcloseTicket(interaction.member,interaction.channel,prefix,"deletenotranscript")
deleteTicket1ButtonChecker = false
})
}
+82
View File
@@ -0,0 +1,82 @@
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
}
+87
View File
@@ -0,0 +1,87 @@
const fs = require("fs")
const location = "./storage/stats.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"))
}
/**
* @param {String} category
* @param {String} key
* @param {String|Boolean|Number} value
* @returns {Boolean} exists?
*/
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|Boolean|Number|undefined}
*/
exports.get = (category,key) => {
const currentData = getData()
const result = currentData.find((d) => (d.category == category) && (d.key == key))
return (result) ? result.value : undefined
}
/**
* @param {String} category
* @returns {[{key:String,value:String|Boolean|Number}]|false}
*/
exports.getCategory = (category) => {
const currentData = getData()
const result = currentData.filter((v) => v.category == category)
return result
}
/**
* @param {String} category
* @param {String} key
* @returns {Boolean} exists?
*/
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,39 +0,0 @@
const localstorage = require("node-localstorage")
const ls = new localstorage.LocalStorage("./storage/dynamicDB")
/**
*
* @param {String} category
* @param {String} id
* @param {String} value
* @returns {Boolean}
*/
exports.set = (category,id,value) => {
ls.setItem(category+"--"+id,value.toString())
return true
}
/**
*
* @param {String} category
* @param {String} id
* @returns {String|false}
*/
exports.get = (category,id) => {
const result = ls.getItem(category+"--"+id)
if (!result) return false
return result
}
/**
*
* @param {String} category
* @param {String} id
* @returns {Boolean}
*/
exports.delete = (category,id) => {
ls.removeItem(category+"--"+id)
return true
}
+18 -28
View File
@@ -1,33 +1,23 @@
//Do not change this without knowing what you are doing!! /**
const databaseFile = "local" ==================================================================
//Do not change this without knowing what you are doing!! 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 { try {
var db = require("./dynamicfiles/local") var main = require("./databases/main")
}catch{ var stats = require("./databases/stats")
console.log("I couldn't find the database file! (location: ./core/dynamicdatabase/storage.js:2)") }catch(err){
console.log(err)
console.log("Unable to find the database handlers!")
process.exit(1) process.exit(1)
} }
module.exports = db module.exports = {
main,
stats
/** ============================= }
** NOT READY YET
** must be dynamic
** =============================*/
//const LocalStorage = require("node-localstorage")
//
//const ticketStorage = new LocalStorage.LocalStorage("./storage/tickets")
//exports.ticketStorage = ticketStorage
//
//const userTicketStorage = new LocalStorage.LocalStorage("./storage/userTickets")
//exports.userTicketStorage = userTicketStorage
//
//const transcriptStorage = new LocalStorage.LocalStorage("./storage/transcripts")
//exports.transcriptStorage = transcriptStorage
//const ticketNumberStorage = new LocalStorage.LocalStorage("./storage/ticketNumbers")
//exports.ticketNumberStorage = ticketNumberStorage
+51 -15
View File
@@ -10,16 +10,29 @@ const loadChalk = async () => {
const embed = discord.EmbedBuilder const embed = discord.EmbedBuilder
const c = discord.Colors const c = discord.Colors
exports.noPermsMessage = new embed() /**@param {discord.User} user*/
exports.noPermsMessage = (user) => {
return new embed()
.setColor(c.Red) .setColor(c.Red)
.setTitle(":x: "+l.errors.noPermsTitle+" :x:") .setTitle("❌ "+l.errors.noPermsTitle)
.setDescription(l.errors.noPermsDescription) .setDescription(l.errors.noPermsDescription)
.setFooter({iconURL:user.displayAvatarURL(),text:user.username})
}
/**@param {discord.User} user*/
exports.noPermsDelete = (user) => {
return new embed()
.setColor(c.Red)
.setTitle("❌ "+l.errors.noPermsTitle)
.setDescription(l.errors.noPermsDelete)
.setFooter({iconURL:user.displayAvatarURL(),text:user.username})
}
/**@param {String} message */ /**@param {String} message */
exports.invalidArgsMessage = (message) => { exports.invalidArgsMessage = (message) => {
var x = new embed() var x = new embed()
.setColor(c.Red) .setColor(c.Red)
.setTitle(":x: "+l.errors.missingArgsTitle+" :x:") .setTitle("❌ "+l.errors.missingArgsTitle)
.setDescription(message) .setDescription(message)
return x return x
@@ -29,32 +42,38 @@ exports.invalidArgsMessage = (message) => {
exports.serverError = (message) => { exports.serverError = (message) => {
var x = new embed() var x = new embed()
.setColor(c.Orange) .setColor(c.Orange)
.setTitle(":warning: "+l.errors.boterror+" :warning:") .setTitle("⚠️ "+l.errors.boterror)
.setDescription(message) .setDescription(message)
return x return x
} }
/**@param {String[]} list */ /**@param {String[]} list @param {String|undefined} message */
exports.invalidIdChooseFromList = (list) => { exports.invalidIdChooseFromList = (list,message) => {
const beforemsg = message ? message+"\n\n" : ""
var x = new embed() var x = new embed()
.setColor(c.Red) .setColor(c.Red)
.setTitle(":x: "+l.errors.chooseFromListTitle+" :x:") .setTitle("❌ "+l.errors.chooseFromListTitle)
.setDescription(l.errors.chooseFromListDescription+"\n`"+list.join("`\n`")+"`") .setDescription(beforemsg+l.errors.chooseFromListDescription+"\n`"+list.join("`\n`")+"`")
return x return x
} }
exports.failedRenameChannel = new embed()
.setColor(c.Red)
.setTitle("❌ Failed to rename channel")
.setDescription("Discord channels can only be renamed twice every 10 minutes! Open Ticket can't do anything about this error!")
exports.notInATicket = new embed() exports.notInATicket = new embed()
.setColor(c.Red) .setColor(c.Red)
.setTitle(":x: "+l.errors.notInTicketTitle+" :x:") .setTitle("❌ "+l.errors.notInTicketTitle)
.setDescription(l.errors.notInTicketDescription) .setDescription(l.errors.notInTicketDescription)
/**@param {String} message @param {String} title */ /**@param {String} message @param {String} title */
exports.success = (title,message) => { exports.success = (title,message) => {
var x = new embed() var x = new embed()
.setColor(config.main_color) .setColor(config.color)
.setTitle(":white_check_mark: "+title+" :white_check_mark:") .setTitle("✅ "+title)
.setDescription(message) .setDescription(message)
return x return x
@@ -64,7 +83,7 @@ exports.success = (title,message) => {
exports.warning = (title,message) => { exports.warning = (title,message) => {
var x = new embed() var x = new embed()
.setColor(c.Orange) .setColor(c.Orange)
.setTitle(":warning: "+title+" :warning:") .setTitle("⚠️ "+title)
.setDescription(message) .setDescription(message)
return x return x
@@ -74,21 +93,35 @@ exports.warning = (title,message) => {
exports.custom = (title,message,emoji,color) => { exports.custom = (title,message,emoji,color) => {
var x = new embed() var x = new embed()
.setColor(color) .setColor(color)
.setTitle(emoji+" "+title+" "+emoji) .setTitle(emoji+" "+title)
.setDescription(message) .setDescription(message)
return x 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 normalLog = (debugString) => {
const fs = require("fs") const fs = require("fs")
const content = fs.existsSync("./openticketdebug.txt") ? fs.readFileSync("./openticketdebug.txt").toString() : "==========================\n<OPEN TICKET DEBUG FILE:>\n==========================" const content = fs.existsSync("./openticketdebug.txt") ? fs.readFileSync("./openticketdebug.txt").toString() : "==========================\n<OPEN TICKET DEBUG FILE:>\n=========================="
fs.writeFileSync("./openticketdebug.txt",content+"\nSYSTEM: "+debugString) fs.writeFileSync("./openticketdebug.txt",content+"\nSYSTEM: "+debugString)
this.clearDebugFile()
} }
/** /**
* *
* @param {"system"|"command"|"info"|"api"} type * @param {"system"|"command"|"info"|"api"|"debug"} type
* @param {String} message * @param {String} message
* @param {[{key:String,value:String}]} params * @param {[{key:String,value:String}]} params
*/ */
@@ -112,10 +145,13 @@ exports.log = async (type,message,params) => {
}else if (ptype == "system"){ }else if (ptype == "system"){
console.log(chalk.green("[system] ")+message+" "+chalk.yellow(parameters)) console.log(chalk.green("[system] ")+message+" "+chalk.yellow(parameters))
}else if (ptype == "api"){ }else if (ptype == "api"){
if (require("./api/modules/base").enableApiLogs == true){ if (require("./api/api.json").enableAPIconsolelogs == true){
console.log(chalk.red("[api v"+require("./api/api.json").version+"] ")+message+" "+chalk.yellow(parameters)) console.log(chalk.red("[api v"+require("./api/api.json").version+"] ")+message+" "+chalk.yellow(parameters))
} }
ptype = "api v"+require("./api/api.json").version 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 cd = new Date()
-116
View File
@@ -1,116 +0,0 @@
const bot = require("../index")
const config = bot.config
/**
* @param {Number} index
* @param {"id"|"name"|"description"|"icon"|"label"|"type"|"color"|"adminroles"|"channelprefix"|"category"|"message"|"enableDMMessage"|"ticketmessage"} value
*/
exports.getTicketValue = (index,value) => {
if (value == "id"){
return "newT"+config.options[index][value]
}
return config.options[index][value]
}
/**
* @param {Number} index
* @param {"id"|"name"|"description"|"icon"|"label"|"type"|"url"} value
*/
exports.getWebsiteValue = (index,value) => {
return config.options[index][value]
}
/**
* @param {Number} index
* @param {"id"|"name"|"description"|"icon"|"label"|"type"|"color"|"roles"|"mode"|"enableDMMessage"} value
*/
exports.getRoleValue = (index,value) => {
return config.options[index][value]
}
/**
* @param {"id"|"name"|"description"|"icon"|"label"|"type"|"color"|"adminroles"|"channelprefix"|"category"|"message"|"enableDMMessage"|"ticketmessage"} value
*/
exports.getTicketValues = (value) => {
var result = []
config.options.forEach((o) => {
if (value == "id"){
result.push("newT"+o[value])
}else{
result.push(o[value])
}
})
return result
}
/**
* @param {"id"|"name"|"description"|"icon"|"label"|"type"|"url"} value
*/
exports.getWebsiteValues = (value) => {
var result = []
config.options.forEach((o) => {
result.push(o[value])
})
return result
}
/**
* @param {"id"|"name"|"description"|"icon"|"label"|"type"|"color"|"roles"|"mode"|"enableDMMessage""} value
*/
exports.getRoleValues = (value) => {
var result = []
config.options.forEach((o) => {
result.push(o[value])
})
return result
}
class TicketOptions {
constructor() {
this.id = ""
this.name = ""
this.description = ""
this.icon = ""
this.label = ""
this.type = ""
this.color = ""
this.adminroles = ["",""]
this.channelprefix = ""
this.category = ""
this.message = ""
this.enableDMMessage = true
this.ticketmessage = ""
}
}
/**
*
* @param {String} id
* @returns {TicketOptions|false}
*/
exports.getOptionsById = (id) => {
var result = false
config.options.forEach((option) => {
if ("newT"+option.id == id){
result = option
}
})
return result
}
exports.exportedOptionClass = class {
constructor() {
this.id = ""
this.name = ""
this.description = ""
this.icon = ""
this.label = ""
this.type = ""
this.color = ""
this.adminroles = ["",""]
this.channelprefix = ""
this.category = ""
this.message = ""
this.enableDMMessage = true
this.ticketmessage = ""
}
}
+87
View File
@@ -0,0 +1,87 @@
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("✖️")
)
@@ -0,0 +1,115 @@
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("✖️")
)
@@ -0,0 +1,71 @@
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
@@ -0,0 +1,144 @@
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.username,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.username,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.username,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.username,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.username,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.username,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.username,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.username,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.username,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.username,iconURL:changer.displayAvatarURL()})
}
@@ -0,0 +1,60 @@
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
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 (!permsChecker.ticket(interaction.user.id,interaction.guild.id,ticketId)){
permsChecker.sendUserNoPerms(interaction.user)
return
}
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.username,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)]})
})
})
}
@@ -0,0 +1,76 @@
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
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.channel.send({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
if (config.system.closeMode == "adminonly"){
if (!permissionChecker.ticket(interaction.user.id,interaction.guild.id,ticketId)){
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
})
}
@@ -0,0 +1,103 @@
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
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.channel.send({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
if (config.system.closeMode == "adminonly"){
if (!permissionChecker.ticket(interaction.user.id,interaction.guild.id,ticketId)){
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
})
}
@@ -0,0 +1,107 @@
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
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.channel.send({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
if (!permissionChecker.ticket(interaction.user.id,interaction.guild.id,ticketId)){
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
const hiddendata = bot.hiddenData.readHiddenData(interaction.channel.id)
if (hiddendata.length < 1) return interaction.channel.send({embeds:[bot.errorLog.notInATicket]})
const ticketId = hiddendata.find(d => d.key == "type").value
if (!permissionChecker.ticket(interaction.user.id,interaction.guild.id,ticketId)){
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
})
}
@@ -0,0 +1,28 @@
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)
})
}
@@ -0,0 +1,20 @@
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 = () => {
}
@@ -0,0 +1,11 @@
module.exports = () => {
require("./firstmsg")()
require("./verifyBars")()
//accepted
require("./accepted/closing")()
require("./accepted/reopening")()
require("./accepted/deleting")()
require("./accepted/closingReason")()
require("./accepted/claiming")()
}
@@ -0,0 +1,100 @@
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]})
})
}
+14 -14
View File
@@ -1,30 +1,30 @@
const index = require("../index") const index = require("../index")
if (index.developerMode){ if (index.developerConfig){
var config = require("../devConfig.json") var config = require("../devconfig.json")
}else{var config = require("../config.json")} }else{var config = require("../config.json")}
var localLanguage = require("../language/english.json") var localLanguage = require("../language/english.json")
if (config.languagefile.startsWith("custom")) localLanguage = require("../language/custom.json") const fs = require("fs")
else if (config.languagefile.startsWith("dutch")) localLanguage = require("../language/dutch.json") const lfexists = fs.existsSync("./language/"+config.languageFile+".json")
else if (config.languagefile.startsWith("english")) localLanguage = require("../language/english.json") if (lfexists) localLanguage = require("../language/"+config.languageFile+".json")
else if (config.languagefile.startsWith("german")) localLanguage = require("../language/german.json")
else if (config.languagefile.startsWith("french")) localLanguage = require("../language/french.json")
else if (config.languagefile.startsWith("romanian")) localLanguage = require("../language/romanian.json")
else if (config.languagefile.startsWith("arabic")) localLanguage = require("../language/arabic.json")
else if (config.languagefile.startsWith("spanish")) localLanguage = require("../language/spanish.json")
const errorLog = async () => { const errorLog = async () => {
const chalk = await (await import("chalk")).default const chalk = await (await import("chalk")).default
console.log(chalk.red("Something went wrong when loading the language!")+"\nCheck the config file or create a ticket in our server!") require("./startscreen").headerDataLanguage("Something went wrong when loading the language!",true)
} }
const successLog = async (language) => { const successLog = async (language) => {
const chalk = await (await import("chalk")).default const chalk = await (await import("chalk")).default
console.log(chalk.green("loaded language "+language+"...")) 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){ if (!localLanguage){
@@ -35,5 +35,5 @@ if (!localLanguage){
runError() runError()
}else{ }else{
exports.language = localLanguage exports.language = localLanguage
successLog(config.languagefile) successLog(config.languageFile)
} }
+7
View File
@@ -0,0 +1,7 @@
██████╗ ██████╗ ███████╗███╗ ██╗ ████████╗██╗ ██████╗██╗ ██╗███████╗████████╗
██╔═══██╗██╔══██╗██╔════╝████╗ ██║ ╚══██╔══╝██║██╔════╝██║ ██╔╝██╔════╝╚══██╔══╝
██║ ██║██████╔╝█████╗ ██╔██╗ ██║ ██║ ██║██║ █████╔╝ █████╗ ██║
██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║ ██║ ██║██║ ██╔═██╗ ██╔══╝ ██║
╚██████╔╝██║ ███████╗██║ ╚████║ ██║ ██║╚██████╗██║ ██╗███████╗ ██║
╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═╝
+76 -47
View File
@@ -11,65 +11,94 @@ const APIEvents = require("./api/modules/events")
module.exports = async () => { module.exports = async () => {
const chalk = await (await import("chalk")).default const chalk = await (await import("chalk")).default
client.on("interactionCreate",(interaction) => { client.on("interactionCreate",async (interaction) => {
if (!interaction.isButton()) return if (!interaction.isButton() && !interaction.isStringSelectMenu()) return
if (!interaction.customId.startsWith("newR")) return if (interaction.isButton() && !interaction.customId.startsWith("newR")) return
if (interaction.isStringSelectMenu() && !(interaction.customId == "OTdropdownMenu")) return
interaction.deferUpdate() bot.actionRecorder.push({
category:"ot.managers.reactionroles",
file:"./core/reactionRoles.js",
time:new Date().getTime(),
type:"reactionRoles.interactionCreated"
})
if (interaction.customId.startsWith("newR")){
const optionid = interaction.customId.split("newR")[1]
if (!optionid){
interaction.reply({embeds:[bot.errorLog.serverError(l.errors.roleDoesntExist)]})
return
}
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 { try {
await interaction.deferUpdate()
} catch{}
}
const option = require("./utils/getButton").getOption(optionid) try {
/**@type {"add"|"remove"|"add&remove"} */
const mode = option.mode const option = require("./utils/getButton").getOption(optionid)
const user = interaction.member /**@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.username},{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.username},{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())
})
if (mode == "add"){ }else if (mode == "add&remove"){
option.roles.forEach((role) => { 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) 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}]) log("system","added role (reaction roles)",[{key:"user",value:interaction.user.username},{key:"role",value:role}])
const apirole = interaction.guild.roles.cache.find(r => r.id == 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()) APIEvents.onReactionRole("add","add&remove",apirole,interaction.user,interaction.channel,interaction.guild,new Date())
}) }else {
}else if (mode == "remove"){
option.roles.forEach((role) => {
interaction.guild.members.cache.find(u => u.id == user.id).roles.remove(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}]) log("system","removed role (reaction roles)",[{key:"user",value:interaction.user.username},{key:"role",value:role}])
const apirole = interaction.guild.roles.cache.find(r => r.id == 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()) APIEvents.onReactionRole("remove","add&remove",apirole,interaction.user,interaction.channel,interaction.guild,new Date())
}) }
})
}else if (mode == "add&remove"){
option.roles.forEach((role) => {
if (interaction.guild.members.cache.find(u => u.id == user.id).roles.cache.has(role)){
interaction.guild.members.cache.find(u => u.id == user.id).roles.remove(role)
log("system","added role (reaction roles)",[{key:"user",value:interaction.user.tag},{key:"role",value:role}])
const apirole = interaction.guild.roles.cache.find(r => r.id == role)
APIEvents.onReactionRole("add","add&remove",apirole,interaction.user,interaction.channel,interaction.guild,new Date())
}else {
interaction.guild.members.cache.find(u => u.id == user.id).roles.add(role)
log("system","removed role (reaction roles)",[{key:"user",value:interaction.user.tag},{key:"role",value:role}])
const apirole = interaction.guild.roles.cache.find(r => r.id == role)
APIEvents.onReactionRole("remove","add&remove",apirole,interaction.user,interaction.channel,interaction.guild,new Date())
}
})
}
}catch{
interaction.channel.send({embeds:[bot.errorLog.serverError(l.errors.somethingWentWrong)]})
} }
}catch{
interaction.channel.send({embeds:[bot.errorLog.serverError(l.errors.somethingWentWrong)]})
} }
}) })
} }
+87
View File
@@ -0,0 +1,87 @@
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)
}
-1
View File
@@ -2,7 +2,6 @@ const discord = require("discord.js")
const bot = require("../../index") const bot = require("../../index")
const client = require("../../index").client const client = require("../../index").client
const config = bot.config const config = bot.config
const getoptions = require("../getoptions")
module.exports = async () => { module.exports = async () => {
const chalk = (await import("chalk")).default const chalk = (await import("chalk")).default
+126 -19
View File
@@ -2,21 +2,22 @@ const discord = require("discord.js")
const bot = require("../../index") const bot = require("../../index")
const client = require("../../index").client const client = require("../../index").client
const config = bot.config const config = bot.config
const getoptions = require("../getoptions") const configParser = require("../utils/configParser")
const act = discord.ApplicationCommandType const act = discord.ApplicationCommandType
const acot = discord.ApplicationCommandOptionType const acot = discord.ApplicationCommandOptionType
module.exports = async () => { /**@param {Boolean|undefined} invisible*/
module.exports = async (invisible) => {
const chalk = (await import("chalk")).default const chalk = (await import("chalk")).default
const sid = config.server_id const sid = config.serverId
const ids = getoptions.getTicketValues("id") const ids = configParser.getTicketValuesArray("id")
/**@type {[{name:String,value:String}]} */ /**@type {[{name:String,value:String}]} */
var choices = [] var choices = []
ids.forEach((id) => { ids.forEach((id) => {
const option = getoptions.getOptionsById(id) const option = configParser.getTicketById(id)
if (option.type == "ticket"){ if (option){
choices.push({name:option.name,value:option.id}) choices.push({name:option.name,value:option.id})
} }
}) })
@@ -29,21 +30,30 @@ module.exports = async () => {
var readystats = 0 var readystats = 0
process.stdout.write("[status] there are "+chalk.blue("0 out of 10")+" commands ready! (this can take up to 40 seconds)") //process.stdout.write("[status] there are "+chalk.blue("0 out of 10")+" commands ready! (this can take up to 40 seconds)")
setInterval(() => { if (!invisible){
process.stdout.cursorTo(0) setInterval(() => {
process.stdout.write("[status] there are "+chalk.blue(readystats+" out of 9")+" commands ready! (this can take up to 40 seconds)") if (process.stdout && process.stdout.cursorTo) process.stdout.cursorTo(0)
if (readystats >= 10){ process.stdout.write("[status] there are "+chalk.blue(readystats+" out of 14")+" commands ready! (this can take up to 40 seconds)")
console.log(chalk.green("\nready!")) if (readystats >= 14){
console.log(chalk.bgBlue("you can now start the bot with 'npm start'!")) console.log(chalk.green("\nready!"))
process.exit(1) console.log(chalk.blue("you can now start the bot with "+chalk.bgBlue("'npm start'")+"!"))
} process.exit(1)
},100) }
},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) //create a ticket (/new or /ticket)
client.application.commands.create({ client.application.commands.create({
name:"ticket", name:"ticket",
description:"Create a ticket!", description:"Create a ticket!",
descriptionLocalizations:ST.newticket,
defaultPermission:true, defaultPermission:true,
type:act.ChatInput, type:act.ChatInput,
options:[ options:[
@@ -53,7 +63,6 @@ module.exports = async () => {
description:"The type of ticket.", description:"The type of ticket.",
required:true, required:true,
choices:choices choices:choices
} }
] ]
},sid).then(() => { },sid).then(() => {
@@ -65,6 +74,7 @@ module.exports = async () => {
description:"Create a ticket!", description:"Create a ticket!",
defaultPermission:true, defaultPermission:true,
type:act.ChatInput, type:act.ChatInput,
descriptionLocalizations:ST.newticket,
options:[ options:[
{ {
type:acot.String, type:acot.String,
@@ -82,8 +92,9 @@ module.exports = async () => {
//help //help
client.application.commands.create({ client.application.commands.create({
name:"help", name:"help",
description:"The help menu", description:"View the available commands.",
defaultPermission:true, defaultPermission:true,
descriptionLocalizations:ST.help,
type:act.ChatInput type:act.ChatInput
},sid).then(() => { },sid).then(() => {
readystats++ readystats++
@@ -95,7 +106,15 @@ module.exports = async () => {
name:"close", name:"close",
description:"Close the current ticket.", description:"Close the current ticket.",
defaultPermission:true, defaultPermission:true,
type:act.ChatInput 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(() => { },sid).then(() => {
readystats++ readystats++
}) })
@@ -105,6 +124,7 @@ module.exports = async () => {
name:"delete", name:"delete",
description:"Delete the current ticket.", description:"Delete the current ticket.",
defaultPermission:true, defaultPermission:true,
descriptionLocalizations:ST.delete,
type:act.ChatInput type:act.ChatInput
},sid).then(() => { },sid).then(() => {
readystats++ readystats++
@@ -115,6 +135,7 @@ module.exports = async () => {
name:"message", name:"message",
description:"Create a ticket message.", description:"Create a ticket message.",
defaultPermission:true, defaultPermission:true,
descriptionLocalizations:ST.message,
type:act.ChatInput, type:act.ChatInput,
options:[ options:[
{ {
@@ -136,6 +157,7 @@ module.exports = async () => {
name:"add", name:"add",
description:"Add people to this ticket.", description:"Add people to this ticket.",
defaultPermission:true, defaultPermission:true,
descriptionLocalizations:ST.add,
type:act.ChatInput, type:act.ChatInput,
options:[ options:[
{ {
@@ -154,6 +176,7 @@ module.exports = async () => {
name:"remove", name:"remove",
description:"Remove people from this ticket.", description:"Remove people from this ticket.",
defaultPermission:true, defaultPermission:true,
descriptionLocalizations:ST.remove,
type:act.ChatInput, type:act.ChatInput,
options:[ options:[
{ {
@@ -172,6 +195,7 @@ module.exports = async () => {
name:"rename", name:"rename",
description:"Rename this ticket.", description:"Rename this ticket.",
defaultPermission:true, defaultPermission:true,
descriptionLocalizations:ST.rename,
type:act.ChatInput, type:act.ChatInput,
options:[ options:[
{ {
@@ -190,9 +214,92 @@ module.exports = async () => {
name:"reopen", name:"reopen",
description:"Reopen this ticket.", description:"Reopen this ticket.",
defaultPermission:true, defaultPermission:true,
descriptionLocalizations:ST.reopen,
type:act.ChatInput type:act.ChatInput
},sid).then(() => { },sid).then(() => {
readystats++ 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++
})
//stats
client.application.commands.create({
name:"stats",
description:"See bot statistics!",
defaultPermission:true,
type:act.ChatInput,
options:[
{
type:acot.Subcommand,
name:"global",
description:"See the global bot stats!"
},
{
type:acot.Subcommand,
name:"ticket",
description:"See the stats of a ticket (use inside of ticket)!"
},
{
type:acot.Subcommand,
name:"user",
description:"See the stats from a user or yourself!",
options:[
{
type:acot.User,
name:"user",
required:false,
description:"See the stats from a specific user!"
}
]
}
]
},sid).then(() => {
readystats++
})
} }
+79
View File
@@ -0,0 +1,79 @@
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:")))
}
+383
View File
@@ -0,0 +1,383 @@
const { EmbedBuilder, Guild, TextChannel, Message, User } = 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 permissionChecker = require("./utils/permisssionChecker")
/**@typedef {"TICKETS_CREATED"|"TICKETS_CLOSED"|"TICKETS_DELETED"|"TICKETS_REOPENED"|"TICKETS_AUTOCLOSED"|"TRANSCRIPTS_CREATED"|"TIME_SINCE_UPDATE"|"LAST_VERSION"} OTGlobalStatsType */
/**@typedef {"CREATED_AT"|"CREATED_BY"|"STATUS"} OTTicketStatsType */
/**@typedef {"TICKETS_CREATED"|"TICKETS_CLOSED"|"TICKETS_DELETED"|"TICKETS_REOPENED"} OTUserStatsType */
/**
* @callback OTStatsCallback
* @param {Boolean|Number|String|undefined} current
* @returns {Boolean|Number|String|undefined}
*/
/**
* @param {OTGlobalStatsType} type
* @param {OTStatsCallback} callback
*/
const updateGlobalStats = (type,callback) => {
const currentstat = bot.statsStorage.get("global",type)
const newstat = callback(currentstat)
if (["string","number","boolean"].includes(typeof newstat)){
bot.statsStorage.set("global",type,newstat)
}
}
/**
* @param {OTTicketStatsType} type
* @param {String} id
* @param {OTStatsCallback} callback
*/
const updateTicketStats = (type,id,callback) => {
const currentstat = bot.statsStorage.get("ticket"+id,type)
const newstat = callback(currentstat)
if (["string","number","boolean"].includes(typeof newstat)){
bot.statsStorage.set("ticket"+id,type,newstat)
}
}
/**
* @param {OTUserStatsType} type
* @param {String} id
* @param {OTStatsCallback} callback
*/
const updateUserStats = (type,id,callback) => {
const currentstat = bot.statsStorage.get("user"+id,type)
const newstat = callback(currentstat)
if (["string","number","boolean"].includes(typeof newstat)){
bot.statsStorage.set("user"+id,type,newstat)
}
}
/**
*
* @param {"global"|"ticket"|"user"} scope
* @param {OTGlobalStatsType|OTTicketStatsType|OTUserStatsType} type
* @param {String} [id]
*/
const removeStats = (scope,type,id) => {
const newScope = (scope == "global") ? scope : scope+id
bot.statsStorage.delete(newScope,type)
}
/**
*
* @param {"global"|"ticket"|"user"} scope
* @param {OTGlobalStatsType|OTTicketStatsType|OTUserStatsType} type
* @param {String} [id]
*/
const existStats = (scope,type,id) => {
const newScope = (scope == "global") ? scope : scope+id
return (typeof bot.statsStorage.get(newScope,type) == "undefined") ? false : true
}
/**
*
* @param {"global"|"ticket"|"user"} scope
* @param {OTGlobalStatsType|OTTicketStatsType|OTUserStatsType} type
* @param {String} [id]
*/
const getStats = (scope,type,id) => {
const newScope = (scope == "global") ? scope : scope+id
return bot.statsStorage.get(newScope,type)
}
const startupStatsManager = () => {
//UPDATE LAST UPDATE DATE
if (!existStats("global","TIME_SINCE_UPDATE")){
updateGlobalStats("TIME_SINCE_UPDATE",(current) => {
return new Date().getTime()
})
updateGlobalStats("LAST_VERSION",(current) => {
return (require("../package.json")).version
})
}
if ((require("../package.json")).version != getStats("global","LAST_VERSION")){
updateGlobalStats("TIME_SINCE_UPDATE",(current) => {
return new Date().getTime()
})
updateGlobalStats("LAST_VERSION",(current) => {
return (require("../package.json")).version
})
}
//UPDATE THE OTHER STATS
if (!existStats("global","TICKETS_CREATED")){
updateGlobalStats("TICKETS_CREATED",(current) => {
return 0
})
}
if (!existStats("global","TICKETS_CLOSED")){
updateGlobalStats("TICKETS_CLOSED",(current) => {
return 0
})
}
if (!existStats("global","TICKETS_DELETED")){
updateGlobalStats("TICKETS_DELETED",(current) => {
return 0
})
}
if (!existStats("global","TICKETS_AUTOCLOSED")){
updateGlobalStats("TICKETS_AUTOCLOSED",(current) => {
return 0
})
}
if (!existStats("global","TICKETS_REOPENED")){
updateGlobalStats("TICKETS_REOPENED",(current) => {
return 0
})
}if (!existStats("global","TRANSCRIPTS_CREATED")){
updateGlobalStats("TRANSCRIPTS_CREATED",(current) => {
return 0
})
}
//HANDLE MEMBER LEAVE (clear the database)
client.on("guildMemberRemove",(member) => {
if (existStats("user","TICKETS_CREATED",member.id)){
removeStats("user","TICKETS_CREATED",member.id)
}
if (existStats("user","TICKETS_CLOSED",member.id)){
removeStats("user","TICKETS_CLOSED",member.id)
}
if (existStats("user","TICKETS_DELETED",member.id)){
removeStats("user","TICKETS_DELETED",member.id)
}
if (existStats("user","TICKETS_REOPENED",member.id)){
removeStats("user","TICKETS_REOPENED",member.id)
}
})
}
/**
* @returns {Promise<{startDate:Number, updateDate:Number, version:String, ticketsCreated:Number, ticketsClosed:Number, ticketsDeleted:Number, ticketsReopened:Number, ticketsAutoclosed:Number, transcriptsCreated:Number}>}
*/
const getGlobalStats = async () => {
//live data
const startDate = new Date().getTime() - client.uptime
const version = (require("../package.json")).version
//saved data
const ticketsCreated = getStats("global","TICKETS_CREATED")
const ticketsClosed = getStats("global","TICKETS_CLOSED")
const ticketsDeleted = getStats("global","TICKETS_DELETED")
const ticketsReopened = getStats("global","TICKETS_REOPENED")
const ticketsAutoclosed = getStats("global","TICKETS_AUTOCLOSED")
const transcriptsCreated = getStats("global","TRANSCRIPTS_CREATED")
const timeSinceUpdate = getStats("global","TIME_SINCE_UPDATE")
return {
startDate,
updateDate: (typeof timeSinceUpdate == "undefined") ? new Date().getTime() : timeSinceUpdate,
version,
ticketsCreated: (typeof ticketsCreated == "undefined") ? 0 : ticketsCreated,
ticketsClosed: (typeof ticketsClosed == "undefined") ? 0 : ticketsClosed,
ticketsDeleted: (typeof ticketsDeleted == "undefined") ? 0 : ticketsDeleted,
ticketsReopened: (typeof ticketsReopened == "undefined") ? 0 : ticketsReopened,
ticketsAutoclosed: (typeof ticketsAutoclosed == "undefined") ? 0 : ticketsAutoclosed,
transcriptsCreated: (typeof transcriptsCreated == "undefined") ? 0 : transcriptsCreated,
}
}
/**
*
* @param {discord.TextChannel} channel
* @param {Number} limit
* @returns {Promise<Message[]>}
*/
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
}
/**
* @param {Guild} guild
* @param {String} channelid
* @returns {Promise<{createdAt:Number, createdBy:String, messageAmount:Number, participants:String[], ticketName:String, status:"open"|"closed"|"reopened"|"autoclosed"}>}
*/
const getTicketStats = async (guild,channelid) => {
//live data
/**@type {TextChannel|undefined} */
const channel = guild.channels.cache.find((c) => c.id == channelid)
const messageAmount = (channel) ? (await getmessages(channel,5000)).length : 0
const participants = (channel) ? channel.members.map((m) => m.user.username) : []
//saved data
const createdAt = getStats("ticket","CREATED_AT",channelid)
const status = getStats("ticket","STATUS",channelid)
const TEMPcreatedBy = getStats("ticket","CREATED_BY",channelid)
const TEMPcreatedByUser = (TEMPcreatedBy) ? guild.members.cache.find((m) => m.id == TEMPcreatedBy) : undefined
const createdBy = (TEMPcreatedByUser) ? TEMPcreatedByUser.user.username : "an unknown person 😄"
return {
createdAt: (typeof createdAt == "undefined") ? new Date().getTime() : createdAt,
createdBy: (typeof createdBy == "undefined") ? 0 : createdBy,
messageAmount,
participants:participants.slice(0,50),
ticketName:channel.name,
status: (typeof status == "undefined") ? "open" : status
}
}
/**
* @param {Guild} guild
* @param {User} user
* @param {String} [channelid]
* @returns {Promise<{ticketsCreated:Number, ticketsClosed:Number, ticketsDeleted:Number, ticketsReopened:Number, role:"globaladmin"|"ticketadmin"|"member", userName:String}>}
*/
const getUserStats = async (guild,user,channelid) => {
//live data
const hiddendata = bot.hiddenData.readHiddenData(channelid)
const ticketId = (hiddendata.length < 1) ? false : hiddendata.find(d => d.key == "type").value
const isGlobalAdmin = permissionChecker.global(user.id,guild.id)
const isTicketAdmin = (ticketId) ? permissionChecker.ticket(user.id,guild.id,ticketId) : false
const role = (isGlobalAdmin) ? "globaladmin" : ((isTicketAdmin) ? "ticketadmin" : "member")
//saved data
const ticketsCreated = getStats("user","TICKETS_CREATED",user.id)
const ticketsClosed = getStats("user","TICKETS_CLOSED",user.id)
const ticketsDeleted = getStats("user","TICKETS_DELETED",user.id)
const ticketsReopened = getStats("user","TICKETS_REOPENED",user.id)
return {
ticketsCreated: (typeof ticketsCreated == "undefined") ? 0 : ticketsCreated,
ticketsClosed: (typeof ticketsClosed == "undefined") ? 0 : ticketsClosed,
ticketsDeleted: (typeof ticketsDeleted == "undefined") ? 0 : ticketsDeleted,
ticketsReopened: (typeof ticketsReopened == "undefined") ? 0 : ticketsReopened,
role,
userName:user.username
}
}
const createGlobalStatsEmbed = async () => {
const stats = await getGlobalStats()
const sentences = [
`${l.stats.ticketsCreated}: \`${stats.ticketsCreated}\``,
`${l.stats.ticketsClosed}: \`${stats.ticketsClosed}\``,
`${l.stats.ticketsDeleted}: \`${stats.ticketsDeleted}\``,
`${l.stats.ticketsReopened}: \`${stats.ticketsReopened}\``,
`${l.stats.ticketsAutoclosed}: \`${stats.ticketsAutoclosed}\``,
`${l.stats.startupDate}: <t:${Math.round(stats.startDate/1000)}:f>`,
`${l.stats.latestUpdate}: <t:${Math.round(stats.updateDate/1000)}:D>`
]
const embed = new EmbedBuilder()
.setColor(config.color)
.setTitle(`📊 ${l.stats.globalTitle}!`)
.setDescription(sentences.slice(0,5).join("\n"))
.addFields({
name:`${l.stats.systemTitle}:`,
value:sentences.slice(5,7).join("\n")
})
.setFooter({text:`${l.stats.versionTitle}: v${stats.version}`})
return embed
}
/**
* @param {Guild} guild
* @param {String} channelid
*/
const createTicketStatsEmbed = async (guild,channelid) => {
const stats = await getTicketStats(guild,channelid)
if (stats.status == "open"){
var newStatus = `🟢 \`${l.stats.switches.open}\``
}else if (stats.status == "reopened"){
var newStatus = `🟢 \`${l.stats.switches.reopened}\``
}else if (stats.status == "closed"){
var newStatus = `🔴 \`${l.stats.switches.closed}\``
}else if (stats.status == "autoclosed"){
var newStatus = `🔴 \`${l.stats.switches.autoclosed}\``
}
const sentences = [
`${l.stats.ticketCreatedOn}: <t:${Math.round(stats.createdAt/1000)}:f>`,
`${l.stats.ticketCreatedBy}: \`${stats.createdBy}\``,
`${l.stats.messagesSent}: \`${stats.messageAmount}\``,
`${l.stats.status}: ${newStatus}`
]
const embed = new EmbedBuilder()
.setColor(config.color)
.setTitle(`📊 ${l.stats.ticketTitle}`.replace("{0}",`#${stats.ticketName}!`))
.setDescription(sentences.join("\n"))
.addFields({
name:`${l.stats.participants}:`,
value:stats.participants.join("\n")
})
return embed
}
/**
* @param {Guild} guild
* @param {User} user
* @param {String} channelid
*/
const createUserStatsEmbed = async (guild,user,channelid) => {
const stats = await getUserStats(guild,user,channelid)
if (stats.role == "globaladmin"){
var newRole = `🟢 \`${l.stats.switches.globalAdmin}\``
}else if (stats.role == "ticketadmin"){
var newRole = `🟡 \`${l.stats.switches.ticketAdmin}\``
}else if (stats.role == "member"){
var newRole = `🔴 \`${l.stats.switches.member}\``
}
const sentences = [
`${l.stats.role}: ${newRole}`,
`${l.stats.ticketsCreated}: \`${stats.ticketsCreated}\``,
`${l.stats.ticketsClosed}: \`${stats.ticketsClosed}\``,
`${l.stats.ticketsDeleted}: \`${stats.ticketsDeleted}\``,
`${l.stats.ticketsReopened}: \`${stats.ticketsReopened}\``
]
const embed = new EmbedBuilder()
.setColor(config.color)
.setTitle(`📊 ${l.stats.userTitle}`.replace("{0}",`${stats.userName}!`))
.setDescription(sentences.join("\n"))
return embed
}
module.exports = {
updateGlobalStats,
updateTicketStats,
updateUserStats,
removeStats,
existStats,
getStats,
startupStatsManager,
getGlobalStats,
getTicketStats,
getUserStats,
createGlobalStatsEmbed,
createTicketStatsEmbed,
createUserStatsEmbed
}
+65
View File
@@ -0,0 +1,65 @@
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)
//STATS
bot.statsManager.updateGlobalStats("TICKETS_AUTOCLOSED",(current) => {
if (typeof current != "undefined") return current+1
return 1
})
bot.statsManager.updateTicketStats("STATUS",channel.id,(current) => {
return "autoclosed"
})
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)
}
+253
View File
@@ -0,0 +1,253 @@
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
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)
//check perms
if (!guild) return
if (!permsChecker.ticket(user.id,guild.id,ticketId)){
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.username},{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)
require("../api/modules/events").onTicketDelete(user,channel,guild,new Date(),{name:channel.name,status:"deleted",ticketOptions:ticketData})
//STATS
bot.statsManager.updateGlobalStats("TICKETS_DELETED",(current) => {
if (typeof current != "undefined") return current+1
return 1
})
bot.statsManager.updateUserStats("TICKETS_DELETED",user.id,(current) => {
if (typeof current != "undefined") return current+1
return 1
})
bot.statsManager.removeStats("ticket","CREATED_BY",channel.id)
bot.statsManager.removeStats("ticket","CREATED_AT",channel.id)
bot.statsManager.removeStats("ticket","STATUS",channel.id)
hiddendata.push({key:"pendingdelete",value:"true"})
bot.hiddenData.writeHiddenData(channel.id,hiddendata)
}else if (mode == "close"){
//close
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)
//check perms
if (config.system.closeMode == "adminonly"){
if (!guild) return
if (!permsChecker.ticket(user.id,guild.id,ticketId)){
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)
}
})
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.username},{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)
//STATS
bot.statsManager.updateGlobalStats("TICKETS_CLOSED",(current) => {
if (typeof current != "undefined") return current+1
return 1
})
bot.statsManager.updateUserStats("TICKETS_CLOSED",user.id,(current) => {
if (typeof current != "undefined") return current+1
return 1
})
bot.statsManager.updateTicketStats("STATUS",channel.id,(current) => {
return "closed"
})
}
/**
*
* @param {discord.TextChannel} channel
* @param {Number} limit
* @returns {Promise<discord.Message[]>}
*/
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()
}
+272
View File
@@ -0,0 +1,272 @@
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()){
try {
await interaction.deferReply({ephemeral:config.system.answerInEphemeralOnOpen})
} catch{}
}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.username}])
require("../api/modules/events").onTicketOpen(interaction.user,ticketChannel,interaction.guild,new Date(),{name:ticketName,status:"open",ticketOptions:currentTicketOptions})
//STATS:
bot.statsManager.updateGlobalStats("TICKETS_CREATED",(current) => {
if (typeof current != "undefined") return current+1
return 1
})
bot.statsManager.updateUserStats("TICKETS_CREATED",interaction.user.id,(current) => {
if (typeof current != "undefined") return current+1
return 1
})
bot.statsManager.updateTicketStats("CREATED_BY",ticketChannel.id,(current) => {
return interaction.user.id
})
bot.statsManager.updateTicketStats("CREATED_AT",ticketChannel.id,(current) => {
return new Date().getTime()
})
bot.statsManager.updateTicketStats("STATUS",ticketChannel.id,(current) => {
return "open"
})
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()){
if (interaction.deferred){
interaction.editReply({embeds:[bot.errorLog.success(l.messages.createdTitle,l.messages.createdDescription)],components:[channelbutton]})
}else{
interaction.reply({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")}
}
}
})
}
+66
View File
@@ -0,0 +1,66 @@
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.username}])
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})
//STATS
bot.statsManager.updateGlobalStats("TICKETS_REOPENED",(current) => {
if (typeof current != "undefined") return current+1
return 1
})
bot.statsManager.updateUserStats("TICKETS_REOPENED",user.id,(current) => {
if (typeof current != "undefined") return current+1
return 1
})
bot.statsManager.updateTicketStats("STATUS",channel.id,(current) => {
return "reopened"
})
}
exports.reopenTicket = reopenTicket
-335
View File
@@ -1,335 +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")
exports.runThis = () => {
client.on("interactionCreate",async (interaction) => {
if (!interaction.isButton()) return
if (interaction.customId != "sendTranscript") return
interaction.deferUpdate()
const channelmessages = await interaction.channel.messages.fetch()
channelmessages.sweep((msgSweep) => {
return msgSweep.author.id == client.user.id
})
var fileattachment = await require("./transcript").createTranscript(channelmessages,interaction.channel)
if (fileattachment == false){
log("system","internal error: transcript is not created!")
interaction.channel.send({embeds:[bot.errorLog.serverError(l.errors.somethingWentWrongTranscript)]})
return
}
interaction.channel.send({content:"**"+l.messages.hereIsTheTranscript+"**",files:[fileattachment]})
})
}
/**
*
* @param {discord.GuildMember} member
* @param {discord.TextChannel} channel
* @param {String} prefix
* @param {"delete"|"close"|"deletenotranscript"} mode
*/
exports.NEWcloseTicket = async (member,channel,prefix,mode) => {
const guild = channel.guild
const user = member.user
const chalk = await (await import("chalk")).default
const channelmessages = await channel.messages.fetch()
//start code
//remove ot bot from transcript
channelmessages.sweep((msgSweep) => {return msgSweep.author.id == client.user.id})
/**@type {String}*/
const channelname = channel.name
const ticketOpenerChannelName = channelname.split(prefix)[1]
//get user that opened the ticket
var getuserID = storage.get("userTicketStorage",channel.id)
try {
var ticketOpener = client.users.cache.find(u => u.id === getuserID)
var isDatabaseError = false
}catch{var isDatabaseError = true}
if (!ticketOpener){
console.log(chalk.red("[database error]"),"something went wrong when getting the data in the database.\nNo panic, this error fixes itself!")
var isDatabaseError = true
}
var enableTranscript = true
var deleteRequired = false
if (mode == "delete"){
//delete
//check perms
if (!guild) return
if (!permsChecker.command(user.id,guild.id)){
permsChecker.sendUserNoPerms(user)
return
}
//start delete proccess
deleteRequired = true
await channel.send({content:"**"+l.messages.gettingdeleted+"**"})
log("system","deleted a ticket",[{key:"user",value:user.tag},{key:"ticket",value:channel.name}])
if (!isDatabaseError) storage.set("ticketStorage",getuserID,Number(storage.get("ticketStorage",getuserID)) - 1)
//getID & send DM & send api event
await channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return false
const ticketId = firstmsg.embeds[0].footer.text.split("Ticket Type: ")[1]
const ticketData = require("./getoptions").getOptionsById("newT"+ticketId)
require("./api/modules/events").onTicketDelete(user,channel,guild,new Date(),{name:channel.name,status:"deleted",ticketOptions:ticketData})
if (!firstmsg.embeds[0].author) return false
const id = firstmsg.embeds[0].author.name
if (!id) return false
try{
if (config.system.enable_DM_Messages){
member.send({embeds:[bot.errorLog.custom(l.messages.deletedTicketDmTitle,l.messages.deletedTicketDmDescription,":ticket:",config.main_color)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
})
}else if (mode == "close"){
//close
//check perms
if (config.system.closeMode == "adminonly"){
if (!guild) return
if (!permsChecker.command(user.id,guild.id)){
permsChecker.sendUserNoPerms(user)
return
}
}
//set new permissions
var permissionArray = []
const pfb = discord.PermissionFlagsBits
if (!isDatabaseError) permissionArray.push({
id:ticketOpener,
type:"member",
allow:[pfb.ViewChannel],
deny:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages]
})
permissionArray.push({
id:guild.roles.everyone,
type:"role",
deny:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
})
//add main adminroles
config.main_adminroles.forEach((role,index) => {
try {
const adminrole = guild.roles.cache.find(r => r.id == role)
if (!adminrole) return
permissionArray.push({
id:adminrole,
type:"role",
allow:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
})
}catch{
log("system","invalid role! At 'config.json => main_adminroles:"+index)
}
})
//add ticket adminroles
await channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return false
const ticketId = firstmsg.embeds[0].footer.text.split("Ticket Type: ")[1]
const ticketData = require("./getoptions").getOptionsById("newT"+ticketId)
if (!ticketData) return
/**
* @type {String[]}
*/
const ticketadmin = ticketData.adminroles
ticketadmin.forEach((role,index) => {
if (!config.main_adminroles.includes(role)){
try {
const adminrole = guild.roles.cache.find(r => r.id == role)
if (!adminrole) return
permissionArray.push({
id:adminrole,
type:"role",
allow:[pfb.AddReactions,pfb.ViewChannel],
deny:[pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages]
})
}catch{
log("system","invalid role! At 'config.json => options/ticket/...:"+index)
}
}
})
})
channel.permissionOverwrites.set(permissionArray)
//message
var closeButtonRow = new discord.ActionRowBuilder()
.addComponents(
new discord.ButtonBuilder()
.setCustomId("deleteTicket1")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Danger)
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("sendTranscript")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setLabel(l.buttons.sendTranscript)
.setEmoji("📄")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("reopenTicket")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Success)
.setLabel(l.buttons.reopen)
.setEmoji("✔")
)
const embed = new discord.EmbedBuilder()
.setColor(config.main_color)
.setTitle(":lock: "+l.messages.closedTitle+" :lock:")
.setDescription(l.messages.closedDescription)
channel.send({embeds:[embed],components:[closeButtonRow]})
log("system","closed a ticket",[{key:"user",value:user.tag},{key:"ticket",value:channel.name}])
//getID & send DM & send api event
await channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return false
const ticketId = firstmsg.embeds[0].footer.text.split("Ticket Type: ")[1]
const ticketData = require("./getoptions").getOptionsById("newT"+ticketId)
require("./api/modules/events").onTicketClose(user,channel,guild,new Date(),{name:channel.name,status:"closed",ticketOptions:ticketData})
const id = firstmsg.embeds[0].author.name
if (!id) return false
try{
if (config.system.enable_DM_Messages){
member.send({embeds:[bot.errorLog.custom(l.messages.closedTicketDmTitle,l.messages.closedTicketDmDescription,":ticket:",config.main_color)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
})
}else if (mode == "deletenotranscript"){
//delete with no transcript
//check perms
if (!guild) return
if (!permsChecker.command(user.id,guild.id)){
permsChecker.sendUserNoPerms(user)
return
}
//start delete proccess
enableTranscript = false
deleteRequired = true
channel.send({content:"**"+l.messages.gettingdeleted+"**"})
log("system","deleted a ticket",[{key:"user",value:user.tag},{key:"ticket",value:channel.name}])
if (!isDatabaseError) storage.set("ticketStorage",getuserID,Number(storage.get("ticketStorage",getuserID)) - 1)
//getID & send DM & send api event
await channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return false
const ticketId = firstmsg.embeds[0].footer.text.split("Ticket Type: ")[1]
const ticketData = require("./getoptions").getOptionsById("newT"+ticketId)
require("./api/modules/events").onTicketDelete(user,channel,guild,new Date(),{name:channel.name,status:"deleted",ticketOptions:ticketData})
const id = firstmsg.embeds[0].author.name
if (!id) return false
try{
if (config.system.enable_DM_Messages){
member.send({embeds:[bot.errorLog.custom(l.messages.deletedTicketDmTitle,l.messages.deletedTicketDmDescription,":ticket:",config.main_color)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
})
}
if (enableTranscript == true && mode != "deletenotranscript"){
if (config.system.enable_transcript || config.system.enable_DM_transcript){
var fileattachment = await require("./transcript").createTranscript(channelmessages,channel)
if (fileattachment == false){log("system","internal error: transcript is not created!");return}
}
if (config.system.enable_transcript){
const transcriptEmbed = new discord.EmbedBuilder()
.setColor(config.main_color)
.setTitle(l.messages.newTranscriptTitle)
.setAuthor({name:user.username,iconURL:user.displayAvatarURL({format:"png"})})
.setDescription(l.messages.newTranscriptDescription)
.setFooter({text:"ticket: "+channelname})
guild.channels.cache.find(c => c.id == config.system.transcript_channel).send({
embeds:[transcriptEmbed],
files:[fileattachment]
})
}
if (config.system.enable_DM_transcript){
const transcriptEmbed = new discord.EmbedBuilder()
.setColor(config.main_color)
.setTitle(l.messages.newTranscriptTitle)
.setDescription(l.messages.newTranscriptDescription)
.setFooter({text:"ticket: "+channelname})
if (!isDatabaseError) ticketOpener.send({
embeds:[transcriptEmbed],
files:[fileattachment]
})
}
}
if (deleteRequired){
const timer = () => {return new Promise((resolve,reject) => {
setTimeout(() => {resolve(true)},7000)
})}
await timer()
await channel.delete()
}
}
-98
View File
@@ -1,98 +0,0 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const getButton = require("./utils/getButton")
const l = bot.language
/**
*
* @param {String} id the id from an open-ticket embed
* @returns {{embed:discord.EmbedBuilder,componentRows:discord.MessageActionRow[]}} discord embed
*/
exports.createEmbed = (id) => {
//-----------------------------------
//general importing
const data = require("./utils/getTicketMessages").getTicketMessage(id)
/**@type {discord.ButtonBuilder[]}*/
var buttons = []
/**@type {getButton.rawButtonData[]} */
var buttonData = []
data.options.forEach((option) => {
var button = getButton.getButton(option)
var localButtonData = getButton.getOption(option)
if (button) buttons.push(button)
if (localButtonData) buttonData.push(localButtonData)
})
//-----------------------------------
//-----------------------------------
//create the embed
const embed = new discord.EmbedBuilder()
.setTitle(data.name)
if (data.enableFooter) embed.setFooter({text:data.footer})
if (data.enableThumbnail) embed.setThumbnail(data.thumbnail)
if (data.enableCustomColor){
embed.setColor(data.color)
}else{
embed.setColor(config.main_color)
}
var description = data.description
if (data.enableTicketExplaination){
description = description+"\n\n__"+l.messages.chooseCategory+"__\n"
var ticketExplainations = []
buttonData.forEach((button) => {
var explaination = button.icon+" **"+button.name+":**\n"+button.description
ticketExplainations.push(explaination)
})
description = description+ticketExplainations.join("\n\n")
}
if (data.enableMaxTicketsWarning){
description = description+"\n\n"+l.commands.maxTicketWarning.replace("{0}",config.system.max_allowed_tickets)
}
embed.setDescription(description)
//-----------------------------------
//-----------------------------------
//create the components
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
}
})
//-----------------------------------
//return everything
/**
* @type {{embed:discord.EmbedBuilder,componentRows:discord.MessageActionRow[]}}
*/
const returnedData = {embed:embed,componentRows:componentRows}
return returnedData
}
-208
View File
@@ -1,208 +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 getconfigoptions = require("./getoptions")
const storage = bot.storage
module.exports = () => {
var closeButton = new discord.ActionRowBuilder()
.addComponents(
new discord.ButtonBuilder()
.setCustomId("closeTicket")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setLabel(l.buttons.close)
.setEmoji("🔒")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("deleteTicket")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Danger)
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
//ticket button click / create ticket
client.on("interactionCreate",(interaction) => {
if (interaction.isChatInputCommand() && (interaction.commandName == "new" || interaction.commandName == "ticket")){
var customId = "newT"+interaction.options.getString("type")
}else if (interaction.isButton()){
var customId = interaction.customId
}else return
if (interaction.isButton()){
if (interaction.customId.startsWith("newT")){
const optionid = interaction.customId.split("newT")[1]
if (!optionid){
interaction.reply({embeds:[bot.errorLog.serverError(l.errors.ticketDoesntExist)]})
return
}
}
}
if (getconfigoptions.getTicketValues("id").includes(customId)){
//ticketoptions from config
const currentTicketOptions = getconfigoptions.getOptionsById(customId)
if (currentTicketOptions == false || currentTicketOptions.type != "ticket") return interaction.reply({embeds:[bot.errorLog.serverError(l.errors.anotherOption)]})
if (interaction.isButton()){
interaction.deferUpdate()
}else if (interaction.isChatInputCommand()){
interaction.reply({embeds:[bot.errorLog.success(l.messages.createdTitle,l.messages.createdDescription)]})
}
if (storage.get("ticketStorage",interaction.member.id) == null || storage.get("ticketStorage",interaction.member.id) == "false"|| Number(storage.get("ticketStorage",interaction.member.id)) < config.system.max_allowed_tickets){
try{
if (config.system.enable_DM_Messages){
interaction.member.send({embeds:[bot.errorLog.custom(l.messages.newTicketDmTitle,currentTicketOptions.message,":ticket:",config.main_color)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
//update storage
storage.set("ticketStorage",interaction.member.id,Number(storage.get("ticketStorage",interaction.member.id))+1)
var ticketNumber = interaction.member.user.username
//set ticketName
var ticketName = currentTicketOptions.channelprefix+ticketNumber
var logsname = currentTicketOptions.name
//category
if (currentTicketOptions.category.length < 16 || currentTicketOptions.category.length > 20){
var newTicketCategory = null
}else{
var newTicketCategory = currentTicketOptions.category
}
var permissionsArray = []
const pfb = discord.PermissionFlagsBits
const guild = client.guilds.cache.find(g => g.id == interaction.guild.id)
//set everyone allowed
if (config.system['has@everyoneaccess']){
var everyoneAllowPerms = [pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
var everyoneDenyPerms = []
}else{
var everyoneAllowPerms = []
var everyoneDenyPerms = [pfb.ViewChannel]
}
permissionsArray.push({
id:interaction.guild.roles.everyone,
type:"role",
allow:everyoneAllowPerms,
deny:everyoneDenyPerms
})
//add the user that created the ticket
permissionsArray.push({
id:interaction.member.user,
type:"member",
allow:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
})
//add main adminroles
config.main_adminroles.forEach((role,index) => {
try {
const adminrole = guild.roles.cache.find(r => r.id == role)
if (!adminrole) return
permissionsArray.push({
id:adminrole,
type:"role",
allow:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
})
}catch{
log("system","invalid role! At 'config.json => main_adminroles:"+index)
}
})
//add ticket adminroles
/**
* @type {String[]}
*/
const ticketadmin = currentTicketOptions.adminroles
ticketadmin.forEach((role,index) => {
if (!config.main_adminroles.includes(role)){
try {
const adminrole = guild.roles.cache.find(r => r.id == role)
if (!adminrole) return
permissionsArray.push({
id:adminrole,
type:"role",
allow:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
})
}catch{
log("system","invalid role! At 'config.json => options/ticket/...:"+index)
}
}
})
//add member role
if (config.system.member_role != "" && config.system.member_role != " " && config.system.member_role != "false" && config.system.member_role != "null" && config.system.member_role != "0"){
try {
const userrole = guild.roles.cache.find(r => r.id == config.system.member_role)
if (!userrole) return
permissionsArray.push({
id:userrole,
type:"role",
deny:[pfb.ViewChannel]
})
}catch{
log("system","invalid role! At 'config.json => system/member_role")
}
}
//create the channel
interaction.guild.channels.create({
name:ticketName,
type:discord.ChannelType.GuildText,
parent:newTicketCategory,
reason:"A new ticket is created",
permissionOverwrites:permissionsArray
}).then((ticketChannel) => {
storage.set("userTicketStorage",ticketChannel.id,interaction.member.id)
var ticketEmbed = new discord.EmbedBuilder()
.setAuthor({name:interaction.user.id})
.setColor(config.main_color)
.setTitle(currentTicketOptions.name)
.setFooter({text:"Ticket Type: "+currentTicketOptions.id})
if (currentTicketOptions.ticketmessage.length > 0) ticketEmbed.setDescription(currentTicketOptions.ticketmessage)
ticketChannel.send({
content:"<@"+interaction.member.id+"> @here",
embeds:[ticketEmbed],
components:[closeButton]
}).then(firstmsg => {
firstmsg.pin()
})
log("system","created new ticket",[{key:"ticket",value:ticketName},{key:"user",value:interaction.user.tag}])
require("./api/modules/events").onTicketOpen(interaction.user,ticketChannel,interaction.guild,new Date(),{name:ticketName,status:"open",ticketOptions:currentTicketOptions})
})
}else{
try {
if (config.system.enable_DM_Messages){
interaction.member.send({embeds:[bot.errorLog.warning(l.errors.maxAmountTitle,l.errors.maxAmountDescription)]})
}
}
catch{log("system","can't send DM to member, member doesn't allow dm's")}
}
}
})
}
-212
View File
@@ -1,212 +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 = () => {
var closeRowNormal = new discord.ActionRowBuilder()
.addComponents(
new discord.ButtonBuilder()
.setCustomId("closeTicket")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setLabel(l.buttons.close)
.setEmoji("🔒")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("deleteTicket")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Danger)
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
var closeRowClosed = new discord.ActionRowBuilder()
.addComponents(
new discord.ButtonBuilder()
.setCustomId("deleteTicket1")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Danger)
.setLabel(l.buttons.delete)
.setEmoji("✖️")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("sendTranscript")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setLabel(l.buttons.sendTranscript)
.setEmoji("📄")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("reopenTicket")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Success)
.setLabel(l.buttons.reopen)
.setEmoji("✔")
)
var reopenBar = new discord.ActionRowBuilder()
.addComponents(
new discord.ButtonBuilder()
.setCustomId("reopenTicketTrue")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setEmoji("✅")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("reopenTicketFalse")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setEmoji("❌")
)
var reopenBar1 = new discord.ActionRowBuilder()
.addComponents(
new discord.ButtonBuilder()
.setCustomId("reopenTicketTrue1")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setEmoji("✅")
)
.addComponents(
new discord.ButtonBuilder()
.setCustomId("reopenTicketFalse1")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setEmoji("❌")
)
var reopenCommandBar = new discord.ActionRowBuilder()
.addComponents(
new discord.ButtonBuilder()
.setCustomId("reopenTicket1")
.setDisabled(false)
.setStyle(discord.ButtonStyle.Secondary)
.setEmoji("🔓")
)
/**
*
* @param {discord.Guild} guild
* @param {discord.TextBasedChannel} channel
* @param {discord.User} user
* @returns
*/
const reopenTicket = (guild,channel,user) => {
log("system","re-opened a ticket",[{key:"ticket",value:channel.name},{key:"user",value:user.tag}])
var permissionsArray = []
//set everyone allowed
if (config.system['has@everyoneaccess']){
var everyoneAllowPerms = [pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel]
var everyoneDenyPerms = []
}else{
var everyoneAllowPerms = []
var everyoneDenyPerms = [pfb.ViewChannel]
}
permissionsArray.push({
id:guild.roles.everyone,
type:"role",
allow:everyoneAllowPerms,
deny:everyoneDenyPerms
})
channel.permissionOverwrites.cache.forEach((p) => {
if (p.type == "member"){
permissionsArray.push({
id:p.id,
type:"member",
allow:[pfb.AddReactions,pfb.AttachFiles,pfb.EmbedLinks,pfb.SendMessages,pfb.ViewChannel],
deny:[]
})
}
})
channel.permissionOverwrites.set(permissionsArray)
require("./api/modules/events").onTicketReopen(user,channel,guild,new Date(),{name:channel.name,status:"reopened",ticketOptions:false})
}
//NORMAL WAY
client.on("interactionCreate",(interaction) => {
if (!interaction.isButton()) return
if (interaction.customId != "reopenTicket") return
interaction.deferUpdate()
interaction.message.edit({components:[reopenBar]})
})
client.on("interactionCreate",(interaction) => {
if (!interaction.isButton()) return
if (interaction.customId != "reopenTicketFalse") return
interaction.deferUpdate()
interaction.message.edit({components:[closeRowClosed]})
})
const pfb = discord.PermissionFlagsBits
client.on("interactionCreate",(interaction) => {
if (!interaction.isButton()) return
if (interaction.customId != "reopenTicketTrue") return
interaction.deferUpdate()
const embed = new discord.EmbedBuilder()
.setColor(config.main_color)
.setTitle(":unlock: "+l.messages.reopenTitle+" :unlock:")
.setDescription(l.messages.reopenDescription)
interaction.message.edit({embeds:[embed],components:[closeRowNormal]})
reopenTicket(interaction.guild,interaction.channel,interaction.user)
})
//COMMAND WAY
client.on("interactionCreate",(interaction) => {
if (!interaction.isButton()) return
if (interaction.customId != "reopenTicket1") return
interaction.deferUpdate()
interaction.message.edit({components:[reopenBar1]})
})
client.on("interactionCreate",(interaction) => {
if (!interaction.isButton()) return
if (interaction.customId != "reopenTicketFalse1") return
interaction.deferUpdate()
interaction.message.edit({components:[reopenCommandBar]})
})
client.on("interactionCreate",(interaction) => {
if (!interaction.isButton()) return
if (interaction.customId != "reopenTicketTrue1") return
interaction.deferUpdate()
const embed = new discord.EmbedBuilder()
.setColor(config.main_color)
.setTitle(":unlock: "+l.messages.reopenTitle+" :unlock:")
.setDescription(l.messages.reopenDescription)
interaction.message.edit({content:null,embeds:[embed],components:[closeRowNormal]})
reopenTicket(interaction.guild,interaction.channel,interaction.user)
})
}
-74
View File
@@ -1,74 +0,0 @@
const discord = require('discord.js')
const bot = require('../index')
const client = bot.client
const config = bot.config
const l = bot.language
/** @param {discord.TextBasedChannel} channel @returns {Promise<{ticketname:String,ticketopener:{discordjsuser:discord.User,name:String,id:String}>} */
const getUserInfo = (channel) => {
return new Promise((promiseresolve,reject) => {
//getID
var result = {
ticketopener:{
discordjsuser:"",
id:"/",
name:"/"
},
ticketname:"/"
}
channel.messages.fetchPinned().then(msglist => {
var firstmsg = msglist.last()
if (firstmsg == undefined || firstmsg.author.id != client.user.id) return false
const id = firstmsg.embeds[0].author.name ? firstmsg.embeds[0].author.name : false
result.ticketopener.id = id
const ticketopener = client.users.cache.find(u => u.id == id)
const name = ticketopener.tag
const channelname = channel.name
promiseresolve({ticketname:channelname,ticketopener:{discordjsuser:ticketopener,name:name,id:id}})
})
})
}
/**
*
* @param {discord.Message[]} messagecollection
* @param {discord.Channel} channel
* @returns new `discord.attachmentBuilder`
*/
exports.createTranscript = async (messagecollection,channel) => {
const ticketuserdata = await getUserInfo(channel)
require("./api/modules/events").onTranscriptCreation(messagecollection,channel,channel.guild,new Date())
try {
const cd = new Date()
const months = ["January","February","March","April","May","June","July","August","September","October","November","December"]
const dateString = cd.getDate()+" "+months[cd.getMonth()-1]+" "+cd.getFullYear()+" - "+cd.getSeconds()+":"+cd.getMinutes()+":"+cd.getHours()
const filearray = ["open ticket transcript:\ntranscript creation: "+dateString+"\nticket name: "+ticketuserdata.ticketname+"\nticket opener: "+ticketuserdata.ticketopener.name,"\nTRANSCRIPT START:"]
messagecollection.reverse()
messagecollection.forEach((msg) => {
const timestamp = new Date(msg.createdTimestamp)
if (msg.content){var content = msg.content}else{var content = "*empty message*"}
const msgstats = "files: "+msg.attachments.size+", embeds: "+msg.embeds.length
filearray.push("["+timestamp.getDate()+"/"+timestamp.getMonth()+"/"+timestamp.getFullYear()+", "+timestamp.getHours()+":"+timestamp.getMinutes()+":"+timestamp.getSeconds()+"|"+msg.author.tag+"] ["+msgstats+"]\n"+content+"\n")
})
if (filearray.length < 2) filearray.push("transcript is empty")
const filestring = filearray.join("\n")
const filebuff = Buffer.from(filestring,"utf-8")
return new discord.AttachmentBuilder(filebuff,{name:"transcript_"+ticketuserdata.ticketname+".txt",description:"An Open Ticket transcript"})
}catch(err){
console.log("[error] "+err)
return false
}
}
@@ -0,0 +1,123 @@
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.username,
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.username,
closedbyid:Number(user.id),
closedtime:data.ticket.closedtime,
openedtime:data.ticket.openedtime,
messages:Array.from(messages).length-invisibleMessages,
files:fileAmount
},
messages:messagesArray
}
return result
}
@@ -0,0 +1,395 @@
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}, favicon:{enableCustomFavicon:Boolean, imageUrl: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.username,
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
const dsf = data.style.favicon
/**@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 || "transcripts.dj-dj.be/favicon.png"
},
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.username,
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:dsf.enableCustomFavicon,
image:(dsf.imageUrl) ? dsf.imageUrl : "https://openticket.dj-dj.be"
},
additionalFlags:[]
}
}
return result
}
@@ -0,0 +1,29 @@
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://apis.dj-dj.be/transcripts/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)
}
})
}
@@ -0,0 +1,57 @@
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
@@ -0,0 +1,78 @@
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.username,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.username,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.username,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
@@ -0,0 +1,3 @@
{
"version":"2"
}
+203
View File
@@ -0,0 +1,203 @@
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())
bot.statsManager.updateGlobalStats("TRANSCRIPTS_CREATED",(current) => {
if (typeof current != "undefined") return current+1
return 1
})
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 tsf = tsconfig.style.favicon
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
},
favicon:{
enableCustomFavicon:tsf.enableCustomFavicon,
imageUrl:tsf.imageUrl
}
},
bot:{
name:client.user.username,
id:client.user.id,
pfp:client.user.displayAvatarURL(),
},
ticket:{
creatorid:ticketopener.id,
creatorname:ticketopener.username,
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]})
}
if (tsconfig.sendTranscripts.enableDM && user){
const embed = tsembeds.tsready(chName,chId,null,user)
try {
ticketopener.send({embeds:[embed],files:[attachment]})
}catch{}
}
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]})
}
if (tsconfig.sendTranscripts.enableDM && user){
const embed = tsembeds.tsready(chName,chId,null,user)
try {
ticketopener.send({embeds:[embed],files:[attachment]})
}catch{}
}
}
}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]})
}
if (tsconfig.sendTranscripts.enableDM && user){
const embed = tsembeds.tsready(chName,chId,null,user)
try {
ticketopener.send({embeds:[embed],files:[attachment]})
}catch{}
}
}
}
asyncmanager()
}
+60
View File
@@ -0,0 +1,60 @@
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.username+"] ["+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
@@ -0,0 +1,71 @@
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
@@ -0,0 +1,188 @@
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
}
-3
View File
@@ -1,3 +0,0 @@
/**
* @typedef {String|Boolean} OTErrorType
*/
+25 -40
View File
@@ -1,24 +1,27 @@
const discord = require("discord.js") const discord = require("discord.js")
const bot = require("../../index") const bot = require("../../index")
const config = bot.config const config = bot.config
const getoptions = require("../getoptions")
const l = bot.language const l = bot.language
const b = discord.ButtonStyle
/**@returns {"DANGER"|"SUCCESS"|"PRIMARY"|"SECONDARY"} */ /**
* @param {String} color
* @returns {"DANGER"|"SUCCESS"|"PRIMARY"|"SECONDARY"} */
const getColor = (color) => { const getColor = (color) => {
const b = discord.ButtonStyle if (color){
if (color.toLowerCase() == "red"){ if (color.toLowerCase() == "red"){
return b.Danger return b.Danger
}else if (color.toLowerCase() == "green"){ }else if (color.toLowerCase() == "green"){
return b.Success return b.Success
}else if (color.toLowerCase() == "blue" || color.toLowerCase() == "blurple"){ }else if (color.toLowerCase() == "blue" || color.toLowerCase() == "blurple"){
return b.Primary return b.Primary
}else if (color.toLowerCase() == "black" || color.toLowerCase() == "gray" || color.toLowerCase() == "grey"){ }else if (color.toLowerCase() == "black" || color.toLowerCase() == "gray" || color.toLowerCase() == "grey"){
return b.Secondary return b.Secondary
}else if (color == "DANGER" || color == "SECONDARY" || color == "SUCCESS" || color == "PRIMARY"){ }else if (color.toUpperCase() == "DANGER" || color.toUpperCase() == "SECONDARY" || color.toUpperCase() == "SUCCESS" || color.toUpperCase() == "PRIMARY"){
return color return color
}else if (color.toLowerCase() == "none" || color.toLowerCase() == "false" || color.toLowerCase() == ""){ }else if (color.toLowerCase() == "none" || color.toLowerCase() == "false" || color.toLowerCase() == ""){
return b.Secondary return b.Secondary
}else return b.Secondary
}else return b.Secondary }else return b.Secondary
} }
@@ -33,11 +36,17 @@ exports.getOption = getOption
* @returns {discord.ButtonBuilder|false} * @returns {discord.ButtonBuilder|false}
*/ */
exports.getButton = (id) => { 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) const option = getOption(id)
if (!option) return false if (!option) return false
if (option.type == "ticket"){ if (option.type == "ticket"){
var button = new discord.ButtonBuilder() var button = new discord.ButtonBuilder()
.setCustomId("newT"+option.id) .setCustomId("OTnewT"+option.id)
.setDisabled(false) .setDisabled(false)
.setStyle(getColor(option.color)) .setStyle(getColor(option.color))
@@ -68,28 +77,4 @@ exports.getButton = (id) => {
} }
return button return button
}
exports.rawButtonData = class {
constructor() {
this.id = ""
this.name = ""
this.description = ""
this.icon = ""
this.label = ""
this.type = ""
this.color = ""
this.enableDMMessage = true
this.url = ""
this.roles = ["",""]
this.mode = ""
this.adminroles = ["",""]
this.channelprefix = ""
this.category = ""
this.message = ""
this.ticketmessage = ""
}
} }
+70
View File
@@ -0,0 +1,70 @@
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 && option.description.length < 100) 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
@@ -0,0 +1,138 @@
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
}
-16
View File
@@ -1,16 +0,0 @@
const bot = require("../../index")
const config = bot.config
const l = bot.language
exports.getTicketMessage = (input) => {
var returned = config.messages.find(a => a.id == input)
if (returned){
return returned
}
var result = config.messages[0]
if (!result){
throw new Error("'messages' object in config.json is empty")
return
}
return result
}
+49
View File
@@ -0,0 +1,49 @@
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 []
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
}
}
+137
View File
@@ -0,0 +1,137 @@
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://apis.dj-dj.be/livestatus/announcements/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"))
}
+107 -7
View File
@@ -12,21 +12,60 @@ const storage = bot.storage
* @param {String} guildid * @param {String} guildid
* @returns {Boolean} has permissions? * @returns {Boolean} has permissions?
*/ */
exports.command = (memberid,guildid) => { exports.global = (memberid,guildid) => {
bot.actionRecorder.push({
category:"ot.managers.permissionChecker",
file:"./core/permissionChecker.js",
time:new Date().getTime(),
type:"global"
})
const permsmember = client.guilds.cache.find(g => g.id == guildid).members.cache.find(m => m.id == memberid) const permsmember = client.guilds.cache.find(g => g.id == guildid).members.cache.find(m => m.id == memberid)
if (config.main_adminroles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("Administrator") && !permsmember.permissions.has("ManageGuild")){ if (config.adminRoles.some((item)=>{return permsmember.roles.cache.has(item)}) == false && !permsmember.permissions.has("Administrator") && !permsmember.permissions.has("ManageGuild")){
return false return false
}else {return true} }else {return true}
} }
/**
*
* @param {String} memberid
* @param {String} guildid
* @param {String} optionid
* @returns {Boolean} has permissions?
*/
exports.ticket = (memberid,guildid,optionid) => {
bot.actionRecorder.push({
category:"ot.managers.permissionChecker",
file:"./core/permissionChecker.js",
time:new Date().getTime(),
type:"ticket"
})
const option = config.options.find((opt) => opt.id == optionid)
const ticketadmins = option && option.adminroles ? option.adminroles : []
const permsmember = client.guilds.cache.find(g => g.id == guildid).members.cache.find(m => m.id == memberid)
const isGlobalAdmin = config.adminRoles.some((item)=>{return permsmember.roles.cache.has(item)})
const isTicketAdmin = ticketadmins.some((item)=>{return permsmember.roles.cache.has(item)})
const hasAdministrator = permsmember.permissions.has("Administrator")
const hasManageGuild = permsmember.permissions.has("ManageGuild")
return isGlobalAdmin || isTicketAdmin || hasAdministrator || hasManageGuild
}
/** /**
* *
* @param {discord.User} user * @param {discord.User} user
* @returns {Boolean} * @returns {Boolean}
*/ */
exports.sendUserNoPerms = (user) => { exports.sendUserNoPerms = (user) => {
bot.actionRecorder.push({
category:"ot.managers.permissionChecker",
file:"./core/permissionChecker.js",
time:new Date().getTime(),
type:"sendusernoperms"
})
try { try {
user.send({embeds:[bot.errorLog.noPermsMessage]}) user.send({embeds:[bot.errorLog.noPermsMessage(user)]})
return true return true
}catch{ }catch{
return false return false
@@ -39,6 +78,12 @@ exports.sendUserNoPerms = (user) => {
* @returns {Boolean} * @returns {Boolean}
*/ */
exports.sendUserNoTicket = (user) => { exports.sendUserNoTicket = (user) => {
bot.actionRecorder.push({
category:"ot.managers.permissionChecker",
file:"./core/permissionChecker.js",
time:new Date().getTime(),
type:"sendusernoticket"
})
try { try {
user.send({embeds:[bot.errorLog.notInATicket]}) user.send({embeds:[bot.errorLog.notInATicket]})
return true return true
@@ -49,12 +94,18 @@ exports.sendUserNoPerms = (user) => {
/** /**
* *
* @param {discord.TextChannel} channel * @param {discord.User} user
* @returns {Boolean} * @returns {Boolean}
*/ */
exports.sendChannelNoPerms = (channel) => { exports.sendUserNoDelete = (user) => {
bot.actionRecorder.push({
category:"ot.managers.permissionChecker",
file:"./core/permissionChecker.js",
time:new Date().getTime(),
type:"sendusernodelete"
})
try { try {
channel.send({embeds:[bot.errorLog.noPermsMessage]}) user.send({embeds:[bot.errorLog.noPermsDelete(user)]})
return true return true
}catch{ }catch{
return false return false
@@ -64,9 +115,37 @@ exports.sendUserNoPerms = (user) => {
/** /**
* *
* @param {discord.TextChannel} channel * @param {discord.TextChannel} channel
* @param {discord.User} user
* @returns {Boolean} * @returns {Boolean}
*/ */
exports.sendChannelNoTicket = (channel) => { 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 { try {
channel.send({embeds:[bot.errorLog.notInATicket]}) channel.send({embeds:[bot.errorLog.notInATicket]})
return true return true
@@ -74,3 +153,24 @@ exports.sendUserNoPerms = (user) => {
return false 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
}
}
+339 -75
View File
@@ -1,16 +1,45 @@
// __________ __________ ___________ ____ ____ /**
// / ____ \ / ______ \ / | | \ | | ____ _____ ______ _ _ _______ _____ _____ _ ________ _______
// | / \ | | | | | | |_______| | \ | | / __ \| __ \| ____| \ | | |__ __|_ _/ ____| |/ / ____|__ __|
// | | | | | |____| | | | | |\ \ | | | | | | |__) | |__ | \| | | | | || | | ' /| |__ | |
// | | | | | ________/ | |______ | | \ \ | | | | | | ___/| __| | . ` | | | | || | | < | __| | |
// | | | | | | | _____| | | \ \ | | | |__| | | | |____| |\ | | | _| || |____| . \| |____ | |
// | | | | | | | | | | \ \ | | \____/|_| |______|_| \_| |_| |_____\_____|_|\_\______| |_|
// | | | | | | | |________ | | \ \| |
// | \____/ | | | | | | | \ | Hey! we are looking for you!
// \__________/ |__| \__________| |__| \___| Do you speak a language that isn't yet in our /languages directory
or do you speak one that isn't up-to-date? Open Ticket needs
translators for lots of different languages!
Feel free to join our translator team and help us improve Open Ticket!
const discord = require('discord.js')
SUGGESTING NEW FEATURES:
=====================
Open Ticket is an open-source community project!
Because of this, almost 80% of all features in OT were ideas from our community!
Feel free to add new ideas in our discord server
or via github issues! Translations are always welcome!
INFORMATION:
============
Open Ticket v3.5.3 - © DJdj Development
discord: https://discord.dj-dj.be
website: https://www.dj-dj.be
github: https://otgithub.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 fs = require('fs')
const {GatewayIntentBits,Partials} = discord const {GatewayIntentBits,Partials} = discord
const client = new discord.Client({ const client = new discord.Client({
@@ -25,113 +54,233 @@ const client = new discord.Client({
partials:[Partials.Channel,Partials.Message] partials:[Partials.Channel,Partials.Message]
}) })
exports.client = client exports.client = client
client.setMaxListeners(100)
if (process.argv.some((v) => v == "--debug")) console.log("[TEMP_DEBUG]","created client")
client.setMaxListeners(30) //LOAD CONFIG
var tempconfig = require("./config.json")
/**@type {Boolean} */
var isDevConfig = false
if (process.argv[2]){ if (process.argv.some((v) => v == "--devconfig")){
if (process.argv[2].endsWith("d")){ isDevConfig = true
var isDev = true try{
console.log("starting in dev mode...") tempconfig = require("./devconfig.json")
}else{var isDev = false} }catch{tempconfig = require("./config.json")}
}else{var isDev = false} }else{
tempconfig = require("./config.json")
}
if (process.argv.some((v) => v == "--debug")) console.log("[TEMP_DEBUG]","loaded flags")
exports.developerMode = isDev exports.developerConfig = isDevConfig
const config = tempconfig
exports.config = config
const tsconfig = isDevConfig ? require("./devtsconfig.json") : require("./transcriptconfig.json")
exports.tsconfig = tsconfig
//LOAD LANGUAGE
const language = require("./core/languageManager").language const language = require("./core/languageManager").language
exports.language = language exports.language = language
if (isDev){ //LOAD FLAGS
try { if (process.argv.some((v) => v == "--debug")) console.log("[TEMP_DEBUG]","loaded language")
var config = require('./devConfig.json')
}catch{
console.log("devConfig.json not found! Trying the normal config...")
var config = require("./config.json")
}
}else{var config = require('./config.json')}
exports.config = config
exports.errorLog = require("./core/errorLogSystem")
const log = this.errorLog.log
if (process.argv.some((v) => v == "--debug")) console.log("[TEMP_DEBUG]","loaded config")
exports.storage = require('./core/dynamicdatabase/storage').main
if (process.argv.some((v) => v == "--debug")) console.log("[TEMP_DEBUG]","loaded storage")
exports.statsStorage = require('./core/dynamicdatabase/storage').stats
if (process.argv.some((v) => v == "--debug")) console.log("[TEMP_DEBUG]","loaded stats 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")
//LOAD SYSTEM LIBRARYS
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")
exports.statsManager = require("./core/statsManager")
this.statsManager.startupStatsManager()
//START CLIENT LOGIN PROCESS
client.on('ready',async () => { client.on('ready',async () => {
var statusSet = false 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"
})
const setStatus = (type,text) => { const setStatus = (type,text) => {
if (statusSet == true) return const getTypeEnum = (type) => {
const getTypeEnum = (text) => { if (type.toLowerCase() == "playing") return discord.ActivityType.Playing
if (text.toLowerCase() == "playing") return discord.ActivityType.Playing else if (type.toLowerCase() == "listening") return discord.ActivityType.Listening
else if (text.toLowerCase() == "listening") return discord.ActivityType.Listening else if (type.toLowerCase() == "watching") return discord.ActivityType.Watching
else if (text.toLowerCase() == "watching") return discord.ActivityType.Watching else if (type.toLowerCase() == "custom") return discord.ActivityType.Custom
else return discord.ActivityType.Listening else return discord.ActivityType.Listening
} }
client.user.setActivity(text,{type:getTypeEnum(type)}) client.user.setActivity({
statusSet = true type:getTypeEnum(type),
log("system","loaded status",[{key:"type",value:type},{key:"text",value:text}]) state:(text.toLowerCase() == "custom") ? text : undefined,
name:text
})
} }
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 const chalk = await (await import("chalk")).default
if (!process.argv[2]){ require("./core/startscreen").run()
console.log(chalk.red("WELCOME TO OPEN TICKET!")) this.actionRecorder.push({
log("info","open ticket ready",[{key:"version",value:require("./package.json").version},{key:"language",value:config.languagefile}]) category:"ot.managers.main",
file:"index.js",
time:new Date().getTime(),
type:"startscreen.success"
})
if (!process.argv[2] || (process.argv[2] && !process.argv[2].startsWith("slash"))){
//normal start
this.errorLog.log("debug","loaded console interface")
console.log(chalk.blue("\n\nlogs:")+"\n============")
if (config.status.enabled){ if (config.status.enabled){
setStatus(config.status.type,config.status.text) setStatus(config.status.type,config.status.text)
} }
log("system","bot logged in!") this.actionRecorder.push({
category:"ot.managers.main",
file:"index.js",
time:new Date().getTime(),
type:"startmode.normal"
})
await client.guilds.cache.find((g) => g.id == config.server_id).members.fetch() var updatingSlash = false
return 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
if (process.argv[2] == "d"){ }else if ((data != require("./package.json").version) && (data != "false")){
if (config.status.enabled){ require("./core/slashSystem/slashEnable")(true)
setStatus(config.status.type,config.status.text) 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"
})
if (!process.argv[2].startsWith("slash")){ try {
console.log(chalk.red("WELCOME TO OPEN TICKET!")) await client.guilds.cache.find((g) => g.id == config.serverId).members.fetch()
log("info","open ticket ready",[{key:"version",value:require("./package.json").version},{key:"language",value:config.languagefile}]) }catch{
this.errorLog.log("info","tried to cache user information, failed!")
console.log(chalk.blue("\n\nlogs:")+"\n============")
if (config.status.enabled){
setStatus(config.status.type,config.status.text)
} }
require("./core/startscreen").headerDataReady(chalk,config.status,updatingSlash,false)
log("system","bot logged in!")
await client.guilds.cache.find((g) => g.id == config.server_id).members.fetch()
}else{ }else{
console.log(chalk.red("STARTING IN ")+chalk.blue("SLASH MODE")+chalk.red("...")) //slash command activation using node index.js slash (enable|disable)
console.log("logs:\n================") require("./core/startscreen").headerDataReady(chalk,config.status,updatingSlash,true)
console.log("client logged in...") this.errorLog.log("debug","slashmode activated")
console.log("loading files...")
if (process.argv[3] == "enable"){ if (process.argv[3] == "enable"){
console.log(chalk.green("switching to slashEnable.js")) 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")() require("./core/slashSystem/slashEnable")()
}else if (process.argv[3] == "disable"){ }else if (process.argv[3] == "disable"){
console.log(chalk.green("switching to slashDisable.js")) 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")() require("./core/slashSystem/slashDisable")()
}else{ }else{
console.log(chalk.red("Internal Error: unknown slash mode!")) console.log(chalk.bgRed("[SLASH CMD MANAGER]: unknown slash command action!"))
process.exit(1) process.exit(1)
} }
} }
//load plugins //LOAD PLUGINS (after client login)
this.actionRecorder.push({
category:"ot.managers.plugins",
file:"./core/api/pluginlauncher.js",
time:new Date().getTime(),
type:"plugins.loading"
})
require("./core/api/pluginlauncher")() 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 (!isDev){ //LOAD CHECKER.JS
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() 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"
})
} }
//LOAD COMMANDS & CORE
if (process.argv[2] && process.argv[2].startsWith("slash")){ if (process.argv[2] && process.argv[2].startsWith("slash")){
//do nothing //do nothing
}else{ }else{
var storage = require('./core/dynamicdatabase/storage')
exports.storage = storage
this.actionRecorder.push({
category:"ot.managers.loader",
file:"./index.js",
time:new Date().getTime(),
type:"commands.loading"
})
this.errorLog.log("debug","LOADING COMMANDS")
//commands //commands
require('./commands/ticket')() require('./commands/ticket')()
require("./commands/help")() require("./commands/help")()
@@ -141,26 +290,83 @@ if (process.argv[2] && process.argv[2].startsWith("slash")){
require("./commands/add")() require("./commands/add")()
require("./commands/remove")() require("./commands/remove")()
require("./commands/reopen")() require("./commands/reopen")()
require("./commands/claim")()
require("./commands/unclaim")()
require("./commands/change")()
require("./commands/stats")()
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 //core
require('./core/ticketOpener')() require('./core/ticketActions/ticketOpener')()
require("./core/ticketCloser").runThis()
require("./core/closebuttons")()
require("./core/reactionRoles")() require("./core/reactionRoles")()
require("./core/ticketReopener")() 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"
})
} }
//LOAD API
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 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"
})
//ERROR SYSTEM
this.actionRecorder.push({
category:"ot.managers.loader",
file:"./index.js",
time:new Date().getTime(),
type:"debugsystem.loading"
})
const debugLog = (debugString) => { 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==========================" const content = fs.existsSync("./openticketdebug.txt") ? fs.readFileSync("./openticketdebug.txt").toString() : "==========================\n<OPEN TICKET DEBUG FILE:>\n=========================="
fs.writeFileSync("./openticketdebug.txt",content+"\nDEBUG: "+debugString) fs.writeFileSync("./openticketdebug.txt",content+"\nDEBUG: "+debugString)
}
this.errorLog.clearDebugFile()
} }
const errorLog = (errorString,stack) => { 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==========================" 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) 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) => { client.on("debug", async (message) => {
if (message.startsWith("Provided token:")){ if (message.startsWith("Provided token:")){
@@ -178,4 +384,62 @@ process.on("uncaughtException",async (error,origin) => {
APIEvents.onError(error.name+": "+error.message,new Date()) APIEvents.onError(error.name+": "+error.message,new Date())
}) })
client.login(config.auth_token) this.actionRecorder.push({
category:"ot.managers.loader",
file:"./index.js",
time:new Date().getTime(),
type:"debugsystem.success"
})
//PARSE .env FILE FROM DOTENV LIB
//npm i dotenv
//https://github.com/motdotla/dotenv
/**@param {Buffer} src */
const loadFromDotEnv = (src) => {
const LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg
const obj = {}
// Convert buffer to string
let lines = src.toString()
// Convert line breaks to same format
lines = lines.replace(/\r\n?/mg, '\n')
let match
while ((match = LINE.exec(lines)) != null) {
const key = match[1]
// Default undefined or null to empty string
let value = (match[2] || '')
// Remove whitespace
value = value.trim()
// Check if double quoted
const maybeQuote = value[0]
// Remove surrounding quotes
value = value.replace(/^(['"`])([\s\S]*)\1$/mg, '$2')
// Expand newlines if double quoted
if (maybeQuote === '"') {
value = value.replace(/\\n/g, '\n')
value = value.replace(/\\r/g, '\r')
}
// Add to object
obj[key] = value
}
process.env.TOKEN = obj.TOKEN
}
//LOGIN SYSTEM
if (config.token.fromENV){
loadFromDotEnv(fs.readFileSync(".env"))
client.login(process.env.TOKEN)
}else{
client.login(config.token.value)
}
this.errorLog.log("debug","login with token")
+123 -68
View File
@@ -1,80 +1,135 @@
{ {
"errors":{ "_CREDITS":"deqressing",
"missingArgsTitle":"حجج باطلة", "_INFO":"This file is a translation for open ticket 3.5.3",
"missingArgsDescription":"حجة مفقودة",
"noPermsTitle":"ليس لديك إذن", "errors": {
"noPermsDescription":"ليس لديك إذن لاستخدام هذا\nأنت بحاجة إلى إذن 'ADMINISTRATOR' أو أن تكون في قائمة الأدوار المسموح بها!", "missingArgsTitle": "قيمة غير صالحة!",
"chooseFromListTitle":"بطاقة التعريف غير صالحة", "missingArgsDescription": "قيمة مفقودة",
"chooseFromListDescription":"اختر أحد المعرفات أدناه:", "noPermsTitle": "ليس لديك برمشنات !",
"boterror":"مشكلة في الروبوت", "noPermsDescription": "أنت بحاجة الى برمشن `ADMINISTRATOR` او أن تكون في قائمة المسموح بهم!",
"notInTicketTitle":"أنت لست في تذكرة!", "noPermsDelete": "فقط الإداريين يمكنهم حذف التيكت!",
"notInTicketDescription":"هذا الأمر لا يعمل خارج التذاكر!", "chooseFromListTitle": "الايدي غير صحيح!",
"ticketDoesntExist":"هذه التذكرة لم تعد موجودة!", "chooseFromListDescription": "قم بأختيار أحد من الأيديات من الأسفل:",
"roleDoesntExist":"هذا الدور لم يعد موجودًا!", "boterror": "خلل في البوت !",
"anotherOption":"هذا الخيار ليس تذكرة بل نوع آخر!", "notInTicketTitle": "انت لست في تكت!",
"maxAmountTitle":"بلغ الحد الأقصى!", "notInTicketDescription": "هذا الأمر لا يعمل خارج التيكت!",
"maxAmountDescription":"لقد وصلت إلى الحد الأقصى لعدد التذاكر المسموح بها!\nلذلك لا يمكنك إنشاء واحدة جديدة!", "ticketDoesntExist": "هذا التيكت لم يعد فعال!",
"somethingWentWrong":"**هناك خطأ ما!**\nالرجاء المحاولة مرة أخرى!", "roleDoesntExist": "خطاً ,لم تعد الرتبة موجوده!",
"somethingWentWrongTranscript":"**حدث خطأ ما أثناء كتابة النص!**\nالرجاء المحاولة مرة أخرى!" "anotherOption": "هذا الخيار ليس التيكت و لكنه شيء أخر!",
"maxAmountTitle": "خطأ , تم الوصول الى الحد الأقصى!",
"maxAmountDescription": "لقد وصلت الى الحد الأقصى لعدد التيكتات المسموحة بها!\nSo لا يمكنك فتح واحدة أخرى!",
"somethingWentWrong": "**هناك خطاً!**\nأعد المحاولة لاحقاً!"
}, },
"commands":{ "commands": {
"userAddedTitle":"تمت إضافة المستخدم!", "userAddedTitle": "تم أضافة {0} من المستخدمين في التيكت!",
"userAddedDescription":"{0} يضاف إلى هذه التذكرة!", "userRemovedTitle": "تم أزالة {0} من المستخدمين من التيكت!",
"userRemovedTitle":"تمت إزالة المستخدم!", "renameTitle": "تم تغيير أسم التيكت الى {0}!",
"userRemovedDescription":"{0} تمت إزالته من هذه التذكرة!", "closeTitle": "تم أغلاق التيكت!",
"deleteTitle": " جاري حذف التيكت...",
"reopenTitle": "إعادة فتح التيكت!",
"claimTitle":"تم تعيين التيكت الى {0}",
"unclaimTitle":"هذا التيكت لم يتم تعيينه لاحد",
"changeTitle":"!تم تغيير نوع التيكت الى {0}",
"renameTitle":"تم تغيير الاسم!", "statsTitle":"ها هي احصائيات {0}",
"renameWarning":"تحذير: يمكنك فقط تغيير اسم القناة مرتين في الدقيقة!\n(هذا يرجع إلى حدود معدل الخلاف)", "autocloseTitle":"سيتم اغلاق التيكت تلقائيا في {0}",
"autocloseRejectTitle":"تم الغاء اغلاق التيكت تلقائيا",
"autocloseWarn":"هذا يؤثر فقط على التذاكر الغير نشطة",
"closeTitle":"أغلق هذه التذكرة!", "goToTicket":"الذهاب الى التيكت",
"closeDescription":"يمكنك إغلاق هذه التذكرة بالضغط على الزر أدناه!", "ticketWarning": "هذا الأمبد موجود بالفعل في الرسالة بالأسفل!",
"deleteTitle":"احذف هذه التذكرة!", "maxTicketWarning": "**تحذير:** _يمكنك فقط فتح {0} تكت في الوقت!_"
"deleteDescription":"يمكنك حذف هذه التذكرة بالضغط على الزر أدناه!",
"reopenTitle":"أعد فتح هذه التذكرة!",
"reopenDescription":"يمكنك إعادة فتح هذه التذكرة بالضغط على الزر أدناه!",
"ticketWarning":"التضمين في الرسالة أدناه!",
"maxTicketWarning":"**تحذير:** _يمكنك فقط إنشاء ملفات {0} تذكرة في كل مرة!_"
}, },
"helpMenu":{ "helpMenu": {
"title":"قائمة التعليمات:", "title": "الأوامر المتاحة:",
"header1":"**اذهب إلى {0} لإنشاء تذكرة!**\n\n", "header1": "**أذهب الى {0} لإنشاء تذكرة!**\n\n",
"header2":"**قم بتشغيل الأمر `/new` أو `/ticket` لإنشاء تذكرة!**\n\n", "header2": "**قم بكتابة أمر `/new` او `/ticket` لفتح تكت!**\n\n",
"msgCmd":"تفرخ تضمين مع الأزرار. (المسؤولون فقط)", "msgCmd": "أنشاء أيمبد مع الأزرار. (الأداريين فقط)",
"renameCmd":"إعادة تسمية تذكرة. (بدون مسافات)", "renameCmd": "إعادة تسمية التيكت. (بدون مسافات)",
"closeCmd":"أغلق التذكرة.", "closeCmd": "أغلاق التيكت.",
"deleteCmd":"حذف التذكرة.", "deleteCmd": "حذف التيكت.",
"addCmd":"أضف مستخدمًا إلى التذكرة.", "addCmd": "إضافة مستخدم الى التيكت.",
"removeCmd":"إزالة مستخدم من التذكرة.", "removeCmd": "إزالة مستخدم من التيكت.",
"reopenCmd":"أعد فتح التذكرة بعد إغلاقه." "reopenCmd": "إعادة فتح تكت بعد إغلاقة.",
"changeCmd":"تغيير نوع التيكت.",
"claimCmd":"تعيينك لتيكت معين.",
"unclaimCmd":"الغاء التغيين لتيكت معين",
"statsCmd":"اضهار احصائيات التيكت",
"autocloseCmd":"قم بضبط مؤقت لاغلاق التيكت تلقائياً"
}, },
"buttons":{ "buttons": {
"close":"إغلاق التذكرة", "close": "إغلاق التيكت",
"delete":"حذف التذكرة", "delete": "حذف التيكت",
"reopen":"إعادة فتح التذكرة", "reopen": "إعادة فتح التيكت",
"sendTranscript":"إرسال ملف النص" "closeWithReason":"اغلاق مع سبب"
}, },
"messages":{ "messages": {
"reopenTitle":"أعيد فتح هذه التذكرة!", "closedDescription": "فقط الأداريين يمكنهم التحدث في هذا التيكت الأن!\n\n*أضغط على الزر بالأسفل لحذف التيكت او إعادة فتحة مجدداً!*",
"reopenDescription":"لا تتردد في التحدث مرة أخرى!", "createdTitle": "تم إنشاء تكت!",
"closedTitle":"أغلقت هذه التذكرة!", "createdDescription": "تم أنشاء تكت , قم بأنتظار الدعم في الطريق!",
"closedDescription":"يمكن للمسؤولين فقط التحدث في هذه التذكرة الآن!\n\n*انقر فوق الزر أدناه لحذف هذه التذكرة أو إعادة فتحها!*",
"createdTitle":"تم إنشاء التذكرة!",
"createdDescription":"تم إنشاء تذكرتك ، يمكنك اكتشافها عن طريق ping",
"newTicketDmTitle":"تذكرة جديدة!", "newTicketDmTitle": "تكت جديد!",
"closedTicketDmTitle":"تم إغلاق التذكرة!", "closedTicketDmTitle": "تم إغلاق التيكت!",
"deletedTicketDmTitle":"تم حذف التذكرة!", "deletedTicketDmTitle": "تم حذف التيكت!",
"closedTicketDmDescription":"تم إغلاق تذكرتك!", "closedTicketDmDescription": "تم أغلاق تذكرتك من قبل إداري",
"deletedTicketDmDescription":"تم حذف تذكرتك!", "deletedTicketDmDescription": "تم حذف تذكرتك من قبل إداري!",
"reopenTicketDmTitle":"أعيد فتح التذكرة!", "reopenTicketDmTitle": "تم إعادة فتح تذكرتك!",
"reopenTicketDmDescription":"تم إعادة فتح تذكرتك!", "reopenTicketDmDescription": "تم إعادة فتح التيكت!",
"newTranscriptTitle":"نسخة جديدة هنا!",
"newTranscriptDescription":"يمكنك العثور على النص في الملف النصي أعلاه!", "chooseCategory": "أختر الكتقاجوري:",
"hereIsTheTranscript":"هذا هو النص:", "gettingdeleted": "يتم حذف التيكت...",
"chooseCategory":"اختر فئة:", "none": "لا يوجد",
"gettingdeleted":"...يتم حذف التذكرة" "reason": "سبب",
"createdat":"تم الانشاء في",
"openedby":"تم الانشاء من قبل",
"deletedby":"تم الحذف من قبل",
"closedby":"تم الاغلاق من قبل",
"modalreason":"ماهو سببك لاغلاق التيكت؟",
"chooseATicket": "اختار تيكت معين"
},
"transcripts":{
"title":"سجل",
"processed":"يتم معالجة هذا السجل...",
"wait":"فضلا انتظر",
"estimated":"الوقت المتوقع",
"available":"تم انشاء السجل وهو متاح هنا"
},
"stats":{
"globalTitle":"احصائيات العامه",
"ticketTitle":"احصائيات التيكت ل {0}",
"userTitle":"احصائيات المستخدم {0}",
"systemTitle":"احصائيات السيستم",
"versionTitle":"نسخة البوت",
"ticketsCreated":"التيكتس التي تمت انشاؤه",
"ticketsClosed":"التيكتس التي تمت اغلاقه",
"ticketsDeleted":"التيكتس التي تمت حذفه",
"ticketsReopened":"التيكتس التي تمت العادة فتحه",
"ticketsAutoclosed":"التيكتس التي تمت اغلاقه تلقائيا",
"transcriptsCreated":"السجلات التي تمت انشاؤه",
"startupDate":"تم تشغيل البوت في",
"latestUpdate":"اخر التحديثات",
"ticketCreatedOn":"تم انشاءالتيكت في",
"ticketCreatedBy":"تم انشاء التيكت من قبل",
"messagesSent":"جميع الرسائل",
"status":"الحالة",
"participants":"المشاركون",
"role":"الرانك",
"switches":{
"globalAdmin":"ادمن عام",
"ticketAdmin":"ادمن تيكت",
"member":"عضو",
"open":"مفتوح",
"reopened":"اعادة فتحه",
"closed":"مغلق",
"autoclosed":"مغلق تلقائياً"
},
"errorUserNotFound":"هذا المستخدم لم يتم العثور عليه في قاعدة بياناتنا!"
} }
} }
+81 -26
View File
@@ -1,9 +1,13 @@
{ {
"_CREDITS":"DJdj Development",
"_INFO":"This file is a translation for open ticket 3.5.3",
"errors":{ "errors":{
"missingArgsTitle":"Invalid Arguments!", "missingArgsTitle":"Invalid Arguments!",
"missingArgsDescription":"Missing Argument", "missingArgsDescription":"Missing Argument",
"noPermsTitle":"No Permissions!", "noPermsTitle":"No Permissions!",
"noPermsDescription":"You don't have the correct roles to run this command!\nYou need the `ADMINISTRATOR` permission or be in the list of allowed roles!", "noPermsDescription":"You need the `ADMINISTRATOR` permission or be in the list of allowed roles!",
"noPermsDelete":"Only admins can delete a ticket!",
"chooseFromListTitle":"Invalid ID", "chooseFromListTitle":"Invalid ID",
"chooseFromListDescription":"Choose one of the id's below:", "chooseFromListDescription":"Choose one of the id's below:",
"boterror":"Bot Error!", "boterror":"Bot Error!",
@@ -14,30 +18,31 @@
"anotherOption":"This option is not a ticket but another type!", "anotherOption":"This option is not a ticket but another type!",
"maxAmountTitle":"Max amount reached!", "maxAmountTitle":"Max amount reached!",
"maxAmountDescription":"You reached the maximum number of tickets allowed!\nSo you can't create a new one!", "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!", "somethingWentWrong":"**Something went wrong!**\nPlease try again another time!"
"somethingWentWrongTranscript":"Something went wrong while making the transcript!**\nPlease try again another time!"
}, },
"commands":{ "commands":{
"userAddedTitle":"User Added!", "userAddedTitle":"Added {0} to this ticket!",
"userAddedDescription":"{0} is added to this ticket!", "userRemovedTitle":"Removed {0} from this ticket!",
"userRemovedTitle":"User Removed!", "renameTitle":"Changed the name to {0}!",
"userRemovedDescription":"{0} is removed from this ticket!", "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}!",
"renameTitle":"The name is changed!", "statsTitle":"Here are the stats for {0}!",
"renameWarning":"Warning: you can only change the channel name 2 times per minute!\n(this is due discord rate limits)", "autocloseTitle":"This ticket will be closed automatically after {0}!",
"autocloseRejectTitle":"This ticket will no longer be closed automatically!",
"closeTitle":"Close this ticket!", "autocloseWarn":"This only affects inactive tickets!",
"closeDescription":"You can close this ticket by clicking on the button below!",
"deleteTitle":"Delete this ticket!",
"deleteDescription":"You can delete this ticket by clicking on the button below!",
"reopenTitle":"Re-Open this ticket!",
"reopenDescription":"You can re-open this ticket by clicking on the button below!",
"goToTicket":"go to ticket",
"ticketWarning":"The embed is in the message below!", "ticketWarning":"The embed is in the message below!",
"maxTicketWarning":"**Warning:** _You can only create {0} ticket(s) at a time!_" "maxTicketWarning":"**Warning:** _You can only create {0} ticket(s) at a time!_"
}, },
"helpMenu":{ "helpMenu":{
"title":"Help Menu:", "title":"Available Commands:",
"header1":"**Go to {0} to create a ticket!**\n\n", "header1":"**Go to {0} to create a ticket!**\n\n",
"header2":"**Run the command `/new` or `/ticket` to create a ticket!**\n\n", "header2":"**Run the command `/new` or `/ticket` to create a ticket!**\n\n",
@@ -47,18 +52,20 @@
"deleteCmd":"Delete a ticket.", "deleteCmd":"Delete a ticket.",
"addCmd":"Add a user to the ticket.", "addCmd":"Add a user to the ticket.",
"removeCmd":"Remove a user from the ticket.", "removeCmd":"Remove a user from the ticket.",
"reopenCmd":"Re-Open a ticket after it was closed." "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":{ "buttons":{
"close":"Close Ticket", "close":"Close Ticket",
"delete":"Delete Ticket", "delete":"Delete Ticket",
"reopen":"Re-Open Ticket", "reopen":"Re-Open Ticket",
"sendTranscript":"Send Transcript File" "closeWithReason":"close with reason"
}, },
"messages":{ "messages":{
"reopenTitle":"Re-Opened this ticket!",
"reopenDescription":"Feel free to talk again!",
"closedTitle":"Closed this ticket!",
"closedDescription":"Only admins can talk in this ticket now!\n\n*Click on the button below to delete or to re-open this ticket!*", "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!", "createdTitle":"Ticket Created!",
"createdDescription":"Your ticket is created, you can detect it by a ping!", "createdDescription":"Your ticket is created, you can detect it by a ping!",
@@ -70,11 +77,59 @@
"deletedTicketDmDescription":"Your ticket is deleted!", "deletedTicketDmDescription":"Your ticket is deleted!",
"reopenTicketDmTitle":"Ticket Re-opened!", "reopenTicketDmTitle":"Ticket Re-opened!",
"reopenTicketDmDescription":"Your ticket is re-opened!", "reopenTicketDmDescription":"Your ticket is re-opened!",
"newTranscriptTitle":"A new transcript is here!",
"newTranscriptDescription":"You can find the transcript in the text file above!",
"hereIsTheTranscript":"Here is the transcript:",
"chooseCategory":"choose a category:", "chooseCategory":"choose a category:",
"gettingdeleted":"Ticket is getting deleted..." "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"
},
"stats":{
"globalTitle":"Global Stats",
"ticketTitle":"Ticket Stats for {0}",
"userTitle":"User Stats for {0}",
"systemTitle":"System Stats",
"versionTitle":"Bot Version",
"ticketsCreated":"Tickets Created",
"ticketsClosed":"Tickets Closed",
"ticketsDeleted":"Tickets Deleted",
"ticketsReopened":"Tickets Reopened",
"ticketsAutoclosed":"Tickets Autoclosed",
"transcriptsCreated":"Transcripts Created",
"startupDate":"Startup Date",
"latestUpdate":"Latest Update",
"ticketCreatedOn":"Ticket Created On",
"ticketCreatedBy":"Ticket Created By",
"messagesSent":"Messages Sent",
"status":"Status",
"participants":"Participants",
"role":"Role",
"switches":{
"globalAdmin":"Global Admin",
"ticketAdmin":"Ticket Admin",
"member":"Member",
"open":"Open",
"reopened":"Reopened",
"closed":"Closed",
"autoclosed":"Autoclosed"
},
"errorUserNotFound":"This user can't be found in the stats database!"
} }
} }
+134 -78
View File
@@ -1,79 +1,135 @@
{ {
"errors":{ "_CREDITS":"spyeye_",
"missingArgsTitle":"Neplatné argumenty", "_INFO":"This file is a translation for open ticket 3.5.3",
"missingArgsDescription":"Chybí argumenty",
"noPermsTitle":"Nemáš práva!", "errors":{
"noPermsDescription":"Nemáš dostatečné práva na tento příkaz!\n Potřebuješ ADMINISTRATOR aby jsi mohl provést příkaz!", "missingArgsTitle":"Neplatný Argument!",
"chooseFromListTitle":"Neplatné ID", "missingArgsDescription":"Chybí Argument",
"chooseFromListDescription":"Vyber si z těchto ID:", "noPermsTitle":"K tomuto nemáš práva!",
"boterror":"Error!", "noPermsDescription":"Potřebuješ `ADMINISTRATOR`roli nebo být na seznamu povolených rolí!",
"notInTicketTitle":"Nejsi v ticketu!", "noPermsDelete":"Pouze Admin může vymazat ticket!",
"notInTicketDescription":"Tento příkaz nefunguje mimo tickety!", "chooseFromListTitle":"Neplatné ID",
"ticketDoesntExist":"Tento ticket už bohužel neexistuje!", "chooseFromListDescription":"Vyber si jedno z ID níže:",
"roleDoesntExist":"Tato role bohužel neexistuje!", "boterror":"Chyba Bota!",
"anotherOption":"Tato možnost není ticket ale něco jiného!", "notInTicketTitle":"Nejsi v ticketu!",
"maxAmountTitle":"Maximální počet ticketů dosažen!", "notInTicketDescription":"Tento příkaz nefunguje mimo ticket!",
"maxAmountDescription":"Dosáhl jsi maximálního povoleného počtu ticketů!\n Nemůžeš si vytvořit nový!", "ticketDoesntExist":"Tento ticket už neexistuje!",
"somethingWentWrong":"**Něco je špatně**\nProsím zkus to příště znovu!", "roleDoesntExist":"Tato role už neexistuje!",
"somethingWentWrongTranscript":"Něco je špatně s transcriptem!**\nProsím zkus to příště znovu!" "anotherOption":"Tato možnost není ticket, ale jiná!",
}, "maxAmountTitle":"Byl dosáhnut maximální počet",
"commands":{ "maxAmountDescription":"Dosáhl jsi maximální počet povolených ticketů!\nTaže si nemůžeš vytvořit nový.",
"userAddedTitle":"Uživatel přidán!", "somethingWentWrong":"**Něco se pokazilo!**\nProsíme zkuste to později!"
"userAddedDescription":"{0} je přidán do ticketu!", },
"userRemovedTitle":"Uživatel odebrán!", "commands":{
"userRemovedDescription":"{0} je odstraněn z ticketu!", "userAddedTitle":"Přidat {0} do tohoto ticketu.",
"userRemovedTitle":"Odstranit {0} z tohoto ticketu.",
"renameTitle":"Jméno bylo změněno!", "renameTitle":"Změnit jméno na {0}!",
"renameWarning":"Varování: jméno kanálu můžeš změnit pouze 2x za minutu!", "closeTitle":"Uzavřít tento ticket!",
"deleteTitle":"Probíhá vymazání ticketu...",
"closeTitle":"Zavři tento ticket!", "reopenTitle":"Ticket byl znovu otevřen",
"closeDescription":"Můžeš zavřít ticket kliknutím na tlačítko níže!",
"deleteTitle":"Smaž tento ticket!", "claimTitle":"Ticket nyní převzal {0}",
"deleteDescription":"Můžeš smazat ticket kliknutím na tlačítko níže!", "unclaimTitle":"Ticket není nadále převzaný",
"reopenTitle":"Znovu otevři ticket!", "changeTitle":"Typ ticketu byl změněn {0}!",
"reopenDescription":"Můžeš znovu otevřít tento ticket kliknutínm na tlačítko níže!",
"statsTitle":"Zde jsou informace o ticketu {0}!",
"ticketWarning":"The embed is in the message below!", "autocloseTitle":"Tento ticketu bude automaticky uzavřen za {0}!",
"maxTicketWarning":"**Varovaní:** _Můžeš si vytvořit použe {0} ticket(s) v jednu chvíli!_" "autocloseRejectTitle":"Tento ticket již nebude automaticky uzavřen!",
}, "autocloseWarn":"Tato možnost uzavře pouze neaktivní tickety!",
"helpMenu":{
"title":"Příkazy:", "goToTicket":"Jít do ticketu",
"header1":"**Běž {0} vytvořit si ticket!**\n\n", "ticketWarning":"Embed se náchází pod touto zprávou.",
"header2":"**Použij příkaz `/new` nebo `/ticket` k vytvoření ticketu!**\n\n", "maxTicketWarning":"**Warning:** _V tuto chvíli můžeš vytvořit pouze {0} ticketů_"
},
"msgCmd":"Vytvoř možnost otevírat tickety přes tlačítko. (ADMIN)", "helpMenu":{
"renameCmd":"Přejmenovat ticket. (Žádné mezery)", "title":"Zde jsou všechny dostupné příkazy:",
"closeCmd":"Zavři ticket.", "header1":"**Pro vytvoření ticketu bež do {0} **\n\n",
"deleteCmd":"Smaž ticket.", "header2":"**Použíj příkaz `/nový` nebo `/ticket` pro vytvoření nového ticketu**\n\n",
"addCmd":"Přidej člena do ticketu.",
"removeCmd":"Odebere člena z ticketu.", "msgCmd":"Vytvoř embed s tlačíky. (Pouze Admin)",
"reopenCmd":"Znovu otevři ticket po uzavření." "renameCmd":"Přejmenovat ticket. (Bez mezer)",
}, "closeCmd":"Zavřít ticket.",
"buttons":{ "deleteCmd":"Odstranit ticket.",
"close":"Zavři ticket", "addCmd":"Pridat uživatele do ticketu.",
"delete":"Smaž ticket", "removeCmd":"Odebrat uživatele z ticketu.",
"reopen":"Znovu otevři ticket", "reopenCmd":"Znovu otevře ticket, který byl uzavřen.",
"sendTranscript":"Odešli log ticketu" "changeCmd":"Změnit typ ticketu.",
}, "claimCmd":"Převzi ticket.",
"messages":{ "unclaimCmd":"Uvolnit ticket.",
"reopenTitle":"Ticket znovu otevřen!", "statsCmd":"Zobrazit info o ticketu.",
"reopenDescription":"Cítím se skvěle že si můžeme zase povídat!", "autocloseCmd":"Nastavit automatické uzavření ticketu"
"closedTitle":"Zavřený ticket!", },
"closedDescription":"Pouze admin team zde může nyní komunikovat!\n\n*Klikni na tlačítko níže pro smazání nebo znovu otevření ticketu!*", "buttons":{
"createdTitle":"Ticket vytvořen!", "close":"Uzavřít ticket",
"createdDescription":"Váš tiket je vytvořen, můžete ho zjistit pomocí pingu!", "delete":"Vymazat ticket",
"reopen":"Znovu otevřít ticket",
"newTicketDmTitle":"Nový ticket!", "closeWithReason":"Zzavřít s důvodem"
"closedTicketDmTitle":"Ticket uzavřen!", },
"deletedTicketDmTitle":"Ticket smazán!", "messages":{
"closedTicketDmDescription":"Tvůj ticket byl uzavřen!", "closedDescription":"Zde mohou psát pouze Admin uživatelé\n\n*Klikni na tlačítko níže pro smazání nebo pro znovu otevření tohoto ticketu!*",
"deletedTicketDmDescription":"Tvůj ticket byl smazán!", "createdTitle":"Ticket otevřen!",
"reopenTicketDmTitle":"Ticket znovu otevřen!", "createdDescription":"Tvůj ticket je vytvořem, můžeš si ho všimnout pomocí pingu!",
"reopenTicketDmDescription":"Tvůj ticket byl znovu otevřen!",
"newTranscriptTitle":"Nový log ticketu je zde!", "newTicketDmTitle":"Nový ticket!",
"newTranscriptDescription":"Zde najdeš log svého ticketu!", "closedTicketDmTitle":"Ticket byl Uzavřen!",
"hereIsTheTranscript":"Zde je log:", "deletedTicketDmTitle":"Ticket byl Odstraněn!",
"closedTicketDmDescription":"Tvůj ticket je uzavřen!",
"chooseCategory":"Vyber kategorii:" "deletedTicketDmDescription":"Tvůj ticket byl vymazán!",
} "reopenTicketDmTitle":"Ticket je znovu otevřený!",
"reopenTicketDmDescription":"Tvuj ticket byl znovu ovetřený!",
"chooseCategory":"Vyber si kategorii:",
"gettingdeleted":"Ticket bude vymazán...",
"none":"Žádný",
"reason":"Důvod",
"createdat":"Otevřeno v",
"openedby":"Otevřel",
"deletedby":"Vymázáno uživatelem",
"closedby":"Uzavřeno uživatelem",
"modalreason":"Zde napiš důvod uzavření tohoto ticketu.",
"chooseATicket": "Vyber si ticket"
},
"transcripts":{
"title":"Záznam",
"processed":"Tento záznam byl zpracován",
"wait":"Prosím počkej!",
"estimated":"Odhadovaný čas",
"available":"Záloha je uložena zde!"
},
"stats":{
"globalTitle":"Globální statistiky",
"ticketTitle":"Ticket statistiky pro {0}",
"userTitle":"Uživatelské statistiky pro {0}",
"systemTitle":"Sytstémov= statistiky",
"versionTitle":"Verze bota",
"ticketsCreated":"Ticketů vytvořeno:",
"ticketsClosed":"Tickety zavřeno:",
"ticketsDeleted":"Ticketu smazáno:",
"ticketsReopened":"Ticketů znovuotevřených:",
"ticketsAutoclosed":"Ticketů automaticky zavřeno:",
"transcriptsCreated":"Záloh ticketů vytvořeno:",
"startupDate":"Datum zapnutí",
"latestUpdate":"Poslední aktualizace",
"ticketCreatedOn":"Ticket založen na",
"ticketCreatedBy":"Ticket vytvořil",
"messagesSent":"Zpráva poslána",
"status":"Status",
"participants":"Účastníci",
"role":"Role",
"switches":{
"globalAdmin":"Globální Admin",
"ticketAdmin":"Ticket Admin",
"member":"Člen",
"open":"Otevřený",
"reopened":"Znovuotevřený",
"closed":"Zavřený",
"autoclosed":"Automaticky zavřený"
},
"errorUserNotFound":"Tento uživatel nebyl nalezen v databázi statistik!"
}
} }
+135
View File
@@ -0,0 +1,135 @@
{
"_CREDITS":"the_gamer#5095",
"_INFO":"This file is a translation for open ticket 3.5.3",
"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"
},
"stats":{
"globalTitle":"Globale Statestikker",
"ticketTitle":"Ticket Statestikker tilhørende: {0}",
"userTitle":"Bruger Statestikker tilhørende: {0}",
"systemTitle":"System Statestikker",
"versionTitle":"Bot Version",
"ticketsCreated":"Tickets Oprettet",
"ticketsClosed":"Tickets Lukket",
"ticketsDeleted":"Tickets Slettet",
"ticketsReopened":"Tickets Genåbnet",
"ticketsAutoclosed":"Tickets Autolukket",
"transcriptsCreated":"Transcripts Oprettet",
"startupDate":"Startup Dato",
"latestUpdate":"Seneste Opdatering",
"ticketCreatedOn":"Ticket Oprettet Den",
"ticketCreatedBy":"Ticket Oprettet Af",
"messagesSent":"Beskeder sendt",
"status":"Status",
"participants":"Deltagere",
"role":"Rolle",
"switches":{
"globalAdmin":"Global Admin",
"ticketAdmin":"Ticket Admin",
"member":"Medlem",
"open":"Åben",
"reopened":"Genåbnet",
"closed":"Lukket",
"autoclosed":"Autolukket"
},
"errorUserNotFound":"Denne bruger kan ikke findes i statestik databasen!"
}
}
+96 -41
View File
@@ -1,67 +1,74 @@
{ {
"_CREDITS":"DJj123dj#1706",
"_INFO":"This file is a translation for open ticket 3.5.3",
"errors":{ "errors":{
"missingArgsTitle":"Ongeldige Argumenten!", "missingArgsTitle":"Onjuiste parameters!",
"missingArgsDescription":"Geen Argument", "missingArgsDescription":"Er missen parameters",
"noPermsTitle":"Geen permissies!", "noPermsTitle":"Geen permissies!",
"noPermsDescription":"Je hebt niet de juiste rollen om deze command uit te voeren!\nJe hebt de `ADMINISTRATOR` permissie nodig of je moet in de lijst van toegestane rollen zitten!", "noPermsDescription":"Je hebt de `ADMINISTRATOR` permissie nodig of je moet in de lijst van toegestane users staan!",
"chooseFromListTitle":"Ongeldig ID", "noPermsDelete":"Alleen admins kunnen een ticket verwijderen!",
"chooseFromListDescription":"Kies een van deze id's:", "chooseFromListTitle":"Onjuist ID",
"chooseFromListDescription":"Kies een van de id's hier onder:",
"boterror":"Bot Error!", "boterror":"Bot Error!",
"notInTicketTitle":"Je bent niet in een ticket!", "notInTicketTitle":"Je bent niet in een ticket!",
"notInTicketDescription":"Deze command werkt niet buiten tickets!", "notInTicketDescription":"Deze command werkt niet buiten tickets!",
"ticketDoesntExist":"Dit ticket bestaat niet meer!", "ticketDoesntExist":"Dit ticket bestaat niet meer!",
"roleDoesntExist":"Deze rol bestaat niet meer!", "roleDoesntExist":"Deze rol bestaat niet meer!",
"anotherOption":"Deze optie is geen ticket maar een ander type!", "anotherOption":"Deze optie is niet een ticket, maar een ander type!",
"maxAmountTitle":"Max aantal bereikt!", "maxAmountTitle":"Maximum numer bereikt!",
"maxAmountDescription":"Je hebt het maximum aantal openstaande ticket bereikt!\nDus je kan er geen nieuwe maken!", "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!", "somethingWentWrong":"**Iets ging fout!**\nProbeer een andere keer opnieuw!"
"somethingWentWrongTranscript":"Iets ging fout bij het maken van het transcript!**\nProbeer een andere keer opnieuw!"
}, },
"commands":{ "commands":{
"userAddedTitle":"User Toegevoegd!", "userAddedTitle":"{0} is toegevoegd aan dit ticket!",
"userAddedDescription":"{0} is toegevoegd aan dit ticket!", "userRemovedTitle":"{0} is verwijderd van dit ticket!",
"userRemovedTitle":"User Verwijderd!", "renameTitle":"De naam is veranderd naar {0}!",
"userRemovedDescription":"{0} is verwijderd van dit ticket!", "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}!",
"renameTitle":"De naam is veranderd!", "statsTitle":"Hier zijn de stats voor {0}!",
"renameWarning":"Waarschuwing: je kan de kanaalnaam maar 2 keer per minuut veranderen!\n(dit heeft te maken met discord rate limits)", "autocloseTitle":"Dit ticket wordt automatisch gesloten na {0}!",
"autocloseRejectTitle":"Dit ticket wordt niet langer automatisch gesloten!",
"closeTitle":"Sluit dit ticket!", "autocloseWarn":"Dit geldt alleen voor inactieve tickets!",
"closeDescription":"Je kan dit ticket sluiten door op de knop hier onder te duwen!",
"deleteTitle":"Verwijder dit ticket!",
"deleteDescription":"Je kan dit ticket verwijderen door op de knop hier onder te duwen!",
"reopenTitle":"Heropen dit ticket!",
"reopenDescription":"Je kan dit ticket heropenen door op de knop hier onder te duwen!",
"goToTicket":"ga naar ticket",
"ticketWarning":"De embed is in het bericht hier onder!", "ticketWarning":"De embed is in het bericht hier onder!",
"maxTicketWarning":"**Waarschuwing:** _Je kan maar {0} ticket(s) tegelijkertijd aanmaken!_" "maxTicketWarning":"**Waarschuwing:** _Je kan maar {0} ticket(s) tegelijkertijd maken!_"
}, },
"helpMenu":{ "helpMenu":{
"title":"Help Menu:", "title":"Beschikbare Commands:",
"header1":"**Ga naar {0} om een ticket te maken!**\n\n", "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", "header2":"**Run de command `/new` of `/ticket` om een ticket te maken!**\n\n",
"msgCmd":"Spawn een embed met knoppen. (admins only)", "msgCmd":"Spawn een embed met knoppen. (alleen admins)",
"renameCmd":"Hernoem een ticket. (geen spaties)", "renameCmd":"Hernoem een ticket. (geen spaties)",
"closeCmd":"Sluit een ticket.", "closeCmd":"Sluit een ticket.",
"deleteCmd":"Verwijder een ticket.", "deleteCmd":"Verijder een ticket.",
"addCmd":"Voeg een user toe aan een ticket.", "addCmd":"Voeg een user aan een ticket.",
"removeCmd":"Verwijder een user van een ticket.", "removeCmd":"Verwijder een user van een ticket.",
"reopenCmd":"Heropen een ticket nadat het gesloten wordt." "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":{ "buttons":{
"close":"Sluit Ticket", "close":"Sluit Ticket",
"delete":"Verwijder Ticket", "delete":"Verwijder Ticket",
"reopen":"Heropen Ticket", "reopen":"Heropen Ticket",
"sendTranscript":"Stuur Transcript Bestand" "closeWithReason":"sluit met reden"
}, },
"messages":{ "messages":{
"reopenTitle":"Dit ticket is terug geopend!", "closedDescription":"Alleen admins kunnen nog praten.\n\n*Klik op de knoppen hieronder voor meer acties!*",
"reopenDescription":"Voel vrij om terug te praten!", "createdTitle":"Ticket Aangemaakt!",
"closedTitle":"Dit ticket is gesloten!", "createdDescription":"U ticket is gemaakt, je kan het detecteren bij een ping!",
"closedDescription":"Nu kunnen alleen nog admins praten in dit ticket!\n\n*Klik op de knop hier onder om het ticket terug te openen of te verwijderen!*",
"createdTitle":"Ticket Gemaakt!",
"createdDescription":"Je ticket is gemaakt, je kan het detecteren bij een ping!",
"newTicketDmTitle":"Nieuw Ticket!", "newTicketDmTitle":"Nieuw Ticket!",
"closedTicketDmTitle":"Ticket Gesloten!", "closedTicketDmTitle":"Ticket Gesloten!",
@@ -70,11 +77,59 @@
"deletedTicketDmDescription":"Je ticket is verwijderd!", "deletedTicketDmDescription":"Je ticket is verwijderd!",
"reopenTicketDmTitle":"Ticket Heropend!", "reopenTicketDmTitle":"Ticket Heropend!",
"reopenTicketDmDescription":"Je ticket is heropend!", "reopenTicketDmDescription":"Je ticket is heropend!",
"newTranscriptTitle":"Een nieuw transcript is hier!",
"newTranscriptDescription":"Je kan het transcript vinden in het bestand hierboven!",
"hereIsTheTranscript":"Hier is het transcript:",
"chooseCategory":"kies een categorie:", "chooseCategory":"kies een categorie:",
"gettingdeleted":"Ticket wordt verwijderd..." "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"
},
"stats":{
"globalTitle":"Globale Stats",
"ticketTitle":"Ticket Stats voor {0}",
"userTitle":"User Stats voor {0}",
"systemTitle":"Systeem Stats",
"versionTitle":"Bot Versie",
"ticketsCreated":"Tickets Gemaakt",
"ticketsClosed":"Tickets Gesloten",
"ticketsDeleted":"Tickets Verwijderd",
"ticketsReopened":"Tickets Heropend",
"ticketsAutoclosed":"Tickets Auto-gesloten",
"transcriptsCreated":"Transcripts Gemaakt",
"startupDate":"Opstart Datum",
"latestUpdate":"Laatste Update",
"ticketCreatedOn":"Ticket Gemaakt Op",
"ticketCreatedBy":"Ticket Gemaakt Door",
"messagesSent":"Berichten Verzonden",
"status":"Status",
"participants":"Deelnemers",
"role":"Rol",
"switches":{
"globalAdmin":"Globale Admin",
"ticketAdmin":"Ticket Admin",
"member":"Member",
"open":"Open",
"reopened":"Heropend",
"closed":"Gesloten",
"autoclosed":"Auto-gesloten"
},
"errorUserNotFound":"Deze user kan niet in de database gevonden worden!"
} }
} }
+81 -26
View File
@@ -1,9 +1,13 @@
{ {
"_CREDITS":"DJdj Development",
"_INFO":"This file is a translation for open ticket 3.5.3",
"errors":{ "errors":{
"missingArgsTitle":"Invalid Arguments!", "missingArgsTitle":"Invalid Arguments!",
"missingArgsDescription":"Missing Argument", "missingArgsDescription":"Missing Argument",
"noPermsTitle":"No Permissions!", "noPermsTitle":"No Permissions!",
"noPermsDescription":"You don't have the correct roles to run this command!\nYou need the `ADMINISTRATOR` permission or be in the list of allowed roles!", "noPermsDescription":"You need the `ADMINISTRATOR` permission or be in the list of allowed roles!",
"noPermsDelete":"Only admins can delete a ticket!",
"chooseFromListTitle":"Invalid ID", "chooseFromListTitle":"Invalid ID",
"chooseFromListDescription":"Choose one of the id's below:", "chooseFromListDescription":"Choose one of the id's below:",
"boterror":"Bot Error!", "boterror":"Bot Error!",
@@ -14,30 +18,31 @@
"anotherOption":"This option is not a ticket but another type!", "anotherOption":"This option is not a ticket but another type!",
"maxAmountTitle":"Max amount reached!", "maxAmountTitle":"Max amount reached!",
"maxAmountDescription":"You reached the maximum number of tickets allowed!\nSo you can't create a new one!", "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!", "somethingWentWrong":"**Something went wrong!**\nPlease try again another time!"
"somethingWentWrongTranscript":"Something went wrong while making the transcript!**\nPlease try again another time!"
}, },
"commands":{ "commands":{
"userAddedTitle":"User Added!", "userAddedTitle":"Added {0} to this ticket!",
"userAddedDescription":"{0} is added to this ticket!", "userRemovedTitle":"Removed {0} from this ticket!",
"userRemovedTitle":"User Removed!", "renameTitle":"Changed the name to {0}!",
"userRemovedDescription":"{0} is removed from this ticket!", "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}!",
"renameTitle":"The name is changed!", "statsTitle":"Here are the stats for {0}!",
"renameWarning":"Warning: you can only change the channel name 2 times per minute!\n(this is due discord rate limits)", "autocloseTitle":"This ticket will be closed automatically after {0}!",
"autocloseRejectTitle":"This ticket will no longer be closed automatically!",
"closeTitle":"Close this ticket!", "autocloseWarn":"This only affects inactive tickets!",
"closeDescription":"You can close this ticket by clicking on the button below!",
"deleteTitle":"Delete this ticket!",
"deleteDescription":"You can delete this ticket by clicking on the button below!",
"reopenTitle":"Re-Open this ticket!",
"reopenDescription":"You can re-open this ticket by clicking on the button below!",
"goToTicket":"go to ticket",
"ticketWarning":"The embed is in the message below!", "ticketWarning":"The embed is in the message below!",
"maxTicketWarning":"**Warning:** _You can only create {0} ticket(s) at a time!_" "maxTicketWarning":"**Warning:** _You can only create {0} ticket(s) at a time!_"
}, },
"helpMenu":{ "helpMenu":{
"title":"Help Menu:", "title":"Available Commands:",
"header1":"**Go to {0} to create a ticket!**\n\n", "header1":"**Go to {0} to create a ticket!**\n\n",
"header2":"**Run the command `/new` or `/ticket` to create a ticket!**\n\n", "header2":"**Run the command `/new` or `/ticket` to create a ticket!**\n\n",
@@ -47,18 +52,20 @@
"deleteCmd":"Delete a ticket.", "deleteCmd":"Delete a ticket.",
"addCmd":"Add a user to the ticket.", "addCmd":"Add a user to the ticket.",
"removeCmd":"Remove a user from the ticket.", "removeCmd":"Remove a user from the ticket.",
"reopenCmd":"Re-Open a ticket after it was closed." "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":{ "buttons":{
"close":"Close Ticket", "close":"Close Ticket",
"delete":"Delete Ticket", "delete":"Delete Ticket",
"reopen":"Re-Open Ticket", "reopen":"Re-Open Ticket",
"sendTranscript":"Send Transcript File" "closeWithReason":"close with reason"
}, },
"messages":{ "messages":{
"reopenTitle":"Re-Opened this ticket!",
"reopenDescription":"Feel free to talk again!",
"closedTitle":"Closed this ticket!",
"closedDescription":"Only admins can talk in this ticket now!\n\n*Click on the button below to delete or to re-open this ticket!*", "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!", "createdTitle":"Ticket Created!",
"createdDescription":"Your ticket is created, you can detect it by a ping!", "createdDescription":"Your ticket is created, you can detect it by a ping!",
@@ -70,11 +77,59 @@
"deletedTicketDmDescription":"Your ticket is deleted!", "deletedTicketDmDescription":"Your ticket is deleted!",
"reopenTicketDmTitle":"Ticket Re-opened!", "reopenTicketDmTitle":"Ticket Re-opened!",
"reopenTicketDmDescription":"Your ticket is re-opened!", "reopenTicketDmDescription":"Your ticket is re-opened!",
"newTranscriptTitle":"A new transcript is here!",
"newTranscriptDescription":"You can find the transcript in the text file above!",
"hereIsTheTranscript":"Here is the transcript:",
"chooseCategory":"choose a category:", "chooseCategory":"choose a category:",
"gettingdeleted":"Ticket is getting deleted..." "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"
},
"stats":{
"globalTitle":"Global Stats",
"ticketTitle":"Ticket Stats for {0}",
"userTitle":"User Stats for {0}",
"systemTitle":"System Stats",
"versionTitle":"Bot Version",
"ticketsCreated":"Tickets Created",
"ticketsClosed":"Tickets Closed",
"ticketsDeleted":"Tickets Deleted",
"ticketsReopened":"Tickets Reopened",
"ticketsAutoclosed":"Tickets Autoclosed",
"transcriptsCreated":"Transcripts Created",
"startupDate":"Startup Date",
"latestUpdate":"Latest Update",
"ticketCreatedOn":"Ticket Created On",
"ticketCreatedBy":"Ticket Created By",
"messagesSent":"Messages Sent",
"status":"Status",
"participants":"Participants",
"role":"Role",
"switches":{
"globalAdmin":"Global Admin",
"ticketAdmin":"Ticket Admin",
"member":"Member",
"open":"Open",
"reopened":"Reopened",
"closed":"Closed",
"autoclosed":"Autoclosed"
},
"errorUserNotFound":"This user can't be found in the stats database!"
} }
} }
+111 -50
View File
@@ -1,74 +1,135 @@
{ {
"_CREDITS":"tostam",
"_INFO":"Ce fichier est une traduction pour OpenTicket 3.5.0",
"errors":{ "errors":{
"missingArgsTitle":"Arguments invalides !", "missingArgsTitle":"Arguments invalides !",
"missingArgsDescription":"Argument manquant", "missingArgsDescription":"Argument manquant !",
"noPermsTitle":"Pas de permissions!", "noPermsTitle":"Tu n'as pas les permissions requises !",
"noPermsDescription":"Vous n'avez pas les bons rôles pour exécuter cette commande !\nVous avez besoin de la permission `ADMINISTRATOR` ou d'être dans la liste des rôles autorisés !", "noPermsDescription":"Vous avez besoin de la permission `ADMINISTRATOR` ou être dans la liste des rôles autorisés !",
"chooseFromListTitle":"Invalid ID", "noPermsDelete":"Seuls les staffs peuvent supprimer un ticket !",
"chooseFromListTitle":"ID invalide !",
"chooseFromListDescription":"Choisissez l'un des identifiants ci-dessous:", "chooseFromListDescription":"Choisissez l'un des identifiants ci-dessous:",
"boterror":"Bot Error!", "boterror":"Erreur du bot !",
"notInTicketTitle":"Vous n'êtes pas dans un ticket !", "notInTicketTitle":"Vous n'êtes pas dans un ticket !",
"notInTicketDescription":"Cette commande ne fonctionne pas en dehors des tickets !", "notInTicketDescription":"Cette commande ne fonctionne pas en dehors des tickets !",
"ticketDoesntExist":"Ce billet n'existe plus !", "ticketDoesntExist":"Ce ticket n'existe pas !",
"roleDoesntExist":"Ce rôle n'existe plus !", "roleDoesntExist":"Ce rôle n'existe pas !",
"anotherOption":"Cette option n'est pas un ticket mais un autre type !", "anotherOption":"Cette option n'est pas un ticket mais un autre type !",
"maxAmountTitle":"Montant max atteint !", "maxAmountTitle":"Montant maximum de ticket atteint !",
"maxAmountDescription":"Vous avez atteint le nombre maximum de tickets autorisés !\nVous ne pouvez donc pas en créer un nouveau !", "maxAmountDescription":"Vous avez atteint le nombre maximum de tickets autorisés !\nVous ne pouvez donc pas en créer un nouveau !",
"somethingWentWrong":"**Une erreur s'est produite !**\nVeuillez réessayer une autre fois !", "somethingWentWrong":"**Quelque chose s'est mal passé !**\nVeuillez réessayer une autre fois !"
"somethingWentWrongTranscript":"Une erreur s'est produite lors de la création de la transcription !**\nVeuillez réessayer une autre fois !"
}, },
"commands":{ "commands":{
"userAddedTitle":"Utilisateur ajouté !", "userAddedTitle":"{0} a été ajouté à ce ticket !",
"userAddedDescription":"{0} est ajouté à ce billet !", "userRemovedTitle":"{0} a été supprimé de ce ticket !",
"userRemovedTitle":"Utilisateur supprimé!", "renameTitle":"Changement de nom du ticket en {0} !",
"userRemovedDescription":"{0} est supprimé de ce ticket!", "closeTitle":"Ticket fermé",
"deleteTitle":"Suppression de ce ticket...",
"reopenTitle":"Ticket réouvert",
"claimTitle":"Ce ticket est maintenant réclamé par {0}",
"unclaimTitle":"Ce ticket n'est plus réclamé !",
"changeTitle":"Modification du type de ticket en {0} !",
"renameTitle":"Le nom est changé !", "statsTitle":"Voici les statistiques pour {0} !",
"renameWarning":"Attention : vous ne pouvez modifier le nom de la chaîne que 2 fois par minute !\n(ceci est dû aux limites du taux de discorde)", "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 !",
"closeTitle":"Fermez ce ticket !", "goToTicket":"Aller au ticket",
"closeDescription":"Vous pouvez fermer ce ticket en cliquant sur le bouton ci-dessous !", "ticketWarning":"L'intégration est dans le message ci-dessous !",
"deleteTitle":"Supprimez ce billet !", "maxTicketWarning":"**Attention :** _Vous ne pouvez créer seulement {0} ticket(s) à la fois !_"
"deleteDescription":"Vous pouvez supprimer ce ticket en cliquant sur le bouton ci-dessous !",
"reopenTitle":"Ré-ouvrez ce ticket !",
"reopenDescription":"Vous pouvez rouvrir ce ticket en cliquant sur le bouton ci-dessous !",
"ticketWarning":"L'intégration est dans le message ci-dessous !",
"maxTicketWarning":"**Attention :** _Vous ne pouvez créer que {0} billet(s) à la fois !_"
}, },
"helpMenu":{ "helpMenu":{
"title":"Menu d'aide:", "title":"Commandes disponibles :",
"header1":"**Allez à {0} pour créer un ticket !**\n\n", "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", "header2":"**Exécutez la commande `/new` ou `/ticket` pour créer un ticket !**\n\n",
"msgCmd":"Créez une intégration avec des boutons. (administrateurs uniquement)", "msgCmd":"Faire apparaître une intégration avec des boutons (administrateurs uniquement)",
"renameCmd":"Renommer un ticket. (sans espaces)", "renameCmd":"Renommer un ticket (sans espaces)",
"closeCmd":"Fermer un ticket.", "closeCmd":"Fermer un ticket",
"deleteCmd":"Supprimer un billet.", "deleteCmd":"Supprimer un ticket",
"addCmd":"Ajouter un utilisateur au ticket.", "addCmd":"Ajouter un utilisateur au ticket",
"removeCmd":"Supprimer un utilisateur du ticket.", "removeCmd":"Supprimer un utilisateur du ticket",
"reopenCmd":"Re-Open a ticket after it was closed." "reopenCmd":"Réouvrir un ticket après sa clôture",
"changeCmd":"Changer le type de ticket",
"claimCmd":"Réclamer un ticket",
"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":{ "buttons":{
"close":"Fermer le ticket", "close":"Fermer le ticket",
"delete":"Supprimer le billet", "delete":"Supprimer le ticket",
"reopen":"Billet de réouverture", "reopen":"Réouvrir le ticket",
"sendTranscript":"Envoyer le fichier de transcription" "closeWithReason":"Fermer avec une raison"
}, },
"messages":{ "messages":{
"reopenTitle":"A rouvert ce ticket!", "closedDescription":"Seuls les administrateurs peuvent parler dans ce ticket maintenant !\n\n*Cliquez sur le bouton ci-dessous pour supprimer ou réouvrir ce ticket !*",
"reopenDescription":"N'hésitez pas à reparler!", "createdTitle":"Ticket créé !",
"closedTitle":"Fermé ce ticket",
"closedDescription":"Seuls les administrateurs peuvent parler dans ce ticket maintenant !\n\n*Cliquez sur le bouton ci-dessous pour supprimer ou rouvrir ce ticket !*",
"createdTitle":"Ticket créé !",
"createdDescription":"Votre ticket est créé, vous pouvez le détecter par un ping !", "createdDescription":"Votre ticket est créé, vous pouvez le détecter par un ping !",
"newTicketDmTitle":"Nouveau ticket!", "newTicketDmTitle":"Nouveau ticket !",
"newTranscriptTitle":"Une nouvelle transcription est ici!", "closedTicketDmTitle":"Ticket fermé !",
"newTranscriptDescription":"Vous pouvez trouver la transcription dans le fichier texte ci-dessus !", "deletedTicketDmTitle":"Ticket supprimé !",
"hereIsTheTranscript":"Voici la transcription :", "closedTicketDmDescription":"Votre ticket est fermé !",
"deletedTicketDmDescription":"Votre ticket est supprimé !",
"reopenTicketDmTitle":"Ticket réouvert !",
"reopenTicketDmDescription":"Votre ticket est réouvert !",
"chooseCategory":"Choisissez une catégorie:",
"gettingdeleted":"Le ticket est en cours de suppression...",
"chooseCategory":"choisissez une catégorie:", "none":"Rien",
"gettingdeleted":"Le ticket est en cours de suppression..." "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 estimé:",
"available":"La transcript est disponible ici"
},
"stats":{
"globalTitle":"Statistiques du serveur",
"ticketTitle":"Statistiques des tickets pour {0}",
"userTitle":"Statistiques des utilisateurs pour {0}",
"systemTitle":"Statistiques du système",
"versionTitle":"Version du bot",
"ticketsCreated":"Tickets créés",
"ticketsClosed":"Tickets fermés",
"ticketsDeleted":"Tickets supprimés",
"ticketsReopened":"Tickets réouverts",
"ticketsAutoclosed":"Tickets fermés automatiquement",
"transcriptsCreated":"Transcriptions créées",
"startupDate":"Date de démarrage du bot",
"latestUpdate":"Dernière mise à jour",
"ticketCreatedOn":"Ticket créé le",
"ticketCreatedBy":"Ticket créé par",
"messagesSent":"Messages envoyés",
"status":"Status",
"participants":"Participants",
"role":"Role",
"switches":{
"globalAdmin":"Administrateur global",
"ticketAdmin":"Administrateur des tickets",
"member":"Membre",
"open":"Ouvrir",
"reopened":"Réouvert",
"closed":"Fermé",
"autoclosed":"Fermé automatiquement"
},
"errorUserNotFound":"Cet utilisateur est introuvable dans la base de données de statistiques !"
} }
} }
+134 -79
View File
@@ -1,80 +1,135 @@
{ {
"errors":{ "_CREDITS":"david.#8276 ",
"missingArgsTitle":"Ungültiges Argument!", "_INFO":"This file is a translation for open ticket 3.5.3",
"missingArgsDescription":"Fehlendes Argument!",
"noPermsTitle":"Du hast keine Rechte!", "errors":{
"noPermsDescription":"Sie haben nicht die richtigen Rollen, um diesen Befehl auszuführen!\nSie benötigen die `ADMINISTRATOR` Erlaubnis oder in der Liste der erlaubten Rollen sein!", "missingArgsTitle":"Ungültiges Argument!",
"chooseFromListTitle":"Ungültige ID", "missingArgsDescription":"Fehlendes Argument!",
"chooseFromListDescription":"Wählen Sie eine der folgenden ID:", "noPermsTitle":"Du hast keine Rechte!",
"boterror":"Bot Fehler!", "noPermsDescription":"Du benötigst die `ADMINISTRATOR` Rechte oder die erlaubte Rolle",
"notInTicketTitle":"Du bist ein kein Ticket!", "noPermsDelete":"Nur Administratoren können ein Ticket löschen!",
"notInTicketDescription":"Der Befehl funktioniert nicht außerhalb eines Tickets!", "chooseFromListTitle":"Ungültige ID",
"ticketDoesntExist":"Das Ticket Exisitert nicht mehr!", "chooseFromListDescription":"Wählen Sie eine der folgenden ID's:",
"roleDoesntExist":"Die Rolle Exisitiert nicht mehr!", "boterror":"Bot Fehler!",
"anotherOption":"Diese Option ist kein Ticket, sondern eine andere Art!", "notInTicketTitle":"Du bist in keinem Ticket!",
"maxAmountTitle":"Das Limit wurde erreicht!", "notInTicketDescription":"Der Befehl funktioniert außerhalb eines Tickets nicht!",
"maxAmountDescription":"Sie haben die maximal zulässige Anzahl von Tickets erreicht!\nSie können also keine neue erstellen.!", "ticketDoesntExist":"Das Ticket exisitert nicht mehr!",
"somethingWentWrong":"**Etwas ist schief gelaufen!**\nBitte versuchen Sie es ein anderes Mal!", "roleDoesntExist":"Die Rolle exisitiert nicht mehr!",
"somethingWentWrongTranscript":"Bei der Erstellung der Transcript ist etwas schief gelaufen!**\nBitte versuchen Sie es ein anderes Mal!" "anotherOption":"Diese Option ist kein Ticket, sondern eine andere Art!",
}, "maxAmountTitle":"Das Limit wurde erreicht!",
"commands":{ "maxAmountDescription":"Sie haben die maximal zulässige Anzahl von Tickets erreicht!\nSie können also keine neuen erstellen.!",
"userAddedTitle":"User geaddet!", "somethingWentWrong":"**Etwas ist schief gelaufen!**\nBitte versuchen Sie es ein anderes Mal!"
"userAddedDescription":"{0} wird zu diesem Ticket hinzugefügt!", },
"userRemovedTitle":"User entfernt!", "commands":{
"userRemovedDescription":"{0} wird aus diesem Ticket entfernt!", "userAddedTitle":"User geaddet!",
"userRemovedTitle":"User entfernt!",
"renameTitle":"Der Name wurde geändert!", "renameTitle":"Der Name wurde geändert!",
"renameWarning":"Achtung: Sie können den Kanalnamen nur 2 Mal pro Minute ändern!\n(dies ist auf die Begrenzung der Diskordrate zurückzuführen)", "closeTitle":"Dieses Ticket schließen!",
"deleteTitle":"Löschen Sie dieses Ticket!",
"closeTitle":"Dieses Ticket schließen!", "reopenTitle":"Öffne dieses Ticket erneut!",
"closeDescription":"Sie können dieses Ticket schließen, indem Sie auf die Schaltfläche unten klicken!",
"deleteTitle":"Löschen Sie dieses Ticket!", "claimTitle":"Dieses Ticket wurde beansprucht von {0}",
"deleteDescription":"Sie können dieses Ticket löschen, indem Sie auf die Schaltfläche unten klicken!", "unclaimTitle":"Dieses Ticket wird nichtmehr beansprucht.",
"reopenTitle":"Öffne dieses Ticket erneut!", "changeTitle":"Ticket Typ wurde geändert zu {0}!",
"reopenDescription":"Sie können dieses Ticket erneut öffnen, indem Sie auf die Schaltfläche unten klicken!",
"statsTitle":"Hier sind die Stats für {0}!",
"ticketWarning":"Die Einbettung befindet sich in der Nachricht unten!", "autocloseTitle":"Dieses Ticket wird automatisch geschlossen in {0}!",
"maxTicketWarning":"**Warnung:** _Sie können nur {0} ticket(s) erstellen zu einer Zeit!_" "autocloseRejectTitle":"Dieses Ticket wird nichtmehr automatisch geschlossen",
}, "autocloseWarn":"Dies betrifft nur inaktive Tickets!",
"helpMenu":{
"title":"Hilfe Menu:", "goToTicket":"Geh zu deinem Ticket",
"header1":"**Gehe zu {0} um ein Ticket zu erstellen!**\n\n", "ticketWarning":"Die Einbettung befindet sich in der Nachricht unten!",
"header2":"**Führen Sie den Befehl `/new` oder `/ticket` um ein Ticket zu erstellen!**\n\n", "maxTicketWarning":"**Warnung:** _Es können maximal {0} Tickets zur gleichen Zeit geöffnet sein!_"
},
"msgCmd":"Eine Einbettung mit Schaltflächen erzeugen. (nur admins)", "helpMenu":{
"renameCmd":"Ein Ticket umbenennen. (keine Leerzeichen)", "title":"Hilfe Menu:",
"closeCmd":"Schließen Sie ein Ticket.", "header1":"**Gehe zu {0} um ein Ticket zu erstellen!**\n\n",
"deleteCmd":"Ein Ticket löschen.", "header2":"**Führen Sie den Befehl `/new` oder `/ticket` um ein Ticket zu erstellen!**\n\n",
"addCmd":"Fügen Sie dem Ticket einen Benutzer hinzu.",
"removeCmd":"Entfernen eines Benutzers aus dem Ticket.", "msgCmd":"Eine Einbettung mit Schaltflächen erzeugen. (nur admins)",
"reopenCmd":"Öffnen Sie ein Ticket erneut, nachdem es geschlossen wurde." "renameCmd":"Ein Ticket umbenennen. (keine Leerzeichen)",
}, "closeCmd":"Schließen Sie ein Ticket.",
"buttons":{ "deleteCmd":"Ein Ticket löschen.",
"close":"Ticket schließen", "addCmd":"Fügen Sie dem Ticket einen Benutzer hinzu.",
"delete":"Ticket löschen", "removeCmd":"Entfernen eines Benutzers aus dem Ticket.",
"reopen":"Ticket wieder öffnen", "reopenCmd":"Öffnen Sie ein Ticket erneut, nachdem es geschlossen wurde.",
"sendTranscript":"Transcript-Datei senden" "changeCmd":"Ticket Typ ändern",
}, "claimCmd":"Ticket beanspruchen",
"messages":{ "unclaimCmd":"Ticket nicht mehr beanspruchen.",
"reopenTitle":"Dieses Ticket wiedereröffnet!", "statsCmd":"Ticket Stats",
"reopenDescription":"Sie können gerne weiterreden!", "autocloseCmd":"Timer wurde gesetzt auf automatisches schließen des Tickets"
"closedTitle":"Dieses Ticket geschlossen!", },
"closedDescription":"Nur Admins können jetzt in diesem Ticket sprechen!\n\n*Klicken Sie auf die Schaltfläche unten, um dieses Ticket zu löschen oder erneut zu öffnen!*", "buttons":{
"createdTitle":"Ticket erstellt!", "close":"Ticket schließen",
"createdDescription":"Ihr Ticket ist erstellt, Sie können es durch einen Ping erkennen!", "delete":"Ticket löschen",
"reopen":"Ticket wieder öffnen",
"newTicketDmTitle":"Neues Ticket!", "closeWithReason":"Geschlossen mit dem Grund"
"closedTicketDmTitle":"Ticket schließen!", },
"deletedTicketDmTitle":"Ticket löschen!", "messages":{
"closedTicketDmDescription":"Ihr Ticket ist geschlossen!", "closedDescription":"Nur Admins können jetzt in diesem Ticket sprechen!\n\n*Klicken Sie auf die Schaltfläche unten, um dieses Ticket zu löschen oder erneut zu öffnen!*",
"deletedTicketDmDescription":"Ihr Ticket ist gelöscht!", "createdTitle":"Ticket erstellt!",
"reopenTicketDmTitle":"Ticket neu Eröffnen!", "createdDescription":"Ihr Ticket ist erstellt, Sie können es durch einen Ping erkennen!",
"reopenTicketDmDescription":"Dein Ticket ist Neu eröffnet!",
"newTranscriptTitle":"Eine neue Transscript finden Sie hier!", "newTicketDmTitle":"Neues Ticket!",
"newTranscriptDescription":"Die Abschrift finden Sie in der obigen Textdatei!", "closedTicketDmTitle":"Ticket schließen!",
"hereIsTheTranscript":"Hier ist das Transscript:", "deletedTicketDmTitle":"Ticket löschen!",
"closedTicketDmDescription":"Ihr Ticket ist geschlossen!",
"chooseCategory":"Wähle eine Kategorie:", "deletedTicketDmDescription":"Ihr Ticket ist gelöscht!",
"gettingdeleted":"Ticket wird 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"
},
"stats":{
"globalTitle":"Global Stats",
"ticketTitle":"Ticket Stats für {0}",
"userTitle":"NutzerStats für {0}",
"systemTitle":"System Stats",
"versionTitle":"Bot Version",
"ticketsCreated":"Tickets erstellt",
"ticketsClosed":"Tickets geschlossen",
"ticketsDeleted":"Tickets gelöscht",
"ticketsReopened":"Tickets wiedergeöffnet",
"ticketsAutoclosed":"Tickets Autogeschlossen",
"transcriptsCreated":"Transcripts erstellt",
"startupDate":"Start Datum",
"latestUpdate":"Letztes Update",
"ticketCreatedOn":"Ticket erstellt am",
"ticketCreatedBy":"Ticket erstellt von",
"messagesSent":"Nachrichten gesendet",
"status":"Status",
"participants":"Teilnehmer",
"role":"Rolle",
"switches":{
"globalAdmin":"Global Admin",
"ticketAdmin":"Ticket Admin",
"member":"Nutzer",
"open":"Öffnen",
"reopened":"Wiedergeöffnet",
"closed":"Geschlossen",
"autoclosed":"Autogeschlossen"
},
"errorUserNotFound":"Der Nutzer wurde in der Statistik-Datenbank nicht gefunden!"
}
} }
+135
View File
@@ -0,0 +1,135 @@
{
"_CREDITS":"ꙅoᴎɒᎸɘƚꙅ#3744",
"_INFO":"This file is a translation for open ticket 3.5.3",
"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":"Το αντίγραφο είναι ανοιχτώ εδώ!"
},
"stats":{
"globalTitle":"Global Stats",
"ticketTitle":"Ticket Stats for {0}",
"userTitle":"User Stats for {0}",
"systemTitle":"System Stats",
"versionTitle":"Bot Version",
"ticketsCreated":"Tickets Created",
"ticketsClosed":"Tickets Closed",
"ticketsDeleted":"Tickets Deleted",
"ticketsReopened":"Tickets Reopened",
"ticketsAutoclosed":"Tickets Autoclosed",
"transcriptsCreated":"Transcripts Created",
"startupDate":"Startup Date",
"latestUpdate":"Latest Update",
"ticketCreatedOn":"Ticket Created On",
"ticketCreatedBy":"Ticket Created By",
"messagesSent":"Messages Sent",
"status":"Status",
"participants":"Participants",
"role":"Role",
"switches":{
"globalAdmin":"Global Admin",
"ticketAdmin":"Ticket Admin",
"member":"Member",
"open":"Open",
"reopened":"Reopened",
"closed":"Closed",
"autoclosed":"Autoclosed"
},
"errorUserNotFound":"This user can't be found in the stats database!"
}
}
+135
View File
@@ -0,0 +1,135 @@
{
"_CREDITS":"Snowy",
"_INFO":"This file is a translation for open ticket 3.5.3",
"errors":{
"missingArgsTitle":"Hibás paraméterek!",
"missingArgsDescription":"Hiányzó paraméterek",
"noPermsTitle":"Nincs jogosultságod!",
"noPermsDescription":"Szükséged van az `Adminisztrátor` jogra, vagy rajta kell lenned az engedélyezett rangok listáján!",
"noPermsDelete":"Csak adminok törölhetik a ticketet!",
"chooseFromListTitle":"Ismeretlen ID",
"chooseFromListDescription":"Válassz egy ID-t az alábbi listából:",
"boterror":"Bot Hiba!",
"notInTicketTitle":"Nem vagy egy ticketben!",
"notInTicketDescription":"Ez a parancs nem működik a ticketeken kívűl!",
"ticketDoesntExist":"Ez a ticket már nem létezik!",
"roleDoesntExist":"Ez a rang már nem létezik!",
"anotherOption":"Ez a választás nem egy ticket, hanem más!",
"maxAmountTitle":"Maximum limit elérve!",
"maxAmountDescription":"Elérted a maximum engedélyezett ticketek számát!\nSzóval nem tudsz újat csinálni!",
"somethingWentWrong":"**Valami balul sült el!**\nKérlek próbáld újra később!"
},
"commands":{
"userAddedTitle":"{0} hozzáadva a tickethez!",
"userRemovedTitle":"{0} elvéve a ticketből!",
"renameTitle":"Ticket neve megváltoztatva erre: {0}!",
"closeTitle":"Ticket bezárva!",
"deleteTitle":"Ticket törlése...",
"reopenTitle":"Ticket újranyitva!",
"claimTitle":"A ticketet igényelte: {0}",
"unclaimTitle":"Már senki nem ingényeli a ticketet!",
"changeTitle":"Ticket típus megváltoztatva erre: {0}!",
"statsTitle":"Ticket statisztikák erre: {0}!",
"autocloseTitle":"Ez a ticket automatikusan be lesz zárva ennyi idő múlva: {0}!",
"autocloseRejectTitle":"Ez a ticket nem lesz automatikusan bezárva!",
"autocloseWarn":"Ez csak az inaktív hibajegyeket érinti!",
"goToTicket":"A tickethez",
"ticketWarning":"Az embed az alábbi üzenetben van!",
"maxTicketWarning":"**Warning:** _Csak {0} ticketet készíthetsz egy időben!_"
},
"helpMenu":{
"title":"Elérhető parancsok:",
"header1":"**Hogy elkészíts egy ticketet, menj ide: {0}!**\n\n",
"header2":"**Futtasd a `/new` vagy `/ticket` parancsot a ticket készítéséhez!**\n\n",
"msgCmd":"Embed küldése gombokkal. (csak adminok)",
"renameCmd":"Ticket átnevezése. (szóköz nélkül)",
"closeCmd":"Ticket bezárása.",
"deleteCmd":"Ticket törlése.",
"addCmd":"Felhasználó hozzáadása a tickethez.",
"removeCmd":"Felhasználó elvétele a tickettől.",
"reopenCmd":"Ticket újranyitása miután már be lett zárva.",
"changeCmd":"Ticket típusának megváltoztatása.",
"claimCmd":"Ticket igénylése.",
"unclaimCmd":"Ticket igénylésének törlése.",
"statsCmd":"Ticket statisztikák megtekintése.",
"autocloseCmd":"Ticketek automatikus bezárási idejének beállítása"
},
"buttons":{
"close":"Ticket bezárása",
"delete":"Ticket törlése",
"reopen":"Ticket újranyitása",
"closeWithReason":"Bezárás indokkal"
},
"messages":{
"closedDescription":"Csak adminok tudnak ebben a ticketben beszélni!\n\n*Kattints az alábbi gombokkal hogy töröld vagy újranyisd a ticketet!*",
"createdTitle":"Ticket Elkészítve!",
"createdDescription":"A ticketet elkészítve, meg tudod találni egy pingel!",
"newTicketDmTitle":"Új ticket!",
"closedTicketDmTitle":"Ticket bezárva!",
"deletedTicketDmTitle":"Ticket törölve!",
"closedTicketDmDescription":"A ticketed bezárták!",
"deletedTicketDmDescription":"A ticketed törölték!",
"reopenTicketDmTitle":"Ticket újranyitva!",
"reopenTicketDmDescription":"A ticketed újranyitották!",
"chooseCategory":"válassz egy kategóriát:",
"gettingdeleted":"A ticket törölve lesz...",
"none":"nincs",
"reason":"indok",
"createdat":"elkészítve ekkor:",
"openedby":"nyitotta:",
"deletedby":"törölve általa:",
"closedby":"bezárva általa:",
"modalreason":"Mi az indokod a ticket bezárására?",
"chooseATicket": "Válassz egy ticketet"
},
"transcripts":{
"title":"Átirat",
"processed":"Ez az átirat jelenleg feldolgozás alatt van",
"wait":"Kérlek várj!",
"estimated":"Becsült idő",
"available":"Az átirat itt érhető el"
},
"stats":{
"globalTitle":"Global Stats",
"ticketTitle":"Ticket Stats for {0}",
"userTitle":"User Stats for {0}",
"systemTitle":"System Stats",
"versionTitle":"Bot Version",
"ticketsCreated":"Tickets Created",
"ticketsClosed":"Tickets Closed",
"ticketsDeleted":"Tickets Deleted",
"ticketsReopened":"Tickets Reopened",
"ticketsAutoclosed":"Tickets Autoclosed",
"transcriptsCreated":"Transcripts Created",
"startupDate":"Startup Date",
"latestUpdate":"Latest Update",
"ticketCreatedOn":"Ticket Created On",
"ticketCreatedBy":"Ticket Created By",
"messagesSent":"Messages Sent",
"status":"Status",
"participants":"Participants",
"role":"Role",
"switches":{
"globalAdmin":"Global Admin",
"ticketAdmin":"Ticket Admin",
"member":"Member",
"open":"Open",
"reopened":"Reopened",
"closed":"Closed",
"autoclosed":"Autoclosed"
},
"errorUserNotFound":"This user can't be found in the stats database!"
}
}
+135
View File
@@ -0,0 +1,135 @@
{
"_CREDITS":"erxg",
"_INFO":"This file is a translation for open ticket 3.5.3",
"errors":{
"missingArgsTitle":"Argumen tidak valid!",
"missingArgsDescription":"Argumen hilang",
"noPermsTitle":"Tidak ada akses!",
"noPermsDescription":"Anda memerlukan akses `ADMINISTRATOR` atau berada di dalam peran yang diizinkan!",
"noPermsDelete":"Hanya admin yang dapat menghapus tiket!",
"chooseFromListTitle":"ID Tidak Valid",
"chooseFromListDescription":"Silahkan pilih salah satu id di bawah:",
"boterror":"Bot Error!",
"notInTicketTitle":"Anda tidak berada di dalam sebuah tiket!",
"notInTicketDescription":"Perintah ini tidak bekerja di luar tiket!",
"ticketDoesntExist":"Tiket ini sudah tidak ada lagi!",
"roleDoesntExist":"Peran ini sudah tidak ada lagi!",
"anotherOption":"Opsi ini bukan tiket, melainkan tipe lain!",
"maxAmountTitle":"Batas maksimum tercapai!",
"maxAmountDescription":"Kamu telah meraih batas maksimum tiket yang diperbolehkan!\nJadi kamu tidak bisa membuat tiket baru!",
"somethingWentWrong":"Ada yang salah! Silakan coba lagi nanti!"
},
"commands":{
"userAddedTitle":"Menambah {0} ke tiket ini!",
"userRemovedTitle":"Mengeluarkan {0} dari tiket ini!",
"renameTitle":"Mengganti nama menjadi {0}!",
"closeTitle":"Menutup tiket ini!",
"deleteTitle":"Menghapus tiket ini...",
"reopenTitle":"Membuka ulang tiket ini!",
"claimTitle":"Tiket ini diklaim oleh {0}",
"unclaimTitle":"Tiket ini tidak diklaim lagi!",
"changeTitle":"Mengganti tipe tiket menjadi {0}!",
"statsTitle":"Ini adalah status untuk {0}!",
"autocloseTitle":"Tiket ini akan tutup otomatis setelah {0}!",
"autocloseRejectTitle":"Tiket ini tidak akan tertutup secara otomatis lagi!",
"autocloseWarn":"Ini hanya mempengaruhi tiket yang tidak aktif!",
"goToTicket":"Pergi ke tiket",
"ticketWarning":"Sematan tersebut tersedia dalam pesan di bawah ini!",
"maxTicketWarning":"**Peringatan:** _Anda hanya bisa membuat {0} tiket dalam satu waktu!_"
},
"helpMenu":{
"title":"Perintah yang tersedia:",
"header1":"**Pergi ke {0} untuk membuat tiket!**\n\n",
"header2":"**Jalankan perintah `/new` atau `/ticket` untuk membuat tiket!**\n\n",
"msgCmd":"Munculkan sematan dengan tombol. (hanya admin)",
"renameCmd":"Ganti nama tiket. (tanpa spasi)",
"closeCmd":"Tutup tiket.",
"deleteCmd":"Hapus tiket.",
"addCmd":"Tambahkan pengguna ke dalam tiket.",
"removeCmd":"Keluarkan pengguna dari tiket.",
"reopenCmd":"Buka ulang tiket setelah ditutup.",
"changeCmd":"Ganti tipe tiket.",
"claimCmd":"Klaim tiket.",
"unclaimCmd":"Batalkan klaim tiket.",
"statsCmd":"Lihat status tiket.",
"autocloseCmd":"Atur timer untuk menutup tiket secara otomatis"
},
"buttons":{
"close":"Tutup tiket",
"delete":"Hapus tiket",
"reopen":"Buka ulang tiket",
"closeWithReason":"Tutup dengan alasan"
},
"messages":{
"closedDescription":"Hanya admin yang dapat berbincang di tiket ini sekarang!\n\n*Tekan tombol di bawah untuk menghapus atau membuka ulang tiket ini!*",
"createdTitle":"Tiket dibuat!",
"createdDescription":"Tiket anda dibuat, anda dapat mengetahui dengan ping!",
"newTicketDmTitle":"Tiket baru!",
"closedTicketDmTitle":"Tiket ditutup!",
"deletedTicketDmTitle":"TIket dihapus!",
"closedTicketDmDescription":"Tiket anda ditutup!",
"deletedTicketDmDescription":"Tiket anda dihapus!",
"reopenTicketDmTitle":"Tiket dibuka kembali!",
"reopenTicketDmDescription":"Tiket anda dibuka kembali!",
"chooseCategory":"Pilih kategori:",
"gettingdeleted":"Tiket sedang dihapus...",
"none":"tidak ada",
"reason":"Alasan",
"createdat":"dibuat di",
"openedby":"dibuka oleh",
"deletedby":"dihapus oleh",
"closedby":"ditutup oleh",
"modalreason":"Apa alasan penutupan tiket ini?",
"chooseATicket": "Pilih tiket"
},
"transcripts":{
"title":"Transcript",
"processed":"Transkrip sedang diproses",
"wait":"Mohon tunggu!",
"estimated":"Estimasi waktu",
"available":"Transkrip tersedia di sini"
},
"stats":{
"globalTitle":"Statistik Global",
"ticketTitle":"Status Tiket Untuk {0}",
"userTitle":"Status Pengguna Untuk {0}",
"systemTitle":"Status Sistem",
"versionTitle":"Versi Robot",
"ticketsCreated":"Tiket Dibuat",
"ticketsClosed":"Tiket Ditutup",
"ticketsDeleted":"Tiket Dihapus",
"ticketsReopened":"Tiket Dibuka Kembali",
"ticketsAutoclosed":"Tiket Ditutup Otomatis",
"transcriptsCreated":"Transkrip Dibuat",
"startupDate":"Tanggal Mulai",
"latestUpdate":"Pembaruan Terbaru",
"ticketCreatedOn":"Tiket Dibuat Pada",
"ticketCreatedBy":"Tiket Dibuat Oleh",
"messagesSent":"Pesan Terkirim",
"status":"Status",
"participants":"Partisipan",
"role":"Peran",
"switches":{
"globalAdmin":"Admin Global",
"ticketAdmin":"Ticket Admin",
"member":"Anggota",
"open":"Buka",
"reopened":"Dibuka kembali",
"closed":"Ditutup",
"autoclosed":"Ditutup Otomatis"
},
"errorUserNotFound":"Pengguna ini tidak dapat ditemukan dalam basis data statistik!"
}
}
+135
View File
@@ -0,0 +1,135 @@
{
"_CREDITS":"Maurizio#0268",
"_INFO":"This file is a translation for open ticket 3.5.3",
"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"
},
"stats": {
"globalTitle": "Statistiche Globali",
"ticketTitle": "Statistiche Ticket per {0}",
"userTitle": "Statistiche Utenti per {0}",
"systemTitle": "Sistema Statistiche",
"versionTitle": "Versione Bot",
"ticketsCreated": "Tickets Creato",
"ticketsClosed": "Tickets Chiuso",
"ticketsDeleted": "Tickets Eliminato",
"ticketsReopened": "Tickets Riaperto",
"ticketsAutoclosed": "Tickets Chiuso Automaticamente",
"transcriptsCreated": "Transcrizione Creata",
"startupDate": "Data Inizio",
"latestUpdate": "Ultimo Update",
"ticketCreatedOn": "Ticket Creato Su",
"ticketCreatedBy": "Ticket Creato Da",
"messagesSent": "Messaggi Inviati",
"status": "Stato",
"participants": "Partecipanti",
"role": "Ruolo",
"switches": {
"globalAdmin": "Amministratore Globale",
"ticketAdmin": "Amministratore Ticket",
"member": "Membro",
"open": "Aperto",
"reopened": "Riaperto",
"closed": "Chiuso",
"autoclosed": "Chiuso Automaticamente"
},
"errorUserNotFound": "Questo utente non può essere trovato nel database delle statistiche!"
}
}
+135
View File
@@ -0,0 +1,135 @@
{
"_CREDITS":"NoOneNook#0266",
"_INFO":"This file is a translation for open ticket 3.5.3",
"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!"
},
"stats":{
"globalTitle":"Globale Stats",
"ticketTitle":"Ticket Stats for {0}",
"userTitle":"Bruker Stats for {0}",
"systemTitle":"System Stats",
"versionTitle":"Bot Versjon",
"ticketsCreated":"Tickets Laget",
"ticketsClosed":"Tickets Lukket",
"ticketsDeleted":"Tickets Slettet",
"ticketsReopened":"Tickets Gjenåpnet",
"ticketsAutoclosed":"Tickets Auto-lukket",
"transcriptsCreated":"Transcripts Opprettet",
"startupDate":"Start Dato",
"latestUpdate":"Siste Oppdatering",
"ticketCreatedOn":"Ticket Laget den",
"ticketCreatedBy":"Ticket Laget av",
"messagesSent":"Meldinger sendt",
"status":"Status",
"participants":"Deltakere",
"role":"Rolle",
"switches":{
"globalAdmin":"Global Admin",
"ticketAdmin":"Ticket Admin",
"member":"Medlem",
"open":"Åpen",
"reopened":"Gjenåpnet",
"closed":"Lukket",
"autoclosed":"Auto-Lukket"
},
"errorUserNotFound":"Denne brukeren kan ikke bli funnet i statistikkdatabasen!"
}
}
+135
View File
@@ -0,0 +1,135 @@
{
"_CREDITS":"MKevas#8311",
"_INFO":"This file is a translation for open ticket 3.5.3",
"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"
},
"stats":{
"globalTitle":"Globalne Statystyki",
"ticketTitle":"Statystyki biletów dla {0}",
"userTitle":"Statystyki użytkowników dla {0}",
"systemTitle":"Statystyki systemu",
"versionTitle":"Wersja bota",
"ticketsCreated":"Bilety stworzone",
"ticketsClosed":"Bilety zamknięte",
"ticketsDeleted":"Bilety skasowane",
"ticketsReopened":"Bilety otwarte ponownie",
"ticketsAutoclosed":"Bilety automatycznie zamknięte",
"transcriptsCreated":"Utworzono transkrypcje",
"startupDate":"Data uruchomienia",
"latestUpdate":"Najnowsza aktualizacja",
"ticketCreatedOn":"Bilet został utworzony dnia",
"ticketCreatedBy":"Bilet stworzony przez",
"messagesSent":"Wiadomość wysłana",
"status":"Status",
"participants":"Uczestnicy",
"role":"Rola",
"switches":{
"globalAdmin":"Globalny administrator",
"ticketAdmin":"Admin biletowy",
"member":"Użytkownik",
"open":"Otwarte",
"reopened":"Otwarte ponownie",
"closed":"Zamknięte",
"autoclosed":"Automatycznie zamknięte"
},
"errorUserNotFound":"Tego użytkownika nie można znaleźć w bazie statystyk!"
}
}
+135
View File
@@ -0,0 +1,135 @@
{
"_CREDITS":"QuirAddon#9778",
"_INFO":"This file is a translation for open ticket 3.5.3",
"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"
},
"stats":{
"globalTitle":"Global Stats",
"ticketTitle":"Ticket Stats for {0}",
"userTitle":"User Stats for {0}",
"systemTitle":"System Stats",
"versionTitle":"Bot Version",
"ticketsCreated":"Tickets Created",
"ticketsClosed":"Tickets Closed",
"ticketsDeleted":"Tickets Deleted",
"ticketsReopened":"Tickets Reopened",
"ticketsAutoclosed":"Tickets Autoclosed",
"transcriptsCreated":"Transcripts Created",
"startupDate":"Startup Date",
"latestUpdate":"Latest Update",
"ticketCreatedOn":"Ticket Created On",
"ticketCreatedBy":"Ticket Created By",
"messagesSent":"Messages Sent",
"status":"Status",
"participants":"Participants",
"role":"Role",
"switches":{
"globalAdmin":"Global Admin",
"ticketAdmin":"Ticket Admin",
"member":"Member",
"open":"Open",
"reopened":"Reopened",
"closed":"Closed",
"autoclosed":"Autoclosed"
},
"errorUserNotFound":"This user can't be found in the stats database!"
}
}
+109 -54
View File
@@ -1,80 +1,135 @@
{ {
"_CREDITS":"Sanke#6086",
"_INFO":"This file is a translation for open ticket 3.5.3",
"errors":{ "errors":{
"missingArgsTitle":"Argumente invalide!", "missingArgsTitle":"Argumente Invalide",
"missingArgsDescription":"Argument lipsa", "missingArgsDescription":"Argument Lipsa",
"noPermsTitle":"Nu ai permisiunile necesare!", "noPermsTitle":"Nu ai permisiunea necesara!",
"noPermsDescription":"Nu ai rolurile necesare!\nAi nevoie de permisiunea `ADMINISTRATOR` sau sa fii in lista rolurilor permise!", "noPermsDescription":"Ai nevoie de permisiunea de `ADMINISTRATOR`!",
"chooseFromListTitle":"ID invalid", "noPermsDelete":"Doar adminii pot inchide un ticket!",
"chooseFromListTitle":"Invalid ID",
"chooseFromListDescription":"Alege unul dintre id-urile urmatoare:", "chooseFromListDescription":"Alege unul dintre id-urile urmatoare:",
"boterror":"Eroare bot!", "boterror":"Eroare bot!",
"notInTicketTitle":"Nu esti intr-un ticket!", "notInTicketTitle":"Nu esti intr-un ticket!",
"notInTicketDescription":"Aceasta comanda nu functioneaza in afara ticket-urilor!", "notInTicketDescription":"Aceasta comanda nu merge inafara unui ticket!",
"ticketDoesntExist":"Acest ticket nu mai exista!", "ticketDoesntExist":"Acest ticket nu mai exista!",
"roleDoesntExist":"Acest rol nu mai exista", "roleDoesntExist":"Acest rol nu mai exista!",
"anotherOption":"Aceasta optiune nu este un ticket ci doar alt tip!", "anotherOption":"Aceasta optiune este altceva decat un tip de ticket!",
"maxAmountTitle":"Limita a fost atinsa", "maxAmountTitle":"Limita atinsa!",
"maxAmountDescription":"Ai atins limita maxima de tickete\nNu mai poti creea altele!", "maxAmountDescription":"Ai atins limita de tickets!\nAsa ca nu mai poti creea altele noi!",
"somethingWentWrong":"**Ceva nu a mers bine :(**\nTe rugam sa incerci din nou mai tarziu", "somethingWentWrong":"**Ceva nu a mers bine!**\nTe rugam sa incerci mai tarziu!"
"somethingWentWrongTranscript":"**Ceva nu a mers bine in timpul creerii copiei a ticket-ului!**\nTe rugam sa incerci din nou mai tarziu!" },
},
"commands":{ "commands":{
"userAddedTitle":"Utilizator adaugat!", "userAddedTitle":"{0} a fost adaugat in acest ticket!",
"userAddedDescription":"{0} este adaugat la acest ticket!", "userRemovedTitle":"{0} a fost scos din acest ticket!",
"userRemovedTitle":"Utilizator eliminat!", "renameTitle":"Nume schimbat in {0}!",
"userRemovedDescription":"{0} este eliminat din acest ticket!", "closeTitle":"Ticket inchis!",
"deleteTitle":"Se sterge ticket-ul...",
"reopenTitle":"Ticket Re-deschis!",
"renameTitle":"Numele este schimbat!", "claimTitle":"Acest ticket a primit claim de la {0}",
"renameWarning":"ATENTIE: poti schimba numele acestui ticket doar de 2 ori pe minut!\n(se datoreaza limitarii discord-ului)", "unclaimTitle":"Acest ticket nu mai este detinut!",
"changeTitle":"A fost schimbat tipul ticket-ului la {0}!",
"closeTitle":"Inchide acest ticket", "statsTitle":"Acestea sunt informatiile pentru {0}!",
"closeDescription":"Poti inchide acest ticket doar apasand butonul de mai jos!", "autocloseTitle":"Acest ticket va fi inchis automat dupa {0}!",
"deleteTitle":"Sterge acest ticket!", "autocloseRejectTitle":"Acest ticket nu va mai fi inchis automat!",
"deleteDescription":"Poti sterge acest ticket doar apasand butonul de mai jos", "autocloseWarn":"Aceasta optiune afecteaza numai ticketele inactive!",
"reopenTitle":"Re-deschide acest ticket!",
"reopenDescription":"Poti redeschide acest ticket doar apasand butonul de mai jos!",
"ticketWarning":"Embed-ul se afla in mesajul de mai jos:", "goToTicket":"Mergi la ticket",
"maxTicketWarning":"**ATENTIE:** _Poti creea doar {0} ticket-e odata!_" "ticketWarning":"Embed-ul se afla in mesajul de mai jos!",
"maxTicketWarning":"**Avertizare:** _Poti creea doar {0} tickete active!_"
}, },
"helpMenu":{ "helpMenu":{
"title":"Meniu de ajutor:", "title":"Comenzi disponibile:",
"header1":"**Deschide {0} pentru a creea un ticket!**\n\n", "header1":"**Mergi la {0} pentru a creea un ticket!**\n\n",
"header2":"**Ruleaza comanda `/new` ori `/ticket` pentru a creea un ticket!**\n\n", "header2":"**Ruleaza comanda `/new` ori `/ticket` pentru a creea un ticket!**\n\n",
"msgCmd":"Afiseaza embed-ul cu tickete. (doar administratorii)", "msgCmd":"Trimite embed-ul cu tickete. (doar admini)",
"renameCmd":"Redenumeste un ticket. (fara spatii)", "renameCmd":"Redenumeste un ticket. (fara spatii)",
"closeCmd":"Redenumeste un ticket ticket.", "closeCmd":"Inchide un ticket.",
"deleteCmd":"Sterge un ticket a ticket.", "deleteCmd":"Sterge un ticket.",
"addCmd":"adauga un utilizator la ticket.", "addCmd":"Adauga un utilizator in ticket.",
"removeCmd":"Elimina un utilizator de la ticket.", "removeCmd":"Sterge un utilizator din ticket.",
"reopenCmd":"Re-deschide un ticket dupa ce a fost inchis." "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":{ "buttons":{
"close":"Inchide Ticket-ul", "close":"Inchide ticket-ul",
"delete":"Sterge Ticket-ul", "delete":"Sterge ticket-ul",
"reopen":"Re-deschide Ticket-ul", "reopen":"Re-deschide un ticket",
"sendTranscript":"Trimite copia chat-ului ticket-ului" "closeWithReason":"Inchide cu motiv"
}, },
"messages":{ "messages":{
"reopenTitle":"Ticket re-deschis", "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!*",
"reopenDescription":"Simte-te comfortabil sa vorbesti din nou!",
"closedTitle":"Inchide acest ticket ticket!",
"closedDescription":"Doar administratorii pot vorbi in acest ticket de acum!\n\n*Apasa pe butonele de mai jos pentru a inchide/deschide ticket-ul!*",
"createdTitle":"Ticket Creat!", "createdTitle":"Ticket Creat!",
"createdDescription":"Ticket-ul tau a fost creat, il poti vedea dupa mentionarea ta!", "createdDescription":"Ticket-ul tau a fost creat, poti sa il vezi in canalul pe care ai fost mentionat!",
"newTicketDmTitle":"Ticket Nou!", "newTicketDmTitle":"Ticket nou!",
"closedTicketDmTitle":"Ticket închis!", "closedTicketDmTitle":"Ticket Inchis!",
"deletedTicketDmTitle":"Ticket șters!", "deletedTicketDmTitle":"Ticket Sters!",
"closedTicketDmDescription":"Ticket-ul tau este închis!", "closedTicketDmDescription":"Ticket-ul tau este inchis!",
"deletedTicketDmDescription":"Ticket-ul tau este șters!", "deletedTicketDmDescription":"Ticket-ul tau este sters!",
"reopenTicketDmTitle":"Ticket Re-deschis!", "reopenTicketDmTitle":"Ticket Re-deschis!",
"reopenTicketDmDescription":"Ticket-ul tau este re-deschis!", "reopenTicketDmDescription":"Ticket-ul tau este re-deschis!",
"newTranscriptTitle":"O noua copie a ticket-ului este aici!",
"newTranscriptDescription":"Poti vedea copia ticket-ului in fisierul .txt de mai sus!",
"hereIsTheTranscript":"Aceasta este copia ticket-ului:",
"chooseCategory":"Alege o categorie:", "chooseCategory":"Alege o categorie:",
"gettingdeleted":"Ticket-ul se sterge..." "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"
},
"stats":{
"globalTitle":"Statistici Globale",
"ticketTitle":"Statistici Ticket pentru {0}",
"userTitle":"Statistici utilizator pentru {0}",
"systemTitle":"Statistici Sistem",
"versionTitle":"Versiune Bot",
"ticketsCreated":"Tickete Create",
"ticketsClosed":"Tickets Inchise",
"ticketsDeleted":"Tickete Sterse",
"ticketsReopened":"Tickete Redeschise",
"ticketsAutoclosed":"Tickets Inchise automat",
"transcriptsCreated":"Transcript-uri create",
"startupDate":"Data startup",
"latestUpdate":"Update recent",
"ticketCreatedOn":"Ticket creat pe data",
"ticketCreatedBy":"Ticket Creat de",
"messagesSent":"Mesaje trimise",
"status":"Status",
"participants":"Participanti",
"role":"Rol",
"switches":{
"globalAdmin":"Admin Global",
"ticketAdmin":"Admin Ticket",
"member":"Membru",
"open":"Deschis",
"reopened":"Redeschis",
"closed":"Inchis",
"autoclosed":"Inchis automat"
},
"errorUserNotFound":"Acest utilizator nu poate fi gasit in database-ul nostru!"
} }
} }
+135
View File
@@ -0,0 +1,135 @@
{
"_CREDITS":"Apexo#0723",
"_INFO":"This file is a translation for open ticket 3.5.3",
"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":"Транскрипт здесь доступен"
},
"stats":{
"globalTitle":"Общая статистика",
"ticketTitle":"Статистика тикета для {0}",
"userTitle":"Статистика пользователя для {0}",
"systemTitle":"Системная статистика",
"versionTitle":"Версия бота",
"ticketsCreated":"Тикет создан",
"ticketsClosed":"Тикет закрыт",
"ticketsDeleted":"Тикет удален",
"ticketsReopened":"Тикет переоткрыт",
"ticketsAutoclosed":"Тикет автоматически закрыт",
"transcriptsCreated":"Транскрипт создан",
"startupDate":"Дата запуска",
"latestUpdate":"Последнее обновление",
"ticketCreatedOn":"Тикет создан",
"ticketCreatedBy":"Тикет создан",
"messagesSent":"Сообщение отправлено",
"status":"Статус",
"participants":"Участники",
"role":"Роль",
"switches":{
"globalAdmin":"Главная",
"ticketAdmin":"Тикет",
"member":"Участник",
"open":"Открыть",
"reopened":"Переоткрытый",
"closed":"Закрыт",
"autoclosed":"Автоматически закрыт"
},
"errorUserNotFound":"Участник не найден в базе данных статистики!"
}
}
+202
View File
@@ -0,0 +1,202 @@
{
"examples":{
"en-GB":"english",
"en-US":"english",
"no": "Norwegian",
"nl":"dutch",
"ro":"romanian",
"de":"german",
"cs":"czech",
"fr":"french",
"es-ES":"spanish",
"it":"italian",
"ru":"russian",
"tr": "Türkçe",
"ar": "Arabic",
"MISSING":"portuguese",
"NOTAVAILABLE":"portuguese,czech"
},
"data":{
"help":{
"en-GB":"A list of the available commands.",
"en-US":"A list of the available commands.",
"no":"En liste over 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.",
"ar": "قائمة للكوماندات المتاحة"
},
"message":{
"en-GB":"Spawn an embed with buttons.",
"en-US":"Spawn an embed with buttons.",
"no":"Legg inn en melding i denne kanalen",
"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.",
"ar": "أنشاء أيمبد مع الأزرار."
},
"close":{
"en-GB":"Close a ticket.",
"en-US":"Close a ticket.",
"no":"Lukk 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.",
"ar": "اغلاق تيكت."
},
"delete":{
"en-GB":"Delete a ticket.",
"en-US":"Delete a ticket.",
"no":"Slett 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.",
"ar": "حذف تيكت."
},
"reopen":{
"en-GB":"Re-Open a ticket.",
"en-US":"Re-Open a ticket.",
"no":"Gjenåpne 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ç.",
"ar": "اعادة فتح تيكت."
},
"add":{
"en-GB":"Add another user to a ticket.",
"en-US":"Add another user to a ticket.",
"no":"Legg til en annen bruker til 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.",
"ar": "اضافة مستخدم اخر الى تيكت معين."
},
"remove":{
"en-GB":"Remove a user from a ticket.",
"en-US":"Remove a user from a ticket.",
"no":"Fjern en bruker fra 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.",
"ar": "ازالة مستخدم من تيكت معين."
},
"newticket":{
"en-GB":"Create a ticket",
"en-US":"Create a ticket",
"no":"Lag en ny 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",
"ar": "انشاء تيكت."
},
"rename":{
"en-GB":"Rename a ticket channel.",
"en-US":"Rename a ticket channel.",
"no":"Gi nytt navn til ticket kanalen.",
"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.",
"ar": "اعادة تسمية التيكت."
},
"claim":{
"en-GB":"Claim a ticket.",
"en-US":"Claim a ticket.",
"no":"Overta ticket.",
"nl":"Claim een ticket.",
"ro":" ",
"de":" ",
"cs":" ",
"fr":" ",
"es-ES":" ",
"it":" ",
"ru":"Взять тикет",
"tr":"Bilet talep et.",
"ar": "تعيين التيكت"
},
"unclaim":{
"en-GB":"Un-claim a ticket.",
"en-US":"Un-claim a ticket.",
"no":"Frigjør ticket.",
"nl":"Ontclaim een ticket.",
"ro":" ",
"de":" ",
"cs":" ",
"fr":" ",
"es-ES":" ",
"it":" ",
"ru":"Снять тикет",
"tr":"Bileti iptal et.",
"ar": "ازالة التعيين من شخص الى التيكت"
},
"category":{
"en-GB":"Change ticket type.",
"en-US":"Change ticket type.",
"no":"Endre ticket type.",
"nl":"Verander ticket type.",
"ro":" ",
"de":" ",
"cs":" ",
"fr":" ",
"es-ES":" ",
"it":" ",
"ru":"Изменить тип тикета",
"tr":"Bilet türünü değiştir.",
"ar": "تغيير نوع التيكت"
}
}
}
+135
View File
@@ -0,0 +1,135 @@
{
"_CREDITS":"n1kkec#5341",
"_INFO":"This file is a translation for open ticket 3.5.3",
"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"
},
"stats":{
"globalTitle":"Global Stats",
"ticketTitle":"Ticket Stats for {0}",
"userTitle":"User Stats for {0}",
"systemTitle":"System Stats",
"versionTitle":"Bot Version",
"ticketsCreated":"Tickets Created",
"ticketsClosed":"Tickets Closed",
"ticketsDeleted":"Tickets Deleted",
"ticketsReopened":"Tickets Reopened",
"ticketsAutoclosed":"Tickets Autoclosed",
"transcriptsCreated":"Transcripts Created",
"startupDate":"Startup Date",
"latestUpdate":"Latest Update",
"ticketCreatedOn":"Ticket Created On",
"ticketCreatedBy":"Ticket Created By",
"messagesSent":"Messages Sent",
"status":"Status",
"participants":"Participants",
"role":"Role",
"switches":{
"globalAdmin":"Global Admin",
"ticketAdmin":"Ticket Admin",
"member":"Member",
"open":"Open",
"reopened":"Reopened",
"closed":"Closed",
"autoclosed":"Autoclosed"
},
"errorUserNotFound":"This user can't be found in the stats database!"
}
}
+84 -29
View File
@@ -1,9 +1,13 @@
{ {
"_CREDITS":"Redactado#1673 & josuens14#5267",
"_INFO":"This file is a translation for open ticket 3.5.3",
"errors":{ "errors":{
"missingArgsTitle":"¡Argumentos inválidos!", "missingArgsTitle":"¡Argumentos inválidos!",
"missingArgsDescription":"Argumento faltante.", "missingArgsDescription":"Argumento faltante.",
"noPermsTitle":"¡Sin permisos!", "noPermsTitle":"¡Sin permisos!",
"noPermsDescription":"¡No tienes permiso para usar este comando.!\n¡Necesitas el permiso `ADMINISTRATOR` permiso o tener uno de los roles permitidos!", "noPermsDescription":"Necesitas el permiso de `ADMINISTRADOR` o estar en la lista de roles permitidos!",
"noPermsDelete":"Solo los administradores pueden eliminar un ticket.!",
"chooseFromListTitle":"ID Invalida", "chooseFromListTitle":"ID Invalida",
"chooseFromListDescription":"Elije una de las ID de abajo:", "chooseFromListDescription":"Elije una de las ID de abajo:",
"boterror":"¡Error del bot!", "boterror":"¡Error del bot!",
@@ -14,30 +18,31 @@
"anotherOption":"¡Esta opción no es un ticket, si no otra cosa!", "anotherOption":"¡Esta opción no es un ticket, si no otra cosa!",
"maxAmountTitle":"¡Máxima cantidad alcanzada!", "maxAmountTitle":"¡Máxima cantidad alcanzada!",
"maxAmountDescription":"¡Has alcanzado la máxima cantidad de tickets permitida!\n¡Por lo que no puedes crear otro!", "maxAmountDescription":"¡Has alcanzado la máxima cantidad de tickets permitida!\n¡Por lo que no puedes crear otro!",
"somethingWentWrong":"**¡Algo salió mal!**\n¡Prueba dentro de un rato!", "somethingWentWrong":"**¡Algo salió mal!**\n¡Prueba dentro de un rato!"
"somethingWentWrongTranscript":"**¡Algo salió mal al hacer el transcript!**\n¡Prueba en otro momento!"
}, },
"commands":{ "commands":{
"userAddedTitle":"¡Usuario agregado!", "userAddedTitle":"Se agregó {0} al ticket!",
"userAddedDescription":"¡{0} fué agregado al ticket!", "userRemovedTitle":"Se eliminó {0} del ticket!",
"userRemovedTitle":"¡Usuario eliminado!", "renameTitle":"Cambió el nombre a {0}!",
"userRemovedDescription":"¡{0} fué eliminado del ticket!", "closeTitle":"Cerró este ticket!",
"deleteTitle":"Eliminando este ticket...",
"reopenTitle":"Re-abrió este boleto!",
"claimTitle":"Este ticket fué reclamado por {0}",
"unclaimTitle":"¡Este ticket se encuentra desatendido!",
"changeTitle":"¡Cambiado el tipo de ticket a {0}!",
"renameTitle":"¡El nombre fué cambiado!", "statsTitle":"¡Aquí están las estadísticas para {0}!",
"renameWarning":"Aviso: Solo puedes cambiar el nombre 2 veces por minuto.\n(Esto es por limitaciones de Discord)", "autocloseTitle":"¡Este ticket será cerrado después de {0}!",
"autocloseRejectTitle":"¡Cierre automático del ticket desactivado!",
"autocloseWarn":"¡Esto solo afecta tickets inactivos!",
"closeTitle":"¡Cierra el ticket!", "goToTicket":"ir al ticket",
"closeDescription":"¡Puedes cerrar el ticket con el botón de abajo!", "ticketWarning":"La inserción está en el mensaje a continuación!",
"deleteTitle":"¡Elimina el ticket!", "maxTicketWarning":"**Advertencia:** _Solo puedes crear {0} ticket(s) a la vez!_"
"deleteDescription":"¡Puedes eliminar el ticket con el botón de abajo!",
"reopenTitle":"¡Re-Abre el ticket!",
"reopenDescription":"¡Puedes re-abrir el ticket con el botón de abajo!",
"ticketWarning":"¡El emblema está en el mensaje de abajo!",
"maxTicketWarning":"**Aviso:** _Solo puedes poseer {0} ticket(s) al mismo tiempo!_"
}, },
"helpMenu":{ "helpMenu":{
"title":"Menú de ayuda:", "title":"Comandos disponibles:",
"header1":"**¡Dirígete a {0} para crear un nuevo ticket!**\n\n", "header1":"**¡Dirígete a {0} para crear un nuevo ticket!**\n\n",
"header2":"**¡Ejecuta el comando `/new` o `/ticket` para crear un ticket!**\n\n", "header2":"**¡Ejecuta el comando `/new` o `/ticket` para crear un ticket!**\n\n",
@@ -47,18 +52,20 @@
"deleteCmd":"Eliminar un ticket.", "deleteCmd":"Eliminar un ticket.",
"addCmd":"Agregar un usuario al ticket.", "addCmd":"Agregar un usuario al ticket.",
"removeCmd":"Eliminar un usuario del ticket.", "removeCmd":"Eliminar un usuario del ticket.",
"reopenCmd":"Re-Abre un ticket después de que este se vea cerrado." "reopenCmd":"Re-Abre un ticket después de que este se vea cerrado.",
"changeCmd":"Cambia el tipo de ticket.",
"claimCmd":"Reclama un ticket.",
"unclaimCmd":"Desatiende un ticket.",
"statsCmd":"Mira las estadísticas de los tickets.",
"autocloseCmd":"Establece un temporizador para cerrar el ticket."
}, },
"buttons":{ "buttons":{
"close":"Cerrar ticket.", "close":"Cerrar ticket.",
"delete":"Eliminar ticket", "delete":"Eliminar ticket",
"reopen":"Re-Abrir ticket", "reopen":"Re-Abrir ticket",
"sendTranscript":"Obtener transcript." "closeWithReason":"cerrar con razón"
}, },
"messages":{ "messages":{
"reopenTitle":"¡Ticket Re-Abierto!",
"reopenDescription":"¡Siéntete libre de hablar de nuevo!",
"closedTitle":"¡Ticket cerrado!",
"closedDescription":"¡Solo admins pueden hablar ahora en este ticket!\n\n*¡Presiona en el botón de abajo para eliminar o re-abrir el ticket!*", "closedDescription":"¡Solo admins pueden hablar ahora en este ticket!\n\n*¡Presiona en el botón de abajo para eliminar o re-abrir el ticket!*",
"createdTitle":"¡Ticket creado!", "createdTitle":"¡Ticket creado!",
"createdDescription":"¡Ticket creado, también te he mencionado en él!", "createdDescription":"¡Ticket creado, también te he mencionado en él!",
@@ -70,11 +77,59 @@
"deletedTicketDmDescription":"¡Tu ticket fué eliminado!", "deletedTicketDmDescription":"¡Tu ticket fué eliminado!",
"reopenTicketDmTitle":"¡Ticket re-abierto!", "reopenTicketDmTitle":"¡Ticket re-abierto!",
"reopenTicketDmDescription":"¡Tu ticket se vió abierto de nuevo!", "reopenTicketDmDescription":"¡Tu ticket se vió abierto de nuevo!",
"newTranscriptTitle":"¡Un nuevo transcript está aquí!",
"newTranscriptDescription":"¡Puedes encontrar el transcript en el archivo de texto que se muestra arriba!", "chooseCategory":"Elije una categoría:",
"hereIsTheTranscript":"Aquí está el transcript:", "gettingdeleted":"El ticket se está viendo eliminado...",
"chooseCategory":"elije una categoría:", "none":"Ninguna.",
"gettingdeleted":"El ticket se está viendo eliminado..." "reason":"Razón",
"createdat":"creado el",
"openedby":"abierto por",
"deletedby":"eliminado por",
"closedby":"cerrado por",
"modalreason":"Cúal es la razón para cerrar este ticket?",
"chooseATicket": "Elije un ticket"
},
"transcripts":{
"title":"Transcripción",
"processed":"La transcripción del ticket está siendo procesada...",
"wait":"¡Por favor, espere!",
"estimated":"Tiempo estimado",
"available":"La transcripción estará disponible aquí"
},
"stats":{
"globalTitle":"Estadísticas Globales",
"ticketTitle":"Estadísitcas para el ticket {0}",
"userTitle":"Estadísticas para el usuario {0}",
"systemTitle":"Estadísticas del sistema",
"versionTitle":"Versión del bot",
"ticketsCreated":"Tickets Creados",
"ticketsClosed":"Tickets Cerrados",
"ticketsDeleted":"Tickets Eliminados",
"ticketsReopened":"Tickets Reabiertos",
"ticketsAutoclosed":"Tickets Cerrados automáticamente",
"transcriptsCreated":"Transcripciones Creadas",
"startupDate":"Fecha de Inicio",
"latestUpdate":"Última Actualización",
"ticketCreatedOn":"Ticket creado el",
"ticketCreatedBy":"Ticket creado por",
"messagesSent":"Mensajes enviados",
"status":"Estado",
"participants":"Participantes",
"role":"Rol",
"switches":{
"globalAdmin":"Admin Global",
"ticketAdmin":"Admin del Ticket",
"member":"Miembro",
"open":"Abierto",
"reopened":"Reabierto",
"closed":"Cerrado",
"autoclosed":"Cerrado automáticamente"
},
"errorUserNotFound":"¡Este usuario no pudo ser encontrado en la base de datos de estadísitcas!"
} }
} }

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