Hypixel Marketplace Tracker

Real-Time Auction House Intelligence

A specialized Discord Bot engineered to continuously monitor and retrieve real-time data directly from the Hypixel SkyBlock Auction House API. It eliminates the need for manual game logins by allowing users to instantly check dynamic market values, highest/lowest offers, and Buy-It-Now (BIN) prices. The bot chains multiple external APIs—Mojang for UUID resolution and Hypixel for profile and auction data—through advanced Discord Slash Commands with configurable price filtering.

Architecture & How It Works

The application follows a monolithic, event-driven architecture built on Node.js. On startup, it loads credentials via dotenv, initializes the Discord client with specific Gateway Intents, and dynamically registers Slash Commands to a target Guild. When a user invokes a command, the handler in index.js parses the interaction, chains API calls (Mojang → Hypixel), processes the data, and formats the response as a rich Discord Embed—all within a single event loop.

1. API Chain-Loading (Mojang → Hypixel)

The core data pipeline chains two external APIs sequentially. First, the Mojang API resolves a human-readable Minecraft username into a unique UUID. That UUID is then passed to the Hypixel APIto fetch the player's full SkyBlock profile, including purse balance, banking data, and active profiles. This two-step resolution is necessary because Hypixel indexes all data by UUID, not username.

// Chain: Username → UUID → SkyBlock Profile
async function fetchPlayerData(username) {
  // Step 1: Resolve username to UUID via Mojang
  const mojang = await axios.get(
    `https://api.mojang.com/users/profiles/minecraft/${username}`
  );
  const uuid = mojang.data.id;

  // Step 2: Fetch SkyBlock profiles via Hypixel
  const hypixel = await axios.get(
    `https://api.hypixel.net/skyblock/profiles?key=${API_KEY}&uuid=${uuid}`
  );
  
  return { uuid, profiles: hypixel.data.profiles };
}

2. Auction House Pagination Crawler

The /skyblockauctions command implements a full pagination-crawling engine that scrapes up to 60 pages of live auction data from the Hypixel API, then filters and sorts results in-memory:

  • BIN Filter: Only “Buy It Now” listings are included—standard auction-style listings are discarded since they lack a fixed price.
  • Name Matching: Each listing's item_name is checked against the user's search query using case-insensitive substring matching.
  • Price Range: Results are filtered by user-defined min_price and max_price parameters, then sorted low-to-high to surface the best deals.
    results.sort((a, b) => a.starting_bid - b.starting_bid).slice(0, 10)

3. Discord Slash Commands & Embed Formatting

The bot dynamically registers Slash Commands to a specific Guild on startup using client.guilds.cache.get(GUILD_ID).commands.set(). Each command defines typed options (strings, integers) that Discord validates before the interaction reaches the bot. Responses are formatted as rich EmbedBuilder messages with colored sidebars, inline fields for balances, and formatted price strings—providing a clean, readable output directly in the Discord channel without requiring users to leave the app.

Tech Stack & Tools Used

Runtime & Discord

  • Node.js: JavaScript runtime powering the event-driven bot architecture.
  • discord.js v14: Official Discord API wrapper handling Gateway connections, Slash Commands, and Embeds.
  • Axios: Promise-based HTTP client for chaining Mojang and Hypixel API requests.
  • dotenv: Environment variable management for securely loading API keys and tokens.

External APIs & Tooling

  • Hypixel API: SkyBlock profile data, auction house listings, and player statistics.
  • Mojang API: Minecraft username → UUID resolution for cross-API identity linking.
  • Nodemon: Hot-reloading development server for rapid iteration during bot development.
  • ES6+ / CommonJS: Modern JavaScript with async/await for clean asynchronous API orchestration.

Architecture Diagram

📐Event-Driven Architecture & API Flow

[ ARCHITECTURE OVERVIEW ]

┌─────────────────────────────────────────────────────────────┐
│                     DISCORD CLIENT                          │
│                     discord.js v14                          │
│                                                             │
│   ┌─────────────────────────────────────────────────────┐   │
│   │              Slash Command Registry                 │   │
│   │                                                     │   │
│   │  /skyblock          → Player profile lookup         │   │
│   │  /skyblockauctions  → Auction house crawler         │   │
│   │  /roll_a_dice       → Utility command               │   │
│   └────────────────────────┬────────────────────────────┘   │
│                            │                                 │
│   client.on('ready')       │  client.on('interactionCreate') │
│   → Register commands      │  → Route to handler             │
│     to Guild               │                                 │
└────────────────────────────┼────────────────────────────────┘
                             │
              ┌──────────────┴──────────────┐
              │    COMMAND HANDLER (index.js) │
              │                              │
              │  1. Parse interaction options │
              │  2. Validate input           │
              │  3. Chain API calls          │
              │  4. Format embed response    │
              │  5. Reply to interaction     │
              └──────┬───────────────┬───────┘
                     │               │
          ┌──────────┴───┐   ┌───────┴──────────────────┐
          ▼              ▼   ▼                          ▼
┌──────────────┐  ┌──────────────────────────────────────┐
│  MOJANG API  │  │         HYPIXEL API                  │
│              │  │                                      │
│  GET /users/ │  │  GET /skyblock/profiles?uuid=        │
│  profiles/   │  │  → Player data, purse, banking       │
│  minecraft/  │  │                                      │
│  {username}  │  │  GET /skyblock/auctions?page=        │
│              │  │  → Paginated auction listings         │
│  Returns:    │  │  → Up to 60 pages crawled            │
│  UUID        │  │  → BIN filter + price sort           │
└──────┬───────┘  └──────────────────┬───────────────────┘
       │                             │
       │    username → UUID          │  UUID → profile data
       │                             │  page → auction listings
       ▼                             ▼
┌─────────────────────────────────────────────────────────────┐
│                   DISCORD EMBED RESPONSE                    │
│                                                             │
│   ┌─────────────────────────────────────────────────────┐   │
│   │  Player Profile Embed                               │   │
│   │  ● Username & UUID                                  │   │
│   │  ● Purse Balance                                    │   │
│   │  ● Banking Balance                                  │   │
│   │  ● Profile Cute Name                                │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                             │
│   ┌─────────────────────────────────────────────────────┐   │
│   │  Auction Results Embed                              │   │
│   │  ● Item Name + Tier                                 │   │
│   │  ● BIN Price (sorted low→high)                      │   │
│   │  ● Filtered by min/max range                        │   │
│   │  ● Top 10 results displayed                         │   │
│   └─────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘

Auction Crawl Pipeline:

  /skyblockauctions { name, min_price, max_price }
       │
       ▼
  for (page = 0; page < totalPages; page++)
       │
       ├─ GET /skyblock/auctions?page={page}
       ├─ Filter: bin === true
       ├─ Filter: item_name.includes(query)
       ├─ Filter: price >= min && price <= max
       └─ Push to results[]
       │
       ▼
  results.sort((a, b) => a.price - b.price)
       │
       ▼
  Display top 10 as Discord Embed

Local Execution & Testing

The bot requires a Discord Bot Token and a Hypixel API Key configured in a .env file. You'll also need to update the Guild ID in index.js to point to your Discord server for Slash Command registration:

# Install Dependenciesnpm install
# Configure Environment (.env)DISCORD_TOKEN=your_discord_bot_tokenHYPIXEL_API_KEY=your_hypixel_api_key
# Update Guild ID in index.js (line 85)client.guilds.cache.get('YOUR_SERVER_ID').commands.set([...])
# Launch the Botnpm start

Testing Strategy

  • Player Data Test: Run /skyblock username: your_name to verify UUID resolution and profile data retrieval.
  • Auction Filtering Test: Run /skyblockauctions name: "Hyperion" min_price: 1000000 to verify the pagination crawler and BIN filtering logic.
  • Edge Case Handling: Fetch a non-existent Minecraft username to verify try-catch error handling and user-facing error messages.