@zhin.js/adapter-icqq 4.0.0 → 5.0.0
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 +26 -0
- package/README.md +30 -30
- package/client/ICQQManagement.tsx +15 -15
- package/client/LoginAssistPanel.tsx +2 -2
- package/dist/index.js +1 -2
- package/lib/adapter.d.ts +14 -13
- package/lib/adapter.d.ts.map +1 -1
- package/lib/adapter.js +31 -30
- package/lib/adapter.js.map +1 -1
- package/lib/{bot.d.ts → endpoint.d.ts} +9 -9
- package/lib/endpoint.d.ts.map +1 -0
- package/lib/{bot.js → endpoint.js} +30 -41
- package/lib/endpoint.js.map +1 -0
- package/lib/icqq-side-events.d.ts +2 -2
- package/lib/icqq-side-events.d.ts.map +1 -1
- package/lib/icqq-side-events.js +4 -4
- package/lib/icqq-side-events.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/ipc-client.js +2 -2
- package/lib/ipc-client.js.map +1 -1
- package/lib/outbound-media.d.ts +2 -2
- package/lib/outbound-media.d.ts.map +1 -1
- package/lib/outbound-media.js.map +1 -1
- package/lib/routes.js +14 -14
- package/lib/routes.js.map +1 -1
- package/lib/tools/index.d.ts.map +1 -1
- package/lib/tools/index.js +80 -75
- package/lib/tools/index.js.map +1 -1
- package/lib/types.d.ts +2 -2
- package/lib/types.d.ts.map +1 -1
- package/lib/typing-indicator-example.d.ts +10 -10
- package/lib/typing-indicator-example.d.ts.map +1 -1
- package/lib/typing-indicator-example.js +24 -24
- package/lib/typing-indicator-example.js.map +1 -1
- package/lib/typing-indicator.d.ts +10 -10
- package/lib/typing-indicator.d.ts.map +1 -1
- package/lib/typing-indicator.js +37 -37
- package/lib/typing-indicator.js.map +1 -1
- package/package.json +15 -11
- package/skills/icqq/PERMITS.md +22 -0
- package/src/adapter.ts +33 -31
- package/src/{bot.ts → endpoint.ts} +30 -40
- package/src/icqq-side-events.ts +4 -4
- package/src/index.ts +1 -1
- package/src/ipc-client.ts +2 -2
- package/src/outbound-media.ts +2 -2
- package/src/routes.ts +14 -14
- package/src/tools/index.ts +68 -63
- package/src/types.ts +2 -2
- package/src/typing-indicator-example.ts +25 -25
- package/src/typing-indicator.ts +40 -40
- package/lib/bot.d.ts.map +0 -1
- package/lib/bot.js.map +0 -1
package/src/tools/index.ts
CHANGED
|
@@ -29,20 +29,21 @@ export function registerTools(
|
|
|
29
29
|
parameters: {
|
|
30
30
|
type: "object",
|
|
31
31
|
properties: {
|
|
32
|
-
|
|
32
|
+
endpoint_id: { type: "string", description: "Endpoint QQ号", contextKey: 'endpointId' },
|
|
33
33
|
group_id: { type: "number", description: "目标群号" },
|
|
34
34
|
user_id: { type: "number", description: "目标成员 QQ号" },
|
|
35
35
|
title: { type: "string", description: "头衔文字" },
|
|
36
36
|
duration: { type: "number", description: "持续时间(秒),-1永久" },
|
|
37
37
|
},
|
|
38
|
-
required: ["
|
|
38
|
+
required: ["endpoint_id", "group_id", "user_id", "title"],
|
|
39
39
|
},
|
|
40
40
|
platforms: ["icqq"],
|
|
41
41
|
tags: ["icqq"],
|
|
42
|
+
permissions: ["platform(icqq,group_owner)"],
|
|
42
43
|
execute: async (args: Record<string, any>) => {
|
|
43
|
-
const
|
|
44
|
-
if (!
|
|
45
|
-
const resp = await
|
|
44
|
+
const endpoint = icqq.endpoints.get(args.endpoint_id);
|
|
45
|
+
if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
|
|
46
|
+
const resp = await endpoint.ipc.request(Actions.SET_GROUP_TITLE, {
|
|
46
47
|
group_id: args.group_id,
|
|
47
48
|
user_id: args.user_id,
|
|
48
49
|
title: args.title,
|
|
@@ -64,18 +65,19 @@ export function registerTools(
|
|
|
64
65
|
parameters: {
|
|
65
66
|
type: "object",
|
|
66
67
|
properties: {
|
|
67
|
-
|
|
68
|
+
endpoint_id: { type: "string", description: "Endpoint QQ号", contextKey: 'endpointId' },
|
|
68
69
|
group_id: { type: "number", description: "目标群号" },
|
|
69
70
|
content: { type: "string", description: "公告内容" },
|
|
70
71
|
},
|
|
71
|
-
required: ["
|
|
72
|
+
required: ["endpoint_id", "group_id", "content"],
|
|
72
73
|
},
|
|
73
74
|
platforms: ["icqq"],
|
|
74
75
|
tags: ["icqq"],
|
|
76
|
+
permissions: ["platform(icqq,group_admin)"],
|
|
75
77
|
execute: async (args: Record<string, any>) => {
|
|
76
|
-
const
|
|
77
|
-
if (!
|
|
78
|
-
const resp = await
|
|
78
|
+
const endpoint = icqq.endpoints.get(args.endpoint_id);
|
|
79
|
+
if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
|
|
80
|
+
const resp = await endpoint.ipc.request(Actions.GROUP_ANNOUNCE, {
|
|
79
81
|
group_id: args.group_id,
|
|
80
82
|
content: args.content,
|
|
81
83
|
});
|
|
@@ -95,18 +97,18 @@ export function registerTools(
|
|
|
95
97
|
parameters: {
|
|
96
98
|
type: "object",
|
|
97
99
|
properties: {
|
|
98
|
-
|
|
100
|
+
endpoint_id: { type: "string", description: "Endpoint QQ号", contextKey: 'endpointId' },
|
|
99
101
|
group_id: { type: "number", description: "目标群号" },
|
|
100
102
|
user_id: { type: "number", description: "要戳的目标成员 QQ号" },
|
|
101
103
|
},
|
|
102
|
-
required: ["
|
|
104
|
+
required: ["endpoint_id", "group_id", "user_id"],
|
|
103
105
|
},
|
|
104
106
|
platforms: ["icqq"],
|
|
105
107
|
tags: ["icqq"],
|
|
106
108
|
execute: async (args: Record<string, any>) => {
|
|
107
|
-
const
|
|
108
|
-
if (!
|
|
109
|
-
const resp = await
|
|
109
|
+
const endpoint = icqq.endpoints.get(args.endpoint_id);
|
|
110
|
+
if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
|
|
111
|
+
const resp = await endpoint.ipc.request(Actions.GROUP_POKE, {
|
|
110
112
|
group_id: args.group_id,
|
|
111
113
|
user_id: args.user_id,
|
|
112
114
|
});
|
|
@@ -126,17 +128,18 @@ export function registerTools(
|
|
|
126
128
|
parameters: {
|
|
127
129
|
type: "object",
|
|
128
130
|
properties: {
|
|
129
|
-
|
|
131
|
+
endpoint_id: { type: "string", description: "Endpoint QQ号", contextKey: 'endpointId' },
|
|
130
132
|
group_id: { type: "number", description: "目标群号" },
|
|
131
133
|
},
|
|
132
|
-
required: ["
|
|
134
|
+
required: ["endpoint_id", "group_id"],
|
|
133
135
|
},
|
|
134
136
|
platforms: ["icqq"],
|
|
135
137
|
tags: ["icqq"],
|
|
138
|
+
permissions: ["platform(icqq,group_admin)"],
|
|
136
139
|
execute: async (args: Record<string, any>) => {
|
|
137
|
-
const
|
|
138
|
-
if (!
|
|
139
|
-
const resp = await
|
|
140
|
+
const endpoint = icqq.endpoints.get(args.endpoint_id);
|
|
141
|
+
if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
|
|
142
|
+
const resp = await endpoint.ipc.request(Actions.GROUP_MUTED_LIST, {
|
|
140
143
|
group_id: args.group_id,
|
|
141
144
|
});
|
|
142
145
|
if (!resp.ok) throw new Error(resp.error ?? "获取禁言列表失败");
|
|
@@ -157,18 +160,18 @@ export function registerTools(
|
|
|
157
160
|
parameters: {
|
|
158
161
|
type: "object",
|
|
159
162
|
properties: {
|
|
160
|
-
|
|
163
|
+
endpoint_id: { type: "string", description: "Endpoint QQ号", contextKey: 'endpointId' },
|
|
161
164
|
user_id: { type: "number", description: "要点赞的目标用户 QQ号" },
|
|
162
165
|
times: { type: "number", description: "点赞次数(1-20),默认 1" },
|
|
163
166
|
},
|
|
164
|
-
required: ["
|
|
167
|
+
required: ["endpoint_id", "user_id"],
|
|
165
168
|
},
|
|
166
169
|
platforms: ["icqq"],
|
|
167
170
|
tags: ["icqq"],
|
|
168
171
|
execute: async (args: Record<string, any>) => {
|
|
169
|
-
const
|
|
170
|
-
if (!
|
|
171
|
-
const resp = await
|
|
172
|
+
const endpoint = icqq.endpoints.get(args.endpoint_id);
|
|
173
|
+
if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
|
|
174
|
+
const resp = await endpoint.ipc.request(Actions.FRIEND_LIKE, {
|
|
172
175
|
user_id: args.user_id,
|
|
173
176
|
times: Math.min(args.times ?? 1, 20),
|
|
174
177
|
});
|
|
@@ -188,19 +191,20 @@ export function registerTools(
|
|
|
188
191
|
parameters: {
|
|
189
192
|
type: "object",
|
|
190
193
|
properties: {
|
|
191
|
-
|
|
194
|
+
endpoint_id: { type: "string", description: "Endpoint QQ号", contextKey: 'endpointId' },
|
|
192
195
|
group_id: { type: "number", description: "目标群号" },
|
|
193
196
|
enable: { type: "boolean", description: "true=开启,false=关闭,默认 true" },
|
|
194
197
|
},
|
|
195
|
-
required: ["
|
|
198
|
+
required: ["endpoint_id", "group_id"],
|
|
196
199
|
},
|
|
197
200
|
platforms: ["icqq"],
|
|
198
201
|
tags: ["icqq"],
|
|
202
|
+
permissions: ["platform(icqq,group_owner)"],
|
|
199
203
|
execute: async (args: Record<string, any>) => {
|
|
200
|
-
const
|
|
201
|
-
if (!
|
|
204
|
+
const endpoint = icqq.endpoints.get(args.endpoint_id);
|
|
205
|
+
if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
|
|
202
206
|
const enable = args.enable ?? true;
|
|
203
|
-
const resp = await
|
|
207
|
+
const resp = await endpoint.ipc.request(Actions.GROUP_ALLOW_ANONY, {
|
|
204
208
|
group_id: args.group_id,
|
|
205
209
|
enable,
|
|
206
210
|
});
|
|
@@ -220,17 +224,17 @@ export function registerTools(
|
|
|
220
224
|
parameters: {
|
|
221
225
|
type: "object",
|
|
222
226
|
properties: {
|
|
223
|
-
|
|
227
|
+
endpoint_id: { type: "string", description: "Endpoint 名称", contextKey: 'endpointId' },
|
|
224
228
|
group_id: { type: "number", description: "群号" },
|
|
225
229
|
},
|
|
226
|
-
required: ["
|
|
230
|
+
required: ["endpoint_id", "group_id"],
|
|
227
231
|
},
|
|
228
232
|
platforms: ["icqq"],
|
|
229
233
|
tags: ["icqq"],
|
|
230
234
|
execute: async (args: Record<string, any>) => {
|
|
231
|
-
const
|
|
232
|
-
if (!
|
|
233
|
-
const resp = await
|
|
235
|
+
const endpoint = icqq.endpoints.get(args.endpoint_id);
|
|
236
|
+
if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
|
|
237
|
+
const resp = await endpoint.ipc.request(Actions.GFS_LIST, {
|
|
234
238
|
group_id: args.group_id,
|
|
235
239
|
});
|
|
236
240
|
if (!resp.ok) throw new Error(resp.error ?? "获取群文件失败");
|
|
@@ -260,21 +264,21 @@ export function registerTools(
|
|
|
260
264
|
parameters: {
|
|
261
265
|
type: "object",
|
|
262
266
|
properties: {
|
|
263
|
-
|
|
267
|
+
endpoint_id: { type: "string", description: "Endpoint 名称", contextKey: 'endpointId' },
|
|
264
268
|
},
|
|
265
|
-
required: ["
|
|
269
|
+
required: ["endpoint_id"],
|
|
266
270
|
},
|
|
267
271
|
platforms: ["icqq"],
|
|
268
272
|
tags: ["icqq"],
|
|
269
273
|
execute: async (args: Record<string, any>) => {
|
|
270
|
-
const
|
|
271
|
-
if (!
|
|
272
|
-
const friends = Array.from(
|
|
274
|
+
const endpoint = icqq.endpoints.get(args.endpoint_id);
|
|
275
|
+
if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
|
|
276
|
+
const friends = Array.from(endpoint.friends.values()).map((f) => ({
|
|
273
277
|
user_id: f.user_id,
|
|
274
278
|
nickname: f.nickname,
|
|
275
279
|
remark: f.remark,
|
|
276
280
|
}));
|
|
277
|
-
return { friends: friends.slice(0, 50), count:
|
|
281
|
+
return { friends: friends.slice(0, 50), count: endpoint.friends.size };
|
|
278
282
|
},
|
|
279
283
|
},
|
|
280
284
|
pluginName,
|
|
@@ -286,26 +290,26 @@ export function registerTools(
|
|
|
286
290
|
toolService.addTool(
|
|
287
291
|
{
|
|
288
292
|
name: "icqq_group_list",
|
|
289
|
-
description: "获取
|
|
293
|
+
description: "获取 Endpoint 的 QQ 群列表",
|
|
290
294
|
parameters: {
|
|
291
295
|
type: "object",
|
|
292
296
|
properties: {
|
|
293
|
-
|
|
297
|
+
endpoint_id: { type: "string", description: "Endpoint 名称", contextKey: 'endpointId' },
|
|
294
298
|
},
|
|
295
|
-
required: ["
|
|
299
|
+
required: ["endpoint_id"],
|
|
296
300
|
},
|
|
297
301
|
platforms: ["icqq"],
|
|
298
302
|
tags: ["icqq"],
|
|
299
303
|
execute: async (args: Record<string, any>) => {
|
|
300
|
-
const
|
|
301
|
-
if (!
|
|
302
|
-
const groups = Array.from(
|
|
304
|
+
const endpoint = icqq.endpoints.get(args.endpoint_id);
|
|
305
|
+
if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
|
|
306
|
+
const groups = Array.from(endpoint.groups.values()).map((g) => ({
|
|
303
307
|
group_id: g.group_id,
|
|
304
308
|
group_name: g.group_name,
|
|
305
309
|
member_count: g.member_count,
|
|
306
310
|
max_member_count: g.max_member_count,
|
|
307
311
|
}));
|
|
308
|
-
return { groups: groups.slice(0, 50), count:
|
|
312
|
+
return { groups: groups.slice(0, 50), count: endpoint.groups.size };
|
|
309
313
|
},
|
|
310
314
|
},
|
|
311
315
|
pluginName,
|
|
@@ -321,17 +325,17 @@ export function registerTools(
|
|
|
321
325
|
parameters: {
|
|
322
326
|
type: "object",
|
|
323
327
|
properties: {
|
|
324
|
-
|
|
328
|
+
endpoint_id: { type: "string", description: "Endpoint QQ号", contextKey: 'endpointId' },
|
|
325
329
|
group_id: { type: "number", description: "目标群号" },
|
|
326
330
|
},
|
|
327
|
-
required: ["
|
|
331
|
+
required: ["endpoint_id", "group_id"],
|
|
328
332
|
},
|
|
329
333
|
platforms: ["icqq"],
|
|
330
334
|
tags: ["icqq"],
|
|
331
335
|
execute: async (args: Record<string, any>) => {
|
|
332
|
-
const
|
|
333
|
-
if (!
|
|
334
|
-
const resp = await
|
|
336
|
+
const endpoint = icqq.endpoints.get(args.endpoint_id);
|
|
337
|
+
if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
|
|
338
|
+
const resp = await endpoint.ipc.request(Actions.GROUP_SIGN, {
|
|
335
339
|
group_id: args.group_id,
|
|
336
340
|
});
|
|
337
341
|
return { success: resp.ok, message: resp.ok ? "群签到成功" : (resp.error ?? "签到失败") };
|
|
@@ -350,18 +354,18 @@ export function registerTools(
|
|
|
350
354
|
parameters: {
|
|
351
355
|
type: "object",
|
|
352
356
|
properties: {
|
|
353
|
-
|
|
357
|
+
endpoint_id: { type: "string", description: "Endpoint QQ号", contextKey: 'endpointId' },
|
|
354
358
|
group_id: { type: "number", description: "目标群号" },
|
|
355
359
|
user_id: { type: "number", description: "要邀请的 QQ号" },
|
|
356
360
|
},
|
|
357
|
-
required: ["
|
|
361
|
+
required: ["endpoint_id", "group_id", "user_id"],
|
|
358
362
|
},
|
|
359
363
|
platforms: ["icqq"],
|
|
360
364
|
tags: ["icqq"],
|
|
361
365
|
execute: async (args: Record<string, any>) => {
|
|
362
|
-
const
|
|
363
|
-
if (!
|
|
364
|
-
const resp = await
|
|
366
|
+
const endpoint = icqq.endpoints.get(args.endpoint_id);
|
|
367
|
+
if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
|
|
368
|
+
const resp = await endpoint.ipc.request(Actions.GROUP_INVITE, {
|
|
365
369
|
group_id: args.group_id,
|
|
366
370
|
user_id: args.user_id,
|
|
367
371
|
});
|
|
@@ -381,19 +385,20 @@ export function registerTools(
|
|
|
381
385
|
parameters: {
|
|
382
386
|
type: "object",
|
|
383
387
|
properties: {
|
|
384
|
-
|
|
388
|
+
endpoint_id: { type: "string", description: "Endpoint QQ号", contextKey: 'endpointId' },
|
|
385
389
|
message_id: { type: "string", description: "消息 ID" },
|
|
386
390
|
action: { type: "string", description: "add=设为精华, remove=移除精华" },
|
|
387
391
|
},
|
|
388
|
-
required: ["
|
|
392
|
+
required: ["endpoint_id", "message_id", "action"],
|
|
389
393
|
},
|
|
390
394
|
platforms: ["icqq"],
|
|
391
395
|
tags: ["icqq"],
|
|
396
|
+
permissions: ["platform(icqq,group_admin)"],
|
|
392
397
|
execute: async (args: Record<string, any>) => {
|
|
393
|
-
const
|
|
394
|
-
if (!
|
|
398
|
+
const endpoint = icqq.endpoints.get(args.endpoint_id);
|
|
399
|
+
if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
|
|
395
400
|
const action = args.action === "add" ? Actions.GROUP_ESSENCE_ADD : Actions.GROUP_ESSENCE_REMOVE;
|
|
396
|
-
const resp = await
|
|
401
|
+
const resp = await endpoint.ipc.request(action, {
|
|
397
402
|
message_id: args.message_id,
|
|
398
403
|
});
|
|
399
404
|
return { success: resp.ok, message: resp.ok ? (args.action === "add" ? "已设为精华" : "已移除精华") : (resp.error ?? "操作失败") };
|
package/src/types.ts
CHANGED
|
@@ -58,12 +58,12 @@ export interface TypingIndicatorConfig {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
|
-
*
|
|
61
|
+
* Endpoint 配置:支持本地 IPC 和远程 RPC 两种连接模式。
|
|
62
62
|
*
|
|
63
63
|
* - 本地模式(默认):只需 name(QQ号),自动连接 ~/.icqq/<uin>/daemon.sock
|
|
64
64
|
* - 远程模式:额外配置 rpc.host / rpc.port / rpc.token
|
|
65
65
|
*/
|
|
66
|
-
export interface
|
|
66
|
+
export interface IcqqEndpointConfig {
|
|
67
67
|
context: "icqq";
|
|
68
68
|
/** QQ 号码字符串 */
|
|
69
69
|
name: `${number}`;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* 展示如何在 ICQQ 适配器中集成消息处理状态提示
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type {
|
|
7
|
+
import type { IcqqEndpoint } from './endpoint.js';
|
|
8
8
|
import type { IcqqAdapter } from './adapter.js';
|
|
9
9
|
import {
|
|
10
10
|
ICQQTypingIndicatorManager,
|
|
@@ -19,9 +19,9 @@ import {
|
|
|
19
19
|
* 在 ICQQ 适配器初始化时启用 Typing Indicator
|
|
20
20
|
*/
|
|
21
21
|
export function enableTypingIndicatorForAdapter(adapter: IcqqAdapter): void {
|
|
22
|
-
// 遍历所有
|
|
23
|
-
for (const [
|
|
24
|
-
const manager = enableTypingIndicator(
|
|
22
|
+
// 遍历所有 Endpoint 实例
|
|
23
|
+
for (const [endpointId, endpoint] of adapter.endpoints.entries()) {
|
|
24
|
+
const manager = enableTypingIndicator(endpoint, {
|
|
25
25
|
enabled: true,
|
|
26
26
|
defaultEmoji: '⏳',
|
|
27
27
|
autoRemove: true,
|
|
@@ -42,7 +42,7 @@ export function enableTypingIndicatorForAdapter(adapter: IcqqAdapter): void {
|
|
|
42
42
|
},
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
-
console.log(`[ICQQ] Typing indicator enabled for
|
|
45
|
+
console.log(`[ICQQ] Typing indicator enabled for endpoint: ${endpointId}`);
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
|
|
@@ -54,7 +54,7 @@ export function enableTypingIndicatorForAdapter(adapter: IcqqAdapter): void {
|
|
|
54
54
|
* 使用示例:
|
|
55
55
|
* ```typescript
|
|
56
56
|
* // 在消息处理开始时
|
|
57
|
-
* const indicator = await startTypingIndicator(
|
|
57
|
+
* const indicator = await startTypingIndicator(endpoint, {
|
|
58
58
|
* messageId: message.$id,
|
|
59
59
|
* sessionId: `${message.$channel.type}:${message.$channel.id}`,
|
|
60
60
|
* userId: message.$sender.id,
|
|
@@ -73,7 +73,7 @@ export function enableTypingIndicatorForAdapter(adapter: IcqqAdapter): void {
|
|
|
73
73
|
* ```
|
|
74
74
|
*/
|
|
75
75
|
export async function withTypingIndicator<T>(
|
|
76
|
-
|
|
76
|
+
endpoint: IcqqEndpoint,
|
|
77
77
|
options: {
|
|
78
78
|
messageId?: string;
|
|
79
79
|
sessionId: string;
|
|
@@ -84,9 +84,9 @@ export async function withTypingIndicator<T>(
|
|
|
84
84
|
fn: () => Promise<T>,
|
|
85
85
|
): Promise<T> {
|
|
86
86
|
// 获取或创建 Typing Indicator 管理器
|
|
87
|
-
let manager =
|
|
87
|
+
let manager = endpoint.$typingIndicator;
|
|
88
88
|
if (!manager) {
|
|
89
|
-
manager = enableTypingIndicator(
|
|
89
|
+
manager = enableTypingIndicator(endpoint);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
// 开始提示
|
|
@@ -183,13 +183,13 @@ export const customConfigs: Record<string, Partial<ICQQTypingIndicatorConfig>> =
|
|
|
183
183
|
export function setupTypingIndicatorHooks(adapter: IcqqAdapter): void {
|
|
184
184
|
// 监听消息接收事件
|
|
185
185
|
adapter.on('message.receive', async (message) => {
|
|
186
|
-
const
|
|
187
|
-
if (!
|
|
186
|
+
const endpoint = adapter.endpoints.get(message.$endpoint);
|
|
187
|
+
if (!endpoint) return;
|
|
188
188
|
|
|
189
189
|
// 获取或创建 Typing Indicator 管理器
|
|
190
|
-
let manager =
|
|
190
|
+
let manager = endpoint.$typingIndicator;
|
|
191
191
|
if (!manager) {
|
|
192
|
-
manager = enableTypingIndicator(
|
|
192
|
+
manager = enableTypingIndicator(endpoint);
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
// 开始提示
|
|
@@ -209,24 +209,24 @@ export function setupTypingIndicatorHooks(adapter: IcqqAdapter): void {
|
|
|
209
209
|
// ── 示例 6: 批量操作 ──────────────────────────────────────────────────
|
|
210
210
|
|
|
211
211
|
/**
|
|
212
|
-
* 批量管理多个
|
|
212
|
+
* 批量管理多个 Endpoint 的 Typing Indicator
|
|
213
213
|
*/
|
|
214
214
|
export class BatchTypingIndicatorManager {
|
|
215
215
|
private managers: Map<string, ICQQTypingIndicatorManager> = new Map();
|
|
216
216
|
|
|
217
217
|
/**
|
|
218
|
-
* 注册
|
|
218
|
+
* 注册 Endpoint
|
|
219
219
|
*/
|
|
220
|
-
|
|
221
|
-
const manager = enableTypingIndicator(
|
|
222
|
-
this.managers.set(
|
|
220
|
+
registerEndpoint(endpoint: IcqqEndpoint, config?: Partial<ICQQTypingIndicatorConfig>): void {
|
|
221
|
+
const manager = enableTypingIndicator(endpoint, config);
|
|
222
|
+
this.managers.set(endpoint.$id, manager);
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
/**
|
|
226
226
|
* 开始提示
|
|
227
227
|
*/
|
|
228
228
|
async start(
|
|
229
|
-
|
|
229
|
+
endpointId: string,
|
|
230
230
|
options: {
|
|
231
231
|
messageId?: string;
|
|
232
232
|
sessionId: string;
|
|
@@ -235,7 +235,7 @@ export class BatchTypingIndicatorManager {
|
|
|
235
235
|
sceneType: 'private' | 'group';
|
|
236
236
|
},
|
|
237
237
|
): Promise<void> {
|
|
238
|
-
const manager = this.managers.get(
|
|
238
|
+
const manager = this.managers.get(endpointId);
|
|
239
239
|
if (manager) {
|
|
240
240
|
await manager.start(options);
|
|
241
241
|
}
|
|
@@ -244,8 +244,8 @@ export class BatchTypingIndicatorManager {
|
|
|
244
244
|
/**
|
|
245
245
|
* 停止提示
|
|
246
246
|
*/
|
|
247
|
-
async stop(
|
|
248
|
-
const manager = this.managers.get(
|
|
247
|
+
async stop(endpointId: string, options: { sessionId: string }): Promise<void> {
|
|
248
|
+
const manager = this.managers.get(endpointId);
|
|
249
249
|
if (manager) {
|
|
250
250
|
await manager.stop(options);
|
|
251
251
|
}
|
|
@@ -261,9 +261,9 @@ export class BatchTypingIndicatorManager {
|
|
|
261
261
|
}
|
|
262
262
|
|
|
263
263
|
/**
|
|
264
|
-
* 获取
|
|
264
|
+
* 获取 Endpoint 的管理器
|
|
265
265
|
*/
|
|
266
|
-
getManager(
|
|
267
|
-
return this.managers.get(
|
|
266
|
+
getManager(endpointId: string): ICQQTypingIndicatorManager | undefined {
|
|
267
|
+
return this.managers.get(endpointId);
|
|
268
268
|
}
|
|
269
269
|
}
|