Merge pull request #2 from Fretuks/main

Implement some commands
This commit is contained in:
2026-01-26 12:16:05 +01:00
committed by GitHub
7 changed files with 213 additions and 37 deletions
+26
View File
@@ -0,0 +1,26 @@
const { SlashCommandBuilder } = require('discord.js');
const { connectToDatabase } = require('../../db.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('balance')
.setDescription('Check your coin balance or another user\'s balance.')
.addUserOption(option =>
option
.setName('user')
.setDescription('User to check (defaults to you)')
.setRequired(false)),
async execute(interaction) {
const dbClient = await connectToDatabase();
const db = dbClient.db('discord');
const collection = db.collection('currency');
const target = interaction.options.getUser('user') ?? interaction.user;
const targetData = await collection.findOne({ userID: target.id });
const balance = targetData?.balance ?? 0;
return interaction.reply({
content: `${target.tag} has **${balance}** coins.`,
});
}
};
+59
View File
@@ -0,0 +1,59 @@
const { SlashCommandBuilder } = require('discord.js');
const { connectToDatabase } = require('../../db.js');
const REWARD_AMOUNT = 100;
const COOLDOWN_MS = 24 * 60 * 60 * 1000;
const formatDuration = (ms) => {
const totalSeconds = Math.ceil(ms / 1000);
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
const parts = [];
if (hours) parts.push(`${hours}h`);
if (minutes) parts.push(`${minutes}m`);
if (!hours && !minutes) parts.push(`${seconds}s`);
return parts.join(' ');
};
module.exports = {
data: new SlashCommandBuilder()
.setName('earn')
.setDescription('Claim your daily coin reward.'),
async execute(interaction) {
const dbClient = await connectToDatabase();
const db = dbClient.db('discord');
const collection = db.collection('currency');
const now = new Date();
const userId = interaction.user.id;
const userData = await collection.findOne({ userID: userId });
const lastClaim = userData?.lastClaimedAt ? new Date(userData.lastClaimedAt) : null;
if (lastClaim) {
const elapsed = now - lastClaim;
if (elapsed < COOLDOWN_MS) {
const remaining = COOLDOWN_MS - elapsed;
return interaction.reply({
content: `You already claimed your reward. Try again in **${formatDuration(remaining)}**.`,
ephemeral: true,
});
}
}
await collection.updateOne(
{ userID: userId },
{
$set: { lastClaimedAt: now.toISOString() },
$inc: { balance: REWARD_AMOUNT },
},
{ upsert: true }
);
return interaction.reply({
content: `You earned **${REWARD_AMOUNT}** coins! Come back tomorrow for more.`,
});
}
};
+23 -15
View File
@@ -1,37 +1,45 @@
// exampleCommand.js const { SlashCommandBuilder, PermissionFlagsBits } = require('discord.js');
const { SlashCommandBuilder } = require('discord.js');
const { connectToDatabase } = require('../../db.js'); const { connectToDatabase } = require('../../db.js');
module.exports = { module.exports = {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('give') .setName('give')
.setDescription('give somebody coins') .setDescription('Admin: grant coins to a user.')
.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild)
.addIntegerOption(option => .addIntegerOption(option =>
option option
.setName('amount') .setName('amount')
.setDescription('amount of the coins') .setDescription('Amount of coins to give')
.setMinValue(1)
.setRequired(true)) .setRequired(true))
.addUserOption(option => .addUserOption(option =>
option.setName('target') option
.setDescription('The user to give coins to') .setName('target')
.setDescription('User to receive coins')
.setRequired(true)), .setRequired(true)),
async execute(interaction) { async execute(interaction) {
const dbClient = await connectToDatabase(); const dbClient = await connectToDatabase();
const target = interaction.options.getUser('target'); const target = interaction.options.getUser('target');
const amount = interaction.options.getInteger('amount'); const amount = interaction.options.getInteger('amount');
// Choose a DB + Collection if (target.bot) {
return interaction.reply({
content: 'You cannot grant coins to bot accounts.',
ephemeral: true,
});
}
const db = dbClient.db('discord'); const db = dbClient.db('discord');
const collection = db.collection('currency'); const collection = db.collection('currency');
let targetData = await collection.findOne({ userID: target.id }); await collection.updateOne(
if (!targetData) { { userID: target.id },
await collection.insertOne({ userID: target.id, balance: 0 }); { $inc: { balance: amount } },
} { upsert: true }
);
// Perform the transaction: subtract from sender and add to target. return interaction.reply({
await collection.updateOne({ userID: target.id }, { $inc: { balance: amount } }, { upsert: true }); content: `You granted **${amount}** coins to ${target.tag}.`,
});
return interaction.reply({ content: `You have given ${amount} coins to ${target.tag}.` });
} }
}; };
+68
View File
@@ -0,0 +1,68 @@
const { SlashCommandBuilder } = require('discord.js');
const { connectToDatabase } = require('../../db.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('transfer')
.setDescription('Send coins to another user.')
.addUserOption(option =>
option
.setName('target')
.setDescription('User to send coins to')
.setRequired(true))
.addIntegerOption(option =>
option
.setName('amount')
.setDescription('Amount of coins to send')
.setMinValue(1)
.setRequired(true)),
async execute(interaction) {
const dbClient = await connectToDatabase();
const db = dbClient.db('discord');
const collection = db.collection('currency');
const target = interaction.options.getUser('target');
const amount = interaction.options.getInteger('amount');
if (target.bot) {
return interaction.reply({
content: 'You cannot transfer coins to a bot account.',
ephemeral: true,
});
}
if (target.id === interaction.user.id) {
return interaction.reply({
content: 'You cannot transfer coins to yourself.',
ephemeral: true,
});
}
const senderId = interaction.user.id;
const senderData = await collection.findOne({ userID: senderId });
const senderBalance = senderData?.balance ?? 0;
if (senderBalance < amount) {
return interaction.reply({
content: `You only have **${senderBalance}** coins available.`,
ephemeral: true,
});
}
await collection.updateOne(
{ userID: senderId },
{ $inc: { balance: -amount } },
{ upsert: true }
);
await collection.updateOne(
{ userID: target.id },
{ $inc: { balance: amount } },
{ upsert: true }
);
return interaction.reply({
content: `You sent **${amount}** coins to ${target.tag}.`,
});
}
};
+11 -7
View File
@@ -1,19 +1,23 @@
const {SlashCommandBuilder, EmbedBuilder} = require("discord.js"); const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
module.exports = { module.exports = {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName("about") .setName('about')
.setDescription("Information about this bot and creator"), .setDescription('Information about this bot and creator'),
async execute(interaction) { async execute(interaction) {
const exampleEmbed = new EmbedBuilder() const exampleEmbed = new EmbedBuilder()
.setColor(0x0099FF) .setColor(0x0099FF)
.setTitle('About Page') .setTitle('About This Bot')
.setDescription('I build this bot for managing my servers. (to lazy to write mor text rn)') .setDescription('A multipurpose Discord bot focused on helpful utilities, moderation, and fun community features.')
.addFields(
{ name: 'Highlights', value: 'Timezone converter, quiz games, and a growing currency system.' },
{ name: 'Created By', value: interaction.client.user?.username ?? 'Bot Creator' }
)
.setImage('https://i.postimg.cc/QdZZwKVD/Screenshot-2024-12-25-005933.png') .setImage('https://i.postimg.cc/QdZZwKVD/Screenshot-2024-12-25-005933.png')
.setTimestamp(); .setTimestamp();
await interaction.reply({ await interaction.reply({
embeds: [exampleEmbed] embeds: [exampleEmbed]
}) });
}
} }
};
+12 -8
View File
@@ -1,23 +1,27 @@
const { SlashCommandBuilder} = require("discord.js"); const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
module.exports = { module.exports = {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('help') .setName('help')
.setDescription('Gives all available commands.'), .setDescription('Gives all available commands.'),
async execute(interaction) { async execute(interaction) {
// Map over the full command objects to get names and descriptions const commandDetails = interaction.client.commands
const commandDetails = interaction.client.commands.map(cmd => ({ .map(cmd => ({
name: cmd.data.name, name: cmd.data.name,
description: cmd.data.description, description: cmd.data.description,
})); }))
.sort((a, b) => a.name.localeCompare(b.name));
// Format the commands into a user-friendly help message
const helpMessage = commandDetails const helpMessage = commandDetails
.map(detail => `/${detail.name} - ${detail.description}`) .map(detail => `• **/${detail.name}** — ${detail.description}`)
.join('\n'); .join('\n');
// Send the help message const embed = new EmbedBuilder()
await interaction.reply(`Here are all the available commands:\n\n${helpMessage}`); .setColor(0x4b7bec)
.setTitle('Available Commands')
.setDescription(helpMessage)
.setFooter({ text: `${commandDetails.length} commands loaded.` });
await interaction.reply({ embeds: [embed], ephemeral: true });
}, },
}; };
+9 -2
View File
@@ -3,8 +3,15 @@ const { SlashCommandBuilder } = require('discord.js');
module.exports = { module.exports = {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('ping') .setName('ping')
.setDescription('Check if the bots responsivnes'), .setDescription('Check the bot\'s responsiveness.'),
async execute(interaction) { async execute(interaction) {
await interaction.reply({ content: 'Pong! (Online)', ephemeral: true }); const sentAt = Date.now();
await interaction.reply({ content: 'Pinging...', ephemeral: true });
const latency = Date.now() - sentAt;
const apiLatency = Math.round(interaction.client.ws.ping);
await interaction.editReply({
content: `Pong! **${latency}ms** (API: **${apiLatency}ms**)`,
});
}, },
}; };