Building Verse Stock Bot for Discord 🤖

16/03/2025 16/04/2024 Development 7 mins read
Table Of Contents

Why I created Verse Stock Bot

I’ve been playing Verse, a popular game where the availability of fruits in the in-game shop changes periodically. Players need to know when rare fruits become available, but constantly checking was time-consuming. I wanted to create a notification system that would automatically alert players about stock changes in both normal and mirage servers.

This problem sparked the idea for Verse Stock Bot—a Discord bot that monitors fruit stock changes and notifies users on dedicated channels. It took some time to streamline the development without overcomplicating the system. In 2024, I finally released the bot to the community, and it’s been growing steadily ever since.

What features does the bot offer?

Verse Stock Bot provides several key functionalities:

  • Real-time monitoring of fruit stock in both normal and mirage servers
  • Customizable notification channels for each server type
  • Role mentions when stock changes to alert interested players
  • Multi-language support (currently Spanish and English)
  • Detailed stock information with prices in Beli and Robux
  • Server configuration management with admin controls
  • System statistics and uptime monitoring
Ashfid

Technical implementation

Since this is a Discord bot project, I needed a reliable tech stack that could handle continuous monitoring and notification systems. Here are the core technologies I used:

  • Discord.js - The foundation of the bot
  • Node.js - Runtime environment
  • JSON-based data storage - Simple but effective for this use case
  • File system monitoring - For tracking stock changes

The bot was designed with a modular approach, separating core functionalities into distinct components:

Data Management System

The bot uses several JSON files to maintain state and configuration:

// Constants for file paths
const SERVER_CONFIG_FILE = 'server_config.json';
const FRUITS_DATA_FILE = 'fruits.json';
const CURRENT_STOCK_FILE = 'current_stock.json';

These files store critical information:

  • Server configurations (channels, roles, language preferences)
  • Fruit data (names, emojis, prices)
  • Current stock information

Server Configuration Management

Each server that adds the bot gets a customized configuration:

function initServerConfig(guildId) {
guildId = guildId.toString();
if (!serverConfig[guildId]) {
serverConfig[guildId] = {
normal_channels: [],
mirage_channels: [],
normal_roles: [],
mirage_roles: [],
language: 'es' // Default language is Spanish
};
saveServerConfig(serverConfig);
}
}

This allows for granular control over notification preferences on a per-server basis, with channels and roles for both normal and mirage servers.

Multilingual Support

The bot includes translation support to make it accessible to more users:

function getTranslation(guildId) {
guildId = guildId.toString();
const lang = serverConfig[guildId]?.language || 'es';
return translations[lang] || translations.es; // Fallback to Spanish
}

Currently, the bot supports Spanish (default) and English, with plans to add more languages in the future.

Stock Monitoring System

The heart of the bot is its stock monitoring functionality:

async function checkStockChanges() {
console.log("Verificando cambios en el stock...");
const newStock = await getCurrentStock();
// Check if there are changes to notify
if (hasStockChanged(lastKnownStock, newStock)) {
console.log("¡Se detectaron cambios en el stock!");
// Notification code...
}
}

This function runs every 5 minutes, checking for changes in the fruit stock. When changes are detected, it notifies all configured channels with customized embeds.

Stock Notification Example
Stock Notification Example

Rich Embeds for Better User Experience

The bot uses Discord’s embed system to create visually appealing notifications:

function createStockEmbed(stockType, fruitsList, guildId) {
const t = getTranslation(guildId);
let title, color;
if (stockType === "normal") {
title = t.stockNormalTitle;
color = 0x3498db; // Blue
} else {
title = t.stockMirageTitle;
color = 0x9b59b6; // Purple
}
// Build the embed...
}

Each notification includes:

  • Color coding (blue for normal server, purple for mirage)
  • Full fruit list with emojis
  • Price information in both Beli and Robux
  • Timestamp of the update

Command System

The bot offers a variety of commands to configure notifications and check stock:

Normal Server Commands

  • .add - Add a channel for normal server notifications
  • .remove - Remove a channel from normal server notifications
  • .notify - Add a role to mention for normal server updates
  • .remove-ping - Remove a role from normal server mentions
  • .stock - Check current normal server stock

Mirage Server Commands

  • .add-mirage - Add a channel for mirage server notifications
  • .remove-mirage - Remove a channel from mirage notifications
  • .notify-mirage - Add a role to mention for mirage server updates
  • .remove-ping-mirage - Remove a role from mirage mentions
  • .mirage - Check current mirage server stock

General Commands

  • .allstock - Check stock for both servers at once
  • .config - View current server configuration
  • .bothelp - Display help information
  • .reset - Reset specific configuration elements
  • .lang - Change the bot language
  • .data - View bot statistics
  • .force-update - Force a stock check immediately

Challenges During Development

Creating this bot wasn’t without challenges:

Stock Detection Logic

One of the trickiest parts was creating a reliable stock change detection system:

function hasStockChanged(oldStock, newStock) {
if (oldStock.normal.length !== newStock.normal.length) {
return true;
}
if (oldStock.mirage.length !== newStock.mirage.length) {
return true;
}
for (const fruit of oldStock.normal) {
if (!newStock.normal.includes(fruit)) {
return true;
}
}
for (const fruit of oldStock.mirage) {
if (!newStock.mirage.includes(fruit)) {
return true;
}
}
return false;
}

The system needed to be sensitive enough to detect any change while avoiding false positives.

Server Configuration Management

With each server having its own configuration, managing and updating these settings required careful consideration:

function saveServerConfig(config) {
try {
fs.writeFileSync(SERVER_CONFIG_FILE, JSON.stringify(config, null, 4), 'utf8');
} catch (error) {
console.error(`Error saving server config: ${error}`);
}
}

Ensuring that configuration changes persisted across bot restarts while maintaining data integrity was crucial.

Resource Optimization

Since the bot runs 24/7, optimizing resource usage was essential:

function getMemoryUsage() {
const usedMemory = process.memoryUsage().heapUsed / 1024 / 1024;
const totalMemory = os.totalmem() / 1024 / 1024;
const freeMemory = os.freemem() / 1024 / 1024;
return {
used: usedMemory.toFixed(2),
total: totalMemory.toFixed(2),
free: freeMemory.toFixed(2),
percentage: ((usedMemory / totalMemory) * 100).toFixed(2)
};
}

Monitoring memory usage and optimizing check intervals helped keep the bot running smoothly.

Future Plans

While the current version of Verse Stock Bot is stable and functional, I have several improvements planned:

  • Additional Languages: Expand beyond Spanish and English to support more communities
  • Web Dashboard: Create a web interface for easier configuration
  • Price History: Track and display fruit price trends over time
  • Custom Notifications: Allow users to set up alerts for specific fruits
  • API Integration: Direct integration with game data when possible
  • Enhanced Stats: More detailed analytics about stock patterns

Join the Community

Verse Stock Bot is now available to add to your Discord server! It currently serves over 50 servers and thousands of players.

If you’d like to add the bot to your server, you can use this invitation link: Invite Verse Stock Bot

For support, feature requests, or to connect with other users, join our support server: Support Server

Thank you for reading about my Discord bot project! I hope it serves the Verse gaming community well and continues to grow.