Spotify Chrome Extension: Music Controller | Phase 5
Tags: programming, react, javascript, webdev
Published: 2020-12-15 16:32:02

### <center>Spotify Chrome Extension - Business Logic</center>

------------

### <center>This is Phase Five of a multi-phase project where we build a Spotify Chrome Extension powered by ReactJS that allows us to control the user's Spotify session</center>

### <center>Phase One can be found [here](https://dev.to/anobjectisa/spotify-chrome-extension-music-controller-phase-1-iki "here").</center>

------------

#### <center>This tutorial assumes you know how Google Chrome Extensions work. Learn more [here](https://dev.to/anobjectisa/how-to-build-a-chrome-extension-4oig "here").</center>

------------

![React-Chrome Spotify Controller](https://user-images.githubusercontent.com/58220766/102025333-26fc6b00-3d65-11eb-9d55-52f34dd40d0a.png)

### Let's start by [registering with the Spotify developer console.](https://developer.spotify.com/dashboard/)


#### The authorization flow we'll be using is called [AUTH FLOW WITH PKCE.](https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow-with-proof-key-for-code-exchange-pkce "AUTH")

We want to be able to refresh our token, so we'll be using the Authorization Code Flow with Proof Key.

There are three steps to this flow:

1. get an authorization code
2. get an access token using the authorization code
3. when our access token expires, refresh the token

-----------------

### We'll follow the instructions for getting an authorization code and construct the proper URI to request.

We'll handle all of this logic in the **background.js** of our extension.

Here, we're creating variables to hold all of the **parameters** for the **request URL**.

We bring all of this together in one long URL string (***oauth2_url***).

```
...
const CLIENT_ID = encodeURIComponent('<client_id from spotify console'),
RESPONSE_TYPE = encodeURIComponent('code'),
REDIRECT_URI = encodeURIComponent(chrome.identity.getRedirectURL()),
CODE_CHALLENDGE_METHOD = encodeURIComponent('S256'),
SCOPE = encodeURIComponent('user-modify-playback-state user-read-playback-state'),
SHOW_DIALOG = encodeURIComponent('true');
...

CODE_VERIFIER = rand_string().repeat('5');
const code_challenge = base64urlencode(await sha256(CODE_VERIFIER));
STATE = encodeURIComponent('meet' + rand_string());

const oauth2_url =
    `https://accounts.spotify.com/authorize
?client_id=${CLIENT_ID}
&response_type=${RESPONSE_TYPE}
&redirect_uri=${REDIRECT_URI}
&code_challenge_method=${CODE_CHALLENDGE_METHOD}
&code_challenge=${code_challenge}
&state=${STATE}
&scope=${SCOPE}
&show_dialog=${SHOW_DIALOG}`;
...
```

-----------------

### Let's trade in that authorization code for an access token.

We'll simply pass the **authorization code** using a **Fetch** call to the approprate URL.

```
return fetch('https://accounts.spotify.com/api/token', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: `client_id=${CLIENT_ID}&grant_type=authorization_code&code=${code}&redirect_uri=${chrome.identity.getRedirectURL()}&code_verifier=${CODE_VERIFIER}`
})
...
```

-----------------

### When our token expires, we request another token using a refresh token.

When we get our **access token**, we also get a **refresh token**.

With that **refresh token** we can request a new **access token**.

```
return fetch('https://accounts.spotify.com/api/token', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: `client_id=${CLIENT_ID}&grant_type=refresh_token&refresh_token=${REFRESH_TOKEN}`
})
```

-----------------

### Now that we have access to Spotify's API, we can start using it.

It's as simple as following the instructions in the API Docs.

[Pause the music.](https://api.spotify.com/v1/me/player/pause "pause")

[Play the music.](https://api.spotify.com/v1/me/player/play "play")
 
[Next track.](https://api.spotify.com/v1/me/player/next "next")

[Previous track.](https://api.spotify.com/v1/me/player/previous "previous")
 
[Current track details.](https://api.spotify.com/v1/me/player/currently-playing "current track")

##### Here's an example of how to use the API.

A function that **starts a music track** using the **PLAY** API.

Notice how we send the **access token** in the **header** of our **fetch** request.

```
function play () {
    return fetch(`https://api.spotify.com/v1/me/player/play`, {
        method: 'PUT',
        headers: {
            'Authorization': `Bearer ${ACCESS_TOKEN}`
        }
    })
        .then(res => {
            if (res.status === 204) {
                return 'success';
            } else {
                throw new Error('fail');
            }
        });
}
```

------------

### The rest of this tutorial just involves coding separate functions that handle the different API calls.

If you want to see how that's done see the **video tutorial below**.

#### In the next phase we're going to bring this whole project together.

We're going to merge the front-end and back-end.

You can find the source files for this Phase [here](https://github.com/an-object-is-a/project-1-spotify-controller-phase5 "here").

------------

#### <center>If you want a more in-depth guide, check out my full video tutorial on YouTube, **[An Object Is A](https://www.youtube.com/c/anobjectisa "An Object Is A")**.</center>

### <center>Build a Cyberpunk 2077-inspired Spotify Controller - Phase 5</center>

{% youtube -3FRc4tQD6c %}