latest build
This commit is contained in:
parent
836d4751ad
commit
a25c71a04a
163
dist/bot.js
vendored
163
dist/bot.js
vendored
@ -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
14
dist/bot.test.js
vendored
@ -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
10
dist/index.js
vendored
@ -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();
|
Loading…
Reference in New Issue
Block a user