Skip to content

Commit d6d8569

Browse files
committed
Initial commit
0 parents  commit d6d8569

File tree

15 files changed

+1163
-0
lines changed

15 files changed

+1163
-0
lines changed

.env

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
TOKEN=
2+
BOTID=
3+
SERVERID=
4+
OWNERS=["596227913209217024"]

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2021 Fnr
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# BOT NAME
2+
3+
4+
## BOT DESCRIPTION
5+
6+
---
7+
### Note: Node.js 16.6.0 or newer is required.
8+
---
9+
10+
## Installation
11+
12+
```sh
13+
npm install
14+
```
15+
---
16+
17+
### You need to rename example.env file to `.env` and fill the info.
18+
19+
- .env
20+
```sh
21+
TOKEN=YOUR_DISCORD_BOT_TOKEN
22+
BOTID=BOT_ID
23+
SERVERID=SERVER_ID
24+
OWNERS=["596227913209217024"]
25+
```

commands/general/ping.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const Discord = require('discord.js')
2+
3+
module.exports = {
4+
name: "ping",
5+
description: "Get bot speed",
6+
timeout: 5000,
7+
category: "general",
8+
usage: "/ping",
9+
run: async(interaction, client) => {
10+
await interaction.reply('🏓 Pong!')
11+
const msg = await interaction.fetchReply()
12+
const embed = new Discord.MessageEmbed()
13+
.setAuthor(interaction.user.tag, interaction.user.displayAvatarURL({ dynamic: true }))
14+
.setColor('RANDOM')
15+
.setTimestamp()
16+
.setDescription(`**Time:** ${Math.floor(msg.createdTimestamp - interaction.createdTimestamp)} ms\n**API Ping:** ${client.ws.ping} ms`)
17+
interaction.editReply({ embeds: [embed], content: null })
18+
}
19+
}

commands/info/help.js

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
const { MessageEmbed, MessageActionRow, MessageSelectMenu } = require('discord.js');
2+
const humanizeDuration = require("humanize-duration");
3+
4+
module.exports = {
5+
name: "help",
6+
description: "Get list of all bot commands",
7+
options: [
8+
{
9+
name: "command",
10+
description: "Command you need help for",
11+
type: 3
12+
}
13+
],
14+
usage: "/ping",
15+
category: "info",
16+
run: async(interaction, client) => {
17+
try {
18+
const command = interaction.options.getString('command');
19+
if (command) {
20+
const cmd = client.commands.get(command.toLowerCase());
21+
if (!cmd) {
22+
return interaction.reply({ content: `I can\'t find \`${cmd}\` command`, ephemeral: true })
23+
}
24+
const embed = new MessageEmbed()
25+
.setColor(interaction.guild.me.displayHexColor)
26+
if (cmd.name) {
27+
embed.setTitle(`Command: ${cmd.name}`)
28+
}
29+
if (cmd.description) {
30+
embed.setDescription(cmd.description)
31+
}
32+
if (cmd.usage) {
33+
embed.addField('Usage:', cmd.usage)
34+
}
35+
if (cmd.timeout) {
36+
embed.addField('Timeout:', humanizeDuration(cmd.timeout, { round: true }))
37+
}
38+
return interaction.reply({ embeds: [embed] })
39+
}
40+
const row = new MessageActionRow()
41+
.addComponents(
42+
new MessageSelectMenu()
43+
.setCustomId('help_menu')
44+
.setPlaceholder('Select Command Category.')
45+
.setMinValues(1)
46+
.setMaxValues(1)
47+
.addOptions([
48+
{
49+
label: "General",
50+
emoji: "⚙",
51+
description: "Show all commands in general category.",
52+
value: "general"
53+
},
54+
{
55+
label: "Info",
56+
description: "Show all commands in info category.",
57+
emoji: "ℹ",
58+
value: "info"
59+
}
60+
])
61+
)
62+
interaction.reply({ content: "**👋 Select Category You Need Help For**", components: [row] });
63+
const filter = i => i.customId === 'help_menu' || 'selected_command' && i.user.id === interaction.user.id;
64+
const collector = interaction.channel.createMessageComponentCollector({ filter: filter, max: 2, componentType: "SELECT_MENU" });
65+
collector.on('collect', async i => {
66+
if (i.values.includes('general')) {
67+
await i.deferUpdate();
68+
const loopArray = [];
69+
if (client.commands.filter(r => r.category === 'general').size === '25') {
70+
loopArray.slice(0, 25)
71+
}
72+
client.commands.filter(r => r.category === "general").forEach(cmd => {
73+
loopArray.push({
74+
label: cmd.name,
75+
value: cmd.name,
76+
description: cmd.description,
77+
emoji: "⚙"
78+
})
79+
})
80+
const commandRow = row.setComponents(
81+
new MessageSelectMenu()
82+
.setCustomId('general_cmd')
83+
.setPlaceholder('General Commands')
84+
.setMinValues(1)
85+
.setMaxValues(1)
86+
.addOptions(loopArray)
87+
)
88+
return i.editReply({
89+
content: "**Select what command you need help for.**",
90+
components: [commandRow]
91+
})
92+
}
93+
if (i.values.includes('info')) {
94+
await i.deferUpdate();
95+
const loopArray = [];
96+
if (client.commands.filter(r => r.category === 'info').size === '25') {
97+
loopArray.slice(0, 25)
98+
}
99+
client.commands.filter(r => r.category === "info").forEach(cmd => {
100+
loopArray.push({
101+
label: cmd.name,
102+
value: cmd.name,
103+
description: cmd.description,
104+
emoji: "ℹ"
105+
})
106+
})
107+
const commandRow = row.setComponents(
108+
new MessageSelectMenu()
109+
.setCustomId('info_cmd')
110+
.setPlaceholder('Info Commands')
111+
.setMinValues(1)
112+
.setMaxValues(1)
113+
.addOptions(loopArray)
114+
)
115+
return i.editReply({
116+
content: "**Select what command you need help for.**",
117+
components: [commandRow]
118+
})
119+
}
120+
})
121+
} catch (e) {
122+
return false;
123+
}
124+
}
125+
}

commands/info/info.js

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
const { MessageEmbed, MessageActionRow, MessageButton } = require('discord.js')
2+
const humanizeDuration = require("humanize-duration");
3+
4+
module.exports = {
5+
name: "info",
6+
description: "Get info about bot",
7+
timeout: 5000,
8+
usage: "/info",
9+
category: "info",
10+
run: async(interaction, client) => {
11+
const loopGuilds = [];
12+
client.guilds.cache.forEach((guild, i) => {
13+
loopGuilds.push(guild.memberCount);
14+
});
15+
let TotalUsers = 0;
16+
for (let i = 0; i < loopGuilds.length; i++) {
17+
if (isNaN(loopGuilds[i])) continue;
18+
TotalUsers += loopGuilds[i];
19+
}
20+
const embed = new MessageEmbed()
21+
.setTitle('__Bot Stats__')
22+
.setColor('RANDOM')
23+
.setThumbnail(client.user.displayAvatarURL())
24+
.setFooter(${client.user.username} - Coded By Fnr#0017`)
25+
.addFields(
26+
{
27+
name: "<a:IconBot:855532513770340424> Total Guilds: ",
28+
value: client.guilds.cache.size.toLocaleString(),
29+
inline: true
30+
},
31+
{
32+
name: "<a:IconUsers:856146782451007508> Total Users: ",
33+
value: TotalUsers.toLocaleString(),
34+
inline: true
35+
},
36+
{
37+
name: "<:discord_bot_dev:747685855682101309> Developer: ",
38+
value: `[Fnr#0017](https://twitter.com/Fnr_8)`,
39+
inline: true
40+
},
41+
{
42+
name: "<a:wait:767349330361057350> Bot Uptime: ",
43+
value: humanizeDuration(client.uptime, { round: true }),
44+
inline: true
45+
},
46+
)
47+
const row = new MessageActionRow()
48+
.addComponents(
49+
new MessageButton()
50+
.setStyle('LINK')
51+
.setLabel('Bot Link')
52+
.setURL(`https://discord.com/api/oauth2/authorize?client_id=${client.user.id}&permissions=92160&scope=bot%20applications.commands`)
53+
)
54+
interaction.reply({ embeds: [embed], components: [row] })
55+
}
56+
}

events/client/ready.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
require('colors');
2+
3+
module.exports = async client => {
4+
const clientPresence = client.user.setActivity({ name: "GitHub: FnrDev", type: "WATCHING" });
5+
console.log(`[Discord API] Logged in as ${client.user.tag}`.green);
6+
console.log(`[Discord API] Loaded ${client.guilds.cache.size} Guilds`.yellow);
7+
console.log(`[Discord API] Loaded ${client.users.cache.size} Users`.yellow);
8+
console.log(`[Discord API] Loaded ${client.channels.cache.size} Channels`.yellow);
9+
console.log(`[Discord API] ${client.user.username} Presence has been set to "${clientPresence.activities[0].name}" with status "${clientPresence.status}"`.yellow);
10+
};

events/guild/interactionCreate.js

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
const Timeout = new Set()
2+
const { MessageEmbed } = require('discord.js');
3+
const humanizeDuration = require("humanize-duration");
4+
5+
module.exports = async(client, interaction) => {
6+
if (interaction.isCommand() || interaction.isContextMenu()) {
7+
if (!client.commands.has(interaction.commandName)) return;
8+
if (!interaction.guild) return;
9+
const command = client.commands.get(interaction.commandName)
10+
try {
11+
if (command.timeout) {
12+
if (Timeout.has(`${interaction.user.id}${command.name}`)) {
13+
const embed = new MessageEmbed()
14+
.setTitle('You are in timeout!')
15+
.setDescription(`You need to wait **${humanizeDuration(command.timeout, { round: true })}** to use command again`)
16+
.setColor('#ff0000')
17+
return interaction.reply({ embeds: [embed], ephemeral: true })
18+
}
19+
}
20+
if (command.permission) {
21+
if (!interaction.member.permissions.has(command.permission)) {
22+
const embed = new MessageEmbed()
23+
.setTitle('Missing Permission')
24+
.setDescription(`:x: You need \`${command.permission}\` to use this command`)
25+
.setColor('#ff0000')
26+
.setFooter(interaction.user.tag, interaction.user.displayAvatarURL({ dynamic: true }))
27+
.setTimestamp()
28+
return interaction.reply({ embeds: [embed], ephemeral: true })
29+
}
30+
}
31+
if (command.devs) {
32+
if (!process.env.OWNERS.includes(interaction.user.id)) {
33+
return interaction.reply({ content: ":x: Only devs can use this command", ephemeral: true });
34+
}
35+
}
36+
if (command.ownerOnly) {
37+
if (interaction.user.id !== interaction.guild.ownerId) {
38+
return interaction.reply({ content: "Only ownership of this server can use this command", ephemeral: true })
39+
}
40+
}
41+
command.run(interaction, client);
42+
Timeout.add(`${interaction.user.id}${command.name}`)
43+
setTimeout(() => {
44+
Timeout.delete(`${interaction.user.id}${command.name}`)
45+
}, command.timeout);
46+
} catch (error) {
47+
console.error(error);
48+
await interaction.reply({ content: ':x: There was an error while executing this command!', ephemeral: true });
49+
}
50+
}
51+
try {
52+
if (interaction.isSelectMenu()) {
53+
if (interaction.customId === 'ticket_cmd' || interaction.customId === 'info_cmd' || interaction.customId === 'general_cmd') {
54+
const selectedValues = interaction.values;
55+
const findCommand = client.commands.find(r => r.name === selectedValues[0])
56+
if (selectedValues.includes(findCommand.name)) {
57+
const embed = new MessageEmbed()
58+
.setColor(interaction.guild.me.displayHexColor)
59+
.setFooter(`Requested by ${interaction.user.tag}`, interaction.user.displayAvatarURL({ dynamic: true }))
60+
if (findCommand.name) {
61+
embed.setTitle(`Command: ${findCommand.name}`)
62+
}
63+
if (findCommand.description) {
64+
embed.setDescription(findCommand.description)
65+
}
66+
if (findCommand.usage) {
67+
embed.addField("Usage:", findCommand.usage)
68+
}
69+
if (findCommand.timeout) {
70+
embed.addField("Timeout:", humanizeDuration(findCommand.timeout, { round: true }))
71+
}
72+
interaction.reply({
73+
embeds: [embed],
74+
ephemeral: true
75+
})
76+
}
77+
}
78+
}
79+
} catch (e) {
80+
console.error(e)
81+
return false;
82+
}
83+
}

handlers/events.js

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const { readdirSync } = require("fs");
2+
module.exports = (client) => {
3+
const load = dirs => {
4+
const events = readdirSync(`./events/${dirs}/`).filter(d => d.endsWith("js") );
5+
for (let file of events) {
6+
let evt = require(`../events/${dirs}/${file}`);
7+
let eName = file.split('.')[0];
8+
client.on(eName, evt.bind(null,client));
9+
}
10+
};
11+
["client", "guild"].forEach((x) => load(x));
12+
};

handlers/hanlders.js

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const { readdirSync } = require('fs');
2+
module.exports = async(client) => {
3+
readdirSync("./commands/").map(async dir => {
4+
const commands = readdirSync(`./commands/${dir}/`).map(async cmd=> {
5+
let pull = require(`../commands/${dir}/${cmd}`)
6+
client.commands.set(pull.name, pull)
7+
if (pull.aliases) {
8+
pull.aliases.map(p => client.aliases.set(p, pull))
9+
}
10+
})
11+
})
12+
}

0 commit comments

Comments
 (0)