Skip to content

Commit f77bf82

Browse files
committed
Update v2.1.0
1 parent bb0f3d3 commit f77bf82

File tree

21 files changed

+305
-45
lines changed

21 files changed

+305
-45
lines changed

.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CLIENT_TOKEN = Your bot token
2+
CLIENT_ID = Your bot ID
3+
MONGODB_URI = Your mongodb URI string

README.md

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ The simplified Discord bot commands & events handler built with discord.js versi
77
- The user commands are built-in Discord commands, and to execute a user command, right-click on a Discord user profile, Apps, and then select a command.
88
- The message commands are built-in Discord commands, and to execute a message command, right-click on a message, Apps, and then select a command.
99

10-
Did you liked my project? Click on the star button (⭐️) right above your screen, thank you!
10+
This project also handles components, such as Buttons and Select menu (any; String, User, Role...).
11+
12+
Did you like my project? Click on the star button (⭐️) right above your screen, thank you!
1113

1214
Looking for the old version? [Click here](https://github.com/TFAGaming/DiscordJS-V14-Bot-Template/releases/tag/v1.7.0-last).
1315

14-
## Commands/Events structure
16+
## Commands, events, and components structure
1517

1618
> **Note**
1719
> This handler uses **CommonJS** modules system.
@@ -44,14 +46,24 @@ module.exports = {
4446
```ts
4547
module.exports = {
4648
event: string,
47-
once: boolean,
48-
// ...args are the arguments of the event chosen (from discord.js).
49+
once?: boolean,
50+
// '...args' are the arguments of the event chosen (from discord.js).
4951
run: (client, ...args) => {
5052

5153
}
5254
};
5355
```
5456

57+
### Component:
58+
```ts
59+
module.exports = {
60+
customId: string,
61+
run: (client, interaction) => {
62+
63+
}
64+
};
65+
```
66+
5567
## Requirements
5668
### Packages:
5769
- **chalk** v2.4.2
@@ -89,22 +101,32 @@ handler: {
89101
message: boolean // <= Toggle message commands
90102
},
91103
mongodb: { // MongoDB database
92-
uri: string // <= Your MongoDB URI string
104+
uri: string, // <= Your MongoDB URI string,
105+
toggle: boolean // <= Connect to the database or not? (true: Yes, false: No)
93106
}
94107
}
95108
```
96109

110+
You can use ENV instead of `config.js` to keep your bot token and ID and your MongoDB URI in a safe place. Rename the file `.env.example` to `.env` and fill all the required values.
111+
112+
```apache
113+
CLIENT_TOKEN = Your bot token
114+
CLIENT_ID = Your bot ID
115+
MONGODB_URI = Your mongodb URI string
116+
```
117+
97118
6. To start your bot, run `node .` or `npm run start`.
98119
7. Enjoy. =)
99120

100121
## Hosting (<img src="https://media.discordapp.net/attachments/1111644651036876822/1124045180484472882/discloud_white_horizon-e96efbfa.png?width=960&height=163" width=100>)
101-
Use [DisCloud](https://discloudbot.com/)! A trust-worthy Discord bot hosting service.
122+
Use [Discloud](https://discloudbot.com/)! A trust-worthy Discord bot hosting service.
102123

103124
1. Login using your Discord/GitHub account, and then don't close the Dashboard tab (because we need it later).
104-
2. Go to your project on VSCode, create a new file `discloud.config`. This file is a configuration file for DisCloud apps servers. The `discloud.config` file content must be like the codeblock below, and remember to change **YOUR_BOT_ID** to your actual bot ID.
125+
2. Go to your project on VSCode, create a new file `discloud.config`. This file is a configuration file for Discloud apps servers. The `discloud.config` file content must be like the codeblock below, and remember to change **YOUR_BOT_ID** to your actual bot ID.
105126

106-
```config
107-
ID = YOUR_BOT_ID
127+
```apache
128+
# Your actual bot ID below
129+
ID = 1234567890123456789
108130
TYPE = bot
109131
MAIN = src/index.js
110132
RAM = 100
@@ -114,11 +136,11 @@ API = tools
114136
```
115137

116138
3. Open explorer and navigate using the path of your project. Hold the **CTRL** key, and click on `src/`, `package.json`, and `discloud.config`. Now release the key, and right click on the selected files/folders and click on **Convert into .zip file**.
117-
4. Go back to the DisCloud dashboard, click on **Add App**, and then upload the .zip file in the upload box. Make sure to accept the ToS of the service and then click on **Upload**.
139+
4. Go back to the Discloud dashboard, click on **Add App**, and then upload the .zip file in the upload box. Make sure to accept the ToS of the service and then click on **Upload**.
118140
5. Wait for at least 20 seconds (depends on your Internet speed), and then your bot should be on.
119141

120142
> **Warning**
121-
> DisCloud has recently made every Free plan servers into **15 days** hosting only. Use the command `.rw` from their bot in the commands channel (on their Discord server) to reset the timer to **0**.
143+
> Discloud has recently made every Free plan servers into **15 days** hosting only. Use the command `.rw` from their bot in the commands channel (on their Discord server) to reset the timer. Join the server: [Click here!](https://discord.gg/discloud-584490943034425391)
122144
123145
## Contributors
124146
<img src="https://contrib.rocks/image?repo=TFAGaming/DiscordJS-V14-Bot-Template">

command.example.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ module.exports = {
77
structure: {
88
name: '',
99
description: '',
10-
aliases: ['']
10+
aliases: [],
11+
permissions: null
1112
},
1213
/**
1314
* @param {ExtendedClient} client

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
{
22
"name": "discordjs-v14-bot-template",
33
"version": "2.0.0",
4-
"description": "",
4+
"description": "The simplified Discord bot commands & events handler built with discord.js version 14 and written in JavaScript. This handler can load up to 4 different type of commands; Prefix, Slash, User context and Message context.",
55
"main": "src/index.js",
66
"scripts": {
77
"test": "echo \"Wow is this a test?\" && exit 1",
8-
"start": "node .",
9-
"git": "git add . && git commit -m \"Git auto\""
8+
"start": "node ."
109
},
1110
"keywords": [],
1211
"author": "",

src/class/ExtendedClient.js

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,27 @@
1-
const { Client, Partials, Collection } = require("discord.js");
1+
const { Client, Partials, Collection, GatewayIntentBits } = require("discord.js");
22
const config = require('../config');
33
const commands = require("../handlers/commands");
44
const events = require("../handlers/events");
55
const deploy = require("../handlers/deploy");
66
const mongoose = require("../handlers/mongoose");
7+
const components = require("../handlers/components");
78

89
module.exports = class extends Client {
910
collection = {
1011
interactioncommands: new Collection(),
1112
prefixcommands: new Collection(),
12-
aliases: new Collection()
13+
aliases: new Collection(),
14+
components: {
15+
buttons: new Collection(),
16+
selects: new Collection()
17+
}
1318
};
1419
applicationcommandsArray = [];
1520

1621
constructor() {
1722
super({
18-
intents: [
19-
'Guilds',
20-
'GuildMessages',
21-
'GuildMembers',
22-
'MessageContent'
23-
],
24-
partials: [
25-
Partials.Channel,
26-
Partials.User,
27-
Partials.Message
28-
],
23+
intents: [Object.keys(GatewayIntentBits)],
24+
partials: [Object.keys(Partials)],
2925
presence: {
3026
activities: [{
3127
name: 'DiscordJS-V14-Bot-Template v2'
@@ -35,11 +31,12 @@ module.exports = class extends Client {
3531
};
3632

3733
start = async () => {
38-
await this.login(process.env.CLIENT_TOKEN || config.client.token);
39-
4034
commands(this);
4135
events(this);
42-
mongoose();
36+
components(this);
37+
if (config.handler.mongodb.toggle) mongoose();
38+
39+
await this.login(process.env.CLIENT_TOKEN || config.client.token);
4340

4441
if (config.handler.deploy) deploy(this, config);
4542
};

src/commands/prefix/Info/help.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,20 @@ module.exports = {
1616
*/
1717
run: async (client, message, args) => {
1818

19-
const prefix = (await GuildSchema.findOne({ guild: message.guildId }))?.prefix || config.handler.prefix;
19+
let prefix = config.handler.prefix;
2020

21-
const mapIntCmds = client.applicationcommandsArray.map((v) => `\`/${v.name}\`: ${v.description}`);
22-
const mapPreCmds = client.collection.prefixcommands.map((v) => `\`${prefix}${v.structure.name}\` (${v.structure.aliases.length > 0 ? v.structure.aliases.map((a) => `**${a}**`).join(', ') : 'None'}): ${v.structure.description || '[No description was provided]'}`);
21+
if (config.handler?.mongodb?.toggle) {
22+
try {
23+
const data = (await GuildSchema.findOne({ guild: message.guildId }));
24+
25+
prefix = data?.prefix;
26+
} catch {
27+
prefix = config.handler.prefix;
28+
};
29+
};
30+
31+
const mapIntCmds = client.applicationcommandsArray.map((v) => `\`/${v.name}\`: ${v.description || '(No description)'}`);
32+
const mapPreCmds = client.collection.prefixcommands.map((v) => `\`${prefix}${v.structure.name}\` (${v.structure.aliases.length > 0 ? v.structure.aliases.map((a) => `**${a}**`).join(', ') : 'None'}): ${v.structure.description || '(No description)'}`);
2333

2434
await message.reply({
2535
embeds: [

src/commands/prefix/Utility/ping.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ module.exports = {
55
structure: {
66
name: 'ping',
77
description: 'Replies with Pong!',
8-
aliases: ['p']
8+
aliases: ['p'],
9+
permissions: 'Administrator'
910
},
1011
/**
1112
* @param {ExtendedClient} client

src/commands/prefix/Utility/prefix.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ module.exports = {
1616
*/
1717
run: async (client, message, args) => {
1818

19+
if (!config.handler?.mongodb?.toggle) {
20+
await message.reply({
21+
content: 'Database is not ready, this command cannot be executed.'
22+
});
23+
24+
return;
25+
};
26+
1927
const type = args[0];
2028

2129
switch (type) {

src/commands/slash/Info/help.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,20 @@ module.exports = {
1616

1717
await interaction.deferReply();
1818

19-
const prefix = (await GuildSchema.findOne({ guild: interaction.guildId }))?.prefix || config.handler.prefix;
19+
let prefix = config.handler.prefix;
2020

21-
const mapIntCmds = client.applicationcommandsArray.map((v) => `\`/${v.name}\`: ${v.description}`);
22-
const mapPreCmds = client.collection.prefixcommands.map((v) => `\`${prefix}${v.structure.name}\` (${v.structure.aliases.length > 0 ? v.structure.aliases.map((a) => `**${a}**`).join(', ') : 'None'}): ${v.structure.description || '[No description was provided]'}`);
21+
if (config.handler?.mongodb?.toggle) {
22+
try {
23+
const data = (await GuildSchema.findOne({ guild: message.guildId }));
24+
25+
prefix = data?.prefix;
26+
} catch {
27+
prefix = config.handler.prefix;
28+
};
29+
};
30+
31+
const mapIntCmds = client.applicationcommandsArray.map((v) => `\`/${v.name}\`: ${v.description || '(No description)'}`);
32+
const mapPreCmds = client.collection.prefixcommands.map((v) => `\`${prefix}${v.structure.name}\` (${v.structure.aliases.length > 0 ? v.structure.aliases.map((a) => `**${a}**`).join(', ') : 'None'}): ${v.structure.description || '(No description)'}`);
2333

2434
await interaction.followUp({
2535
embeds: [
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
const { ChatInputCommandInteraction, SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, StringSelectMenuBuilder } = require('discord.js');
2+
const ExtendedClient = require('../../../class/ExtendedClient');
3+
4+
module.exports = {
5+
structure: new SlashCommandBuilder()
6+
.setName('components')
7+
.setDescription('Test the components handler.'),
8+
/**
9+
* @param {ExtendedClient} client
10+
* @param {ChatInputCommandInteraction} interaction
11+
* @param {[]} args
12+
*/
13+
run: async (client, interaction, args) => {
14+
15+
await interaction.reply({
16+
content: 'Select one of the components below.',
17+
components: [
18+
new ActionRowBuilder()
19+
.addComponents(
20+
new ButtonBuilder()
21+
.setCustomId('example-button')
22+
.setLabel('Example Button')
23+
.setStyle(1)
24+
),
25+
new ActionRowBuilder()
26+
.addComponents(
27+
new StringSelectMenuBuilder()
28+
.setCustomId('example-select')
29+
.setPlaceholder('Example Select menu')
30+
.addOptions(
31+
{ label: 'Option 1', value: 'option 1' },
32+
{ label: 'Option 2', value: 'option 2' },
33+
{ label: 'Option 3', value: 'option 3' },
34+
)
35+
)
36+
]
37+
});
38+
39+
}
40+
};
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const { ButtonInteraction } = require('discord.js');
2+
const ExtendedClient = require('../../class/ExtendedClient');
3+
4+
module.exports = {
5+
customId: 'example-button',
6+
/**
7+
*
8+
* @param {ExtendedClient} client
9+
* @param {ButtonInteraction} interaction
10+
*/
11+
run: async (client, interaction) => {
12+
13+
await interaction.reply({
14+
content: 'The button has been successfully responded!',
15+
ephemeral: true
16+
});
17+
18+
}
19+
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const { StringSelectMenuInteraction } = require('discord.js');
2+
const ExtendedClient = require('../../class/ExtendedClient');
3+
4+
module.exports = {
5+
customId: 'example-select',
6+
/**
7+
*
8+
* @param {ExtendedClient} client
9+
* @param {StringSelectMenuInteraction} interaction
10+
*/
11+
run: async (client, interaction) => {
12+
13+
const value = interaction.values[0];
14+
15+
await interaction.reply({
16+
content: `You have selected from the menu: **${value}**`,
17+
ephemeral: true
18+
});
19+
20+
}
21+
};

src/events/Guild/components.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
const config = require('../../config');
2+
const { log } = require('../../functions');
3+
const ExtendedClient = require('../../class/ExtendedClient');
4+
5+
module.exports = {
6+
event: 'interactionCreate',
7+
/**
8+
*
9+
* @param {ExtendedClient} client
10+
* @param {import('discord.js').Interaction} interaction
11+
* @returns
12+
*/
13+
run: (client, interaction) => {
14+
if (interaction.isButton()) {
15+
const component = client.collection.components.buttons.get(interaction.customId);
16+
17+
if (!component) return;
18+
19+
try {
20+
component.run(client, interaction);
21+
} catch (error) {
22+
log(error, 'error');
23+
}
24+
25+
return;
26+
};
27+
28+
if (interaction.isAnySelectMenu()) {
29+
const component = client.collection.components.selects.get(interaction.customId);
30+
31+
if (!component) return;
32+
33+
try {
34+
component.run(client, interaction);
35+
} catch (error) {
36+
log(error, 'error');
37+
}
38+
39+
return;
40+
};
41+
},
42+
};

src/events/Guild/interactionCreate.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
const config = require('../../config');
22
const { log } = require('../../functions');
3+
const ExtendedClient = require('../../class/ExtendedClient');
34

45
module.exports = {
56
event: 'interactionCreate',
7+
/**
8+
*
9+
* @param {ExtendedClient} client
10+
* @param {import('discord.js').Interaction} interaction
11+
* @returns
12+
*/
613
run: (client, interaction) => {
714
if (config.handler.commands.slash === false && interaction.isChatInputCommand()) return;
815
if (config.handler.commands.user === false && interaction.isUserContextMenuCommand()) return;

0 commit comments

Comments
 (0)