@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.
@@ -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
+ };