Skip to content

Instantly share code, notes, and snippets.

@eric
Last active December 25, 2015 17:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eric/7012296 to your computer and use it in GitHub Desktop.
Save eric/7012296 to your computer and use it in GitHub Desktop.
Pipe all messages from BlueBox customer chat into Campfire
# Description:
# Providing ways to interact with bluebox
#
# Commands:
# hubot bluebox chat on - Enable chat transcripts
# hubot bluebox chat off - Disable chat trascripts
#
# Dependencies:
# "cookie": "0.1.0"
# "cheerio": "0.12.3"
#
cookie = require('cookie')
querystring = require('querystring')
cheerio = require('cheerio')
module.exports = (robot) ->
class BlueBoxChat
constructor: (@username, @password) ->
login: (cb) ->
if @cookies
if cb then cb()
return
data =
'person[username]': @username
'person[password]': @password
robot.http("https://boxpanel.bluebox.net/public")
.post(querystring.stringify(data)) (err, res, body) =>
if err
robot.logger.error "Failed to login: #{err}\n#{err.stack}"
return
robot.logger.info "Output from login: #{body}"
if res.headers && res.headers['set-cookie']
robot.logger.info "Logged in to bluebox as '#{@username}'"
@cookies = res.headers["set-cookie"].map (c) ->
c.split(/[;,] */)[0]
.join("; ")
if cb then cb()
messages: (cb) ->
@login =>
robot.http('https://boxpanel.bluebox.net/public/bp/chat?get=messages')
.header('Accept', 'application/json')
.header('Cookie', @cookies)
.post(' ') (err, res, body) =>
if err
robot.logger.error "Failed to fetch messages: #{err}"
return
if res.statusCode != 200
robot.logger.error "Failed to fetch messages: #{body}"
@cookies = null
return
cb @parseMessages(body)
parseMessages: (messages) ->
parse = (u, msg) ->
$ = cheerio.load(msg)
[ time, sender, content ] = [ $('.time').text(), $('.sender').text(), $('.content').text() ]
id = $('div').attr('id').replace("message-", "")
m = if sender == ":"
"#{time} #{content}"
else
"#{time} #{sender} #{content}"
[ id, m ]
lines = []
for line in messages.split(/\n/)
if line.indexOf("new Insertion.Bottom") != -1
parsed = eval(line.replace(/^.*new Insertion.Bottom/, "parse"))
lines.push parsed
lines
class RoomMonitor
constructor: (@client) ->
@lastSeenId = 0
@maxIdle = 30 * 60 * 1000 # 30 minutes
@rooms = {}
addRoom: (response) ->
if @rooms[response.envelope.room]
return false
else
@rooms[response.envelope.room] = response
@start()
return true
removeRoom: (response) ->
if @rooms[response.envelope.room]
delete @rooms[response.envelope.room]
if @rooms.length == 0
@stop()
return true
else
return false
handle: (messages) =>
paste = []
for [ id, message ] in messages
robot.logger.info "handle_message: id=#{id} last_seen_id=#{@lastSeenId} message=#{message}"
if id > @lastSeenId
@lastSeenId = id
@lastSeenAt = new Date()
paste.push message
if paste.length > 0
robot.logger.info "sending_paste: paste=#{paste}"
@say(paste.join("\n") + "\n")
if @isExpired()
@close()
@say "[bluebox] Stopped monitoring after not seeing new messages for #{@maxIdleInMinutes()} minutes"
isActive: -> @intervalId?
maxIdleInMinutes: ->
Math.round(@maxIdle / 60 / 1000)
say: (message) ->
for _, response of @rooms
response.send message
start: ->
if !@isActive()
@lastSeenAt = new Date()
@client.messages(@handle)
@intervalId = setInterval((=> @client.messages(@handle)), 5000)
stop: ->
if @isActive()
clearInterval(@intervalId)
@intervalId = undefined
isExpired: ->
sinceLastMessage = new Date() - @lastSeenAt
sinceLastMessage > @maxIdle
username = process.env.BLUEBOX_USERNAME
password = process.env.BLUEBOX_PASSWORD
if username && password
monitor = new RoomMonitor(new BlueBoxChat(username, password))
robot.respond /bluebox chat (off|stop|done|cancel)/i, (msg) ->
if monitor
if monitor.removeRoom(msg)
msg.send "[bluebox] Stopped monitoring of bluebox chat"
else
msg.send "[bluebox] Not monitoring bluebox chat"
else
msg.send "[bluebox] No credentials have been specified"
robot.respond /bluebox chat (on|start|begin|engage|me)/i, (msg) ->
if monitor
if monitor.addRoom(msg)
msg.send "[bluebox] Starting to monitor bluebox chat"
else
msg.send "[bluebox] Monitor of bluebox chat already running"
else
msg.send "[bluebox] No credentials have been specified"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment