Skip to content

Instantly share code, notes, and snippets.

@kylefritz
Last active October 23, 2015 14:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kylefritz/ef730240047ee0cd176a to your computer and use it in GitHub Desktop.
Save kylefritz/ef730240047ee0cd176a to your computer and use it in GitHub Desktop.
Control Squeezebox Through Hubot [Must be a firmware version pre "UE Smart Radio"; e.g. must work with http://www.mysqueezebox.com]
# Description:
# Allows Hubot to control pandora on a squeezebox music player.
# Also plays a generic internet radio station via play.
#
# Dependencies:
# none
#
# Configuration:
# SQUEEZE_BOX_EMAIL (for mysqueezebox.com)
# SQUEEZE_BOX_PASSWORD
# SQUEEZE_BOX_PLAYER_ID (MAC address)
#
# Commands:
# hubot pandorame <artist, song, etc> - plays on pandora
# hubot pause|play
# hubot vol <positive or negative #> - changes volume
# hubot crankit|indoor voices - volume presets
# hubot who's playing? - lists station, artist, song
# hubot thumbsup|thumbsdown - relay preferences to pandora
# hubot add station <station name> <station url> - add internet radio station
# hubot stations - list add internet radio stations
# hubot play <station name> - play add internet radio station
#
# Notes:
# you must:
# have accounts on both mysqueezebox.com & pandora
# have the pandora app installed on squeezebox
# be signed into your pandora account on mysqueezebox.com#
#
# Author:
# kylefritz
#
Sqzbx = require 'sqzbx'
_ = require 'underscore'
module.exports = (robot) ->
queueup = (msg, what) ->
Sqzbx.playing = true
Sqzbx.lastRequest = what
robot.logger.info "pandorame #{what}"
Sqzbx.queueup(msg, what, queueupResp(msg,what))
robot.respond /(queue ?up|pandora ?me) (.+)/i, (msg) ->
what = msg.match[2]
queueup(msg,what)
robot.respond /pause/i, (msg) ->
Sqzbx.playing = false
Sqzbx.cmd msg, ["pause"]
msg.send "lips are sealed"
robot.respond /play$/i, (msg) ->
Sqzbx.playing = true
Sqzbx.cmd msg, ["play"]
msg.send "resuming jam"
robot.respond /foghorn ?me/i, (msg) ->
soundEffect(msg, "loop://content.mysqueezebox.com/static/sounds/effects/foghorn.mp3", "Foghorn")
robot.respond /play?me (.*)/i, (msg) ->
Sqzbx.cmd msg, ['playlist','play', msg.match[1], "Custom Station"]
robot.respond /vol \+?(\-?\d+)/i, (msg) ->
Sqzbx.vol(msg,parseInt(msg.match[1]))
msg.send "commencing volume adjustment"
robot.respond /crank ?it/i, (msg) ->
Sqzbx.vol(msg,100)
msg.send "oh hell yeah"
robot.respond /indoor voices|quiet|shut ?up|silent|silence/i, (msg) ->
Sqzbx.vol msg,-100, () ->
Sqzbx.vol(msg,40)
msg.send "what do you work at a library?"
robot.respond /wh(o|at)'?s ?(playing|this)/i, (msg) ->
Sqzbx.artist(msg, artistResp(msg))
robot.respond /who (th|d)(at|is)( i(s|z))?/i, (msg) ->
Sqzbx.artist(msg, artistResp(msg))
robot.respond /\(?thumbsup\)?/i,(msg) ->
Sqzbx.cmd msg, ["pandora","rate",1]
msg.send "glad you like it"
robot.respond /5 bobs|five bobs|5 bob|5 bobs/i,(msg) ->
Sqzbx.cmd msg, ["pandora","rate",1]
msg.send "glad you like it"
robot.respond /yuck|\(?thumbsdown\)?/i,(msg) ->
Sqzbx.cmd msg, ["pandora","rate",0]
msg.send "seriously! who put that on?"
robot.respond /1 bob|1 bobs|one bob|one bobs/i,(msg) ->
Sqzbx.cmd msg, ["pandora","rate",0]
msg.send "seriously! who put that on?"
robot.respond /stations/i, (msg) ->
msg.send """play phish radio
play dead radio
play floyd radio
let's do acid
talking heads mode
p-funk mode
hipster mode
gangster mode
katy perry mode
jazz mode
chill mode
rickroll
shake it off
pandorame <whatever>
Create your own! https://github.com/orderup/hubot/blob/master/scripts/squeezebox.coffee"""
robot.respond /play phish ?radio/i, (msg) ->
stream(msg, 'http://radio.nugs.net:8002')
msg.send "You're about to blast off!"
robot.respond /play dead ?radio/i, (msg) ->
stream(msg, 'http://smoke.wavestreamer.com:8148')
msg.send "Don't tell me this town ain't got no heart"
robot.respond /play floyd ?radio/i, (msg) ->
stream(msg, 'http://smoke.wavestreamer.com:9307')
msg.send "Shine on you crazy diamond"
robot.respond /let's do acid/i, (msg) ->
stream(msg, 'http://206.190.150.90:8459')
msg.send "Yeah man"
robot.respond /talking heads ?mode/i, (msg) ->
queueup(msg, 'the talking heads')
msg.send "Let's stop making sense"
robot.respond /p-?funk ?mode/i, (msg) ->
queueup(msg, 'pfunk')
msg.send "Let's make our funk the p-funk"
robot.respond /hipst(er|a) ?mode/i, (msg) ->
queueup(msg, 'mgmt')
msg.send "Put a bird on it."
robot.respond /gangst(er|a) ?mode/i, (msg) ->
queueup(msg, 'jay-z')
msg.send "You got it."
robot.respond /kat(y|ie) perry ?mode/i, (msg) ->
queueup(msg, 'katy perry')
msg.send "LOL OMG"
robot.respond /jazz ?mode/i, (msg) ->
queueup(msg, 'john coltrane')
msg.send "Right on."
robot.respond /chill ?mode/i, (msg) ->
queueup(msg, 'the xx')
msg.send "I hear ya."
robot.respond /rickroll/i, (msg) ->
queueup(msg, 'rick astley')
msg.send "love that guy."
robot.respond /shake it off/i, (msg) ->
queueup(msg, 'taylor swift')
msg.send "haters gonna hatehatehatehatehate"
anthems = [
"http://s3.amazonaws.com/jmj/ludacris_stand_up.mp3", # luda, 10000ms
"http://s3.amazonaws.com/jmj/Get_Up_Stand_Up.mp3" # bob, 13000ms
]
robot.respond /stand ?up/i, (msg) ->
soundEffect(msg, msg.random(anthems), "Time for dev stand up meeting", 13000)
msg.send "Let's hangout! https://plus.google.com/hangouts/_/orderup.com/daily-standup?authuser=0"
robot.respond /love you/i, (msg) ->
soundEffect(msg, "http://a.clyp.it/zia1gzmm.mp3", "Love you galpal!", 3000)
robot.respond /enable now playing/i, (msg) ->
robot.logger.info "enabling now playing"
robot.brain.set('nowPlayingEnabled', true)
# define a function that will call itself again in 60 seconds
updateNowPlaying = ->
robot.logger.info "Getting now playing info from squeezebox"
Sqzbx.artist msg, (result) ->
t = result.remoteMeta
if t.title and t.artist and t.album
updatedNowPlaying = "Now playing: \"#{t.title}\" by #{t.artist} from #{t.album} on #{result.current_title}"
else
updatedNowPlaying = "Now playing: #{result.current_title}"
robot.logger.info "currentNowPlaying: #{robot.brain.get('nowPlaying')}"
robot.logger.info "updatedNowPlaying: #{updatedNowPlaying}"
if robot.brain.get('nowPlaying') != updatedNowPlaying
robot.logger.info "now playing has changed, sending msg"
robot.brain.set('nowPlaying', updatedNowPlaying)
msg.send updatedNowPlaying
else
robot.logger.info "now playing has not changed, not sending msg"
if robot.brain.get('nowPlayingEnabled')
robot.logger.info "now playing is enabled, will check again in a minute"
setTimeout updateNowPlaying, 60000
else
robot.logger.info "now playing is enabled, will check again in a minute"
# Let's get this party started
updateNowPlaying()
robot.respond /disable now playing/i, (msg) ->
robot.logger.info "disabling now playing"
robot.brain.set('nowPlayingEnabled', false)
#start the url with loop:// instead of http://
stream = (msg, url) ->
Sqzbx.cmd msg, ['playlist', 'play', url]
soundEffect = (msg, url, name, lengthMilliseconds=10000) ->
Sqzbx.cmd msg, ['playlist', 'play', url, name]
_.delay(resume(msg), lengthMilliseconds)
resume = (msg) ->
() ->
if Sqzbx.playing
Sqzbx.cmd msg, ["pause"]
msg.send "Returning to #{Sqzbx.lastRequest}"
Sqzbx.queueup(msg, Sqzbx.lastRequest, queueupResp(msg, Sqzbx.lastRequest))
artistResp = (msg) ->
(result) ->
t = result.remoteMeta
if t.artist
msg.send "\"#{t.title}\" by #{t.artist} from #{t.album} @ #{result.current_title}"
msg.send "#{t.artwork_url}"
else
msg.send "playing #{result.current_title}"
queueupResp = (msg,what) ->
(err,res,body) ->
if body.match(/No items found./)
msg.send "no dice. couldn't find \"#{what}\"."
else if body.match(/Max station limit reached/)
msg.send "lux lyke u gawta dlt sum stayshunz furzt dawg"
msg.send "https://gist.github.com/kylefritz/5372921"
else
hits = body.match(/selectorMarker/g).length
if hits == 1 or what[what.length - 1] == '0'
Sqzbx.artist msg, artistResp(msg)
else
msg.send "got #{hits} hits for #{what}, trying first"
Sqzbx.queueup msg, "#{what}.0", queueupResp(msg, "#{what}.0")
module.exports =
login: (client, cb) ->
enc = encodeURIComponent
data = "email=#{enc(process.env.SQUEEZE_BOX_EMAIL)}&password=#{enc(process.env.SQUEEZE_BOX_PASSWORD)}"
client.http("http://mysqueezebox.com/user/login")
.header("content-length",data.length)
.header("Content-Type","application/x-www-form-urlencoded")
.post(data) (err,res,body) ->
setString = res.headers['set-cookie'][0]
#dirty split
squeeze_session = setString.split('; ')[0].split('=')[1]
cookie = "Squeezebox-player=#{enc(process.env.SQUEEZE_BOX_PLAYER_ID)}; sdi_squeezenetwork_session=#{squeeze_session}"
cb(cookie)
auth: () ->
user = process.env.SQUEEZE_BOX_EMAIL
pass = process.env.SQUEEZE_BOX_PASSWORD
auth = 'Basic ' + new Buffer(user + ':' + pass).toString('base64')
cmd: (client, what, cb) ->
data =
"id": 1,
"method": "slim.request",
"params": [process.env.SQUEEZE_BOX_PLAYER_ID,what]
json = JSON.stringify(data)
client.http("http://50.79.0.117:9000/jsonrpc.js")
.header("content-type","application/json")
.header("content-length",json.length)
.headers(Authorization: @auth(), Accept: 'application/json')
.post(json) (err,res,body) ->
cb(err,res,body) if cb?
queueup: (client, what, cb) ->
url = "http://mysqueezebox.com/plugins/pandora/index.html?index=1_#{encodeURIComponent(what)}&player=00%3A13%3Aef%3A60%3A22%3A63&sess="
client.http(url)
.headers(Authorization: @auth(), Accept: 'application/json')
.get() (err,res,body) ->
cb(err,res,body)
artist: (client, cb) ->
@cmd client, ["status","-",1,"tags:cgABbehldiqtyrSuoKLN"], (err,res,body) ->
result = JSON.parse(body).result
cb(result) if result
vol: (client, amt, cb) ->
delt = if amt > 0 then "+" else ""
change = "#{delt}#{amt}"
@cmd client, ["mixer","volume",change], cb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment