From bc9c3eeb15cc9d9d262c810890688a3878abea6c Mon Sep 17 00:00:00 2001 From: Knut Ahlers Date: Thu, 28 Mar 2024 18:29:39 +0100 Subject: [PATCH] [spotify] Add `spotifyLink` template function Signed-off-by: Knut Ahlers --- docs/content/configuration/templating.md | 17 ++++++++++- internal/actors/spotify/client.go | 37 +++++++++++++++++------- internal/actors/spotify/spotify.go | 21 ++++++++++++-- 3 files changed, 62 insertions(+), 13 deletions(-) diff --git a/docs/content/configuration/templating.md b/docs/content/configuration/templating.md index 99ba5ef..21a9804 100644 --- a/docs/content/configuration/templating.md +++ b/docs/content/configuration/templating.md @@ -441,7 +441,7 @@ Example: ``` # Your int this hour: {{ printf "%.0f" (mulf (seededRandom (list "int" .username (now | date "2006-01-02 15") | join ":")) 100) }}% -< Your int this hour: 88% +< Your int this hour: 27% ``` ### `spotifyCurrentPlaying` @@ -459,6 +459,21 @@ Example: * Beast in Black - Die By The Blade ``` +### `spotifyLink` + +Retrieves the link for the playing track for the given channel + +Syntax: `spotifyLink ` + +Example: + +``` +! ^!spotifylink +> !spotifylink +# {{ spotifyLink .channel }} +* https://open.spotify.com/track/3HCzXf0lNpekSqsGBcGrCd +``` + ### `streamUptime` Returns the duration the stream is online (causes an error if no current stream is found) diff --git a/internal/actors/spotify/client.go b/internal/actors/spotify/client.go index 9ba6712..aa2dfb3 100644 --- a/internal/actors/spotify/client.go +++ b/internal/actors/spotify/client.go @@ -11,17 +11,17 @@ import ( "golang.org/x/oauth2" ) -func getCurrentTrackForChannel(channel string) (track string, err error) { +func getCurrentTrackForChannel(channel string) (track currentPlayingTrackResponse, err error) { channel = strings.TrimLeft(channel, "#") conf, err := oauthConfig(channel, "") if err != nil { - return "", fmt.Errorf("getting oauth config: %w", err) + return track, fmt.Errorf("getting oauth config: %w", err) } var token *oauth2.Token if err = db.ReadEncryptedCoreMeta(strings.Join([]string{"spotify-auth", channel}, ":"), &token); err != nil { - return "", fmt.Errorf("loading oauth token: %w", err) + return track, fmt.Errorf("loading oauth token: %w", err) } ctx, cancel := context.WithTimeout(context.Background(), spotifyRequestTimeout) @@ -29,12 +29,12 @@ func getCurrentTrackForChannel(channel string) (track string, err error) { req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://api.spotify.com/v1/me/player/currently-playing", nil) if err != nil { - return "", fmt.Errorf("creating currently-playing request: %w", err) + return track, fmt.Errorf("creating currently-playing request: %w", err) } resp, err := conf.Client(context.Background(), token).Do(req) if err != nil { - return "", fmt.Errorf("executing request: %w", err) + return track, fmt.Errorf("executing request: %w", err) } defer func() { if err := resp.Body.Close(); err != nil { @@ -48,18 +48,35 @@ func getCurrentTrackForChannel(channel string) (track string, err error) { } }() - var payload currentPlayingTrackResponse - if err = json.NewDecoder(resp.Body).Decode(&payload); err != nil { - return "", fmt.Errorf("decoding response: %w", err) + if err = json.NewDecoder(resp.Body).Decode(&track); err != nil { + return track, fmt.Errorf("decoding response: %w", err) + } + + return track, nil +} + +func getCurrentArtistTitleForChannel(channel string) (artistTitle string, err error) { + track, err := getCurrentTrackForChannel(channel) + if err != nil { + return "", fmt.Errorf("getting track info: %w", err) } var artistNames []string - for _, artist := range payload.Item.Artists { + for _, artist := range track.Item.Artists { artistNames = append(artistNames, artist.Name) } return strings.Join([]string{ strings.Join(artistNames, ", "), - payload.Item.Name, + track.Item.Name, }, " - "), nil } + +func getCurrentLinkForChannel(channel string) (link string, err error) { + track, err := getCurrentTrackForChannel(channel) + if err != nil { + return "", fmt.Errorf("getting track info: %w", err) + } + + return track.Item.ExternalUrls.Spotify, nil +} diff --git a/internal/actors/spotify/spotify.go b/internal/actors/spotify/spotify.go index d4dd643..e267005 100644 --- a/internal/actors/spotify/spotify.go +++ b/internal/actors/spotify/spotify.go @@ -32,7 +32,7 @@ func Register(args plugins.RegistrationArguments) (err error) { args.RegisterTemplateFunction( "spotifyCurrentPlaying", - plugins.GenericTemplateFunctionGetter(getCurrentTrackForChannel), + plugins.GenericTemplateFunctionGetter(getCurrentArtistTitleForChannel), plugins.TemplateFuncDocumentation{ Name: "spotifyCurrentPlaying", Description: "Retrieves the current playing track for the given channel", @@ -43,7 +43,24 @@ func Register(args plugins.RegistrationArguments) (err error) { Template: "{{ spotifyCurrentPlaying .channel }}", FakedOutput: "Beast in Black - Die By The Blade", }, - }) + }, + ) + + args.RegisterTemplateFunction( + "spotifyLink", + plugins.GenericTemplateFunctionGetter(getCurrentLinkForChannel), + plugins.TemplateFuncDocumentation{ + Name: "spotifyLink", + Description: "Retrieves the link for the playing track for the given channel", + Syntax: "spotifyLink ", + Example: &plugins.TemplateFuncDocumentationExample{ + MatchMessage: "^!spotifylink", + MessageContent: "!spotifylink", + Template: "{{ spotifyLink .channel }}", + FakedOutput: "https://open.spotify.com/track/3HCzXf0lNpekSqsGBcGrCd", + }, + }, + ) if err = args.RegisterAPIRoute(plugins.HTTPRouteRegistrationArgs{ Description: "Starts authorization of an Spotify Account for a {channel}",