- Modified shared.ts to maintain a Map of clients per accountId - Each account gets its own Matrix client instance - Backwards compatible with single-account usage - resolveMatrixAuth now accepts accountId parameter - stopSharedClient can stop specific or all accounts Files changed: - src/matrix/client/shared.ts (main changes) - src/matrix/client/config.ts (accountId support) - src/matrix/accounts.ts (list enabled accounts) - src/matrix/monitor/index.ts (pass accountId) - src/types.ts (accounts config type)
120 lines
3.4 KiB
TypeScript
120 lines
3.4 KiB
TypeScript
import {
|
|
EventType,
|
|
MsgType,
|
|
RelationType,
|
|
type MatrixActionClientOpts,
|
|
type MatrixMessageSummary,
|
|
type MatrixRawEvent,
|
|
type RoomMessageEventContent,
|
|
} from "./types.js";
|
|
import { resolveActionClient } from "./client.js";
|
|
import { summarizeMatrixRawEvent } from "./summary.js";
|
|
import { resolveMatrixRoomId, sendMessageMatrix } from "../send.js";
|
|
|
|
export async function sendMatrixMessage(
|
|
to: string,
|
|
content: string,
|
|
opts: MatrixActionClientOpts & {
|
|
mediaUrl?: string;
|
|
replyToId?: string;
|
|
threadId?: string;
|
|
} = {},
|
|
) {
|
|
return await sendMessageMatrix(to, content, {
|
|
mediaUrl: opts.mediaUrl,
|
|
replyToId: opts.replyToId,
|
|
threadId: opts.threadId,
|
|
client: opts.client,
|
|
timeoutMs: opts.timeoutMs,
|
|
});
|
|
}
|
|
|
|
export async function editMatrixMessage(
|
|
roomId: string,
|
|
messageId: string,
|
|
content: string,
|
|
opts: MatrixActionClientOpts = {},
|
|
) {
|
|
const trimmed = content.trim();
|
|
if (!trimmed) throw new Error("Matrix edit requires content");
|
|
const { client, stopOnDone } = await resolveActionClient(opts);
|
|
try {
|
|
const resolvedRoom = await resolveMatrixRoomId(client, roomId);
|
|
const newContent = {
|
|
msgtype: MsgType.Text,
|
|
body: trimmed,
|
|
} satisfies RoomMessageEventContent;
|
|
const payload: RoomMessageEventContent = {
|
|
msgtype: MsgType.Text,
|
|
body: `* ${trimmed}`,
|
|
"m.new_content": newContent,
|
|
"m.relates_to": {
|
|
rel_type: RelationType.Replace,
|
|
event_id: messageId,
|
|
},
|
|
};
|
|
const eventId = await client.sendMessage(resolvedRoom, payload);
|
|
return { eventId: eventId ?? null };
|
|
} finally {
|
|
if (stopOnDone) client.stop();
|
|
}
|
|
}
|
|
|
|
export async function deleteMatrixMessage(
|
|
roomId: string,
|
|
messageId: string,
|
|
opts: MatrixActionClientOpts & { reason?: string } = {},
|
|
) {
|
|
const { client, stopOnDone } = await resolveActionClient(opts);
|
|
try {
|
|
const resolvedRoom = await resolveMatrixRoomId(client, roomId);
|
|
await client.redactEvent(resolvedRoom, messageId, opts.reason);
|
|
} finally {
|
|
if (stopOnDone) client.stop();
|
|
}
|
|
}
|
|
|
|
export async function readMatrixMessages(
|
|
roomId: string,
|
|
opts: MatrixActionClientOpts & {
|
|
limit?: number;
|
|
before?: string;
|
|
after?: string;
|
|
} = {},
|
|
): Promise<{
|
|
messages: MatrixMessageSummary[];
|
|
nextBatch?: string | null;
|
|
prevBatch?: string | null;
|
|
}> {
|
|
const { client, stopOnDone } = await resolveActionClient(opts);
|
|
try {
|
|
const resolvedRoom = await resolveMatrixRoomId(client, roomId);
|
|
const limit =
|
|
typeof opts.limit === "number" && Number.isFinite(opts.limit)
|
|
? Math.max(1, Math.floor(opts.limit))
|
|
: 20;
|
|
const token = opts.before?.trim() || opts.after?.trim() || undefined;
|
|
const dir = opts.after ? "f" : "b";
|
|
// @vector-im/matrix-bot-sdk uses doRequest for room messages
|
|
const res = await client.doRequest(
|
|
"GET",
|
|
`/_matrix/client/v3/rooms/${encodeURIComponent(resolvedRoom)}/messages`,
|
|
{
|
|
dir,
|
|
limit,
|
|
from: token,
|
|
},
|
|
) as { chunk: MatrixRawEvent[]; start?: string; end?: string };
|
|
const messages = res.chunk
|
|
.filter((event) => event.type === EventType.RoomMessage)
|
|
.filter((event) => !event.unsigned?.redacted_because)
|
|
.map(summarizeMatrixRawEvent);
|
|
return {
|
|
messages,
|
|
nextBatch: res.end ?? null,
|
|
prevBatch: res.start ?? null,
|
|
};
|
|
} finally {
|
|
if (stopOnDone) client.stop();
|
|
}
|
|
}
|