セットプチフォッカ

勉強したアウトプット、ときどきフォッカチオ作っていました

spotifyのプレイリストを自動で作るnpm(recommendify)を作った

f:id:ikmbear:20211017210157p:plain 少し前にフィヨルドブートキャンプの課題でspotifyのプレイリストを自動作成してくれるnpm:recommendifyを作ったので、紹介します。

何を作ったの?

以下の4つの質問に答えると、それにあったSpotifyのプレイリストを作成してくれるnpmです(15曲入っています)。

  1. 最近聴いた曲から1~3曲
  2. 曲の明るさ
  3. アーティストの人気度
  4. 曲のBPM

recommendify - npm

f:id:ikmbear:20211017204037g:plain

どうして作ったの?

Spotifyのプレミアムプランに契約して、まあまあ曲は聴いているし、毎日使っているんですが、ついつい同じ曲を選んでしまうんですよね
自分で探しに行けばいいんですけど、Spotifyの検索画面ってジャンルを選ぶと人気の曲が出てくるので、結局最近聴いた曲ばっか出てきてしまう...。

そこで「いっそのことプログラムに勝手にプレイリストを作らせてしまえばいいのでは」と思い、本npmを作成するに至りました。

どうやって使うの?

recommendify - npmにも記載がありますが、一応日本語でも記載しておきます。

Spotifyアカウントを持っていることが前提になります。

前準備

  1. Spotifyの開発者ダッシュボードにログインする

developer.spotify.com

  1. 「CREATE AN APP」を選択する。App nameとApp descriptionに適当な値を入れてチェックをし、「CREATE」を選択する

f:id:ikmbear:20211017204403p:plain

  1. 「EDIT SETTING」を開き、コールバックURLにhttp://localhost:8888/callbackを設定する

f:id:ikmbear:20211017204541p:plain

  1. クライアントIDとクライアントシークレットを控えておく

f:id:ikmbear:20211017204628p:plain

実行

  1. recommendifyをインストールする
% npm i -g recommendify
  1. 以下のコマンドを実行し、クライアントIDとシークレットを入力して、トークンの取得を行う
% recommendify settoken

f:id:ikmbear:20211017204810p:plain

  1. これでrecommendifyが実行可能になります!プレイリストを作成しましょう!
% recommendify

工夫したところは?

曲をどうやって選出するかですね。

SpotifyのWebAPIでは結構いろいろなパラメータがあって、最初はそれらを全部選べるようにもしようかと思ったのですが、ランダムな曲を選ぶのにパラメータをいくつも選ぶのはいかがなものかと思いまして、現在の形に至りました。

ガチャを回すので4手くらいが限界かなあと。

あとは一応同じ選択肢を選んでもランダムになるように、曲にはシャッフルをかけています(一応SpotifyAPIは同じパラメータだと同じ内容を返すように見えましたが、登録されている曲のリストが変われはその限りではないとも思っています)。

難しかったところは?

アクセストークンが切れた場合のリフレッシュ処理に少し苦労しました。

Spotifyのアクセストークンはたしか1時間くらいで切れてしまうのですが、切れるたびにエラーになってはストレスなので、confというnpmを使ってリフレッシュトークンをローカルに保存し、アクセス時にトークンの有効期限が切れていれば、アクセストークンの再取得を行うようにしました。

const callApi = (func, argumentArray) => {
  return (async function callSpotifyApi (retryCounter = 1) {
    try {
      return await func.apply(spotifyApi, argumentArray)
    } catch (error) {
      if (error.body.error.status === 401 && retryCounter) {
        await refreshAccessToken()
        return await callSpotifyApi(retryCounter - 1)
      }
      throw new Error(error)
    }
  }())
}

github.com

とはいっても、何回もリトライすると無限ループに陥る可能性があるので、再帰処理として実装しつつも、複数回は実行しないようにする部分に結構頭を使いました。

おわりに

個人的に結構気に入っているアプリです(本当はWebアプリとして実装できたらいいんですが...)。
皆さんもぜひダウンロードしてみてください。