UNPKG

hubot-remotestorage-logger

Version:

Logs channel messages to a remoteStorage account

193 lines (158 loc) 5.04 kB
/* Description: * Logs chat channel messages to a remoteStorage-enabled account * * Configuration: * RS_LOGGER_USER: RemoteStorage user address * RS_LOGGER_TOKEN: RemoteStorage OAuth bearer token for "chat-messages:rw" scope * RS_LOGGER_PUBLIC: Store log files in public folder (doesn't log direct messages) * * Notes: * Some code translated from hubot-logger * * Author: * Sebastian Kippe <sebastian@kip.pe> */ const hubot = require("hubot"); // TODO Remove once re-added in rs.js package global.XMLHttpRequest = require('xhr2'); const RemoteStorage = require("remotestoragejs"); const ChatMessages = require("remotestorage-module-chat-messages"); const remoteStorage = new RemoteStorage({ cache: false, // TODO re-enable default caching (SEEN) when getListing maxAge is fixed modules: [ ChatMessages ] }); module.exports = function (robot) { // // SETUP // let rsToken, rsUser, hubotAdapter; let messageCache = {}; rsUser = process.env.RS_LOGGER_USER; rsToken = process.env.RS_LOGGER_TOKEN; hubotAdapter = robot.adapterName; const log = function(str, logLevel='info') { robot.logger[logLevel](`[hubot-rs-logger] ${str}`); }; if (typeof rsUser === "undefined" || typeof rsToken === "undefined") { throw new Error('ENV variable for RS user and/or token missing'); } log("RemoteStorage credentials set, connecting storage..."); remoteStorage.access.claim('chat-messages', 'rw'); // remoteStorage.caching.disable('/'); remoteStorage.on('ready', function() { log("remoteStorage ready"); }); remoteStorage.on('connected', function() { log("remoteStorage connected"); setInterval(flushMessageCache, 2000); }); remoteStorage.on('error', function(error) { log("remoteStorage.js had a problem: " + error); }); remoteStorage.connect(rsUser, rsToken); // // LOGS // var logMessage = function(response) { let message = response.message; let type; if ((typeof message === 'object' && message.constructor.name === 'TextMessage') || message instanceof hubot.TextMessage) { type = 'text'; } else { // TODO implement optional join/leave message logging return; } let room = message.user.room || 'general'; let entry = { from: message.user['id'], timestamp: (+Date.now()), type: type, text: message.text }; logEntry(room, entry); }; var logResponse = (room, strings) => { strings.forEach(function(string) { string.split('\n').forEach(function(line) { let entry = { from: robot.name, timestamp: (+Date.now()), type: 'text', text: line }; logEntry(room, entry); }); }); }; var logEntry = function(room, entry) { if (!(messageCache[room] instanceof Array)) { messageCache[room] = []; } messageCache[room].push(entry); }; var flushMessageCache = function() { Object.keys(messageCache).forEach(function(room) { let messages = messageCache[room]; if (messages && messages.length > 0) { log(`Storing ${messages.length} new messages for room ${room}`); messageCache[room] = []; rsAddMessages(room, messages).then(function(){ }, function(error) { messageCache[room] = messages.concat(messageCache[room]); log(error, 'error'); }); } else { // nothing to flush } }); }; var rsAddMessages = function(room, messages) { let archive = { date: new Date(messages[0].timestamp), isPublic: process.env.RS_LOGGER_PUBLIC != null }; switch (hubotAdapter) { case 'irc': archive.channelName = room; archive.service = { protocol: 'IRC', domain: process.env.RS_LOGGER_SERVER_NAME || process.env.HUBOT_IRC_SERVER } break; case 'xmpp': let [roomName, mucHost] = room.split("@"); archive.channelName = roomName; archive.service = { protocol: 'XMPP', domain: mucHost } break; } let rsArchive = new remoteStorage.chatMessages.DailyArchive(archive); return rsArchive.addMessages(messages); }; // // ROBOT // // Add a listener that matches all messages and calls logMessage // with a Response object var listener = new hubot.Listener(robot, (function() { return true; }), function(res) { return logMessage(res); }); robot.listeners.push(listener); // Override send methods in the Response prototype so that we can // log Hubot's replies var responseOrig = { send: robot.Response.prototype.send, reply: robot.Response.prototype.reply }; robot.Response.prototype.send = function(...strings) { logResponse(this.message.user.room, strings); responseOrig.send.call(this, ...strings); }; robot.Response.prototype.reply = function(...strings) { logResponse(this.message.user.room, strings); responseOrig.reply.call(this, ...strings); }; };