package capabilities// Scrobbler provides scrobbling functionality to external services.// This capability allows plugins to submit listening history to services like Last.fm,// ListenBrainz, or custom scrobbling backends.//// All methods are required - plugins implementing this capability must provide// all four functions: IsAuthorized, NowPlaying, Scrobble, and PlaybackReport.////nd:capability name=scrobbler required=truetype Scrobbler interface {// IsAuthorized checks if a user is authorized to scrobble to this service.//nd:export name=nd_scrobbler_is_authorizedIsAuthorized(IsAuthorizedRequest) (bool, error)// NowPlaying sends a now playing notification to the scrobbling service.//nd:export name=nd_scrobbler_now_playingNowPlaying(NowPlayingRequest) error// Scrobble submits a completed scrobble to the scrobbling service.//nd:export name=nd_scrobbler_scrobbleScrobble(ScrobbleRequest) error// PlaybackReport sends a playback state report to the scrobbling service.//nd:export name=nd_scrobbler_playback_reportPlaybackReport(PlaybackReportRequest) error}// IsAuthorizedRequest is the request for authorization check.type IsAuthorizedRequest struct {// Username is the username of the user.Username string `json:"username"`}// ArtistRef is a reference to an artist with name and optional MBID.type ArtistRef struct {// ID is the internal Navidrome artist ID (if known).ID string `json:"id,omitempty"`// Name is the artist name.Name string `json:"name"`// MBID is the MusicBrainz ID for the artist.MBID string `json:"mbid,omitempty"`}// TrackInfo contains track metadata.type TrackInfo struct {// ID is the internal Navidrome track ID.ID string `json:"id"`// Title is the track title.Title string `json:"title"`// Album is the album name.Album string `json:"album"`// Artist is the formatted artist name for display (e.g., "Artist1 • Artist2").Artist string `json:"artist"`// AlbumArtist is the formatted album artist name for display.AlbumArtist string `json:"albumArtist"`// Artists is the list of track artists.Artists []ArtistRef `json:"artists"`// AlbumArtists is the list of album artists.AlbumArtists []ArtistRef `json:"albumArtists"`// Duration is the track duration in seconds.Duration float32 `json:"duration"`// TrackNumber is the track number on the album.TrackNumber int32 `json:"trackNumber"`// DiscNumber is the disc number.DiscNumber int32 `json:"discNumber"`// MBZRecordingID is the MusicBrainz recording ID.MBZRecordingID string `json:"mbzRecordingId,omitempty"`// MBZAlbumID is the MusicBrainz album/release ID.MBZAlbumID string `json:"mbzAlbumId,omitempty"`// MBZReleaseGroupID is the MusicBrainz release group ID.MBZReleaseGroupID string `json:"mbzReleaseGroupId,omitempty"`// MBZReleaseTrackID is the MusicBrainz release track ID.MBZReleaseTrackID string `json:"mbzReleaseTrackId,omitempty"`// LibraryID is the ID of the library the track belongs to.// Only included if the plugin has library permission with filesystem access for the track's library.LibraryID int32 `json:"libraryId,omitempty"`// Path is the full path to the track file, relative to the library root.// Only included if the plugin has library permission with filesystem access for the track's library.Path string `json:"path,omitempty"`}// NowPlayingRequest is the request for now playing notification.type NowPlayingRequest struct {// Username is the username of the user.Username string `json:"username"`// Track is the track currently playing.Track TrackInfo `json:"track"`// Position is the current playback position in seconds.Position int32 `json:"position"`}// ScrobbleRequest is the request for submitting a scrobble.type ScrobbleRequest struct {// Username is the username of the user.Username string `json:"username"`// Track is the track that was played.Track TrackInfo `json:"track"`// Timestamp is the Unix timestamp when the track started playing.Timestamp int64 `json:"timestamp"`}// PlaybackReportRequest is the request for playback report notifications.type PlaybackReportRequest struct {// Username is the username of the user.Username string `json:"username"`// Track is the track being played.Track TrackInfo `json:"track"`// State is the current playback state (starting/playing/paused/stopped/expired).State string `json:"state"`// PositionMs is the current playback position in milliseconds.PositionMs int64 `json:"positionMs"`// PlaybackRate is the playback speed (1.0 = normal).PlaybackRate float64 `json:"playbackRate"`// PlayerId is the unique client identifier.PlayerId string `json:"playerId"`// PlayerName is the human-readable player name.PlayerName string `json:"playerName"`// Timestamp is the Unix timestamp when this report was generated.Timestamp int64 `json:"timestamp"`}// ScrobblerError represents an error type for scrobbling operations.type ScrobblerError stringconst (// ScrobblerErrorNotAuthorized indicates the user is not authorized.ScrobblerErrorNotAuthorized ScrobblerError = "scrobbler(not_authorized)"// ScrobblerErrorRetryLater indicates the operation should be retried later.ScrobblerErrorRetryLater ScrobblerError = "scrobbler(retry_later)"// ScrobblerErrorUnrecoverable indicates an unrecoverable error.ScrobblerErrorUnrecoverable ScrobblerError = "scrobbler(unrecoverable)")// Error implements the error interface for ScrobblerError.func (e ScrobblerError) Error() string { return string(e) }