feat: direct Spotify/Bandcamp links via MusicBrainz url-relations (task/odesli-direct-links)

The Odesli/Songlink API rejects artist URLs (405 UNSUPPORTED_URL — it is song/album
only), so the planned Odesli hop is not viable for artist linking. Pivoted to
MusicBrainz `inc=url-rels`, which returns the artist's official Bandcamp + Spotify
URLs directly, zero-cred:
- service/lib.js: relUrls() extracts direct bandcamp/spotify from MB relations;
  mbResult() prefers them, falls back to search URLs per-platform (replaces searchResult).
- service/resolver.js: viaMusicBrainz now does search -> url-rels enrichment (both
  throttled through one gate); resolveOne calls it directly.
- service/lib.test.js: +3 tests (relUrls + mbResult); 9 total, green.
- README: document the direct-link behavior.

Verified zero-cred end to end: "Cattle Decapitation" -> open.spotify.com/artist/... +
cattledecapitation.bandcamp.com/ (both direct, not search); nonsense -> null.

Source: task/odesli-direct-links (objective/linker-improvements); approach changed from
Odesli to MB url-rels after the API probe; goal (direct Bandcamp) achieved.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
paul
2026-06-16 12:35:33 +00:00
co-authored by Claude Opus 4.8
parent 9f9858a050
commit 7c695be590
4 changed files with 83 additions and 27 deletions
+8 -4
View File
@@ -44,8 +44,9 @@ node resolver.js
```
That's it. With no configuration the resolver validates names against
**MusicBrainz** (no account required) and links to Spotify/Bandcamp **search**
pages.
**MusicBrainz** (no account required). When MusicBrainz knows an artist's official
links (its `url-relations`), you get **direct** Spotify and Bandcamp artist pages;
otherwise it falls back to Spotify/Bandcamp **search** URLs.
### Optional: direct Spotify links
@@ -62,7 +63,8 @@ API credentials:
```
3. Restart the service. It will report `provider: spotify` on startup.
(Bandcamp has no public API, so Bandcamp links are always a search URL.)
(Bandcamp has no public API; direct Bandcamp links come from MusicBrainz
`url-relations` when present, else a Bandcamp search URL.)
Quick check that it works:
@@ -107,7 +109,9 @@ let the content script reach it).
across formatting (e.g. **bold** in the middle of a name), can be missed. The
resolver's exact-name match keeps false *positives* low; the trade-off is some
false *negatives*.
- **Bandcamp links are searches**, not direct artist pages (no public API).
- **Links are direct when MusicBrainz has the artist's `url-relations`** (official
Bandcamp / Spotify pages); otherwise they fall back to a search URL. (Each
confirmed artist costs one extra throttled MusicBrainz lookup, cached after.)
- The resolver caches results in memory; it resets when you restart it.
- Without Spotify credentials the MusicBrainz path is rate-limited to ~1 lookup/
second, so the first scan of a large thread fills in gradually (cached after).