@inline-openclaw/inline 0.0.4 → 0.0.6
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 +32 -12
- package/dist/inline/accounts.d.ts.map +1 -1
- package/dist/inline/accounts.js +19 -7
- package/dist/inline/accounts.js.map +1 -1
- package/dist/inline/actions.d.ts +1 -0
- package/dist/inline/actions.d.ts.map +1 -1
- package/dist/inline/actions.js +644 -40
- package/dist/inline/actions.js.map +1 -1
- package/dist/inline/channel.d.ts.map +1 -1
- package/dist/inline/channel.js +421 -29
- package/dist/inline/channel.js.map +1 -1
- package/dist/inline/config-schema.d.ts +91 -0
- package/dist/inline/config-schema.d.ts.map +1 -1
- package/dist/inline/config-schema.js +16 -0
- package/dist/inline/config-schema.js.map +1 -1
- package/dist/inline/media.d.ts +9 -0
- package/dist/inline/media.d.ts.map +1 -0
- package/dist/inline/media.js +137 -0
- package/dist/inline/media.js.map +1 -0
- package/dist/inline/monitor.d.ts.map +1 -1
- package/dist/inline/monitor.js +193 -94
- package/dist/inline/monitor.js.map +1 -1
- package/dist/inline/policy.d.ts.map +1 -1
- package/dist/inline/policy.js +2 -3
- package/dist/inline/policy.js.map +1 -1
- package/package.json +5 -3
package/dist/inline/actions.js
CHANGED
|
@@ -1,18 +1,43 @@
|
|
|
1
|
-
import { jsonResult, readReactionParams, readNumberParam, readStringParam, } from "openclaw/plugin-sdk";
|
|
2
|
-
import { InlineSdkClient, Method } from "@inline-chat/realtime-sdk";
|
|
1
|
+
import { createActionGate, jsonResult, readReactionParams, readNumberParam, readStringParam, } from "openclaw/plugin-sdk";
|
|
2
|
+
import { InlineSdkClient, Method, Member_Role, } from "@inline-chat/realtime-sdk";
|
|
3
3
|
import { resolveInlineAccount, resolveInlineToken } from "./accounts.js";
|
|
4
4
|
import { normalizeInlineTarget } from "./normalize.js";
|
|
5
|
-
const
|
|
6
|
-
"
|
|
7
|
-
"reactions",
|
|
8
|
-
"read",
|
|
9
|
-
"search",
|
|
10
|
-
"edit",
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
const ACTION_GROUPS = [
|
|
6
|
+
{ key: "reply", defaultEnabled: true, actions: ["reply", "thread-reply"] },
|
|
7
|
+
{ key: "reactions", defaultEnabled: true, actions: ["react", "reactions"] },
|
|
8
|
+
{ key: "read", defaultEnabled: true, actions: ["read"] },
|
|
9
|
+
{ key: "search", defaultEnabled: true, actions: ["search"] },
|
|
10
|
+
{ key: "edit", defaultEnabled: true, actions: ["edit"] },
|
|
11
|
+
{
|
|
12
|
+
key: "channels",
|
|
13
|
+
defaultEnabled: true,
|
|
14
|
+
actions: [
|
|
15
|
+
"channel-info",
|
|
16
|
+
"channel-edit",
|
|
17
|
+
"channel-list",
|
|
18
|
+
"channel-create",
|
|
19
|
+
"channel-delete",
|
|
20
|
+
"channel-move",
|
|
21
|
+
"thread-list",
|
|
22
|
+
"thread-create",
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
key: "participants",
|
|
27
|
+
defaultEnabled: true,
|
|
28
|
+
actions: ["addParticipant", "removeParticipant", "leaveGroup", "member-info"],
|
|
29
|
+
},
|
|
30
|
+
{ key: "delete", defaultEnabled: true, actions: ["delete", "unsend"] },
|
|
31
|
+
{ key: "pins", defaultEnabled: true, actions: ["pin", "unpin", "list-pins"] },
|
|
32
|
+
{ key: "permissions", defaultEnabled: true, actions: ["permissions"] },
|
|
15
33
|
];
|
|
34
|
+
const ACTION_TO_GATE_KEY = new Map();
|
|
35
|
+
for (const group of ACTION_GROUPS) {
|
|
36
|
+
for (const action of group.actions) {
|
|
37
|
+
ACTION_TO_GATE_KEY.set(action, group.key);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const SUPPORTED_ACTIONS = Array.from(ACTION_TO_GATE_KEY.keys());
|
|
16
41
|
function normalizeChatId(raw) {
|
|
17
42
|
const normalized = normalizeInlineTarget(raw) ?? raw.trim();
|
|
18
43
|
if (!/^[0-9]+$/.test(normalized)) {
|
|
@@ -35,11 +60,28 @@ function readFlexibleId(params, key) {
|
|
|
35
60
|
}
|
|
36
61
|
return undefined;
|
|
37
62
|
}
|
|
63
|
+
function readBooleanParam(params, key) {
|
|
64
|
+
const value = params[key];
|
|
65
|
+
if (typeof value === "boolean")
|
|
66
|
+
return value;
|
|
67
|
+
if (typeof value === "string") {
|
|
68
|
+
const trimmed = value.trim().toLowerCase();
|
|
69
|
+
if (trimmed === "true")
|
|
70
|
+
return true;
|
|
71
|
+
if (trimmed === "false")
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
38
76
|
function parseInlineId(raw, label) {
|
|
39
|
-
if (typeof raw === "bigint")
|
|
77
|
+
if (typeof raw === "bigint") {
|
|
78
|
+
if (raw < 0n) {
|
|
79
|
+
throw new Error(`inline action: invalid ${label} "${raw.toString()}"`);
|
|
80
|
+
}
|
|
40
81
|
return raw;
|
|
82
|
+
}
|
|
41
83
|
if (typeof raw === "number") {
|
|
42
|
-
if (!Number.isFinite(raw) || !Number.isInteger(raw)) {
|
|
84
|
+
if (!Number.isFinite(raw) || !Number.isInteger(raw) || raw < 0) {
|
|
43
85
|
throw new Error(`inline action: invalid ${label} "${String(raw)}"`);
|
|
44
86
|
}
|
|
45
87
|
return BigInt(raw);
|
|
@@ -61,6 +103,34 @@ function parseOptionalInlineId(raw, label) {
|
|
|
61
103
|
return undefined;
|
|
62
104
|
return parseInlineId(raw, label);
|
|
63
105
|
}
|
|
106
|
+
function parseInlineIdList(raw, label) {
|
|
107
|
+
if (raw == null)
|
|
108
|
+
return [];
|
|
109
|
+
if (Array.isArray(raw)) {
|
|
110
|
+
return raw.map((item) => parseInlineId(item, label));
|
|
111
|
+
}
|
|
112
|
+
if (typeof raw === "string") {
|
|
113
|
+
const trimmed = raw.trim();
|
|
114
|
+
if (!trimmed)
|
|
115
|
+
return [];
|
|
116
|
+
const chunks = trimmed
|
|
117
|
+
.split(",")
|
|
118
|
+
.map((item) => item.trim())
|
|
119
|
+
.filter(Boolean);
|
|
120
|
+
if (chunks.length <= 1) {
|
|
121
|
+
return [parseInlineId(trimmed, label)];
|
|
122
|
+
}
|
|
123
|
+
return chunks.map((item) => parseInlineId(item, label));
|
|
124
|
+
}
|
|
125
|
+
return [parseInlineId(raw, label)];
|
|
126
|
+
}
|
|
127
|
+
function parseInlineIdListFromParams(params, key) {
|
|
128
|
+
const direct = params[key];
|
|
129
|
+
if (direct != null) {
|
|
130
|
+
return parseInlineIdList(direct, key);
|
|
131
|
+
}
|
|
132
|
+
return [];
|
|
133
|
+
}
|
|
64
134
|
function resolveChatIdFromParams(params) {
|
|
65
135
|
const raw = readFlexibleId(params, "chatId") ??
|
|
66
136
|
readFlexibleId(params, "channelId") ??
|
|
@@ -79,6 +149,15 @@ function buildChatPeer(chatId) {
|
|
|
79
149
|
},
|
|
80
150
|
};
|
|
81
151
|
}
|
|
152
|
+
function buildInlineUserDisplayName(user) {
|
|
153
|
+
const explicit = [user.firstName?.trim(), user.lastName?.trim()].filter(Boolean).join(" ");
|
|
154
|
+
if (explicit)
|
|
155
|
+
return explicit;
|
|
156
|
+
const username = user.username?.trim();
|
|
157
|
+
if (username)
|
|
158
|
+
return `@${username}`;
|
|
159
|
+
return "Unknown";
|
|
160
|
+
}
|
|
82
161
|
function mapMessage(message) {
|
|
83
162
|
const reactions = (message.reactions?.reactions ?? []).map((reaction) => ({
|
|
84
163
|
emoji: reaction.emoji ?? "",
|
|
@@ -97,19 +176,52 @@ function mapMessage(message) {
|
|
|
97
176
|
reactions,
|
|
98
177
|
};
|
|
99
178
|
}
|
|
179
|
+
function mapChatEntry(params) {
|
|
180
|
+
const dialog = params.dialogByChatId.get(String(params.chat.id));
|
|
181
|
+
const peer = params.chat.peerId?.type;
|
|
182
|
+
let peerUser = null;
|
|
183
|
+
if (peer?.oneofKind === "user") {
|
|
184
|
+
peerUser = params.usersById.get(String(peer.user.userId)) ?? null;
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
id: String(params.chat.id),
|
|
188
|
+
title: params.chat.title,
|
|
189
|
+
spaceId: params.chat.spaceId != null ? String(params.chat.spaceId) : null,
|
|
190
|
+
isPublic: params.chat.isPublic ?? false,
|
|
191
|
+
createdBy: params.chat.createdBy != null ? String(params.chat.createdBy) : null,
|
|
192
|
+
date: params.chat.date != null ? Number(params.chat.date) * 1000 : null,
|
|
193
|
+
unreadCount: dialog?.unreadCount ?? 0,
|
|
194
|
+
archived: Boolean(dialog?.archived),
|
|
195
|
+
pinned: Boolean(dialog?.pinned),
|
|
196
|
+
peer: peer?.oneofKind === "user"
|
|
197
|
+
? {
|
|
198
|
+
kind: "user",
|
|
199
|
+
id: String(peer.user.userId),
|
|
200
|
+
username: peerUser?.username ?? null,
|
|
201
|
+
name: peerUser ? buildInlineUserDisplayName(peerUser) : null,
|
|
202
|
+
}
|
|
203
|
+
: peer?.oneofKind === "chat"
|
|
204
|
+
? { kind: "chat", id: String(peer.chat.chatId) }
|
|
205
|
+
: null,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
function mapSpaceMemberRole(role) {
|
|
209
|
+
if (role == null)
|
|
210
|
+
return null;
|
|
211
|
+
if (role === Member_Role.OWNER)
|
|
212
|
+
return "owner";
|
|
213
|
+
if (role === Member_Role.ADMIN)
|
|
214
|
+
return "admin";
|
|
215
|
+
if (role === Member_Role.MEMBER)
|
|
216
|
+
return "member";
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
100
219
|
async function loadMessageReactions(params) {
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
offsetId: params.messageId + 1n,
|
|
106
|
-
limit: 8,
|
|
107
|
-
},
|
|
220
|
+
const target = await findMessageById({
|
|
221
|
+
client: params.client,
|
|
222
|
+
chatId: params.chatId,
|
|
223
|
+
messageId: params.messageId,
|
|
108
224
|
});
|
|
109
|
-
if (result.oneofKind !== "getChatHistory") {
|
|
110
|
-
throw new Error(`inline action: expected getChatHistory result, got ${String(result.oneofKind)}`);
|
|
111
|
-
}
|
|
112
|
-
const target = (result.getChatHistory.messages ?? []).find((message) => message.id === params.messageId) ?? null;
|
|
113
225
|
if (!target) {
|
|
114
226
|
return [];
|
|
115
227
|
}
|
|
@@ -132,6 +244,32 @@ async function loadMessageReactions(params) {
|
|
|
132
244
|
}
|
|
133
245
|
return Array.from(byEmoji.values());
|
|
134
246
|
}
|
|
247
|
+
async function findMessageById(params) {
|
|
248
|
+
const directResult = await params.client
|
|
249
|
+
.invokeRaw(Method.GET_MESSAGES, {
|
|
250
|
+
oneofKind: "getMessages",
|
|
251
|
+
getMessages: {
|
|
252
|
+
peerId: buildChatPeer(params.chatId),
|
|
253
|
+
messageIds: [params.messageId],
|
|
254
|
+
},
|
|
255
|
+
})
|
|
256
|
+
.catch(() => null);
|
|
257
|
+
if (directResult?.oneofKind === "getMessages") {
|
|
258
|
+
return (directResult.getMessages.messages ?? []).find((message) => message.id === params.messageId) ?? null;
|
|
259
|
+
}
|
|
260
|
+
const result = await params.client.invokeRaw(Method.GET_CHAT_HISTORY, {
|
|
261
|
+
oneofKind: "getChatHistory",
|
|
262
|
+
getChatHistory: {
|
|
263
|
+
peerId: buildChatPeer(params.chatId),
|
|
264
|
+
offsetId: params.messageId + 1n,
|
|
265
|
+
limit: 8,
|
|
266
|
+
},
|
|
267
|
+
});
|
|
268
|
+
if (result.oneofKind !== "getChatHistory") {
|
|
269
|
+
throw new Error(`inline action: expected getChatHistory result, got ${String(result.oneofKind)}`);
|
|
270
|
+
}
|
|
271
|
+
return (result.getChatHistory.messages ?? []).find((message) => message.id === params.messageId) ?? null;
|
|
272
|
+
}
|
|
135
273
|
async function withInlineClient(params) {
|
|
136
274
|
const account = resolveInlineAccount({ cfg: params.cfg, accountId: params.accountId ?? null });
|
|
137
275
|
if (!account.configured || !account.baseUrl) {
|
|
@@ -164,14 +302,68 @@ function toJsonSafe(value) {
|
|
|
164
302
|
}
|
|
165
303
|
return value;
|
|
166
304
|
}
|
|
305
|
+
function buildDialogMap(dialogs) {
|
|
306
|
+
const map = new Map();
|
|
307
|
+
for (const dialog of dialogs) {
|
|
308
|
+
const chatId = dialog.chatId;
|
|
309
|
+
if (chatId != null) {
|
|
310
|
+
map.set(String(chatId), dialog);
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
const peer = dialog.peer?.type;
|
|
314
|
+
if (peer?.oneofKind === "chat") {
|
|
315
|
+
map.set(String(peer.chat.chatId), dialog);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return map;
|
|
319
|
+
}
|
|
320
|
+
function buildUserMap(users) {
|
|
321
|
+
const map = new Map();
|
|
322
|
+
for (const user of users) {
|
|
323
|
+
map.set(String(user.id), user);
|
|
324
|
+
}
|
|
325
|
+
return map;
|
|
326
|
+
}
|
|
327
|
+
function listAllActions() {
|
|
328
|
+
const out = new Set();
|
|
329
|
+
for (const group of ACTION_GROUPS) {
|
|
330
|
+
for (const action of group.actions) {
|
|
331
|
+
out.add(action);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return Array.from(out);
|
|
335
|
+
}
|
|
336
|
+
function isActionEnabled(params) {
|
|
337
|
+
const key = ACTION_TO_GATE_KEY.get(params.action);
|
|
338
|
+
if (!key)
|
|
339
|
+
return false;
|
|
340
|
+
const group = ACTION_GROUPS.find((item) => item.key === key);
|
|
341
|
+
if (!group)
|
|
342
|
+
return false;
|
|
343
|
+
const account = resolveInlineAccount({
|
|
344
|
+
cfg: params.cfg,
|
|
345
|
+
accountId: params.accountId ?? null,
|
|
346
|
+
});
|
|
347
|
+
const gate = createActionGate((account.config.actions ?? {}));
|
|
348
|
+
return gate(key, group.defaultEnabled);
|
|
349
|
+
}
|
|
167
350
|
export const inlineMessageActions = {
|
|
168
351
|
listActions: ({ cfg }) => {
|
|
169
352
|
const account = resolveInlineAccount({ cfg, accountId: null });
|
|
170
353
|
if (!account.enabled || !account.configured)
|
|
171
354
|
return [];
|
|
172
|
-
|
|
355
|
+
const gate = createActionGate((account.config.actions ?? {}));
|
|
356
|
+
const actions = new Set();
|
|
357
|
+
for (const group of ACTION_GROUPS) {
|
|
358
|
+
if (!gate(group.key, group.defaultEnabled))
|
|
359
|
+
continue;
|
|
360
|
+
for (const action of group.actions) {
|
|
361
|
+
actions.add(action);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return Array.from(actions);
|
|
173
365
|
},
|
|
174
|
-
supportsAction: ({ action }) =>
|
|
366
|
+
supportsAction: ({ action }) => SUPPORTED_ACTIONS.includes(action),
|
|
175
367
|
extractToolSend: ({ args }) => {
|
|
176
368
|
const action = typeof args.action === "string" ? args.action.trim() : "";
|
|
177
369
|
if (action !== "sendMessage")
|
|
@@ -185,13 +377,51 @@ export const inlineMessageActions = {
|
|
|
185
377
|
return { to: normalized };
|
|
186
378
|
},
|
|
187
379
|
handleAction: async ({ action, params, cfg, accountId }) => {
|
|
188
|
-
if (action
|
|
380
|
+
if (!SUPPORTED_ACTIONS.includes(action)) {
|
|
381
|
+
throw new Error(`Action ${action} is not supported for provider inline.`);
|
|
382
|
+
}
|
|
383
|
+
if (!isActionEnabled({ cfg, accountId: accountId ?? null, action })) {
|
|
384
|
+
throw new Error(`inline action: ${action} is disabled by channels.inline.actions`);
|
|
385
|
+
}
|
|
386
|
+
const normalizedAction = action === "thread-reply" ? "reply" : action;
|
|
387
|
+
if (normalizedAction === "reply") {
|
|
388
|
+
const parseMarkdown = resolveInlineAccount({ cfg, accountId: accountId ?? null }).config.parseMarkdown ?? true;
|
|
189
389
|
return await withInlineClient({
|
|
190
390
|
cfg,
|
|
191
391
|
accountId,
|
|
192
392
|
fn: async (client) => {
|
|
193
393
|
const chatId = resolveChatIdFromParams(params);
|
|
194
|
-
const
|
|
394
|
+
const replyToMsgId = parseInlineId(readFlexibleId(params, "messageId") ??
|
|
395
|
+
readFlexibleId(params, "replyTo") ??
|
|
396
|
+
readFlexibleId(params, "replyToId") ??
|
|
397
|
+
readStringParam(params, "messageId") ??
|
|
398
|
+
readStringParam(params, "replyTo") ??
|
|
399
|
+
readStringParam(params, "replyToId", { required: true }), "messageId");
|
|
400
|
+
const text = readStringParam(params, "message") ??
|
|
401
|
+
readStringParam(params, "text", { required: true, allowEmpty: true });
|
|
402
|
+
const sent = await client.sendMessage({
|
|
403
|
+
chatId,
|
|
404
|
+
text,
|
|
405
|
+
replyToMsgId,
|
|
406
|
+
parseMarkdown,
|
|
407
|
+
});
|
|
408
|
+
return jsonResult({
|
|
409
|
+
ok: true,
|
|
410
|
+
chatId: String(chatId),
|
|
411
|
+
messageId: sent.messageId != null ? String(sent.messageId) : null,
|
|
412
|
+
replyToId: String(replyToMsgId),
|
|
413
|
+
});
|
|
414
|
+
},
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
if (normalizedAction === "react") {
|
|
418
|
+
return await withInlineClient({
|
|
419
|
+
cfg,
|
|
420
|
+
accountId,
|
|
421
|
+
fn: async (client) => {
|
|
422
|
+
const chatId = resolveChatIdFromParams(params);
|
|
423
|
+
const messageId = parseInlineId(readFlexibleId(params, "messageId") ??
|
|
424
|
+
readStringParam(params, "messageId", { required: true }), "messageId");
|
|
195
425
|
const { emoji, remove, isEmpty } = readReactionParams(params, {
|
|
196
426
|
removeErrorMessage: "Emoji is required to remove an Inline reaction.",
|
|
197
427
|
});
|
|
@@ -234,13 +464,14 @@ export const inlineMessageActions = {
|
|
|
234
464
|
},
|
|
235
465
|
});
|
|
236
466
|
}
|
|
237
|
-
if (
|
|
467
|
+
if (normalizedAction === "reactions") {
|
|
238
468
|
return await withInlineClient({
|
|
239
469
|
cfg,
|
|
240
470
|
accountId,
|
|
241
471
|
fn: async (client) => {
|
|
242
472
|
const chatId = resolveChatIdFromParams(params);
|
|
243
|
-
const messageId = parseInlineId(readFlexibleId(params, "messageId") ??
|
|
473
|
+
const messageId = parseInlineId(readFlexibleId(params, "messageId") ??
|
|
474
|
+
readStringParam(params, "messageId", { required: true }), "messageId");
|
|
244
475
|
const reactions = await loadMessageReactions({
|
|
245
476
|
client,
|
|
246
477
|
chatId,
|
|
@@ -255,7 +486,7 @@ export const inlineMessageActions = {
|
|
|
255
486
|
},
|
|
256
487
|
});
|
|
257
488
|
}
|
|
258
|
-
if (
|
|
489
|
+
if (normalizedAction === "read") {
|
|
259
490
|
return await withInlineClient({
|
|
260
491
|
cfg,
|
|
261
492
|
accountId,
|
|
@@ -282,7 +513,7 @@ export const inlineMessageActions = {
|
|
|
282
513
|
},
|
|
283
514
|
});
|
|
284
515
|
}
|
|
285
|
-
if (
|
|
516
|
+
if (normalizedAction === "search") {
|
|
286
517
|
return await withInlineClient({
|
|
287
518
|
cfg,
|
|
288
519
|
accountId,
|
|
@@ -314,13 +545,14 @@ export const inlineMessageActions = {
|
|
|
314
545
|
},
|
|
315
546
|
});
|
|
316
547
|
}
|
|
317
|
-
if (
|
|
548
|
+
if (normalizedAction === "edit") {
|
|
318
549
|
return await withInlineClient({
|
|
319
550
|
cfg,
|
|
320
551
|
accountId,
|
|
321
552
|
fn: async (client) => {
|
|
322
553
|
const chatId = resolveChatIdFromParams(params);
|
|
323
|
-
const messageId = parseInlineId(readFlexibleId(params, "messageId") ??
|
|
554
|
+
const messageId = parseInlineId(readFlexibleId(params, "messageId") ??
|
|
555
|
+
readStringParam(params, "messageId", { required: true }), "messageId");
|
|
324
556
|
const text = readStringParam(params, "message", { required: true, allowEmpty: true });
|
|
325
557
|
const result = await client.invokeRaw(Method.EDIT_MESSAGE, {
|
|
326
558
|
oneofKind: "editMessage",
|
|
@@ -337,7 +569,7 @@ export const inlineMessageActions = {
|
|
|
337
569
|
},
|
|
338
570
|
});
|
|
339
571
|
}
|
|
340
|
-
if (
|
|
572
|
+
if (normalizedAction === "channel-info") {
|
|
341
573
|
return await withInlineClient({
|
|
342
574
|
cfg,
|
|
343
575
|
accountId,
|
|
@@ -360,7 +592,7 @@ export const inlineMessageActions = {
|
|
|
360
592
|
},
|
|
361
593
|
});
|
|
362
594
|
}
|
|
363
|
-
if (
|
|
595
|
+
if (normalizedAction === "channel-edit") {
|
|
364
596
|
return await withInlineClient({
|
|
365
597
|
cfg,
|
|
366
598
|
accountId,
|
|
@@ -388,7 +620,150 @@ export const inlineMessageActions = {
|
|
|
388
620
|
},
|
|
389
621
|
});
|
|
390
622
|
}
|
|
391
|
-
if (
|
|
623
|
+
if (normalizedAction === "channel-list" || normalizedAction === "thread-list") {
|
|
624
|
+
return await withInlineClient({
|
|
625
|
+
cfg,
|
|
626
|
+
accountId,
|
|
627
|
+
fn: async (client) => {
|
|
628
|
+
const query = readStringParam(params, "query") ??
|
|
629
|
+
readStringParam(params, "q") ??
|
|
630
|
+
undefined;
|
|
631
|
+
const limit = Math.max(1, Math.min(200, readNumberParam(params, "limit", { integer: true }) ?? 50));
|
|
632
|
+
const result = await client.invokeRaw(Method.GET_CHATS, {
|
|
633
|
+
oneofKind: "getChats",
|
|
634
|
+
getChats: {},
|
|
635
|
+
});
|
|
636
|
+
if (result.oneofKind !== "getChats") {
|
|
637
|
+
throw new Error(`inline action: expected getChats result, got ${String(result.oneofKind)}`);
|
|
638
|
+
}
|
|
639
|
+
const dialogByChatId = buildDialogMap(result.getChats.dialogs ?? []);
|
|
640
|
+
const usersById = buildUserMap(result.getChats.users ?? []);
|
|
641
|
+
const entries = (result.getChats.chats ?? []).map((chat) => mapChatEntry({ chat, dialogByChatId, usersById }));
|
|
642
|
+
const normalizedQuery = query?.trim().toLowerCase() ?? "";
|
|
643
|
+
const filtered = normalizedQuery
|
|
644
|
+
? entries.filter((entry) => {
|
|
645
|
+
const haystack = [
|
|
646
|
+
entry.id,
|
|
647
|
+
entry.title,
|
|
648
|
+
entry.peer?.kind === "user" ? entry.peer.username ?? "" : "",
|
|
649
|
+
entry.peer?.kind === "user" ? entry.peer.name ?? "" : "",
|
|
650
|
+
]
|
|
651
|
+
.join("\n")
|
|
652
|
+
.toLowerCase();
|
|
653
|
+
return haystack.includes(normalizedQuery);
|
|
654
|
+
})
|
|
655
|
+
: entries;
|
|
656
|
+
return jsonResult(toJsonSafe({
|
|
657
|
+
ok: true,
|
|
658
|
+
query: query ?? null,
|
|
659
|
+
count: filtered.length,
|
|
660
|
+
chats: filtered.slice(0, limit),
|
|
661
|
+
}));
|
|
662
|
+
},
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
if (normalizedAction === "channel-create" || normalizedAction === "thread-create") {
|
|
666
|
+
return await withInlineClient({
|
|
667
|
+
cfg,
|
|
668
|
+
accountId,
|
|
669
|
+
fn: async (client) => {
|
|
670
|
+
const title = readStringParam(params, "title") ??
|
|
671
|
+
readStringParam(params, "name") ??
|
|
672
|
+
readStringParam(params, "message", { required: true });
|
|
673
|
+
const description = readStringParam(params, "description");
|
|
674
|
+
const emoji = readStringParam(params, "emoji");
|
|
675
|
+
const spaceId = parseOptionalInlineId(readFlexibleId(params, "spaceId") ?? readFlexibleId(params, "space"), "spaceId");
|
|
676
|
+
const isPublic = readBooleanParam(params, "isPublic") ?? false;
|
|
677
|
+
const participantIds = [
|
|
678
|
+
...parseInlineIdListFromParams(params, "participants"),
|
|
679
|
+
...parseInlineIdListFromParams(params, "participantIds"),
|
|
680
|
+
...parseInlineIdListFromParams(params, "userIds"),
|
|
681
|
+
...parseInlineIdListFromParams(params, "userId"),
|
|
682
|
+
];
|
|
683
|
+
const dedupedParticipants = Array.from(new Set(participantIds.map((id) => id.toString()))).map((id) => BigInt(id));
|
|
684
|
+
const result = await client.invokeRaw(Method.CREATE_CHAT, {
|
|
685
|
+
oneofKind: "createChat",
|
|
686
|
+
createChat: {
|
|
687
|
+
title,
|
|
688
|
+
...(spaceId != null ? { spaceId } : {}),
|
|
689
|
+
...(description ? { description } : {}),
|
|
690
|
+
...(emoji ? { emoji } : {}),
|
|
691
|
+
isPublic,
|
|
692
|
+
participants: isPublic ? [] : dedupedParticipants.map((userId) => ({ userId })),
|
|
693
|
+
},
|
|
694
|
+
});
|
|
695
|
+
if (result.oneofKind !== "createChat") {
|
|
696
|
+
throw new Error(`inline action: expected createChat result, got ${String(result.oneofKind)}`);
|
|
697
|
+
}
|
|
698
|
+
return jsonResult(toJsonSafe({
|
|
699
|
+
ok: true,
|
|
700
|
+
title,
|
|
701
|
+
spaceId: spaceId != null ? String(spaceId) : null,
|
|
702
|
+
isPublic,
|
|
703
|
+
participants: dedupedParticipants.map((id) => String(id)),
|
|
704
|
+
chat: result.createChat.chat ?? null,
|
|
705
|
+
dialog: result.createChat.dialog ?? null,
|
|
706
|
+
}));
|
|
707
|
+
},
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
if (normalizedAction === "channel-delete") {
|
|
711
|
+
return await withInlineClient({
|
|
712
|
+
cfg,
|
|
713
|
+
accountId,
|
|
714
|
+
fn: async (client) => {
|
|
715
|
+
const chatId = resolveChatIdFromParams(params);
|
|
716
|
+
const result = await client.invokeRaw(Method.DELETE_CHAT, {
|
|
717
|
+
oneofKind: "deleteChat",
|
|
718
|
+
deleteChat: {
|
|
719
|
+
peerId: buildChatPeer(chatId),
|
|
720
|
+
},
|
|
721
|
+
});
|
|
722
|
+
if (result.oneofKind !== "deleteChat") {
|
|
723
|
+
throw new Error(`inline action: expected deleteChat result, got ${String(result.oneofKind)}`);
|
|
724
|
+
}
|
|
725
|
+
return jsonResult({
|
|
726
|
+
ok: true,
|
|
727
|
+
chatId: String(chatId),
|
|
728
|
+
});
|
|
729
|
+
},
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
if (normalizedAction === "channel-move") {
|
|
733
|
+
return await withInlineClient({
|
|
734
|
+
cfg,
|
|
735
|
+
accountId,
|
|
736
|
+
fn: async (client) => {
|
|
737
|
+
const chatId = resolveChatIdFromParams(params);
|
|
738
|
+
const rawSpace = readStringParam(params, "spaceId") ?? readStringParam(params, "toSpaceId");
|
|
739
|
+
const normalizedSpace = rawSpace?.trim().toLowerCase();
|
|
740
|
+
const moveToHome = normalizedSpace === "" ||
|
|
741
|
+
normalizedSpace === "home" ||
|
|
742
|
+
normalizedSpace === "none" ||
|
|
743
|
+
normalizedSpace === "null";
|
|
744
|
+
const parsedSpace = moveToHome
|
|
745
|
+
? undefined
|
|
746
|
+
: parseOptionalInlineId(readFlexibleId(params, "spaceId") ?? readFlexibleId(params, "toSpaceId"), "spaceId");
|
|
747
|
+
const result = await client.invokeRaw(Method.MOVE_THREAD, {
|
|
748
|
+
oneofKind: "moveThread",
|
|
749
|
+
moveThread: {
|
|
750
|
+
chatId,
|
|
751
|
+
...(parsedSpace != null ? { spaceId: parsedSpace } : {}),
|
|
752
|
+
},
|
|
753
|
+
});
|
|
754
|
+
if (result.oneofKind !== "moveThread") {
|
|
755
|
+
throw new Error(`inline action: expected moveThread result, got ${String(result.oneofKind)}`);
|
|
756
|
+
}
|
|
757
|
+
return jsonResult(toJsonSafe({
|
|
758
|
+
ok: true,
|
|
759
|
+
chatId: String(chatId),
|
|
760
|
+
spaceId: parsedSpace != null ? String(parsedSpace) : null,
|
|
761
|
+
chat: result.moveThread.chat ?? null,
|
|
762
|
+
}));
|
|
763
|
+
},
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
if (normalizedAction === "addParticipant") {
|
|
392
767
|
return await withInlineClient({
|
|
393
768
|
cfg,
|
|
394
769
|
accountId,
|
|
@@ -417,13 +792,69 @@ export const inlineMessageActions = {
|
|
|
417
792
|
},
|
|
418
793
|
});
|
|
419
794
|
}
|
|
420
|
-
if (
|
|
795
|
+
if (normalizedAction === "removeParticipant") {
|
|
796
|
+
return await withInlineClient({
|
|
797
|
+
cfg,
|
|
798
|
+
accountId,
|
|
799
|
+
fn: async (client) => {
|
|
800
|
+
const chatId = resolveChatIdFromParams(params);
|
|
801
|
+
const userId = parseInlineId(readFlexibleId(params, "userId") ??
|
|
802
|
+
readFlexibleId(params, "participant") ??
|
|
803
|
+
readFlexibleId(params, "memberId") ??
|
|
804
|
+
readStringParam(params, "userId", { required: true }), "userId");
|
|
805
|
+
const result = await client.invokeRaw(Method.REMOVE_CHAT_PARTICIPANT, {
|
|
806
|
+
oneofKind: "removeChatParticipant",
|
|
807
|
+
removeChatParticipant: {
|
|
808
|
+
chatId,
|
|
809
|
+
userId,
|
|
810
|
+
},
|
|
811
|
+
});
|
|
812
|
+
if (result.oneofKind !== "removeChatParticipant") {
|
|
813
|
+
throw new Error(`inline action: expected removeChatParticipant result, got ${String(result.oneofKind)}`);
|
|
814
|
+
}
|
|
815
|
+
return jsonResult({
|
|
816
|
+
ok: true,
|
|
817
|
+
chatId: String(chatId),
|
|
818
|
+
userId: String(userId),
|
|
819
|
+
});
|
|
820
|
+
},
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
if (normalizedAction === "leaveGroup") {
|
|
421
824
|
return await withInlineClient({
|
|
422
825
|
cfg,
|
|
423
826
|
accountId,
|
|
424
827
|
fn: async (client) => {
|
|
425
828
|
const chatId = resolveChatIdFromParams(params);
|
|
426
|
-
const
|
|
829
|
+
const me = await client.getMe();
|
|
830
|
+
const userId = me.userId;
|
|
831
|
+
const result = await client.invokeRaw(Method.REMOVE_CHAT_PARTICIPANT, {
|
|
832
|
+
oneofKind: "removeChatParticipant",
|
|
833
|
+
removeChatParticipant: {
|
|
834
|
+
chatId,
|
|
835
|
+
userId,
|
|
836
|
+
},
|
|
837
|
+
});
|
|
838
|
+
if (result.oneofKind !== "removeChatParticipant") {
|
|
839
|
+
throw new Error(`inline action: expected removeChatParticipant result, got ${String(result.oneofKind)}`);
|
|
840
|
+
}
|
|
841
|
+
return jsonResult({
|
|
842
|
+
ok: true,
|
|
843
|
+
chatId: String(chatId),
|
|
844
|
+
userId: String(userId),
|
|
845
|
+
left: true,
|
|
846
|
+
});
|
|
847
|
+
},
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
if (normalizedAction === "member-info") {
|
|
851
|
+
return await withInlineClient({
|
|
852
|
+
cfg,
|
|
853
|
+
accountId,
|
|
854
|
+
fn: async (client) => {
|
|
855
|
+
const chatId = resolveChatIdFromParams(params);
|
|
856
|
+
const userId = parseInlineId(readFlexibleId(params, "userId") ??
|
|
857
|
+
readStringParam(params, "userId", { required: true }), "userId");
|
|
427
858
|
const result = await client.invokeRaw(Method.GET_CHAT_PARTICIPANTS, {
|
|
428
859
|
oneofKind: "getChatParticipants",
|
|
429
860
|
getChatParticipants: { chatId },
|
|
@@ -443,7 +874,180 @@ export const inlineMessageActions = {
|
|
|
443
874
|
},
|
|
444
875
|
});
|
|
445
876
|
}
|
|
877
|
+
if (normalizedAction === "delete" || normalizedAction === "unsend") {
|
|
878
|
+
return await withInlineClient({
|
|
879
|
+
cfg,
|
|
880
|
+
accountId,
|
|
881
|
+
fn: async (client) => {
|
|
882
|
+
const chatId = resolveChatIdFromParams(params);
|
|
883
|
+
const messageIds = [
|
|
884
|
+
...parseInlineIdListFromParams(params, "messageIds"),
|
|
885
|
+
...parseInlineIdListFromParams(params, "messages"),
|
|
886
|
+
...parseInlineIdListFromParams(params, "ids"),
|
|
887
|
+
];
|
|
888
|
+
if (messageIds.length === 0) {
|
|
889
|
+
messageIds.push(parseInlineId(readFlexibleId(params, "messageId") ??
|
|
890
|
+
readStringParam(params, "messageId", { required: true }), "messageId"));
|
|
891
|
+
}
|
|
892
|
+
const deduped = Array.from(new Set(messageIds.map((id) => id.toString()))).map((id) => BigInt(id));
|
|
893
|
+
const result = await client.invokeRaw(Method.DELETE_MESSAGES, {
|
|
894
|
+
oneofKind: "deleteMessages",
|
|
895
|
+
deleteMessages: {
|
|
896
|
+
peerId: buildChatPeer(chatId),
|
|
897
|
+
messageIds: deduped,
|
|
898
|
+
},
|
|
899
|
+
});
|
|
900
|
+
if (result.oneofKind !== "deleteMessages") {
|
|
901
|
+
throw new Error(`inline action: expected deleteMessages result, got ${String(result.oneofKind)}`);
|
|
902
|
+
}
|
|
903
|
+
return jsonResult({
|
|
904
|
+
ok: true,
|
|
905
|
+
chatId: String(chatId),
|
|
906
|
+
messageIds: deduped.map((id) => String(id)),
|
|
907
|
+
});
|
|
908
|
+
},
|
|
909
|
+
});
|
|
910
|
+
}
|
|
911
|
+
if (normalizedAction === "pin" || normalizedAction === "unpin") {
|
|
912
|
+
return await withInlineClient({
|
|
913
|
+
cfg,
|
|
914
|
+
accountId,
|
|
915
|
+
fn: async (client) => {
|
|
916
|
+
const chatId = resolveChatIdFromParams(params);
|
|
917
|
+
const messageId = parseInlineId(readFlexibleId(params, "messageId") ??
|
|
918
|
+
readStringParam(params, "messageId", { required: true }), "messageId");
|
|
919
|
+
const unpin = normalizedAction === "unpin" || readBooleanParam(params, "unpin") === true;
|
|
920
|
+
const result = await client.invokeRaw(Method.PIN_MESSAGE, {
|
|
921
|
+
oneofKind: "pinMessage",
|
|
922
|
+
pinMessage: {
|
|
923
|
+
peerId: buildChatPeer(chatId),
|
|
924
|
+
messageId,
|
|
925
|
+
unpin,
|
|
926
|
+
},
|
|
927
|
+
});
|
|
928
|
+
if (result.oneofKind !== "pinMessage") {
|
|
929
|
+
throw new Error(`inline action: expected pinMessage result, got ${String(result.oneofKind)}`);
|
|
930
|
+
}
|
|
931
|
+
return jsonResult({
|
|
932
|
+
ok: true,
|
|
933
|
+
chatId: String(chatId),
|
|
934
|
+
messageId: String(messageId),
|
|
935
|
+
unpin,
|
|
936
|
+
});
|
|
937
|
+
},
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
if (normalizedAction === "list-pins") {
|
|
941
|
+
return await withInlineClient({
|
|
942
|
+
cfg,
|
|
943
|
+
accountId,
|
|
944
|
+
fn: async (client) => {
|
|
945
|
+
const chatId = resolveChatIdFromParams(params);
|
|
946
|
+
const result = await client.invokeRaw(Method.GET_CHAT, {
|
|
947
|
+
oneofKind: "getChat",
|
|
948
|
+
getChat: { peerId: buildChatPeer(chatId) },
|
|
949
|
+
});
|
|
950
|
+
if (result.oneofKind !== "getChat") {
|
|
951
|
+
throw new Error(`inline action: expected getChat result, got ${String(result.oneofKind)}`);
|
|
952
|
+
}
|
|
953
|
+
const pinnedMessageIds = (result.getChat.pinnedMessageIds ?? []).map((id) => String(id));
|
|
954
|
+
return jsonResult({
|
|
955
|
+
ok: true,
|
|
956
|
+
chatId: String(chatId),
|
|
957
|
+
pinnedMessageIds,
|
|
958
|
+
});
|
|
959
|
+
},
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
if (normalizedAction === "permissions") {
|
|
963
|
+
return await withInlineClient({
|
|
964
|
+
cfg,
|
|
965
|
+
accountId,
|
|
966
|
+
fn: async (client) => {
|
|
967
|
+
const chatId = resolveChatIdFromParams(params);
|
|
968
|
+
const chatResult = await client.invokeRaw(Method.GET_CHAT, {
|
|
969
|
+
oneofKind: "getChat",
|
|
970
|
+
getChat: { peerId: buildChatPeer(chatId) },
|
|
971
|
+
});
|
|
972
|
+
if (chatResult.oneofKind !== "getChat") {
|
|
973
|
+
throw new Error(`inline action: expected getChat result, got ${String(chatResult.oneofKind)}`);
|
|
974
|
+
}
|
|
975
|
+
const spaceId = chatResult.getChat.chat?.spaceId ?? chatResult.getChat.dialog?.spaceId;
|
|
976
|
+
if (spaceId == null) {
|
|
977
|
+
throw new Error("inline action: permissions requires a chat that belongs to a space");
|
|
978
|
+
}
|
|
979
|
+
const userIdRaw = readFlexibleId(params, "userId") ??
|
|
980
|
+
readFlexibleId(params, "memberId") ??
|
|
981
|
+
readStringParam(params, "userId");
|
|
982
|
+
const userId = userIdRaw ? parseInlineId(userIdRaw, "userId") : undefined;
|
|
983
|
+
const roleValue = readStringParam(params, "role")?.trim().toLowerCase();
|
|
984
|
+
const canAccessPublicChats = readBooleanParam(params, "canAccessPublicChats");
|
|
985
|
+
if (userId != null && roleValue) {
|
|
986
|
+
const role = roleValue === "admin"
|
|
987
|
+
? { role: { oneofKind: "admin", admin: {} } }
|
|
988
|
+
: roleValue === "member"
|
|
989
|
+
? {
|
|
990
|
+
role: {
|
|
991
|
+
oneofKind: "member",
|
|
992
|
+
member: {
|
|
993
|
+
canAccessPublicChats: canAccessPublicChats ?? true,
|
|
994
|
+
},
|
|
995
|
+
},
|
|
996
|
+
}
|
|
997
|
+
: null;
|
|
998
|
+
if (!role) {
|
|
999
|
+
throw new Error("inline action: role must be \"admin\" or \"member\"");
|
|
1000
|
+
}
|
|
1001
|
+
const updateResult = await client.invokeRaw(Method.UPDATE_MEMBER_ACCESS, {
|
|
1002
|
+
oneofKind: "updateMemberAccess",
|
|
1003
|
+
updateMemberAccess: {
|
|
1004
|
+
spaceId,
|
|
1005
|
+
userId,
|
|
1006
|
+
role,
|
|
1007
|
+
},
|
|
1008
|
+
});
|
|
1009
|
+
if (updateResult.oneofKind !== "updateMemberAccess") {
|
|
1010
|
+
throw new Error(`inline action: expected updateMemberAccess result, got ${String(updateResult.oneofKind)}`);
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
const membersResult = await client.invokeRaw(Method.GET_SPACE_MEMBERS, {
|
|
1014
|
+
oneofKind: "getSpaceMembers",
|
|
1015
|
+
getSpaceMembers: {
|
|
1016
|
+
spaceId,
|
|
1017
|
+
},
|
|
1018
|
+
});
|
|
1019
|
+
if (membersResult.oneofKind !== "getSpaceMembers") {
|
|
1020
|
+
throw new Error(`inline action: expected getSpaceMembers result, got ${String(membersResult.oneofKind)}`);
|
|
1021
|
+
}
|
|
1022
|
+
const usersById = buildUserMap(membersResult.getSpaceMembers.users ?? []);
|
|
1023
|
+
const members = (membersResult.getSpaceMembers.members ?? []).map((member) => {
|
|
1024
|
+
const linkedUser = usersById.get(String(member.userId));
|
|
1025
|
+
return {
|
|
1026
|
+
userId: String(member.userId),
|
|
1027
|
+
role: mapSpaceMemberRole(member.role),
|
|
1028
|
+
canAccessPublicChats: member.canAccessPublicChats,
|
|
1029
|
+
date: Number(member.date) * 1000,
|
|
1030
|
+
user: linkedUser
|
|
1031
|
+
? {
|
|
1032
|
+
id: String(linkedUser.id),
|
|
1033
|
+
name: buildInlineUserDisplayName(linkedUser),
|
|
1034
|
+
username: linkedUser.username ?? null,
|
|
1035
|
+
}
|
|
1036
|
+
: null,
|
|
1037
|
+
};
|
|
1038
|
+
});
|
|
1039
|
+
const filteredMembers = userId != null ? members.filter((member) => member.userId === String(userId)) : members;
|
|
1040
|
+
return jsonResult(toJsonSafe({
|
|
1041
|
+
ok: true,
|
|
1042
|
+
chatId: String(chatId),
|
|
1043
|
+
spaceId: String(spaceId),
|
|
1044
|
+
members: filteredMembers,
|
|
1045
|
+
}));
|
|
1046
|
+
},
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
446
1049
|
throw new Error(`Action ${action} is not supported for provider inline.`);
|
|
447
1050
|
},
|
|
448
1051
|
};
|
|
1052
|
+
export const inlineSupportedActions = listAllActions();
|
|
449
1053
|
//# sourceMappingURL=actions.js.map
|