imubot
Version:
A simple helpful bot.
424 lines (392 loc) • 15.2 kB
JavaScript
// Generated by CoffeeScript 1.12.6
(function() {
var Adapter, Campfire, CampfireStreaming, EnterMessage, EventEmitter, HTTPS, LeaveMessage, Bot, TextMessage, TopicMessage, ref,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty,
slice = [].slice;
HTTPS = require('https');
EventEmitter = require('events').EventEmitter;
Bot = require('../bot');
Adapter = require('../adapter');
ref = require('../message'), TextMessage = ref.TextMessage, EnterMessage = ref.EnterMessage, LeaveMessage = ref.LeaveMessage, TopicMessage = ref.TopicMessage;
Campfire = (function(superClass) {
extend(Campfire, superClass);
function Campfire() {
return Campfire.__super__.constructor.apply(this, arguments);
}
Campfire.prototype.send = function() {
var envelope, string, strings;
envelope = arguments[0], strings = 2 <= arguments.length ? slice.call(arguments, 1) : [];
if (strings.length > 0) {
string = strings.shift();
if (typeof string === 'function') {
string();
return this.send.apply(this, [envelope].concat(slice.call(strings)));
} else {
return this.bot.Room(envelope.room).speak(string, (function(_this) {
return function(err, data) {
if (err != null) {
_this.bot.logger.error("Campfire send error: " + err);
}
return _this.send.apply(_this, [envelope].concat(slice.call(strings)));
};
})(this));
}
}
};
Campfire.prototype.emote = function() {
var envelope, strings;
envelope = arguments[0], strings = 2 <= arguments.length ? slice.call(arguments, 1) : [];
return this.send.apply(this, [envelope].concat(slice.call(strings.map(function(str) {
return "*" + str + "*";
}))));
};
Campfire.prototype.reply = function() {
var envelope, strings;
envelope = arguments[0], strings = 2 <= arguments.length ? slice.call(arguments, 1) : [];
return this.send.apply(this, [envelope].concat(slice.call(strings.map(function(str) {
return envelope.user.name + ": " + str;
}))));
};
Campfire.prototype.topic = function() {
var envelope, strings;
envelope = arguments[0], strings = 2 <= arguments.length ? slice.call(arguments, 1) : [];
return this.bot.Room(envelope.room).topic(strings.join(" / "), (function(_this) {
return function(err, data) {
if (err != null) {
return _this.bot.logger.error("Campfire topic error: " + err);
}
};
})(this));
};
Campfire.prototype.play = function() {
var envelope, strings;
envelope = arguments[0], strings = 2 <= arguments.length ? slice.call(arguments, 1) : [];
return this.bot.Room(envelope.room).sound(strings.shift(), (function(_this) {
return function(err, data) {
if (err != null) {
_this.bot.logger.error("Campfire sound error: " + err);
}
return _this.play.apply(_this, [envelope].concat(slice.call(strings)));
};
})(this));
};
Campfire.prototype.locked = function() {
var envelope, strings;
envelope = arguments[0], strings = 2 <= arguments.length ? slice.call(arguments, 1) : [];
if (envelope.message["private"]) {
return this.send.apply(this, [envelope].concat(slice.call(strings)));
} else {
return this.bot.Room(envelope.room).lock((function(_this) {
return function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
strings.push(function() {
return setTimeout((function() {
return _this.bot.Room(envelope.room).unlock();
}), 3000);
});
return _this.send.apply(_this, [envelope].concat(slice.call(strings)));
};
})(this));
}
};
Campfire.prototype.run = function() {
var bot, options, self, withAuthor;
self = this;
options = {
token: process.env.MUBOT_CAMPFIRE_TOKEN,
rooms: process.env.MUBOT_CAMPFIRE_ROOMS,
account: process.env.MUBOT_CAMPFIRE_ACCOUNT
};
bot = new CampfireStreaming(options, this.bot);
withAuthor = function(callback) {
return function(id, created, room, user, body) {
return bot.User(user, function(err, userData) {
var author, userId;
if (userData.user) {
author = self.bot.brain.userForId(userData.user.id, userData.user);
userId = userData.user.id;
self.bot.brain.data.users[userId].name = userData.user.name;
self.bot.brain.data.users[userId].email_address = userData.user.email_address;
author.room = room;
return callback(id, created, room, user, body, author);
}
});
};
};
bot.on("TextMessage", withAuthor(function(id, created, room, user, body, author) {
var message;
if (bot.info.id !== author.id) {
message = new TextMessage(author, body, id);
message["private"] = bot["private"][room];
return self.receive(message);
}
}));
bot.on("EnterMessage", withAuthor(function(id, created, room, user, body, author) {
if (bot.info.id !== author.id) {
return self.receive(new EnterMessage(author, null, id));
}
}));
bot.on("LeaveMessage", withAuthor(function(id, created, room, user, body, author) {
if (bot.info.id !== author.id) {
return self.receive(new LeaveMessage(author, null, id));
}
}));
bot.on("TopicChangeMessage", withAuthor(function(id, created, room, user, body, author) {
if (bot.info.id !== author.id) {
return self.receive(new TopicMessage(author, body, id));
}
}));
bot.on("LockMessage", withAuthor(function(id, created, room, user, body, author) {
return bot["private"][room] = true;
}));
bot.on("UnlockMessage", withAuthor(function(id, created, room, user, body, author) {
return bot["private"][room] = false;
}));
bot.Me(function(err, data) {
var i, len, ref1, results, roomId;
bot.info = data.user;
bot.name = bot.info.name;
ref1 = bot.rooms;
results = [];
for (i = 0, len = ref1.length; i < len; i++) {
roomId = ref1[i];
results.push((function(roomId) {
return bot.Room(roomId).join(function(err, callback) {
return bot.Room(roomId).listen();
});
})(roomId));
}
return results;
});
bot.on("reconnect", function(roomId) {
return bot.Room(roomId).join(function(err, callback) {
return bot.Room(roomId).listen();
});
});
this.bot = bot;
return self.emit("connected");
};
return Campfire;
})(Adapter);
exports.use = function(bot) {
return new Campfire(bot);
};
CampfireStreaming = (function(superClass) {
extend(CampfireStreaming, superClass);
function CampfireStreaming(options, bot1) {
this.bot = bot1;
if (!((options.token != null) && (options.rooms != null) && (options.account != null))) {
this.bot.logger.error("Not enough parameters provided. I need a token, rooms and account");
process.exit(1);
}
this.token = options.token;
this.rooms = options.rooms.split(",");
this.account = options.account;
this.host = this.account + ".campfirenow.com";
this.authorization = "Basic " + new Buffer(this.token + ":x").toString("base64");
this["private"] = {};
}
CampfireStreaming.prototype.Rooms = function(callback) {
return this.get("/rooms", callback);
};
CampfireStreaming.prototype.User = function(id, callback) {
return this.get("/users/" + id, callback);
};
CampfireStreaming.prototype.Me = function(callback) {
return this.get("/users/me", callback);
};
CampfireStreaming.prototype.Room = function(id) {
var logger, self;
self = this;
logger = this.bot.logger;
return {
show: function(callback) {
return self.get("/room/" + id, callback);
},
join: function(callback) {
return self.post("/room/" + id + "/join", "", callback);
},
leave: function(callback) {
return self.post("/room/" + id + "/leave", "", callback);
},
lock: function(callback) {
return self.post("/room/" + id + "/lock", "", callback);
},
unlock: function(callback) {
return self.post("/room/" + id + "/unlock", "", callback);
},
paste: function(text, callback) {
return this.message(text, "PasteMessage", callback);
},
topic: function(text, callback) {
var body;
body = {
room: {
topic: text
}
};
return self.put("/room/" + id, body, callback);
},
sound: function(text, callback) {
return this.message(text, "SoundMessage", callback);
},
speak: function(text, callback) {
var body;
body = {
message: {
"body": text
}
};
return self.post("/room/" + id + "/speak", body, callback);
},
message: function(text, type, callback) {
var body;
body = {
message: {
"body": text,
"type": type
}
};
return self.post("/room/" + id + "/speak", body, callback);
},
listen: function() {
var headers, options, ref1, ref2, request;
headers = {
"Host": "streaming.campfirenow.com",
"Authorization": self.authorization,
"User-Agent": "Mubot/" + ((ref1 = this.bot) != null ? ref1.version : void 0) + " (" + ((ref2 = this.bot) != null ? ref2.name : void 0) + ")"
};
options = {
"agent": false,
"host": "streaming.campfirenow.com",
"port": 443,
"path": "/room/" + id + "/live.json",
"method": "GET",
"headers": headers
};
request = HTTPS.request(options, function(response) {
var buf;
response.setEncoding("utf8");
buf = '';
response.on("data", function(chunk) {
var data, error, offset, part, results;
if (chunk === ' ') {
} else if (chunk.match(/^\s*Access Denied/)) {
return logger.error("Campfire error on room " + id + ": " + chunk);
} else {
buf += chunk;
results = [];
while ((offset = buf.indexOf("\r")) > -1) {
part = buf.substr(0, offset);
buf = buf.substr(offset + 1);
if (part) {
try {
data = JSON.parse(part);
results.push(self.emit(data.type, data.id, data.created_at, data.room_id, data.user_id, data.body));
} catch (error1) {
error = error1;
results.push(logger.error("Campfire data error: " + error + "\n" + error.stack));
}
} else {
results.push(void 0);
}
}
return results;
}
});
response.on("end", function() {
logger.error("Streaming connection closed for room " + id + ". :(");
return setTimeout(function() {
return self.emit("reconnect", id);
}, 5000);
});
return response.on("error", function(err) {
return logger.error("Campfire listen response error: " + err);
});
});
request.on("error", function(err) {
return logger.error("Campfire listen request error: " + err);
});
return request.end();
}
};
};
CampfireStreaming.prototype.get = function(path, callback) {
return this.request("GET", path, null, callback);
};
CampfireStreaming.prototype.post = function(path, body, callback) {
return this.request("POST", path, body, callback);
};
CampfireStreaming.prototype.put = function(path, body, callback) {
return this.request("PUT", path, body, callback);
};
CampfireStreaming.prototype.request = function(method, path, body, callback) {
var headers, logger, options, ref1, ref2, request;
logger = this.bot.logger;
headers = {
"Authorization": this.authorization,
"Host": this.host,
"Content-Type": "application/json",
"User-Agent": "Mubot/" + ((ref1 = this.bot) != null ? ref1.version : void 0) + " (" + ((ref2 = this.bot) != null ? ref2.name : void 0) + ")"
};
options = {
"agent": false,
"host": this.host,
"port": 443,
"path": path,
"method": method,
"headers": headers
};
if (method === "POST" || method === "PUT") {
if (typeof body !== "string") {
body = JSON.stringify(body);
}
body = new Buffer(body);
options.headers["Content-Length"] = body.length;
}
request = HTTPS.request(options, function(response) {
var data;
data = "";
response.on("data", function(chunk) {
return data += chunk;
});
response.on("end", function() {
var error;
if (response.statusCode >= 400) {
switch (response.statusCode) {
case 401:
throw new Error("Invalid access token provided");
break;
default:
logger.error("Campfire HTTPS status code: " + response.statusCode);
logger.error("Campfire HTTPS response data: " + data);
}
}
if (callback) {
try {
return callback(null, JSON.parse(data));
} catch (error1) {
error = error1;
return callback(null, data || {});
}
}
});
return response.on("error", function(err) {
logger.error("Campfire HTTPS response error: " + err);
return callback(err, {});
});
});
if (method === "POST" || method === "PUT") {
request.end(body, 'binary');
} else {
request.end();
}
return request.on("error", function(err) {
return logger.error("Campfire request error: " + err);
});
};
return CampfireStreaming;
})(EventEmitter);
}).call(this);