@fjrodafo/discord-app 1.0.0
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/CONTRIBUTING +9 -0
- package/LICENSE +121 -0
- package/dashboard/index.js +27 -0
- package/dashboard/public/index.html +18 -0
- package/dashboard/public/script.js +11 -0
- package/dashboard/public/style.css +0 -0
- package/dashboard/routes/api.js +75 -0
- package/dashboard/routes/logs.js +11 -0
- package/dashboard/routes/metrics.js +57 -0
- package/dashboard/utils/format.js +60 -0
- package/dashboard/utils/logs.js +19 -0
- package/package.json +46 -0
- package/src/commands/admin/ping.js +13 -0
- package/src/commands/admin/prune.js +36 -0
- package/src/commands/admin/reload.js +36 -0
- package/src/commands/context-menu/avatar.js +19 -0
- package/src/commands/context-menu/user.js +26 -0
- package/src/commands/help/help.js +154 -0
- package/src/commands/moderation/kick.js +23 -0
- package/src/commands/utility/buttons.js +83 -0
- package/src/commands/utility/embed.js +33 -0
- package/src/commands/utility/info.js +61 -0
- package/src/commands/utility/paginate.js +189 -0
- package/src/commands/utility/select-menus.js +133 -0
- package/src/config.example.json +5 -0
- package/src/deploy-commands.js +77 -0
- package/src/events/interactionCreate.js +51 -0
- package/src/events/messageCreate.js +16 -0
- package/src/events/ready.js +29 -0
- package/src/index.js +79 -0
- package/src/utils/emoji.js +17 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const fs = require('node:fs');
|
|
2
|
+
const path = require('node:path');
|
|
3
|
+
const { REST, Routes } = require('discord.js');
|
|
4
|
+
|
|
5
|
+
// Global commands
|
|
6
|
+
const { clientId, token } = require('./config.json');
|
|
7
|
+
|
|
8
|
+
// Guild commands
|
|
9
|
+
/*
|
|
10
|
+
const { clientId, guildId, token } = require('./config.json');
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const commands = [];
|
|
14
|
+
// Grab all the command folders from the commands directory you created earlier
|
|
15
|
+
const foldersPath = path.join(__dirname, 'commands');
|
|
16
|
+
const commandFolders = fs.readdirSync(foldersPath);
|
|
17
|
+
|
|
18
|
+
for (const folder of commandFolders) {
|
|
19
|
+
// Grab all the command files from the commands directory you created earlier
|
|
20
|
+
const commandsPath = path.join(foldersPath, folder);
|
|
21
|
+
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
|
|
22
|
+
// Grab the SlashCommandBuilder#toJSON() output of each command's data for deployment
|
|
23
|
+
for (const file of commandFiles) {
|
|
24
|
+
const filePath = path.join(commandsPath, file);
|
|
25
|
+
const command = require(filePath);
|
|
26
|
+
if ('data' in command && 'execute' in command) {
|
|
27
|
+
commands.push(command.data.toJSON());
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Construct and prepare an instance of the REST module
|
|
36
|
+
const rest = new REST().setToken(token);
|
|
37
|
+
|
|
38
|
+
// and deploy your commands!
|
|
39
|
+
(async () => {
|
|
40
|
+
try {
|
|
41
|
+
console.log(`Started refreshing ${commands.length} application (/) commands.`);
|
|
42
|
+
|
|
43
|
+
// Global commands
|
|
44
|
+
const data = await rest.put(
|
|
45
|
+
Routes.applicationCommands(clientId),
|
|
46
|
+
{ body: commands },
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
// The put method is used to fully refresh all commands in the guild with the current set
|
|
50
|
+
/*
|
|
51
|
+
const data = await rest.put(
|
|
52
|
+
Routes.applicationGuildCommands(clientId, guildId),
|
|
53
|
+
{ body: commands },
|
|
54
|
+
);
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
console.log(`Successfully reloaded ${data.length} application (/) commands.`);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
// And of course, make sure you catch and log any errors!
|
|
61
|
+
console.error(error);
|
|
62
|
+
}
|
|
63
|
+
})();
|
|
64
|
+
|
|
65
|
+
// Deleting commands for global commands
|
|
66
|
+
/*
|
|
67
|
+
rest.put(Routes.applicationCommands(clientId), { body: [] })
|
|
68
|
+
.then(() => console.log('Successfully deleted all application commands.'))
|
|
69
|
+
.catch(console.error);
|
|
70
|
+
*/
|
|
71
|
+
|
|
72
|
+
// Deleting commands for guild-based commands
|
|
73
|
+
/*
|
|
74
|
+
rest.put(Routes.applicationGuildCommands(clientId, guildId), { body: [] })
|
|
75
|
+
.then(() => console.log('Successfully deleted all guild commands.'))
|
|
76
|
+
.catch(console.error);
|
|
77
|
+
*/
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const { Events, Collection } = require('discord.js');
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
name: Events.InteractionCreate,
|
|
5
|
+
async execute(interaction) {
|
|
6
|
+
if (!interaction.isChatInputCommand() && !interaction.isUserContextMenuCommand()) return;
|
|
7
|
+
const command = interaction.client.commands.get(interaction.commandName);
|
|
8
|
+
|
|
9
|
+
if (!command) {
|
|
10
|
+
console.error(`No command matching ${interaction.commandName} was found.`);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Cooldowns
|
|
15
|
+
const { cooldowns } = interaction.client;
|
|
16
|
+
|
|
17
|
+
if (!cooldowns.has(command.data.name)) {
|
|
18
|
+
cooldowns.set(command.data.name, new Collection());
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const now = Date.now();
|
|
22
|
+
const timestamps = cooldowns.get(command.data.name);
|
|
23
|
+
const defaultCooldownDuration = 3;
|
|
24
|
+
const cooldownAmount = (command.cooldown ?? defaultCooldownDuration) * 1000;
|
|
25
|
+
|
|
26
|
+
if (timestamps.has(interaction.user.id)) {
|
|
27
|
+
const expirationTime = timestamps.get(interaction.user.id) + cooldownAmount;
|
|
28
|
+
|
|
29
|
+
if (now < expirationTime) {
|
|
30
|
+
const expiredTimestamp = Math.round(expirationTime / 1000);
|
|
31
|
+
return interaction.reply({ content: `Please wait, you are on a cooldown for \`/${command.data.name}\`. You can use it again <t:${expiredTimestamp}:R>.`, ephemeral: true });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
timestamps.set(interaction.user.id, now);
|
|
36
|
+
setTimeout(() => timestamps.delete(interaction.user.id), cooldownAmount);
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
await command.execute(interaction);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
console.error(error);
|
|
43
|
+
if (interaction.replied || interaction.deferred) {
|
|
44
|
+
await interaction.followUp({ content: 'There was an error while executing this command!', ephemeral: true });
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const { Events } = require('discord.js');
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
name: Events.MessageCreate,
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* GatewayIntentBits.MessageContent must be enabled in the index.js file
|
|
8
|
+
*
|
|
9
|
+
* @param {*} message
|
|
10
|
+
* @returns messages depending on the content
|
|
11
|
+
*/
|
|
12
|
+
async execute(message) {
|
|
13
|
+
if (message.author.bot) return;
|
|
14
|
+
if (message.content.toLowerCase() === 'hello') await message.channel.send('Hello, World!');
|
|
15
|
+
},
|
|
16
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const { Events, ActivityType } = require('discord.js');
|
|
2
|
+
const dashboard = require('./../../dashboard/index.js');
|
|
3
|
+
const dashboardLogs = require('./../../dashboard/utils/logs.js');
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
name: Events.ClientReady,
|
|
7
|
+
once: true,
|
|
8
|
+
execute(client) {
|
|
9
|
+
const status = [
|
|
10
|
+
{ activities: [{ name: 'I respond to DMs', type: ActivityType.Custom }], status: 'online' },
|
|
11
|
+
{ activities: [{ name: 'custom', type: ActivityType.Custom, state: 'What\'s on your mind?' }], status: 'online' },
|
|
12
|
+
{ activities: [{ name: 'Music', type: ActivityType.Listening }], status: 'idle' },
|
|
13
|
+
{ activities: [{ name: 'Movies', type: ActivityType.Watching }], status: 'dnd' },
|
|
14
|
+
{ activities: [{ name: 'Video Games', type: ActivityType.Playing }], status: 'idle' },
|
|
15
|
+
{ activities: [{ name: 'Video Games', type: ActivityType.Competing }], status: 'dnd' },
|
|
16
|
+
{ activities: [{ name: 'Video Games', type: ActivityType.Streaming, url: 'https://www.twitch.tv/directory' }] },
|
|
17
|
+
];
|
|
18
|
+
function updateStatus() {
|
|
19
|
+
const random = Math.floor(Math.random() * status.length);
|
|
20
|
+
client.user.setPresence(status[random]);
|
|
21
|
+
}
|
|
22
|
+
updateStatus();
|
|
23
|
+
setInterval(updateStatus, 600_000);
|
|
24
|
+
// Dashboard
|
|
25
|
+
dashboard(client);
|
|
26
|
+
dashboardLogs.add(`Ready! ${client.user.tag}`);
|
|
27
|
+
dashboardLogs.add(`Server count: ${client.guilds.cache.size}`);
|
|
28
|
+
},
|
|
29
|
+
};
|
package/src/index.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const fs = require('node:fs');
|
|
2
|
+
const path = require('node:path');
|
|
3
|
+
const { Client, Collection, GatewayIntentBits } = require('discord.js');
|
|
4
|
+
const { token } = require('./config.json');
|
|
5
|
+
|
|
6
|
+
// Create a new client instance
|
|
7
|
+
const client = new Client({
|
|
8
|
+
intents: [
|
|
9
|
+
GatewayIntentBits.Guilds,
|
|
10
|
+
GatewayIntentBits.GuildMessages,
|
|
11
|
+
// GatewayIntentBits.MessageContent,
|
|
12
|
+
],
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
// Cooldowns
|
|
16
|
+
client.cooldowns = new Collection();
|
|
17
|
+
|
|
18
|
+
// Command handling
|
|
19
|
+
client.commands = new Collection();
|
|
20
|
+
|
|
21
|
+
const foldersPath = path.join(__dirname, 'commands');
|
|
22
|
+
const commandFolders = fs.readdirSync(foldersPath);
|
|
23
|
+
|
|
24
|
+
for (const folder of commandFolders) {
|
|
25
|
+
const commandsPath = path.join(foldersPath, folder);
|
|
26
|
+
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
|
|
27
|
+
for (const file of commandFiles) {
|
|
28
|
+
const filePath = path.join(commandsPath, file);
|
|
29
|
+
const command = require(filePath);
|
|
30
|
+
if ('data' in command && 'execute' in command) {
|
|
31
|
+
client.commands.set(command.data.name, command);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Event handling
|
|
40
|
+
const eventsPath = path.join(__dirname, 'events');
|
|
41
|
+
const eventFiles = fs.readdirSync(eventsPath).filter(file => file.endsWith('.js'));
|
|
42
|
+
|
|
43
|
+
for (const file of eventFiles) {
|
|
44
|
+
const filePath = path.join(eventsPath, file);
|
|
45
|
+
const event = require(filePath);
|
|
46
|
+
if (event.once) {
|
|
47
|
+
client.once(event.name, (...args) => event.execute(...args));
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
client.on(event.name, (...args) => event.execute(...args));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Error handling and reconnection
|
|
55
|
+
client.on('error', error => {
|
|
56
|
+
console.error('Error in client:', error);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const handleReconnect = () => {
|
|
60
|
+
console.log('Attempting to reconnect...');
|
|
61
|
+
client.login(token).catch(err => {
|
|
62
|
+
console.error('Failed to reconnect:', err);
|
|
63
|
+
// Try to reconnect after 5 seconds
|
|
64
|
+
setTimeout(handleReconnect, 5000);
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
client.on('shardDisconnect', (event, id) => {
|
|
69
|
+
console.warn(`Shard ${id} disconnected (${event.code}): ${event.reason}`);
|
|
70
|
+
if (event.code === 1000) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
handleReconnect();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Log in to Discord with your client's token
|
|
77
|
+
client.login(token).catch(error => {
|
|
78
|
+
console.error('Failed to login:', error);
|
|
79
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
a: '🇦', b: '🇧', c: '🇨', d: '🇩',
|
|
3
|
+
e: '🇪', f: '🇫', g: '🇬', h: '🇭',
|
|
4
|
+
i: '🇮', j: '🇯', k: '🇰', l: '🇱',
|
|
5
|
+
m: '🇲', n: '🇳', o: '🇴', p: '🇵',
|
|
6
|
+
q: '🇶', r: '🇷', s: '🇸', t: '🇹',
|
|
7
|
+
u: '🇺', v: '🇻', w: '🇼', x: '🇽',
|
|
8
|
+
y: '🇾', z: '🇿', 0: '0️⃣', 1: '1️⃣',
|
|
9
|
+
2: '2️⃣', 3: '3️⃣', 4: '4️⃣', 5: '5️⃣',
|
|
10
|
+
6: '6️⃣', 7: '7️⃣', 8: '8️⃣', 9: '9️⃣',
|
|
11
|
+
10: '🔟', '#': '#️⃣', '*': '*️⃣',
|
|
12
|
+
'!': '❗', '?': '❓',
|
|
13
|
+
'arrow_up': '↑', 'arrow_left': '←',
|
|
14
|
+
'arrow_right': '→', 'arrow_down': '↓',
|
|
15
|
+
'white_check_mark': '✅', 'warning': '⚠️',
|
|
16
|
+
'herb': '🌿', 'fire': '🔥', 'bubbles': '🫧',
|
|
17
|
+
};
|