Skip to content

Architecture ​

Solstice uses a unified single-process Go architecture. A single compiled native binary handles all Telegram Bot API interactions, command parsing, database persistence, queue management, voice chat streaming (via CGo libntgcalls), and the embedded Web Room server.

High-Level Overview ​

┌─────────────────────────────────────────────────────────────────┐
│                         Telegram Cloud                          │
│                    (Bot API + MTProto API)                      │
└──────────────┬──────────────────────────────────┬───────────────┘
               │ Bot API (HTTPS)                  │ MTProto (TCP)
               ▼                                  ▼
┌─────────────────────────────────────────────────────────────────┐
│                    SolsticeIO (Single Go Process)               │
│                                                                 │
│  ┌───────────────────────┐         ┌─────────────────────────┐  │
│  │   Bot Engine (telebot)│         │ MTProto Client (gogram) │  │
│  │  • Command routing    │         │ • Assistant account     │  │
│  │  • User permissions   │         │ • Join group voice chat │  │
│  │  • i18n localization  │         │ • Universal session     │  │
│  └───────────┬───────────┘         └────────────┬────────────┘  │
│              │                                  │               │
│              ▼                                  ▼               │
│  ┌───────────────────────┐         ┌─────────────────────────┐  │
│  │   Action Dispatcher   │         │ Voice Engine (CGo)      │  │
│  │  • Play, Pause, Skip  │◄───────►│ • libntgcalls bindings  │  │
│  │  • Queue transitions  │         │ • In-process WebRTC     │  │
│  │  • Thread-safe locks  │         │ • FFmpeg media stream   │  │
│  └───────────┬───────────┘         └─────────────────────────┘  │
│              │                                                  │
│              ├──────────────────────────────────┐               │
│              ▼                                  ▼               │
│  ┌───────────────────────┐         ┌─────────────────────────┐  │
│  │ Embedded Web Server   │         │  Storage & Resolvers    │  │
│  │ • HTTP & WebSockets   │         │  • MongoDB persistence  │  │
│  │ • Web Room Mini App   │         │  • Upstash Redis cache  │  │
│  │ • On-demand sync hub  │         │  • InnerTube / yt-dlp   │  │
│  └───────────────────────┘         └─────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘

Why Pure Go with CGo? ​

AreaImplementationAdvantage
Bot API Handlingtelebot.v3High concurrency, typed handlers, clean middleware
Voice Chat EngineCGo (libntgcalls)In-process WebRTC streaming without external daemons
MTProto AssistantgogramNative Go MTProto client; supports Pyrogram, Telethon, & GoGram sessions
Web Room & Mini AppNative net/http + //go:embedZero CORS, 1 deployment URL, no Node.js runtime needed
Audio ExtractionInnerTube + yt-dlp fallbackFast YouTube resolver with Upstash Redis stream caching
Databasego.mongodb.org/mongo-driverDirect connection pooling with replica-set support

By embedding libntgcalls directly into Go via CGo, Solstice eliminates the CPU overhead, memory consumption.


Centralized Action Dispatcher ​

All playback operations (whether triggered from Telegram commands, inline buttons, or the Web Room) funnel through internal/dispatcher/:

Telegram Chat Command ──┐
Telegram Inline Button ─┼──► [Action Dispatcher] ──► [QueueManager]
Web Room WebSocket ─────┘         │                        │
                                  ▼                        ▼
                          [Role Check & Lock]     [CGo Voice Engine]
  1. Per-Chat Mutex Serialization: Every chat has an isolated mutex preventing race conditions during concurrent skips, seeks, or queue additions.
  2. Role Verification: Actions enforce permission hierarchies (Owner > Sudoer > Group Admin > Song Requester > Member).
  3. Event Broadcasting: When a track starts or advances, the dispatcher updates both Telegram inline play cards and broadcasts the state change to all connected Web Room clients.

Embedded Web Room Architecture ​

The embedded web server (internal/web/) runs concurrently with the bot on :PORT (default 8080):

  • Static Asset Serving: All frontend assets (index.html, app.css, app.js) are compiled into the binary via Go 1.16+ //go:embed static/*.
  • On-Demand WebSocket Hub:
    • Starts a 1-second sync loop only when the first client connects to a voice chat room.
    • Automatically terminates the ticker and deletes room memory when all clients leave (0% idle CPU).
  • Interactive Controls: Users can play, pause, seek, adjust volume, reorder, remove, or search and queue new tracks directly from the web interface.
  • Synced Lyrics Proxy: Calls LRCLIB with in-memory caching to synchronize lyrics with the voice stream.

Sequence: Playing a Song ​

User sends: /play Bohemian Rhapsody (or clicks Add in Web Room)
          │
          ▼
┌─── Go Action Dispatcher ───────────────────────────────────┐
│ 1. Validate permissions (admin / requester / everyone)     │
│ 2. Search YouTube (InnerTube → HTML scrape → yt-dlp)       │
│ 3. Extract direct stream URL (checking Upstash Redis)      │
│ 4. Atomic Enqueue in QueueManager                          │
│ 5. If stream is idle:                                      │
│    a. Initialize VoiceSession via Assistant                │
│    b. Join voice chat WebRTC via libntgcalls               │
│    c. Start audio stream pipeline                          │
│ 6. Send Now Playing card to Telegram & broadcast to Web    │
└────────────────────────────────────────────────────────────┘
          │
          │ Stream ends naturally
          ▼
┌─── CGo libntgcalls Callback ───────────────────────────────┐
│ 1. Engine fires OnStreamEnd                                │
│ 2. Dispatcher advances queue in-place                      │
│ 3. If next song exists, streams immediately                │
│ 4. If queue empty + autoplay enabled:                      │
│    Fetches related YouTube Mix track and queues it         │
│ 5. If queue empty + autoplay disabled:                     │
│    Leaves VC after alone timeout                           │
└────────────────────────────────────────────────────────────┘

Concurrency Model ​

  • Goroutines: YouTube searches, stream caching, broadcast messages, and WebSocket pump loops run non-blocking in lightweight goroutines.
  • Thread Safety: All state managers (QueueManager, ActionDispatcher, Hub) use strict read/write mutexes (sync.RWMutex) to guarantee safe concurrent access.
  • Graceful Shutdown: Intercepts SIGINT and SIGTERM, cleanly closing WebRTC voice sessions, terminating the web server, and disconnecting MongoDB connections.

Released under the GPL-3.0 License.