|
| 1 | +Robot = require "robot" |
| 2 | +HTTPS = require "https" |
| 3 | +EventEmitter = require("events").EventEmitter |
| 4 | + |
| 5 | +class Campfire extends Robot |
| 6 | + send: (user, strings...) -> |
| 7 | + strings.forEach (str) => |
| 8 | + @bot.Room(user.room).speak str, (err, data) -> |
| 9 | + console.log "#{user}: #{str}" |
| 10 | + |
| 11 | + reply: (user, strings...) -> |
| 12 | + strings.forEach (str) => |
| 13 | + @send user, "#{user.name}: #{str}" |
| 14 | + |
| 15 | + run: -> |
| 16 | + self = @ |
| 17 | + options = |
| 18 | + token: process.env.HUBOT_CAMPFIRE_TOKEN |
| 19 | + rooms: process.env.HUBOT_CAMPFIRE_ROOMS |
| 20 | + account: process.env.HUBOT_CAMPFIRE_ACCOUNT |
| 21 | + |
| 22 | + console.log options |
| 23 | + bot = new CampfireStreaming(options) |
| 24 | + console.log bot |
| 25 | + |
| 26 | + bot.on "TextMessage", (id, created, room, user, body) -> |
| 27 | + if body.match new RegExp "^#{bot.info.name}", "i" |
| 28 | + bot.User user, (err, userData) -> |
| 29 | + self.receive( |
| 30 | + text: body |
| 31 | + user: { id: user, name: userData.user.name, room: room } |
| 32 | + ) |
| 33 | + |
| 34 | + bot.Me (err, data) -> |
| 35 | + console.log data |
| 36 | + bot.info = data.user |
| 37 | + bot.rooms.forEach (room_id) -> |
| 38 | + bot.Room(room_id).join (err, callback) -> |
| 39 | + bot.Room(room_id).listen() |
| 40 | + |
| 41 | + @bot = bot |
| 42 | + |
| 43 | +exports.Campfire = Campfire |
| 44 | + |
| 45 | +class CampfireStreaming extends EventEmitter |
| 46 | + constructor: (options) -> |
| 47 | + @token = options.token |
| 48 | + @rooms = options.rooms.split(",") |
| 49 | + @account = options.account |
| 50 | + @domain = @account + ".campfirenow.com" |
| 51 | + @authorization = "Basic " + new Buffer("#{@token}:x").toString("base64") |
| 52 | + |
| 53 | + Rooms: (callback) -> |
| 54 | + @get "/rooms", callback |
| 55 | + |
| 56 | + User: (id, callback) -> |
| 57 | + @get "/users/#{id}", callback |
| 58 | + |
| 59 | + Me: (callback) -> |
| 60 | + @get "/users/me", callback |
| 61 | + |
| 62 | + Room: (id) -> |
| 63 | + self = @ |
| 64 | + |
| 65 | + show: (callback) -> |
| 66 | + self.post "/room/#{id}", "", callback |
| 67 | + join: (callback) -> |
| 68 | + self.post "/room/#{id}/join", "", callback |
| 69 | + leave: (callback) -> |
| 70 | + self.post "/room/#{id}/leave", "", callback |
| 71 | + lock: (callback) -> |
| 72 | + self.post "/room/#{id}/lock", "", callback |
| 73 | + unlock: (callback) -> |
| 74 | + self.post "/room/#{id}/unlock", "", callback |
| 75 | + |
| 76 | + # say things to this channel on behalf of the token user |
| 77 | + paste: (text, callback) -> |
| 78 | + @message text, "PasteMessage", callback |
| 79 | + sound: (text, callback) -> |
| 80 | + @message text, "SoundMessage", callback |
| 81 | + speak: (text, callback) -> |
| 82 | + @message text, "TextMessage", callback |
| 83 | + message: (text, type, callback) -> |
| 84 | + body = { message: { "body":text, "type":type } } |
| 85 | + self.post "/room/#{id}/speak", body, callback |
| 86 | + |
| 87 | + # listen for activity in channels |
| 88 | + listen: -> |
| 89 | + headers = |
| 90 | + "Host" : "streaming.campfirenow.com", |
| 91 | + "Authorization" : self.authorization |
| 92 | + |
| 93 | + options = |
| 94 | + "host" : "streaming.campfirenow.com" |
| 95 | + "port" : 443 |
| 96 | + "path" : "/room/#{id}/live.json" |
| 97 | + "method" : "GET" |
| 98 | + "headers": headers |
| 99 | + |
| 100 | + request = HTTPS.request options, (response) -> |
| 101 | + response.setEncoding("utf8") |
| 102 | + response.on "data", (chunk) -> |
| 103 | + if chunk.match(/^\S+/) |
| 104 | + console.log "#{new Date}: Received #{id} \"#{chunk}\"" |
| 105 | + try |
| 106 | + chunk.split("\r").forEach (part) -> |
| 107 | + data = JSON.parse part |
| 108 | + |
| 109 | + self.emit data.type, data.id, data.created_at, data.room_id, data.user_id, data.body |
| 110 | + data |
| 111 | + |
| 112 | + response.on "end", -> |
| 113 | + console.log "Streaming Connection closed. :(" |
| 114 | + process.exit(1) |
| 115 | + |
| 116 | + response.on "error", (err) -> |
| 117 | + console.log err |
| 118 | + request.end() |
| 119 | + request.on "error", (err) -> |
| 120 | + console.log err |
| 121 | + console.log err.stack |
| 122 | + |
| 123 | + # Convenience HTTP Methods for posting on behalf of the token"d user |
| 124 | + get: (path, callback) -> |
| 125 | + @request "GET", path, null, callback |
| 126 | + |
| 127 | + post: (path, body, callback) -> |
| 128 | + @request "POST", path, body, callback |
| 129 | + |
| 130 | + request: (method, path, body, callback) -> |
| 131 | + headers = |
| 132 | + "Authorization" : @authorization |
| 133 | + "Host" : @domain |
| 134 | + "Content-Type" : "application/json" |
| 135 | + |
| 136 | + options = |
| 137 | + "host" : @domain |
| 138 | + "port" : 443 |
| 139 | + "path" : path |
| 140 | + "method" : method |
| 141 | + "headers": headers |
| 142 | + |
| 143 | + if method == "POST" |
| 144 | + if typeof(body) != "string" |
| 145 | + body = JSON.stringify body |
| 146 | + options.headers["Content-Length"] = body.length |
| 147 | + |
| 148 | + request = HTTPS.request options, (response) -> |
| 149 | + data = "" |
| 150 | + response.on "data", (chunk) -> |
| 151 | + data += chunk |
| 152 | + response.on "end", -> |
| 153 | + try |
| 154 | + callback null, JSON.parse(data) |
| 155 | + catch err |
| 156 | + callback null, data || { } |
| 157 | + response.on "error", (err) -> |
| 158 | + callback err, { } |
| 159 | + |
| 160 | + if method == "POST" |
| 161 | + request.end(body) |
| 162 | + else |
| 163 | + request.end() |
| 164 | + request.on "error", (err) -> |
| 165 | + console.log err |
| 166 | + console.log err.stack |
0 commit comments