Releases: thecodedrift/firebot-script-music-to-my-ears
Release list
v2.1.1
Patch Changes
-
b920c2a: Stop a song request from queueing an unrelated track that happens to share a common word. The raw
search fallback accepted any candidate sharing at least one token with the request, and every token
counted equally — so a sharedthewas enough. A request forwalk the dinosaur by ninja sex party
could come back with "The Decision".The floor now requires a shared content token: a word that is not an article, conjunction,
preposition, or feature marker. A candidate whose only commonality is a function word is reported as
not-found instead of queued. Pronouns still count (Stand By Me,Call Me Maybe), and a query made
entirely of function words —The The,You And Me— keeps the old behavior so it stays findable.Ranking is unchanged: it still weighs every token, because choosing between related candidates is a
different question from deciding whether a candidate is related at all. -
0aca4b4: Strip a leaked command trigger from a song request.
!sr Toxic by Britney Spearsused to search
Spotify fortrack:"!sr Toxic", which matches nothing — so every request carrying a trigger burned
its first search and fell back to a raw query that still contained the junk token, leaving the match
to Spotify's ranking. The trigger is now removed first, so the request matches on the real title and
costs one search instead of two.$arg[all]is safe to wire straight into the effect.The rule is deliberately narrow: only the first token, only when a letter follows the
!(so the
band!!!is untouched), and never when nothing would be left to search for. -
aa2806e: Fix bug reports arriving with no logs. The script now keeps its own log of the Firebot session —
every search, candidate, and refused request, at every level and whatever your Firebot log level is
— and the script settings page has a Copy debug log button that puts the lot on your clipboard,
prefixed with the script and Firebot versions and your settings (client id and secret left out).The per-effect Enable logging checkbox is gone with it. It defaulted to off, which meant the
records were missing from exactly the sessions that needed them; those diagnostics are now always
recorded, and they moved frominfotodebug, so Firebot's own log file gets quieter.
v2.1.0
Minor Changes
- 0dfe2e0: Add an optional global "Country of Play" setting — a 2-letter country code (e.g.
US,GB,DE).
When set, song requests resolve against that country's Spotify catalog: the code is sent as the
Spotifymarket, region-locked tracks are dropped from the results instead of being queued, and a
pasted link to a track that can't play in that country reports "not playable". Leaving it blank keeps
today's behavior (your linked account's country is used automatically). This pairs with relevance
ranking so requests match a playable track more often. - 31f42f1: Add a global blocklist for artists, tracks, and terms. A new script setting takes one entry per
line, applied to every song request on top of each Request Song effect's own list. Paste a Spotify
artist or track link (or URI) to block that exact artist or track by id — so you can ban an artist
without banning their name as a word — or type any other line as a case-insensitive term matched
against the artist and track names. The per-effect blocked-terms field becomes the same one-per-line
textarea and accepts links too; effects saved with the old list upgrade automatically. Blocks now
reportblocked-artistorblocked-track(alongside the existingblocked-term) so you can tell a
viewer exactly why their request was turned away.
Patch Changes
- 1f2b409: Song requests now rank Spotify search results by relevance instead of blindly taking the first
result. Candidates are scored by how many query tokens appear in the track and artist names, and the
best-matching one is queued (ties keep Spotify's order). The raw fallback also gains a relevance
floor: when no candidate shares any word with the request, it reports "not found" rather than queuing
an unrelated track. Fixes requests likeCome play - advancethat previously queued a wildly wrong
song.
v2.0.0
Major Changes
-
f0f42df: Add jukebox protection to the Request Song effect, and ship a friendly failure message with every
error.Breaking: the no-repeat window moved. It is no longer a script setting. Each Request Song effect
now has its own Same track cooldown (minutes) under a new Restrictions section, defaulting to
30 — the same value the script setting defaulted to. If you had changed the old No-Repeat Window
from 30, set it again on each Request Song effect after upgrading. Nothing else changes behavior.Jukebox protection. The no-repeat window stops the same track being requeued, but nothing
stopped the same artist from crowding out the queue: two fans of one band could stack hours of it
without ever repeating a track. Three new per-effect restrictions, all disabled by default:- Artist cooldown — how long before that artist can be requested again by anyone. This
protects the variety of the playlist, so it applies to every viewer, not only the one who requested
the artist. Only the track's primary artist is gated, and artists are matched by Spotify id rather
than by name. - Artist cooldown per viewer — how long before the same viewer can request that artist again.
Skipped entirely for triggers that carry no username, such as timers. - Maximum track length — rejects anything longer than the configured number of seconds.
Each has its own
errorReason:artist-recently-played,user-artist-recently-played,too-long.When several cooldowns apply at once, the one with the longest remaining wait is reported — not
the most specific one. Telling a viewer "try again in 5 minutes" while a 58-minute artist cooldown is
still running would send them back to be rejected a second time.Two new outputs.
errorTextis a prebuilt message you can send straight to chat, on the Request
Song effect and on every other effect that reports anerrorReason.errorCooldownis the remaining
wait in whole seconds, and is0whenever the failure was not a cooldown. Branch onerrorReasonwhen
you want your own wording; useerrorTextwhen you don't. - Artist cooldown — how long before that artist can be requested again by anyone. This
v1.1.0
Minor Changes
-
c454930: Normalize song-request searches with Spotify field filters, and add opt-in per-effect logging.
A request shaped
<title> by <artist>(or<title> - <artist>) is now sent to Spotify as
track:"<title>" artist:"<artist>"instead of as one free-text blob, which stops artist words from
competing with track titles for rank.seven dollars by happy birthday mr basketsnarrows from 13
loosely-related matches to the 1 correct one.The split only happens when the separator appears exactly once, and the result is validated by
whole-token containment before it is accepted — so a title that contains the separator, like
Stand By Me, is caught and retried once with the raw query rather than queuing the wrong song.
Any query that does not split, or whose filtered result fails validation, behaves exactly as before.The Request Song effect also gains an Enable logging checkbox (default off). When on, it logs
each search attempt: the query sent to Spotify, the total number of matches, every candidate
returned, which one was selected, and the raw response — enough to diagnose a wrong match after the
fact. It is verbose by design, which is why it is opt-in.
v1.0.4
Patch Changes
-
3ca1a27: Fix empty
errorReason(and all other outputs) on the failure path of every
Spotify effect. Firebot's effect-runner only registers an effect'soutputs
when the effect reports a truthy top-levelsuccess; onsuccess: falseit
logs the effect as failed and discardsoutputsentirely. Our effects returned
top-levelsuccess: falseon failure, so$effectOutput[errorReason]resolved
to empty and the widget could not surface why a request failed.The effect still ran to completion — it evaluated the request and produced a
verdict — so the failure branches now return top-levelsuccess: trueand carry
the real pass/fail inoutputs.success(which the streamer branches on), keeping
errorReasonintact. Applies to Request Song, Get Current Track, and the shared
playback factory behind Skip / Play-Resume / Pause.
v1.0.3
Patch Changes
-
01b21a9: Stop sending the deprecated
market=from_tokenparameter on Spotify track and
search requests. Spotify removedfrom_tokenin its November 2024 API changes
and now rejects it (with a misleading error) on some endpoints and accounts,
which could make name searches fail while direct links still worked. With a
valid user token, Spotify uses the account's own country automatically, so the
correct per-account catalog andis_playableare preserved without the
deprecated value. Also adds a debug log when a name search resolves to no
playable track, so the previously silent "not found" path is diagnosable.Adds a triage debug block on every failed Spotify response capturing the
request shape, the response (status, status text, retry-after / request-id,
body), and the derived error. It deliberately omits the Authorization header,
access token, and client secret, and redacts user-content query values (search
text, track uris) from the logged endpoint.
v1.0.2
Patch Changes
-
a4031ac: Rename the package to
firebot-script-music-to-my-earsto match the renamed
GitHub repository. The package is private (unpublished) and the build output
name (scriptOutputName) is unchanged, so the Firebot-loaded script file is
unaffected. -
04921cd: Harden Spotify token handling and add scope diagnostics.
- Expired-token protection — when Spotify rejects a call with a 401 (the
token was revoked or rotated behind our back and the local expiry timer can't
see it), the request now forces a token refresh and retries once instead of
failing. - Scope validation logging — on every token refresh we compare the scopes
Spotify actually granted against the scopes we request and warn when any are
missing (typicallyuser-modify-playback-state, the cause of "Insufficient
client scope"), pointing at a re-link. Debug logging confirms the token is
valid when all scopes are present. - Single source of truth for the token — the access token is now read only
from the integration definition Firebot persists, removing the parallel
captured-token fallback that could diverge from the live linked token.
- Expired-token protection — when Spotify rejects a call with a 401 (the
v1.0.1
Patch Changes
-
a349f0f: Fix Spotify song-request matching and add per-account playability checks.
- Better search matches — Spotify's relevance ranking is unreliable at
limit=1(it could return a worse match than the obvious one, e.g. "The Mystic
Crystal" for "Walk The Dinosaur by Ninja Sex Party"). Requests now fetch
several results and pick the first playable one, which also tolerates noisy
queries (a strayby, or a leaked!srcommand prefix). - Direct track links — a Spotify track URL,
spotify:track:URI, or bare
track id is now resolved directly to that exact track instead of being run as
a text search. - Region/playability gating — search and track lookups use
market=from_token
so results are filtered to what the linked account can play; a specifically
requested but unplayable track now fails with the newnot-playableerror
reason instead of being queued or mis-reported.
- Better search matches — Spotify's relevance ranking is unreliable at
v1.0.0
Major Changes
-
ef07824: Initial release: a Firebot custom script that adds Spotify song-request and
playback effects, built as a single self-contained CommonJS bundle.- Spotify integration — links a Spotify account via Firebot's OAuth flow with
automatic token refresh; client id/secret and the no-repeat window are
configured on the script settings page. - Request Song effect — searches Spotify (tracks only; podcasts excluded),
moderates, and queues in one atomic action, outputtingsuccessplus an
errorReason(not-found/blocked-term/explicit/recently-played/
no-active-device/not-premium/not-linked) so streamers can branch
(e.g. refund a redemption) on a single condition. Moderation is a per-effect
substring blocked-terms list (pre-filled withkaraoke,instrumental,
inst.), an optional "allow explicit tracks" toggle, and a no-repeat window. - Playback effects — Skip Track, Play / Resume, and Pause.
- Get Current Track effect — outputs the now-playing track plus the requester,
attributed via an in-memory ledger that also backs the no-repeat check.
- Spotify integration — links a Spotify account via Firebot's OAuth flow with
Minor Changes
- ef07824: Add project automation: CI (lint, typecheck, build, test) on PRs and main, Jest
tests covering moderation, the no-repeat/requester ledger, API error mapping, and
the run()/stop() lifecycle, Changesets-based versioning, a release workflow that
attaches the built bundle to a GitHub Release, and a stack-aware OpenSpec archive
check.