DiscordSH
DiscordSH
Section titled “DiscordSH”This is unofficial notes and docs for discordsh.
Overview
Section titled “Overview”DiscordSH is a topsite designed to promote Discord servers through a dual mechanic of voting and bumping. It serves as a platform where server owners and members can increase visibility by engaging with these systems, helping servers gain traction and attract new users. These unofficial notes aim to clarify how DiscordSH operates based on its core features.
Voting System
Section titled “Voting System”- Frequency: Users can vote for a server once every 12 hours.
- Ranking: Servers are ranked based on the total number of votes received. Those with the most votes appear higher on the list, increasing their exposure.
- Reset Cycle: All votes reset monthly, giving every server a fresh chance to climb the rankings each month.
- Purpose: Encourages consistent community engagement and rewards active participation with visibility.
Bump System
Section titled “Bump System”- Mechanism: Unlike voting, bumping is a continuous stream of recently promoted servers. When a server is “bumped,” it appears in this stream, showcasing the latest activity.
- No Reset: There’s no monthly reset for bumps—it’s a real-time feed of the most recently bumped servers.
- Purpose: Provides an alternative promotion method focused on immediacy rather than cumulative effort, ideal for quick visibility boosts.
Key Differences
Section titled “Key Differences”Feature | Voting System | Bump System |
---|---|---|
Frequency | Once per 12 hours | No fixed limit (stream-based) |
Ranking | Cumulative, monthly reset | Latest activity only |
Goal | Long-term visibility | Short-term exposure |
Tips for Server Owners
Section titled “Tips for Server Owners”- Maximize Votes: Encourage your community to vote every 12 hours to maintain a high ranking, especially early in the month to build momentum.
- Leverage Bumps: Use the bump system for quick visibility spikes, such as during events or recruitment drives.
- Combine Strategies: Pair consistent voting with periodic bumps to balance sustained growth and immediate attention.
- DiscordSH’s voting reset aligns with a competitive cycle, making it distinct from perpetual ranking systems on other topsites.
- The bump stream’s simplicity offers flexibility but lacks the prestige of top vote rankings.
- No official API or detailed documentation is referenced here; this is an unofficial interpretation based on observed functionality.
Potential Enhancements (Speculative)
Section titled “Potential Enhancements (Speculative)”- Vote Reminders: A bot integration could notify users when their 12-hour voting window resets.
- Bump Analytics: Tracking bump frequency and resulting joins could help optimize usage.
- Categories/Tags: Filtering servers by type (e.g., gaming, social) might improve discoverability—unclear if currently implemented.
Development
Section titled “Development”This section outlines the technical foundation of DiscordSH, based on inferred architecture and common practices for a topsite with voting and bumping features.
Tech Stack
Section titled “Tech Stack”- Databases:
- Supabase: Provides a scalable, real-time PostgreSQL database with a RESTful API and WebSocket support. Likely used for core data like server listings and user votes.
- Postgres: The underlying database managed by Supabase, handling structured data storage (e.g., server metadata, vote counts).
- Redis: A fast, in-memory store for ephemeral data, such as bump timestamps or session caches, ensuring low-latency operations.
- Frontend: Built with Astro (static site generation) paired with Alpine.js (lightweight interactivity) and React (dynamic components), balancing performance and reactivity.
- Backend: Powered by Rust with the Axum framework, offering a high-performance, thin layer that integrates Supabase and Redis.
- Deployment: Runs on a Kubernetes cluster, enabling scalability, resilience, and automated management of containerized services.
RESTful API
Section titled “RESTful API”DiscordSH leverages two RESTful APIs:
- Supabase REST API: Automatically provided by Supabase, exposing database operations (e.g., GET servers, POST votes) with built-in authentication and row-level security.
- Axum REST API: A custom thin layer written in Rust/Axum, wrapping Supabase and Redis interactions. It likely handles:
- Vote submissions (e.g., rate-limiting to enforce 12-hour cycles).
- Bump processing (e.g., pushing to Redis and updating the stream).
- Aggregating metrics or caching responses for efficiency.
- The Axum layer acts as a mediator, adding business logic and reducing direct frontend reliance on Supabase.
WebSockets
Section titled “WebSockets”WebSockets enable real-time features, such as live vote updates or bump stream refreshes. Data is exchanged in two formats:
-
JSON: Human-readable, used for simplicity and debugging. Example payloads for testing:
// Client -> Server (e.g., bump request){"action": "bump","server_id": "12345","timestamp": "2025-04-09T12:00:00Z"}
WS Commands
Section titled “WS Commands”Below are example JSON payloads for WebSocket commands, primarily interacting with key-value operations (likely backed by Redis). These commands support setting, retrieving, and watching data in real time. Nested Direct Command Set / Get / WATCH:
Command | Description | Example JSON Payload |
---|---|---|
SET | Sets a key-value pair without TTL | json { "message": { "Command": { "command": { "Set": { "key": "1", "value": "pop" } } } } } |
SET with TTL | Sets a key-value pair with a time-to-live (in seconds) | json { "message": { "Command": { "command": { "Set": { "key": "1", "value": "pop", "ttl": 30 } } } } } |
GET | Retrieves the value for a key | json { "message": { "Command": { "command": { "Get": { "key": "1" } } } } } |
WATCH | Subscribes to updates for a key | json { "message": { "Watch": { "key": "1" } } } |
- Notes:
- The
Command
object nestsSet
orGet
under acommand
field, suggesting a structured protocol for key-value operations. WATCH
uses a flatter structure, likely for subscribing to real-time updates (e.g., vote changes or bump events).- TTL (time-to-live) in
SET with TTL
expires the key after the specified duration (e.g., 30 seconds), useful for temporary data like cooldowns.
- The
WS Thin Layer JSON
Section titled “WS Thin Layer JSON”The thin layer (Axum) also supports WebSocket commands with a simpler JSON structure, designed for real-time interactions with the backend (e.g., Redis or Supabase).
Command | Description | Example JSON Payload |
---|---|---|
SET | Sets a key-value pair without TTL | json { "type": "set", "key": "mykey", "value": "myvalue" } |
SET with TTL | Sets a key-value pair with a time-to-live (in seconds) | json { "type": "set", "key": "mykey", "value": "myvalue", "ttl": 9000 } |
WATCH | Subscribes to updates for a key | json { "type": "watch", "key": "mykey" } |
- Notes:
- These commands use a flat structure with a
type
field to specify the action, contrasting with the nestedWS Commands
above. SET with TTL
specifies a 9000-second (2.5-hour) expiration, ideal for longer-term real-time data like bump visibility or vote buffers.WATCH
enables clients to receive live updates for a key, such as vote increments or bump stream changes, leveraging WebSocket’s real-time capabilities.- Likely used for lightweight, frontend-driven interactions with the thin layer’s WebSocket endpoint.
- These commands use a flat structure with a
DevLog
Section titled “DevLog”This is for unprocessed notes and logs from the DiscordSH development process. It includes various JSON payloads and other data structures used in the application.
For testing the websockets, we have these two JSONs:
WS Unit Commands
Section titled “WS Unit Commands”{ "message": { "Command": { "command": { "Set": { "key": "1", "value": "pop", "ttl": 30 } } } }}
Then to get:
{ "message": { "Command": { "command": { "Get": { "key": "1" } } } }}
Watch Command:
{ "message": { "Watch": { "key": "1" } }}
{ "type": "set", "key": "mykey", "value": "myvalue" }
Thin JSON 2
{ "type": "set", "key": "mykey", "value": "myvalue", "ttl": 9000 }
Thin Watch
{ "type": "watch", "key": "mykey" }