diff --git a/src/bot.js b/src/bot.js index 664b182..f12f77b 100644 --- a/src/bot.js +++ b/src/bot.js @@ -12,7 +12,8 @@ import logger from "./logger"; const ENCRYPTION_CONFIG = { algorithm: "m.megolm.v1.aes-sha2" }; const KICK_REASON = "A facilitator has already joined this chat."; -const BOT_ERROR_MESSAGE = "Something went wrong on our end, please restart the chat and try again."; +const BOT_ERROR_MESSAGE = + "Something went wrong on our end, please restart the chat and try again."; const MAX_RETRIES = 3; class OcrccBot { @@ -33,14 +34,14 @@ class OcrccBot { return new LocalStorage(localStoragePath); } - sendTextMessage(roomId, msgText, showToUser=null) { + sendTextMessage(roomId, msgText, showToUser = null) { const content = { msgtype: "m.text", body: msgText, showToUser: showToUser - } + }; - this.sendMessage(roomId, content) + this.sendMessage(roomId, content); } sendMessage(roomId, content) { @@ -132,12 +133,16 @@ class OcrccBot { this.client .getGroupUsers(process.env.FACILITATOR_GROUP_ID) .then(res => { - const members = res.chunk + const members = res.chunk; let onlineMembersCount = 0; members.forEach(member => { - const memberId = member.user_id + const memberId = member.user_id; const user = this.client.getUser(memberId); - if (user && user.presence === "online" && memberId !== process.env.BOT_USERID) { + if ( + user && + user.presence === "online" && + memberId !== process.env.BOT_USERID + ) { chatOffline = false; this.inviteUserToRoom(this.client, roomId, memberId); } @@ -161,7 +166,7 @@ class OcrccBot { .then(groupUsers => { this.client.getJoinedRoomMembers(roomId).then(roomMembers => { const membersIds = Object.keys(roomMembers["joined"]); - const facilitators = groupUsers.chunk + const facilitators = groupUsers.chunk; const facilitatorsIds = facilitators.map(f => f.user_id); facilitatorsIds.forEach(f => { if (!membersIds.includes(f)) { @@ -196,13 +201,13 @@ class OcrccBot { } // bot commands - if (content.body.startsWith('!bot')) { + if (content.body.startsWith("!bot")) { return this.handleBotCommand(event); } // write to transcript if (process.env.CAPTURE_TRANSCRIPTS) { - return this.writeToTranscript(event) + return this.writeToTranscript(event); } } @@ -229,22 +234,33 @@ class OcrccBot { const senderId = event.getSender(); const roomId = event.getRoomId(); const content = event.getContent(); - const command = content.body.substring("!bot".length).trim() + const command = content.body.substring("!bot".length).trim(); - switch(command) { - case 'transcript': - this.sendTranscript(senderId, roomId) + switch (command) { + case "transcript": + this.sendTranscript(senderId, roomId); break; - case 'transcript please': - this.sendTranscript(senderId, roomId) + case "transcript please": + this.sendTranscript(senderId, roomId); break; - case 'hi': - const responses = ['Hi!', 'Hello', 'Hey :)', 'Hi there', 'Bleep bloop'] - const message = responses[Math.floor(Math.random() * responses.length)] - this.sendTextMessage(roomId, message, senderId) + case "hi": + const responses = [ + "Hi!", + "Hello", + "Hey :)", + "Hi there", + "Bleep bloop" + ]; + const message = + responses[Math.floor(Math.random() * responses.length)]; + this.sendTextMessage(roomId, message, senderId); break; default: - this.sendTextMessage(roomId, `Sorry, I don't know that command. I'm not a very smart bot.`, senderId) + this.sendTextMessage( + roomId, + `Sorry, I don't know that command. I'm not a very smart bot.`, + senderId + ); break; } } catch (err) { @@ -255,29 +271,39 @@ class OcrccBot { sendTranscript(senderId, roomId) { const transcriptFile = this.activeChatrooms[roomId].transcriptFile; if (!transcriptFile) { - this.sendTextMessage(roomId, 'There is no transcript for this chat.', senderId) + this.sendTextMessage( + roomId, + "There is no transcript for this chat.", + senderId + ); } - const filename = path.basename(transcriptFile) || 'Transcript'; + const filename = path.basename(transcriptFile) || "Transcript"; const stream = fs.createReadStream(transcriptFile); - this.client.uploadContent({ - stream: stream, - name: filename - }).then((contentUrl) => { - const content = { - msgtype: "m.file", - body: filename, - url: JSON.parse(contentUrl).content_uri, - showToUser: senderId - }; - - this.sendMessage(roomId, content); - }).catch(err => { - logger.log("error", `ERROR UPLOADING CONTENT: ${err}`) - this.sendTextMessage(roomId, 'There was an error uploading the transcript.', senderId) - }) + this.client + .uploadContent({ + stream: stream, + name: filename + }) + .then(contentUrl => { + const content = { + msgtype: "m.file", + body: filename, + url: JSON.parse(contentUrl).content_uri, + showToUser: senderId + }; + this.sendMessage(roomId, content); + }) + .catch(err => { + logger.log("error", `ERROR UPLOADING CONTENT: ${err}`); + this.sendTextMessage( + roomId, + "There was an error uploading the transcript.", + senderId + ); + }); } deleteOldDevices() { @@ -286,33 +312,31 @@ class OcrccBot { const allDeviceIds = data.devices.map(d => d.device_id); const oldDevices = allDeviceIds.filter(id => id !== currentDeviceId); logger.log("info", `DELETING OLD DEVICES: ${oldDevices}`); - this.client - .deleteMultipleDevices(oldDevices) + this.client.deleteMultipleDevices(oldDevices).catch(err => { + const auth = { + session: err.data.session, + type: "m.login.password", + user: process.env.BOT_USERID, + identifier: { type: "m.id.user", user: process.env.BOT_USERID }, + password: process.env.BOT_PASSWORD + }; + this.client + .deleteMultipleDevices(oldDevices, auth) + .then(() => logger.log("info", "DELETED OLD DEVICES")) .catch(err => { - const auth = { - session: err.data.session, - type: "m.login.password", - user: process.env.BOT_USERID, - identifier: { type: "m.id.user", user: process.env.BOT_USERID }, - password: process.env.BOT_PASSWORD - }; - this.client - .deleteMultipleDevices(oldDevices, auth) - .then(() => logger.log("info", "DELETED OLD DEVICES")) - .catch(err => { - if (err.errcode === "M_LIMIT_EXCEEDED") { - const delay = err.retry_after_ms || 2000 - logger.log("info", `RETRYING DELETE OLD DEVICES: ${oldDevices}`); - setTimeout(() => { - this.client.deleteMultipleDevices(oldDevices) - }, delay) - } else { - logger.log( - "error", - `ERROR DELETING OLD DEVICES: ${JSON.stringify(err.data)}` - ) - } - }); + if (err.errcode === "M_LIMIT_EXCEEDED") { + const delay = err.retry_after_ms || 2000; + logger.log("info", `RETRYING DELETE OLD DEVICES: ${oldDevices}`); + setTimeout(() => { + this.client.deleteMultipleDevices(oldDevices); + }, delay); + } else { + logger.log( + "error", + `ERROR DELETING OLD DEVICES: ${JSON.stringify(err.data)}` + ); + } + }); }); }); } @@ -349,6 +373,20 @@ class OcrccBot { this.activeChatrooms[member.roomId] = { facilitator: member.userId }; + const event = { + getType: () => { + return "m.room.power_levels"; + }, + getContent: () => { + return { + users: { + [process.env.BOT_USERID]: 100, + [member.userId]: 50 + } + }; + } + }; + this.client.setPowerLevel(member.roomId, member.userId, 50, event); this.sendTextMessage( member.roomId, `${member.name} has joined the chat.` @@ -365,10 +403,7 @@ class OcrccBot { month: "short", day: "numeric" }; - const chatDate = currentDate.toLocaleDateString( - "en-GB", - dateOpts - ); + const chatDate = currentDate.toLocaleDateString("en-GB", dateOpts); const chatTime = currentDate.toLocaleTimeString("en-GB", { timeZone: "America/New_York" }); @@ -399,7 +434,7 @@ class OcrccBot { return logger.log("error", `ERROR DECRYPTING EVENT: ${err}`); } if (event.getType() === "m.room.message") { - this.handleMessageEvent(event) + this.handleMessageEvent(event); } }); // unencrypted messages @@ -411,7 +446,7 @@ class OcrccBot { if (event.isEncrypted()) { return; } - this.handleMessageEvent(event) + this.handleMessageEvent(event); } }); } @@ -429,7 +464,7 @@ class OcrccBot { .then(data => { const accessToken = data.access_token; const deviceId = data.device_id; - logger.log('info', `LOGIN DATA ==> ${JSON.stringify(data)}`) + logger.log("info", `LOGIN DATA ==> ${JSON.stringify(data)}`); // create new client with full options @@ -447,7 +482,7 @@ class OcrccBot { logger.log("error", `ERROR WITH LOGIN: ${err}`); }) .then(() => { - this.deleteOldDevices() + this.deleteOldDevices(); }) .then(() => this.client.initCrypto()) .catch(err => logger.log("error", `ERROR STARTING CRYPTO: ${err}`)) @@ -457,8 +492,8 @@ class OcrccBot { }) ) .then(() => { - this.setMembershipListeners() - this.setMessageListeners() + this.setMembershipListeners(); + this.setMessageListeners(); }) .then(() => this.client.startClient({ initialSyncLimit: 0 })) .catch(err => { @@ -469,4 +504,3 @@ class OcrccBot { } export default OcrccBot; -