@openclaw/matrix 2026.1.29 → 2026.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/index.ts +0 -1
- package/openclaw.plugin.json +1 -3
- package/package.json +12 -12
- package/src/actions.ts +16 -6
- package/src/channel.directory.test.ts +13 -5
- package/src/channel.ts +61 -39
- package/src/directory-live.ts +21 -8
- package/src/group-mentions.ts +10 -5
- package/src/matrix/accounts.test.ts +0 -1
- package/src/matrix/accounts.ts +4 -2
- package/src/matrix/actions/client.ts +8 -4
- package/src/matrix/actions/messages.ts +17 -9
- package/src/matrix/actions/pins.ts +12 -6
- package/src/matrix/actions/reactions.ts +24 -12
- package/src/matrix/actions/room.ts +10 -13
- package/src/matrix/actions/summary.ts +4 -6
- package/src/matrix/client/config.ts +4 -9
- package/src/matrix/client/create-client.ts +12 -16
- package/src/matrix/client/logging.ts +17 -16
- package/src/matrix/client/shared.ts +6 -5
- package/src/matrix/client/storage.ts +12 -12
- package/src/matrix/client.test.ts +0 -1
- package/src/matrix/client.ts +1 -5
- package/src/matrix/credentials.ts +7 -5
- package/src/matrix/deps.ts +8 -5
- package/src/matrix/format.test.ts +0 -1
- package/src/matrix/monitor/allowlist.test.ts +45 -0
- package/src/matrix/monitor/allowlist.ts +62 -17
- package/src/matrix/monitor/auto-join.ts +7 -4
- package/src/matrix/monitor/direct.ts +11 -12
- package/src/matrix/monitor/events.ts +1 -3
- package/src/matrix/monitor/handler.ts +69 -53
- package/src/matrix/monitor/index.ts +118 -59
- package/src/matrix/monitor/location.ts +27 -10
- package/src/matrix/monitor/media.test.ts +1 -2
- package/src/matrix/monitor/media.ts +8 -8
- package/src/matrix/monitor/replies.ts +4 -3
- package/src/matrix/monitor/room-info.ts +5 -8
- package/src/matrix/monitor/rooms.test.ts +39 -0
- package/src/matrix/monitor/rooms.ts +7 -3
- package/src/matrix/monitor/threads.ts +6 -2
- package/src/matrix/poll-types.test.ts +0 -1
- package/src/matrix/poll-types.ts +16 -7
- package/src/matrix/send/client.ts +7 -4
- package/src/matrix/send/formatting.ts +14 -17
- package/src/matrix/send/media.ts +17 -8
- package/src/matrix/send/targets.test.ts +7 -11
- package/src/matrix/send/targets.ts +19 -27
- package/src/matrix/send.test.ts +1 -2
- package/src/matrix/send.ts +9 -4
- package/src/onboarding.ts +24 -14
- package/src/outbound.ts +1 -2
- package/src/resolve-targets.test.ts +48 -0
- package/src/resolve-targets.ts +55 -9
- package/src/tool-actions.ts +15 -11
- package/src/types.ts +5 -5
|
@@ -4,40 +4,89 @@ function normalizeAllowList(list?: Array<string | number>) {
|
|
|
4
4
|
return (list ?? []).map((entry) => String(entry).trim()).filter(Boolean);
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
function normalizeMatrixUser(raw?: string | null): string {
|
|
8
|
+
const value = (raw ?? "").trim();
|
|
9
|
+
if (!value) {
|
|
10
|
+
return "";
|
|
11
|
+
}
|
|
12
|
+
if (!value.startsWith("@") || !value.includes(":")) {
|
|
13
|
+
return value.toLowerCase();
|
|
14
|
+
}
|
|
15
|
+
const withoutAt = value.slice(1);
|
|
16
|
+
const splitIndex = withoutAt.indexOf(":");
|
|
17
|
+
if (splitIndex === -1) {
|
|
18
|
+
return value.toLowerCase();
|
|
19
|
+
}
|
|
20
|
+
const localpart = withoutAt.slice(0, splitIndex).toLowerCase();
|
|
21
|
+
const server = withoutAt.slice(splitIndex + 1).toLowerCase();
|
|
22
|
+
if (!server) {
|
|
23
|
+
return value.toLowerCase();
|
|
24
|
+
}
|
|
25
|
+
return `@${localpart}:${server.toLowerCase()}`;
|
|
9
26
|
}
|
|
10
27
|
|
|
11
|
-
function
|
|
12
|
-
|
|
28
|
+
export function normalizeMatrixUserId(raw?: string | null): string {
|
|
29
|
+
const trimmed = (raw ?? "").trim();
|
|
30
|
+
if (!trimmed) {
|
|
31
|
+
return "";
|
|
32
|
+
}
|
|
33
|
+
const lowered = trimmed.toLowerCase();
|
|
34
|
+
if (lowered.startsWith("matrix:")) {
|
|
35
|
+
return normalizeMatrixUser(trimmed.slice("matrix:".length));
|
|
36
|
+
}
|
|
37
|
+
if (lowered.startsWith("user:")) {
|
|
38
|
+
return normalizeMatrixUser(trimmed.slice("user:".length));
|
|
39
|
+
}
|
|
40
|
+
return normalizeMatrixUser(trimmed);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function normalizeMatrixAllowListEntry(raw: string): string {
|
|
44
|
+
const trimmed = raw.trim();
|
|
45
|
+
if (!trimmed) {
|
|
46
|
+
return "";
|
|
47
|
+
}
|
|
48
|
+
if (trimmed === "*") {
|
|
49
|
+
return trimmed;
|
|
50
|
+
}
|
|
51
|
+
const lowered = trimmed.toLowerCase();
|
|
52
|
+
if (lowered.startsWith("matrix:")) {
|
|
53
|
+
return `matrix:${normalizeMatrixUser(trimmed.slice("matrix:".length))}`;
|
|
54
|
+
}
|
|
55
|
+
if (lowered.startsWith("user:")) {
|
|
56
|
+
return `user:${normalizeMatrixUser(trimmed.slice("user:".length))}`;
|
|
57
|
+
}
|
|
58
|
+
return normalizeMatrixUser(trimmed);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function normalizeMatrixAllowList(list?: Array<string | number>) {
|
|
62
|
+
return normalizeAllowList(list).map((entry) => normalizeMatrixAllowListEntry(entry));
|
|
13
63
|
}
|
|
14
64
|
|
|
15
65
|
export type MatrixAllowListMatch = AllowlistMatch<
|
|
16
|
-
"wildcard" | "id" | "prefixed-id" | "prefixed-user"
|
|
66
|
+
"wildcard" | "id" | "prefixed-id" | "prefixed-user"
|
|
17
67
|
>;
|
|
18
68
|
|
|
19
69
|
export function resolveMatrixAllowListMatch(params: {
|
|
20
70
|
allowList: string[];
|
|
21
71
|
userId?: string;
|
|
22
|
-
userName?: string;
|
|
23
72
|
}): MatrixAllowListMatch {
|
|
24
73
|
const allowList = params.allowList;
|
|
25
|
-
if (allowList.length === 0)
|
|
74
|
+
if (allowList.length === 0) {
|
|
75
|
+
return { allowed: false };
|
|
76
|
+
}
|
|
26
77
|
if (allowList.includes("*")) {
|
|
27
78
|
return { allowed: true, matchKey: "*", matchSource: "wildcard" };
|
|
28
79
|
}
|
|
29
80
|
const userId = normalizeMatrixUser(params.userId);
|
|
30
|
-
const userName = normalizeMatrixUser(params.userName);
|
|
31
|
-
const localPart = userId.startsWith("@") ? (userId.slice(1).split(":")[0] ?? "") : "";
|
|
32
81
|
const candidates: Array<{ value?: string; source: MatrixAllowListMatch["matchSource"] }> = [
|
|
33
82
|
{ value: userId, source: "id" },
|
|
34
83
|
{ value: userId ? `matrix:${userId}` : "", source: "prefixed-id" },
|
|
35
84
|
{ value: userId ? `user:${userId}` : "", source: "prefixed-user" },
|
|
36
|
-
{ value: userName, source: "name" },
|
|
37
|
-
{ value: localPart, source: "localpart" },
|
|
38
85
|
];
|
|
39
86
|
for (const candidate of candidates) {
|
|
40
|
-
if (!candidate.value)
|
|
87
|
+
if (!candidate.value) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
41
90
|
if (allowList.includes(candidate.value)) {
|
|
42
91
|
return {
|
|
43
92
|
allowed: true,
|
|
@@ -49,10 +98,6 @@ export function resolveMatrixAllowListMatch(params: {
|
|
|
49
98
|
return { allowed: false };
|
|
50
99
|
}
|
|
51
100
|
|
|
52
|
-
export function resolveMatrixAllowListMatches(params: {
|
|
53
|
-
allowList: string[];
|
|
54
|
-
userId?: string;
|
|
55
|
-
userName?: string;
|
|
56
|
-
}) {
|
|
101
|
+
export function resolveMatrixAllowListMatches(params: { allowList: string[]; userId?: string }) {
|
|
57
102
|
return resolveMatrixAllowListMatch(params).allowed;
|
|
58
103
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { MatrixClient } from "@vector-im/matrix-bot-sdk";
|
|
2
|
-
import { AutojoinRoomsMixin } from "@vector-im/matrix-bot-sdk";
|
|
3
|
-
|
|
4
2
|
import type { RuntimeEnv } from "openclaw/plugin-sdk";
|
|
3
|
+
import { AutojoinRoomsMixin } from "@vector-im/matrix-bot-sdk";
|
|
5
4
|
import type { CoreConfig } from "../../types.js";
|
|
6
5
|
import { getMatrixRuntime } from "../../runtime.js";
|
|
7
6
|
|
|
@@ -13,7 +12,9 @@ export function registerMatrixAutoJoin(params: {
|
|
|
13
12
|
const { client, cfg, runtime } = params;
|
|
14
13
|
const core = getMatrixRuntime();
|
|
15
14
|
const logVerbose = (message: string) => {
|
|
16
|
-
if (!core.logging.shouldLogVerbose())
|
|
15
|
+
if (!core.logging.shouldLogVerbose()) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
17
18
|
runtime.log?.(message);
|
|
18
19
|
};
|
|
19
20
|
const autoJoin = cfg.channels?.matrix?.autoJoin ?? "always";
|
|
@@ -32,7 +33,9 @@ export function registerMatrixAutoJoin(params: {
|
|
|
32
33
|
|
|
33
34
|
// For "allowlist" mode, handle invites manually
|
|
34
35
|
client.on("room.invite", async (roomId: string, _inviteEvent: unknown) => {
|
|
35
|
-
if (autoJoin !== "allowlist")
|
|
36
|
+
if (autoJoin !== "allowlist") {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
36
39
|
|
|
37
40
|
// Get room alias if available
|
|
38
41
|
let alias: string | undefined;
|
|
@@ -12,17 +12,16 @@ type DirectRoomTrackerOptions = {
|
|
|
12
12
|
|
|
13
13
|
const DM_CACHE_TTL_MS = 30_000;
|
|
14
14
|
|
|
15
|
-
export function createDirectRoomTracker(
|
|
16
|
-
client: MatrixClient,
|
|
17
|
-
opts: DirectRoomTrackerOptions = {},
|
|
18
|
-
) {
|
|
15
|
+
export function createDirectRoomTracker(client: MatrixClient, opts: DirectRoomTrackerOptions = {}) {
|
|
19
16
|
const log = opts.log ?? (() => {});
|
|
20
17
|
let lastDmUpdateMs = 0;
|
|
21
18
|
let cachedSelfUserId: string | null = null;
|
|
22
19
|
const memberCountCache = new Map<string, { count: number; ts: number }>();
|
|
23
20
|
|
|
24
21
|
const ensureSelfUserId = async (): Promise<string | null> => {
|
|
25
|
-
if (cachedSelfUserId)
|
|
22
|
+
if (cachedSelfUserId) {
|
|
23
|
+
return cachedSelfUserId;
|
|
24
|
+
}
|
|
26
25
|
try {
|
|
27
26
|
cachedSelfUserId = await client.getUserId();
|
|
28
27
|
} catch {
|
|
@@ -33,7 +32,9 @@ export function createDirectRoomTracker(
|
|
|
33
32
|
|
|
34
33
|
const refreshDmCache = async (): Promise<void> => {
|
|
35
34
|
const now = Date.now();
|
|
36
|
-
if (now - lastDmUpdateMs < DM_CACHE_TTL_MS)
|
|
35
|
+
if (now - lastDmUpdateMs < DM_CACHE_TTL_MS) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
37
38
|
lastDmUpdateMs = now;
|
|
38
39
|
try {
|
|
39
40
|
await client.dms.update();
|
|
@@ -61,7 +62,9 @@ export function createDirectRoomTracker(
|
|
|
61
62
|
|
|
62
63
|
const hasDirectFlag = async (roomId: string, userId?: string): Promise<boolean> => {
|
|
63
64
|
const target = userId?.trim();
|
|
64
|
-
if (!target)
|
|
65
|
+
if (!target) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
65
68
|
try {
|
|
66
69
|
const state = await client.getRoomStateEvent(roomId, "m.room.member", target);
|
|
67
70
|
return state?.is_direct === true;
|
|
@@ -94,11 +97,7 @@ export function createDirectRoomTracker(
|
|
|
94
97
|
return true;
|
|
95
98
|
}
|
|
96
99
|
|
|
97
|
-
log(
|
|
98
|
-
`matrix: dm check room=${roomId} result=group members=${
|
|
99
|
-
memberCount ?? "unknown"
|
|
100
|
-
}`,
|
|
101
|
-
);
|
|
100
|
+
log(`matrix: dm check room=${roomId} result=group members=${memberCount ?? "unknown"}`);
|
|
102
101
|
return false;
|
|
103
102
|
},
|
|
104
103
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { MatrixClient } from "@vector-im/matrix-bot-sdk";
|
|
2
2
|
import type { PluginRuntime } from "openclaw/plugin-sdk";
|
|
3
|
-
|
|
4
3
|
import type { MatrixAuth } from "../client.js";
|
|
5
4
|
import type { MatrixRawEvent } from "./types.js";
|
|
6
5
|
import { EventType } from "./types.js";
|
|
@@ -84,8 +83,7 @@ export function registerMatrixMonitorEvents(params: {
|
|
|
84
83
|
const hint = formatNativeDependencyHint({
|
|
85
84
|
packageName: "@matrix-org/matrix-sdk-crypto-nodejs",
|
|
86
85
|
manager: "pnpm",
|
|
87
|
-
downloadCommand:
|
|
88
|
-
"node node_modules/@matrix-org/matrix-sdk-crypto-nodejs/download-lib.js",
|
|
86
|
+
downloadCommand: "node node_modules/@matrix-org/matrix-sdk-crypto-nodejs/download-lib.js",
|
|
89
87
|
});
|
|
90
88
|
const warning = `matrix: encryption enabled but crypto is unavailable; ${hint}`;
|
|
91
89
|
logger.warn({ roomId }, warning);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { LocationMessageEventContent, MatrixClient } from "@vector-im/matrix-bot-sdk";
|
|
2
|
-
|
|
3
2
|
import {
|
|
4
3
|
createReplyPrefixContext,
|
|
5
4
|
createTypingCallbacks,
|
|
@@ -10,25 +9,30 @@ import {
|
|
|
10
9
|
type RuntimeEnv,
|
|
11
10
|
} from "openclaw/plugin-sdk";
|
|
12
11
|
import type { CoreConfig, ReplyToMode } from "../../types.js";
|
|
12
|
+
import type { MatrixRawEvent, RoomMessageEventContent } from "./types.js";
|
|
13
13
|
import {
|
|
14
14
|
formatPollAsText,
|
|
15
15
|
isPollStartType,
|
|
16
16
|
parsePollStartContent,
|
|
17
17
|
type PollStartContent,
|
|
18
18
|
} from "../poll-types.js";
|
|
19
|
-
import { reactMatrixMessage, sendMessageMatrix, sendReadReceiptMatrix, sendTypingMatrix } from "../send.js";
|
|
20
19
|
import {
|
|
20
|
+
reactMatrixMessage,
|
|
21
|
+
sendMessageMatrix,
|
|
22
|
+
sendReadReceiptMatrix,
|
|
23
|
+
sendTypingMatrix,
|
|
24
|
+
} from "../send.js";
|
|
25
|
+
import {
|
|
26
|
+
normalizeMatrixAllowList,
|
|
21
27
|
resolveMatrixAllowListMatch,
|
|
22
28
|
resolveMatrixAllowListMatches,
|
|
23
|
-
normalizeAllowListLower,
|
|
24
29
|
} from "./allowlist.js";
|
|
30
|
+
import { resolveMatrixLocation, type MatrixLocationPayload } from "./location.js";
|
|
25
31
|
import { downloadMatrixMedia } from "./media.js";
|
|
26
32
|
import { resolveMentions } from "./mentions.js";
|
|
27
33
|
import { deliverMatrixReplies } from "./replies.js";
|
|
28
34
|
import { resolveMatrixRoomConfig } from "./rooms.js";
|
|
29
35
|
import { resolveMatrixThreadRootId, resolveMatrixThreadTarget } from "./threads.js";
|
|
30
|
-
import { resolveMatrixLocation, type MatrixLocationPayload } from "./location.js";
|
|
31
|
-
import type { MatrixRawEvent, RoomMessageEventContent } from "./types.js";
|
|
32
36
|
import { EventType, RelationType } from "./types.js";
|
|
33
37
|
|
|
34
38
|
export type MatrixMonitorHandlerParams = {
|
|
@@ -37,7 +41,7 @@ export type MatrixMonitorHandlerParams = {
|
|
|
37
41
|
logging: {
|
|
38
42
|
shouldLogVerbose: () => boolean;
|
|
39
43
|
};
|
|
40
|
-
channel: typeof import("openclaw/plugin-sdk")["channel"];
|
|
44
|
+
channel: (typeof import("openclaw/plugin-sdk"))["channel"];
|
|
41
45
|
system: {
|
|
42
46
|
enqueueSystemEvent: (
|
|
43
47
|
text: string,
|
|
@@ -59,7 +63,7 @@ export type MatrixMonitorHandlerParams = {
|
|
|
59
63
|
: Record<string, unknown> | undefined
|
|
60
64
|
: Record<string, unknown> | undefined;
|
|
61
65
|
mentionRegexes: ReturnType<
|
|
62
|
-
typeof import("openclaw/plugin-sdk")["channel"]["mentions"]["buildMentionRegexes"]
|
|
66
|
+
(typeof import("openclaw/plugin-sdk"))["channel"]["mentions"]["buildMentionRegexes"]
|
|
63
67
|
>;
|
|
64
68
|
groupPolicy: "open" | "allowlist" | "disabled";
|
|
65
69
|
replyToMode: ReplyToMode;
|
|
@@ -77,7 +81,9 @@ export type MatrixMonitorHandlerParams = {
|
|
|
77
81
|
selfUserId: string;
|
|
78
82
|
}) => Promise<boolean>;
|
|
79
83
|
};
|
|
80
|
-
getRoomInfo: (
|
|
84
|
+
getRoomInfo: (
|
|
85
|
+
roomId: string,
|
|
86
|
+
) => Promise<{ name?: string; canonicalAlias?: string; altAliases: string[] }>;
|
|
81
87
|
getMemberDisplayName: (roomId: string, userId: string) => Promise<string>;
|
|
82
88
|
};
|
|
83
89
|
|
|
@@ -118,17 +124,24 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
|
|
118
124
|
const locationContent = event.content as LocationMessageEventContent;
|
|
119
125
|
const isLocationEvent =
|
|
120
126
|
eventType === EventType.Location ||
|
|
121
|
-
(eventType === EventType.RoomMessage &&
|
|
122
|
-
|
|
123
|
-
|
|
127
|
+
(eventType === EventType.RoomMessage && locationContent.msgtype === EventType.Location);
|
|
128
|
+
if (eventType !== EventType.RoomMessage && !isPollEvent && !isLocationEvent) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
124
131
|
logVerboseMessage(
|
|
125
132
|
`matrix: room.message recv room=${roomId} type=${eventType} id=${event.event_id ?? "unknown"}`,
|
|
126
133
|
);
|
|
127
|
-
if (event.unsigned?.redacted_because)
|
|
134
|
+
if (event.unsigned?.redacted_because) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
128
137
|
const senderId = event.sender;
|
|
129
|
-
if (!senderId)
|
|
138
|
+
if (!senderId) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
130
141
|
const selfUserId = await client.getUserId();
|
|
131
|
-
if (senderId === selfUserId)
|
|
142
|
+
if (senderId === selfUserId) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
132
145
|
const eventTs = event.origin_server_ts;
|
|
133
146
|
const eventAge = event.unsigned?.age;
|
|
134
147
|
if (typeof eventTs === "number" && eventTs < startupMs - startupGraceMs) {
|
|
@@ -144,10 +157,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
|
|
144
157
|
|
|
145
158
|
const roomInfo = await getRoomInfo(roomId);
|
|
146
159
|
const roomName = roomInfo.name;
|
|
147
|
-
const roomAliases = [
|
|
148
|
-
roomInfo.canonicalAlias ?? "",
|
|
149
|
-
...roomInfo.altAliases,
|
|
150
|
-
].filter(Boolean);
|
|
160
|
+
const roomAliases = [roomInfo.canonicalAlias ?? "", ...roomInfo.altAliases].filter(Boolean);
|
|
151
161
|
|
|
152
162
|
let content = event.content as RoomMessageEventContent;
|
|
153
163
|
if (isPollEvent) {
|
|
@@ -176,7 +186,9 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
|
|
176
186
|
|
|
177
187
|
const relates = content["m.relates_to"];
|
|
178
188
|
if (relates && "rel_type" in relates) {
|
|
179
|
-
if (relates.rel_type === RelationType.Replace)
|
|
189
|
+
if (relates.rel_type === RelationType.Replace) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
180
192
|
}
|
|
181
193
|
|
|
182
194
|
const isDirectMessage = await directTracker.isDirectMessage({
|
|
@@ -186,7 +198,9 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
|
|
186
198
|
});
|
|
187
199
|
const isRoom = !isDirectMessage;
|
|
188
200
|
|
|
189
|
-
if (isRoom && groupPolicy === "disabled")
|
|
201
|
+
if (isRoom && groupPolicy === "disabled") {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
190
204
|
|
|
191
205
|
const roomConfigInfo = isRoom
|
|
192
206
|
? resolveMatrixRoomConfig({
|
|
@@ -219,22 +233,22 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
|
|
219
233
|
}
|
|
220
234
|
|
|
221
235
|
const senderName = await getMemberDisplayName(roomId, senderId);
|
|
222
|
-
const storeAllowFrom = await core.channel.pairing
|
|
223
|
-
|
|
236
|
+
const storeAllowFrom = await core.channel.pairing
|
|
237
|
+
.readAllowFromStore("matrix")
|
|
238
|
+
.catch(() => []);
|
|
239
|
+
const effectiveAllowFrom = normalizeMatrixAllowList([...allowFrom, ...storeAllowFrom]);
|
|
224
240
|
const groupAllowFrom = cfg.channels?.matrix?.groupAllowFrom ?? [];
|
|
225
|
-
const effectiveGroupAllowFrom =
|
|
226
|
-
...groupAllowFrom,
|
|
227
|
-
...storeAllowFrom,
|
|
228
|
-
]);
|
|
241
|
+
const effectiveGroupAllowFrom = normalizeMatrixAllowList(groupAllowFrom);
|
|
229
242
|
const groupAllowConfigured = effectiveGroupAllowFrom.length > 0;
|
|
230
243
|
|
|
231
244
|
if (isDirectMessage) {
|
|
232
|
-
if (!dmEnabled || dmPolicy === "disabled")
|
|
245
|
+
if (!dmEnabled || dmPolicy === "disabled") {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
233
248
|
if (dmPolicy !== "open") {
|
|
234
249
|
const allowMatch = resolveMatrixAllowListMatch({
|
|
235
250
|
allowList: effectiveAllowFrom,
|
|
236
251
|
userId: senderId,
|
|
237
|
-
userName: senderName,
|
|
238
252
|
});
|
|
239
253
|
const allowMatchMeta = formatAllowlistMatchMeta(allowMatch);
|
|
240
254
|
if (!allowMatch.allowed) {
|
|
@@ -279,9 +293,8 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
|
|
279
293
|
const roomUsers = roomConfig?.users ?? [];
|
|
280
294
|
if (isRoom && roomUsers.length > 0) {
|
|
281
295
|
const userMatch = resolveMatrixAllowListMatch({
|
|
282
|
-
allowList:
|
|
296
|
+
allowList: normalizeMatrixAllowList(roomUsers),
|
|
283
297
|
userId: senderId,
|
|
284
|
-
userName: senderName,
|
|
285
298
|
});
|
|
286
299
|
if (!userMatch.allowed) {
|
|
287
300
|
logVerboseMessage(
|
|
@@ -296,7 +309,6 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
|
|
296
309
|
const groupAllowMatch = resolveMatrixAllowListMatch({
|
|
297
310
|
allowList: effectiveGroupAllowFrom,
|
|
298
311
|
userId: senderId,
|
|
299
|
-
userName: senderName,
|
|
300
312
|
});
|
|
301
313
|
if (!groupAllowMatch.allowed) {
|
|
302
314
|
logVerboseMessage(
|
|
@@ -311,8 +323,8 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
|
|
311
323
|
logVerboseMessage(`matrix: allow room ${roomId} (${roomMatchMeta})`);
|
|
312
324
|
}
|
|
313
325
|
|
|
314
|
-
const rawBody =
|
|
315
|
-
?? (typeof content.body === "string" ? content.body.trim() : "");
|
|
326
|
+
const rawBody =
|
|
327
|
+
locationPayload?.text ?? (typeof content.body === "string" ? content.body.trim() : "");
|
|
316
328
|
let media: {
|
|
317
329
|
path: string;
|
|
318
330
|
contentType?: string;
|
|
@@ -334,8 +346,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
|
|
334
346
|
? (content.info as { mimetype?: string; size?: number })
|
|
335
347
|
: undefined;
|
|
336
348
|
const contentType = contentInfo?.mimetype;
|
|
337
|
-
const contentSize =
|
|
338
|
-
typeof contentInfo?.size === "number" ? contentInfo.size : undefined;
|
|
349
|
+
const contentSize = typeof contentInfo?.size === "number" ? contentInfo.size : undefined;
|
|
339
350
|
if (mediaUrl?.startsWith("mxc://")) {
|
|
340
351
|
try {
|
|
341
352
|
media = await downloadMatrixMedia({
|
|
@@ -352,7 +363,9 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
|
|
352
363
|
}
|
|
353
364
|
|
|
354
365
|
const bodyText = rawBody || media?.placeholder || "";
|
|
355
|
-
if (!bodyText)
|
|
366
|
+
if (!bodyText) {
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
356
369
|
|
|
357
370
|
const { wasMentioned, hasExplicitMention } = resolveMentions({
|
|
358
371
|
content,
|
|
@@ -368,21 +381,18 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
|
|
368
381
|
const senderAllowedForCommands = resolveMatrixAllowListMatches({
|
|
369
382
|
allowList: effectiveAllowFrom,
|
|
370
383
|
userId: senderId,
|
|
371
|
-
userName: senderName,
|
|
372
384
|
});
|
|
373
385
|
const senderAllowedForGroup = groupAllowConfigured
|
|
374
386
|
? resolveMatrixAllowListMatches({
|
|
375
387
|
allowList: effectiveGroupAllowFrom,
|
|
376
388
|
userId: senderId,
|
|
377
|
-
userName: senderName,
|
|
378
389
|
})
|
|
379
390
|
: false;
|
|
380
391
|
const senderAllowedForRoomUsers =
|
|
381
392
|
isRoom && roomUsers.length > 0
|
|
382
393
|
? resolveMatrixAllowListMatches({
|
|
383
|
-
allowList:
|
|
394
|
+
allowList: normalizeMatrixAllowList(roomUsers),
|
|
384
395
|
userId: senderId,
|
|
385
|
-
userName: senderName,
|
|
386
396
|
})
|
|
387
397
|
: false;
|
|
388
398
|
const hasControlCommandInMessage = core.channel.text.hasControlCommand(bodyText, cfg);
|
|
@@ -493,7 +503,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
|
|
493
503
|
MediaPath: media?.path,
|
|
494
504
|
MediaType: media?.contentType,
|
|
495
505
|
MediaUrl: media?.path,
|
|
496
|
-
...
|
|
506
|
+
...locationPayload?.context,
|
|
497
507
|
CommandAuthorized: commandAuthorized,
|
|
498
508
|
CommandSource: "text" as const,
|
|
499
509
|
OriginatingChannel: "matrix" as const,
|
|
@@ -514,7 +524,11 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
|
|
514
524
|
: undefined,
|
|
515
525
|
onRecordError: (err) => {
|
|
516
526
|
logger.warn(
|
|
517
|
-
{
|
|
527
|
+
{
|
|
528
|
+
error: String(err),
|
|
529
|
+
storePath,
|
|
530
|
+
sessionKey: ctxPayload.SessionKey ?? route.sessionKey,
|
|
531
|
+
},
|
|
518
532
|
"failed updating session meta",
|
|
519
533
|
);
|
|
520
534
|
},
|
|
@@ -528,16 +542,16 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
|
|
528
542
|
const shouldAckReaction = () =>
|
|
529
543
|
Boolean(
|
|
530
544
|
ackReaction &&
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
545
|
+
core.channel.reactions.shouldAckReaction({
|
|
546
|
+
scope: ackScope,
|
|
547
|
+
isDirect: isDirectMessage,
|
|
548
|
+
isGroup: isRoom,
|
|
549
|
+
isMentionableGroup: isRoom,
|
|
550
|
+
requireMention: Boolean(shouldRequireMention),
|
|
551
|
+
canDetectMention,
|
|
552
|
+
effectiveWasMentioned: wasMentioned || shouldBypassMention,
|
|
553
|
+
shouldBypassMention,
|
|
554
|
+
}),
|
|
541
555
|
);
|
|
542
556
|
if (shouldAckReaction() && messageId) {
|
|
543
557
|
reactMatrixMessage(roomId, messageId, ackReaction, client).catch((err) => {
|
|
@@ -625,7 +639,9 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
|
|
625
639
|
},
|
|
626
640
|
});
|
|
627
641
|
markDispatchIdle();
|
|
628
|
-
if (!queuedFinal)
|
|
642
|
+
if (!queuedFinal) {
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
629
645
|
didSendReply = true;
|
|
630
646
|
const finalCount = counts.final;
|
|
631
647
|
logVerboseMessage(
|