-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
192 lines (158 loc) · 4.93 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/* 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);
};
};