Using Spotify Web API with Qt

Starting with Qt 5.8 the toolkit learned the to use OAuth2 to autheticate web services. I was interested to use this with the Spotify Web API.

Before, I was playing with the old Libspotify SDK, but its lifetime is limited. It is deprecated for years now and partially disabled – You can no longer create new application keys. There was also Qt wrapper QtLibSpotify, coded by some people by Digita Inc., which made the integration into Qt applications simple. I played with this classes, but nowadays it seems to make more sense to explore the recent web API. Unfortunately the community is still waiting for way to stream music.

This post will connect us to Spotify web API using the authorization code flow. The code can be fetched my Github repository.

Register your application at Spotify

To get the permission to connect to the Spotify API and work with the users data, we have to register the application on the developer site of Spotify. If you don’t have an account, register first.

Go to “My Applications” and register a new application.

Create an application at Spotify

After that you will get a client Id and a client secret. Both are required for the authorization code flow. The third thing is, that we have to register a callback URL. Unfortunately oauth is designed for web services and not for desktop applications. After the user gives us the permission to work with his data, Spotify calls a redirect URL which has to be registered. At this point Qt will help us and create an HTTP server in background to receive the token. Therefore the URL points to localhost, eg. http://localhost:8080/cb.

The authorization flow

In our main window class we have a member

QOAuth2AuthorizationCodeFlow spotify;

In the constructor of the main window we prepare our spotify object.

This is the class which does the magic in the background. It is the http server and the port must match the port of the registered callback.

auto replyHandler = new QOAuthHttpServerReplyHandler(8080, this);
spotify.setReplyHandler(replyHandler);

The Urls for authentication and fetching the auth token:

spotify.setAuthorizationUrl(QUrl("https://accounts.spotify.com/authorize"));
spotify.setAccessTokenUrl(QUrl("https://accounts.spotify.com/api/token"));

This are the two peaces from the registration process:

spotify.setClientIdentifier(clientId);
spotify.setClientIdentifierSharedKey(clientSecret);

This is the list of scopes, we want to access. The complete list is documented on the Spotify web API reference.

spotify.setScope("user-read-private user-top-read playlist-read-private playlist-modify-public playlist-modify-private");

After that we have to connect some signals. The first one opens the process and request the users permission. This is completely done on the Spotify web site. The users credentials are never exposed to our application.

connect(&spotify, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, 
        &QDesktopServices::openUrl);

This is mostly for information and show the steps during authentication

connect(&spotify, &QOAuth2AuthorizationCodeFlow::statusChanged,
        this, &MainWindow::authStatusChanged);

This connects to the granted signal, which says, that we are authenticated a can start with API calls.

connect(&spotify, &QOAuth2AuthorizationCodeFlow::granted, 
        this, &MainWindow::granted);

After doing this we can start the authentication with calling grant. In the example code this is done trough the menu. Calling grant will open the web browser, showing the Spotify page requesting the permission for our application. After the permission is granted the Spotify page redirects to the Callback URL, providing the temporary authorization code. This code is the exchanged to the access token. This is done internally in the QOAuth2AuthorizationFlow, which is very convenient.

Doing the first API call

After we have received the access token, we have the permission to do API calls. The first thing we need is more information about the user. Esp. the user name is needed to query the users playlists. This now straight forward. We do a get to the endpoint

https://api.spotify.com/v1/me

and receive a JSON Object with the data. After extracting the user name we request the playlists. The playlists are paginated and the default is to get only 20 playlist objects with one call. So further processing is not part of this example.

Links

Posted in Qt

Leave a Reply

Your email address will not be published. Required fields are marked *