rewuite to use async
This commit is contained in:
parent
fefda571d6
commit
242d32639a
8
.babelrc
8
.babelrc
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"presets": [
|
|
||||||
"@babel/preset-env"
|
|
||||||
],
|
|
||||||
"plugins": [
|
|
||||||
"dynamic-import-node"
|
|
||||||
]
|
|
||||||
}
|
|
51
package.json
51
package.json
@ -21,9 +21,20 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "^7.8.4",
|
"@babel/cli": "^7.8.4",
|
||||||
"@babel/core": "^7.8.4",
|
"@babel/core": "7.7.7",
|
||||||
"@babel/node": "^7.8.4",
|
"@babel/node": "^7.8.7",
|
||||||
"@babel/preset-env": "^7.8.4",
|
"@babel/plugin-proposal-class-properties": "7.7.4",
|
||||||
|
"@babel/plugin-proposal-decorators": "7.7.4",
|
||||||
|
"@babel/plugin-proposal-export-namespace-from": "7.7.4",
|
||||||
|
"@babel/plugin-proposal-function-sent": "7.7.4",
|
||||||
|
"@babel/plugin-proposal-json-strings": "7.7.4",
|
||||||
|
"@babel/plugin-proposal-numeric-separator": "7.7.4",
|
||||||
|
"@babel/plugin-proposal-object-rest-spread": "^7.9.5",
|
||||||
|
"@babel/plugin-proposal-throw-expressions": "7.7.4",
|
||||||
|
"@babel/plugin-syntax-dynamic-import": "7.7.4",
|
||||||
|
"@babel/plugin-syntax-import-meta": "7.7.4",
|
||||||
|
"@babel/plugin-transform-runtime": "^7.9.0",
|
||||||
|
"@babel/preset-env": "^7.9.0",
|
||||||
"babel-jest": "^25.1.0",
|
"babel-jest": "^25.1.0",
|
||||||
"babel-plugin-dynamic-import-node": "^2.3.0",
|
"babel-plugin-dynamic-import-node": "^2.3.0",
|
||||||
"jest": "^25.1.0",
|
"jest": "^25.1.0",
|
||||||
@ -32,6 +43,38 @@
|
|||||||
"wait-for-expect": "^3.0.2"
|
"wait-for-expect": "^3.0.2"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"testPathIgnorePatterns": ["dist"]
|
"testPathIgnorePatterns": [
|
||||||
|
"dist"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"babel": {
|
||||||
|
"presets": [
|
||||||
|
[
|
||||||
|
"@babel/preset-env",
|
||||||
|
{
|
||||||
|
"targets": {
|
||||||
|
"node": "12"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"@babel/plugin-syntax-dynamic-import",
|
||||||
|
"@babel/plugin-syntax-import-meta",
|
||||||
|
"@babel/plugin-proposal-class-properties",
|
||||||
|
"@babel/plugin-proposal-json-strings",
|
||||||
|
[
|
||||||
|
"@babel/plugin-proposal-decorators",
|
||||||
|
{
|
||||||
|
"legacy": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"@babel/plugin-proposal-function-sent",
|
||||||
|
"@babel/plugin-proposal-export-namespace-from",
|
||||||
|
"@babel/plugin-proposal-numeric-separator",
|
||||||
|
"@babel/plugin-proposal-throw-expressions",
|
||||||
|
"@babel/plugin-proposal-object-rest-spread",
|
||||||
|
"@babel/plugin-transform-runtime"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
435
src/bot.js
435
src/bot.js
@ -10,22 +10,18 @@ import * as matrix from "matrix-js-sdk";
|
|||||||
|
|
||||||
import logger from "./logger";
|
import logger from "./logger";
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
class OcrccBot {
|
class OcrccBot {
|
||||||
constructor() {
|
constructor(botConfig) {
|
||||||
|
this.config = botConfig
|
||||||
this.awaitingFacilitator = {};
|
this.awaitingFacilitator = {};
|
||||||
this.client = matrix.createClient(process.env.MATRIX_SERVER_URL);
|
this.client = matrix.createClient(this.config.MATRIX_SERVER_URL);
|
||||||
this.joinedRooms = [];
|
this.joinedRooms = [];
|
||||||
this.activeChatrooms = {};
|
this.activeChatrooms = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
createLocalStorage() {
|
createLocalStorage() {
|
||||||
const storageLoc = `matrix-chatbot-${process.env.BOT_USERNAME}`;
|
const storageLoc = `matrix-chatbot-${this.config.BOT_USERNAME}`;
|
||||||
const dir = path.resolve(path.join(os.homedir(), ".local-storage"));
|
const dir = path.resolve(path.join(os.homedir(), ".local-storage"));
|
||||||
if (!fs.existsSync(dir)) {
|
if (!fs.existsSync(dir)) {
|
||||||
fs.mkdirSync(dir);
|
fs.mkdirSync(dir);
|
||||||
@ -44,150 +40,102 @@ class OcrccBot {
|
|||||||
this.sendMessage(roomId, content);
|
this.sendMessage(roomId, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessage(roomId, content) {
|
async sendMessage(roomId, content) {
|
||||||
|
logger.log("info", `SENDING MESSAGE: ${content.body}`)
|
||||||
return this.client.sendMessage(roomId, content).catch(err => {
|
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 => {
|
||||||
Object.keys(err.devices[userId]).map(deviceId => {
|
Object.keys(err.devices[userId]).map(async deviceId => {
|
||||||
this.client.setDeviceVerified(userId, deviceId, true);
|
await this.client.setDeviceVerified(userId, deviceId, true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return this.sendMessage(roomId, content);
|
return this.sendMessage(roomId, content);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logger.log("error", `ERROR SENDING MESSAGE: ${err}`);
|
logger.log("error", `ERROR SENDING MESSAGE: ${err}`);
|
||||||
this.handleBotCrash(roomId, err);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
inviteUserToRoom(client, roomId, member, retries = 0) {
|
inviteUserToRoom(roomId, member) {
|
||||||
logger.log("info", "INVITING MEMBER: " + member);
|
try {
|
||||||
if (retries > MAX_RETRIES) {
|
this.client.invite(roomId, member)
|
||||||
this.handleBotCrash(roomId, "Rate limit exceeded for bot account");
|
} catch(err) {
|
||||||
return logger.log(
|
this.handleBotCrash(roomId, err);
|
||||||
"error",
|
|
||||||
`RATE LIMIT EXCEEDED AND RETRY LIMIT EXCEEDED`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return client.invite(roomId, member).catch(err => {
|
|
||||||
switch (err["name"]) {
|
|
||||||
case "M_LIMIT_EXCEEDED":
|
|
||||||
logger.log("info", "Rate limit exceeded, retrying.");
|
|
||||||
const retryCount = retries + 1;
|
|
||||||
const delay = retryCount * 2 * 1000;
|
|
||||||
return setTimeout(
|
|
||||||
this.inviteUserToRoom,
|
|
||||||
delay,
|
|
||||||
client,
|
|
||||||
roomId,
|
|
||||||
member,
|
|
||||||
retryCount
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
logger.log("error", `ERROR INVITING MEMBER: ${err}`);
|
|
||||||
this.handleBotCrash(roomId, err);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kickUserFromRoom(client, roomId, member, retries = 0) {
|
kickUserFromRoom(roomId, member) {
|
||||||
logger.log("info", "KICKING OUT MEMBER: " + member);
|
try {
|
||||||
if (retries > MAX_RETRIES) {
|
this.client.kick(roomId, member, this.config.KICK_REASON)
|
||||||
this.handleBotCrash(roomId, "Rate limit exceeded for bot account.");
|
} catch(err) {
|
||||||
return logger.log(
|
this.handleBotCrash(roomId, err);
|
||||||
"error",
|
logger.log("error", `ERROR KICKING OUT MEMBER: ${err}`);
|
||||||
`RATE LIMIT EXCEEDED AND RETRY LIMIT EXCEEDED`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return client.kick(roomId, member, KICK_REASON).catch(err => {
|
|
||||||
switch (err["name"]) {
|
|
||||||
case "M_LIMIT_EXCEEDED":
|
|
||||||
logger.log("info", "Rate limit exceeded, retrying.");
|
|
||||||
const retryCount = retries + 1;
|
|
||||||
const delay = retryCount * 2 * 1000;
|
|
||||||
return setTimeout(
|
|
||||||
this.kickUserFromRoom,
|
|
||||||
delay,
|
|
||||||
client,
|
|
||||||
roomId,
|
|
||||||
member,
|
|
||||||
retryCount
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
this.handleBotCrash(roomId, err);
|
|
||||||
logger.log("error", `ERROR KICKING OUT MEMBER: ${err}`);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inviteFacilitators(roomId) {
|
async inviteFacilitators(roomId) {
|
||||||
this.awaitingFacilitator[roomId] = true;
|
this.awaitingFacilitator[roomId] = true;
|
||||||
let chatOffline = true;
|
let chatOffline = true;
|
||||||
this.client
|
|
||||||
.getGroupUsers(process.env.FACILITATOR_GROUP_ID)
|
try {
|
||||||
.then(res => {
|
const data = await this.client.getGroupUsers(this.config.FACILITATOR_GROUP_ID)
|
||||||
const members = res.chunk;
|
const members = data.chunk
|
||||||
let onlineMembersCount = 0;
|
|
||||||
members.forEach(member => {
|
members.forEach(member => {
|
||||||
const memberId = member.user_id;
|
const memberId = member.user_id;
|
||||||
const user = this.client.getUser(memberId);
|
const user = this.client.getUser(memberId);
|
||||||
if (
|
if (
|
||||||
user &&
|
user &&
|
||||||
user.presence === "online" &&
|
user.presence === "online" &&
|
||||||
memberId !== process.env.BOT_USERID
|
memberId !== this.config.BOT_USERID
|
||||||
) {
|
) {
|
||||||
chatOffline = false;
|
chatOffline = false;
|
||||||
this.inviteUserToRoom(this.client, roomId, memberId);
|
this.inviteUserToRoom(roomId, memberId);
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
if (chatOffline) {
|
|
||||||
this.sendTextMessage(roomId, process.env.CHAT_OFFLINE_MESSAGE);
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
this.handleBotCrash(roomId, err);
|
|
||||||
logger.log("error", `ERROR GETTING FACILITATORS: ${err}`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (chatOffline) {
|
||||||
|
logger.log('info', "CHAT OFFLINE!")
|
||||||
|
this.sendTextMessage(roomId, this.config.CHAT_OFFLINE_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch(err) {
|
||||||
|
this.handleBotCrash(roomId, err);
|
||||||
|
logger.log("error", `ERROR GETTING FACILITATORS: ${err}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uninviteFacilitators(roomId) {
|
async uninviteFacilitators(roomId) {
|
||||||
this.awaitingFacilitator[roomId] = false;
|
this.awaitingFacilitator[roomId] = false;
|
||||||
this.client
|
|
||||||
.getGroupUsers(process.env.FACILITATOR_GROUP_ID)
|
try {
|
||||||
.then(groupUsers => {
|
const groupUsers = await this.client.getGroupUsers(this.config.FACILITATOR_GROUP_ID)
|
||||||
this.client.getJoinedRoomMembers(roomId).then(roomMembers => {
|
const roomMembers = await this.client.getJoinedRoomMembers(roomId)
|
||||||
const membersIds = Object.keys(roomMembers["joined"]);
|
|
||||||
const facilitators = groupUsers.chunk;
|
const membersIds = Object.keys(roomMembers["joined"]);
|
||||||
const facilitatorsIds = facilitators.map(f => f.user_id);
|
const facilitatorsIds = groupUsers.chunk.map(f => f.user_id);
|
||||||
facilitatorsIds.forEach(f => {
|
|
||||||
if (!membersIds.includes(f)) {
|
facilitatorsIds.forEach(f => {
|
||||||
this.kickUserFromRoom(this.client, roomId, f);
|
if (!membersIds.includes(f)) {
|
||||||
}
|
this.kickUserFromRoom(roomId, f);
|
||||||
});
|
}
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
this.handleBotCrash(roomId, err);
|
|
||||||
logger.log("error", err);
|
|
||||||
});
|
});
|
||||||
|
} catch(err) {
|
||||||
|
this.handleBotCrash(roomId, err);
|
||||||
|
logger.log("ERROR UNINVITING FACILITATORS", err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleBotCrash(roomId, error) {
|
handleBotCrash(roomId, error) {
|
||||||
if (roomId) {
|
if (roomId) {
|
||||||
this.sendTextMessage(roomId, BOT_ERROR_MESSAGE);
|
this.sendTextMessage(roomId, this.config.BOT_ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sendTextMessage(
|
this.sendTextMessage(
|
||||||
process.env.FACILITATOR_ROOM_ID,
|
this.config.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.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -206,7 +154,7 @@ class OcrccBot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// write to transcript
|
// write to transcript
|
||||||
if (process.env.CAPTURE_TRANSCRIPTS) {
|
if (this.config.CAPTURE_TRANSCRIPTS) {
|
||||||
return this.writeToTranscript(event);
|
return this.writeToTranscript(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -268,109 +216,112 @@ class OcrccBot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sendTranscript(senderId, roomId) {
|
async sendTranscript(senderId, roomId) {
|
||||||
const transcriptFile = this.activeChatrooms[roomId]
|
try {
|
||||||
? this.activeChatrooms[roomId].transcriptFile
|
const transcriptFile = this.activeChatrooms[roomId]
|
||||||
: false;
|
? this.activeChatrooms[roomId].transcriptFile
|
||||||
if (!transcriptFile) {
|
: false;
|
||||||
this.sendTextMessage(
|
if (!transcriptFile) {
|
||||||
roomId,
|
this.sendTextMessage(
|
||||||
"There is no transcript for this chat.",
|
roomId,
|
||||||
senderId
|
"There is no transcript for this chat.",
|
||||||
);
|
senderId
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const filename = path.basename(transcriptFile) || "Transcript";
|
const filename = path.basename(transcriptFile) || "Transcript";
|
||||||
const stream = fs.createReadStream(transcriptFile);
|
const stream = fs.createReadStream(transcriptFile);
|
||||||
|
|
||||||
this.client
|
const contentUrl = await this.client.uploadContent({
|
||||||
.uploadContent({
|
|
||||||
stream: stream,
|
stream: stream,
|
||||||
name: filename
|
name: filename
|
||||||
})
|
})
|
||||||
.then(contentUrl => {
|
|
||||||
const content = {
|
|
||||||
msgtype: "m.file",
|
|
||||||
body: filename,
|
|
||||||
url: JSON.parse(contentUrl).content_uri,
|
|
||||||
showToUser: senderId
|
|
||||||
};
|
|
||||||
|
|
||||||
this.sendMessage(roomId, content);
|
const content = {
|
||||||
})
|
msgtype: "m.file",
|
||||||
.catch(err => {
|
body: filename,
|
||||||
logger.log("error", `ERROR UPLOADING CONTENT: ${err}`);
|
url: JSON.parse(contentUrl).content_uri,
|
||||||
this.sendTextMessage(
|
showToUser: senderId
|
||||||
roomId,
|
};
|
||||||
"There was an error uploading the transcript.",
|
|
||||||
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() {
|
async deleteOldDevices() {
|
||||||
return this.client.getDevices().then(data => {
|
const currentDeviceId = this.client.getDeviceId();
|
||||||
const currentDeviceId = this.client.getDeviceId();
|
const deviceData = await this.client.getDevices()
|
||||||
const allDeviceIds = data.devices.map(d => d.device_id);
|
const allDeviceIds = deviceData.devices.map(d => d.device_id)
|
||||||
const oldDevices = allDeviceIds.filter(id => id !== currentDeviceId);
|
const oldDevices = allDeviceIds.filter(id => id !== currentDeviceId);
|
||||||
logger.log("info", `DELETING OLD DEVICES: ${oldDevices}`);
|
|
||||||
this.client.deleteMultipleDevices(oldDevices).catch(err => {
|
try {
|
||||||
const auth = {
|
await this.client.deleteMultipleDevices(oldDevices)
|
||||||
session: err.data.session,
|
} catch(err) {
|
||||||
type: "m.login.password",
|
logger.log("info", "RETRYING DELETE OLD DEVICES WITH AUTH")
|
||||||
user: process.env.BOT_USERID,
|
const auth = {
|
||||||
identifier: { type: "m.id.user", user: process.env.BOT_USERID },
|
session: err.data.session,
|
||||||
password: process.env.BOT_PASSWORD
|
type: "m.login.password",
|
||||||
};
|
user: this.config.BOT_USERID,
|
||||||
this.client
|
identifier: { type: "m.id.user", user: this.config.BOT_USERID },
|
||||||
.deleteMultipleDevices(oldDevices, auth)
|
password: this.config.BOT_PASSWORD
|
||||||
.then(() => logger.log("info", "DELETED OLD DEVICES"))
|
};
|
||||||
.catch(err => {
|
|
||||||
if (err.errcode === "M_LIMIT_EXCEEDED") {
|
await this.client.deleteMultipleDevices(oldDevices, auth)
|
||||||
const delay = err.retry_after_ms || 2000;
|
logger.log("info", "DELETED OLD DEVICES")
|
||||||
logger.log("info", `RETRYING DELETE OLD DEVICES: ${oldDevices}`);
|
}
|
||||||
setTimeout(() => {
|
|
||||||
this.client.deleteMultipleDevices(oldDevices);
|
|
||||||
}, delay);
|
|
||||||
} else {
|
|
||||||
logger.log(
|
|
||||||
"error",
|
|
||||||
`ERROR DELETING OLD DEVICES: ${JSON.stringify(err.data)}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setMembershipListeners() {
|
async leaveOldRooms() {
|
||||||
|
const roomData = await this.client.getJoinedRooms()
|
||||||
|
const joinedRoomsIds = roomData["joined_rooms"]
|
||||||
|
this.joinedRooms = joinedRoomsIds
|
||||||
|
|
||||||
|
logger.log("info", `LEAVING ROOMS ${joinedRoomsIds}`)
|
||||||
|
|
||||||
|
joinedRoomsIds.forEach(async(roomId) => {
|
||||||
|
if (roomId === this.config.FACILITATOR_ROOM_ID) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.client.leave(roomId)
|
||||||
|
} catch(err) {
|
||||||
|
logger.log("error", `ERROR LEAVING ROOM => ${err}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async setMembershipListeners() {
|
||||||
// Automatically accept all room invitations
|
// Automatically accept all room invitations
|
||||||
return this.client.on("RoomMember.membership", (event, member) => {
|
this.client.on("RoomMember.membership", async (event, member) => {
|
||||||
if (
|
if (
|
||||||
member.membership === "invite" &&
|
member.membership === "invite" &&
|
||||||
member.userId === process.env.BOT_USERID &&
|
member.userId === this.config.BOT_USERID &&
|
||||||
!this.joinedRooms.includes(member.roomId)
|
!this.joinedRooms.includes(member.roomId)
|
||||||
) {
|
) {
|
||||||
logger.log("info", "Auto-joining room " + member.roomId);
|
try {
|
||||||
this.client
|
logger.log("info", "Auto-joining room " + member.roomId);
|
||||||
.joinRoom(member.roomId)
|
const room = await this.client.joinRoom(member.roomId)
|
||||||
.then(room => {
|
this.sendTextMessage(
|
||||||
this.sendTextMessage(
|
this.config.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})`
|
);
|
||||||
);
|
this.inviteFacilitators(member.roomId)
|
||||||
})
|
} catch(err) {
|
||||||
.then(() => this.inviteFacilitators(member.roomId))
|
logger.log("error", err);
|
||||||
.catch(err => {
|
}
|
||||||
logger.log("error", err);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When a facilitator joins a support session, make them a moderator
|
// When a facilitator joins a support session, make them a moderator
|
||||||
// revoke the other invitations
|
// revoke the other invitations
|
||||||
if (
|
if (
|
||||||
member.membership === "join" &&
|
member.membership === "join" &&
|
||||||
member.userId !== process.env.BOT_USERID &&
|
member.userId !== this.config.BOT_USERID &&
|
||||||
this.awaitingFacilitator[member.roomId]
|
this.awaitingFacilitator[member.roomId]
|
||||||
) {
|
) {
|
||||||
this.activeChatrooms[member.roomId] = {
|
this.activeChatrooms[member.roomId] = {
|
||||||
@ -383,7 +334,7 @@ class OcrccBot {
|
|||||||
getContent: () => {
|
getContent: () => {
|
||||||
return {
|
return {
|
||||||
users: {
|
users: {
|
||||||
[process.env.BOT_USERID]: 100,
|
[this.config.BOT_USERID]: 100,
|
||||||
[member.userId]: 50
|
[member.userId]: 50
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -395,11 +346,11 @@ class OcrccBot {
|
|||||||
`${member.name} has joined the chat.`
|
`${member.name} has joined the chat.`
|
||||||
);
|
);
|
||||||
this.sendTextMessage(
|
this.sendTextMessage(
|
||||||
process.env.FACILITATOR_ROOM_ID,
|
this.config.FACILITATOR_ROOM_ID,
|
||||||
`${member.name} joined the chat (Room ID: ${member.roomId})`
|
`${member.name} joined the chat (Room ID: ${member.roomId})`
|
||||||
);
|
);
|
||||||
this.uninviteFacilitators(member.roomId);
|
this.uninviteFacilitators(member.roomId);
|
||||||
if (process.env.CAPTURE_TRANSCRIPTS) {
|
if (this.config.CAPTURE_TRANSCRIPTS) {
|
||||||
const currentDate = new Date();
|
const currentDate = new Date();
|
||||||
const dateOpts = {
|
const dateOpts = {
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
@ -418,7 +369,7 @@ class OcrccBot {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
member.membership === "leave" &&
|
member.membership === "leave" &&
|
||||||
member.userId !== process.env.BOT_USERID &&
|
member.userId !== this.config.BOT_USERID &&
|
||||||
this.activeChatrooms[member.roomId] &&
|
this.activeChatrooms[member.roomId] &&
|
||||||
member.userId === this.activeChatrooms[member.roomId].facilitator
|
member.userId === this.activeChatrooms[member.roomId].facilitator
|
||||||
) {
|
) {
|
||||||
@ -426,6 +377,14 @@ class OcrccBot {
|
|||||||
member.roomId,
|
member.roomId,
|
||||||
`${member.name} has left the chat.`
|
`${member.name} has left the chat.`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const room = this.client.getRoom(member.roomId)
|
||||||
|
const memberCount = room.getJoinedMemberCount()
|
||||||
|
|
||||||
|
if (memberCount === 1) {
|
||||||
|
logger.log("info", `LEAVING EMPTY ROOM ==> ${member.roomId}`);
|
||||||
|
this.client.leave(event.roomId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -448,54 +407,38 @@ class OcrccBot {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
async start() {
|
||||||
const localStorage = this.createLocalStorage();
|
const localStorage = this.createLocalStorage();
|
||||||
|
|
||||||
this.client
|
try {
|
||||||
.login("m.login.password", {
|
const auth = {
|
||||||
user: process.env.BOT_USERNAME,
|
user: this.config.BOT_USERNAME,
|
||||||
password: process.env.BOT_PASSWORD,
|
password: this.config.BOT_PASSWORD,
|
||||||
initial_device_display_name: process.env.BOT_DISPLAY_NAME
|
initial_device_display_name: this.config.BOT_DISPLAY_NAME
|
||||||
})
|
}
|
||||||
.then(data => {
|
const account = await this.client.login("m.login.password", auth)
|
||||||
const accessToken = data.access_token;
|
logger.log("info", `ACCOUNT ==> ${JSON.stringify(account)}`);
|
||||||
const deviceId = data.device_id;
|
|
||||||
logger.log("info", `LOGIN DATA ==> ${JSON.stringify(data)}`);
|
|
||||||
|
|
||||||
// create new client with full options
|
let opts = {
|
||||||
|
baseUrl: this.config.MATRIX_SERVER_URL,
|
||||||
|
accessToken: account.access_token,
|
||||||
|
userId: this.config.BOT_USERID,
|
||||||
|
deviceId: account.device_id,
|
||||||
|
sessionStore: new matrix.WebStorageSessionStore(localStorage)
|
||||||
|
};
|
||||||
|
|
||||||
let opts = {
|
this.client = matrix.createClient(opts);
|
||||||
baseUrl: process.env.MATRIX_SERVER_URL,
|
await this.deleteOldDevices()
|
||||||
accessToken: accessToken,
|
await this.leaveOldRooms();
|
||||||
userId: process.env.BOT_USERID,
|
await this.client.initCrypto()
|
||||||
deviceId: deviceId,
|
|
||||||
sessionStore: new matrix.WebStorageSessionStore(localStorage)
|
|
||||||
};
|
|
||||||
|
|
||||||
this.client = matrix.createClient(opts);
|
this.setMembershipListeners();
|
||||||
})
|
this.setMessageListeners();
|
||||||
.catch(err => {
|
this.client.startClient({ initialSyncLimit: 0 })
|
||||||
logger.log("error", `ERROR WITH LOGIN: ${err}`);
|
} catch(err) {
|
||||||
})
|
this.handleBotCrash(undefined, err);
|
||||||
.then(() => {
|
logger.log("error", `ERROR INITIALIZING CLIENT: ${err}`);
|
||||||
this.deleteOldDevices();
|
}
|
||||||
})
|
|
||||||
.then(() => this.client.initCrypto())
|
|
||||||
.catch(err => logger.log("error", `ERROR STARTING CRYPTO: ${err}`))
|
|
||||||
.then(() =>
|
|
||||||
this.client.getJoinedRooms().then(data => {
|
|
||||||
this.joinedRooms = data["joined_rooms"];
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.then(() => {
|
|
||||||
this.setMembershipListeners();
|
|
||||||
this.setMessageListeners();
|
|
||||||
})
|
|
||||||
.then(() => this.client.startClient({ initialSyncLimit: 0 }))
|
|
||||||
.catch(err => {
|
|
||||||
this.handleBotCrash(undefined, err);
|
|
||||||
logger.log("error", `ERROR INITIALIZING CLIENT: ${err}`);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
35
src/index.js
35
src/index.js
@ -1,6 +1,39 @@
|
|||||||
require('dotenv').config()
|
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_GROUP_ID,
|
||||||
|
FACILITATOR_ROOM_ID,
|
||||||
|
CHAT_OFFLINE_MESSAGE,
|
||||||
|
CAPTURE_TRANSCRIPTS
|
||||||
|
} = 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_GROUP_ID,
|
||||||
|
FACILITATOR_ROOM_ID,
|
||||||
|
CHAT_OFFLINE_MESSAGE,
|
||||||
|
CAPTURE_TRANSCRIPTS
|
||||||
|
}
|
||||||
|
|
||||||
import OcrccBot from './bot'
|
import OcrccBot from './bot'
|
||||||
|
|
||||||
const bot = new OcrccBot();
|
const bot = new OcrccBot(botConfig);
|
||||||
bot.start();
|
bot.start();
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
@help-bot:rhok.space [17:39:36]: Facilitator Demo Account has joined the chat.
|
|
||||||
@ocrcc-facilitator-demo:rhok.space [17:39:48]: heyooo
|
|
||||||
@help-bot:rhok.space [17:41:13]: Bleep bloop
|
|
||||||
@help-bot:rhok.space [17:41:21]: 20 Mar 2020 - 17:39:35 - !HyOQxerRxiwlUBolJA:rhok.space.txt
|
|
||||||
@95326bf0-cd5e-45d7-be64-cb413d37d929:rhok.space [17:42:01]: hi
|
|
Loading…
Reference in New Issue
Block a user