djs-builder 0.7.0 โ 0.7.1-8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2137 -272
- package/function/dash.js +705 -210
- package/function/function.js +255 -8
- package/function/level.js +337 -10
- package/function/log.js +407 -332
- package/handler/helper.js +46 -25
- package/handler/starter.js +47 -13
- package/package.json +23 -9
- package/views/dashboard.ejs +52 -18
- package/views/giveaways.ejs +1 -0
- package/views/guild.ejs +4 -0
- package/views/levels.ejs +672 -32
- package/views/logs.ejs +624 -0
package/README.md
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
**Welcome to the ultimate Discord Bot Utilities package! ๐ฅ**
|
|
6
6
|
Boost your Discord bot development with ease, speed, and all-in-one features.
|
|
7
7
|
|
|
8
|
+
[](https://discord.gg/uYcKCZk3)
|
|
9
|
+
|
|
8
10
|
---
|
|
9
11
|
|
|
10
12
|
## ๐ Table of Contents
|
|
@@ -64,6 +66,7 @@ const starterOptions = {
|
|
|
64
66
|
|
|
65
67
|
database: {
|
|
66
68
|
url: "mongodb://localhost:27017", // ๐พ MongoDB connection
|
|
69
|
+
dbName: "yourDatabaseName", // ๐ Optional: Specify database name (default: "test")
|
|
67
70
|
},
|
|
68
71
|
|
|
69
72
|
anticrash: {
|
|
@@ -73,11 +76,10 @@ const starterOptions = {
|
|
|
73
76
|
|
|
74
77
|
// ๐ Dashboard Configuration (Full docs at the end of this page)
|
|
75
78
|
dashboard: {
|
|
76
|
-
clientID: "YOUR_DISCORD_CLIENT_ID", // ๐ Discord Application Client ID
|
|
77
79
|
clientSecret: "YOUR_DISCORD_CLIENT_SECRET", // ๐ Discord Application Client Secret
|
|
78
|
-
callbackURL: "http://localhost:3000/auth/discord/callback", // ๐ OAuth2 Callback URL
|
|
79
|
-
sessionSecret: "your-super-secret-key",
|
|
80
|
-
port: 3000,
|
|
80
|
+
callbackURL: "http://localhost:3000/auth/discord/callback", // ๐ OAuth2 Callback URL (OPTINAL)
|
|
81
|
+
sessionSecret: "your-super-secret-key", // ๐ Session encryption secret
|
|
82
|
+
port: 3000, // ๐ Dashboard port (OPTINAL / default: 3000)
|
|
81
83
|
},
|
|
82
84
|
};
|
|
83
85
|
|
|
@@ -100,6 +102,7 @@ await starter(client, starterOptions);
|
|
|
100
102
|
|
|
101
103
|
- Connects automatically to MongoDB ๐พ.
|
|
102
104
|
- Useful for bots with persistent data storage.
|
|
105
|
+
- Specify the database name using the `dbName` option. If not specified, MongoDB uses "test" as the default database name.
|
|
103
106
|
|
|
104
107
|
#### 3๏ธโฃ Anticrash System
|
|
105
108
|
|
|
@@ -208,6 +211,12 @@ const actionRow = new CreateRow([
|
|
|
208
211
|
emoji: "๐",
|
|
209
212
|
disabled: true, // Button is disabled
|
|
210
213
|
},
|
|
214
|
+
{
|
|
215
|
+
style: 5,
|
|
216
|
+
label: "link",
|
|
217
|
+
emoji: "๐"
|
|
218
|
+
url : "https://discord.gg/z9GpYsYF" // for url button
|
|
219
|
+
}
|
|
211
220
|
],
|
|
212
221
|
|
|
213
222
|
// ๐น Row #2: Select Menu
|
|
@@ -242,7 +251,7 @@ const actionRow = new CreateRow([
|
|
|
242
251
|
disabled: false, // Disable the entire menu
|
|
243
252
|
defaultValues: [
|
|
244
253
|
// For role/user/channel menus
|
|
245
|
-
{ id: "123456789012345678"
|
|
254
|
+
{ id: "123456789012345678" }, // Pre-selected
|
|
246
255
|
],
|
|
247
256
|
channelTypes: [0, 2], // Only for ChannelSelectMenu (0 = Text, 2 = Voice)
|
|
248
257
|
},
|
|
@@ -261,6 +270,7 @@ const actionRow = new CreateRow([
|
|
|
261
270
|
- `label` โ Button text
|
|
262
271
|
- `emoji` โ Displayed emoji
|
|
263
272
|
- `disabled` โ true = button is unclickable
|
|
273
|
+
- `url` โ requiier for like button (style : 5)
|
|
264
274
|
|
|
265
275
|
#### ๐น Select Menus
|
|
266
276
|
|
|
@@ -350,210 +360,1966 @@ console.log(
|
|
|
350
360
|
|
|
351
361
|
---
|
|
352
362
|
|
|
353
|
-
### ๐ Fun Emoji example:
|
|
363
|
+
### ๐ Fun Emoji example:
|
|
364
|
+
|
|
365
|
+
```js
|
|
366
|
+
console.log(
|
|
367
|
+
CreateBar(6, 10, {
|
|
368
|
+
length: 12,
|
|
369
|
+
fill: "๐ฅ",
|
|
370
|
+
empty: "โ๏ธ",
|
|
371
|
+
partialChar: "๐",
|
|
372
|
+
showPercent: true,
|
|
373
|
+
left: "ยซ",
|
|
374
|
+
right: "ยป",
|
|
375
|
+
})
|
|
376
|
+
);
|
|
377
|
+
|
|
378
|
+
// Output: ยซ๐ฅ๐ฅ๐ฅ๐ฅ๐ฅ๐ฅ๐โ๏ธโ๏ธโ๏ธโ๏ธยป 60%
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
### ๐น Options Summary
|
|
384
|
+
|
|
385
|
+
- `length` โ Total number of symbols
|
|
386
|
+
- `fill` โ Symbol for filled portion
|
|
387
|
+
- `empty` โ Symbol for empty portion
|
|
388
|
+
- `partialChar` โ Symbol for partial fill (e.g., half-filled)
|
|
389
|
+
- `showPercent` โ Show percentage at the end
|
|
390
|
+
- `left` / `right` โ Brackets or edges for the bar
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
### ๐น Notes
|
|
395
|
+
|
|
396
|
+
- Supports **fractional values** for partial fill
|
|
397
|
+
- Fully **customizable with any emoji or character** ๐จ
|
|
398
|
+
- Great for **progress, stats, experience bars, or loading indicators**
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
</details>
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
<details>
|
|
407
|
+
<summary>CreateModal ๐ณ</summary>
|
|
408
|
+
|
|
409
|
+
**๐ณ CreateModal โ Easily create Discord Modals with Text Inputs, Menus, Files, and Labels โจ**
|
|
410
|
+
|
|
411
|
+
`CreateModal` is a powerful utility to build Discord **Modals**. It supports:
|
|
412
|
+
|
|
413
|
+
- **Text Inputs** ๐
|
|
414
|
+
- **Select Menus** ๐ฏ (`string`, `role`, `user`, `channel`)
|
|
415
|
+
- **File Uploads** ๐
|
|
416
|
+
- **Text Displays** ๐ท๏ธ
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
### ๐ Example Usage:
|
|
421
|
+
|
|
422
|
+
```js
|
|
423
|
+
const { CreateModal } = require("djs-builder");
|
|
424
|
+
|
|
425
|
+
const modal = CreateModal({
|
|
426
|
+
id: "myModal",
|
|
427
|
+
title: "User Information",
|
|
428
|
+
components: [
|
|
429
|
+
{
|
|
430
|
+
type: "textInput",
|
|
431
|
+
components: [
|
|
432
|
+
{
|
|
433
|
+
label: "Your Name",
|
|
434
|
+
id: "name",
|
|
435
|
+
style: 1, // 1: Short, 2: Paragraph
|
|
436
|
+
placeholder: "Enter your name",
|
|
437
|
+
required: true,
|
|
438
|
+
minLength: 2,
|
|
439
|
+
maxLength: 50,
|
|
440
|
+
},
|
|
441
|
+
],
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
type: "menu",
|
|
445
|
+
components: {
|
|
446
|
+
type: "string",
|
|
447
|
+
options: {
|
|
448
|
+
id: "favoriteColor",
|
|
449
|
+
placeholder: "Choose your favorite color",
|
|
450
|
+
min: 1,
|
|
451
|
+
max: 1,
|
|
452
|
+
data: [
|
|
453
|
+
{
|
|
454
|
+
label: "Red",
|
|
455
|
+
value: "red",
|
|
456
|
+
description: "A bold color",
|
|
457
|
+
emoji: "๐ด",
|
|
458
|
+
default: false,
|
|
459
|
+
},
|
|
460
|
+
{
|
|
461
|
+
label: "Blue",
|
|
462
|
+
value: "blue",
|
|
463
|
+
description: "A calm color",
|
|
464
|
+
emoji: "๐ต",
|
|
465
|
+
},
|
|
466
|
+
],
|
|
467
|
+
label: "label",
|
|
468
|
+
value: "value",
|
|
469
|
+
description: "description",
|
|
470
|
+
emoji: "emoji",
|
|
471
|
+
disabled: false,
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
type: "file",
|
|
477
|
+
components: {
|
|
478
|
+
id: "avatar",
|
|
479
|
+
label: "Upload Avatar",
|
|
480
|
+
description: "Optional avatar image",
|
|
481
|
+
},
|
|
482
|
+
},
|
|
483
|
+
{
|
|
484
|
+
type: "text",
|
|
485
|
+
components: {
|
|
486
|
+
content: "Thank you for your input!",
|
|
487
|
+
},
|
|
488
|
+
},
|
|
489
|
+
],
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
// Show the modal
|
|
493
|
+
await interaction.showModal(modal);
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
---
|
|
497
|
+
|
|
498
|
+
### ๐ Examples for Each Component Type:
|
|
499
|
+
|
|
500
|
+
#### ๐น Text Input Example:
|
|
501
|
+
|
|
502
|
+
```js
|
|
503
|
+
{
|
|
504
|
+
type: "textInput",
|
|
505
|
+
components: [
|
|
506
|
+
{
|
|
507
|
+
label: "Your Age",
|
|
508
|
+
id: "age",
|
|
509
|
+
style: 1, // Short input
|
|
510
|
+
placeholder: "Enter your age",
|
|
511
|
+
required: true,
|
|
512
|
+
minLength: 1,
|
|
513
|
+
maxLength: 3,
|
|
514
|
+
value: "18", // Pre-filled
|
|
515
|
+
},
|
|
516
|
+
],
|
|
517
|
+
},
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
#### ๐น Menu Example:
|
|
521
|
+
|
|
522
|
+
```js
|
|
523
|
+
{
|
|
524
|
+
type: "menu",
|
|
525
|
+
components: {
|
|
526
|
+
type: "string",
|
|
527
|
+
options: {
|
|
528
|
+
id: "country",
|
|
529
|
+
mine_label: "Choose Your Country", // Label displayed above the menu
|
|
530
|
+
mine_description: "Please select your country from the list below", // Optional description
|
|
531
|
+
placeholder: "Select your country",
|
|
532
|
+
min: 1,
|
|
533
|
+
max: 1,
|
|
534
|
+
data: [
|
|
535
|
+
{
|
|
536
|
+
name: "USA",
|
|
537
|
+
id: "usa",
|
|
538
|
+
desc: "United States",
|
|
539
|
+
icon: "๐บ๐ธ",
|
|
540
|
+
default: true, // This option is pre-selected
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
name: "Canada",
|
|
544
|
+
id: "canada",
|
|
545
|
+
desc: "Canada",
|
|
546
|
+
icon: "๐จ๐ฆ",
|
|
547
|
+
},
|
|
548
|
+
],
|
|
549
|
+
label: "name", // Maps to 'name' field in data
|
|
550
|
+
value: "id", // Maps to 'id' field in data
|
|
551
|
+
description: "desc", // Maps to 'desc' field
|
|
552
|
+
emoji: "icon", // Maps to 'icon' field
|
|
553
|
+
disabled: false,
|
|
554
|
+
},
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
#### ๐น File Example:
|
|
560
|
+
|
|
561
|
+
```js
|
|
562
|
+
{
|
|
563
|
+
type: "file",
|
|
564
|
+
components: {
|
|
565
|
+
id: "document",
|
|
566
|
+
label: "Upload Document",
|
|
567
|
+
description: "Upload a PDF or image",
|
|
568
|
+
},
|
|
569
|
+
},
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
#### ๐น Label Example:
|
|
573
|
+
|
|
574
|
+
```js
|
|
575
|
+
{
|
|
576
|
+
type: "text",
|
|
577
|
+
components: {
|
|
578
|
+
content: "Please fill out the form above.",
|
|
579
|
+
},
|
|
580
|
+
},
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
---
|
|
584
|
+
|
|
585
|
+
### ๏ฟฝ๐ Explanation
|
|
586
|
+
|
|
587
|
+
#### ๐น Text Input
|
|
588
|
+
|
|
589
|
+
- `label` โ Label for the input field
|
|
590
|
+
- `id` โ customId for the input
|
|
591
|
+
- `style` โ 1: Short, 2: Paragraph
|
|
592
|
+
- `placeholder` โ Placeholder text
|
|
593
|
+
- `required` โ true/false
|
|
594
|
+
- `minLength` / `maxLength` โ Min/Max characters
|
|
595
|
+
- `value` โ Pre-filled value
|
|
596
|
+
|
|
597
|
+
#### ๐น Menu
|
|
598
|
+
|
|
599
|
+
Same as CreateRow select menus.
|
|
600
|
+
|
|
601
|
+
- `type` โ `"string" | "user" | "role" | "channel"`
|
|
602
|
+
- `id` โ customId for menu
|
|
603
|
+
- `mine_label` โ Label displayed above the menu component (defaults to "Select an option")
|
|
604
|
+
- `mine_description` โ Description text displayed below the menu label (optional)
|
|
605
|
+
- `placeholder` โ Text shown before selection
|
|
606
|
+
- `min` / `max` โ Min/Max selectable values
|
|
607
|
+
- `data` โ Options array (for string select only)
|
|
608
|
+
|
|
609
|
+
- `label` โ Visible text (maps to the field specified in `label` key)
|
|
610
|
+
- `value` โ Internal value (maps to the field specified in `value` key)
|
|
611
|
+
- `description` โ Short description (maps to the field specified in `description` key)
|
|
612
|
+
- `emoji` โ Option emoji (maps to the field specified in `emoji` key)
|
|
613
|
+
- `default` โ Pre-selected option (true/false in data array)
|
|
614
|
+
|
|
615
|
+
- `label` โ Key in data to use as label (e.g., "name")
|
|
616
|
+
- `value` โ Key in data to use as value (e.g., "id")
|
|
617
|
+
- `description` โ Key in data to use as description (e.g., "desc")
|
|
618
|
+
- `emoji` โ Key in data to use as emoji (e.g., "icon")
|
|
619
|
+
- `disabled` โ Disable menu completely
|
|
620
|
+
- `defaultValues` โ Pre-selected user/role/channel options (for non-string menus)
|
|
621
|
+
- `channelTypes` โ Restrict selectable channel types (for channel menu)
|
|
622
|
+
|
|
623
|
+
#### ๐น File
|
|
624
|
+
|
|
625
|
+
- `id` โ customId for the file upload
|
|
626
|
+
- `label` โ Label
|
|
627
|
+
- `description` โ Description
|
|
628
|
+
|
|
629
|
+
#### ๐น text
|
|
630
|
+
|
|
631
|
+
- `content` โ Text to display
|
|
632
|
+
|
|
633
|
+
---
|
|
634
|
+
|
|
635
|
+
### ๐น Notes
|
|
636
|
+
|
|
637
|
+
- Supports multiple components in one modal
|
|
638
|
+
- Fully customizable with Discord.js ModalBuilder
|
|
639
|
+
|
|
640
|
+
</details>
|
|
641
|
+
|
|
642
|
+
---
|
|
643
|
+
|
|
644
|
+
<details>
|
|
645
|
+
<summary>CreateComponents ๐งฉ</summary>
|
|
646
|
+
|
|
647
|
+
**๐งฉ CreateComponents โ Build Advanced Discord UI Components with Containers, Sections & Media โจ**
|
|
648
|
+
|
|
649
|
+
`CreateComponents` is a powerful utility to build Discord's **new UI components**. It supports:
|
|
650
|
+
|
|
651
|
+
- **Text Displays** ๐
|
|
652
|
+
- **Separators** โ
|
|
653
|
+
- **Media Galleries** ๐ผ๏ธ
|
|
654
|
+
- **File Attachments** ๐
|
|
655
|
+
- **Buttons** ๐
|
|
656
|
+
- **Select Menus** ๐ฏ (`string`, `role`, `user`, `channel`)
|
|
657
|
+
- **Sections with Accessories** ๐ฆ (Thumbnails & Buttons)
|
|
658
|
+
- **Containers** ๐ฆ (Group all components together)
|
|
659
|
+
|
|
660
|
+
---
|
|
661
|
+
|
|
662
|
+
### ๐ Example Usage (Array Mode):
|
|
663
|
+
|
|
664
|
+
```js
|
|
665
|
+
const { CreateComponents } = require("djs-builder");
|
|
666
|
+
|
|
667
|
+
const components = await CreateComponents("array", [
|
|
668
|
+
{
|
|
669
|
+
type: "text",
|
|
670
|
+
content: "Welcome to our server! ๐",
|
|
671
|
+
},
|
|
672
|
+
{
|
|
673
|
+
type: "separator",
|
|
674
|
+
divider: true,
|
|
675
|
+
spacing: 1, // 1: Small, 2: Large
|
|
676
|
+
},
|
|
677
|
+
{
|
|
678
|
+
type: "media",
|
|
679
|
+
links: [
|
|
680
|
+
"https://example.com/image1.png",
|
|
681
|
+
{
|
|
682
|
+
url: "https://example.com/image2.png",
|
|
683
|
+
description: "A cool image",
|
|
684
|
+
spoiler: true,
|
|
685
|
+
},
|
|
686
|
+
],
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
type: "button",
|
|
690
|
+
components: [
|
|
691
|
+
{
|
|
692
|
+
id: "btn_1",
|
|
693
|
+
style: 1, // 1: Primary, 2: Secondary, 3: Success, 4: Danger, 5: Link
|
|
694
|
+
label: "Click Me!",
|
|
695
|
+
emoji: "๐",
|
|
696
|
+
},
|
|
697
|
+
{
|
|
698
|
+
id: "btn_2",
|
|
699
|
+
style: 3,
|
|
700
|
+
label: "Confirm",
|
|
701
|
+
},
|
|
702
|
+
],
|
|
703
|
+
},
|
|
704
|
+
]);
|
|
705
|
+
|
|
706
|
+
// Send the components
|
|
707
|
+
await channel.send({
|
|
708
|
+
flags: 32768,
|
|
709
|
+
components : components
|
|
710
|
+
});
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
---
|
|
714
|
+
|
|
715
|
+
### ๐ Example Usage (Container Mode):
|
|
716
|
+
|
|
717
|
+
```js
|
|
718
|
+
const { CreateComponents } = require("djs-builder");
|
|
719
|
+
|
|
720
|
+
const components = await CreateComponents(true, [
|
|
721
|
+
{
|
|
722
|
+
type: "text",
|
|
723
|
+
content: "# ๐ข Server Announcement\nWelcome everyone!",
|
|
724
|
+
},
|
|
725
|
+
{
|
|
726
|
+
type: "separator",
|
|
727
|
+
divider: true,
|
|
728
|
+
},
|
|
729
|
+
{
|
|
730
|
+
type: "section",
|
|
731
|
+
content: "Check out our latest updates and news!",
|
|
732
|
+
accessory: {
|
|
733
|
+
type: "thumbnail",
|
|
734
|
+
url: "https://example.com/thumbnail.png",
|
|
735
|
+
description: "News Image",
|
|
736
|
+
},
|
|
737
|
+
},
|
|
738
|
+
{
|
|
739
|
+
type: "section",
|
|
740
|
+
content: "**Click below to get your roles!**",
|
|
741
|
+
accessory: {
|
|
742
|
+
type: "button",
|
|
743
|
+
id: "get_roles",
|
|
744
|
+
style: 1,
|
|
745
|
+
label: "Get Roles",
|
|
746
|
+
emoji: "๐ญ",
|
|
747
|
+
},
|
|
748
|
+
},
|
|
749
|
+
{
|
|
750
|
+
type: "media",
|
|
751
|
+
links: ["https://example.com/banner.png"],
|
|
752
|
+
},
|
|
753
|
+
{
|
|
754
|
+
type: "button",
|
|
755
|
+
components: [
|
|
756
|
+
{ id: "rules", style: 2, label: "๐ Rules", emoji: "๐" },
|
|
757
|
+
{ id: "help", style: 2, label: "โ Help", emoji: "โ" },
|
|
758
|
+
{ style: 5, label: "๐ Website", url: "https://example.com" },
|
|
759
|
+
],
|
|
760
|
+
},
|
|
761
|
+
]);
|
|
762
|
+
|
|
763
|
+
// Send with container
|
|
764
|
+
await channel.send({ components, flags: 32768 }); // flags for components v2
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
---
|
|
768
|
+
|
|
769
|
+
### ๐ Examples for Each Component Type:
|
|
770
|
+
|
|
771
|
+
---
|
|
772
|
+
|
|
773
|
+
<details>
|
|
774
|
+
<summary>๐น Text Component Examples</summary>
|
|
775
|
+
|
|
776
|
+
#### ๐ Simple Text:
|
|
777
|
+
|
|
778
|
+
```js
|
|
779
|
+
{
|
|
780
|
+
type: "text",
|
|
781
|
+
content: "Hello World! ๐",
|
|
782
|
+
}
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
#### ๐ Text with Markdown:
|
|
786
|
+
|
|
787
|
+
```js
|
|
788
|
+
{
|
|
789
|
+
type: "text",
|
|
790
|
+
content: "# ๐ข Announcement\n**Important:** Server maintenance tonight!",
|
|
791
|
+
}
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
#### ๐ Text with Multiple Lines:
|
|
795
|
+
|
|
796
|
+
```js
|
|
797
|
+
{
|
|
798
|
+
type: "text",
|
|
799
|
+
content: `## ๐ฎ Game Stats
|
|
800
|
+
|
|
801
|
+
**Player:** Ahmed
|
|
802
|
+
**Level:** 50
|
|
803
|
+
**XP:** 12,500 / 15,000
|
|
804
|
+
**Rank:** Diamond ๐`,
|
|
805
|
+
}
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
#### ๐ Text with Emojis & Formatting:
|
|
809
|
+
|
|
810
|
+
```js
|
|
811
|
+
{
|
|
812
|
+
type: "text",
|
|
813
|
+
content: ">>> ๐ก **Tip:** Use `/help` to see all commands!\n\n*This message will auto-delete in 30 seconds*",
|
|
814
|
+
}
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
</details>
|
|
818
|
+
|
|
819
|
+
---
|
|
820
|
+
|
|
821
|
+
<details>
|
|
822
|
+
<summary>โ Separator Component Examples</summary>
|
|
823
|
+
|
|
824
|
+
**โ Separator โ Add spacing and dividers between components**
|
|
825
|
+
|
|
826
|
+
The separator component allows you to add visual breaks between other components with customizable spacing and divider lines.
|
|
827
|
+
|
|
828
|
+
---
|
|
829
|
+
|
|
830
|
+
### ๐ Separator Options
|
|
831
|
+
|
|
832
|
+
| Option | Type | Default | Description |
|
|
833
|
+
| --------- | --------- | ------- | -------------------------------------------------- |
|
|
834
|
+
| `type` | `string` | โ | Must be `"separator"` |
|
|
835
|
+
| `divider` | `boolean` | `false` | Show a horizontal dividing line |
|
|
836
|
+
| `spacing` | `number` | `1` | Spacing size: `1` (Small) or `2` (Large) |
|
|
837
|
+
|
|
838
|
+
---
|
|
839
|
+
|
|
840
|
+
#### ๐ Simple Divider Line:
|
|
841
|
+
|
|
842
|
+
```js
|
|
843
|
+
{
|
|
844
|
+
type: "separator",
|
|
845
|
+
divider: true,
|
|
846
|
+
}
|
|
847
|
+
```
|
|
848
|
+
**Result:** A thin horizontal line appears between components.
|
|
849
|
+
|
|
850
|
+
---
|
|
851
|
+
|
|
852
|
+
#### ๐ Separator without Line (Spacing Only):
|
|
853
|
+
|
|
854
|
+
```js
|
|
855
|
+
{
|
|
856
|
+
type: "separator",
|
|
857
|
+
divider: false,
|
|
858
|
+
spacing: 2, // Large spacing
|
|
859
|
+
}
|
|
860
|
+
```
|
|
861
|
+
**Result:** Empty space without any visible line - useful for visual grouping.
|
|
862
|
+
|
|
863
|
+
---
|
|
864
|
+
|
|
865
|
+
#### ๐ Small Spacing with Divider:
|
|
866
|
+
|
|
867
|
+
```js
|
|
868
|
+
{
|
|
869
|
+
type: "separator",
|
|
870
|
+
divider: true,
|
|
871
|
+
spacing: 1, // Small spacing (default)
|
|
872
|
+
}
|
|
873
|
+
```
|
|
874
|
+
**Result:** A divider line with minimal padding above and below.
|
|
875
|
+
|
|
876
|
+
---
|
|
877
|
+
|
|
878
|
+
#### ๐ Large Spacing with Divider:
|
|
879
|
+
|
|
880
|
+
```js
|
|
881
|
+
{
|
|
882
|
+
type: "separator",
|
|
883
|
+
divider: true,
|
|
884
|
+
spacing: 2, // Large spacing
|
|
885
|
+
}
|
|
886
|
+
```
|
|
887
|
+
**Result:** A divider line with more padding - creates stronger visual separation.
|
|
888
|
+
|
|
889
|
+
---
|
|
890
|
+
|
|
891
|
+
### ๐ก When to Use Each Option:
|
|
892
|
+
|
|
893
|
+
| Scenario | `divider` | `spacing` |
|
|
894
|
+
| ------------------------------------- | --------- | --------- |
|
|
895
|
+
| Separate major sections | `true` | `2` |
|
|
896
|
+
| Separate sub-sections | `true` | `1` |
|
|
897
|
+
| Group related items visually | `false` | `1` |
|
|
898
|
+
| Create breathing room between content | `false` | `2` |
|
|
899
|
+
| Minimal separation | `false` | `1` |
|
|
900
|
+
|
|
901
|
+
</details>
|
|
902
|
+
|
|
903
|
+
---
|
|
904
|
+
|
|
905
|
+
<details>
|
|
906
|
+
<summary>๐ผ๏ธ Media Gallery Examples</summary>
|
|
907
|
+
|
|
908
|
+
**๐ผ๏ธ Media Gallery โ Display images in a beautiful gallery format**
|
|
909
|
+
|
|
910
|
+
The media component creates an image gallery that can display one or multiple images. Each image can be a simple URL string or a detailed object with additional options.
|
|
911
|
+
|
|
912
|
+
|
|
913
|
+
---
|
|
914
|
+
|
|
915
|
+
### ๐ Format 1: Simple String URLs
|
|
916
|
+
|
|
917
|
+
The simplest way - just pass image URLs as strings:
|
|
918
|
+
|
|
919
|
+
```js
|
|
920
|
+
{
|
|
921
|
+
type: "media",
|
|
922
|
+
links: ["https://example.com/image.png"],
|
|
923
|
+
}
|
|
924
|
+
```
|
|
925
|
+
|
|
926
|
+
---
|
|
927
|
+
|
|
928
|
+
### ๐ Format 2: Object with Full Options
|
|
929
|
+
|
|
930
|
+
For more control, use objects with url, description, and spoiler:
|
|
931
|
+
|
|
932
|
+
```js
|
|
933
|
+
{
|
|
934
|
+
type: "media",
|
|
935
|
+
links: [
|
|
936
|
+
{
|
|
937
|
+
url: "https://example.com/image.png",
|
|
938
|
+
description: "A beautiful sunset",
|
|
939
|
+
spoiler: false,
|
|
940
|
+
},
|
|
941
|
+
],
|
|
942
|
+
}
|
|
943
|
+
```
|
|
944
|
+
|
|
945
|
+
---
|
|
946
|
+
|
|
947
|
+
### ๐ Single Image with Spoiler:
|
|
948
|
+
|
|
949
|
+
```js
|
|
950
|
+
{
|
|
951
|
+
type: "media",
|
|
952
|
+
links: [
|
|
953
|
+
{
|
|
954
|
+
url: "https://example.com/spoiler.png",
|
|
955
|
+
description: "โ ๏ธ Spoiler Alert!",
|
|
956
|
+
spoiler: true,
|
|
957
|
+
},
|
|
958
|
+
],
|
|
959
|
+
}
|
|
960
|
+
```
|
|
961
|
+
|
|
962
|
+
---
|
|
963
|
+
|
|
964
|
+
### ๐ Multiple Images (Simple Strings):
|
|
965
|
+
|
|
966
|
+
```js
|
|
967
|
+
{
|
|
968
|
+
type: "media",
|
|
969
|
+
links: [
|
|
970
|
+
"https://example.com/image1.png",
|
|
971
|
+
"https://example.com/image2.png",
|
|
972
|
+
"https://example.com/image3.png",
|
|
973
|
+
"https://example.com/image4.png",
|
|
974
|
+
],
|
|
975
|
+
}
|
|
976
|
+
```
|
|
977
|
+
**Result:** A 2x2 gallery grid of images.
|
|
978
|
+
|
|
979
|
+
---
|
|
980
|
+
|
|
981
|
+
### ๐ Mixed Format (Strings + Objects):
|
|
982
|
+
|
|
983
|
+
You can mix simple strings with detailed objects in the same array:
|
|
984
|
+
|
|
985
|
+
```js
|
|
986
|
+
{
|
|
987
|
+
type: "media",
|
|
988
|
+
links: [
|
|
989
|
+
// Simple string - just the URL
|
|
990
|
+
"https://example.com/public-image.png",
|
|
991
|
+
|
|
992
|
+
// Object with description
|
|
993
|
+
{
|
|
994
|
+
url: "https://example.com/special-image.png",
|
|
995
|
+
description: "Limited Edition Art",
|
|
996
|
+
},
|
|
997
|
+
|
|
998
|
+
// Object with spoiler
|
|
999
|
+
{
|
|
1000
|
+
url: "https://example.com/secret-image.png",
|
|
1001
|
+
description: "Secret Content",
|
|
1002
|
+
spoiler: true,
|
|
1003
|
+
},
|
|
1004
|
+
|
|
1005
|
+
// Another simple string
|
|
1006
|
+
"https://example.com/another-image.png",
|
|
1007
|
+
],
|
|
1008
|
+
}
|
|
1009
|
+
```
|
|
1010
|
+
|
|
1011
|
+
---
|
|
1012
|
+
|
|
1013
|
+
### ๐ Meme/Artwork Gallery with Spoilers:
|
|
1014
|
+
|
|
1015
|
+
```js
|
|
1016
|
+
{
|
|
1017
|
+
type: "media",
|
|
1018
|
+
links: [
|
|
1019
|
+
{
|
|
1020
|
+
url: "https://example.com/meme1.png",
|
|
1021
|
+
description: "Funny meme #1",
|
|
1022
|
+
spoiler: false,
|
|
1023
|
+
},
|
|
1024
|
+
{
|
|
1025
|
+
url: "https://example.com/meme2.png",
|
|
1026
|
+
description: "Funny meme #2",
|
|
1027
|
+
spoiler: false,
|
|
1028
|
+
},
|
|
1029
|
+
{
|
|
1030
|
+
url: "https://example.com/nsfw-meme.png",
|
|
1031
|
+
description: "โ ๏ธ Slightly inappropriate",
|
|
1032
|
+
spoiler: true, // Hidden behind blur
|
|
1033
|
+
},
|
|
1034
|
+
],
|
|
1035
|
+
}
|
|
1036
|
+
```
|
|
1037
|
+
|
|
1038
|
+
---
|
|
1039
|
+
|
|
1040
|
+
### ๐ก Tips for Media Galleries:
|
|
1041
|
+
|
|
1042
|
+
| Images Count | Display Layout |
|
|
1043
|
+
| ------------ | ---------------------- |
|
|
1044
|
+
| 1 image | Full width single image |
|
|
1045
|
+
| 2 images | Side by side |
|
|
1046
|
+
| 3 images | 1 large + 2 small |
|
|
1047
|
+
| 4+ images | Grid layout |
|
|
1048
|
+
|
|
1049
|
+
- Use `description` for accessibility and context
|
|
1050
|
+
- Use `spoiler: true` for sensitive/spoiler content
|
|
1051
|
+
- Mix formats freely - strings for quick images, objects for detailed ones
|
|
1052
|
+
- Images are displayed in the order provided
|
|
1053
|
+
|
|
1054
|
+
</details>
|
|
1055
|
+
|
|
1056
|
+
---
|
|
1057
|
+
|
|
1058
|
+
<details>
|
|
1059
|
+
<summary>๐ File Component Examples</summary>
|
|
1060
|
+
|
|
1061
|
+
#### ๐ Simple File Attachment:
|
|
1062
|
+
|
|
1063
|
+
```js
|
|
1064
|
+
{
|
|
1065
|
+
type: "file",
|
|
1066
|
+
url: "attachment://document.pdf",
|
|
1067
|
+
}
|
|
1068
|
+
```
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
|
|
1072
|
+
#### ๐ Full Example with File:
|
|
1073
|
+
|
|
1074
|
+
```js
|
|
1075
|
+
const { CreateComponents } = require("djs-builder");
|
|
1076
|
+
const { AttachmentBuilder } = require("discord.js");
|
|
1077
|
+
|
|
1078
|
+
const file = new AttachmentBuilder("./myfile.txt", { name: "myfile.txt" });
|
|
1079
|
+
|
|
1080
|
+
const components = await CreateComponents("container", [
|
|
1081
|
+
{
|
|
1082
|
+
type: "text",
|
|
1083
|
+
content: "๐ **Here is your requested file:**",
|
|
1084
|
+
},
|
|
1085
|
+
{
|
|
1086
|
+
type: "file",
|
|
1087
|
+
url: "attachment://myfile.txt",
|
|
1088
|
+
},
|
|
1089
|
+
]);
|
|
1090
|
+
|
|
1091
|
+
await channel.send({ components, files: [file], flags: 32768 });
|
|
1092
|
+
```
|
|
1093
|
+
|
|
1094
|
+
</details>
|
|
1095
|
+
|
|
1096
|
+
---
|
|
1097
|
+
|
|
1098
|
+
<details>
|
|
1099
|
+
<summary>๐ Button Component Examples</summary>
|
|
1100
|
+
|
|
1101
|
+
#### ๐ Button with Emoji:
|
|
1102
|
+
|
|
1103
|
+
```js
|
|
1104
|
+
{
|
|
1105
|
+
type: "button",
|
|
1106
|
+
components: [
|
|
1107
|
+
{
|
|
1108
|
+
id: "like_btn",
|
|
1109
|
+
style: 3, // Success (Green)
|
|
1110
|
+
label: "Like",
|
|
1111
|
+
emoji: "๐",
|
|
1112
|
+
},
|
|
1113
|
+
],
|
|
1114
|
+
}
|
|
1115
|
+
```
|
|
1116
|
+
|
|
1117
|
+
#### ๐ Multiple Buttons in Row:
|
|
1118
|
+
|
|
1119
|
+
```js
|
|
1120
|
+
{
|
|
1121
|
+
type: "button",
|
|
1122
|
+
components: [
|
|
1123
|
+
{ id: "btn_yes", style: 3, label: "Yes", emoji: "โ
" },
|
|
1124
|
+
{ id: "btn_no", style: 4, label: "No", emoji: "โ" },
|
|
1125
|
+
{ id: "btn_maybe", style: 2, label: "Maybe", emoji: "๐ค" },
|
|
1126
|
+
],
|
|
1127
|
+
}
|
|
1128
|
+
```
|
|
1129
|
+
|
|
1130
|
+
#### ๐ All Button Styles:
|
|
1131
|
+
|
|
1132
|
+
```js
|
|
1133
|
+
{
|
|
1134
|
+
type: "button",
|
|
1135
|
+
components: [
|
|
1136
|
+
{ id: "primary", style: 1, label: "Primary", emoji: "๐ต" }, // Blue
|
|
1137
|
+
{ id: "secondary", style: 2, label: "Secondary", emoji: "โช" }, // Gray
|
|
1138
|
+
{ id: "success", style: 3, label: "Success", emoji: "๐ข" }, // Green
|
|
1139
|
+
{ id: "danger", style: 4, label: "Danger", emoji: "๐ด" }, // Red
|
|
1140
|
+
{ style: 5, label: "Link", emoji: "๐", url: "https://discord.com" }, // Link
|
|
1141
|
+
],
|
|
1142
|
+
}
|
|
1143
|
+
```
|
|
1144
|
+
|
|
1145
|
+
|
|
1146
|
+
</details>
|
|
1147
|
+
|
|
1148
|
+
---
|
|
1149
|
+
|
|
1150
|
+
<details>
|
|
1151
|
+
<summary>๐ฏ Menu Component Examples</summary>
|
|
1152
|
+
|
|
1153
|
+
#### ๐ String Select Menu (Basic):
|
|
1154
|
+
|
|
1155
|
+
```js
|
|
1156
|
+
{
|
|
1157
|
+
type: "menu",
|
|
1158
|
+
components: {
|
|
1159
|
+
type: "string",
|
|
1160
|
+
options: {
|
|
1161
|
+
id: "color_select",
|
|
1162
|
+
placeholder: "๐จ Choose a color",
|
|
1163
|
+
data: [
|
|
1164
|
+
{ name: "Red", id: "red", icon: "๐ด" },
|
|
1165
|
+
{ name: "Blue", id: "blue", icon: "๐ต" },
|
|
1166
|
+
{ name: "Green", id: "green", icon: "๐ข" },
|
|
1167
|
+
],
|
|
1168
|
+
label: "name",
|
|
1169
|
+
value: "id",
|
|
1170
|
+
emoji: "icon",
|
|
1171
|
+
},
|
|
1172
|
+
},
|
|
1173
|
+
}
|
|
1174
|
+
```
|
|
1175
|
+
|
|
1176
|
+
#### ๐ String Select with Description:
|
|
1177
|
+
|
|
1178
|
+
```js
|
|
1179
|
+
{
|
|
1180
|
+
type: "menu",
|
|
1181
|
+
components: {
|
|
1182
|
+
type: "string",
|
|
1183
|
+
options: {
|
|
1184
|
+
id: "role_select",
|
|
1185
|
+
placeholder: "๐ญ Select your role",
|
|
1186
|
+
data: [
|
|
1187
|
+
{ name: "Gamer", id: "gamer", desc: "For gaming enthusiasts", icon: "๐ฎ" },
|
|
1188
|
+
{ name: "Artist", id: "artist", desc: "For creative people", icon: "๐จ" },
|
|
1189
|
+
{ name: "Developer", id: "dev", desc: "For coders & programmers", icon: "๐ป" },
|
|
1190
|
+
{ name: "Music Lover", id: "music", desc: "For music fans", icon: "๐ต" },
|
|
1191
|
+
],
|
|
1192
|
+
label: "name",
|
|
1193
|
+
value: "id",
|
|
1194
|
+
description: "desc",
|
|
1195
|
+
emoji: "icon",
|
|
1196
|
+
},
|
|
1197
|
+
},
|
|
1198
|
+
}
|
|
1199
|
+
```
|
|
1200
|
+
|
|
1201
|
+
#### ๐ String Select with Min/Max:
|
|
1202
|
+
|
|
1203
|
+
```js
|
|
1204
|
+
{
|
|
1205
|
+
type: "menu",
|
|
1206
|
+
components: {
|
|
1207
|
+
type: "string",
|
|
1208
|
+
options: {
|
|
1209
|
+
id: "games_select",
|
|
1210
|
+
placeholder: "๐ฎ Select your favorite games (2-4)",
|
|
1211
|
+
min: 2,
|
|
1212
|
+
max: 4,
|
|
1213
|
+
data: [
|
|
1214
|
+
{ name: "Minecraft", id: "mc", icon: "โ๏ธ" },
|
|
1215
|
+
{ name: "Fortnite", id: "fn", icon: "๐ซ" },
|
|
1216
|
+
{ name: "Valorant", id: "val", icon: "๐ฏ" },
|
|
1217
|
+
{ name: "League of Legends", id: "lol", icon: "โ๏ธ" },
|
|
1218
|
+
{ name: "Rocket League", id: "rl", icon: "๐" },
|
|
1219
|
+
],
|
|
1220
|
+
label: "name",
|
|
1221
|
+
value: "id",
|
|
1222
|
+
emoji: "icon",
|
|
1223
|
+
},
|
|
1224
|
+
},
|
|
1225
|
+
}
|
|
1226
|
+
```
|
|
1227
|
+
|
|
1228
|
+
|
|
1229
|
+
#### ๐ User Select (Multiple):
|
|
1230
|
+
|
|
1231
|
+
```js
|
|
1232
|
+
{
|
|
1233
|
+
type: "menu",
|
|
1234
|
+
components: {
|
|
1235
|
+
type: "user",
|
|
1236
|
+
options: {
|
|
1237
|
+
id: "users_select",
|
|
1238
|
+
placeholder: "๐ฅ Select users to invite (1-5)",
|
|
1239
|
+
min: 1,
|
|
1240
|
+
max: 5,
|
|
1241
|
+
},
|
|
1242
|
+
},
|
|
1243
|
+
}
|
|
1244
|
+
```
|
|
1245
|
+
|
|
1246
|
+
#### ๐ Role Select Menu:
|
|
1247
|
+
|
|
1248
|
+
```js
|
|
1249
|
+
{
|
|
1250
|
+
type: "menu",
|
|
1251
|
+
components: {
|
|
1252
|
+
type: "role",
|
|
1253
|
+
options: {
|
|
1254
|
+
id: "role_select",
|
|
1255
|
+
placeholder: "๐ญ Select a role",
|
|
1256
|
+
min: 1,
|
|
1257
|
+
max: 1,
|
|
1258
|
+
},
|
|
1259
|
+
},
|
|
1260
|
+
}
|
|
1261
|
+
```
|
|
1262
|
+
|
|
1263
|
+
|
|
1264
|
+
#### ๐ Channel Select Menu:
|
|
1265
|
+
|
|
1266
|
+
```js
|
|
1267
|
+
{
|
|
1268
|
+
type: "menu",
|
|
1269
|
+
components: {
|
|
1270
|
+
type: "channel",
|
|
1271
|
+
options: {
|
|
1272
|
+
id: "channel_select",
|
|
1273
|
+
placeholder: "๐ข Select a channel",
|
|
1274
|
+
min: 1,
|
|
1275
|
+
max: 1,
|
|
1276
|
+
},
|
|
1277
|
+
},
|
|
1278
|
+
}
|
|
1279
|
+
```
|
|
1280
|
+
|
|
1281
|
+
#### ๐ Channel Select with Type Filter:
|
|
1282
|
+
|
|
1283
|
+
```js
|
|
1284
|
+
const { ChannelType } = require("discord.js");
|
|
1285
|
+
|
|
1286
|
+
{
|
|
1287
|
+
type: "menu",
|
|
1288
|
+
components: {
|
|
1289
|
+
type: "channel",
|
|
1290
|
+
options: {
|
|
1291
|
+
id: "text_channel_select",
|
|
1292
|
+
placeholder: "๐ฌ Select a text channel",
|
|
1293
|
+
channelTypes: [ChannelType.GuildText, ChannelType.GuildAnnouncement],
|
|
1294
|
+
},
|
|
1295
|
+
},
|
|
1296
|
+
}
|
|
1297
|
+
```
|
|
1298
|
+
|
|
1299
|
+
#### ๐ Menu with Default Values (User/Role/Channel):
|
|
1300
|
+
|
|
1301
|
+
```js
|
|
1302
|
+
{
|
|
1303
|
+
type: "menu",
|
|
1304
|
+
components: {
|
|
1305
|
+
type: "user",
|
|
1306
|
+
options: {
|
|
1307
|
+
id: "user_select_default",
|
|
1308
|
+
placeholder: "๐ค Select users",
|
|
1309
|
+
min: 1,
|
|
1310
|
+
max: 3,
|
|
1311
|
+
defaultValues: [
|
|
1312
|
+
{ id: "123456789012345678", type: "user" },
|
|
1313
|
+
{ id: "987654321098765432", type: "user" },
|
|
1314
|
+
],
|
|
1315
|
+
},
|
|
1316
|
+
},
|
|
1317
|
+
}
|
|
1318
|
+
```
|
|
1319
|
+
|
|
1320
|
+
</details>
|
|
1321
|
+
|
|
1322
|
+
---
|
|
1323
|
+
|
|
1324
|
+
<details>
|
|
1325
|
+
<summary>๐ฆ Section Component Examples</summary>
|
|
1326
|
+
|
|
1327
|
+
|
|
1328
|
+
#### ๐ Section with Thumbnail (Product):
|
|
1329
|
+
|
|
1330
|
+
```js
|
|
1331
|
+
{
|
|
1332
|
+
type: "section",
|
|
1333
|
+
content: "๐ **iPhone 15 Pro**\n๐ฐ Price: $999\nโญ Rating: 4.8/5\n๐ฆ In Stock: Yes",
|
|
1334
|
+
accessory: {
|
|
1335
|
+
type: "thumbnail",
|
|
1336
|
+
url: "https://example.com/iphone.png",
|
|
1337
|
+
description: "iPhone 15 Pro Image",
|
|
1338
|
+
},
|
|
1339
|
+
}
|
|
1340
|
+
```
|
|
1341
|
+
|
|
1342
|
+
#### ๐ Section with Button :
|
|
1343
|
+
|
|
1344
|
+
```js
|
|
1345
|
+
{
|
|
1346
|
+
type: "section",
|
|
1347
|
+
content: "๐ **Daily Reward**\nClick to claim your daily reward!\n๐ **+100 Coins**",
|
|
1348
|
+
accessory: {
|
|
1349
|
+
type: "button",
|
|
1350
|
+
id: "claim_daily",
|
|
1351
|
+
style: 3,
|
|
1352
|
+
label: "Claim",
|
|
1353
|
+
emoji: "๐",
|
|
1354
|
+
},
|
|
1355
|
+
}
|
|
1356
|
+
```
|
|
1357
|
+
|
|
1358
|
+
|
|
1359
|
+
|
|
1360
|
+
|
|
1361
|
+
</details>
|
|
1362
|
+
|
|
1363
|
+
---
|
|
1364
|
+
|
|
1365
|
+
|
|
1366
|
+
### ๐ Component Types Explanation
|
|
1367
|
+
|
|
1368
|
+
#### ๐น Text
|
|
1369
|
+
|
|
1370
|
+
- `type` โ `"text"`
|
|
1371
|
+
- `content` โ The text content to display (supports Markdown)
|
|
1372
|
+
|
|
1373
|
+
#### ๐น Separator
|
|
1374
|
+
|
|
1375
|
+
- `type` โ `"separator"`
|
|
1376
|
+
- `divider` โ Show a dividing line (true/false)
|
|
1377
|
+
- `spacing` โ Spacing size (1: Small, 2: Large)
|
|
1378
|
+
|
|
1379
|
+
#### ๐น Media Gallery
|
|
1380
|
+
|
|
1381
|
+
- `type` โ `"media"`
|
|
1382
|
+
- `links` โ Array of image URLs or objects with:
|
|
1383
|
+
- `url` โ Image URL
|
|
1384
|
+
- `description` โ Alt text for the image
|
|
1385
|
+
- `spoiler` โ Hide behind spoiler (true/false)
|
|
1386
|
+
|
|
1387
|
+
#### ๐น File
|
|
1388
|
+
|
|
1389
|
+
- `type` โ `"file"`
|
|
1390
|
+
- `url` โ File URL or attachment reference
|
|
1391
|
+
- `spoiler` โ Hide behind spoiler (true/false)
|
|
1392
|
+
|
|
1393
|
+
#### ๐น Button
|
|
1394
|
+
|
|
1395
|
+
- `type` โ `"button"`
|
|
1396
|
+
- `components` โ Array of button objects:
|
|
1397
|
+
- `id` โ customId (required for non-link buttons)
|
|
1398
|
+
- `style` โ 1: Primary, 2: Secondary, 3: Success, 4: Danger, 5: Link
|
|
1399
|
+
- `label` โ Button text
|
|
1400
|
+
- `emoji` โ Button emoji
|
|
1401
|
+
- `disabled` โ Disable button (true/false)
|
|
1402
|
+
- `url` โ URL for link buttons (style: 5)
|
|
1403
|
+
|
|
1404
|
+
#### ๐น Menu
|
|
1405
|
+
|
|
1406
|
+
- `type` โ `"menu"`
|
|
1407
|
+
- `components` โ Object containing:
|
|
1408
|
+
- `type` โ `"string" | "user" | "role" | "channel"`
|
|
1409
|
+
- `options` โ Menu configuration:
|
|
1410
|
+
- `id` โ customId
|
|
1411
|
+
- `placeholder` โ Placeholder text
|
|
1412
|
+
- `min` / `max` โ Min/Max selectable values
|
|
1413
|
+
- `data` โ Options array (for string select)
|
|
1414
|
+
- `label` โ Key in data for label
|
|
1415
|
+
- `value` โ Key in data for value
|
|
1416
|
+
- `emoji` โ Key in data for emoji
|
|
1417
|
+
- `description` โ Key in data for description
|
|
1418
|
+
- `channelTypes` โ Channel types filter (for channel menu)
|
|
1419
|
+
- `defaultValues` โ Pre-selected values
|
|
1420
|
+
|
|
1421
|
+
#### ๐น Section
|
|
1422
|
+
|
|
1423
|
+
- `type` โ `"section"`
|
|
1424
|
+
- `content` โ Text content for the section
|
|
1425
|
+
- `accessory` โ Side component:
|
|
1426
|
+
- **Button Accessory:**
|
|
1427
|
+
- `type` โ `"button"`
|
|
1428
|
+
- `id` โ customId
|
|
1429
|
+
- `style` โ Button style
|
|
1430
|
+
- `label` โ Button text
|
|
1431
|
+
- `emoji` โ Button emoji
|
|
1432
|
+
- `url` โ URL (for link buttons)
|
|
1433
|
+
- **Thumbnail Accessory:**
|
|
1434
|
+
- `type` โ `"thumbnail"`
|
|
1435
|
+
- `url` โ Image URL
|
|
1436
|
+
- `description` โ Image description
|
|
1437
|
+
|
|
1438
|
+
---
|
|
1439
|
+
|
|
1440
|
+
### ๐น Mode Differences
|
|
1441
|
+
|
|
1442
|
+
| Feature | `"array"` Mode | `"container"` Mode |
|
|
1443
|
+
| ---------------- | ----------------------- | ------------------------- |
|
|
1444
|
+
| Return Type | Array of components | Single ContainerBuilder |
|
|
1445
|
+
| Usage | Standard messages | Components V2 messages |
|
|
1446
|
+
| Sections Support | โ
| โ
|
|
|
1447
|
+
| Grouping | Individual components | All grouped in container |
|
|
1448
|
+
| Flags Required | โ | โ
(flags: 32768) |
|
|
1449
|
+
|
|
1450
|
+
---
|
|
1451
|
+
|
|
1452
|
+
### ๐น Notes
|
|
1453
|
+
|
|
1454
|
+
- Use `"container"` mode for Discord's **Components V2** (newer UI)
|
|
1455
|
+
- Use `"array"` mode for standard component arrays
|
|
1456
|
+
- Sections can have either a **button** or **thumbnail** as accessory, not both
|
|
1457
|
+
- Media galleries support multiple images in a single component
|
|
1458
|
+
- All components are fully customizable ๐จ
|
|
1459
|
+
|
|
1460
|
+
</details>
|
|
1461
|
+
|
|
1462
|
+
---
|
|
1463
|
+
|
|
1464
|
+
<details>
|
|
1465
|
+
<summary>Wait โฐ</summary>
|
|
1466
|
+
|
|
1467
|
+
**โฐ Wait โ Await messages, buttons, select menus or modals easily โจ**
|
|
1468
|
+
|
|
1469
|
+
`Wait` is a replacement for traditional collectors. It supports:
|
|
1470
|
+
|
|
1471
|
+
- Awaiting **messages** ๐
|
|
1472
|
+
- Awaiting **interactions** (buttons / select menus) ๐๏ธ
|
|
1473
|
+
- Awaiting **modal submissions** ๐
|
|
1474
|
+
- Filtering by **user** and timeout
|
|
1475
|
+
|
|
1476
|
+
---
|
|
1477
|
+
|
|
1478
|
+
### ๐ Example Usage:
|
|
1479
|
+
|
|
1480
|
+
```js
|
|
1481
|
+
const { Wait } = require("djs-builder");
|
|
1482
|
+
|
|
1483
|
+
const response = await Wait({
|
|
1484
|
+
context: message, // Message or Interaction object
|
|
1485
|
+
userId: message.author.id, // Optional: filter by user
|
|
1486
|
+
type: "both", // "message" | "interaction" | "both"
|
|
1487
|
+
time: 30000, // Time in ms
|
|
1488
|
+
message_Wait: message, // Required if waiting for buttons/selects
|
|
1489
|
+
});
|
|
1490
|
+
|
|
1491
|
+
if (!response) return console.log("โฑ๏ธ Timeout!");
|
|
1492
|
+
console.log("โ
Collected:", response);
|
|
1493
|
+
```
|
|
1494
|
+
|
|
1495
|
+
---
|
|
1496
|
+
|
|
1497
|
+
### ๐น Options
|
|
1498
|
+
|
|
1499
|
+
- `context` โ The message or interaction context
|
|
1500
|
+
- `userId` โ Only collect from this user (optional)
|
|
1501
|
+
- `type` โ `"message" | "interaction" | "both"`
|
|
1502
|
+
- `time` โ Timeout in milliseconds
|
|
1503
|
+
- `message_Wait` โ Message containing buttons/select menus (for interaction/both type)
|
|
1504
|
+
|
|
1505
|
+
---
|
|
1506
|
+
|
|
1507
|
+
### ๐น Notes
|
|
1508
|
+
|
|
1509
|
+
- Supports **automatic cleanup** of collectors after completion
|
|
1510
|
+
- Can return **Message**, **Interaction**, or **ModalSubmitInteraction**
|
|
1511
|
+
|
|
1512
|
+
</details>
|
|
1513
|
+
|
|
1514
|
+
---
|
|
1515
|
+
|
|
1516
|
+
<details>
|
|
1517
|
+
<summary>GetUser ๐ค</summary>
|
|
1518
|
+
|
|
1519
|
+
**๐ค GetUser โ Fetch a GuildMember easily from a message โจ**
|
|
1520
|
+
|
|
1521
|
+
`GetUser` helps to detect a **target member** in multiple ways:
|
|
1522
|
+
|
|
1523
|
+
1. Mention (`@User`)
|
|
1524
|
+
2. User ID (`123456789012345678`)
|
|
1525
|
+
3. Reply to another message
|
|
1526
|
+
|
|
1527
|
+
---
|
|
1528
|
+
|
|
1529
|
+
### ๐ Example Usage:
|
|
1530
|
+
|
|
1531
|
+
```js
|
|
1532
|
+
const { GetUser } = require("djs-builder");
|
|
1533
|
+
|
|
1534
|
+
const data = await GetUser(message);
|
|
1535
|
+
|
|
1536
|
+
if (!data) return message.reply("โ Could not find the user.");
|
|
1537
|
+
|
|
1538
|
+
const member = data.user; // GuildMember object
|
|
1539
|
+
const args = data.args; // Remaining arguments
|
|
1540
|
+
const reason = args.join(" ") || "No reason provided";
|
|
1541
|
+
|
|
1542
|
+
await member.ban({ reason });
|
|
1543
|
+
message.reply(`๐ซ ${member.user.tag} was banned for: ${reason}`);
|
|
1544
|
+
```
|
|
1545
|
+
|
|
1546
|
+
---
|
|
1547
|
+
|
|
1548
|
+
### ๐น Returns
|
|
1549
|
+
|
|
1550
|
+
```js
|
|
1551
|
+
{
|
|
1552
|
+
user: <GuildMember>, // Targeted member
|
|
1553
|
+
args: [ "arg1", "arg2" ] // Remaining message arguments
|
|
1554
|
+
}
|
|
1555
|
+
```
|
|
1556
|
+
|
|
1557
|
+
---
|
|
1558
|
+
|
|
1559
|
+
### ๐น Detection Methods
|
|
1560
|
+
|
|
1561
|
+
- **Mention:** `!ban @Ahmed Spamming`
|
|
1562
|
+
- **User ID:** `!ban 123456789012345678 Spamming`
|
|
1563
|
+
- **Reply:** `Reply to user's message with !ban`
|
|
1564
|
+
|
|
1565
|
+
---
|
|
1566
|
+
|
|
1567
|
+
### ๐น Notes
|
|
1568
|
+
|
|
1569
|
+
- Automatically handles missing users
|
|
1570
|
+
- Returns `null` if user not found
|
|
1571
|
+
- Works in any text channel of the guild
|
|
1572
|
+
|
|
1573
|
+
</details>
|
|
1574
|
+
|
|
1575
|
+
---
|
|
1576
|
+
|
|
1577
|
+
<details>
|
|
1578
|
+
<summary>Logging System ๐ก๏ธ</summary>
|
|
1579
|
+
|
|
1580
|
+
## ๐ก๏ธ Logging System โ Track Everything in Your Server
|
|
1581
|
+
|
|
1582
|
+
The **Logging System** is a powerful feature that keeps track of almost everything happening inside your Discord server ๐.
|
|
1583
|
+
From **messages** ๐ to **channels** ๐, **roles** ๐ญ, **invites** ๐, and even **voice state changes** ๐๏ธ โ nothing goes unnoticed!
|
|
1584
|
+
|
|
1585
|
+
> **Note 1**: Using `database: true` requires a **MongoDB** connection. | **Note 2**: You can import the **Log** model for direct database access ๐พ.
|
|
1586
|
+
|
|
1587
|
+
---
|
|
1588
|
+
|
|
1589
|
+
### ๐ฆ Module Exports
|
|
1590
|
+
|
|
1591
|
+
```js
|
|
1592
|
+
const { log, Log } = require("djs-builder");
|
|
1593
|
+
```
|
|
1594
|
+
|
|
1595
|
+
- `log(client, options)` โ Start the logging system with your configuration ๐.
|
|
1596
|
+
- `Log` โ The Mongoose model for direct database access and custom modifications ๐พ.
|
|
1597
|
+
|
|
1598
|
+
---
|
|
1599
|
+
|
|
1600
|
+
### ๐ Simple Example
|
|
1601
|
+
|
|
1602
|
+
```js
|
|
1603
|
+
const { log } = require("djs-builder");
|
|
1604
|
+
|
|
1605
|
+
module.exports = {
|
|
1606
|
+
name: "clientReady",
|
|
1607
|
+
async run(client) {
|
|
1608
|
+
const logData = [
|
|
1609
|
+
{
|
|
1610
|
+
guildId: "999888777666555444",
|
|
1611
|
+
channelId: "444555666777888999",
|
|
1612
|
+
},
|
|
1613
|
+
|
|
1614
|
+
{
|
|
1615
|
+
guildId: "999888777666555444",
|
|
1616
|
+
channelId: "444555666777888999",
|
|
1617
|
+
},
|
|
1618
|
+
];
|
|
1619
|
+
|
|
1620
|
+
// Start logging with custom data
|
|
1621
|
+
await log(client, {
|
|
1622
|
+
Data: logData, // ๐ Your configurations
|
|
1623
|
+
});
|
|
1624
|
+
|
|
1625
|
+
console.log("โ
Logging system started with custom data!");
|
|
1626
|
+
},
|
|
1627
|
+
};
|
|
1628
|
+
```
|
|
1629
|
+
|
|
1630
|
+
---
|
|
1631
|
+
|
|
1632
|
+
### โจ Features
|
|
1633
|
+
|
|
1634
|
+
- ๐ **Messages** โ Deleted & edited messages are logged with details.
|
|
1635
|
+
- ๐ **Channels** โ Creation, deletion, and updates are tracked.
|
|
1636
|
+
- ๐ญ **Roles** โ Created, deleted, and updated roles, including member role changes.
|
|
1637
|
+
- ๐๏ธ **Voice State** โ Joins, leaves, and moves between channels.
|
|
1638
|
+
- ๐ **Invites** โ Created invites & usage tracking.
|
|
1639
|
+
- ๐ **Emojis & Stickers** โ Added, removed, or updated.
|
|
1640
|
+
- ๐ค **Members** โ Join, leave, kick, ban, and unban events.
|
|
1641
|
+
- ๐จ **Audit Log Integration** โ Fetches the executor (who did what).
|
|
1642
|
+
- ๐จ **Beautiful Embeds** โ Every log is shown in a clean, styled embed with timestamps.
|
|
1643
|
+
- ๐๏ธ **Caching System** โ Fast performance with built-in data caching.
|
|
1644
|
+
|
|
1645
|
+
---
|
|
1646
|
+
|
|
1647
|
+
### ๐ Database Schema
|
|
1648
|
+
|
|
1649
|
+
The logging system uses the following data structure:
|
|
1650
|
+
|
|
1651
|
+
```js
|
|
1652
|
+
{
|
|
1653
|
+
guildId: String, // ๐ Server ID (required)
|
|
1654
|
+
channelId: String, // ๐ข Default log channel ID
|
|
1655
|
+
channels: Object, // ๐ Custom channels per event type (optional)
|
|
1656
|
+
colors: Object, // ๐จ Custom colors per event type (optional)
|
|
1657
|
+
disable: Array, // ๐ซ Array of disabled event types (optional)
|
|
1658
|
+
}
|
|
1659
|
+
```
|
|
1660
|
+
|
|
1661
|
+
---
|
|
1662
|
+
|
|
1663
|
+
<details>
|
|
1664
|
+
<summary>๐ Supported Event Types</summary>
|
|
1665
|
+
|
|
1666
|
+
### ๐ Supported Event Types
|
|
1667
|
+
|
|
1668
|
+
| Event Type | Description |
|
|
1669
|
+
| ------------------- | ------------------------- |
|
|
1670
|
+
| `messageDelete` | Message deleted ๐ |
|
|
1671
|
+
| `messageUpdate` | Message edited โ๏ธ |
|
|
1672
|
+
| `channelCreate` | Channel created ๐ |
|
|
1673
|
+
| `channelDelete` | Channel deleted ๐๏ธ |
|
|
1674
|
+
| `channelUpdate` | Channel updated โ๏ธ |
|
|
1675
|
+
| `guildMemberAdd` | Member joined ๐ |
|
|
1676
|
+
| `guildMemberRemove` | Member left/kicked ๐ช |
|
|
1677
|
+
| `guildBanAdd` | Member banned ๐จ |
|
|
1678
|
+
| `guildBanRemove` | Member unbanned ๐ค |
|
|
1679
|
+
| `roleCreate` | Role created ๐
|
|
|
1680
|
+
| `roleDelete` | Role deleted โ |
|
|
1681
|
+
| `roleUpdate` | Role updated ๐ |
|
|
1682
|
+
| `guildMemberUpdate` | Member roles changed ๐ค |
|
|
1683
|
+
| `voiceStateUpdate` | Voice channel activity ๐ค |
|
|
1684
|
+
| `inviteCreate` | Invite created ๐ |
|
|
1685
|
+
| `emojiCreate` | Emoji added ๐ |
|
|
1686
|
+
| `emojiDelete` | Emoji removed ๐ซ |
|
|
1687
|
+
| `emojiUpdate` | Emoji updated ๐ |
|
|
1688
|
+
| `stickerCreate` | Sticker added โจ |
|
|
1689
|
+
| `stickerDelete` | Sticker removed ๐๏ธ |
|
|
1690
|
+
| `stickerUpdate` | Sticker updated ๐ |
|
|
1691
|
+
|
|
1692
|
+
</details>
|
|
1693
|
+
|
|
1694
|
+
---
|
|
1695
|
+
|
|
1696
|
+
<details>
|
|
1697
|
+
<summary>โก Method Using Database (Recommended) ๐๏ธ</summary>
|
|
1698
|
+
|
|
1699
|
+
### ๐๏ธ Using MongoDB Database
|
|
1700
|
+
|
|
1701
|
+
This method stores log configuration in MongoDB, allowing dynamic management via commands.
|
|
1702
|
+
|
|
1703
|
+
**โก Setup in `clientReady` Event:**
|
|
1704
|
+
|
|
1705
|
+
```js
|
|
1706
|
+
const { log } = require("djs-builder");
|
|
1707
|
+
|
|
1708
|
+
module.exports = {
|
|
1709
|
+
name: "clientReady",
|
|
1710
|
+
async run(client) {
|
|
1711
|
+
// Start logging with database mode
|
|
1712
|
+
await log(client, {
|
|
1713
|
+
database: true, // ๐๏ธ Uses MongoDB to store/fetch config
|
|
1714
|
+
});
|
|
1715
|
+
|
|
1716
|
+
console.log("โ
Logging system started with database mode!");
|
|
1717
|
+
},
|
|
1718
|
+
};
|
|
1719
|
+
```
|
|
1720
|
+
|
|
1721
|
+
---
|
|
1722
|
+
|
|
1723
|
+
### ๐ก How It Works
|
|
1724
|
+
|
|
1725
|
+
- โ
The system automatically fetches log configuration for each guild from MongoDB.
|
|
1726
|
+
- ๐ ๏ธ You can manage settings via slash commands (see management command below).
|
|
1727
|
+
- ๐จ Supports per-guild customization for channels, colors, and disabled events.
|
|
1728
|
+
- ๐ **Important**: If you use database mode, see the [Log Management Command](#-slash-command-for-log-management-) below to edit data.
|
|
1729
|
+
|
|
1730
|
+
</details>
|
|
1731
|
+
|
|
1732
|
+
---
|
|
1733
|
+
|
|
1734
|
+
<details>
|
|
1735
|
+
<summary>โก Method Using Custom Data Array ๐</summary>
|
|
1736
|
+
|
|
1737
|
+
### ๐ Using Custom Data Array
|
|
1738
|
+
|
|
1739
|
+
This method uses a predefined array of configurations โ perfect for simple setups or testing.
|
|
1740
|
+
|
|
1741
|
+
**โก Setup in `clientReady` Event:**
|
|
1742
|
+
|
|
1743
|
+
|
|
1744
|
+
|
|
1745
|
+
|
|
1746
|
+
```js
|
|
1747
|
+
const { log } = require("djs-builder");
|
|
1748
|
+
|
|
1749
|
+
module.exports = {
|
|
1750
|
+
name: "clientReady",
|
|
1751
|
+
async run(client) {
|
|
1752
|
+
// Define your log configurations
|
|
1753
|
+
const logData = [
|
|
1754
|
+
{
|
|
1755
|
+
guildId: "123456789012345678", // ๐ Server ID
|
|
1756
|
+
channelId: "987654321098765432", // ๐ข Default log channel
|
|
1757
|
+
channels: {
|
|
1758
|
+
// ๐ Custom channels (optional)
|
|
1759
|
+
messageDelete: "111111111111111111",
|
|
1760
|
+
voiceStateUpdate: "222222222222222222",
|
|
1761
|
+
},
|
|
1762
|
+
colors: {
|
|
1763
|
+
// ๐จ Custom colors (optional)
|
|
1764
|
+
messageDelete: "DarkRed",
|
|
1765
|
+
channelCreate: "DarkGreen",
|
|
1766
|
+
},
|
|
1767
|
+
disable: ["inviteCreate"], // ๐ซ Disabled events (optional)
|
|
1768
|
+
},
|
|
1769
|
+
// Add more guild configurations...
|
|
1770
|
+
{
|
|
1771
|
+
guildId: "999888777666555444",
|
|
1772
|
+
channelId: "444555666777888999",
|
|
1773
|
+
},
|
|
1774
|
+
];
|
|
1775
|
+
|
|
1776
|
+
// Start logging with custom data
|
|
1777
|
+
await log(client, {
|
|
1778
|
+
database: false, // ๐ Uses custom array
|
|
1779
|
+
Data: logData, // ๐ Your configurations
|
|
1780
|
+
});
|
|
1781
|
+
|
|
1782
|
+
console.log("โ
Logging system started with custom data!");
|
|
1783
|
+
},
|
|
1784
|
+
};
|
|
1785
|
+
```
|
|
1786
|
+
|
|
1787
|
+
---
|
|
1788
|
+
|
|
1789
|
+
### ๐จ Supported Colors
|
|
1790
|
+
|
|
1791
|
+
`Default`, `White`, `Aqua`, `Green`, `Blue`, `Yellow`, `Purple`, `LuminousVividPink`, `Fuchsia`, `Gold`, `Orange`, `Red`, `Grey`, `Navy`, `DarkAqua`, `DarkGreen`, `DarkBlue`, `DarkPurple`, `DarkVividPink`, `DarkGold`, `DarkOrange`, `DarkRed`, `DarkGrey`, `DarkerGrey`, `LightGrey`, `DarkNavy`, `Blurple`, `Greyple`, `DarkButNotBlack`, `NotQuiteBlack`, `Random`, or any **Hex Color** like `#FF5733`.
|
|
1792
|
+
|
|
1793
|
+
---
|
|
1794
|
+
|
|
1795
|
+
### ๐ Multi-Guild Support
|
|
1796
|
+
|
|
1797
|
+
> ๐ก **Tip:** You can add configurations for multiple guilds in the same array. Each guild can have its own unique settings for channels, colors, and disabled events!
|
|
1798
|
+
|
|
1799
|
+
</details>
|
|
1800
|
+
|
|
1801
|
+
---
|
|
1802
|
+
|
|
1803
|
+
<details>
|
|
1804
|
+
<summary>๐ง Direct Database Access with Log Model ๐พ</summary>
|
|
1805
|
+
|
|
1806
|
+
### ๐พ Using the Log Model Directly
|
|
1807
|
+
|
|
1808
|
+
You can import the `Log` Mongoose model to create, update, or delete log configurations programmatically.
|
|
1809
|
+
|
|
1810
|
+
**๐ฅ Import the Model:**
|
|
1811
|
+
|
|
1812
|
+
```js
|
|
1813
|
+
const { Log } = require("djs-builder");
|
|
1814
|
+
```
|
|
1815
|
+
|
|
1816
|
+
**โ Create New Configuration:**
|
|
1817
|
+
|
|
1818
|
+
```js
|
|
1819
|
+
const { Log } = require("djs-builder");
|
|
1820
|
+
|
|
1821
|
+
// Create a new log configuration for a guild
|
|
1822
|
+
const newConfig = await Log.create({
|
|
1823
|
+
guildId: "123456789012345678",
|
|
1824
|
+
channelId: "987654321098765432",
|
|
1825
|
+
channels: {
|
|
1826
|
+
messageDelete: "111111111111111111",
|
|
1827
|
+
},
|
|
1828
|
+
colors: {
|
|
1829
|
+
messageDelete: "Red",
|
|
1830
|
+
},
|
|
1831
|
+
disable: [],
|
|
1832
|
+
});
|
|
1833
|
+
|
|
1834
|
+
console.log("โ
Log configuration created!", newConfig);
|
|
1835
|
+
```
|
|
1836
|
+
|
|
1837
|
+
**โ๏ธ Update Existing Configuration:**
|
|
354
1838
|
|
|
355
1839
|
```js
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
left: "ยซ",
|
|
364
|
-
right: "ยป",
|
|
365
|
-
})
|
|
1840
|
+
const { Log } = require("djs-builder");
|
|
1841
|
+
|
|
1842
|
+
// Update log channel
|
|
1843
|
+
await Log.findOneAndUpdate(
|
|
1844
|
+
{ guildId: "123456789012345678" },
|
|
1845
|
+
{ channelId: "NEW_CHANNEL_ID" },
|
|
1846
|
+
{ upsert: true } // Create if doesn't exist
|
|
366
1847
|
);
|
|
367
1848
|
|
|
368
|
-
//
|
|
369
|
-
|
|
1849
|
+
// Add event to disable list
|
|
1850
|
+
await Log.findOneAndUpdate(
|
|
1851
|
+
{ guildId: "123456789012345678" },
|
|
1852
|
+
{ $push: { disable: "voiceStateUpdate" } }
|
|
1853
|
+
);
|
|
370
1854
|
|
|
371
|
-
|
|
1855
|
+
// Remove event from disable list
|
|
1856
|
+
await Log.findOneAndUpdate(
|
|
1857
|
+
{ guildId: "123456789012345678" },
|
|
1858
|
+
{ $pull: { disable: "voiceStateUpdate" } }
|
|
1859
|
+
);
|
|
372
1860
|
|
|
373
|
-
|
|
1861
|
+
// Update specific channel for an event
|
|
1862
|
+
await Log.findOneAndUpdate(
|
|
1863
|
+
{ guildId: "123456789012345678" },
|
|
1864
|
+
{ $set: { "channels.messageDelete": "NEW_CHANNEL_ID" } }
|
|
1865
|
+
);
|
|
374
1866
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
1867
|
+
// Update specific color for an event
|
|
1868
|
+
await Log.findOneAndUpdate(
|
|
1869
|
+
{ guildId: "123456789012345678" },
|
|
1870
|
+
{ $set: { "colors.messageDelete": "DarkRed" } }
|
|
1871
|
+
);
|
|
1872
|
+
```
|
|
381
1873
|
|
|
382
|
-
|
|
1874
|
+
**๐๏ธ Delete Configuration:**
|
|
383
1875
|
|
|
384
|
-
|
|
1876
|
+
```js
|
|
1877
|
+
const { Log } = require("djs-builder");
|
|
385
1878
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
1879
|
+
await Log.findOneAndDelete({ guildId: "123456789012345678" });
|
|
1880
|
+
console.log("๐๏ธ Log configuration deleted!");
|
|
1881
|
+
```
|
|
389
1882
|
|
|
390
|
-
|
|
1883
|
+
**๐ Fetch Configuration:**
|
|
1884
|
+
|
|
1885
|
+
```js
|
|
1886
|
+
const { Log } = require("djs-builder");
|
|
1887
|
+
|
|
1888
|
+
const config = await Log.findOne({ guildId: "123456789012345678" });
|
|
1889
|
+
if (config) {
|
|
1890
|
+
console.log("๐ข Log Channel:", config.channelId);
|
|
1891
|
+
console.log("๐ Custom Channels:", config.channels);
|
|
1892
|
+
console.log("๐จ Custom Colors:", config.colors);
|
|
1893
|
+
console.log("๐ซ Disabled Events:", config.disable);
|
|
1894
|
+
}
|
|
1895
|
+
```
|
|
391
1896
|
|
|
392
1897
|
</details>
|
|
393
1898
|
|
|
394
1899
|
---
|
|
395
1900
|
|
|
396
1901
|
<details>
|
|
397
|
-
<summary
|
|
1902
|
+
<summary>๐ Dashboard Integration โ Manage Logs from Web Panel ๐ฅ๏ธ</summary>
|
|
398
1903
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
`Wait` is a replacement for traditional collectors. It supports:
|
|
1904
|
+
### ๐ฅ๏ธ Web Dashboard for Log Management
|
|
402
1905
|
|
|
403
|
-
|
|
404
|
-
- Awaiting **interactions** (buttons / select menus) ๐๏ธ
|
|
405
|
-
- Awaiting **modal submissions** ๐
|
|
406
|
-
- Filtering by **user** and timeout
|
|
1906
|
+
When you use **database mode** (`database: true`), you can manage the logging system directly from the **djs-builder Dashboard**! ๐๏ธ
|
|
407
1907
|
|
|
408
1908
|
---
|
|
409
1909
|
|
|
410
|
-
|
|
1910
|
+
#### โจ Dashboard Features for Logs
|
|
411
1911
|
|
|
412
|
-
|
|
413
|
-
|
|
1912
|
+
| Feature | Description |
|
|
1913
|
+
| ---------------------- | -------------------------------------------- |
|
|
1914
|
+
| ๐ข **Default Channel** | Set the main channel for all logs |
|
|
1915
|
+
| ๐ **Custom Channels** | Assign specific channels for each event type |
|
|
1916
|
+
| ๐จ **Custom Colors** | Choose embed colors for each event type |
|
|
1917
|
+
| ๐ **Toggle Events** | Enable/Disable specific event types |
|
|
1918
|
+
| ๐ **Statistics** | View enabled/disabled events count |
|
|
1919
|
+
| ๐๏ธ **Reset** | Clear all log settings with one click |
|
|
414
1920
|
|
|
415
|
-
|
|
416
|
-
context: message, // Message or Interaction object
|
|
417
|
-
userId: message.author.id, // Optional: filter by user
|
|
418
|
-
type: "both", // "message" | "interaction" | "both"
|
|
419
|
-
time: 30000, // Time in ms
|
|
420
|
-
message_Wait: message, // Required if waiting for buttons/selects
|
|
421
|
-
});
|
|
1921
|
+
---
|
|
422
1922
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
1923
|
+
#### ๐ How to Access
|
|
1924
|
+
|
|
1925
|
+
1. Navigate to your dashboard (e.g., `http://localhost:3000`)
|
|
1926
|
+
2. Log in with Discord OAuth2
|
|
1927
|
+
3. Select a server
|
|
1928
|
+
4. Click on **"ุณุฌูุงุช ุงูู
ุฑุงูุจุฉ"** (Logs) in the sidebar
|
|
426
1929
|
|
|
427
1930
|
---
|
|
428
1931
|
|
|
429
|
-
|
|
1932
|
+
#### โ ๏ธ Important Notes
|
|
430
1933
|
|
|
431
|
-
|
|
432
|
-
- `userId` โ Only collect from this user (optional)
|
|
433
|
-
- `type` โ `"message" | "interaction" | "both"`
|
|
434
|
-
- `time` โ Timeout in milliseconds
|
|
435
|
-
- `message_Wait` โ Message containing buttons/select menus (for interaction/both type)
|
|
1934
|
+
**When `database: true`:**
|
|
436
1935
|
|
|
437
|
-
|
|
1936
|
+
- โ
Full editing capabilities from dashboard
|
|
1937
|
+
- โ
Changes are saved automatically to MongoDB
|
|
1938
|
+
- โ
Real-time updates
|
|
438
1939
|
|
|
439
|
-
|
|
1940
|
+
**When `database: false` (Custom Data Array):**
|
|
440
1941
|
|
|
441
|
-
-
|
|
442
|
-
-
|
|
1942
|
+
- โ ๏ธ Dashboard shows **read-only** mode
|
|
1943
|
+
- โ ๏ธ A warning banner appears at the top
|
|
1944
|
+
- โ ๏ธ You must edit settings in your code
|
|
443
1945
|
|
|
444
1946
|
</details>
|
|
445
1947
|
|
|
446
1948
|
---
|
|
447
1949
|
|
|
448
1950
|
<details>
|
|
449
|
-
<summary
|
|
1951
|
+
<summary>๐ฎ Slash Command for Log Management ๐ ๏ธ</summary>
|
|
450
1952
|
|
|
451
|
-
|
|
1953
|
+
### ๐ ๏ธ Complete Log Management Slash Command
|
|
452
1954
|
|
|
453
|
-
|
|
1955
|
+
This command allows server administrators to manage the logging system via Discord.
|
|
454
1956
|
|
|
455
|
-
|
|
456
|
-
2. User ID (`123456789012345678`)
|
|
457
|
-
3. Reply to another message
|
|
1957
|
+
> โ ๏ธ **Important**: This command requires `database: true` mode to work properly.
|
|
458
1958
|
|
|
459
|
-
|
|
1959
|
+
```js
|
|
1960
|
+
const { Log, getLogConfigData } = require("djs-builder");
|
|
1961
|
+
const {
|
|
1962
|
+
SlashCommandBuilder,
|
|
1963
|
+
PermissionFlagsBits,
|
|
1964
|
+
EmbedBuilder,
|
|
1965
|
+
ChannelType,
|
|
1966
|
+
} = require("discord.js");
|
|
460
1967
|
|
|
461
|
-
|
|
1968
|
+
// All supported event types (21 events)
|
|
1969
|
+
const EVENT_TYPES = [
|
|
1970
|
+
{ name: "Message Delete", value: "messageDelete" },
|
|
1971
|
+
{ name: "Message Update", value: "messageUpdate" },
|
|
1972
|
+
{ name: "Channel Create", value: "channelCreate" },
|
|
1973
|
+
{ name: "Channel Delete", value: "channelDelete" },
|
|
1974
|
+
{ name: "Channel Update", value: "channelUpdate" },
|
|
1975
|
+
{ name: "Member Join", value: "guildMemberAdd" },
|
|
1976
|
+
{ name: "Member Leave", value: "guildMemberRemove" },
|
|
1977
|
+
{ name: "Member Ban", value: "guildBanAdd" },
|
|
1978
|
+
{ name: "Member Unban", value: "guildBanRemove" },
|
|
1979
|
+
{ name: "Role Create", value: "roleCreate" },
|
|
1980
|
+
{ name: "Role Delete", value: "roleDelete" },
|
|
1981
|
+
{ name: "Role Update", value: "roleUpdate" },
|
|
1982
|
+
{ name: "Member Role Update", value: "guildMemberUpdate" },
|
|
1983
|
+
{ name: "Voice State", value: "voiceStateUpdate" },
|
|
1984
|
+
{ name: "Invite Create", value: "inviteCreate" },
|
|
1985
|
+
{ name: "Emoji Create", value: "emojiCreate" },
|
|
1986
|
+
{ name: "Emoji Delete", value: "emojiDelete" },
|
|
1987
|
+
{ name: "Emoji Update", value: "emojiUpdate" },
|
|
1988
|
+
{ name: "Sticker Create", value: "stickerCreate" },
|
|
1989
|
+
{ name: "Sticker Delete", value: "stickerDelete" },
|
|
1990
|
+
{ name: "Sticker Update", value: "stickerUpdate" },
|
|
1991
|
+
];
|
|
1992
|
+
|
|
1993
|
+
// Helper function to clear cache after updates
|
|
1994
|
+
function clearLogCache(guildId) {
|
|
1995
|
+
const logData = getLogConfigData();
|
|
1996
|
+
if (logData.clearCache) logData.clearCache(guildId);
|
|
1997
|
+
}
|
|
462
1998
|
|
|
463
|
-
|
|
464
|
-
|
|
1999
|
+
module.exports = {
|
|
2000
|
+
data: new SlashCommandBuilder()
|
|
2001
|
+
.setName("logs")
|
|
2002
|
+
.setDescription("๐ก๏ธ Manage the server logging system")
|
|
2003
|
+
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
|
|
2004
|
+
.addSubcommand((sub) =>
|
|
2005
|
+
sub
|
|
2006
|
+
.setName("setup")
|
|
2007
|
+
.setDescription("๐ข Set up the default log channel")
|
|
2008
|
+
.addChannelOption((opt) =>
|
|
2009
|
+
opt
|
|
2010
|
+
.setName("channel")
|
|
2011
|
+
.setDescription("The channel to send logs to")
|
|
2012
|
+
.addChannelTypes(ChannelType.GuildText)
|
|
2013
|
+
.setRequired(true)
|
|
2014
|
+
)
|
|
2015
|
+
)
|
|
2016
|
+
.addSubcommand((sub) =>
|
|
2017
|
+
sub
|
|
2018
|
+
.setName("channel")
|
|
2019
|
+
.setDescription("๐ Set a specific channel for an event type")
|
|
2020
|
+
.addStringOption((opt) =>
|
|
2021
|
+
opt
|
|
2022
|
+
.setName("event")
|
|
2023
|
+
.setDescription("The event type")
|
|
2024
|
+
.setRequired(true)
|
|
2025
|
+
.addChoices(...EVENT_TYPES)
|
|
2026
|
+
)
|
|
2027
|
+
.addChannelOption((opt) =>
|
|
2028
|
+
opt
|
|
2029
|
+
.setName("channel")
|
|
2030
|
+
.setDescription("The channel for this event")
|
|
2031
|
+
.addChannelTypes(ChannelType.GuildText)
|
|
2032
|
+
.setRequired(true)
|
|
2033
|
+
)
|
|
2034
|
+
)
|
|
2035
|
+
.addSubcommand((sub) =>
|
|
2036
|
+
sub
|
|
2037
|
+
.setName("color")
|
|
2038
|
+
.setDescription("๐จ Set a custom color for an event type")
|
|
2039
|
+
.addStringOption((opt) =>
|
|
2040
|
+
opt
|
|
2041
|
+
.setName("event")
|
|
2042
|
+
.setDescription("The event type")
|
|
2043
|
+
.setRequired(true)
|
|
2044
|
+
.addChoices(...EVENT_TYPES)
|
|
2045
|
+
)
|
|
2046
|
+
.addStringOption((opt) =>
|
|
2047
|
+
opt
|
|
2048
|
+
.setName("color")
|
|
2049
|
+
.setDescription("Color name or hex code (e.g., Red, #FF5733)")
|
|
2050
|
+
.setRequired(true)
|
|
2051
|
+
)
|
|
2052
|
+
)
|
|
2053
|
+
.addSubcommand((sub) =>
|
|
2054
|
+
sub
|
|
2055
|
+
.setName("toggle")
|
|
2056
|
+
.setDescription("๐ Enable or disable an event type")
|
|
2057
|
+
.addStringOption((opt) =>
|
|
2058
|
+
opt
|
|
2059
|
+
.setName("event")
|
|
2060
|
+
.setDescription("The event type")
|
|
2061
|
+
.setRequired(true)
|
|
2062
|
+
.addChoices(...EVENT_TYPES)
|
|
2063
|
+
)
|
|
2064
|
+
.addStringOption((opt) =>
|
|
2065
|
+
opt
|
|
2066
|
+
.setName("action")
|
|
2067
|
+
.setDescription("Enable or disable")
|
|
2068
|
+
.setRequired(true)
|
|
2069
|
+
.addChoices(
|
|
2070
|
+
{ name: "Enable", value: "enable" },
|
|
2071
|
+
{ name: "Disable", value: "disable" }
|
|
2072
|
+
)
|
|
2073
|
+
)
|
|
2074
|
+
)
|
|
2075
|
+
.addSubcommand((sub) =>
|
|
2076
|
+
sub.setName("view").setDescription("๐ View current log configuration")
|
|
2077
|
+
)
|
|
2078
|
+
.addSubcommand((sub) =>
|
|
2079
|
+
sub
|
|
2080
|
+
.setName("reset")
|
|
2081
|
+
.setDescription("๐๏ธ Reset all log settings for this server")
|
|
2082
|
+
),
|
|
465
2083
|
|
|
466
|
-
|
|
2084
|
+
async run(client, interaction) {
|
|
2085
|
+
await interaction.deferReply({ ephemeral: true });
|
|
467
2086
|
|
|
468
|
-
|
|
2087
|
+
const subcommand = interaction.options.getSubcommand();
|
|
2088
|
+
const guildId = interaction.guild.id;
|
|
469
2089
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
2090
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
2091
|
+
// ๐ข SETUP - Set default log channel
|
|
2092
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
2093
|
+
if (subcommand === "setup") {
|
|
2094
|
+
const channel = interaction.options.getChannel("channel");
|
|
473
2095
|
|
|
474
|
-
await
|
|
475
|
-
|
|
476
|
-
|
|
2096
|
+
await Log.findOneAndUpdate(
|
|
2097
|
+
{ guildId },
|
|
2098
|
+
{ guildId, channelId: channel.id },
|
|
2099
|
+
{ upsert: true, new: true }
|
|
2100
|
+
);
|
|
477
2101
|
|
|
478
|
-
|
|
2102
|
+
clearLogCache(guildId); // Clear cache to apply changes immediately
|
|
479
2103
|
|
|
480
|
-
|
|
2104
|
+
const embed = new EmbedBuilder()
|
|
2105
|
+
.setTitle("โ
Logging System Setup")
|
|
2106
|
+
.setDescription(`Logs will now be sent to ${channel}`)
|
|
2107
|
+
.setColor("Green")
|
|
2108
|
+
.setTimestamp();
|
|
481
2109
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
user: <GuildMember>, // Targeted member
|
|
485
|
-
args: [ "arg1", "arg2" ] // Remaining message arguments
|
|
486
|
-
}
|
|
487
|
-
```
|
|
2110
|
+
return interaction.editReply({ embeds: [embed] });
|
|
2111
|
+
}
|
|
488
2112
|
|
|
489
|
-
|
|
2113
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
2114
|
+
// ๐ CHANNEL - Set specific channel for event
|
|
2115
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
2116
|
+
if (subcommand === "channel") {
|
|
2117
|
+
const event = interaction.options.getString("event");
|
|
2118
|
+
const channel = interaction.options.getChannel("channel");
|
|
2119
|
+
|
|
2120
|
+
await Log.findOneAndUpdate(
|
|
2121
|
+
{ guildId },
|
|
2122
|
+
{ $set: { [`channels.${event}`]: channel.id } },
|
|
2123
|
+
{ upsert: true }
|
|
2124
|
+
);
|
|
490
2125
|
|
|
491
|
-
|
|
2126
|
+
clearLogCache(guildId);
|
|
492
2127
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
2128
|
+
const eventName =
|
|
2129
|
+
EVENT_TYPES.find((e) => e.value === event)?.name || event;
|
|
2130
|
+
const embed = new EmbedBuilder()
|
|
2131
|
+
.setTitle("๐ Event Channel Updated")
|
|
2132
|
+
.setDescription(`**${eventName}** logs will now be sent to ${channel}`)
|
|
2133
|
+
.setColor("Blue")
|
|
2134
|
+
.setTimestamp();
|
|
496
2135
|
|
|
497
|
-
|
|
2136
|
+
return interaction.editReply({ embeds: [embed] });
|
|
2137
|
+
}
|
|
498
2138
|
|
|
499
|
-
|
|
2139
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
2140
|
+
// ๐จ COLOR - Set custom color for event
|
|
2141
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
2142
|
+
if (subcommand === "color") {
|
|
2143
|
+
const event = interaction.options.getString("event");
|
|
2144
|
+
const color = interaction.options.getString("color");
|
|
2145
|
+
|
|
2146
|
+
await Log.findOneAndUpdate(
|
|
2147
|
+
{ guildId },
|
|
2148
|
+
{ $set: { [`colors.${event}`]: color } },
|
|
2149
|
+
{ upsert: true }
|
|
2150
|
+
);
|
|
500
2151
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
2152
|
+
clearLogCache(guildId);
|
|
2153
|
+
|
|
2154
|
+
const eventName =
|
|
2155
|
+
EVENT_TYPES.find((e) => e.value === event)?.name || event;
|
|
2156
|
+
|
|
2157
|
+
// Try to use the color, fallback to Blue if invalid
|
|
2158
|
+
let embedColor;
|
|
2159
|
+
try {
|
|
2160
|
+
embedColor = color;
|
|
2161
|
+
} catch {
|
|
2162
|
+
embedColor = "Blue";
|
|
2163
|
+
}
|
|
504
2164
|
|
|
505
|
-
|
|
2165
|
+
const embed = new EmbedBuilder()
|
|
2166
|
+
.setTitle("๐จ Event Color Updated")
|
|
2167
|
+
.setDescription(
|
|
2168
|
+
`**${eventName}** embeds will now use color: \`${color}\``
|
|
2169
|
+
)
|
|
2170
|
+
.setColor(embedColor)
|
|
2171
|
+
.setTimestamp();
|
|
506
2172
|
|
|
507
|
-
|
|
2173
|
+
return interaction.editReply({ embeds: [embed] });
|
|
2174
|
+
}
|
|
508
2175
|
|
|
509
|
-
|
|
510
|
-
|
|
2176
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
2177
|
+
// ๐ TOGGLE - Enable/Disable event
|
|
2178
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
2179
|
+
if (subcommand === "toggle") {
|
|
2180
|
+
const event = interaction.options.getString("event");
|
|
2181
|
+
const action = interaction.options.getString("action");
|
|
2182
|
+
|
|
2183
|
+
if (action === "disable") {
|
|
2184
|
+
await Log.findOneAndUpdate(
|
|
2185
|
+
{ guildId },
|
|
2186
|
+
{ $addToSet: { disable: event } },
|
|
2187
|
+
{ upsert: true }
|
|
2188
|
+
);
|
|
2189
|
+
} else {
|
|
2190
|
+
await Log.findOneAndUpdate(
|
|
2191
|
+
{ guildId },
|
|
2192
|
+
{ $pull: { disable: event } },
|
|
2193
|
+
{ upsert: true }
|
|
2194
|
+
);
|
|
2195
|
+
}
|
|
511
2196
|
|
|
512
|
-
|
|
513
|
-
From **messages** ๐ to **channels** ๐, **roles** ๐ญ, **invites** ๐, and even **voice state changes** ๐๏ธ โ nothing goes unnoticed!
|
|
2197
|
+
clearLogCache(guildId);
|
|
514
2198
|
|
|
515
|
-
|
|
2199
|
+
const eventName =
|
|
2200
|
+
EVENT_TYPES.find((e) => e.value === event)?.name || event;
|
|
2201
|
+
const embed = new EmbedBuilder()
|
|
2202
|
+
.setTitle(
|
|
2203
|
+
action === "disable" ? "๐ซ Event Disabled" : "โ
Event Enabled"
|
|
2204
|
+
)
|
|
2205
|
+
.setDescription(`**${eventName}** logging has been ${action}d`)
|
|
2206
|
+
.setColor(action === "disable" ? "Red" : "Green")
|
|
2207
|
+
.setTimestamp();
|
|
516
2208
|
|
|
517
|
-
|
|
2209
|
+
return interaction.editReply({ embeds: [embed] });
|
|
2210
|
+
}
|
|
518
2211
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
- ๐ **Emojis & Stickers** โ Added, removed, or updated.
|
|
525
|
-
- ๐จ **Audit Log Integration** โ Fetches the executor (who did what).
|
|
526
|
-
- ๐จ **Beautiful Embeds** โ Every log is shown in a clean, styled embed with timestamps.
|
|
2212
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
2213
|
+
// ๐ VIEW - Show current configuration
|
|
2214
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
2215
|
+
if (subcommand === "view") {
|
|
2216
|
+
const config = await Log.findOne({ guildId });
|
|
527
2217
|
|
|
528
|
-
|
|
2218
|
+
if (!config) {
|
|
2219
|
+
return interaction.editReply({
|
|
2220
|
+
content:
|
|
2221
|
+
"โ No logging configuration found for this server. Use `/logs setup` first!",
|
|
2222
|
+
});
|
|
2223
|
+
}
|
|
529
2224
|
|
|
530
|
-
|
|
2225
|
+
const channelsList = config.channels
|
|
2226
|
+
? Object.entries(config.channels)
|
|
2227
|
+
.map(([k, v]) => {
|
|
2228
|
+
const eventName = EVENT_TYPES.find((e) => e.value === k)?.name || k;
|
|
2229
|
+
return `โข **${eventName}**: <#${v}>`;
|
|
2230
|
+
})
|
|
2231
|
+
.join("\n") || "None"
|
|
2232
|
+
: "None";
|
|
2233
|
+
|
|
2234
|
+
const colorsList = config.colors
|
|
2235
|
+
? Object.entries(config.colors)
|
|
2236
|
+
.map(([k, v]) => {
|
|
2237
|
+
const eventName = EVENT_TYPES.find((e) => e.value === k)?.name || k;
|
|
2238
|
+
return `โข **${eventName}**: \`${v}\``;
|
|
2239
|
+
})
|
|
2240
|
+
.join("\n") || "None"
|
|
2241
|
+
: "None";
|
|
2242
|
+
|
|
2243
|
+
const disabledList =
|
|
2244
|
+
config.disable?.length > 0
|
|
2245
|
+
? config.disable.map((e) => {
|
|
2246
|
+
const eventName = EVENT_TYPES.find((ev) => ev.value === e)?.name || e;
|
|
2247
|
+
return `โข ${eventName}`;
|
|
2248
|
+
}).join("\n")
|
|
2249
|
+
: "None";
|
|
2250
|
+
|
|
2251
|
+
const enabledCount = EVENT_TYPES.length - (config.disable?.length || 0);
|
|
2252
|
+
|
|
2253
|
+
const embed = new EmbedBuilder()
|
|
2254
|
+
.setTitle("๐ Log Configuration")
|
|
2255
|
+
.setDescription(`**${enabledCount}/${EVENT_TYPES.length}** events are enabled`)
|
|
2256
|
+
.setColor("Blue")
|
|
2257
|
+
.addFields(
|
|
2258
|
+
{
|
|
2259
|
+
name: "๐ข Default Channel",
|
|
2260
|
+
value: config.channelId ? `<#${config.channelId}>` : "Not set",
|
|
2261
|
+
inline: true,
|
|
2262
|
+
},
|
|
2263
|
+
{
|
|
2264
|
+
name: "๐ Custom Channels",
|
|
2265
|
+
value: channelsList.slice(0, 1024) || "None",
|
|
2266
|
+
inline: false,
|
|
2267
|
+
},
|
|
2268
|
+
{
|
|
2269
|
+
name: "๐จ Custom Colors",
|
|
2270
|
+
value: colorsList.slice(0, 1024) || "None",
|
|
2271
|
+
inline: false,
|
|
2272
|
+
},
|
|
2273
|
+
{
|
|
2274
|
+
name: "๐ซ Disabled Events",
|
|
2275
|
+
value: disabledList.slice(0, 1024) || "None",
|
|
2276
|
+
inline: false,
|
|
2277
|
+
}
|
|
2278
|
+
)
|
|
2279
|
+
.setFooter({ text: `Guild ID: ${guildId}` })
|
|
2280
|
+
.setTimestamp();
|
|
531
2281
|
|
|
532
|
-
|
|
533
|
-
|
|
2282
|
+
return interaction.editReply({ embeds: [embed] });
|
|
2283
|
+
}
|
|
534
2284
|
|
|
535
|
-
|
|
536
|
-
|
|
2285
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
2286
|
+
// ๐๏ธ RESET - Delete all configuration
|
|
2287
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
2288
|
+
if (subcommand === "reset") {
|
|
2289
|
+
await Log.findOneAndDelete({ guildId });
|
|
2290
|
+
|
|
2291
|
+
clearLogCache(guildId);
|
|
537
2292
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
2293
|
+
const embed = new EmbedBuilder()
|
|
2294
|
+
.setTitle("๐๏ธ Configuration Reset")
|
|
2295
|
+
.setDescription(
|
|
2296
|
+
"All logging settings have been deleted for this server."
|
|
2297
|
+
)
|
|
2298
|
+
.setColor("Red")
|
|
2299
|
+
.setTimestamp();
|
|
2300
|
+
|
|
2301
|
+
return interaction.editReply({ embeds: [embed] });
|
|
2302
|
+
}
|
|
546
2303
|
},
|
|
547
2304
|
};
|
|
548
2305
|
```
|
|
549
2306
|
|
|
2307
|
+
</details>
|
|
2308
|
+
|
|
550
2309
|
---
|
|
551
2310
|
|
|
552
|
-
### ๐ก
|
|
2311
|
+
### ๐ก Tips & Notes
|
|
553
2312
|
|
|
554
|
-
-
|
|
555
|
-
-
|
|
556
|
-
-
|
|
2313
|
+
- ๐ **Caching**: The system caches guild configurations for better performance.
|
|
2314
|
+
- ๐ **Permissions**: Make sure your bot has `View Audit Log` permission for full functionality.
|
|
2315
|
+
- ๐ข **Invite Tracking**: Uses `discord-inviter` package for accurate invite tracking.
|
|
2316
|
+
- ๐จ **Default Colors**: Each event type has sensible default colors if not customized.
|
|
2317
|
+
- ๐ซ **Disabled Events**: Events in the `disable` array will be completely ignored.
|
|
2318
|
+
- ๐ **Channel Fallback**: If no specific channel is set for an event, it uses `channelId`.
|
|
2319
|
+
- ๐พ **Database Mode**: Recommended for multi-server bots with dynamic configuration needs.
|
|
2320
|
+
- ๐ **Dashboard Integration**: When using database mode, you can manage logs via the web dashboard!
|
|
2321
|
+
|
|
2322
|
+
---
|
|
557
2323
|
|
|
558
2324
|
</details>
|
|
559
2325
|
|
|
@@ -809,55 +2575,54 @@ const { Gstart } = require("djs-builder");
|
|
|
809
2575
|
const { EmbedBuilder } = require("discord.js");
|
|
810
2576
|
|
|
811
2577
|
module.exports = {
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
const twoDays = Date.now() +
|
|
817
|
-
const channelId =
|
|
818
|
-
|
|
819
|
-
ย ย await Gstart({
|
|
820
|
-
ย ย ย context: message,
|
|
821
|
-
ย ย ย endTime: twoDays,
|
|
822
|
-
ย ย ย winers: 5, // 5 lucky winners! ๐
|
|
823
|
-
ย ย ย channelId: channelId,
|
|
2578
|
+
name: "gstart",
|
|
2579
|
+
description: "Starts a new highly-customized giveaway.",
|
|
2580
|
+
run: async (client, message, args) => {
|
|
2581
|
+
// โฐ Giveaway ends in 48 hours
|
|
2582
|
+
const twoDays = Date.now() + 48 * 60 * 60 * 1000;
|
|
2583
|
+
const channelId = "YOUR_GIVEAWAY_CHANNEL_ID"; // ๐ข Target Channel
|
|
824
2584
|
|
|
825
|
-
|
|
826
|
-
|
|
2585
|
+
await Gstart({
|
|
2586
|
+
context: message,
|
|
2587
|
+
endTime: twoDays,
|
|
2588
|
+
winers: 5, // 5 lucky winners! ๐
|
|
2589
|
+
channelId: channelId,
|
|
827
2590
|
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
2591
|
+
// ๐จ Customization for the STARTING EMBED
|
|
2592
|
+
embed: {
|
|
2593
|
+
custom: new EmbedBuilder().setTitle("Raw Embed"), // ๐ก You can use 'custom' to pass a raw Discord.js EmbedBuilder JSON
|
|
2594
|
+
title: "๐ **HUGE SERVER BOOST GIVEAWAY!**",
|
|
2595
|
+
description:
|
|
2596
|
+
"Click the button below to enter for a chance to win a free server boost!",
|
|
2597
|
+
color: "Blue", // Any valid Discord color
|
|
2598
|
+
image: "https://yourimage.com/banner.png", // image URL
|
|
2599
|
+
thumbnail: message.guild.iconURL(),
|
|
2600
|
+
},
|
|
835
2601
|
|
|
836
2602
|
// ๐ Customization for the ENDED EMBED
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
ย ย ย },
|
|
2603
|
+
endEmbed: {
|
|
2604
|
+
custom: new EmbedBuilder().setTitle("Raw Embed"), // ๐ก You can use 'custom' to pass a raw Discord.js EmbedBuilder JSON
|
|
2605
|
+
title: "๐ Giveaway Has Concluded!",
|
|
2606
|
+
description: "Congratulations to the winners! Check the message below.",
|
|
2607
|
+
color: "Green", // Eimage and Ethumbnail can also be set here
|
|
2608
|
+
},
|
|
844
2609
|
|
|
845
2610
|
// ๐ฑ๏ธ Button Entry Method
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
2611
|
+
reaction: {
|
|
2612
|
+
type: "button", // Use 'reaction' for an emoji reaction
|
|
2613
|
+
emoji: "โ
", // The emoji displayed on the button
|
|
2614
|
+
label: "Enter Giveaway!", // The text label
|
|
2615
|
+
style: 3, // Button style: Primary(1), Secondary(2), Success(3), Danger(4)
|
|
2616
|
+
id: "djs-builder-giveaway", // Custom ID for the button
|
|
2617
|
+
},
|
|
853
2618
|
|
|
854
2619
|
// ๐ Requirements (Optional)
|
|
855
2620
|
requirements: {
|
|
856
2621
|
requiredRoles: ["123456789012345678"], // ๐ก๏ธ User MUST have this role to join (Button Only)
|
|
857
2622
|
},
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
2623
|
+
});
|
|
2624
|
+
message.reply("๐ Giveaway started successfully!");
|
|
2625
|
+
},
|
|
861
2626
|
};
|
|
862
2627
|
```
|
|
863
2628
|
|
|
@@ -1103,14 +2868,14 @@ module.exports = {
|
|
|
1103
2868
|
const result = await GaddUser(
|
|
1104
2869
|
interaction.message.id,
|
|
1105
2870
|
interaction.user.id,
|
|
1106
|
-
interaction.guild
|
|
2871
|
+
interaction.guild
|
|
1107
2872
|
);
|
|
1108
2873
|
|
|
1109
2874
|
if (result?.error) {
|
|
1110
2875
|
// Handles both "User Already Joined" and "Missing Roles" errors
|
|
1111
2876
|
if (result.error === "โ User Already Joined") {
|
|
1112
|
-
|
|
1113
|
-
|
|
2877
|
+
// ... (Leave button logic)
|
|
2878
|
+
const row = await CreateRow([
|
|
1114
2879
|
[
|
|
1115
2880
|
{
|
|
1116
2881
|
label: "Leave Giveaway",
|
|
@@ -1120,16 +2885,17 @@ module.exports = {
|
|
|
1120
2885
|
],
|
|
1121
2886
|
]);
|
|
1122
2887
|
return interaction.reply({
|
|
1123
|
-
content:
|
|
2888
|
+
content:
|
|
2889
|
+
"โ ๏ธ You have **already joined** this giveaway! You can **leave** by clicking the button below.",
|
|
1124
2890
|
components: row,
|
|
1125
|
-
flags: 64,
|
|
2891
|
+
flags: 64,
|
|
1126
2892
|
});
|
|
1127
2893
|
}
|
|
1128
|
-
|
|
2894
|
+
|
|
1129
2895
|
// Show error (e.g. Missing Role)
|
|
1130
2896
|
return interaction.reply({
|
|
1131
|
-
|
|
1132
|
-
|
|
2897
|
+
content: result.error,
|
|
2898
|
+
flags: 64,
|
|
1133
2899
|
});
|
|
1134
2900
|
}
|
|
1135
2901
|
|
|
@@ -1139,7 +2905,6 @@ module.exports = {
|
|
|
1139
2905
|
});
|
|
1140
2906
|
}
|
|
1141
2907
|
|
|
1142
|
-
|
|
1143
2908
|
// 2. Handle Leave Button Click (Dynamically Generated ID)
|
|
1144
2909
|
if (
|
|
1145
2910
|
interaction.customId &&
|
|
@@ -1534,7 +3299,7 @@ module.exports = {
|
|
|
1534
3299
|
channelId: channel.id,
|
|
1535
3300
|
winers: winnerCount,
|
|
1536
3301
|
endTime: endTimeMs,
|
|
1537
|
-
prize
|
|
3302
|
+
prize: prize,
|
|
1538
3303
|
embed: {
|
|
1539
3304
|
title: `๐ ${prize} Giveaway!`,
|
|
1540
3305
|
image: image,
|
|
@@ -1810,7 +3575,6 @@ module.exports = {
|
|
|
1810
3575
|
|
|
1811
3576
|
---
|
|
1812
3577
|
|
|
1813
|
-
|
|
1814
3578
|
<details>
|
|
1815
3579
|
<summary>Blacklist System ๐ซ</summary>
|
|
1816
3580
|
|
|
@@ -1882,10 +3646,12 @@ console.log("Role unblacklisted! ๐");
|
|
|
1882
3646
|
Returns an array of blacklisted items for a guild. You can optionally filter by type (`user`, `role`, `channel`).
|
|
1883
3647
|
|
|
1884
3648
|
**Parameters:**
|
|
3649
|
+
|
|
1885
3650
|
- `guildId` (String): The ID of the guild.
|
|
1886
3651
|
- `type` (String, optional): The type to filter by (`user`, `role`, `channel`).
|
|
1887
3652
|
|
|
1888
3653
|
**Example:**
|
|
3654
|
+
|
|
1889
3655
|
```js
|
|
1890
3656
|
// Get all blacklisted items
|
|
1891
3657
|
const allBlacklisted = await getBlacklist("GUILD_ID");
|
|
@@ -1910,35 +3676,80 @@ Output:
|
|
|
1910
3676
|
You can create a slash command to manage the blacklist easily.
|
|
1911
3677
|
|
|
1912
3678
|
```js
|
|
1913
|
-
const {
|
|
1914
|
-
|
|
3679
|
+
const {
|
|
3680
|
+
addToBlacklist,
|
|
3681
|
+
removeFromBlacklist,
|
|
3682
|
+
isBlacklisted,
|
|
3683
|
+
getBlacklist,
|
|
3684
|
+
} = require("djs-builder");
|
|
3685
|
+
const {
|
|
3686
|
+
SlashCommandBuilder,
|
|
3687
|
+
PermissionFlagsBits,
|
|
3688
|
+
EmbedBuilder,
|
|
3689
|
+
} = require("discord.js");
|
|
1915
3690
|
|
|
1916
3691
|
module.exports = {
|
|
1917
3692
|
data: new SlashCommandBuilder()
|
|
1918
3693
|
.setName("blacklist")
|
|
1919
3694
|
.setDescription("Manage the blacklist")
|
|
1920
3695
|
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
|
|
1921
|
-
.addSubcommand(sub =>
|
|
1922
|
-
sub
|
|
1923
|
-
.
|
|
1924
|
-
.
|
|
1925
|
-
.
|
|
3696
|
+
.addSubcommand((sub) =>
|
|
3697
|
+
sub
|
|
3698
|
+
.setName("add")
|
|
3699
|
+
.setDescription("Add to blacklist")
|
|
3700
|
+
.addUserOption((opt) =>
|
|
3701
|
+
opt.setName("user").setDescription("User to blacklist")
|
|
3702
|
+
)
|
|
3703
|
+
.addRoleOption((opt) =>
|
|
3704
|
+
opt.setName("role").setDescription("Role to blacklist")
|
|
3705
|
+
)
|
|
3706
|
+
.addChannelOption((opt) =>
|
|
3707
|
+
opt.setName("channel").setDescription("Channel to blacklist")
|
|
3708
|
+
)
|
|
1926
3709
|
)
|
|
1927
|
-
.addSubcommand(sub =>
|
|
1928
|
-
sub
|
|
1929
|
-
.
|
|
1930
|
-
.
|
|
1931
|
-
.
|
|
3710
|
+
.addSubcommand((sub) =>
|
|
3711
|
+
sub
|
|
3712
|
+
.setName("remove")
|
|
3713
|
+
.setDescription("Remove from blacklist")
|
|
3714
|
+
.addUserOption((opt) =>
|
|
3715
|
+
opt.setName("user").setDescription("User to remove")
|
|
3716
|
+
)
|
|
3717
|
+
.addRoleOption((opt) =>
|
|
3718
|
+
opt.setName("role").setDescription("Role to remove")
|
|
3719
|
+
)
|
|
3720
|
+
.addChannelOption((opt) =>
|
|
3721
|
+
opt.setName("channel").setDescription("Channel to remove")
|
|
3722
|
+
)
|
|
1932
3723
|
)
|
|
1933
|
-
.addSubcommand(sub =>
|
|
1934
|
-
sub
|
|
1935
|
-
.
|
|
1936
|
-
.
|
|
1937
|
-
.
|
|
3724
|
+
.addSubcommand((sub) =>
|
|
3725
|
+
sub
|
|
3726
|
+
.setName("check")
|
|
3727
|
+
.setDescription("Check if a target is blacklisted")
|
|
3728
|
+
.addUserOption((opt) =>
|
|
3729
|
+
opt.setName("user").setDescription("User to check")
|
|
3730
|
+
)
|
|
3731
|
+
.addRoleOption((opt) =>
|
|
3732
|
+
opt.setName("role").setDescription("Role to check")
|
|
3733
|
+
)
|
|
3734
|
+
.addChannelOption((opt) =>
|
|
3735
|
+
opt.setName("channel").setDescription("Channel to check")
|
|
3736
|
+
)
|
|
1938
3737
|
)
|
|
1939
|
-
.addSubcommand(sub =>
|
|
1940
|
-
sub
|
|
1941
|
-
.
|
|
3738
|
+
.addSubcommand((sub) =>
|
|
3739
|
+
sub
|
|
3740
|
+
.setName("list")
|
|
3741
|
+
.setDescription("List all blacklisted items")
|
|
3742
|
+
.addStringOption((opt) =>
|
|
3743
|
+
opt
|
|
3744
|
+
.setName("type")
|
|
3745
|
+
.setDescription("Filter by type")
|
|
3746
|
+
.addChoices(
|
|
3747
|
+
{ name: "User", value: "user" },
|
|
3748
|
+
{ name: "Role", value: "role" },
|
|
3749
|
+
{ name: "Channel", value: "channel" },
|
|
3750
|
+
{ name: "All", value: "all" }
|
|
3751
|
+
)
|
|
3752
|
+
)
|
|
1942
3753
|
),
|
|
1943
3754
|
async run(interaction) {
|
|
1944
3755
|
const sub = interaction.options.getSubcommand();
|
|
@@ -1948,54 +3759,95 @@ module.exports = {
|
|
|
1948
3759
|
const guildId = interaction.guild.id;
|
|
1949
3760
|
|
|
1950
3761
|
if (sub === "list") {
|
|
1951
|
-
|
|
1952
|
-
|
|
3762
|
+
const type = interaction.options.getString("type");
|
|
3763
|
+
if (type !== "all") {
|
|
1953
3764
|
const list = await getBlacklist(guildId, type);
|
|
1954
3765
|
|
|
1955
|
-
if (!list.length)
|
|
3766
|
+
if (!list.length)
|
|
3767
|
+
return interaction.reply({
|
|
3768
|
+
content: "โ
No blacklisted items found.",
|
|
3769
|
+
flags: 64,
|
|
3770
|
+
});
|
|
1956
3771
|
|
|
1957
3772
|
const embed = new EmbedBuilder()
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
3773
|
+
.setTitle("๐ซ Blacklist")
|
|
3774
|
+
.setColor("Red")
|
|
3775
|
+
.setDescription(
|
|
3776
|
+
list
|
|
3777
|
+
.map(
|
|
3778
|
+
(item) =>
|
|
3779
|
+
`โข **${item.type.toUpperCase()}**: <${
|
|
3780
|
+
item.type === "channel"
|
|
3781
|
+
? "#"
|
|
3782
|
+
: item.type === "role"
|
|
3783
|
+
? "@&"
|
|
3784
|
+
: "@"
|
|
3785
|
+
}${item.id}> (\`${item.id}\`)`
|
|
3786
|
+
)
|
|
3787
|
+
.join("\n")
|
|
3788
|
+
.slice(0, 4000)
|
|
3789
|
+
);
|
|
3790
|
+
|
|
3791
|
+
return interaction.reply({ embeds: [embed], flags: 64 });
|
|
3792
|
+
} else {
|
|
1964
3793
|
const list = await getBlacklist(guildId);
|
|
1965
|
-
if (!list.length)
|
|
3794
|
+
if (!list.length)
|
|
3795
|
+
return interaction.reply({
|
|
3796
|
+
content: "โ
No blacklisted items found.",
|
|
3797
|
+
flags: 64,
|
|
3798
|
+
});
|
|
1966
3799
|
|
|
1967
3800
|
const embeds = [];
|
|
1968
|
-
const roles = list.filter(i => i.type === "role");
|
|
1969
|
-
const users = list.filter(i => i.type === "user");
|
|
1970
|
-
const channels = list.filter(i => i.type === "channel");
|
|
3801
|
+
const roles = list.filter((i) => i.type === "role");
|
|
3802
|
+
const users = list.filter((i) => i.type === "user");
|
|
3803
|
+
const channels = list.filter((i) => i.type === "channel");
|
|
1971
3804
|
|
|
1972
3805
|
if (users.length) {
|
|
1973
|
-
|
|
3806
|
+
const userEmbed = new EmbedBuilder()
|
|
1974
3807
|
.setTitle("๐ซ Blacklisted Users")
|
|
1975
3808
|
.setColor("Red")
|
|
1976
|
-
.setDescription(
|
|
1977
|
-
|
|
3809
|
+
.setDescription(
|
|
3810
|
+
users
|
|
3811
|
+
.map((item) => `โข <@${item.id}> (\`${item.id}\`)`)
|
|
3812
|
+
.join("\n")
|
|
3813
|
+
.slice(0, 4000)
|
|
3814
|
+
);
|
|
3815
|
+
embeds.push(userEmbed);
|
|
1978
3816
|
}
|
|
1979
|
-
if(
|
|
1980
|
-
|
|
3817
|
+
if (roles.length) {
|
|
3818
|
+
const roleEmbed = new EmbedBuilder()
|
|
1981
3819
|
.setTitle("๐ซ Blacklisted Roles")
|
|
1982
3820
|
.setColor("Red")
|
|
1983
|
-
.setDescription(
|
|
1984
|
-
|
|
3821
|
+
.setDescription(
|
|
3822
|
+
roles
|
|
3823
|
+
.map((item) => `โข <@&${item.id}> (\`${item.id}\`)`)
|
|
3824
|
+
.join("\n")
|
|
3825
|
+
.slice(0, 4000)
|
|
3826
|
+
);
|
|
3827
|
+
embeds.push(roleEmbed);
|
|
1985
3828
|
}
|
|
1986
|
-
if(
|
|
1987
|
-
|
|
3829
|
+
if (channels.length) {
|
|
3830
|
+
const channelEmbed = new EmbedBuilder()
|
|
1988
3831
|
.setTitle("๐ซ Blacklisted Channels")
|
|
1989
3832
|
.setColor("Red")
|
|
1990
|
-
.setDescription(
|
|
1991
|
-
|
|
3833
|
+
.setDescription(
|
|
3834
|
+
channels
|
|
3835
|
+
.map((item) => `โข <#${item.id}> (\`${item.id}\`)`)
|
|
3836
|
+
.join("\n")
|
|
3837
|
+
.slice(0, 4000)
|
|
3838
|
+
);
|
|
3839
|
+
embeds.push(channelEmbed);
|
|
1992
3840
|
}
|
|
1993
|
-
return interaction.reply({ embeds, flags
|
|
3841
|
+
return interaction.reply({ embeds, flags: 64 });
|
|
3842
|
+
}
|
|
1994
3843
|
}
|
|
1995
|
-
|
|
1996
|
-
|
|
3844
|
+
|
|
1997
3845
|
if (!user && !role && !channel) {
|
|
1998
|
-
return interaction.reply({
|
|
3846
|
+
return interaction.reply({
|
|
3847
|
+
content:
|
|
3848
|
+
"โ ๏ธ You must provide at least one option (User, Role, or Channel).",
|
|
3849
|
+
flags: 64,
|
|
3850
|
+
});
|
|
1999
3851
|
}
|
|
2000
3852
|
const target = user || role || channel;
|
|
2001
3853
|
const type = user ? "user" : role ? "role" : "channel";
|
|
@@ -2003,18 +3855,25 @@ module.exports = {
|
|
|
2003
3855
|
|
|
2004
3856
|
if (sub === "add") {
|
|
2005
3857
|
const success = await addToBlacklist(guildId, type, id);
|
|
2006
|
-
if (success)
|
|
2007
|
-
|
|
3858
|
+
if (success)
|
|
3859
|
+
interaction.reply(`โ
Added **${type}** ${target} to blacklist.`);
|
|
3860
|
+
else
|
|
3861
|
+
interaction.reply(`โ ๏ธ **${type}** ${target} is already blacklisted.`);
|
|
2008
3862
|
} else if (sub === "remove") {
|
|
2009
3863
|
const success = await removeFromBlacklist(guildId, type, id);
|
|
2010
|
-
if (success)
|
|
3864
|
+
if (success)
|
|
3865
|
+
interaction.reply(`โ
Removed **${type}** ${target} from blacklist.`);
|
|
2011
3866
|
else interaction.reply(`โ ๏ธ **${type}** ${target} is not blacklisted.`);
|
|
2012
3867
|
} else if (sub === "check") {
|
|
2013
3868
|
const isBlocked = await isBlacklisted(guildId, type, id);
|
|
2014
|
-
if (isBlocked)
|
|
2015
|
-
|
|
3869
|
+
if (isBlocked)
|
|
3870
|
+
interaction.reply(
|
|
3871
|
+
`๐ซ **${type}** ${target} is currently **blacklisted**.`
|
|
3872
|
+
);
|
|
3873
|
+
else
|
|
3874
|
+
interaction.reply(`โ
**${type}** ${target} is **not** blacklisted.`);
|
|
2016
3875
|
}
|
|
2017
|
-
}
|
|
3876
|
+
},
|
|
2018
3877
|
};
|
|
2019
3878
|
```
|
|
2020
3879
|
|
|
@@ -2160,6 +4019,7 @@ The **Dashboard System** is a modern, lightweight web-based control panel for yo
|
|
|
2160
4019
|
- ๐ **Commands Viewer** โ Browse all slash and prefix commands.
|
|
2161
4020
|
- ๐ **Level System Management** โ View leaderboards, manage user XP and levels.
|
|
2162
4021
|
- ๐ **Giveaway Control** โ Pause, resume, end, reroll, or delete giveaways.
|
|
4022
|
+
- ๐ฆพ **Logging System Control** โ Manage log channels, colors, and event toggles.
|
|
2163
4023
|
- ๐ซ **Blacklist Management** โ Add/remove users, roles, or channels from blacklist.
|
|
2164
4024
|
- ๐จ **Modern UI** โ Beautiful, responsive design with dark mode support.
|
|
2165
4025
|
|
|
@@ -2191,11 +4051,10 @@ const starterOptions = {
|
|
|
2191
4051
|
|
|
2192
4052
|
// ๐ Dashboard Configuration
|
|
2193
4053
|
dashboard: {
|
|
2194
|
-
clientID: "YOUR_DISCORD_CLIENT_ID", // ๐ Discord Application Client ID
|
|
2195
4054
|
clientSecret: "YOUR_DISCORD_CLIENT_SECRET", // ๐ Discord Application Client Secret
|
|
2196
|
-
callbackURL: "http://localhost:3000/auth/discord/callback", // ๐ OAuth2 Callback URL
|
|
2197
|
-
sessionSecret: "your-super-secret-key",
|
|
2198
|
-
port: 3000,
|
|
4055
|
+
callbackURL: "http://localhost:3000/auth/discord/callback", // ๐ OAuth2 Callback URL (OPTINAL)
|
|
4056
|
+
sessionSecret: "your-super-secret-key", // ๐ Session encryption secret
|
|
4057
|
+
port: 3000, // ๐ Dashboard port (OPTINAL / default: 3000)
|
|
2199
4058
|
},
|
|
2200
4059
|
|
|
2201
4060
|
// ... other options (Status, database, anticrash, etc.)
|
|
@@ -2229,11 +4088,10 @@ client.once("ready", () => {
|
|
|
2229
4088
|
|
|
2230
4089
|
// ๐ Start the Dashboard
|
|
2231
4090
|
dashboard(client, {
|
|
2232
|
-
clientID: "YOUR_DISCORD_CLIENT_ID", // ๐ Discord Application Client ID
|
|
2233
4091
|
clientSecret: "YOUR_DISCORD_CLIENT_SECRET", // ๐ Discord Application Client Secret
|
|
2234
|
-
callbackURL: "http://localhost:3000/auth/discord/callback", // ๐ OAuth2 Callback URL
|
|
2235
|
-
sessionSecret: "your-super-secret-key",
|
|
2236
|
-
port: 3000,
|
|
4092
|
+
callbackURL: "http://localhost:3000/auth/discord/callback", // ๐ OAuth2 Callback URL (OPTINAL)
|
|
4093
|
+
sessionSecret: "your-super-secret-key", // ๐ Session encryption secret
|
|
4094
|
+
port: 3000, // ๐ Dashboard port (OPTINAL / default: 3000)
|
|
2237
4095
|
});
|
|
2238
4096
|
});
|
|
2239
4097
|
```
|
|
@@ -2249,15 +4107,16 @@ client.once("ready", () => {
|
|
|
2249
4107
|
|
|
2250
4108
|
### ๐ Dashboard Routes
|
|
2251
4109
|
|
|
2252
|
-
| Route
|
|
2253
|
-
|
|
2254
|
-
| `/`
|
|
2255
|
-
| `/login`
|
|
2256
|
-
| `/dashboard`
|
|
2257
|
-
| `/dashboard/:guildId`
|
|
2258
|
-
| `/dashboard/:guildId/commands`
|
|
2259
|
-
| `/dashboard/:guildId/levels`
|
|
2260
|
-
| `/dashboard/:guildId/giveaways` | ๐ Giveaway management
|
|
4110
|
+
| Route | Description |
|
|
4111
|
+
| ------------------------------- | ---------------------------- |
|
|
4112
|
+
| `/` | ๐ Homepage with bot stats |
|
|
4113
|
+
| `/login` | ๐ Login page |
|
|
4114
|
+
| `/dashboard` | ๐ Server selection |
|
|
4115
|
+
| `/dashboard/:guildId` | ๐ Server overview |
|
|
4116
|
+
| `/dashboard/:guildId/commands` | ๐ Commands list |
|
|
4117
|
+
| `/dashboard/:guildId/levels` | ๐ Level leaderboard |
|
|
4118
|
+
| `/dashboard/:guildId/giveaways` | ๐ Giveaway management |
|
|
4119
|
+
| `/dashboard/:guildId/logs` | ๐ก๏ธ Logging system management |
|
|
2261
4120
|
|
|
2262
4121
|
---
|
|
2263
4122
|
|
|
@@ -2290,7 +4149,13 @@ POST /api/:guildId/giveaway/end
|
|
|
2290
4149
|
POST /api/:guildId/giveaway/reroll
|
|
2291
4150
|
POST /api/:guildId/giveaway/delete
|
|
2292
4151
|
|
|
2293
|
-
//
|
|
4152
|
+
// ๏ฟฝ๏ธ Logging system management
|
|
4153
|
+
POST /api/:guildId/logs/channel // Set default log channel
|
|
4154
|
+
POST /api/:guildId/logs/toggle // Enable/disable event type
|
|
4155
|
+
POST /api/:guildId/logs/event // Update event settings (channel, color)
|
|
4156
|
+
POST /api/:guildId/logs/reset // Reset all log settings
|
|
4157
|
+
|
|
4158
|
+
// ๏ฟฝ๐ซ Blacklist management
|
|
2294
4159
|
POST /api/guild/:guildId/blacklist // Add to blacklist
|
|
2295
4160
|
DELETE /api/guild/:guildId/blacklist // Remove from blacklist
|
|
2296
4161
|
```
|
|
@@ -2304,13 +4169,12 @@ DELETE /api/guild/:guildId/blacklist // Remove from blacklist
|
|
|
2304
4169
|
|
|
2305
4170
|
### ๐ง Configuration Options
|
|
2306
4171
|
|
|
2307
|
-
| Option
|
|
2308
|
-
|
|
2309
|
-
| `
|
|
2310
|
-
| `
|
|
2311
|
-
| `
|
|
2312
|
-
| `
|
|
2313
|
-
| `port` | `number` | โ | ๐ Port to run the dashboard (default: 3000) |
|
|
4172
|
+
| Option | Type | Required | Description |
|
|
4173
|
+
| --------------- | -------- | -------- | ---------------------------------------------------- |
|
|
4174
|
+
| `clientSecret` | `string` | โ
| ๐ Your Discord Application Client Secret |
|
|
4175
|
+
| `callbackURL` | `string` | โ
| ๐ OAuth2 redirect URL (must match Discord settings) |
|
|
4176
|
+
| `sessionSecret` | `string` | โ
| ๐ Secret key for session encryption |
|
|
4177
|
+
| `port` | `number` | โ | ๐ Port to run the dashboard (default: 3000) |
|
|
2314
4178
|
|
|
2315
4179
|
---
|
|
2316
4180
|
|
|
@@ -2318,16 +4182,17 @@ DELETE /api/guild/:guildId/blacklist // Remove from blacklist
|
|
|
2318
4182
|
|
|
2319
4183
|
The dashboard uses **EJS** templates located in the `views` folder:
|
|
2320
4184
|
|
|
2321
|
-
| File
|
|
2322
|
-
|
|
2323
|
-
| `index.ejs`
|
|
2324
|
-
| `login.ejs`
|
|
2325
|
-
| `dashboard.ejs` | ๐ Server selection
|
|
2326
|
-
| `guild.ejs`
|
|
2327
|
-
| `commands.ejs`
|
|
2328
|
-
| `levels.ejs`
|
|
2329
|
-
| `giveaways.ejs` | ๐ Giveaway management
|
|
2330
|
-
| `
|
|
4185
|
+
| File | Description |
|
|
4186
|
+
| --------------- | ---------------------------- |
|
|
4187
|
+
| `index.ejs` | ๐ Homepage |
|
|
4188
|
+
| `login.ejs` | ๐ Login page |
|
|
4189
|
+
| `dashboard.ejs` | ๐ Server selection |
|
|
4190
|
+
| `guild.ejs` | ๐ Server overview |
|
|
4191
|
+
| `commands.ejs` | ๐ Commands list |
|
|
4192
|
+
| `levels.ejs` | ๐ Level management |
|
|
4193
|
+
| `giveaways.ejs` | ๐ Giveaway management |
|
|
4194
|
+
| `logs.ejs` | ๐ก๏ธ Logging system management |
|
|
4195
|
+
| `404.ejs` | โ Not found page |
|
|
2331
4196
|
|
|
2332
4197
|
</details>
|
|
2333
4198
|
|
|
@@ -2368,4 +4233,4 @@ We welcome contributions! If you have any suggestions, bug reports, or feature r
|
|
|
2368
4233
|
|
|
2369
4234
|
๐ **Join our Discord:**
|
|
2370
4235
|
|
|
2371
|
-
[](https://discord.gg/uYcKCZk3)
|