latest build

This commit is contained in:
Sharon Kennedy 2020-09-06 14:07:44 -04:00
parent 836d4751ad
commit a25c71a04a
3 changed files with 127 additions and 60 deletions

163
dist/bot.js vendored
View File

@ -33,6 +33,7 @@ class OcrccBot {
this.config = botConfig; this.config = botConfig;
this.client = matrix.createClient(this.config.MATRIX_SERVER_URL); this.client = matrix.createClient(this.config.MATRIX_SERVER_URL);
this.joinedRooms = []; this.joinedRooms = [];
this.inactivityTimers = {};
} }
createLocalStorage() { createLocalStorage() {
@ -188,10 +189,19 @@ class OcrccBot {
} }
handleMessageEvent(event) { handleMessageEvent(event) {
const content = event.getContent(); // do nothing if there's no content const content = event.getContent();
const sender = event.getSender();
const roomId = event.getRoomId(); // do nothing if there's no content
if (!content) { if (!content) {
return; return;
} // 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) {
this.setInactivityTimeout(roomId);
} // bot commands } // bot commands
@ -434,6 +444,7 @@ class OcrccBot {
const notification = `Incoming support chat at ${chatTime} (room ID: ${roomId})`; const notification = `Incoming support chat at ${chatTime} (room ID: ${roomId})`;
this.sendTextMessage(this.config.FACILITATOR_ROOM_ID, notification); this.sendTextMessage(this.config.FACILITATOR_ROOM_ID, notification);
this.inviteFacilitators(room.roomId); this.inviteFacilitators(room.roomId);
this.setTimeoutforFacilitator(room.roomId);
} }
} catch (err) { } catch (err) {
_logger.default.log("error", "ERROR JOINING ROOM => " + err); _logger.default.log("error", "ERROR JOINING ROOM => " + err);
@ -441,74 +452,83 @@ 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.BOT_USERID && this.localStorage.getItem(`${member.roomId}-waiting`)) {
// make sure it's a facilitator joining try {
const roomMembers = await this.client.getJoinedRoomMembers(this.config.FACILITATOR_ROOM_ID); // make sure it's a facilitator joining
const members = Object.keys(roomMembers["joined"]); const roomMembers = await this.client.getJoinedRoomMembers(this.config.FACILITATOR_ROOM_ID);
const isFacilitator = members.includes(member.userId); const members = Object.keys(roomMembers["joined"]);
const isFacilitator = members.includes(member.userId);
if (isFacilitator) { if (isFacilitator) {
// made facilitator a moderator in the room // made facilitator a moderator in the room
this.localStorage.setItem(`${member.roomId}-facilitator`, member.userId); this.localStorage.setItem(`${member.roomId}-facilitator`, member.userId);
const event = { const event = {
getType: () => { getType: () => {
return "m.room.power_levels"; return "m.room.power_levels";
}, },
getContent: () => { getContent: () => {
return { return {
users: { users: {
[this.config.BOT_USERID]: 100, [this.config.BOT_USERID]: 100,
[member.userId]: 50 [member.userId]: 50
} }
}; };
} }
};
this.client.setPowerLevel(member.roomId, member.userId, 50, event); // send notification to Support Chat Notifications room
const currentDate = new Date();
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(member.roomId, `${member.name} has joined the chat.`); // revoke the other invitations
this.uninviteFacilitators(member.roomId); // set transcript file
if (this.config.CAPTURE_TRANSCRIPTS) {
const currentDate = new Date();
const dateOpts = {
year: "numeric",
month: "short",
day: "numeric"
}; };
const chatDate = currentDate.toLocaleDateString("en-GB", dateOpts); this.client.setPowerLevel(member.roomId, member.userId, 50, event); // send notification to Support Chat Notifications room
const chatTime = currentDate.toLocaleTimeString("en-GB", {
timeZone: "America/New_York" const currentDate = new Date();
}); const chatTime = currentDate.toLocaleTimeString();
const filename = `${chatDate} - ${chatTime} - ${member.roomId}.txt`; const roomId = member.roomId.split(':')[0];
const filepath = path.resolve(path.join("transcripts", filename)); const notification = `${member.name} joined the chat at ${chatTime} (room ID: ${roomId})`;
this.localStorage.setItem(`${member.roomId}-transcript`, filepath); this.sendTextMessage(this.config.FACILITATOR_ROOM_ID, 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) {
const currentDate = new Date();
const dateOpts = {
year: "numeric",
month: "short",
day: "numeric"
};
const chatDate = currentDate.toLocaleDateString("en-GB", dateOpts);
const chatTime = currentDate.toLocaleTimeString("en-GB", {
timeZone: "America/New_York"
});
const filename = `${chatDate} - ${chatTime} - ${member.roomId}.txt`;
const filepath = path.resolve(path.join("transcripts", filename));
this.localStorage.setItem(`${member.roomId}-transcript`, filepath);
}
} }
} catch (err) {
_logger.default.log("error", `ERROR WHEN FACILITATOR JOINED ROOM ==> ${err}`);
} }
} }
if (member.membership === "leave" && member.userId !== this.config.BOT_USERID) { if (member.membership === "leave" && member.userId !== this.config.BOT_USERID) {
// ensure bot is still in the room
const roomData = await this.client.getJoinedRooms();
const joinedRooms = roomData["joined_rooms"];
const isBotInRoom = joinedRooms.includes(member.roomId);
const room = this.client.getRoom(member.roomId); const room = this.client.getRoom(member.roomId);
if (!room) return; // notify room if the facilitator has left if (!room) return;
const roomMembers = await room.getJoinedMembers(); // array
const facilitatorId = this.localStorage.getItem(`${member.roomId}-facilitator`); const facilitatorRoomMembers = await this.client.getJoinedRoomMembers(this.config.FACILITATOR_ROOM_ID); // object
if (isBotInRoom && member.userId === facilitatorId) { const isBotInRoom = roomMembers.find(member => member.userId === this.config.BOT_USERID); // notify room if the facilitator has left
this.sendTextMessage(member.roomId, `${member.name} has left the chat.`);
try {
const facilitatorId = this.localStorage.getItem(`${member.roomId}-facilitator`);
if (isBotInRoom && member.userId === facilitatorId) {
this.sendTextMessage(member.roomId, `${member.name} has left the chat.`);
}
} catch (err) {
_logger.default.log("error", `ERROR NOTIFYING THAT FACLITATOR HAS LEFT THE ROOM ==> ${err}`);
} // leave if there is nobody in the room } // leave if there is nobody in the room
try { try {
const memberCount = room.getJoinedMemberCount(); const memberCount = roomMembers.length;
if (memberCount === 1 && isBotInRoom) { if (memberCount === 1 && isBotInRoom) {
// just the bot left // just the bot left
@ -525,8 +545,6 @@ class OcrccBot {
try { try {
const roomMembers = await room.getJoinedMembers();
const facilitatorRoomMembers = await this.client.getJoinedRoomMembers(this.config.FACILITATOR_ROOM_ID);
const facilitators = facilitatorRoomMembers['joined']; const facilitators = facilitatorRoomMembers['joined'];
let facilitatorInRoom = false; let facilitatorInRoom = false;
roomMembers.forEach(member => { roomMembers.forEach(member => {
@ -545,6 +563,30 @@ class OcrccBot {
}); });
} }
setTimeoutforFacilitator(roomId) {
setTimeout(() => {
const stillWaiting = this.localStorage.getItem(`${roomId}-waiting`);
if (stillWaiting) {
this.sendBotSignal(roomId, BOT_SIGNAL_END_CHAT);
}
}, this.config.MAX_WAIT_TIME);
}
setInactivityTimeout(roomId) {
const oldTimeout = this.inactivityTimers[roomId];
if (oldTimeout) {
clearTimeout(oldTimeout);
}
const newTimeout = setTimeout(() => {
this.sendTextMessage(roomId, `This chat has been closed due to inactivity.`);
this.sendBotSignal(roomId, BOT_SIGNAL_END_CHAT);
}, this.config.MAX_INACTIVE);
this.inactivityTimers[roomId] = newTimeout;
}
async setMessageListeners() { async setMessageListeners() {
// encrypted messages // encrypted messages
this.client.on("Event.decrypted", (event, err) => { this.client.on("Event.decrypted", (event, err) => {
@ -580,7 +622,12 @@ class OcrccBot {
signal: signal, signal: signal,
args: args args: args
}; };
await this.client.sendStateEvent(roomId, 'm.bot.signal', content);
try {
await this.client.sendStateEvent(roomId, 'm.bot.signal', content);
} catch (err) {
_logger.default.log('error', "ERROR SENDING BOT SIGNAL => " + err);
}
} }
async start() { async start() {

14
dist/bot.test.js vendored
View File

@ -103,6 +103,8 @@ describe('OcrccBot', () => {
mockAppendFileSync.mockClear(); mockAppendFileSync.mockClear();
_matrixJsSdk.mockGetGroupUsers.mockClear(); _matrixJsSdk.mockGetGroupUsers.mockClear();
_matrixJsSdk.mockSendStateEvent.mockClear();
}); });
test('constructor should inititialize class variables', () => { test('constructor should inititialize class variables', () => {
const bot = new _bot.default(botConfig); const bot = new _bot.default(botConfig);
@ -276,4 +278,16 @@ describe('OcrccBot', () => {
expect(_matrixJsSdk.mockStartClient).toHaveBeenCalled(); expect(_matrixJsSdk.mockStartClient).toHaveBeenCalled();
}); });
}); });
test('#sendBotSignal should send custom state event', () => {
const bot = new _bot.default(botConfig);
bot.start();
const test_room_id = 'test_room_id';
const signal = 'END_CHAT';
bot.sendBotSignal(test_room_id, signal);
(0, _waitForExpect.default)(() => {
expect(_matrixJsSdk.mockSendStateEvent).toHaveBeenCalledWith(test_room_id, 'm.bot.signal', {
signal
});
});
});
}); });

10
dist/index.js vendored
View File

@ -19,7 +19,10 @@ const {
BOT_PASSWORD, BOT_PASSWORD,
BOT_DISPLAY_NAME, BOT_DISPLAY_NAME,
FACILITATOR_ROOM_ID, FACILITATOR_ROOM_ID,
CAPTURE_TRANSCRIPTS CAPTURE_TRANSCRIPTS,
CHAT_NOT_AVAILABLE_MESSAGE,
MAX_WAIT_TIME,
MAX_INACTIVE
} = process.env; } = process.env;
const botConfig = { const botConfig = {
ENCRYPTION_CONFIG, ENCRYPTION_CONFIG,
@ -32,7 +35,10 @@ const botConfig = {
BOT_PASSWORD, BOT_PASSWORD,
BOT_DISPLAY_NAME, BOT_DISPLAY_NAME,
FACILITATOR_ROOM_ID, FACILITATOR_ROOM_ID,
CAPTURE_TRANSCRIPTS CAPTURE_TRANSCRIPTS,
CHAT_NOT_AVAILABLE_MESSAGE,
MAX_WAIT_TIME,
MAX_INACTIVE
}; };
const bot = new _bot.default(botConfig); const bot = new _bot.default(botConfig);
bot.start(); bot.start();