2022年01月30日 (日)

Spotify APIでやりたいことができなかった

Spotifynoriyu.dev

Spotify APIを使って、こんなことを考えてました。

「自分のトップソングを自動で更新して、それをnoriyu.devに表示したいな〜」

でも、できないことがわかりました。

Spotify APIを簡単に紹介


以下、spotifyの公式ドキュメントをgoogle翻訳したものです。

単純なREST原則に基づいて、Spotify Web APIエンドポイントは、音楽アーティスト、アルバム、トラックに関するJSONメタデータをSpotifyデータカタログから直接返します。
Web APIは、ユーザーがYourMusicライブラリに保存するプレイリストや音楽などのユーザー関連データへのアクセスも提供します。このようなアクセスは、ユーザーによる選択的な承認によって有効になります。
WebAPIのベースアドレスはhttps://api.spotify.comです。APIは、それぞれが独自のパスを持つ一連のエンドポイントを提供します。ユーザープロファイルやプレイリストなどのWebAPIを介してプライベートデータにアクセスするには、アプリケーションはデータにアクセスするためのユーザーの許可を取得する必要があります。承認はSpotifyアカウントサービスを介して行われます。


spotifyで公開されている音楽やプレイリストだけでなく、ユーザー固有の情報も取得することができます。

その中でもGet User's Top Items というAPIがあり、ユーザーのアクセストークンを使えばここ数ヶ月によく聞いているアーティストの情報を取得することができます。

リクエスト

curl -X "GET" "https://api.spotify.com/v1/me/top/artists" \
-H "Accept: application/json" 
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${access_token}


レスポンス

{
  "items": [
    {
      "external_urls": {
        "spotify": "https://open.spotify.com/artist/2IUl3m1H1EQ7QfNbNWvgru"
      },
      "followers": {
        "href": null,
        "total": 616649
      },
      "genres": [
        "j-pop",
        "japanese soul"
      ],
      "href": "https://api.spotify.com/v1/artists/2IUl3m1H1EQ7QfNbNWvgru",
      "id": "2IUl3m1H1EQ7QfNbNWvgru",
      "images": [],
      "name": "Vaundy",
      "popularity": 73,
      "type": "artist",
      "uri": "spotify:artist:2IUl3m1H1EQ7QfNbNWvgru"
    },
   ...
    }


このデータを使えば、普段spotifyを勝手に使っているだけで勝手に自分のお気に入りソングが更新され続けるのではないかと思ったわけです。

しかし、ダメでした。

アクセストークンの扱い


アクセストークンの有効期限は60分と決まっています。ドキュメント

{
   "access_token": "NgCXRKc...MzYjw",
   "token_type": "bearer",
   "expires_in": 3600
}


なので更新し続ける仕組みにしないといけません。

access_tokenは以下のリクエストで取得することができました。参考

axios({
        url: 'https://accounts.spotify.com/api/token',
        method: 'post',
        params: {
          grant_type: 'client_credentials'
        },
        headers: {
          'Accept':'application/json',
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        auth: {
          username: 'YOUR-CLIENT-ID',
          password: 'YOUR-CLIENT-SECRET'
        }
      }).then(function(response) {
          console.log(response);
      }).catch(function(error) {
      });


実際にaccess_tokenは取得できたし、そのトークンでいくつかのAPIを利用することができました。
ただし、Get User's Top Items では使えませんでした。。。

スコープが必要

ユーザー固有のデータは機密情報なのでアクセストークンを取得する際にスコープを指定する必要がありました。
例えばGet User's Top Itemsではuser-top-readが必要です。参考

で、このスコープはtokenを取得する前にSpotifyにログインして連携する必要があります。
こちらのサイトがとても参考になりました。

Spotifyにログイン



noriyu.devでは自分の曲を表示するだけなので、ユーザーにログインしてもらう必要はありません。
つまり、自分が定期的にログインしてaccess_tokenをリフレッシュする必要がありそうです。

結論

なんとかならないかもう少し試行錯誤する。

現状、どうにもなりそうにないので自分のプレイリストをiframeで埋め込むだけにしました。
https://noriyu.dev/spotify