Last active
December 25, 2015 17:19
-
-
Save eric/7012296 to your computer and use it in GitHub Desktop.
Pipe all messages from BlueBox customer chat into Campfire
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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