Node.js
MacOSX
AppleScript
Slack
Spotify

Spotifyで聞いている音楽をSlackのStatusに表示させるアプリを作った

https://gyazo.com/51505a9647471452d7bc27492e0bf1d4

tl;dr

  • MacのSpotifyアプリで聞いている音楽情報をSlackのstatusに表示させる
  • SpotifyからデータとってくるところはAppleScriptを使った

元ネタ

iTunes版が以前紹介されてました。

iTunesで曲を聞くことはほぼなくなっていたので、Spotifyの再生情報をとってこれないかなーと考えていてAPIみてました。
Web APIをみても再生中の曲をとってくるやつはなさそうだったので断念していたのですが、Spotifyで再生中の曲をtmuxのステータスバーに表示するという記事が目について、AppleScript使えばできるってことがわかったのでやってみました。

Spotify版

ソースは以下になります。
https://github.com/iwata/nowplaying-on-slack

fork元ではplaybackを使ってiTunesの情報をとってきていた部分を、AppleScriptを使ってSpotifyの情報をとってくるように変更してます。
あと永続化のためにelectron使っていたのを、foreverでdaemonizeするようにしました。

AppleScript

bin/get-playing-on-spotify
#!/usr/bin/osascript

if application "Spotify" is running
  tell application "Spotify"
    set currentState to player state as string
    set currentArtist to artist of current track as string
    set currentTrack to name of current track as string
    return "{\"state\":\"" & currentState & "\", \"track\":\"" & currentTrack & "\", \"artist\":\"" & currentArtist & "\"}"
  end tell
else
  return "{\"error\":\"Spotify is not running.\"}"
end if

ドキュメントのサンプルコードをみてもらえば大体わかると思います。
このscriptをNodeからshell execしてあげるんですが、構造化されたデータをやりとりしたかったのでJSONを標準出力にだすことで実現しました。
AppleScriptでJSON書くのシンドイ…。

main.js

NodeでSpotifyのデータを処理してくる部分は以下。

const watchSpotify = () => {
  let before;

  setInterval(() => {
    exec(spotifyScript, (e, stdout, stderr) => {
      if (e) {
        console.error(e);
        return;
      }
      if (stderr) {
        console.error(stderr);
        return;
      }

      const m = JSON.parse(stdout);
      if ('error' in m) {
        console.error(m.error);
        return;
      }

      if (before === JSON.stringify(m)) {
        // console.log('not change');
        return;
      }
      before = JSON.stringify(m);
      const message = `${m.track} - ${m.artist}`;
      const emoji = (m.state === 'playing') ? ':spotify:' : ':musical_note:';
      sendToSlack({ message, emoji });
      console.log(m);
    });
  }, 3000);
};

playerの再生状態をもっているstateをみて、statusで使うemojiを切り替えてます。
Spotifyのカスタム絵文字を使うようにしているので、環境によっては使えないと思うので適宜変更してもらえればと思います。

実行

git clone git@github.com:iwata/nowplaying-on-slack.git
cd nowplaying-on-slack
yarn install
SLACK_API_TOKEN=[[token]] npm start

現場からは以上です。