@inline-openclaw/inline 0.0.13 → 0.0.15
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/README.md +15 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/inline/actions.d.ts +1 -1
- package/dist/inline/actions.d.ts.map +1 -1
- package/dist/inline/actions.js +226 -78
- package/dist/inline/actions.js.map +1 -1
- package/dist/inline/config-schema.d.ts +14 -0
- package/dist/inline/config-schema.d.ts.map +1 -1
- package/dist/inline/config-schema.js +2 -0
- package/dist/inline/config-schema.js.map +1 -1
- package/dist/inline/members-tool.d.ts +6 -0
- package/dist/inline/members-tool.d.ts.map +1 -0
- package/dist/inline/members-tool.js +135 -0
- package/dist/inline/members-tool.js.map +1 -0
- package/dist/inline/message-content.d.ts +51 -0
- package/dist/inline/message-content.d.ts.map +1 -0
- package/dist/inline/message-content.js +305 -0
- package/dist/inline/message-content.js.map +1 -0
- package/dist/inline/monitor.d.ts.map +1 -1
- package/dist/inline/monitor.js +284 -25
- package/dist/inline/monitor.js.map +1 -1
- package/dist/inline/space-members.d.ts +22 -0
- package/dist/inline/space-members.d.ts.map +1 -0
- package/dist/inline/space-members.js +57 -0
- package/dist/inline/space-members.js.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -100,6 +100,7 @@ channels:
|
|
|
100
100
|
# Streaming + chunking:
|
|
101
101
|
mediaMaxMb: 20
|
|
102
102
|
blockStreaming: true
|
|
103
|
+
streamViaEditMessage: true # optional: paragraph-level text streaming via send+edit fallback; off by default
|
|
103
104
|
chunkMode: "newline" # length|newline
|
|
104
105
|
blockStreamingCoalesce:
|
|
105
106
|
minChars: 600
|
|
@@ -136,14 +137,16 @@ For `message send`/plugin outbound sends:
|
|
|
136
137
|
## Message Tool RPC Actions
|
|
137
138
|
|
|
138
139
|
The plugin exposes Inline RPC-backed actions through OpenClaw's `message` tool.
|
|
139
|
-
Inline RPC-backed actions use a numeric chat id via `to`, `chatId`, or `channelId`.
|
|
140
|
+
Most Inline RPC-backed actions use a numeric chat id via `to`, `chatId`, or `channelId`.
|
|
141
|
+
Direct DM sends can also target `user:<id>`.
|
|
140
142
|
|
|
143
|
+
- Sending: `send`, `sendAttachment`
|
|
141
144
|
- Replying: `reply`, `thread-reply`
|
|
142
145
|
- Reactions: `react`, `reactions`
|
|
143
146
|
- Reading/searching: `read`, `search`
|
|
144
147
|
- Editing: `edit`
|
|
145
|
-
- Channels/threads: `channel-info`, `channel-edit`, `channel-list`, `channel-create`, `channel-delete`, `channel-move`, `thread-list`, `thread-create`
|
|
146
|
-
- Participants: `addParticipant`, `removeParticipant`, `leaveGroup`, `member-info`
|
|
148
|
+
- Channels/threads: `channel-info`, `channel-edit`, `renameGroup`, `channel-list`, `channel-create`, `channel-delete`, `channel-move`, `thread-list`, `thread-create`
|
|
149
|
+
- Participants: `addParticipant`, `removeParticipant`, `kick`, `leaveGroup`, `member-info`
|
|
147
150
|
- Message lifecycle: `delete`, `unsend`
|
|
148
151
|
- Pins: `pin`, `unpin`, `list-pins`
|
|
149
152
|
- Space permissions: `permissions`
|
|
@@ -154,6 +157,7 @@ You can gate action groups from config:
|
|
|
154
157
|
channels:
|
|
155
158
|
inline:
|
|
156
159
|
actions:
|
|
160
|
+
send: true
|
|
157
161
|
reply: true
|
|
158
162
|
reactions: true
|
|
159
163
|
read: true
|
|
@@ -166,6 +170,14 @@ channels:
|
|
|
166
170
|
permissions: true
|
|
167
171
|
```
|
|
168
172
|
|
|
173
|
+
## Extra Agent Tools
|
|
174
|
+
|
|
175
|
+
The plugin also registers a dedicated `inline_members` tool for space-member discovery outside the `message` action surface.
|
|
176
|
+
|
|
177
|
+
- Required input: `spaceId`
|
|
178
|
+
- Optional filters: `query`, `userId`, `limit`, `accountId`
|
|
179
|
+
- Returned members include explicit DM targets like `user:123`
|
|
180
|
+
|
|
169
181
|
Multi-account:
|
|
170
182
|
|
|
171
183
|
```yaml
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAM1E,QAAA,MAAM,MAAM,EAAE;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IAGnB,YAAY,EAAE,OAAO,CAAA;IACrB,QAAQ,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,IAAI,CAAA;CAa3C,CAAA;AAED,eAAe,MAAM,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk";
|
|
2
2
|
import { inlineChannelPlugin } from "./inline/channel.js";
|
|
3
|
+
import { createInlineMembersTool } from "./inline/members-tool.js";
|
|
3
4
|
import { setInlineRuntime } from "./runtime.js";
|
|
4
5
|
const plugin = {
|
|
5
6
|
id: "inline",
|
|
@@ -9,6 +10,9 @@ const plugin = {
|
|
|
9
10
|
register(api) {
|
|
10
11
|
setInlineRuntime(api.runtime);
|
|
11
12
|
api.registerChannel({ plugin: inlineChannelPlugin });
|
|
13
|
+
api.registerTool((ctx) => createInlineMembersTool(ctx), {
|
|
14
|
+
names: ["inline_members"],
|
|
15
|
+
});
|
|
12
16
|
},
|
|
13
17
|
};
|
|
14
18
|
export default plugin;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAE/C,MAAM,MAAM,GAQR;IACF,EAAE,EAAE,QAAQ;IACZ,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,2CAA2C;IACxD,YAAY,EAAE,uBAAuB,EAAE;IACvC,QAAQ,CAAC,GAAsB;QAC7B,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAC7B,GAAG,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAE/C,MAAM,MAAM,GAQR;IACF,EAAE,EAAE,QAAQ;IACZ,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,2CAA2C;IACxD,YAAY,EAAE,uBAAuB,EAAE;IACvC,QAAQ,CAAC,GAAsB;QAC7B,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAC7B,GAAG,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC,CAAA;QACpD,GAAG,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,uBAAuB,CAAC,GAAG,CAAiB,EAAE;YACtE,KAAK,EAAE,CAAC,gBAAgB,CAAC;SAC1B,CAAC,CAAA;IACJ,CAAC;CACF,CAAA;AAED,eAAe,MAAM,CAAA"}
|
package/dist/inline/actions.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ChannelMessageActionAdapter } from "openclaw/plugin-sdk";
|
|
2
2
|
export declare const inlineMessageActions: ChannelMessageActionAdapter;
|
|
3
|
-
export declare const inlineSupportedActions: ("send" | "
|
|
3
|
+
export declare const inlineSupportedActions: ("send" | "reply" | "reactions" | "read" | "search" | "edit" | "delete" | "permissions" | "broadcast" | "poll" | "react" | "unsend" | "sendWithEffect" | "renameGroup" | "setGroupIcon" | "addParticipant" | "removeParticipant" | "leaveGroup" | "sendAttachment" | "pin" | "unpin" | "list-pins" | "thread-create" | "thread-list" | "thread-reply" | "sticker" | "sticker-search" | "member-info" | "role-info" | "emoji-list" | "emoji-upload" | "sticker-upload" | "role-add" | "role-remove" | "channel-info" | "channel-list" | "channel-create" | "channel-edit" | "channel-delete" | "channel-move" | "category-create" | "category-edit" | "category-delete" | "voice-status" | "event-list" | "event-create" | "timeout" | "kick" | "ban" | "set-presence")[];
|
|
4
4
|
//# sourceMappingURL=actions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/inline/actions.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,2BAA2B,EAGjC,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/inline/actions.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,2BAA2B,EAGjC,MAAM,qBAAqB,CAAA;AAqqB5B,eAAO,MAAM,oBAAoB,EAAE,2BAy6BlC,CAAA;AAED,eAAO,MAAM,sBAAsB,0uBAAmB,CAAA"}
|
package/dist/inline/actions.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { createActionGate, jsonResult, readReactionParams, readNumberParam, readStringParam, } from "openclaw/plugin-sdk";
|
|
2
|
-
import { InlineSdkClient, Method,
|
|
2
|
+
import { InlineSdkClient, Method, } from "@inline-chat/realtime-sdk";
|
|
3
3
|
import { resolveInlineAccount, resolveInlineToken } from "./accounts.js";
|
|
4
|
+
import { uploadInlineMediaFromUrl } from "./media.js";
|
|
5
|
+
import { summarizeInlineMessageContent } from "./message-content.js";
|
|
4
6
|
import { normalizeInlineTarget } from "./normalize.js";
|
|
7
|
+
import { buildInlineUserDisplayName, getSpaceMembersWithUsers } from "./space-members.js";
|
|
5
8
|
const ACTION_GROUPS = [
|
|
6
|
-
{ key: "
|
|
9
|
+
{ key: "send", defaultEnabled: true, actions: ["send", "sendAttachment"] },
|
|
10
|
+
{ key: "reply", defaultEnabled: true, actions: ["reply", "thread-reply"] },
|
|
7
11
|
{ key: "reactions", defaultEnabled: true, actions: ["react", "reactions"] },
|
|
8
12
|
{ key: "read", defaultEnabled: true, actions: ["read"] },
|
|
9
13
|
{ key: "search", defaultEnabled: true, actions: ["search"] },
|
|
@@ -14,6 +18,7 @@ const ACTION_GROUPS = [
|
|
|
14
18
|
actions: [
|
|
15
19
|
"channel-info",
|
|
16
20
|
"channel-edit",
|
|
21
|
+
"renameGroup",
|
|
17
22
|
"channel-list",
|
|
18
23
|
"channel-create",
|
|
19
24
|
"channel-delete",
|
|
@@ -25,7 +30,7 @@ const ACTION_GROUPS = [
|
|
|
25
30
|
{
|
|
26
31
|
key: "participants",
|
|
27
32
|
defaultEnabled: true,
|
|
28
|
-
actions: ["addParticipant", "removeParticipant", "leaveGroup", "member-info"],
|
|
33
|
+
actions: ["addParticipant", "removeParticipant", "kick", "leaveGroup", "member-info"],
|
|
29
34
|
},
|
|
30
35
|
{ key: "delete", defaultEnabled: true, actions: ["delete", "unsend"] },
|
|
31
36
|
{ key: "pins", defaultEnabled: true, actions: ["pin", "unpin", "list-pins"] },
|
|
@@ -38,6 +43,11 @@ for (const group of ACTION_GROUPS) {
|
|
|
38
43
|
}
|
|
39
44
|
}
|
|
40
45
|
const SUPPORTED_ACTIONS = Array.from(ACTION_TO_GATE_KEY.keys());
|
|
46
|
+
const GET_MESSAGES_METHOD = typeof Method.GET_MESSAGES === "number" &&
|
|
47
|
+
Number.isInteger(Method.GET_MESSAGES) &&
|
|
48
|
+
Method.GET_MESSAGES > 0
|
|
49
|
+
? Method.GET_MESSAGES
|
|
50
|
+
: null;
|
|
41
51
|
function normalizeChatId(raw) {
|
|
42
52
|
const normalized = normalizeInlineTarget(raw) ?? raw.trim();
|
|
43
53
|
if (!/^[0-9]+$/.test(normalized)) {
|
|
@@ -160,6 +170,25 @@ function parseInlineListValuesFromParams(params, keys) {
|
|
|
160
170
|
const entries = keys.flatMap((key) => parseInlineListValue(params[key], key));
|
|
161
171
|
return Array.from(new Set(entries.map((entry) => entry.trim()).filter(Boolean)));
|
|
162
172
|
}
|
|
173
|
+
function resolveInlineOutboundMediaInputs(params) {
|
|
174
|
+
const plural = parseInlineListValuesFromParams(params, [
|
|
175
|
+
"mediaUrls",
|
|
176
|
+
"attachmentUrls",
|
|
177
|
+
"filePaths",
|
|
178
|
+
"paths",
|
|
179
|
+
"files",
|
|
180
|
+
]);
|
|
181
|
+
const single = parseInlineListValuesFromParams(params, [
|
|
182
|
+
"mediaUrl",
|
|
183
|
+
"attachmentUrl",
|
|
184
|
+
"url",
|
|
185
|
+
"media",
|
|
186
|
+
"filePath",
|
|
187
|
+
"path",
|
|
188
|
+
"file",
|
|
189
|
+
]);
|
|
190
|
+
return Array.from(new Set([...plural, ...single]));
|
|
191
|
+
}
|
|
163
192
|
function normalizeInlineUserLookupToken(raw) {
|
|
164
193
|
return raw
|
|
165
194
|
.trim()
|
|
@@ -256,6 +285,56 @@ function resolveChatIdFromParams(params) {
|
|
|
256
285
|
}
|
|
257
286
|
return BigInt(normalizeChatId(raw));
|
|
258
287
|
}
|
|
288
|
+
function resolveMessageSendTargetFromParams(params) {
|
|
289
|
+
const explicitUserIdRaw = readFlexibleId(params, "userId") ?? readStringParam(params, "userId");
|
|
290
|
+
if (explicitUserIdRaw) {
|
|
291
|
+
const userId = parseInlineId(explicitUserIdRaw, "userId");
|
|
292
|
+
return {
|
|
293
|
+
target: `user:${String(userId)}`,
|
|
294
|
+
userId,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
const rawTarget = readFlexibleId(params, "to") ?? readStringParam(params, "to");
|
|
298
|
+
if (rawTarget) {
|
|
299
|
+
const normalized = normalizeInlineTarget(rawTarget) ?? rawTarget.trim();
|
|
300
|
+
const userMatch = normalized.match(/^user:([0-9]+)$/i);
|
|
301
|
+
if (userMatch?.[1]) {
|
|
302
|
+
return {
|
|
303
|
+
target: `user:${userMatch[1]}`,
|
|
304
|
+
userId: BigInt(userMatch[1]),
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
if (!/^[0-9]+$/.test(normalized)) {
|
|
308
|
+
throw new Error(`inline action: invalid target "${rawTarget}"`);
|
|
309
|
+
}
|
|
310
|
+
return {
|
|
311
|
+
target: normalized,
|
|
312
|
+
chatId: BigInt(normalized),
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
const rawChatId = readFlexibleId(params, "chatId") ??
|
|
316
|
+
readStringParam(params, "chatId") ??
|
|
317
|
+
readFlexibleId(params, "channelId") ??
|
|
318
|
+
readStringParam(params, "channelId");
|
|
319
|
+
if (!rawChatId) {
|
|
320
|
+
throw new Error("inline action requires to/chatId/channelId/userId");
|
|
321
|
+
}
|
|
322
|
+
const normalized = normalizeInlineTarget(rawChatId) ?? rawChatId.trim();
|
|
323
|
+
const userMatch = normalized.match(/^user:([0-9]+)$/i);
|
|
324
|
+
if (userMatch?.[1]) {
|
|
325
|
+
return {
|
|
326
|
+
target: `user:${userMatch[1]}`,
|
|
327
|
+
userId: BigInt(userMatch[1]),
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
if (!/^[0-9]+$/.test(normalized)) {
|
|
331
|
+
throw new Error(`inline action: invalid target "${rawChatId}"`);
|
|
332
|
+
}
|
|
333
|
+
return {
|
|
334
|
+
target: normalized,
|
|
335
|
+
chatId: BigInt(normalized),
|
|
336
|
+
};
|
|
337
|
+
}
|
|
259
338
|
function buildChatPeer(chatId) {
|
|
260
339
|
return {
|
|
261
340
|
type: {
|
|
@@ -264,16 +343,8 @@ function buildChatPeer(chatId) {
|
|
|
264
343
|
},
|
|
265
344
|
};
|
|
266
345
|
}
|
|
267
|
-
function buildInlineUserDisplayName(user) {
|
|
268
|
-
const explicit = [user.firstName?.trim(), user.lastName?.trim()].filter(Boolean).join(" ");
|
|
269
|
-
if (explicit)
|
|
270
|
-
return explicit;
|
|
271
|
-
const username = user.username?.trim();
|
|
272
|
-
if (username)
|
|
273
|
-
return `@${username}`;
|
|
274
|
-
return "Unknown";
|
|
275
|
-
}
|
|
276
346
|
function mapMessage(message) {
|
|
347
|
+
const content = summarizeInlineMessageContent(message);
|
|
277
348
|
const reactions = (message.reactions?.reactions ?? []).map((reaction) => ({
|
|
278
349
|
emoji: reaction.emoji ?? "",
|
|
279
350
|
userId: String(reaction.userId),
|
|
@@ -285,9 +356,17 @@ function mapMessage(message) {
|
|
|
285
356
|
id: String(message.id),
|
|
286
357
|
fromId: String(message.fromId),
|
|
287
358
|
date: Number(message.date) * 1000,
|
|
288
|
-
text:
|
|
359
|
+
text: content.text,
|
|
360
|
+
rawText: content.rawText,
|
|
361
|
+
attachmentText: content.attachmentText,
|
|
362
|
+
entityText: content.entityText,
|
|
289
363
|
out: Boolean(message.out),
|
|
290
364
|
replyToId: message.replyToMsgId != null ? String(message.replyToMsgId) : undefined,
|
|
365
|
+
attachmentUrls: content.attachmentUrls,
|
|
366
|
+
links: content.links,
|
|
367
|
+
media: content.media,
|
|
368
|
+
attachments: content.attachments,
|
|
369
|
+
entities: content.entities,
|
|
291
370
|
reactions,
|
|
292
371
|
};
|
|
293
372
|
}
|
|
@@ -320,17 +399,6 @@ function mapChatEntry(params) {
|
|
|
320
399
|
: null,
|
|
321
400
|
};
|
|
322
401
|
}
|
|
323
|
-
function mapSpaceMemberRole(role) {
|
|
324
|
-
if (role == null)
|
|
325
|
-
return null;
|
|
326
|
-
if (role === Member_Role.OWNER)
|
|
327
|
-
return "owner";
|
|
328
|
-
if (role === Member_Role.ADMIN)
|
|
329
|
-
return "admin";
|
|
330
|
-
if (role === Member_Role.MEMBER)
|
|
331
|
-
return "member";
|
|
332
|
-
return null;
|
|
333
|
-
}
|
|
334
402
|
async function loadMessageReactions(params) {
|
|
335
403
|
const target = await findMessageById({
|
|
336
404
|
client: params.client,
|
|
@@ -360,15 +428,17 @@ async function loadMessageReactions(params) {
|
|
|
360
428
|
return Array.from(byEmoji.values());
|
|
361
429
|
}
|
|
362
430
|
async function findMessageById(params) {
|
|
363
|
-
const directResult =
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
431
|
+
const directResult = GET_MESSAGES_METHOD == null
|
|
432
|
+
? null
|
|
433
|
+
: await params.client
|
|
434
|
+
.invokeRaw(GET_MESSAGES_METHOD, {
|
|
435
|
+
oneofKind: "getMessages",
|
|
436
|
+
getMessages: {
|
|
437
|
+
peerId: buildChatPeer(params.chatId),
|
|
438
|
+
messageIds: [params.messageId],
|
|
439
|
+
},
|
|
440
|
+
})
|
|
441
|
+
.catch(() => null);
|
|
372
442
|
if (directResult?.oneofKind === "getMessages") {
|
|
373
443
|
return (directResult.getMessages.messages ?? []).find((message) => message.id === params.messageId) ?? null;
|
|
374
444
|
}
|
|
@@ -439,6 +509,33 @@ function buildUserMap(users) {
|
|
|
439
509
|
}
|
|
440
510
|
return map;
|
|
441
511
|
}
|
|
512
|
+
async function resolveSpaceIdFromParams(params) {
|
|
513
|
+
const directSpaceId = parseOptionalInlineId(readFlexibleId(params.rawParams, "spaceId") ??
|
|
514
|
+
readFlexibleId(params.rawParams, "space") ??
|
|
515
|
+
readStringParam(params.rawParams, "spaceId"), "spaceId");
|
|
516
|
+
if (directSpaceId != null)
|
|
517
|
+
return directSpaceId;
|
|
518
|
+
const chatTarget = readFlexibleId(params.rawParams, "chatId") ??
|
|
519
|
+
readFlexibleId(params.rawParams, "channelId") ??
|
|
520
|
+
readFlexibleId(params.rawParams, "to") ??
|
|
521
|
+
readStringParam(params.rawParams, "to");
|
|
522
|
+
if (!chatTarget) {
|
|
523
|
+
throw new Error(`inline action: ${params.action} requires spaceId (or a chat target in a space)`);
|
|
524
|
+
}
|
|
525
|
+
const chatId = BigInt(normalizeChatId(chatTarget));
|
|
526
|
+
const chatResult = await params.client.invokeRaw(Method.GET_CHAT, {
|
|
527
|
+
oneofKind: "getChat",
|
|
528
|
+
getChat: { peerId: buildChatPeer(chatId) },
|
|
529
|
+
});
|
|
530
|
+
if (chatResult.oneofKind !== "getChat") {
|
|
531
|
+
throw new Error(`inline action: expected getChat result, got ${String(chatResult.oneofKind)}`);
|
|
532
|
+
}
|
|
533
|
+
const inferredSpaceId = chatResult.getChat.chat?.spaceId ?? chatResult.getChat.dialog?.spaceId;
|
|
534
|
+
if (inferredSpaceId == null) {
|
|
535
|
+
throw new Error(`inline action: ${params.action} requires a spaceId or a chat that belongs to a space`);
|
|
536
|
+
}
|
|
537
|
+
return inferredSpaceId;
|
|
538
|
+
}
|
|
442
539
|
function listAllActions() {
|
|
443
540
|
const out = new Set();
|
|
444
541
|
for (const group of ACTION_GROUPS) {
|
|
@@ -487,7 +584,7 @@ export const inlineMessageActions = {
|
|
|
487
584
|
if (!to)
|
|
488
585
|
return null;
|
|
489
586
|
const normalized = normalizeInlineTarget(to) ?? to;
|
|
490
|
-
if (!/^[0-9]
|
|
587
|
+
if (!/^(user:)?[0-9]+$/i.test(normalized))
|
|
491
588
|
return null;
|
|
492
589
|
return { to: normalized };
|
|
493
590
|
},
|
|
@@ -499,21 +596,98 @@ export const inlineMessageActions = {
|
|
|
499
596
|
throw new Error(`inline action: ${action} is disabled by channels.inline.actions`);
|
|
500
597
|
}
|
|
501
598
|
const normalizedAction = action;
|
|
502
|
-
if (normalizedAction === "
|
|
599
|
+
if (normalizedAction === "send" || normalizedAction === "sendAttachment") {
|
|
503
600
|
const parseMarkdown = resolveInlineAccount({ cfg, accountId: accountId ?? null }).config.parseMarkdown ?? true;
|
|
504
601
|
return await withInlineClient({
|
|
505
602
|
cfg,
|
|
506
603
|
accountId,
|
|
507
604
|
fn: async (client) => {
|
|
508
|
-
const
|
|
509
|
-
const
|
|
605
|
+
const target = resolveMessageSendTargetFromParams(params);
|
|
606
|
+
const sendTarget = target.chatId != null ? { chatId: target.chatId } : target.userId != null ? { userId: target.userId } : null;
|
|
607
|
+
if (!sendTarget) {
|
|
608
|
+
throw new Error("inline action: missing message target");
|
|
609
|
+
}
|
|
610
|
+
const mediaSources = resolveInlineOutboundMediaInputs(params);
|
|
611
|
+
const text = readStringParam(params, "message") ??
|
|
612
|
+
readStringParam(params, "text") ??
|
|
613
|
+
readStringParam(params, "caption") ??
|
|
614
|
+
"";
|
|
615
|
+
const replyToMsgId = parseOptionalInlineId(readFlexibleId(params, "messageId") ??
|
|
510
616
|
readFlexibleId(params, "replyTo") ??
|
|
511
617
|
readFlexibleId(params, "replyToId") ??
|
|
512
618
|
readStringParam(params, "messageId") ??
|
|
513
619
|
readStringParam(params, "replyTo") ??
|
|
514
|
-
readStringParam(params, "replyToId"
|
|
515
|
-
|
|
516
|
-
|
|
620
|
+
readStringParam(params, "replyToId"), "messageId");
|
|
621
|
+
if (normalizedAction === "sendAttachment" && mediaSources.length === 0) {
|
|
622
|
+
throw new Error("inline action: sendAttachment requires media/file input");
|
|
623
|
+
}
|
|
624
|
+
if (mediaSources.length === 0) {
|
|
625
|
+
const message = readStringParam(params, "message") ??
|
|
626
|
+
readStringParam(params, "text", { required: true, allowEmpty: true });
|
|
627
|
+
const sent = await client.sendMessage({
|
|
628
|
+
...sendTarget,
|
|
629
|
+
text: message,
|
|
630
|
+
...(replyToMsgId != null ? { replyToMsgId } : {}),
|
|
631
|
+
parseMarkdown,
|
|
632
|
+
});
|
|
633
|
+
return jsonResult({
|
|
634
|
+
ok: true,
|
|
635
|
+
target: target.target,
|
|
636
|
+
messageId: sent.messageId != null ? String(sent.messageId) : null,
|
|
637
|
+
replyToId: replyToMsgId != null ? String(replyToMsgId) : null,
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
let lastSent = null;
|
|
641
|
+
for (let index = 0; index < mediaSources.length; index += 1) {
|
|
642
|
+
const mediaUrl = mediaSources[index];
|
|
643
|
+
if (!mediaUrl)
|
|
644
|
+
continue;
|
|
645
|
+
const media = await uploadInlineMediaFromUrl({
|
|
646
|
+
client,
|
|
647
|
+
cfg,
|
|
648
|
+
accountId: accountId ?? null,
|
|
649
|
+
mediaUrl,
|
|
650
|
+
});
|
|
651
|
+
lastSent = await client.sendMessage({
|
|
652
|
+
...sendTarget,
|
|
653
|
+
...(index === 0 && text ? { text } : {}),
|
|
654
|
+
media,
|
|
655
|
+
...(index === 0 && replyToMsgId != null ? { replyToMsgId } : {}),
|
|
656
|
+
...(index === 0 && text ? { parseMarkdown } : {}),
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
return jsonResult({
|
|
660
|
+
ok: true,
|
|
661
|
+
target: target.target,
|
|
662
|
+
messageId: lastSent?.messageId != null ? String(lastSent.messageId) : null,
|
|
663
|
+
...(mediaSources.length === 1 ? { mediaUrl: mediaSources[0] } : { mediaUrls: mediaSources }),
|
|
664
|
+
replyToId: replyToMsgId != null ? String(replyToMsgId) : null,
|
|
665
|
+
});
|
|
666
|
+
},
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
if (normalizedAction === "reply" || normalizedAction === "thread-reply") {
|
|
670
|
+
const parseMarkdown = resolveInlineAccount({ cfg, accountId: accountId ?? null }).config.parseMarkdown ?? true;
|
|
671
|
+
return await withInlineClient({
|
|
672
|
+
cfg,
|
|
673
|
+
accountId,
|
|
674
|
+
fn: async (client) => {
|
|
675
|
+
const replyParams = normalizedAction === "thread-reply" &&
|
|
676
|
+
params.threadId != null &&
|
|
677
|
+
params.to == null &&
|
|
678
|
+
params.chatId == null &&
|
|
679
|
+
params.channelId == null
|
|
680
|
+
? { ...params, to: params.threadId }
|
|
681
|
+
: params;
|
|
682
|
+
const chatId = resolveChatIdFromParams(replyParams);
|
|
683
|
+
const replyToMsgId = parseInlineId(readFlexibleId(replyParams, "messageId") ??
|
|
684
|
+
readFlexibleId(replyParams, "replyTo") ??
|
|
685
|
+
readFlexibleId(replyParams, "replyToId") ??
|
|
686
|
+
readStringParam(replyParams, "messageId") ??
|
|
687
|
+
readStringParam(replyParams, "replyTo") ??
|
|
688
|
+
readStringParam(replyParams, "replyToId", { required: true }), "messageId");
|
|
689
|
+
const text = readStringParam(replyParams, "message") ??
|
|
690
|
+
readStringParam(replyParams, "text", { required: true, allowEmpty: true });
|
|
517
691
|
const sent = await client.sendMessage({
|
|
518
692
|
chatId,
|
|
519
693
|
text,
|
|
@@ -661,6 +835,7 @@ export const inlineMessageActions = {
|
|
|
661
835
|
});
|
|
662
836
|
}
|
|
663
837
|
if (normalizedAction === "edit") {
|
|
838
|
+
const parseMarkdown = resolveInlineAccount({ cfg, accountId: accountId ?? null }).config.parseMarkdown ?? true;
|
|
664
839
|
return await withInlineClient({
|
|
665
840
|
cfg,
|
|
666
841
|
accountId,
|
|
@@ -675,12 +850,13 @@ export const inlineMessageActions = {
|
|
|
675
850
|
messageId,
|
|
676
851
|
peerId: buildChatPeer(chatId),
|
|
677
852
|
text,
|
|
853
|
+
parseMarkdown,
|
|
678
854
|
},
|
|
679
855
|
});
|
|
680
856
|
if (result.oneofKind !== "editMessage") {
|
|
681
857
|
throw new Error(`inline action: expected editMessage result, got ${String(result.oneofKind)}`);
|
|
682
858
|
}
|
|
683
|
-
return jsonResult(toJsonSafe({ ok: true, chatId: String(chatId), messageId: String(messageId), text }));
|
|
859
|
+
return jsonResult(toJsonSafe({ ok: true, chatId: String(chatId), messageId: String(messageId), text, parseMarkdown }));
|
|
684
860
|
},
|
|
685
861
|
});
|
|
686
862
|
}
|
|
@@ -707,7 +883,7 @@ export const inlineMessageActions = {
|
|
|
707
883
|
},
|
|
708
884
|
});
|
|
709
885
|
}
|
|
710
|
-
if (normalizedAction === "channel-edit") {
|
|
886
|
+
if (normalizedAction === "channel-edit" || normalizedAction === "renameGroup") {
|
|
711
887
|
return await withInlineClient({
|
|
712
888
|
cfg,
|
|
713
889
|
accountId,
|
|
@@ -935,7 +1111,7 @@ export const inlineMessageActions = {
|
|
|
935
1111
|
},
|
|
936
1112
|
});
|
|
937
1113
|
}
|
|
938
|
-
if (normalizedAction === "removeParticipant") {
|
|
1114
|
+
if (normalizedAction === "removeParticipant" || normalizedAction === "kick") {
|
|
939
1115
|
return await withInlineClient({
|
|
940
1116
|
cfg,
|
|
941
1117
|
accountId,
|
|
@@ -1128,17 +1304,11 @@ export const inlineMessageActions = {
|
|
|
1128
1304
|
accountId,
|
|
1129
1305
|
fn: async (client) => {
|
|
1130
1306
|
const chatId = resolveChatIdFromParams(params);
|
|
1131
|
-
const
|
|
1132
|
-
|
|
1133
|
-
|
|
1307
|
+
const spaceId = await resolveSpaceIdFromParams({
|
|
1308
|
+
client,
|
|
1309
|
+
action: "permissions",
|
|
1310
|
+
rawParams: params,
|
|
1134
1311
|
});
|
|
1135
|
-
if (chatResult.oneofKind !== "getChat") {
|
|
1136
|
-
throw new Error(`inline action: expected getChat result, got ${String(chatResult.oneofKind)}`);
|
|
1137
|
-
}
|
|
1138
|
-
const spaceId = chatResult.getChat.chat?.spaceId ?? chatResult.getChat.dialog?.spaceId;
|
|
1139
|
-
if (spaceId == null) {
|
|
1140
|
-
throw new Error("inline action: permissions requires a chat that belongs to a space");
|
|
1141
|
-
}
|
|
1142
1312
|
const userIdRaw = readFlexibleId(params, "userId") ??
|
|
1143
1313
|
readFlexibleId(params, "memberId") ??
|
|
1144
1314
|
readStringParam(params, "userId");
|
|
@@ -1173,31 +1343,9 @@ export const inlineMessageActions = {
|
|
|
1173
1343
|
throw new Error(`inline action: expected updateMemberAccess result, got ${String(updateResult.oneofKind)}`);
|
|
1174
1344
|
}
|
|
1175
1345
|
}
|
|
1176
|
-
const
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
spaceId,
|
|
1180
|
-
},
|
|
1181
|
-
});
|
|
1182
|
-
if (membersResult.oneofKind !== "getSpaceMembers") {
|
|
1183
|
-
throw new Error(`inline action: expected getSpaceMembers result, got ${String(membersResult.oneofKind)}`);
|
|
1184
|
-
}
|
|
1185
|
-
const usersById = buildUserMap(membersResult.getSpaceMembers.users ?? []);
|
|
1186
|
-
const members = (membersResult.getSpaceMembers.members ?? []).map((member) => {
|
|
1187
|
-
const linkedUser = usersById.get(String(member.userId));
|
|
1188
|
-
return {
|
|
1189
|
-
userId: String(member.userId),
|
|
1190
|
-
role: mapSpaceMemberRole(member.role),
|
|
1191
|
-
canAccessPublicChats: member.canAccessPublicChats,
|
|
1192
|
-
date: Number(member.date) * 1000,
|
|
1193
|
-
user: linkedUser
|
|
1194
|
-
? {
|
|
1195
|
-
id: String(linkedUser.id),
|
|
1196
|
-
name: buildInlineUserDisplayName(linkedUser),
|
|
1197
|
-
username: linkedUser.username ?? null,
|
|
1198
|
-
}
|
|
1199
|
-
: null,
|
|
1200
|
-
};
|
|
1346
|
+
const members = await getSpaceMembersWithUsers({
|
|
1347
|
+
client,
|
|
1348
|
+
spaceId,
|
|
1201
1349
|
});
|
|
1202
1350
|
const filteredMembers = userId != null ? members.filter((member) => member.userId === String(userId)) : members;
|
|
1203
1351
|
return jsonResult(toJsonSafe({
|