Overview
TGMusic is a feature-rich Discord bot I developed to enhance community engagement through a shared, high-quality audio experience. As one of my foundational projects in backend development, it provided a practical application for learning Node.js, asynchronous programming, and API integration. The bot allows users to seamlessly play music from YouTube, manage a server-wide queue, and customize their listening experience with a variety of commands.
Designed for gaming communities and social servers, TGMusic transforms a standard voice channel into an interactive music hub. It features persistent, per-server settings stored in a MongoDB database, allowing administrators to define custom command prefixes and manage bot permissions. This project was instrumental in developing my understanding of state management in a multi-tenant environment and building responsive, event-driven applications.
Key Features
- High-Quality Music Playback: Leverages
ytdl-coreto stream audio directly from YouTube, ensuring low latency and high-fidelity playback without requiring file downloads. The bot includes a robust queueing system for continuous, shared listening sessions. - Interactive Playback & Queue Management: Users have full control over the music with commands to play, pause, resume, skip, and stop. The queue can be viewed at any time, and users can remove specific songs, providing a flexible and user-friendly experience.
- Lyrics Integration: Integrates with the KSoft.si API to fetch and display song lyrics directly in the chat, allowing users to follow along with the currently playing track.
- Per-Server Customization: Guild administrators can configure the bot’s behavior for their specific server. Settings such as the command prefix and permissions for volume control or song skipping are stored persistently in a MongoDB collection, ensuring a tailored experience for each community.
- Built-in Moderation Tools: Beyond music, the bot includes basic administrative commands like
kick,ban, andpurge, providing server moderators with essential tools to manage their community.
Technologies & Implementation
The bot is built entirely on Node.js, utilizing its event-driven, non-blocking I/O model to efficiently handle numerous simultaneous server connections and Discord API events.
- Backend: The core application is a Node.js server. I chose Discord.js, a powerful Node.js module, to interact with the Discord Gateway and REST API, simplifying event handling for messages, voice state changes, and guild management.
- Database: MongoDB was selected for its flexible, schema-less nature, which was perfect for storing guild-specific configurations. Each server’s settings are stored as a single document, identified by the
guildID, making lookups fast and simple. - Audio Streaming: Audio is handled by
ytdl-core, which directly fetches and pipes YouTube audio streams to Discord’s voice connections. This approach minimizes memory usage and latency compared to downloading files first. - External APIs: In addition to the Discord API, the bot integrates with the KSoft.si API for lyrics and uses
youtube-searchto find videos from user queries.
graph TD
A["Discord User"] -- "!play song name" --> B["Discord API"]
B -- "Message Event" --> C["TGMusic Bot (Node.js)"]
C -- "Search Query" --> D["YouTube API"]
D -- "Video URL" --> C
C -- "Fetch Audio Stream" --> E["ytdl-core"]
E -- "Audio Stream" --> C
C -- "Joins VC & Plays Audio" --> B
B -- "Bot plays music" --> A
subgraph "Persistent Storage"
F["MongoDB Database"]
end
subgraph "External Services"
D
G["KSoft.si API"]
end
C -- "Read/Write Guild Settings" --> F
C -- "!lyrics" --> G
Challenges & Solutions
The primary technical challenge was managing state across hundreds of independent Discord servers (guilds). Each guild required its own isolated queue, voice connection, and settings. A global state would cause conflicts, where actions in one server could disrupt playback in another.
To solve this, I implemented a two-part state management system. For transient, in-memory state like the song queue and the current voice connection, I used a JavaScript Map object with the guild.id as the key. This provided an efficient, O(1) lookup to retrieve the correct state for any incoming command. For persistent configurations, I used MongoDB, creating a guilds collection where each document was uniquely identified by the guildID. This architecture ensured complete isolation between servers, creating a stable and scalable multi-tenant application.
Results & Impact
As an early personal project, TGMusic was a critical learning experience that solidified my skills in backend development and system architecture. It served as a practical introduction to asynchronous programming with async/await, managing real-time WebSocket connections via the Discord API, and integrating a database to create a stateful application. The principles of state isolation and event-driven design I learned from this project have been directly applicable to the more complex, scalable systems I’ve built since.
{TODO: Add screenshot of the bot’s ‘now playing’ embed message in Discord}
