/spotify-huddle

Primary LanguageJavaScriptMIT LicenseMIT

Spotify Huddle

This is a kinda monorepo for Spotify Huddle, a remote-work Spotify streaming bot for Slack's Huddles feature.

It consists of 3 core components:

  • playback-client - A super basic node server for a HTML file which does the actual playback via Spotify's Web Player SDK

  • puppeteer-bot - A basic puppeteer-managed instance that launches the playback-client and launches Slack, joining/leaving huddles as needed.

  • slackbot - A Slack Bolt Framework app for controling the Spotify Instance + managing playback, backed by the Spotify REST API.

Disclaimer

This isn't the most polished codebase in the world, it was put together in around a day with the intent of demonstrating an idea, and as such isn't the best code and has little documentation.

But it works well for it's intended purpose!

Getting Started

Environment Setup.

You're going to need somewhere to run the bot, this is pretty entirely up to you.

In my case, I deployed a Linux (Ubuntu) VM onto Google Cloud Platform via Google Compute Engine, following the steps here to give me a mechanism of remotely accessing the UI for debugging purposes https://cloud.google.com/architecture/chrome-desktop-remote-on-compute-engine

I also installed Google Chrome, Node.JS and Yarn.

Audio Routing

Wherever you deploy the bot, you're going to need some form of virtual audio interface. In my case, I use pulseaudio.

My setup was fairly simple:

Pulseaudio Setup

I wrote this basic audio startup script that would initialise pulseaudio with the virtual devices I needed.

Worth noting that as I'd installed Chrome Remote Desktop on the instance, I noticed that it was always the default audio output, no matter what I tried. So I made the best of this situation and used it, rather than creating my own virtual output.

My script simply:

  • Creates a new monitor of the remote-desktop audio output (sink)
  • Creates a virtual audio source from this monitor
  • Sets the remote-desktop output as the default
  • Sets the virtual source as the default

The bash script is as follows

pacmd set-default-source chrome_remote_desktop_session.monitor

pacmd load-module module-virtual-source source_name=chrome_remote_desktop_session

pacmd set-default-sink chrome_remote_desktop_session

pacmd set-default-source chrome_remote_desktop_session.monitor

Dependencies

All dependencies are managed through Yarn, a 'yarn' in the root will install all necessary dependencies.

Configuration

This repo includes a template.env file which details the required credentials/information needed.

You will need to:

  • Create an 'App' in the Slack Developer Dashboard and register it to your 'workspace' that supports huddles
  • Create an 'App' in the Spotify Developer Dashboard

In the instance of chrome that the bot will be using, you need to log-into a Slack user that the bot can use to join the huddles.

In my case, I created a single-channel guest account for the bot such that it wouldn't have access to any other channels.

You will need to expose a public endpoint for the app, once this is available, plug into the PUBLIC_EP env variable & add to the Slack app config. As we're using bolt, any request urls need to be added as https://{endpoint}/slack/events.

Running it

One command brings the entire app up, simply run the following

EXECUTABLE=/usr/bin/google-chrome yarn start

Feel free to swap that path for your google chrome instance.

Usage

Authentication

The bot will now let you sign into a spotify account, just launch the slack channel the bot is added to and run /spotify-login - it'll return a button that you can click to authorize access to use your spotify subscription.

Commands

Slack slash commands are as follows:

  • /play {song name here}
  • /search-spotify {song name here}
  • /play
  • /pause
  • /now-playing
  • /skip

Contributing

I'm open to pull-requests on this repo, equally please feel-free to fork/remix this as much as you'd like.

I'm not really sure where this is going, but eager to share early in spite of it not being the most polished codebase!