use groups instead of rooms to invite and uninvite facilitators
This commit is contained in:
parent
ef3c44f0d5
commit
e48b001486
169
src/bot.js
169
src/bot.js
@ -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 => {
|
||||||
|
Loading…
Reference in New Issue
Block a user