Social: scrobbling Plugin #26

Closed
opened 2026-10-06 21:16:52 +02:00 by SBDeveloper · 2 comments
Owner

Part of #13

What to build

Optional event Plugin that scrobbles played Tracks to a service, built only on playback events and the public plugin API.

Open question (needs a human)

Which service to scrobble to (e.g. Last.fm or ListenBrainz). Decide before this ticket becomes ready-for-agent.

Acceptance criteria

  • Off by default, enabled by user consent
  • Scrobble sent after a play threshold, now-playing update on start
  • Credentials stay inside the Plugin
  • Tested as a Plugin through the plugin host

Blocked by

Part of #13 ## What to build Optional event Plugin that scrobbles played Tracks to a service, built only on playback events and the public plugin API. ## Open question (needs a human) Which service to scrobble to (e.g. Last.fm or ListenBrainz). Decide before this ticket becomes ready-for-agent. ## Acceptance criteria - [ ] Off by default, enabled by user consent - [ ] Scrobble sent after a play threshold, now-playing update on start - [ ] Credentials stay inside the Plugin - [ ] Tested as a Plugin through the plugin host ## Blocked by - #19
Author
Owner

This was generated by AI during triage.

Agent Brief

Decision: scrobble to ListenBrainz (open API, single user token, no shared secret or request signing). Last.fm is out of scope for this ticket; file a separate ticket if wanted.

Category: enhancement

Summary: Optional event Plugin that submits played Tracks to ListenBrainz, built only on playback events and the public plugin API.

Behaviour:

  • Off by default; enabled only after the user consents to the Plugin's declared capabilities (network access to api.listenbrainz.org, playback events, own secret storage).
  • User supplies a ListenBrainz user token. Validate it via GET /1/validate-token before enabling.
  • On Track start: send playing_now via POST /1/submit-listens (Authorization: Token <token>).
  • After the play threshold: send listen_type: "single" with listened_at, artist_name, track_name, release_name when known. Threshold: 50% of Track duration or 4 minutes, whichever comes first (ListenBrainz guidance). Skip Tracks shorter than 30s.
  • Each Track scrobbled at most once per play; seeking/pausing must not double-submit.
  • Network failure must not affect playback; failed listens are dropped or retried a bounded number of times (decide in implementation, document it).
  • Token lives only inside the Plugin's secret storage and is never exposed to the host UI, other Plugins, or logs.

Acceptance criteria:

  • Off by default, enabled by user consent
  • playing_now on start, single listen after threshold, no duplicates
  • Token stays inside the Plugin (never logged or sent anywhere but ListenBrainz)
  • Tested as a Plugin through the plugin host, with ListenBrainz HTTP faked

Out of scope: Last.fm, love/like sync, importing history, Track matching across Sources.

Dependencies: blocked by #19 (capability enforcement and secret isolation). crates/plugin-api currently exposes no network or event-subscription surface; if #18/#19 don't deliver the HTTP and playback-event capabilities this Plugin needs, add them there first rather than special-casing this Plugin.

> *This was generated by AI during triage.* ## Agent Brief **Decision:** scrobble to **ListenBrainz** (open API, single user token, no shared secret or request signing). Last.fm is out of scope for this ticket; file a separate ticket if wanted. **Category:** enhancement **Summary:** Optional event Plugin that submits played Tracks to ListenBrainz, built only on playback events and the public plugin API. **Behaviour:** - Off by default; enabled only after the user consents to the Plugin's declared capabilities (network access to `api.listenbrainz.org`, playback events, own secret storage). - User supplies a ListenBrainz user token. Validate it via `GET /1/validate-token` before enabling. - On Track start: send `playing_now` via `POST /1/submit-listens` (`Authorization: Token <token>`). - After the play threshold: send `listen_type: "single"` with `listened_at`, `artist_name`, `track_name`, `release_name` when known. Threshold: 50% of Track duration or 4 minutes, whichever comes first (ListenBrainz guidance). Skip Tracks shorter than 30s. - Each Track scrobbled at most once per play; seeking/pausing must not double-submit. - Network failure must not affect playback; failed listens are dropped or retried a bounded number of times (decide in implementation, document it). - Token lives only inside the Plugin's secret storage and is never exposed to the host UI, other Plugins, or logs. **Acceptance criteria:** - [ ] Off by default, enabled by user consent - [ ] `playing_now` on start, `single` listen after threshold, no duplicates - [ ] Token stays inside the Plugin (never logged or sent anywhere but ListenBrainz) - [ ] Tested as a Plugin through the plugin host, with ListenBrainz HTTP faked **Out of scope:** Last.fm, love/like sync, importing history, Track matching across Sources. **Dependencies:** blocked by #19 (capability enforcement and secret isolation). `crates/plugin-api` currently exposes no network or event-subscription surface; if #18/#19 don't deliver the HTTP and playback-event capabilities this Plugin needs, add them there first rather than special-casing this Plugin.
Author
Owner

Implemented in 8066fcf: optional ListenBrainz plugin (plugins/optional/listenbrainz). Token validated and kept in plugin storage; playing_now on start, single listen after 50% or 4 min of real listening; tracks under 30s skipped; failed submissions tried 3 times then dropped. Tested through the plugin host with ListenBrainz faked.

Implemented in 8066fcf: optional ListenBrainz plugin (plugins/optional/listenbrainz). Token validated and kept in plugin storage; playing_now on start, single listen after 50% or 4 min of real listening; tracks under 30s skipped; failed submissions tried 3 times then dropped. Tested through the plugin host with ListenBrainz faked.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
SBDeveloper/medley#26
No description provided.