音楽再生履歴からおすすめを通知するdiscord bot
公開日:
経緯
普段通勤中など音楽を聞くときは、youtube musicもしくはnavidrome(実際にはAndroid用subsonicクライアントアプリのsymfonium)を使って聞いている。
YTMに関しては勝手におすすめしてきたり年次の振り返り機能だとか色々あって面白いけど、navidromeに関しては特にそういう機能があるわけではない。
そもそも既存のライブラリを再生するソフトだからレコメンドされたところでよほど恐ろしい規模のライブラリでもなければあまりうれしい結果は得られなさそう。(一応プラグインで良さそうなものも見つけたけど事前の楽曲のスキャンがめっちゃ大変そうで触ってない)
本当はその辺のレコメンド結果から自動でダウンロードして、みたいな方法も無くはないが勿論法律的にアウト。
そうじゃなくとも、YTMでおすすめされるものは勿論YTMの再生履歴にだけ基づくもの。どうにかYTMとnavidrome両方の再生履歴を反映させたレコメンドエンジン的なものを用意できないかとなんとなく考えていた。
そんな折、ふと思い出してスマホの買い替え以来再設定していなかったlast.fmへのscrobbleを再開しようとした所でこれ使えばいいじゃんねと考え作業を開始。
last.fmはいい感じのレコメンドAPIが無いのを作業開始時点で知ったためListenBrainzへもscrobbleするようにし、両方をソースにするように構想。claude codeとn8nを仕事の間にしばいて作った。
完成したもの

毎朝こんな感じでDiscordに4曲ずつおすすめが届くようになった。
1曲ごとに、こんな情報が載っている。
- なぜおすすめされたのか(「○○に似たアーティスト(Last.fm類似度85%)」「ListenBrainz「Weekly Exploration」より」など)
- last.fmでの自分の再生回数(YTMで聴いたことはあるけどNavidromeには無い曲なのか、まだ聴いていない曲なのか)
- タグ、アルバム名、ジャケット画像
- YouTube Music、YouTube、last.fmへのリンク
構想
おすすめされた後にやりたいのはYTMで聞くかあるいはレンタルCDやototoy、bandcampやboothで購入したりといった事になるが、まぁ後ろの方はちょっと面倒そうなので一旦YTMの検索リンクだけとかで考えてみよう。
また、既にnavidromeのライブラリに含まれてるものをおすすめされてもあまり嬉しくないからざっくりで良いからフィルタして欲しい。
そうなると、ざっくりこんなフローで考えてみよう。
おすすめ楽曲収集ワークフロー
- 一日一回トリガー
- scrobble先の2つから、おすすめを拾う
- listenbrainzは毎週おすすめプレイリストを出してくれるからそこから見るのが良さそう
- last.fmは工夫が必要かも
- 拾ってきたおすすめ楽曲が自前のnavidromeライブラリに含まれていない事を確認
- 未所持のものだけおすすめ用楽曲としてストックしていく
ストックから通知するワークフロー
- 一日一回トリガー
- おすすめストックからランダムに選ぶ
- discord webhookで通知
実装
上の構想をclaude codeに投げては生ゴミが出力されては罵倒してを繰り返して出来上がったのはn8nのワークフロー3本とData Table2つ。
- 在庫更新ワークフロー:毎日5:00におすすめ候補を集め、未所持の曲をストックする
- Last.fm呼び出しワークフロー:在庫更新から呼ばれるサブワークフロー。Last.fm APIをゆっくり1件ずつ叩く
- 通知ワークフロー:毎日8:00にストックから4曲選んでDiscordに投げる
- DB
music_stock:通知待ちのおすすめ曲 - DB
music_notified:通知済みの曲。同じ曲を二度おすすめしないために使う
仕組みのざっくり要約
- ListenBrainz
- おすすめを返すAPIがちゃんとあるので、自分向けのおすすめプレイリスト(Weekly Exploration)と協調フィルタリングの推薦をそのまま使う
- Last.fm
- Web版にはおすすめ機能があるのに、公開APIにはおすすめを返すメソッドが無い。代わりに「似ているもの」を返すAPIがあるので、よく聴くアーティスト・曲をシードにして、類似アーティストの人気曲と類似曲をたどっておすすめを組み立てる。構想で「工夫が必要かも」と書いた部分はこうなった
- 集めた候補はLast.fmで自分の再生回数を補完する。YTMの分もscrobbleされているので、「YTMでは聴いてるけどNavidromeには無い曲」と「まだ聴いていない曲」を区別できる
- Navidromeに同じ曲があるかはSubsonic APIで曲名検索して判定する。表記ゆれがあるので判定はざっくり
外部APIを叩くわけだから、ちゃんとお行儀よくエラーハンドリングしたりレートリミットに気を付けようねせやね。
使ってみて
通知が届くようになって10日くらい経つけど、正直まだこれ経由で実際に聴いたりはしていない。たまに眺めるくらい。
ここから聞くのが習慣になるまではかなり時間がかかりそう。

