hammerspoon icon indicating copy to clipboard operation
hammerspoon copied to clipboard

Spotify - save a song to the user's library

Open fharper opened this issue 6 years ago • 11 comments
trafficstars

It would be nice to add the save tracks feature to the Spotify available functions.

fharper avatar Jan 03 '19 22:01 fharper

Whilst certainly possible, the links you point to are referring the Web API, as opposed to the AppleScript API which the hs.spotify extension is currently using.

In the meantime, you could simply use hs.execute (or hs.task) to do something like this:

hs.execute([[curl -i -X PUT "https://api.spotify.com/v1/me/tracks" -H "Authorization: Bearer {your access token}" -H "Content-Type: application/json" --data "{ids:[\"4iV5W9uYEdYUVa79Axb7Rh\", \"1301WleyT98MSxVHPZCA6M\"]}"]]

latenitefilms avatar Jan 04 '19 11:01 latenitefilms

Thanks @latenitefilms

fharper avatar Jan 04 '19 19:01 fharper

I realize that this thread is over year old, but in case this is helpful -

Unfortunately, the Spotify osascript interface doesn't have access to this. I wanted a hotkey for this myself, so I spent a weekend solving this through a CLI-integration that handles OAuth integration / refreshing of auth tokens / lookup of current song with the Spotify API - all hooked up to a Hammerspoon hotkey.

Here is the golang CLI I wrote that does this:

  • https://github.com/drn/dots/blob/master/cli/bin/spotify/auth/root.go
  • https://github.com/drn/dots/blob/master/cli/bin/spotify/root.go
  • Usage: spotify [save|remove]?

Hammerspoon integration:

  • https://github.com/drn/dots/blob/master/hammerspoon/spotify.lua#L123

I haven't yet extracted this out of my dotfiles into a standalone CLI. If there is interest, just let me know and I can make it available

drn avatar Apr 30 '20 23:04 drn

I reckon you could probably archive the same thing you've done in Go with Lua in Hammerspoon?

latenitefilms avatar May 09 '20 00:05 latenitefilms

Yes, definitely feasible.

If anyone is interested in writing the Lua logic into Hammerspoon - the complexity lies in the user needing to set up a Spotify developer OAuth application & needs to follow the OAuth authorization code callback flow to exchange a code for an access token and a refresh token. After that, tokens can be refreshed automatically using a cached refresh token. I handled it with CLI prompts and by adding a callback endpoint to my homepage, but I'm sure there are cleaner ways of doing this — like setting up a local server and capturing the callback data directly like the Github CLI does.

drn avatar May 09 '20 01:05 drn

I'm just starting to explore Hammerspoon and was also looking to save/remove the currently playing song.

After some digging, I found that the keyboard shortcut to save/remote the currently playing song to the library is Option+Shift+B. I haven't used AppleScript, but would this be easier to add to the Spotify extension compared to using the Web API?

manojkarthick avatar Dec 29 '21 22:12 manojkarthick

@manojkarthick — thanks for flagging that! Here's some AppleScript that does exactly that:

activate application "Spotify"
tell application "System Events"
  keystroke "b" using {option down, shift down}
end tell

Unfortunately, this requires that the application must be activated (in the forefront). So, hooking this up to a hotkey would result in the Spotify application coming to the forefront every time it's pressed. I don't know of a way to send hotkeys to an application without activating it first if the application doesn't expose that functionality in its AppleScript library. If anyone knows how to do that, then please let me know!

The simplest thing would be for Spotify to expose the Like / Unlike as part of its AppleScript library, but alas — that's not in my control.

Separately, I found an easier way to go about this. You can install spotify-tui and hook into the commands spt playback --like and spt playback --dislike commands triggered by a HS binding via os.execute(...). It still requires hooking into the Spotify API and authorizing an OAuth application, but the CLI looks to be well maintained.

drn avatar Dec 29 '21 22:12 drn

Having to activate the application definitely makes the shortcut not as useful.

Thanks a lot for the tip regarding spotify-tui @drn - this is awesome! I just tried it using my developer account and it seems to be pretty seamless.

manojkarthick avatar Dec 29 '21 22:12 manojkarthick

In THEORY, you should be able to use hs.eventtap.keyStroke(modifiers, character[, delay, application]) to send a keystroke to a specific application, even if it's not the active application.

latenitefilms avatar Dec 29 '21 22:12 latenitefilms

Holy shit @latenitefilms @manojkarthick — that worked! This is why I love Hammerspooon.

  local app = hs.application.find("com.spotify.client")
  hs.eventtap.keyStroke({"option", "shift"}, "b", app)

It looks like we can't explicitly trigger a "like" or "dislike", but this for sure solves the toggling use-case.

drn avatar Dec 29 '21 23:12 drn

Amazing 💯 - Thanks @drn @latenitefilms!

manojkarthick avatar Dec 29 '21 23:12 manojkarthick