[spotify] Add spotifyLink template function

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2024-03-28 18:29:39 +01:00
parent bb83c34344
commit bc9c3eeb15
Signed by: luzifer
SSH key fingerprint: SHA256:/xtE5lCgiRDQr8SLxHMS92ZBlACmATUmF1crK16Ks4E
3 changed files with 62 additions and 13 deletions

View file

@ -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: {{ 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` ### `spotifyCurrentPlaying`
@ -459,6 +459,21 @@ Example:
* Beast in Black - Die By The Blade * Beast in Black - Die By The Blade
``` ```
### `spotifyLink`
Retrieves the link for the playing track for the given channel
Syntax: `spotifyLink <channel>`
Example:
```
! ^!spotifylink
> !spotifylink
# {{ spotifyLink .channel }}
* https://open.spotify.com/track/3HCzXf0lNpekSqsGBcGrCd
```
### `streamUptime` ### `streamUptime`
Returns the duration the stream is online (causes an error if no current stream is found) Returns the duration the stream is online (causes an error if no current stream is found)

View file

@ -11,17 +11,17 @@ import (
"golang.org/x/oauth2" "golang.org/x/oauth2"
) )
func getCurrentTrackForChannel(channel string) (track string, err error) { func getCurrentTrackForChannel(channel string) (track currentPlayingTrackResponse, err error) {
channel = strings.TrimLeft(channel, "#") channel = strings.TrimLeft(channel, "#")
conf, err := oauthConfig(channel, "") conf, err := oauthConfig(channel, "")
if err != nil { if err != nil {
return "", fmt.Errorf("getting oauth config: %w", err) return track, fmt.Errorf("getting oauth config: %w", err)
} }
var token *oauth2.Token var token *oauth2.Token
if err = db.ReadEncryptedCoreMeta(strings.Join([]string{"spotify-auth", channel}, ":"), &token); err != nil { 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) 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) req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://api.spotify.com/v1/me/player/currently-playing", nil)
if err != 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) resp, err := conf.Client(context.Background(), token).Do(req)
if err != nil { if err != nil {
return "", fmt.Errorf("executing request: %w", err) return track, fmt.Errorf("executing request: %w", err)
} }
defer func() { defer func() {
if err := resp.Body.Close(); err != nil { 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(&track); err != nil {
if err = json.NewDecoder(resp.Body).Decode(&payload); err != nil { return track, fmt.Errorf("decoding response: %w", err)
return "", 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 var artistNames []string
for _, artist := range payload.Item.Artists { for _, artist := range track.Item.Artists {
artistNames = append(artistNames, artist.Name) artistNames = append(artistNames, artist.Name)
} }
return strings.Join([]string{ return strings.Join([]string{
strings.Join(artistNames, ", "), strings.Join(artistNames, ", "),
payload.Item.Name, track.Item.Name,
}, " - "), nil }, " - "), 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
}

View file

@ -32,7 +32,7 @@ func Register(args plugins.RegistrationArguments) (err error) {
args.RegisterTemplateFunction( args.RegisterTemplateFunction(
"spotifyCurrentPlaying", "spotifyCurrentPlaying",
plugins.GenericTemplateFunctionGetter(getCurrentTrackForChannel), plugins.GenericTemplateFunctionGetter(getCurrentArtistTitleForChannel),
plugins.TemplateFuncDocumentation{ plugins.TemplateFuncDocumentation{
Name: "spotifyCurrentPlaying", Name: "spotifyCurrentPlaying",
Description: "Retrieves the current playing track for the given channel", Description: "Retrieves the current playing track for the given channel",
@ -43,7 +43,24 @@ func Register(args plugins.RegistrationArguments) (err error) {
Template: "{{ spotifyCurrentPlaying .channel }}", Template: "{{ spotifyCurrentPlaying .channel }}",
FakedOutput: "Beast in Black - Die By The Blade", 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 <channel>",
Example: &plugins.TemplateFuncDocumentationExample{
MatchMessage: "^!spotifylink",
MessageContent: "!spotifylink",
Template: "{{ spotifyLink .channel }}",
FakedOutput: "https://open.spotify.com/track/3HCzXf0lNpekSqsGBcGrCd",
},
},
)
if err = args.RegisterAPIRoute(plugins.HTTPRouteRegistrationArgs{ if err = args.RegisterAPIRoute(plugins.HTTPRouteRegistrationArgs{
Description: "Starts authorization of an Spotify Account for a {channel}", Description: "Starts authorization of an Spotify Account for a {channel}",