diff --git a/plugins/README.md b/plugins/README.md index f7e5259ad..3e24d10fb 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -192,8 +192,8 @@ Agents = "lastfm,spotify,my-plugin" Integrates with external scrobbling services. Export one or more of these functions: | Function | Input | Output | Description | -|------------------------------|-----------------------|----------------|-----------------------------|| -| `nd_scrobbler_is_authorized` | `{userId, username}` | `{authorized}` | Check if user is authorized | +|------------------------------|-----------------------|----------------|-----------------------------| +| `nd_scrobbler_is_authorized` | `{userId, username}` | `bool` | Check if user is authorized | | `nd_scrobbler_now_playing` | See below | (none) | Send now playing | | `nd_scrobbler_scrobble` | See below | (none) | Submit a scrobble | @@ -777,15 +777,15 @@ serde_json = "1.0" **Implementing capabilities with traits and macros:** ```rust -use nd_pdk::scrobbler::{Scrobbler, IsAuthorizedRequest, IsAuthorizedResponse, Error}; +use nd_pdk::scrobbler::{Scrobbler, IsAuthorizedRequest, Error}; use nd_pdk::register_scrobbler; #[derive(Default)] struct MyPlugin; impl Scrobbler for MyPlugin { - fn is_authorized(&self, req: IsAuthorizedRequest) -> Result { - Ok(IsAuthorizedResponse { authorized: true }) + fn is_authorized(&self, req: IsAuthorizedRequest) -> Result { + Ok(true) } fn now_playing(&self, req: NowPlayingRequest) -> Result<(), Error> { Ok(()) } fn scrobble(&self, req: ScrobbleRequest) -> Result<(), Error> { Ok(()) } diff --git a/plugins/capabilities/doc.go b/plugins/capabilities/doc.go index a90737f89..27e9e1a98 100644 --- a/plugins/capabilities/doc.go +++ b/plugins/capabilities/doc.go @@ -47,7 +47,7 @@ // // // Scrobbler requires all methods // type Scrobbler interface { -// IsAuthorized(IsAuthorizedRequest) (*IsAuthorizedResponse, error) +// IsAuthorized(IsAuthorizedRequest) (bool, error) // NowPlaying(NowPlayingRequest) error // Scrobble(ScrobbleRequest) error // } diff --git a/plugins/capabilities/scrobbler.go b/plugins/capabilities/scrobbler.go index 13a0fc795..cca50d503 100644 --- a/plugins/capabilities/scrobbler.go +++ b/plugins/capabilities/scrobbler.go @@ -11,7 +11,7 @@ package capabilities type Scrobbler interface { // IsAuthorized checks if a user is authorized to scrobble to this service. //nd:export name=nd_scrobbler_is_authorized - IsAuthorized(IsAuthorizedRequest) (*IsAuthorizedResponse, error) + IsAuthorized(IsAuthorizedRequest) (bool, error) // NowPlaying sends a now playing notification to the scrobbling service. //nd:export name=nd_scrobbler_now_playing @@ -30,12 +30,6 @@ type IsAuthorizedRequest struct { Username string `json:"username"` } -// IsAuthorizedResponse is the response for authorization check. -type IsAuthorizedResponse struct { - // Authorized indicates whether the user is authorized to scrobble. - Authorized bool `json:"authorized"` -} - // TrackInfo contains track metadata for scrobbling. type TrackInfo struct { // ID is the internal Navidrome track ID. diff --git a/plugins/capabilities/scrobbler.yaml b/plugins/capabilities/scrobbler.yaml index b966adecc..f50c2c665 100644 --- a/plugins/capabilities/scrobbler.yaml +++ b/plugins/capabilities/scrobbler.yaml @@ -6,7 +6,7 @@ exports: $ref: '#/components/schemas/IsAuthorizedRequest' contentType: application/json output: - $ref: '#/components/schemas/IsAuthorizedResponse' + type: boolean contentType: application/json nd_scrobbler_now_playing: description: NowPlaying sends a now playing notification to the scrobbling service. @@ -33,15 +33,6 @@ components: required: - userId - username - IsAuthorizedResponse: - description: IsAuthorizedResponse is the response for authorization check. - type: object - properties: - authorized: - type: boolean - description: Authorized indicates whether the user is authorized to scrobble. - required: - - authorized NowPlayingRequest: description: NowPlayingRequest is the request for now playing notification. type: object @@ -144,10 +135,3 @@ components: - duration - trackNumber - discNumber - ScrobblerError: - description: ScrobblerError represents an error type for scrobbling operations. - type: string - enum: - - scrobbler(not_authorized) - - scrobbler(retry_later) - - scrobbler(unrecoverable) diff --git a/plugins/examples/discord-rich-presence-rs/src/lib.rs b/plugins/examples/discord-rich-presence-rs/src/lib.rs index df49eba4e..22b3b9e8c 100644 --- a/plugins/examples/discord-rich-presence-rs/src/lib.rs +++ b/plugins/examples/discord-rich-presence-rs/src/lib.rs @@ -20,7 +20,7 @@ use extism_pdk::*; use nd_pdk::host::{artwork, scheduler}; use nd_pdk::scrobbler::{ - Error as ScrobblerError, IsAuthorizedRequest, IsAuthorizedResponse, NowPlayingRequest, + Error as ScrobblerError, IsAuthorizedRequest, NowPlayingRequest, ScrobbleRequest, Scrobbler, SCROBBLER_ERROR_NOT_AUTHORIZED, SCROBBLER_ERROR_RETRY_LATER, }; use nd_pdk::scheduler::{ @@ -104,18 +104,18 @@ fn get_image_url(track_id: &str) -> String { // ============================================================================ impl Scrobbler for DiscordPlugin { - fn is_authorized(&self, req: IsAuthorizedRequest) -> Result { + fn is_authorized(&self, req: IsAuthorizedRequest) -> Result { let (_, users) = match get_config() { Ok(config) => config, Err(e) => { error!("Failed to get config: {:?}", e); - return Ok(IsAuthorizedResponse { authorized: false }); + return Ok(false); } }; let authorized = users.contains_key(&req.username); info!("IsAuthorized for user {}: {}", req.username, authorized); - Ok(IsAuthorizedResponse { authorized }) + Ok(authorized) } fn now_playing(&self, req: NowPlayingRequest) -> Result<(), ScrobblerError> { diff --git a/plugins/examples/discord-rich-presence/main.go b/plugins/examples/discord-rich-presence/main.go index 37fddf88b..caefb3898 100644 --- a/plugins/examples/discord-rich-presence/main.go +++ b/plugins/examples/discord-rich-presence/main.go @@ -93,15 +93,15 @@ func getImageURL(trackID string) string { // ============================================================================ // IsAuthorized checks if a user is authorized for Discord Rich Presence. -func (p *discordPlugin) IsAuthorized(input scrobbler.IsAuthorizedRequest) (*scrobbler.IsAuthorizedResponse, error) { +func (p *discordPlugin) IsAuthorized(input scrobbler.IsAuthorizedRequest) (bool, error) { _, users, err := getConfig() if err != nil { - return nil, fmt.Errorf("failed to check user authorization: %w", err) + return false, fmt.Errorf("failed to check user authorization: %w", err) } _, authorized := users[input.Username] pdk.Log(pdk.LogInfo, fmt.Sprintf("IsAuthorized for user %s: %v", input.Username, authorized)) - return &scrobbler.IsAuthorizedResponse{Authorized: authorized}, nil + return authorized, nil } // NowPlaying sends a now playing notification to Discord. diff --git a/plugins/examples/webhook-rs/src/lib.rs b/plugins/examples/webhook-rs/src/lib.rs index 30c394855..a32c57ae4 100644 --- a/plugins/examples/webhook-rs/src/lib.rs +++ b/plugins/examples/webhook-rs/src/lib.rs @@ -14,7 +14,7 @@ use extism_pdk::{config, error, http, info, warn, HttpRequest}; use nd_pdk::scrobbler::{ - Error, IsAuthorizedRequest, IsAuthorizedResponse, NowPlayingRequest, ScrobbleRequest, + Error, IsAuthorizedRequest, NowPlayingRequest, ScrobbleRequest, Scrobbler, }; @@ -31,12 +31,12 @@ struct WebhookPlugin; impl Scrobbler for WebhookPlugin { /// Checks if a user is authorized. This plugin authorizes all users. - fn is_authorized(&self, req: IsAuthorizedRequest) -> Result { + fn is_authorized(&self, req: IsAuthorizedRequest) -> Result { info!( "Authorization check for user: {} ({})", req.username, req.user_id ); - Ok(IsAuthorizedResponse { authorized: true }) + Ok(true) } /// Handles now playing notifications. This plugin ignores them (webhooks only on scrobble). diff --git a/plugins/pdk/go/scrobbler/scrobbler.go b/plugins/pdk/go/scrobbler/scrobbler.go index 38fdc4cd5..10c8d946a 100644 --- a/plugins/pdk/go/scrobbler/scrobbler.go +++ b/plugins/pdk/go/scrobbler/scrobbler.go @@ -34,12 +34,6 @@ type IsAuthorizedRequest struct { Username string `json:"username"` } -// IsAuthorizedResponse is the response for authorization check. -type IsAuthorizedResponse struct { - // Authorized indicates whether the user is authorized to scrobble. - Authorized bool `json:"authorized"` -} - // NowPlayingRequest is the request for now playing notification. type NowPlayingRequest struct { // UserID is the internal Navidrome user ID. @@ -105,14 +99,14 @@ type TrackInfo struct { // all three functions: IsAuthorized, NowPlaying, and Scrobble. type Scrobbler interface { // IsAuthorized - IsAuthorized checks if a user is authorized to scrobble to this service. - IsAuthorized(IsAuthorizedRequest) (*IsAuthorizedResponse, error) + IsAuthorized(IsAuthorizedRequest) (bool, error) // NowPlaying - NowPlaying sends a now playing notification to the scrobbling service. NowPlaying(NowPlayingRequest) error // Scrobble - Scrobble submits a completed scrobble to the scrobbling service. Scrobble(ScrobbleRequest) error } // Internal implementation holders var ( - isAuthorizedImpl func(IsAuthorizedRequest) (*IsAuthorizedResponse, error) + isAuthorizedImpl func(IsAuthorizedRequest) (bool, error) nowPlayingImpl func(NowPlayingRequest) error scrobbleImpl func(ScrobbleRequest) error ) diff --git a/plugins/pdk/go/scrobbler/scrobbler_stub.go b/plugins/pdk/go/scrobbler/scrobbler_stub.go index 0849ac2c5..05b04716f 100644 --- a/plugins/pdk/go/scrobbler/scrobbler_stub.go +++ b/plugins/pdk/go/scrobbler/scrobbler_stub.go @@ -31,12 +31,6 @@ type IsAuthorizedRequest struct { Username string `json:"username"` } -// IsAuthorizedResponse is the response for authorization check. -type IsAuthorizedResponse struct { - // Authorized indicates whether the user is authorized to scrobble. - Authorized bool `json:"authorized"` -} - // NowPlayingRequest is the request for now playing notification. type NowPlayingRequest struct { // UserID is the internal Navidrome user ID. @@ -102,7 +96,7 @@ type TrackInfo struct { // all three functions: IsAuthorized, NowPlaying, and Scrobble. type Scrobbler interface { // IsAuthorized - IsAuthorized checks if a user is authorized to scrobble to this service. - IsAuthorized(IsAuthorizedRequest) (*IsAuthorizedResponse, error) + IsAuthorized(IsAuthorizedRequest) (bool, error) // NowPlaying - NowPlaying sends a now playing notification to the scrobbling service. NowPlaying(NowPlayingRequest) error // Scrobble - Scrobble submits a completed scrobble to the scrobbling service. diff --git a/plugins/pdk/rust/README.md b/plugins/pdk/rust/README.md index 36e645365..f020a87f2 100644 --- a/plugins/pdk/rust/README.md +++ b/plugins/pdk/rust/README.md @@ -34,7 +34,7 @@ The Scrobbler capability requires all methods to be implemented: ```rust use nd_pdk::scrobbler::{ - Error, IsAuthorizedRequest, IsAuthorizedResponse, + Error, IsAuthorizedRequest, NowPlayingRequest, ScrobbleRequest, Scrobbler, }; @@ -45,8 +45,8 @@ nd_pdk::register_scrobbler!(MyPlugin); struct MyPlugin; impl Scrobbler for MyPlugin { - fn is_authorized(&self, req: IsAuthorizedRequest) -> Result { - Ok(IsAuthorizedResponse { authorized: true }) + fn is_authorized(&self, req: IsAuthorizedRequest) -> Result { + Ok(true) } fn now_playing(&self, req: NowPlayingRequest) -> Result<(), Error> { diff --git a/plugins/pdk/rust/nd-pdk-capabilities/src/scrobbler.rs b/plugins/pdk/rust/nd-pdk-capabilities/src/scrobbler.rs index afa9ac724..72e5a2a7a 100644 --- a/plugins/pdk/rust/nd-pdk-capabilities/src/scrobbler.rs +++ b/plugins/pdk/rust/nd-pdk-capabilities/src/scrobbler.rs @@ -23,14 +23,6 @@ pub struct IsAuthorizedRequest { #[serde(default)] pub username: String, } -/// IsAuthorizedResponse is the response for authorization check. -#[derive(Debug, Clone, Default, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct IsAuthorizedResponse { - /// Authorized indicates whether the user is authorized to scrobble. - #[serde(default)] - pub authorized: bool, -} /// NowPlayingRequest is the request for now playing notification. #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -142,7 +134,7 @@ impl Error { /// all three functions: IsAuthorized, NowPlaying, and Scrobble. pub trait Scrobbler { /// IsAuthorized - IsAuthorized checks if a user is authorized to scrobble to this service. - fn is_authorized(&self, req: IsAuthorizedRequest) -> Result; + fn is_authorized(&self, req: IsAuthorizedRequest) -> Result; /// NowPlaying - NowPlaying sends a now playing notification to the scrobbling service. fn now_playing(&self, req: NowPlayingRequest) -> Result<(), Error>; /// Scrobble - Scrobble submits a completed scrobble to the scrobbling service. @@ -157,7 +149,7 @@ macro_rules! register_scrobbler { #[extism_pdk::plugin_fn] pub fn nd_scrobbler_is_authorized( req: extism_pdk::Json<$crate::scrobbler::IsAuthorizedRequest> - ) -> extism_pdk::FnResult> { + ) -> extism_pdk::FnResult> { let plugin = <$plugin_type>::default(); let result = $crate::scrobbler::Scrobbler::is_authorized(&plugin, req.into_inner())?; Ok(extism_pdk::Json(result)) diff --git a/plugins/pdk/rust/nd-pdk/src/lib.rs b/plugins/pdk/rust/nd-pdk/src/lib.rs index 45d45e523..b1389938b 100644 --- a/plugins/pdk/rust/nd-pdk/src/lib.rs +++ b/plugins/pdk/rust/nd-pdk/src/lib.rs @@ -6,7 +6,7 @@ //! # Example //! //! ```rust,no_run -//! use nd_pdk::scrobbler::{Scrobbler, IsAuthorizedRequest, IsAuthorizedResponse, Error}; +//! use nd_pdk::scrobbler::{Scrobbler, IsAuthorizedRequest, Error}; //! use nd_pdk::register_scrobbler; //! //! struct MyPlugin; @@ -16,8 +16,8 @@ //! } //! //! impl Scrobbler for MyPlugin { -//! fn is_authorized(&self, req: IsAuthorizedRequest) -> Result { -//! Ok(IsAuthorizedResponse { authorized: true }) +//! fn is_authorized(&self, req: IsAuthorizedRequest) -> Result { +//! Ok(true) //! } //! // ... implement other required methods //! } diff --git a/plugins/scrobbler_adapter.go b/plugins/scrobbler_adapter.go index f7934aa52..928723842 100644 --- a/plugins/scrobbler_adapter.go +++ b/plugins/scrobbler_adapter.go @@ -45,12 +45,12 @@ func (s *ScrobblerPlugin) IsAuthorized(ctx context.Context, userId string) bool Username: username, } - result, err := callPluginFunction[capabilities.IsAuthorizedRequest, *capabilities.IsAuthorizedResponse](ctx, s.plugin, FuncScrobblerIsAuthorized, input) - if err != nil || result == nil { + result, err := callPluginFunction[capabilities.IsAuthorizedRequest, bool](ctx, s.plugin, FuncScrobblerIsAuthorized, input) + if err != nil { return false } - return result.Authorized + return result } // NowPlaying sends a now playing notification to the scrobbler diff --git a/plugins/testdata/test-scrobbler/main.go b/plugins/testdata/test-scrobbler/main.go index 93f8e5889..a40bd6329 100644 --- a/plugins/testdata/test-scrobbler/main.go +++ b/plugins/testdata/test-scrobbler/main.go @@ -17,10 +17,8 @@ func init() { type testScrobbler struct{} // IsAuthorized checks if a user is authorized. -func (t *testScrobbler) IsAuthorized(scrobbler.IsAuthorizedRequest) (*scrobbler.IsAuthorizedResponse, error) { - return &scrobbler.IsAuthorizedResponse{ - Authorized: checkAuthConfig(), - }, nil +func (t *testScrobbler) IsAuthorized(scrobbler.IsAuthorizedRequest) (bool, error) { + return checkAuthConfig(), nil } // NowPlaying sends a now playing notification.