Files
SongRequest/README.md
cottongin 6723413250 Initial commit: SongRequest Limnoria plugin
IRC song request plugin with iTunes validation, HTMX web dashboard,
WebSocket real-time updates, moderation, rate limiting, and history.

Made-with: Cursor
2026-03-28 04:43:50 -04:00

5.6 KiB

SongRequest — Limnoria IRC Song Request Plugin

A Limnoria (Supybot) plugin that watches IRC channels for song requests, validates them against the iTunes Search API, and streams them in real time to an HTMX web dashboard via WebSocket.

Features

  • Passive detection — recognizes Artist - Title patterns in chat and validates against Apple Music
  • Explicit command!request Artist - Title for direct requests
  • Disambiguation — presents top matches when multiple results found; user picks by number
  • Web dashboard — HTMX-powered UI with album art, Apple Music links, and moderation controls
  • Real-time updates — WebSocket pushes new requests and status changes to all connected dashboards
  • Moderation — approve, reject, or mark requests as played from the web UI
  • Rate limiting — configurable per-user request limits
  • Ignore list — block specific users from making requests
  • Persistence — SQLite-backed; survives bot restarts
  • IRC announcements — optionally announces status changes back to the originating channel
  • Quiet mode — suppress the "Queued" IRC confirmation per-channel
  • Alternate matches — when disambiguating, unchosen tracks appear as collapsible sub-cards
  • Clickable cards — the entire request card links to Apple Music
  • Export history — download request history as a Markdown file
  • Open/close requests — global toggle (with per-channel override) from IRC or the web panel
  • Clear history — wipe played/rejected entries from IRC or the web panel

Dependencies

  • aiohttp — standalone async web server for the dashboard
pip install aiohttp

Installation

  1. Copy the SongRequest/ directory into your Limnoria plugins directory (or add its parent to config directories.plugins).

  2. Load the plugin:

    @load SongRequest
    
  3. Configure enabled channels:

    @config plugins.SongRequest.enabledChannels #music #requests
    
  4. Set a web dashboard auth token:

    @config plugins.SongRequest.webAuthToken your-secret-token-here
    
  5. Access the dashboard at http://<bot-host>:8888/ (default port, configurable via webPort).

Configuration

Setting Type Default Description
enabledChannels Space-separated list (empty) Channels for passive detection
ignoredUsers Space-separated list (empty) Nicks/hostmasks to ignore
maxRequestsPerUser Integer 10 Max requests per rate limit window (0 = unlimited)
rateLimitWindow Integer 3600 Rate limit window in seconds
webAuthToken String (private) (empty) Auth token for web dashboard actions
announceStatus Boolean True Announce status changes back to IRC
maxChoices Integer 3 Disambiguation choices shown
webPort Integer 8888 Port for the web dashboard server
webHost String 0.0.0.0 Bind address for the web dashboard server
requestsOpen Boolean True Global toggle — accept or reject new requests
requestsOpenOverride String (per-channel) (empty) Per-channel override: open, closed, or empty for global
quietQueued Boolean (per-channel) False Suppress the "Queued: ..." IRC confirmation
passiveDetection Boolean (per-channel) True Enable passive pattern matching
requestCommand Boolean (per-channel) True Enable the !request command

Commands

Command Description Permission
request <text> Request a song by artist/title Anyone
pick <number> Pick from disambiguation choices Anyone
ignore <nick> Add a nick to the ignore list Admin
unignore <nick> Remove a nick from the ignore list Admin
requeststats Show queue statistics Anyone
openrequests [channel] Open requests globally or per-channel Admin
closerequests [channel] Close requests globally or per-channel Admin
clearhistory Clear all played/rejected requests Admin

Web Dashboard

The dashboard runs on a standalone aiohttp server (separate from Limnoria's built-in HTTP server) at the configured webPort (default 8888). It shows:

  • Pending requests awaiting moderation
  • Approved requests ready to play
  • History of played/rejected requests

Each request card is a clickable link to Apple Music and displays album art, song title, artist, album name, requester info, and action buttons (Approve / Reject / Mark Played). When a request had disambiguation, the alternate matches appear in a collapsible section below the main card.

The history tab includes Export .md (download as Markdown) and Clear History buttons. A toggle switch in the header opens/closes requests globally (synced in real time across all connected dashboards).

Real-time updates are delivered via WebSocket — the status indicator dot in the header shows green when connected and red when disconnected (with automatic reconnection).

Admin actions require the auth token, which is automatically injected into the dashboard page at serve time.

How Passive Detection Works

  1. The bot watches messages in enabledChannels for lines matching Something - Something
  2. Lines starting with bot command prefixes (!, ., @, etc.) or URLs are skipped
  3. The extracted text is searched against the iTunes Search API
  4. If no song matches, the message is silently ignored (primary false-positive filter)
  5. If one match, it's queued automatically
  6. If multiple matches, the user is presented with choices

Running Tests

pip install limnoria aiohttp pytest
python -m pytest SongRequest/test.py -v