Spotify Developer Platform: Spotify APIアクセスしてデータ取得してみてみた

[Spotify](https://ja.wikipedia.org/wiki/Spotify)は2019年現在、2億3,200万人(うち有料会員数1億800万人)のユーザー音楽配信サービスとしては世界最大手で、5000万以上の音楽やコンテンツが揃っていて、ドライブ、エクササイズ、パーティやリラックスタイムなどに、気分に合った音楽、また、友達、アーティストが作ったプレイリストを聴いたりできます。

そんなSpotifyでは Developer Platformが用意されており、Web API、AndroidやiOS向けのSDKなどがあるので、Play ListやTrackに関する詳細な分析データをAPIアクセスしてデータ取得し分析できます。
ということで、この取得したデータをOracle Databaseへ入れて、Analytics, Machine Learning, BIなどData Scienceしてみてみたいので、まずはAPIアクセスしてデータ取得してみてみます。

 ・参考: [Spotify Developer Platform](https://developer.spotify.com/?_ga=2.178253217.584830429.1585551511-1189686145.1585131365)

ここで必要な技術は、Node.js, JavaScript, Curl, Python, JSONなどです。
ということでやってみてみます。


# ■ Spotify Developers アプリケーション作成

[Web API Tutorial](https://developer.spotify.com/documentation/web-api/quick-start/)を参考に、Node.JSで作成した Spotify API へ認証アクセスするための access Tokenを 取得し,Play List情報をJSONデータで取得してみてみます


## ● Spotify Developers ユーザー作成とログイン
Spotify Developers ユーザー作成とログイン
### 1) Spotify Developers ユーザー作成
まず、[Spotify Developersサイト](https://developer.spotify.com/dashboard/)へアクセスし、Sign up for a free Spotify account here.をクリックして、ユーザーアカウントを作成

<img width="1440" alt="01_Login.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109087/566bd1a4-e5ad-631f-de2e-4688bbe74c25.png">


### 2) Spotify Developers ログイン
作成したユーザーでログイン

<img width="659" alt="02_Login.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109087/3be1c4c8-e504-ccba-c741-11787354efea.png">

## ● Register Your Application
### 1) CREATE A CLIENT ID
ClientプログラムでアクセスするためのClient IDを作成
[CREATE A CLIENT ID]をクリック
<img width="1086" alt="03_Login.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109087/4ac496d9-a812-1dcf-7b48-3ac9bc3d20c5.png">



### 2) CREATE AN APP OR HARDWARE INTEGRATION Step 1/3
REATE AN APP OR HARDWARE INTEGRATION画面で必要情報を入力し[NEXT]をクリック
<img width="1074" alt="04_Login.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109087/98f202cc-26e1-e81b-e659-c14dd75818bd.png">




### 3) CREATE AN APP OR HARDWARE INTEGRATION Step 2/3
ここでは商用利用ではないので、[NON-COMMERCIAL]をクリック
<img width="330" alt="05_Login.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109087/530859be-5fc7-7071-6013-c895b6ea77d0.png">


### 4) CREATE AN APP OR HARDWARE INTEGRATION Step 4/3
確認事項を確認し了承した内容にチェックを入れて、[SUBMIT]をクリック
<img width="331" alt="06_Login.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109087/163f9f00-bff9-0e67-ec14-763f697cfeae.png">


## ● App Settings 
### 1) Application(Spotify-demo01)画面
ApplicationをRegisterするとこの画面になり、[EDIT SETTING]をクリック
ここでは、Spotify-demo01という名前で作成しました
<img width="1435" alt="07_Login.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109087/902a6e0a-a43f-547b-73a0-ac2c90e5d1fe.png">

API アクセスするための Client ID と Client Secret を確認

 - Client ID: d9ef929bnjoierg8820bsvkeoi9bo9
 - Client Secret: 18308i390dfb829ves89238erv8932
 


### 2) EDIT SETTINGS画面
アクセスするには、Redirect URIが必要なので、ここでは、Node.jsサーバーのIP(100.100.100.100)でアクセスできるように Redirect URIs項に、 http://100.100.100.100:8888/callback/ を入力
<img width="1078" alt="08_login_修正.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109087/de344445-e8b2-4b74-2db4-6f366a6bd8e2.png">


リダイレクトURIに、Spotifyでホワイトリストに登録するアドレスを1つ以上入力します。 
このURIにより、OAuth 2.0によるユーザー認証がされます。
ということで、このURI用のサーバーをNode.jsで作成します。

・参考： 
　- [Authorization Guide](https://developer.spotify.com/documentation/general/guides/authorization-guide/)
　- [Web API Tutorial](https://developer.spotify.com/documentation/web-api/quick-start/)

## ● Node.jsインストール
### 1) Node.jsインストール
yumでode.jsをインストール

```shell-session
[opc@tokyo-inst01 〜]$ sudo yum install nodejs
    読み込んだプラグイン:langpacks, ulninfo
    依存性の解決をしています
    --> トランザクションの確認を実行しています。
    ---> パッケージ nodejs.x86_64 1:6.17.1-1.el7 を インストール
    --> 依存性の処理をしています: npm = 1:3.10.10-1.6.17.1.1.el7 のパッケージ: 1:nodejs-6.17.1-1.el7.x86_64
    --> 依存性の処理をしています: libuv >= 1:1.9.1 のパッケージ: 1:nodejs-6.17.1-1.el7.x86_64
    --> 依存性の処理をしています: libuv.so.1()(64bit) のパッケージ: 1:nodejs-6.17.1-1.el7.x86_64
    --> トランザクションの確認を実行しています。
    ---> パッケージ libuv.x86_64 1:1.34.0-1.el7 を インストール
    ---> パッケージ npm.x86_64 1:3.10.10-1.6.17.1.1.el7 を インストール
    --> 依存性解決を終了しました。

    依存性を解決しました

    ========================================================================================================
    Package         アーキテクチャー
                                    バージョン                           リポジトリー                 容量
    ========================================================================================================
    インストール中:
    nodejs          x86_64          1:6.17.1-1.el7                       ol7_developer_EPEL          4.7 M
    依存性関連でのインストールをします:
    libuv           x86_64          1:1.34.0-1.el7                       ol7_developer_EPEL          143 k
    npm             x86_64          1:3.10.10-1.6.17.1.1.el7             ol7_developer_EPEL          2.5 M

    ・・・

        インストール:
        git.x86_64 0:1.8.3.1-21.el7_7

        依存性関連をインストールしました:
        perl-Error.noarch 1:0.17020-2.el7                    perl-Git.noarch 0:1.8.3.1-21.el7_7
        perl-TermReadKey.x86_64 0:2.30-20.el7

        完了しました!
```

### 2) web-api-auth-examplesインストール
GitHubリポジトリからOAuthサンプルを GitHub: [spotify/web-api-auth-examples](https://github.com/spotify/web-api-auth-examples)からインストール

```shell-session
[opc@tokyo-inst01 spotify]$ git clone https://github.com/spotify/web-api-auth-examples
    Cloning into 'web-api-auth-examples'...
    remote: Enumerating objects: 112, done.
    remote: Total 112 (delta 0), reused 0 (delta 0), pack-reused 112
    Receiving objects: 100% (112/112), 27.26 KiB | 0 bytes/s, done.
    Resolving deltas: 100% (41/41), done.
```

・ web-api-auth-examplesディレクトリ作成確認

```shell-session
[opc@tokyo-inst01 spotify]$ ls
    web-api-auth-examples
```


### 3) npmインストール
OAuthサンプルのコードは、express、request、およびquerystringパッケージに依存します。
 作成したフォルダー内に次のコマンドを実行して依存関係をインストールします！

```shell-session
[opc@tokyo-inst01 spotify]$ cd web-api-auth-examples/
[opc@tokyo-inst01 web-api-auth-examples]$ ls
    LICENSE  README.md  authorization_code  client_credentials  implicit_grant  package.json
[opc@tokyo-inst01 web-api-auth-examples]$ npm install
        npm WARN deprecated request@2.83.0: request has been deprecated, see https://github.com/request/request/issues/3142
        npm WARN deprecated hawk@6.0.2: This module moved to @hapi/hawk. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues.
        npm WARN deprecated cryptiles@3.1.4: This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).
        npm WARN deprecated boom@4.3.1: This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).
        npm WARN deprecated sntp@2.1.0: This module moved to @hapi/sntp. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues.
        npm WARN deprecated hoek@4.2.1: This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).
        npm WARN deprecated boom@5.2.0: This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).
        web-api-auth-examples@0.0.2 /home/opc/spotify/web-api-auth-examples
        ├─┬ cookie-parser@1.3.2
        │ ├── cookie@0.1.2
        │ └── cookie-signature@1.0.4
        ├─┬ cors@2.8.5
        │ ├── object-assign@4.1.1
        │ └── vary@1.1.2
        ├─┬ express@4.16.4
        │ ├─┬ accepts@1.3.7
        │ │ └── negotiator@0.6.2
        │ ├── array-flatten@1.1.1
        │ ├─┬ body-parser@1.18.3
        │ │ ├── bytes@3.0.0
        │ │ ├─┬ http-errors@1.6.3
        │ │ │ └── inherits@2.0.3
        │ │ ├─┬ iconv-lite@0.4.23
        │ │ │ └── safer-buffer@2.1.2
        │ │ └── raw-body@2.3.3
        │ ├── content-disposition@0.5.2
        │ ├── content-type@1.0.4
        │ ├── cookie@0.3.1
        │ ├── cookie-signature@1.0.6
        │ ├─┬ debug@2.6.9
        │ │ └── ms@2.0.0
        │ ├── depd@1.1.2
        │ ├── encodeurl@1.0.2
        │ ├── escape-html@1.0.3
        │ ├── etag@1.8.1
        │ ├─┬ finalhandler@1.1.1
        │ │ └── unpipe@1.0.0
        │ ├── fresh@0.5.2
        │ ├── merge-descriptors@1.0.1
        │ ├── methods@1.1.2
        │ ├─┬ on-finished@2.3.0
        │ │ └── ee-first@1.1.1
        │ ├── parseurl@1.3.3
        │ ├── path-to-regexp@0.1.7
        │ ├─┬ proxy-addr@2.0.6
        │ │ ├── forwarded@0.1.2
        │ │ └── ipaddr.js@1.9.1
        │ ├── qs@6.5.2
        │ ├── range-parser@1.2.1
        │ ├── safe-buffer@5.1.2
        │ ├─┬ send@0.16.2
        │ │ ├── destroy@1.0.4
        │ │ └── mime@1.4.1
        │ ├── serve-static@1.13.2
        │ ├── setprototypeof@1.1.0
        │ ├── statuses@1.4.0
        │ ├─┬ type-is@1.6.18
        │ │ └── media-typer@0.3.0
        │ └── utils-merge@1.0.1
        ├── querystring@0.2.0
        └─┬ request@2.83.0
        ├── aws-sign2@0.7.0
        ├── aws4@1.9.1
        ├── caseless@0.12.0
        ├─┬ combined-stream@1.0.8
        │ └── delayed-stream@1.0.0
        ├── extend@3.0.2
        ├── forever-agent@0.6.1
        ├─┬ form-data@2.3.3
        │ └── asynckit@0.4.0
        ├─┬ har-validator@5.0.3
        │ ├─┬ ajv@5.5.2
        │ │ ├── co@4.6.0
        │ │ ├── fast-deep-equal@1.1.0
        │ │ ├── fast-json-stable-stringify@2.1.0
        │ │ └── json-schema-traverse@0.3.1
        │ └── har-schema@2.0.0
        ├─┬ hawk@6.0.2
        │ ├── boom@4.3.1
        │ ├─┬ cryptiles@3.1.4
        │ │ └── boom@5.2.0
        │ ├── hoek@4.2.1
        │ └── sntp@2.1.0
        ├─┬ http-signature@1.2.0
        │ ├── assert-plus@1.0.0
        │ ├─┬ jsprim@1.4.1
        │ │ ├── extsprintf@1.3.0
        │ │ ├── json-schema@0.2.3
        │ │ └─┬ verror@1.10.0
        │ │   └── core-util-is@1.0.2
        │ └─┬ sshpk@1.16.1
        │   ├── asn1@0.2.4
        │   ├── bcrypt-pbkdf@1.0.2
        │   ├── dashdash@1.14.1
        │   ├── ecc-jsbn@0.1.2
        │   ├── getpass@0.1.7
        │   ├── jsbn@0.1.1
        │   └── tweetnacl@0.14.5
        ├── is-typedarray@1.0.0
        ├── isstream@0.1.2
        ├── json-stringify-safe@5.0.1
        ├─┬ mime-types@2.1.26
        │ └── mime-db@1.43.0
        ├── oauth-sign@0.8.2
        ├── performance-now@2.1.0
        ├── stringstream@0.0.6
        ├─┬ tough-cookie@2.3.4
        │ └── punycode@1.4.1
        ├── tunnel-agent@0.6.0
        └── uuid@3.4.0

        npm WARN web-api-auth-examples@0.0.2 No repository field.
        npm WARN web-api-auth-examples@0.0.2 No license field.
```

## ● index.html作成
Web rootディレクトリ authorization_codeへindex.htmlファイルを設定

### 1) Web rootディレクトリ authorization_codeへ移動

```shell-session
[opc@tokyo-inst01 web-api-auth-examples]$ cd authorization_code
[opc@tokyo-inst01 authorization_code]$ pwd
    /home/opc/spotify/web-api-auth-examples/authorization_code
[opc@tokyo-inst01 authorization_code]$ ls
    app.js  app.js.org  public
```

### 2) index.htmlファイル設定
[Web API Tutorial](https://developer.spotify.com/documentation/web-api/quick-start/)におるように以下内容を設定


```shell-session
[opc@tokyo-inst01 authorization_code]$ vi index.html
    <html>
    <head>
    ...
    <style type="text/css">
    #login {
        display: none;
    }

    #loggedin {
        display: none;
    }
    ...
    </style>
    <body>
    <div>
        <div id="login">
        <h1>First, log in to spotify</h1>
        <a href="/login">Log in</a>
        </div>
        <div id="loggedin">
        </div>
    </div>

    <script id="loggedin-template" type="text/x-handlebars-template">
        <h1>Logged in as </h1>
        <img id="avatar" width="200" src="" />
        <dl>
        <dt>Display name</dt><dd></dd>
        <dt>Username</dt><dd></dd>
        <dt>Email</dt><dd></dd>
        <dt>Spotify URI</dt><dd><a href=""></a></dd>
        <dt>Link</dt><dd><a href=""></a></dd>
        <dt>Profile Image</dt><dd></dd>
        </dl>
        <p><a href="/">Log in again</a></p>
    </script>
    </body>
    </html>
```

## ● Provide the Application Credentials
app.jsファイルには、アプリケーションのメインコードが含まれおり、
Spotify Developersで作成したアプリケーションの'CLIENT_ID,'CLIENT_SECRET','REDIRECT_URI' 情報を設定します。


    ・app.jsファイル設定箇所
        var client_id = 'CLIENT_ID'; // Your client id
        var client_secret = 'CLIENT_SECRET'; // Your secret
        var redirect_uri = 'REDIRECT_URI'; // Your redirect uri


また、このファイルにはユーザーアクセス制御を許可する scope データーもあります。

```shell
// your application requests authorization
var scope = 'user-read-private user-read-email';
```

これは、アプリがユーザーのフルネーム、プロフィール画像、メールアドレスへのアクセスをすることができることを意味します。
プレイリストへ追加する(playlist-modify-public)などの権限を追加する場合は、次のドキュメントを参考に scope へ追加

・参考: [Authorization Scopes](https://developer.spotify.com/documentation/general/guides/scopes/)





### ・ app.jsファイル設定
ということで、'CLIENT_ID', 'CLIENT_SECRET, 'REDIRECT_URI'部分を代入変更します。

```shell-session
[opc@tokyo-inst01 authorization_code]$ vi app.js
    /**
    * This is an example of a basic node.js script that performs
    * the Authorization Code oAuth2 flow to authenticate against
    * the Spotify Accounts.
    *
    * For more information, read
    * https://developer.spotify.com/web-api/authorization-guide/#authorization_code_flow
    */

    ・・・

    var client_id = 'e15bfd0dccb54db5a1757b'; // Your client id
    var client_secret = 'e17644952de94c6baebef'; // Your secret
    var redirect_uri = 'http://100.100.100.100:8888/callback'; // Your redirect uri
    ・・・

    // your application requests authorization
    var scope = 'user-read-private user-read-email';
    ・・・
```

# ■ Running the Application
設定した Node.jsアプリケーションを起動し、Spotifyへ認証アクセスするためのAccess tokenを取得します


### 1) 設定した Node.jsアプリケーションを起動

```shell-session
[opc@tokyo-inst01 authorization_code]$ node app.js
    Listening on 8888
```


### 2) Node.jsアプリケーションのURLへアクセス
設定したURL http://100.100.100.100:8888  へWebブラウザでアクセス
<img width="1073" alt="11_8888.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109087/c32ea0c9-a3c7-c2ab-870a-7fd8e6bec7f6.png">

### 3) ログイン
[Log in with Spotify]をクリック


### 4) Access Token取得
ログインすると Access tokenが出力されます。
これを使用して、Spotifyへ認証アクセスして、Play Listやアーティスト情報を取得します。
<img width="1072" alt="12_8888.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109087/0a008a98-c0bd-d09c-28d8-2db374f61a6f.png">


# ■ テスト：Play Listデータ取得
Play List「Spotify Japan 急上昇チャート」の情報を取得してみています。
・Spotify Japan 急上昇チャート: https://open.spotify.com/playlist/37i9dQZF1DX9vYRBO9gjDe
<img width="1174" alt="21_急上昇チャート.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109087/f9882838-c1d0-4ad0-5d3b-c4fe1e8289b3.png">

### 1) Play list ID取得
APIリファレンス: [API ENDPOINT REFERENCE](https://developer.spotify.com/documentation/web-api/reference/)を参考にPlay List情報を取得

例) エンドポイントに以下「id」を指定する必要があります
　　- playlists：/v1/playlists/{playlist_id}/tracks
　　- partists：/v1/artists/{id}/albums

「id」は以下になります。
　　・プレイリスト例：Sporify Japan 急上昇チャート: https://open.spotify.com/playlist/37i9dQZF1DX9vYRBO9gjDe 
　　　　-->「37i9dQZF1DX9vYRBO9gjDe」がプレイリストid
　　・アーティスト例：チャイコフスキー: https://open.spotify.com/artist/3MKCzCnpzw3TjUYs2v7vDA
　　　　-->3MKCzCnpzw3TjUYs2v7vDA 」がアーティストidになります。



### 2) Access token確認とPlay List取得Curl作成
上記Node.jsアプリケーションで取得した、Access token: BQDQMF8bDTWt2vBFTRaI0bbIL5RIXlc-wIO5yRWtTzLyBKHsGUEbs1-668aBJ3bIRYpdZnKT...を
以下Curl文の<Access token>へ代入

```html
curl -H "Authorization: Bearer <Access token>" https://api.spotify.com/v1/playlists/37i9dQZF1DX9vYRBO9gjDe/tracks
```




### 3) 実行
作成したcurl実行しPlay Listデータを取得
データはJSONで出力されます

```json
[opc@tokyo-inst01 ~]$ curl -H "Authorization: Bearer BQDQMF8bDTWt2vBFTRaI0bbIL5RIXlc-wIO5yRWtTzLyBKHsGUEbs1-668aBJ3bIRYpdZnKT..." https://api.spotify.com/v1/playlists/37i9dQZF1DX9vYRBO9gjDe/
    {
    "collaborative" : false,
    "description" : "Spotify Japanのデイリー急上昇チャート。4月1日付。",
    "external_urls" : {
        "spotify" : "https://open.spotify.com/playlist/37i9dQZF1DX9vYRBO9gjDe"
    },
    "followers" : {
        "href" : null,
        "total" : 148523
    },

    ・・・<省略>・・・

    } ],
    "limit" : 100,
    "next" : null,
    "offset" : 0,
    "previous" : null,
    "total" : 50
  },
  "type" : "playlist",
  "uri" : "spotify:playlist:37i9dQZF1DX9vYRBO9gjDe"
```

＼( ^o^ )／

ということで、今度はこの一連の処理を Python3で作成して実行してみてみます。
つづく・・・

また、取得したJSONデータを外部表アクセスしてSQLクエリーできることを確認してみたので、こちらも参考してみてください: [Oracle Database: Spotify APIで取得したJSONデータを外部表でSELECTしてみてみた](https://qiita.com/shirok/items/3fdb96683f02fcc6f31e)


# ■ 参考
## ● Spotify Developer
　・[Spotify Developer](https://developer.spotify.com/dashboard/applications/e5219d106e284c2a8ae0c408beb095e9)
　・[Web API Reference](https://developer.spotify.com/documentation/web-api/reference/)
　・[Web API Tutorial](https://developer.spotify.com/documentation/web-api/quick-start/)
　・[Authorization Guide](https://developer.spotify.com/documentation/general/guides/authorization-guide/)

## ● Git
　　- [spotify-web-api-node](https://github.com/thelinmichael/spotify-web-api-node#installation)
　　- [Spotify Charts](https://github.com/kelvingakuo/fycharts)

## ● Google Chormeプラグイン
　　- [Talend API Tester - Free Edition](https://chrome.google.com/webstore/detail/talend-api-tester-free-ed/aejoelaoggembcahagimdiliamlcdmfm/related)