diff --git a/emoji.json b/emoji.json new file mode 100644 index 0000000..762d3c9 --- /dev/null +++ b/emoji.json @@ -0,0 +1,10 @@ +{ + "github": "<:github:1379623104224956448>", + "ping": "<:nodejs:1379635718158024855>", + "cpu": "<:cpu:1379635751511392347>", + "ram": "<:ram:1379635688848359524>", + "gear": "<:gear:1379635703062986822>", + "cache": "<:dev:1379636571019673632>", + "calendar": "<:calendar:1379635730661380196>", + "logo": "<:logo:1379638741907275816>" +} \ No newline at end of file diff --git a/index.js b/index.js index 279be32..723935c 100644 --- a/index.js +++ b/index.js @@ -1,15 +1,24 @@ // index.js require('dotenv').config(); +const settings = require('./settings.json'); +const emojis = require('./emoji.json'); const express = require('express'); const axios = require('axios'); const { v4: uuidv4 } = require('uuid'); -const { Client, GatewayIntentBits, SlashCommandBuilder } = require('discord.js'); +const { Client, GatewayIntentBits, SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js'); const Database = require('./database'); const CommandDeployer = require('./deploy-commands'); const HybridCacheManager = require('./hybridCacheManager'); const MessageSplitter = require('./messageSplitter'); const { MessageFlags } = require('discord-api-types/v10'); +const MongoCacheManager = require('./mongoCacheManager'); + +// ——— MongoDB Instances ——— +const cacheManager = new MongoCacheManager( + process.env.MONGO_URL, + process.env.MONGO_DB_NAME +); // ——— Logging Helpers ——— const logInfo = (msg, ...args) => console.log(`[INFO] ${msg}`, ...args); @@ -44,7 +53,7 @@ const splitter = new MessageSplitter(2000); const commands = [ new SlashCommandBuilder() .setName('chat') - .setDescription('Chat with the RakunNakun') + .setDescription(`Chat with the ${settings.instanceName}`) .addStringOption(o => o.setName('message').setDescription('Your question').setRequired(true)), new SlashCommandBuilder() @@ -62,7 +71,7 @@ const splitter = new MessageSplitter(2000); new SlashCommandBuilder() .setName('invite') - .setDescription('Invite RakunNakun Into Your Server!'), + .setDescription(`Invite ${settings.instanceName} Into Your Server!`), new SlashCommandBuilder() .setName('debugmode') @@ -85,6 +94,10 @@ const splitter = new MessageSplitter(2000); .setDescription('ID of the message to reply') .setRequired(false) ), + + new SlashCommandBuilder() + .setName('info') + .setDescription('Show bot info'), ].map(c => c.toJSON()); await new CommandDeployer(commands, process.env.CLIENT_ID, process.env.DISCORD_TOKEN).deploy(); @@ -372,6 +385,76 @@ const splitter = new MessageSplitter(2000); await interaction.reply({ content: 'Error processing answer.', flags: MessageFlags.Ephemeral }); } } + + else if (commandName === 'info') { + const usedMB = (process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2); + const ping = client.ws.ping; + const guildCount = client.guilds.cache.size; + const cacheCount = await cacheManager.getMongoCacheCount(); + const cpuUsage = process.cpuUsage(); + const cpuPercent = ((cpuUsage.user + cpuUsage.system) / (1000 * 1000 * 1000) * 100).toFixed(2); // approximate + const uptimeSeconds = Math.floor(process.uptime()); + + + const embed = { + title: 'Bot Info', + color: 0x00ff00, + image: { + url: settings.coverImage + }, + fields: [ + { + name: `${emojis.ping} Latency`, + value: `${ping} ms`, + inline: true + }, + { + name: `${emojis.cpu} CPU Usage`, + value: `${cpuPercent}%`, + inline: true + }, + { + name: `${emojis.ram} Memory Usage`, + value: `${usedMB} MB`, + inline: true + }, + { + name: `${emojis.gear} Joined Servers`, + value: `${guildCount}`, + inline: true + }, + { + name: `${emojis.cache} Cache Entries`, + value: `${formatNumber(cacheCount)} Prompts`, + inline: true + }, + { + name: `${emojis.calendar} Uptime`, + value: `${Math.floor(uptimeSeconds / 3600)}h ${Math.floor((uptimeSeconds % 3600) / 60)}m`, + inline: true + } + ] + }; + + const buttonsRow = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setLabel('GitHub Repo') + .setStyle(ButtonStyle.Link) + .setURL('https://github.com/NekoMonci12/RakunNakun-AI') + .setEmoji(emojis.github), + new ButtonBuilder() + .setLabel('Discord Server') + .setStyle(ButtonStyle.Link) + .setURL('https://dsc.gg/yuemi') + .setEmoji(emojis.logo) + ); + + await interaction.reply({ + embeds: [embed], + components: [buttonsRow], + }); + } }); client.login(process.env.DISCORD_TOKEN); @@ -546,3 +629,15 @@ async function processMessage({ return { reply: finalReply, tokensUsed }; } + +function formatNumber(num) { + if (num >= 1_000_000_000) { + return (num / 1_000_000_000).toFixed(1) + 'b'; + } else if (num >= 1_000_000) { + return (num / 1_000_000).toFixed(1) + 'm'; + } else if (num >= 1_000) { + return (num / 1_000).toFixed(1) + 'k'; + } else { + return num.toString(); + } +} \ No newline at end of file diff --git a/mongoCacheManager.js b/mongoCacheManager.js index 0a68360..85d7222 100644 --- a/mongoCacheManager.js +++ b/mongoCacheManager.js @@ -104,6 +104,19 @@ class MongoCacheManager { { upsert: true } ); } + + // Add this function at the bottom of your main file (index.js) + async getMongoCacheCount() { + try { + await this.connect(); // Ensure connection + const count = await this.collection.countDocuments(); + console.log(`Total cache entries in MongoDB: ${count}`); + return count; + } catch (err) { + console.error('Error counting cache documents:', err); + return null; + } + } } module.exports = MongoCacheManager; diff --git a/settings.json b/settings.json new file mode 100644 index 0000000..1b39186 --- /dev/null +++ b/settings.json @@ -0,0 +1,4 @@ +{ + "coverImage": "https://cdn.yuemi.org/yuemi/YueMi-Banner-White.png", + "instanceName": "RakunNakun" +} \ No newline at end of file