aslobot-matrix/src/modules/module.ts

133 lines
3.6 KiB
TypeScript

import {
MatrixClient,
MatrixEvent,
RoomEvent,
type IContent,
} from "matrix-js-sdk";
import type { ICallback, ICallbackStore } from "./types.js";
import { registerModuleBase } from "./base/base.js";
import { registerModuleAdmin } from "./admin/admin.js";
import { registerModuleUser } from "./user/user.js";
import { registerModuleAI } from "./ai/ai.js";
import { checkRoles, getUserById } from "../helpers.js";
import { onAnyMessage, onMissingRole } from "./global.js";
import { config } from "../config.js";
const callbacks: ICallbackStore = {
messageCallbacks: [],
};
const checkMessageCallback = (
client: MatrixClient,
text: string,
callback: ICallback,
roomId: string,
sender: string,
) => {
if (callback.allowedRooms && !callback.allowedRooms.includes(roomId)) {
return false;
}
if (
callback.startConditions &&
!callback.startConditions.some((condition) =>
text.toLowerCase().startsWith(condition),
)
) {
return false;
}
if (
callback.includesConditions &&
!callback.includesConditions.some((condition) =>
text.toLowerCase().includes(condition),
)
) {
return false;
}
if (callback.allowedRoles && !checkRoles(callback.allowedRoles, sender)) {
onMissingRole(client, getUserById(sender).role, roomId);
return false;
}
return true;
};
const registerModules = (client: MatrixClient) => {
const startupTime = Date.now();
client.on(RoomEvent.Timeline, async (event: MatrixEvent) => {
const ts = event.getTs();
if (ts < startupTime) {
return;
}
if (event.getType() !== "m.room.message") {
return;
}
const content = event.getContent<IContent>();
const body = content?.body;
if (!body || !client) {
return;
}
const roomId = event.getRoomId();
const sender = event.getSender();
if (!roomId || !sender) {
return;
}
if (sender === config.userId) {
return;
}
const relatesTo = event.getContent()["m.relates_to"];
const replyToId = relatesTo?.["m.in_reply_to"]?.event_id;
let repliedMessage: string | undefined;
if (replyToId) {
const repliedEvent = await client.fetchRoomEvent(roomId, replyToId);
const repliedContent = repliedEvent.content;
if (repliedContent) {
if (repliedContent.body) {
repliedMessage = repliedContent.body.toString();
} else if (repliedContent.formatted_body) {
repliedMessage = repliedContent.formatted_body.toString();
}
}
}
console.log(`Message from ${sender} in ${roomId}: ${body}`);
onAnyMessage(client, body.toString(), roomId, sender);
callbacks.messageCallbacks.forEach((callback) => {
if (
checkMessageCallback(
client,
body.toString(),
callback,
roomId,
sender,
)
) {
callback.callbackFunc(
body.toString(),
roomId,
sender,
repliedMessage,
);
}
});
});
registerModuleBase(client, callbacks);
registerModuleAdmin(client, callbacks);
registerModuleUser(client, callbacks);
registerModuleAI(client, callbacks);
};
export { registerModules };