diff --git a/.env.sample b/.env.sample deleted file mode 100644 index 2538394..0000000 --- a/.env.sample +++ /dev/null @@ -1,7 +0,0 @@ -MATRIX_SERVER_URL= -BOT_DISPLAY_NAME= -BOT_USERNAME= -BOT_PASSWORD= -BOT_USERID= -FACILITATOR_ROOM_ID= -CAPTURE_TRANSCRIPTS \ No newline at end of file diff --git a/.gitignore b/.gitignore index 0d10baa..f504d94 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ node_modules *.log __mocks__/test_transcript.txt transcripts/*.txt +config.json \ No newline at end of file diff --git a/dist/bot.js b/dist/bot.js index 4b9bb46..6e0f441 100644 --- a/dist/bot.js +++ b/dist/bot.js @@ -30,15 +30,15 @@ const BOT_SIGNAL_END_CHAT = 'END_CHAT'; const BOT_SIGNAL_CHAT_OFFLINE = 'CHAT_OFFLINE'; class OcrccBot { - constructor(botConfig) { - this.config = botConfig; - this.client = matrix.createClient(this.config.MATRIX_SERVER_URL); + constructor(config) { + this.config = config; + this.client = matrix.createClient(this.config.matrixServerUrl); this.joinedRooms = []; this.inactivityTimers = {}; } createLocalStorage() { - const storageLoc = `matrix-chatbot-${this.config.BOT_USERNAME}`; + const storageLoc = `matrix-chatbot-${this.config.botUsername}`; const dir = path.resolve(path.join(os.homedir(), ".local-storage")); if (!fs.existsSync(dir)) { @@ -122,7 +122,7 @@ class OcrccBot { kickUserFromRoom(roomId, member) { try { - this.client.kick(roomId, member, this.config.KICK_REASON); + this.client.kick(roomId, member, this.config.kickReason); } catch (err) { this.handleBotCrash(roomId, err); @@ -134,12 +134,12 @@ class OcrccBot { try { this.localStorage.setItem(`${roomId}-waiting`, 'true'); let invitations = []; - const roomMembers = await this.client.getJoinedRoomMembers(this.config.FACILITATOR_ROOM_ID); + const roomMembers = await this.client.getJoinedRoomMembers(this.config.facilitatorRoomId); const members = Object.keys(roomMembers["joined"]); members.forEach(memberId => { const user = this.client.getUser(memberId); - if (user && user.presence !== "offline" && memberId !== this.config.BOT_USERID) { + if (user && user.presence !== "offline" && memberId !== this.config.botUserId) { invitations.push(memberId); this.inviteUserToRoom(roomId, memberId); } @@ -162,7 +162,7 @@ class OcrccBot { async uninviteFacilitators(roomId) { try { this.localStorage.removeItem(`${roomId}-waiting`); - const facilitatorsRoomMembers = await this.client.getJoinedRoomMembers(this.config.FACILITATOR_ROOM_ID); + const facilitatorsRoomMembers = await this.client.getJoinedRoomMembers(this.config.facilitatorRoomId); const supportRoomMembers = await this.client.getJoinedRoomMembers(roomId); const roomMembersIds = Object.keys(supportRoomMembers["joined"]); const facilitatorsIds = Object.keys(facilitatorsRoomMembers["joined"]); @@ -181,10 +181,10 @@ class OcrccBot { handleBotCrash(roomId, error) { if (roomId) { - this.sendTextMessage(roomId, this.config.BOT_ERROR_MESSAGE); + this.sendTextMessage(roomId, this.config.botErrorMessage); } - this.sendTextMessage(this.config.FACILITATOR_ROOM_ID, `${this.config.BOT_DISPLAY_NAME} ran into an error: ${error}. Please verify that the chat service is working.`); + this.sendTextMessage(this.config.facilitatorRoomId, `${this.config.botDisplayName} ran into an error: ${error}. Please verify that the chat service is working.`); } handleMessageEvent(event) { @@ -199,7 +199,7 @@ class OcrccBot { const facilitatorId = this.localStorage.getItem(`${roomId}-facilitator`); - if (Boolean(facilitatorId) && sender !== this.config.BOT_USERID) { + if (Boolean(facilitatorId) && sender !== this.config.botUserId) { this.setInactivityTimeout(roomId); } // bot commands @@ -209,7 +209,7 @@ class OcrccBot { } // write to transcript - if (this.config.CAPTURE_TRANSCRIPTS) { + if (this.config.captureTranscripts) { return this.writeToTranscript(event); } } @@ -406,12 +406,12 @@ class OcrccBot { const auth = { session: err.data.session, type: "m.login.password", - user: this.config.BOT_USERID, + user: this.config.botUserId, identifier: { type: "m.id.user", - user: this.config.BOT_USERID + user: this.config.botUserId }, - password: this.config.BOT_PASSWORD + password: this.config.botPassword }; await this.client.deleteMultipleDevices(oldDevices, auth); @@ -429,7 +429,7 @@ class OcrccBot { async setMembershipListeners() { // Automatically accept all room invitations this.client.on("RoomMember.membership", async (event, member) => { - if (member.membership === "invite" && member.userId === this.config.BOT_USERID && !this.joinedRooms.includes(member.roomId)) { + if (member.membership === "invite" && member.userId === this.config.botUserId && !this.joinedRooms.includes(member.roomId)) { try { const roomData = await this.client.getJoinedRooms(); const joinedRooms = roomData["joined_rooms"]; @@ -444,7 +444,7 @@ class OcrccBot { const chatTime = inviteDate.toLocaleTimeString(); const roomId = room.roomId.split(':')[0]; const notification = `Incoming support chat at ${chatTime} (room ID: ${roomId})`; - this.sendTextMessage(this.config.FACILITATOR_ROOM_ID, notification); + this.sendTextMessage(this.config.facilitatorRoomId, notification); this.inviteFacilitators(room.roomId); this.setTimeoutforFacilitator(room.roomId); } @@ -453,10 +453,10 @@ class OcrccBot { } } - if (member.membership === "join" && member.userId !== this.config.BOT_USERID && this.localStorage.getItem(`${member.roomId}-waiting`)) { + if (member.membership === "join" && member.userId !== this.config.botUserId && this.localStorage.getItem(`${member.roomId}-waiting`)) { try { // make sure it's a facilitator joining - const roomMembers = await this.client.getJoinedRoomMembers(this.config.FACILITATOR_ROOM_ID); + const roomMembers = await this.client.getJoinedRoomMembers(this.config.facilitatorRoomId); const members = Object.keys(roomMembers["joined"]); const isFacilitator = members.includes(member.userId); @@ -470,7 +470,7 @@ class OcrccBot { getContent: () => { return { users: { - [this.config.BOT_USERID]: 100, + [this.config.botUserId]: 100, [member.userId]: 50 } }; @@ -482,13 +482,13 @@ class OcrccBot { const chatTime = currentDate.toLocaleTimeString(); const roomId = member.roomId.split(':')[0]; const notification = `${member.name} joined the chat at ${chatTime} (room ID: ${roomId})`; - this.sendTextMessage(this.config.FACILITATOR_ROOM_ID, notification); // send notification to chat room + this.sendTextMessage(this.config.facilitatorRoomId, notification); // send notification to chat room this.sendTextMessage(member.roomId, `${member.name} has joined the chat.`); // revoke the other invitations this.uninviteFacilitators(member.roomId); // set transcript file - if (this.config.CAPTURE_TRANSCRIPTS) { + if (this.config.captureTranscripts) { const currentDate = new Date(); const dateOpts = { year: "numeric", @@ -509,14 +509,14 @@ class OcrccBot { } } - if (member.membership === "leave" && member.userId !== this.config.BOT_USERID) { + if (member.membership === "leave" && member.userId !== this.config.botUserId) { const room = this.client.getRoom(member.roomId); if (!room) return; const roomMembers = await room.getJoinedMembers(); // array - const facilitatorRoomMembers = await this.client.getJoinedRoomMembers(this.config.FACILITATOR_ROOM_ID); // object + const facilitatorRoomMembers = await this.client.getJoinedRoomMembers(this.config.facilitatorRoomId); // object - const isBotInRoom = Boolean(roomMembers.find(member => member.userId === this.config.BOT_USERID)); // leave if there is nobody in the room + const isBotInRoom = Boolean(roomMembers.find(member => member.userId === this.config.botUserId)); // leave if there is nobody in the room try { const memberCount = roomMembers.length; @@ -546,7 +546,7 @@ class OcrccBot { const chatTime = currentDate.toLocaleTimeString(); const roomId = member.roomId.split(':')[0]; const notification = `${member.name} left the chat at ${chatTime} (room ID: ${roomId})`; - await this.sendTextMessage(this.config.FACILITATOR_ROOM_ID, notification); + await this.sendTextMessage(this.config.facilitatorRoomId, notification); } } catch (err) { _logger.default.log("error", `ERROR NOTIFYING THAT FACLITATOR HAS LEFT THE ROOM ==> ${err}`); @@ -557,7 +557,7 @@ class OcrccBot { const facilitators = facilitatorRoomMembers['joined']; let facilitatorInRoom = false; roomMembers.forEach(member => { - if (member.userId !== this.config.BOT_USERID && Boolean(facilitators[member.userId])) { + if (member.userId !== this.config.botUserId && Boolean(facilitators[member.userId])) { facilitatorInRoom = true; } }); @@ -581,10 +581,10 @@ class OcrccBot { if (stillWaiting) { _logger.default.log("info", `FACILITATOR DID NOT JOIN CHAT WITHIN TIME LIMIT, SENDING SIGNAL TO END CHAT`); - await this.sendTextMessage(roomId, this.config.CHAT_NOT_AVAILABLE_MESSAGE); + await this.sendTextMessage(roomId, this.config.chatNotAvailableMessage); this.sendBotSignal(roomId, BOT_SIGNAL_END_CHAT); } - }, this.config.MAX_WAIT_TIME); + }, this.config.maxWaitTime); } setInactivityTimeout(roomId) { @@ -597,9 +597,9 @@ class OcrccBot { const newTimeout = setTimeout(async () => { _logger.default.log("info", `CHAT IS INACTIVE, SENDING SIGNAL TO END CHAT`); - await this.sendTextMessage(roomId, `This chat has been closed due to inactivity.`); + await this.sendTextMessage(roomId, this.config.chatInactiveMessage); this.sendBotSignal(roomId, BOT_SIGNAL_END_CHAT); - }, this.config.MAX_INACTIVE); + }, this.config.maxInactiveTime); this.inactivityTimers[roomId] = newTimeout; } @@ -640,18 +640,18 @@ class OcrccBot { const localStorage = this.createLocalStorage(); this.localStorage = localStorage; const auth = { - user: this.config.BOT_USERNAME, - password: this.config.BOT_PASSWORD, - initial_device_display_name: this.config.BOT_DISPLAY_NAME + user: this.config.botUsername, + password: this.config.botPassword, + initial_device_display_name: this.config.botDisplayName }; const account = await this.client.login("m.login.password", auth); _logger.default.log("info", `ACCOUNT ==> ${JSON.stringify(account)}`); let opts = { - baseUrl: this.config.MATRIX_SERVER_URL, + baseUrl: this.config.matrixServerUrl, accessToken: account.access_token, - userId: this.config.BOT_USERID, + userId: this.config.botUserId, deviceId: account.device_id, sessionStore: new matrix.WebStorageSessionStore(localStorage) }; diff --git a/dist/index.js b/dist/index.js index e785bd0..d2ef2e9 100644 --- a/dist/index.js +++ b/dist/index.js @@ -2,48 +2,14 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +var _config = _interopRequireDefault(require("../config.json")); + var _bot = _interopRequireDefault(require("./bot")); -require('dotenv').config(); - -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 MAX_RETRIES = 3; -const { - MATRIX_SERVER_URL, - BOT_USERNAME, - BOT_USERID, - BOT_PASSWORD, - BOT_DISPLAY_NAME, - FACILITATOR_ROOM_ID, - CAPTURE_TRANSCRIPTS, - CHAT_NOT_AVAILABLE_MESSAGE, - MAX_WAIT_TIME, - MAX_INACTIVE -} = process.env; -const botConfig = { - ENCRYPTION_CONFIG, - KICK_REASON, - BOT_ERROR_MESSAGE, - MAX_RETRIES, - MATRIX_SERVER_URL, - BOT_USERNAME, - BOT_USERID, - BOT_PASSWORD, - BOT_DISPLAY_NAME, - FACILITATOR_ROOM_ID, - CAPTURE_TRANSCRIPTS, - CHAT_NOT_AVAILABLE_MESSAGE, - MAX_WAIT_TIME, - MAX_INACTIVE -}; -const bot = new _bot.default(botConfig); +const bot = new _bot.default(_config.default); try { bot.start(); } catch (err) { - console.log("AAAAAAAAAAAAA", err); + console.log("Unable to start bot", err); } \ No newline at end of file diff --git a/dist/setup.js b/dist/setup.js new file mode 100644 index 0000000..b355b22 --- /dev/null +++ b/dist/setup.js @@ -0,0 +1,54 @@ +"use strict"; + +const fs = require('fs'); + +const fetch = require('node-fetch'); + +const config = require('../config.json'); + +const getSettings = async () => { + try { + const url = `${config.settingsEndpoint}?homeserver=${encodeURIComponent(config.matrixServerUrl)}`; + + if (!config.matrixServerUrl) { + throw new Error("The matrix server url is not provided"); + } + + console.log(`Fetching settings for ${config.matrixServerUrl}`); + const res = await fetch(url); + const data = await res.json(); + const { + fields, + schedule = [] + } = data; + return Object.entries(fields).reduce((settingsObj, [k, v]) => { + const [scope, key] = k.split('_'); + + if (scope === 'platfrom') { + settingsObj[key] = v; + } + + return settingsObj; + }, {}); + } catch (err) { + console.log("Error fetching settings", err); + return null; + } +}; + +const writeConfig = async () => { + const settings = await getSettings(); + + if (!settings) { + return console.log('No settings to update'); + } + + const updatedSettings = Object.assign(config, settings); + fs.writeFile('config.json', JSON.stringify(updatedSettings, null, 2), function (err) { + if (err) return console.log("Error updating settings", err); + console.log(`Updated settings to config.json`); + console.log(updatedSettings); + }); +}; + +writeConfig(); \ No newline at end of file diff --git a/package.json b/package.json index eae03c0..2186953 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "scripts": { "develop": "nodemon --exec babel-node src/index.js", "build": "babel src -d dist", + "setup": "node src/setup.js", "start": "yarn build && node dist/index.js", "test": "jest" }, @@ -14,6 +15,7 @@ "dependencies": { "dotenv": "^8.2.0", "matrix-js-sdk": "^6.2.1", + "node-fetch": "^2.6.1", "node-localstorage": "^2.1.5", "node-webcrypto-ossl": "^2.1.0", "olm": "https://packages.matrix.org/npm/olm/olm-3.1.4.tgz", diff --git a/src/bot.js b/src/bot.js index 66432ab..40a41b9 100644 --- a/src/bot.js +++ b/src/bot.js @@ -14,17 +14,16 @@ import encrypt from "./encrypt-attachment"; const BOT_SIGNAL_END_CHAT = 'END_CHAT' const BOT_SIGNAL_CHAT_OFFLINE = 'CHAT_OFFLINE' - class OcrccBot { - constructor(botConfig) { - this.config = botConfig - this.client = matrix.createClient(this.config.MATRIX_SERVER_URL); + constructor(config) { + this.config = config + this.client = matrix.createClient(this.config.matrixServerUrl); this.joinedRooms = []; this.inactivityTimers = {}; } createLocalStorage() { - const storageLoc = `matrix-chatbot-${this.config.BOT_USERNAME}`; + const storageLoc = `matrix-chatbot-${this.config.botUsername}`; const dir = path.resolve(path.join(os.homedir(), ".local-storage")); if (!fs.existsSync(dir)) { fs.mkdirSync(dir); @@ -101,33 +100,41 @@ class OcrccBot { kickUserFromRoom(roomId, member) { try { - this.client.kick(roomId, member, this.config.KICK_REASON) + this.client.kick(roomId, member, this.config.kickReason) } catch(err) { this.handleBotCrash(roomId, err); logger.log("error", `ERROR KICKING OUT MEMBER: ${err}`); } } + async inviteFacilitatorIfOnline(roomId, memberId) { + const user = this.client.getUser(memberId); + if ( + user && + (user.presence !== "offline") && + memberId !== this.config.botUserId + ) { + invitations.push(memberId) + this.inviteUserToRoom(roomId, memberId); + return memberId + } else { + return null + } + } + async inviteFacilitators(roomId) { try { this.localStorage.setItem(`${roomId}-waiting`, 'true') let invitations = [] - const roomMembers = await this.client.getJoinedRoomMembers(this.config.FACILITATOR_ROOM_ID) + const roomMembers = await this.client.getJoinedRoomMembers(this.config.facilitatorRoomId) const members = Object.keys(roomMembers["joined"]); - members.forEach(memberId => { - const user = this.client.getUser(memberId); - if ( - user && - (user.presence !== "offline") && - memberId !== this.config.BOT_USERID - ) { - invitations.push(memberId) - this.inviteUserToRoom(roomId, memberId); - } - }); + for (const memberId of members) { + const invited = await this.inviteFacilitatorIfOnline(roomId, memberId) + invitations.push(invited) + } - if (invitations.length > 0) { + if (invitations.filter(i => i).length > 0) { this.localStorage.setItem(`${roomId}-invitations`, invitations) } else { logger.log('info', "NO FACILITATORS ONLINE") @@ -144,7 +151,7 @@ class OcrccBot { async uninviteFacilitators(roomId) { try { this.localStorage.removeItem(`${roomId}-waiting`) - const facilitatorsRoomMembers = await this.client.getJoinedRoomMembers(this.config.FACILITATOR_ROOM_ID) + const facilitatorsRoomMembers = await this.client.getJoinedRoomMembers(this.config.facilitatorRoomId) const supportRoomMembers = await this.client.getJoinedRoomMembers(roomId) const roomMembersIds = Object.keys(supportRoomMembers["joined"]); @@ -166,12 +173,12 @@ class OcrccBot { handleBotCrash(roomId, error) { if (roomId) { - this.sendTextMessage(roomId, this.config.BOT_ERROR_MESSAGE); + this.sendTextMessage(roomId, this.config.botErrorMessage); } this.sendTextMessage( - this.config.FACILITATOR_ROOM_ID, - `${this.config.BOT_DISPLAY_NAME} ran into an error: ${error}. Please verify that the chat service is working.` + this.config.facilitatorRoomId, + `${this.config.botDisplayName} ran into an error: ${error}. Please verify that the chat service is working.` ); } @@ -187,7 +194,7 @@ class OcrccBot { // if it's a chat message and the facilitator has joined, reset the inactivity timeout const facilitatorId = this.localStorage.getItem(`${roomId}-facilitator`) - if (Boolean(facilitatorId) && sender !== this.config.BOT_USERID) { + if (Boolean(facilitatorId) && sender !== this.config.botUserId) { this.setInactivityTimeout(roomId) } @@ -197,7 +204,7 @@ class OcrccBot { } // write to transcript - if (this.config.CAPTURE_TRANSCRIPTS) { + if (this.config.captureTranscripts) { return this.writeToTranscript(event); } } @@ -417,9 +424,9 @@ class OcrccBot { const auth = { session: err.data.session, type: "m.login.password", - user: this.config.BOT_USERID, - identifier: { type: "m.id.user", user: this.config.BOT_USERID }, - password: this.config.BOT_PASSWORD + user: this.config.botUserId, + identifier: { type: "m.id.user", user: this.config.botUserId }, + password: this.config.botPassword }; await this.client.deleteMultipleDevices(oldDevices, auth) @@ -438,7 +445,7 @@ class OcrccBot { this.client.on("RoomMember.membership", async (event, member) => { if ( member.membership === "invite" && - member.userId === this.config.BOT_USERID && + member.userId === this.config.botUserId && !this.joinedRooms.includes(member.roomId) ) { try { @@ -452,7 +459,7 @@ class OcrccBot { const chatTime = inviteDate.toLocaleTimeString() const roomId = room.roomId.split(':')[0] const notification = `Incoming support chat at ${chatTime} (room ID: ${roomId})` - this.sendTextMessage(this.config.FACILITATOR_ROOM_ID, notification); + this.sendTextMessage(this.config.facilitatorRoomId, notification); this.inviteFacilitators(room.roomId) this.setTimeoutforFacilitator(room.roomId) } @@ -463,12 +470,12 @@ class OcrccBot { if ( member.membership === "join" && - member.userId !== this.config.BOT_USERID && + member.userId !== this.config.botUserId && this.localStorage.getItem(`${member.roomId}-waiting`) ) { try { // make sure it's a facilitator joining - const roomMembers = await this.client.getJoinedRoomMembers(this.config.FACILITATOR_ROOM_ID) + const roomMembers = await this.client.getJoinedRoomMembers(this.config.facilitatorRoomId) const members = Object.keys(roomMembers["joined"]); const isFacilitator = members.includes(member.userId) @@ -482,7 +489,7 @@ class OcrccBot { getContent: () => { return { users: { - [this.config.BOT_USERID]: 100, + [this.config.botUserId]: 100, [member.userId]: 50 } }; @@ -495,7 +502,7 @@ class OcrccBot { const chatTime = currentDate.toLocaleTimeString() const roomId = member.roomId.split(':')[0] const notification = `${member.name} joined the chat at ${chatTime} (room ID: ${roomId})` - this.sendTextMessage(this.config.FACILITATOR_ROOM_ID, notification); + this.sendTextMessage(this.config.facilitatorRoomId, notification); // send notification to chat room this.sendTextMessage( @@ -507,7 +514,7 @@ class OcrccBot { this.uninviteFacilitators(member.roomId); // set transcript file - if (this.config.CAPTURE_TRANSCRIPTS) { + if (this.config.captureTranscripts) { const currentDate = new Date(); const dateOpts = { year: "numeric", @@ -530,14 +537,14 @@ class OcrccBot { if ( member.membership === "leave" && - member.userId !== this.config.BOT_USERID + member.userId !== this.config.botUserId ) { const room = this.client.getRoom(member.roomId) if (!room) return; const roomMembers = await room.getJoinedMembers() // array - const facilitatorRoomMembers = await this.client.getJoinedRoomMembers(this.config.FACILITATOR_ROOM_ID) // object - const isBotInRoom = Boolean(roomMembers.find(member => member.userId === this.config.BOT_USERID)) + const facilitatorRoomMembers = await this.client.getJoinedRoomMembers(this.config.facilitatorRoomId) // object + const isBotInRoom = Boolean(roomMembers.find(member => member.userId === this.config.botUserId)) // leave if there is nobody in the room try { @@ -567,7 +574,7 @@ class OcrccBot { const chatTime = currentDate.toLocaleTimeString() const roomId = member.roomId.split(':')[0] const notification = `${member.name} left the chat at ${chatTime} (room ID: ${roomId})` - await this.sendTextMessage(this.config.FACILITATOR_ROOM_ID, notification); + await this.sendTextMessage(this.config.facilitatorRoomId, notification); } } catch(err) { logger.log("error", `ERROR NOTIFYING THAT FACLITATOR HAS LEFT THE ROOM ==> ${err}`); @@ -579,7 +586,7 @@ class OcrccBot { let facilitatorInRoom = false; roomMembers.forEach(member => { - if (member.userId !== this.config.BOT_USERID && Boolean(facilitators[member.userId])) { + if (member.userId !== this.config.botUserId && Boolean(facilitators[member.userId])) { facilitatorInRoom = true } }) @@ -603,11 +610,11 @@ class OcrccBot { logger.log("info", `FACILITATOR DID NOT JOIN CHAT WITHIN TIME LIMIT, SENDING SIGNAL TO END CHAT`); await this.sendTextMessage( roomId, - this.config.CHAT_NOT_AVAILABLE_MESSAGE + this.config.chatNotAvailableMessage ); this.sendBotSignal(roomId, BOT_SIGNAL_END_CHAT) } - }, this.config.MAX_WAIT_TIME) + }, this.config.maxWaitTime) } setInactivityTimeout(roomId) { @@ -621,10 +628,10 @@ class OcrccBot { logger.log("info", `CHAT IS INACTIVE, SENDING SIGNAL TO END CHAT`); await this.sendTextMessage( roomId, - `This chat has been closed due to inactivity.` + this.config.chatInactiveMessage ); this.sendBotSignal(roomId, BOT_SIGNAL_END_CHAT) - }, this.config.MAX_INACTIVE) + }, this.config.maxInactiveTime) this.inactivityTimers[roomId] = newTimeout; } @@ -665,17 +672,17 @@ class OcrccBot { this.localStorage = localStorage const auth = { - user: this.config.BOT_USERNAME, - password: this.config.BOT_PASSWORD, - initial_device_display_name: this.config.BOT_DISPLAY_NAME + user: this.config.botUsername, + password: this.config.botPassword, + initial_device_display_name: this.config.botDisplayName } const account = await this.client.login("m.login.password", auth) logger.log("info", `ACCOUNT ==> ${JSON.stringify(account)}`); let opts = { - baseUrl: this.config.MATRIX_SERVER_URL, + baseUrl: this.config.matrixServerUrl, accessToken: account.access_token, - userId: this.config.BOT_USERID, + userId: this.config.botUserId, deviceId: account.device_id, sessionStore: new matrix.WebStorageSessionStore(localStorage) }; diff --git a/src/index.js b/src/index.js index 68fbd4c..e23dbf5 100644 --- a/src/index.js +++ b/src/index.js @@ -1,46 +1,9 @@ -require('dotenv').config() +import config from '../config.json'; +import OcrccBot from './bot'; -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 MAX_RETRIES = 3; - -const { - MATRIX_SERVER_URL, - BOT_USERNAME, - BOT_USERID, - BOT_PASSWORD, - BOT_DISPLAY_NAME, - FACILITATOR_ROOM_ID, - CAPTURE_TRANSCRIPTS, - CHAT_NOT_AVAILABLE_MESSAGE, - MAX_WAIT_TIME, - MAX_INACTIVE, -} = process.env; - -const botConfig = { - ENCRYPTION_CONFIG, - KICK_REASON, - BOT_ERROR_MESSAGE, - MAX_RETRIES, - MATRIX_SERVER_URL, - BOT_USERNAME, - BOT_USERID, - BOT_PASSWORD, - BOT_DISPLAY_NAME, - FACILITATOR_ROOM_ID, - CAPTURE_TRANSCRIPTS, - CHAT_NOT_AVAILABLE_MESSAGE, - MAX_WAIT_TIME, - MAX_INACTIVE, -} - -import OcrccBot from './bot' - -const bot = new OcrccBot(botConfig); +const bot = new OcrccBot(config); try { bot.start(); } catch(err) { - console.log("AAAAAAAAAAAAA", err) + console.log("Unable to start bot", err) } diff --git a/src/setup.js b/src/setup.js new file mode 100644 index 0000000..1bac54a --- /dev/null +++ b/src/setup.js @@ -0,0 +1,50 @@ +const fs = require('fs'); +const fetch = require('node-fetch'); +const config = require('../config.json'); + +const getSettings = async () => { + try { + const url = `${config.settingsEndpoint}?homeserver=${encodeURIComponent(config.matrixServerUrl)}`; + + if (!config.matrixServerUrl) { + throw new Error("The matrix server url is not provided") + } + + console.log(`Fetching settings for ${config.matrixServerUrl}`); + + const res = await fetch(url); + const data = await res.json(); + + const { fields, schedule = [] } = data; + + return Object.entries(fields).reduce(((settingsObj, [k,v]) => { + const [scope, key] = k.split('_'); + + if (scope === 'platfrom') { + settingsObj[key] = v; + } + + return settingsObj + }), {}); + } catch (err) { + console.log("Error fetching settings", err); + return null + } +}; + +const writeConfig = async () => { + const settings = await getSettings() + if (!settings) { + return console.log('No settings to update') + } + + const updatedSettings = Object.assign(config, settings) + + fs.writeFile('config.json', JSON.stringify(updatedSettings, null, 2), function (err) { + if (err) return console.log("Error updating settings", err); + console.log(`Updated settings to config.json`); + console.log(updatedSettings); + }); +} + +writeConfig(); \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 492f98c..4cc9045 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3954,6 +3954,11 @@ node-environment-flags@^1.0.5: object.getownpropertydescriptors "^2.0.3" semver "^5.7.0" +node-fetch@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"