use groups instead of rooms to invite and uninvite facilitators

This commit is contained in:
Sharon Kennedy 2020-03-19 12:52:04 -04:00
parent ef3c44f0d5
commit e48b001486

View File

@ -33,8 +33,18 @@ class OcrccBot {
return new LocalStorage(localStoragePath); return new LocalStorage(localStoragePath);
} }
sendMessage(roomId, msgText) { sendTextMessage(roomId, msgText, showToUser=null) {
return this.client.sendTextMessage(roomId, msgText).catch(err => { const content = {
msgtype: "m.text",
body: msgText,
showToUser: showToUser
}
this.sendMessage(roomId, content)
}
sendMessage(roomId, content) {
return this.client.sendMessage(roomId, content).catch(err => {
switch (err["name"]) { switch (err["name"]) {
case "UnknownDeviceError": case "UnknownDeviceError":
Object.keys(err.devices).forEach(userId => { Object.keys(err.devices).forEach(userId => {
@ -42,7 +52,7 @@ class OcrccBot {
this.client.setDeviceVerified(userId, deviceId, true); this.client.setDeviceVerified(userId, deviceId, true);
}); });
}); });
return this.sendMessage(roomId, msgText); return this.sendMessage(roomId, content);
break; break;
default: default:
logger.log("error", `ERROR SENDING MESSAGE: ${err}`); logger.log("error", `ERROR SENDING MESSAGE: ${err}`);
@ -120,20 +130,22 @@ class OcrccBot {
this.awaitingFacilitator[roomId] = true; this.awaitingFacilitator[roomId] = true;
let chatOffline = true; let chatOffline = true;
this.client this.client
.getJoinedRoomMembers(process.env.FACILITATOR_ROOM_ID) .getGroupUsers(process.env.FACILITATOR_GROUP_ID)
.then(members => { .then(res => {
const members = res.chunk
let onlineMembersCount = 0; let onlineMembersCount = 0;
Object.keys(members["joined"]).forEach(member => { members.forEach(member => {
const user = this.client.getUser(member); const memberId = member.user_id
if (user.presence === "online" && member !== process.env.BOT_USERID) { const user = this.client.getUser(memberId);
if (user && user.presence === "online" && memberId !== process.env.BOT_USERID) {
chatOffline = false; chatOffline = false;
this.inviteUserToRoom(this.client, roomId, member); this.inviteUserToRoom(this.client, roomId, memberId);
} }
}); });
}) })
.then(() => { .then(() => {
if (chatOffline) { if (chatOffline) {
this.sendMessage(roomId, process.env.CHAT_OFFLINE_MESSAGE); this.sendTextMessage(roomId, process.env.CHAT_OFFLINE_MESSAGE);
} }
}) })
.catch(err => { .catch(err => {
@ -145,11 +157,12 @@ class OcrccBot {
uninviteFacilitators(roomId) { uninviteFacilitators(roomId) {
this.awaitingFacilitator[roomId] = false; this.awaitingFacilitator[roomId] = false;
this.client this.client
.getJoinedRoomMembers(process.env.FACILITATOR_ROOM_ID) .getGroupUsers(process.env.FACILITATOR_GROUP_ID)
.then(allFacilitators => { .then(groupUsers => {
this.client.getJoinedRoomMembers(roomId).then(roomMembers => { this.client.getJoinedRoomMembers(roomId).then(roomMembers => {
const membersIds = Object.keys(roomMembers["joined"]); const membersIds = Object.keys(roomMembers["joined"]);
const facilitatorsIds = Object.keys(allFacilitators["joined"]); const facilitators = groupUsers.chunk
const facilitatorsIds = facilitators.map(f => f.user_id);
facilitatorsIds.forEach(f => { facilitatorsIds.forEach(f => {
if (!membersIds.includes(f)) { if (!membersIds.includes(f)) {
this.kickUserFromRoom(this.client, roomId, f); this.kickUserFromRoom(this.client, roomId, f);
@ -165,15 +178,34 @@ class OcrccBot {
handleBotCrash(roomId, error) { handleBotCrash(roomId, error) {
if (roomId) { if (roomId) {
this.sendMessage(roomId, BOT_ERROR_MESSAGE); this.sendTextMessage(roomId, BOT_ERROR_MESSAGE);
} }
this.sendMessage( this.sendTextMessage(
process.env.FACILITATOR_ROOM_ID, process.env.FACILITATOR_ROOM_ID,
`The Help Bot ran into an error: ${error}. Please verify that the chat service is working.` `The Help Bot ran into an error: ${error}. Please verify that the chat service is working.`
); );
} }
handleMessageEvent(event) {
const content = event.getContent();
// do nothing if there's no content
if (!content) {
return;
}
// bot commands
if (content.body.startsWith('!bot')) {
return this.handleBotCommand(event);
}
// write to transcript
if (process.env.CAPTURE_TRANSCRIPTS) {
return this.writeToTranscript(event)
}
}
writeToTranscript(event) { writeToTranscript(event) {
try { try {
const sender = event.getSender(); const sender = event.getSender();
@ -184,11 +216,6 @@ class OcrccBot {
timeZone: "America/New_York" timeZone: "America/New_York"
}); });
const filepath = this.activeChatrooms[roomId].transcriptFile; const filepath = this.activeChatrooms[roomId].transcriptFile;
if (!content) {
return;
}
const message = `${sender} [${time}]: ${content.body}\n`; const message = `${sender} [${time}]: ${content.body}\n`;
fs.appendFileSync(filepath, message, "utf8"); fs.appendFileSync(filepath, message, "utf8");
@ -197,6 +224,62 @@ class OcrccBot {
} }
} }
handleBotCommand(event) {
try {
const senderId = event.getSender();
const roomId = event.getRoomId();
const content = event.getContent();
const command = content.body.substring("!bot".length).trim()
switch(command) {
case 'transcript':
this.sendTranscript(senderId, roomId)
break;
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)
break;
default:
this.sendTextMessage(roomId, `Sorry, I don't know that command. I'm not a very smart bot.`, senderId)
break;
}
} catch (err) {
logger.log("error", `ERROR EXECUTING BOT COMMAND: ${err}`);
}
}
sendTranscript(senderId, roomId) {
const transcriptFile = this.activeChatrooms[roomId].transcriptFile;
if (!transcriptFile) {
this.sendTextMessage(roomId, 'There is no transcript for this chat.', senderId)
}
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)
})
}
deleteOldDevices() { deleteOldDevices() {
const doDelete = (oldDevices, auth=null, retries=0) => { const doDelete = (oldDevices, auth=null, retries=0) => {
if (retries > MAX_RETRIES) { if (retries > MAX_RETRIES) {
@ -246,35 +329,6 @@ class OcrccBot {
}); });
} }
// deleteOldDevices() {
// return this.client.getDevices().then(data => {
// const currentDeviceId = this.client.getDeviceId();
// 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)
// .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 =>
// logger.log(
// "error",
// `ERROR DELETING OLD DEVICES: ${JSON.stringify(err.data)}`
// )
// );
// });
// });
// }
setMembershipListeners() { setMembershipListeners() {
// Automatically accept all room invitations // Automatically accept all room invitations
return this.client.on("RoomMember.membership", (event, member) => { return this.client.on("RoomMember.membership", (event, member) => {
@ -287,7 +341,7 @@ class OcrccBot {
this.client this.client
.joinRoom(member.roomId) .joinRoom(member.roomId)
.then(room => { .then(room => {
this.sendMessage( this.sendTextMessage(
process.env.FACILITATOR_ROOM_ID, process.env.FACILITATOR_ROOM_ID,
`A support seeker requested a chat (Room ID: ${member.roomId})` `A support seeker requested a chat (Room ID: ${member.roomId})`
); );
@ -307,11 +361,11 @@ class OcrccBot {
this.activeChatrooms[member.roomId] = { this.activeChatrooms[member.roomId] = {
facilitator: member.userId facilitator: member.userId
}; };
this.sendMessage( this.sendTextMessage(
member.roomId, member.roomId,
`${member.name} has joined the chat.` `${member.name} has joined the chat.`
); );
this.sendMessage( this.sendTextMessage(
process.env.FACILITATOR_ROOM_ID, process.env.FACILITATOR_ROOM_ID,
`${member.name} joined the chat (Room ID: ${member.roomId})` `${member.name} joined the chat (Room ID: ${member.roomId})`
); );
@ -342,7 +396,7 @@ class OcrccBot {
this.activeChatrooms[member.roomId] && this.activeChatrooms[member.roomId] &&
member.userId === this.activeChatrooms[member.roomId].facilitator member.userId === this.activeChatrooms[member.roomId].facilitator
) { ) {
this.sendMessage( this.sendTextMessage(
member.roomId, member.roomId,
`${member.name} has left the chat.` `${member.name} has left the chat.`
); );
@ -357,7 +411,7 @@ class OcrccBot {
return logger.log("error", `ERROR DECRYPTING EVENT: ${err}`); return logger.log("error", `ERROR DECRYPTING EVENT: ${err}`);
} }
if (event.getType() === "m.room.message") { if (event.getType() === "m.room.message") {
this.writeToTranscript(event); this.handleMessageEvent(event)
} }
}); });
// unencrypted messages // unencrypted messages
@ -369,7 +423,7 @@ class OcrccBot {
if (event.isEncrypted()) { if (event.isEncrypted()) {
return; return;
} }
this.writeToTranscript(event); this.handleMessageEvent(event)
} }
}); });
} }
@ -412,10 +466,7 @@ class OcrccBot {
) )
.then(() => { .then(() => {
this.setMembershipListeners() this.setMembershipListeners()
this.setMessageListeners()
if (process.env.CAPTURE_TRANSCRIPTS) {
this.setMessageListeners()
}
}) })
.then(() => this.client.startClient({ initialSyncLimit: 0 })) .then(() => this.client.startClient({ initialSyncLimit: 0 }))
.catch(err => { .catch(err => {