@zhin.js/adapter-qq 8.0.0 → 8.0.1
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 +23 -0
- package/README.md +10 -1
- package/adapters/qq.js +0 -7
- package/adapters/qq.ts +0 -7
- package/agent/tools/add_role.ts +5 -7
- package/agent/tools/channel_info.ts +5 -7
- package/agent/tools/create_role.ts +5 -7
- package/agent/tools/list_channels.ts +5 -7
- package/agent/tools/list_guilds.ts +6 -9
- package/agent/tools/list_roles.ts +5 -7
- package/agent/tools/member_detail.ts +5 -7
- package/agent/tools/remove_role.ts +5 -7
- package/lib/client.d.ts +12 -0
- package/lib/client.js +2 -0
- package/lib/endpoint.d.ts +8 -26
- package/lib/endpoint.js +43 -68
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/qq-endpoint-commands.d.ts +1 -1
- package/lib/side-event-dispatch.d.ts +2 -2
- package/lib/side-event-dispatch.js +3 -3
- package/package.json +16 -15
- package/src/client.ts +16 -0
- package/src/endpoint.ts +50 -97
- package/src/index.ts +1 -7
- package/src/side-event-dispatch.ts +4 -4
- package/lib/qq-agent-deps.d.ts +0 -21
- package/lib/qq-agent-deps.js +0 -30
- package/src/qq-agent-deps.ts +0 -60
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @zhin.js/adapter-qq
|
|
2
2
|
|
|
3
|
+
## 8.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1fc78bc: Unify native platform Client access behind the literal `adapter` discriminant. Handlers infer both native events and Clients, while command, inbound/outbound middleware, and both Agent tool authoring surfaces expose the exact operation-scoped Client through a lazy `$client` getter. Definitions without `adapter` keep `$client` typed as `unknown`, and runtime dispatch rejects adapter mismatches before resolving the Client. Bundled platform tools now use this single path instead of model-provided endpoint ids and adapter-specific dependency wrappers. Every adapter registers one Client/EventMap contract, and protocol adapters including NapCat, Milky, OneBot and Satori now produce transport-independent Client objects rather than letting Endpoint instances impersonate Clients.
|
|
8
|
+
- Updated dependencies [e9c6a73]
|
|
9
|
+
- Updated dependencies [4e8117c]
|
|
10
|
+
- Updated dependencies [902fa35]
|
|
11
|
+
- Updated dependencies [54bfd6b]
|
|
12
|
+
- Updated dependencies [12025ee]
|
|
13
|
+
- Updated dependencies [09b14d6]
|
|
14
|
+
- Updated dependencies [1fc78bc]
|
|
15
|
+
- @zhin.js/agent@1.1.16
|
|
16
|
+
- @zhin.js/adapter@1.2.1
|
|
17
|
+
- @zhin.js/core@1.5.14
|
|
18
|
+
- @zhin.js/host-http@1.0.13
|
|
19
|
+
- @zhin.js/command@1.0.16
|
|
20
|
+
- @zhin.js/logger@1.0.77
|
|
21
|
+
- @zhin.js/middleware@1.0.13
|
|
22
|
+
- zhin.js@6.0.14
|
|
23
|
+
- @zhin.js/feature-kit@1.0.13
|
|
24
|
+
- @zhin.js/permission@1.0.4
|
|
25
|
+
|
|
3
26
|
## 8.0.0
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ pnpm add @zhin.js/adapter-qq
|
|
|
20
20
|
## Plugin Runtime
|
|
21
21
|
|
|
22
22
|
- `@zhin.js/adapter` — 约定式 `adapters/qq.ts`(`defineAdapter`)
|
|
23
|
-
- `@zhin.js/core` — `
|
|
23
|
+
- `@zhin.js/core` — `Endpoint.emit(...)` 入站、`outboundMessageToken` 出站
|
|
24
24
|
- `zhin.js` — `plugin.ts`(`definePlugin`)
|
|
25
25
|
- 配置经插件 `schema.json` 落到 `plugins.<instanceKey>`
|
|
26
26
|
- **无需** `@zhin.js/host-http` / `@zhin.js/host-router`(WebSocket 路径)
|
|
@@ -144,6 +144,15 @@ Markdown + 指令按钮组。按钮值与手动输入共用同一解析入口,
|
|
|
144
144
|
不支持原生按钮的 Adapter 会在 Core 中把同一 keyboard 语义降级为编号列表,并保存数字到
|
|
145
145
|
payload 的回跳映射。图片、音频、视频和文件仍沿 canonical `MediaRef` 出站链投递。
|
|
146
146
|
|
|
147
|
+
## 故障排查
|
|
148
|
+
|
|
149
|
+
| 现象 | 排查 |
|
|
150
|
+
| --- | --- |
|
|
151
|
+
| Gateway Identify 后断线 | 检查 `botKind` 与 intents;公域机器人不要订阅受限 intent |
|
|
152
|
+
| 二维码绑定后仍离线 | 在 Console 登录待办确认结果,并检查 App ID、Secret 与 Token |
|
|
153
|
+
| Webhook 无事件 | 检查 HTTP Host、公网路径、平台回调与签名参数 |
|
|
154
|
+
| Markdown/按钮发送失败 | 检查平台模板与权限,并按 Endpoint 能力降级 |
|
|
155
|
+
|
|
147
156
|
## 许可证
|
|
148
157
|
|
|
149
158
|
MIT License
|
package/adapters/qq.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
* Convention entry: discover `adapters/qq.ts` → defineAdapter.
|
|
4
4
|
*/
|
|
5
5
|
import { defineAdapter } from 'zhin.js/adapter';
|
|
6
|
-
import { messageGatewayToken, sideEventGatewayToken } from '@zhin.js/core/runtime';
|
|
7
6
|
import { httpHostToken } from '@zhin.js/host-http';
|
|
8
7
|
import { QqHttpEndpoint, QqWebsocketEndpoint } from "../lib/endpoint.js";
|
|
9
8
|
import { resolveQqConfig, } from "../lib/protocol.js";
|
|
@@ -22,8 +21,6 @@ export default defineAdapter({
|
|
|
22
21
|
},
|
|
23
22
|
create(context) {
|
|
24
23
|
const config = resolveQqConfig(context.config);
|
|
25
|
-
const gateway = context.use(messageGatewayToken);
|
|
26
|
-
const sideEvents = context.use(sideEventGatewayToken);
|
|
27
24
|
// 注册到插件运行时状态(qq.endpoint list 的"运行中"数据源)
|
|
28
25
|
const state = context.use(qqRuntimeStateToken);
|
|
29
26
|
state.endpoints.set(config.id, {
|
|
@@ -35,14 +32,10 @@ export default defineAdapter({
|
|
|
35
32
|
const endpoint = config.mode === 'websocket'
|
|
36
33
|
? new QqWebsocketEndpoint({
|
|
37
34
|
id: context.id,
|
|
38
|
-
gateway,
|
|
39
|
-
sideEvents,
|
|
40
35
|
config,
|
|
41
36
|
})
|
|
42
37
|
: new QqHttpEndpoint({
|
|
43
38
|
id: context.id,
|
|
44
|
-
gateway,
|
|
45
|
-
sideEvents,
|
|
46
39
|
http: context.use(httpHostToken),
|
|
47
40
|
config,
|
|
48
41
|
});
|
package/adapters/qq.ts
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* Convention entry: discover `adapters/qq.ts` → defineAdapter.
|
|
3
3
|
*/
|
|
4
4
|
import { defineAdapter } from 'zhin.js/adapter';
|
|
5
|
-
import { messageGatewayToken, sideEventGatewayToken } from '@zhin.js/core/runtime';
|
|
6
5
|
import { httpHostToken } from '@zhin.js/host-http';
|
|
7
6
|
import { QqHttpEndpoint, QqWebsocketEndpoint } from '../src/endpoint.js';
|
|
8
7
|
import {
|
|
@@ -43,8 +42,6 @@ export default defineAdapter<QqAdapterConfig>({
|
|
|
43
42
|
},
|
|
44
43
|
create(context) {
|
|
45
44
|
const config = resolveQqConfig(context.config);
|
|
46
|
-
const gateway = context.use(messageGatewayToken);
|
|
47
|
-
const sideEvents = context.use(sideEventGatewayToken);
|
|
48
45
|
// 注册到插件运行时状态(qq.endpoint list 的"运行中"数据源)
|
|
49
46
|
const state = context.use(qqRuntimeStateToken);
|
|
50
47
|
state.endpoints.set(config.id, {
|
|
@@ -56,14 +53,10 @@ export default defineAdapter<QqAdapterConfig>({
|
|
|
56
53
|
const endpoint = config.mode === 'websocket'
|
|
57
54
|
? new QqWebsocketEndpoint({
|
|
58
55
|
id: context.id,
|
|
59
|
-
gateway,
|
|
60
|
-
sideEvents,
|
|
61
56
|
config,
|
|
62
57
|
})
|
|
63
58
|
: new QqHttpEndpoint({
|
|
64
59
|
id: context.id,
|
|
65
|
-
gateway,
|
|
66
|
-
sideEvents,
|
|
67
60
|
http: context.use(httpHostToken),
|
|
68
61
|
config,
|
|
69
62
|
});
|
package/agent/tools/add_role.ts
CHANGED
|
@@ -1,23 +1,21 @@
|
|
|
1
1
|
import { defineAgentTool } from '@zhin.js/agent/tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { platformPermit } from '../../src/platform-permit.js';
|
|
4
|
-
import { getQqAgentDeps } from '../../src/qq-agent-deps.js';
|
|
5
4
|
|
|
6
|
-
export default defineAgentTool<{
|
|
5
|
+
export default defineAgentTool<{ guild_id: string; channel_id: string; user_id: string; role_id: string }>({
|
|
7
6
|
description: '给成员添加 QQ 频道角色',
|
|
8
7
|
inputSchema: z.object({
|
|
9
|
-
endpoint_id: z.string().describe('Endpoint 名称'),
|
|
10
8
|
guild_id: z.string().describe('频道 ID'),
|
|
11
9
|
channel_id: z.string().describe('子频道 ID'),
|
|
12
10
|
user_id: z.string().describe('用户 ID'),
|
|
13
11
|
role_id: z.string().describe('角色 ID'),
|
|
14
12
|
}),
|
|
15
|
-
|
|
13
|
+
adapter: 'qq',
|
|
16
14
|
tags: ['qq'],
|
|
17
15
|
permissions: [platformPermit('manage_roles')],
|
|
18
|
-
async execute({
|
|
19
|
-
const
|
|
20
|
-
const success = await
|
|
16
|
+
async execute({ guild_id, channel_id, user_id, role_id }: { guild_id: string; channel_id: string; user_id: string; role_id: string }, context) {
|
|
17
|
+
const client = context.$client;
|
|
18
|
+
const success = await client.addMemberRole(guild_id, channel_id, user_id, role_id);
|
|
21
19
|
return { success, message: success ? '已给成员添加角色' : '操作失败' };
|
|
22
20
|
},
|
|
23
21
|
});
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import { defineAgentTool } from '@zhin.js/agent/tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { platformPermit } from '../../src/platform-permit.js';
|
|
4
|
-
import { getQqAgentDeps } from '../../src/qq-agent-deps.js';
|
|
5
4
|
|
|
6
|
-
export default defineAgentTool<{
|
|
5
|
+
export default defineAgentTool<{ channel_id: string }>({
|
|
7
6
|
description: '获取 QQ 频道中指定子频道的详细信息',
|
|
8
7
|
inputSchema: z.object({
|
|
9
|
-
endpoint_id: z.string().describe('Endpoint 名称'),
|
|
10
8
|
channel_id: z.string().describe('子频道 ID'),
|
|
11
9
|
}),
|
|
12
|
-
|
|
10
|
+
adapter: 'qq',
|
|
13
11
|
tags: ['qq'],
|
|
14
12
|
permissions: [platformPermit('guild_admin')],
|
|
15
|
-
async execute({
|
|
16
|
-
const
|
|
17
|
-
return
|
|
13
|
+
async execute({ channel_id }: { channel_id: string }, context) {
|
|
14
|
+
const client = context.$client;
|
|
15
|
+
return client.getChannelInfo(channel_id);
|
|
18
16
|
},
|
|
19
17
|
});
|
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
import { defineAgentTool } from '@zhin.js/agent/tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { platformPermit } from '../../src/platform-permit.js';
|
|
4
|
-
import { getQqAgentDeps } from '../../src/qq-agent-deps.js';
|
|
5
4
|
|
|
6
|
-
export default defineAgentTool<{
|
|
5
|
+
export default defineAgentTool<{ guild_id: string; name: string; color?: number }>({
|
|
7
6
|
description: '创建 QQ 频道角色',
|
|
8
7
|
inputSchema: z.object({
|
|
9
|
-
endpoint_id: z.string().describe('Endpoint 名称'),
|
|
10
8
|
guild_id: z.string().describe('频道 ID'),
|
|
11
9
|
name: z.string().describe('角色名称'),
|
|
12
10
|
color: z.number().optional().describe('颜色(RGB 十进制数值)'),
|
|
13
11
|
}),
|
|
14
|
-
|
|
12
|
+
adapter: 'qq',
|
|
15
13
|
tags: ['qq'],
|
|
16
14
|
permissions: [platformPermit('guild_owner')],
|
|
17
|
-
async execute({
|
|
18
|
-
const
|
|
19
|
-
const role = await
|
|
15
|
+
async execute({ guild_id, name, color }: { guild_id: string; name: string; color?: number }, context) {
|
|
16
|
+
const client = context.$client;
|
|
17
|
+
const role = await client.createGuildRole(guild_id, name, color);
|
|
20
18
|
return { success: !!role, role, message: role ? `角色 "${name}" 创建成功` : '创建失败' };
|
|
21
19
|
},
|
|
22
20
|
});
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import { defineAgentTool } from '@zhin.js/agent/tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { platformPermit } from '../../src/platform-permit.js';
|
|
4
|
-
import { getQqAgentDeps } from '../../src/qq-agent-deps.js';
|
|
5
4
|
|
|
6
|
-
export default defineAgentTool<{
|
|
5
|
+
export default defineAgentTool<{ guild_id: string }>({
|
|
7
6
|
description: '获取 QQ 频道下的子频道列表',
|
|
8
7
|
inputSchema: z.object({
|
|
9
|
-
endpoint_id: z.string().describe('Endpoint 名称'),
|
|
10
8
|
guild_id: z.string().describe('频道 ID'),
|
|
11
9
|
}),
|
|
12
|
-
|
|
10
|
+
adapter: 'qq',
|
|
13
11
|
tags: ['qq'],
|
|
14
12
|
permissions: [platformPermit('manage_channels')],
|
|
15
|
-
async execute({
|
|
16
|
-
const
|
|
17
|
-
const channels = await
|
|
13
|
+
async execute({ guild_id }: { guild_id: string }, context) {
|
|
14
|
+
const client = context.$client;
|
|
15
|
+
const channels = await client.getChannels(guild_id);
|
|
18
16
|
return { channels, count: channels.length };
|
|
19
17
|
},
|
|
20
18
|
});
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
import { defineAgentTool } from '@zhin.js/agent/tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { getQqAgentDeps } from '../../src/qq-agent-deps.js';
|
|
4
3
|
|
|
5
|
-
export default defineAgentTool<
|
|
4
|
+
export default defineAgentTool<Record<string, never>>({
|
|
6
5
|
description: '获取 QQ 频道列表',
|
|
7
|
-
inputSchema: z.object({
|
|
8
|
-
|
|
9
|
-
}),
|
|
10
|
-
platforms: ['qq'],
|
|
6
|
+
inputSchema: z.object({}),
|
|
7
|
+
adapter: 'qq',
|
|
11
8
|
tags: ['qq'],
|
|
12
|
-
async execute(
|
|
13
|
-
const
|
|
14
|
-
const guilds = await
|
|
9
|
+
async execute(_input, context) {
|
|
10
|
+
const client = context.$client;
|
|
11
|
+
const guilds = await client.getGuilds();
|
|
15
12
|
return { guilds, count: guilds.length };
|
|
16
13
|
},
|
|
17
14
|
});
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import { defineAgentTool } from '@zhin.js/agent/tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { platformPermit } from '../../src/platform-permit.js';
|
|
4
|
-
import { getQqAgentDeps } from '../../src/qq-agent-deps.js';
|
|
5
4
|
|
|
6
|
-
export default defineAgentTool<{
|
|
5
|
+
export default defineAgentTool<{ guild_id: string }>({
|
|
7
6
|
description: '获取 QQ 频道角色列表',
|
|
8
7
|
inputSchema: z.object({
|
|
9
|
-
endpoint_id: z.string().describe('Endpoint 名称'),
|
|
10
8
|
guild_id: z.string().describe('频道 ID'),
|
|
11
9
|
}),
|
|
12
|
-
|
|
10
|
+
adapter: 'qq',
|
|
13
11
|
tags: ['qq'],
|
|
14
12
|
permissions: [platformPermit('manage_roles')],
|
|
15
|
-
async execute({
|
|
16
|
-
const
|
|
17
|
-
const roles = await
|
|
13
|
+
async execute({ guild_id }: { guild_id: string }, context) {
|
|
14
|
+
const client = context.$client;
|
|
15
|
+
const roles = await client.getGuildRoles(guild_id);
|
|
18
16
|
return { roles, count: roles.length };
|
|
19
17
|
},
|
|
20
18
|
});
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import { defineAgentTool } from '@zhin.js/agent/tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { platformPermit } from '../../src/platform-permit.js';
|
|
4
|
-
import { getQqAgentDeps } from '../../src/qq-agent-deps.js';
|
|
5
4
|
|
|
6
|
-
export default defineAgentTool<{
|
|
5
|
+
export default defineAgentTool<{ guild_id: string; user_id: string }>({
|
|
7
6
|
description: '获取 QQ 频道中指定成员的详细信息',
|
|
8
7
|
inputSchema: z.object({
|
|
9
|
-
endpoint_id: z.string().describe('Endpoint 名称'),
|
|
10
8
|
guild_id: z.string().describe('频道 ID'),
|
|
11
9
|
user_id: z.string().describe('用户 ID'),
|
|
12
10
|
}),
|
|
13
|
-
|
|
11
|
+
adapter: 'qq',
|
|
14
12
|
tags: ['qq'],
|
|
15
13
|
permissions: [platformPermit('guild_admin')],
|
|
16
|
-
async execute({
|
|
17
|
-
const
|
|
18
|
-
return
|
|
14
|
+
async execute({ guild_id, user_id }: { guild_id: string; user_id: string }, context) {
|
|
15
|
+
const client = context.$client;
|
|
16
|
+
return client.getGuildMember(guild_id, user_id);
|
|
19
17
|
},
|
|
20
18
|
});
|
|
@@ -1,23 +1,21 @@
|
|
|
1
1
|
import { defineAgentTool } from '@zhin.js/agent/tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { platformPermit } from '../../src/platform-permit.js';
|
|
4
|
-
import { getQqAgentDeps } from '../../src/qq-agent-deps.js';
|
|
5
4
|
|
|
6
|
-
export default defineAgentTool<{
|
|
5
|
+
export default defineAgentTool<{ guild_id: string; channel_id: string; user_id: string; role_id: string }>({
|
|
7
6
|
description: '移除成员的 QQ 频道角色',
|
|
8
7
|
inputSchema: z.object({
|
|
9
|
-
endpoint_id: z.string().describe('Endpoint 名称'),
|
|
10
8
|
guild_id: z.string().describe('频道 ID'),
|
|
11
9
|
channel_id: z.string().describe('子频道 ID'),
|
|
12
10
|
user_id: z.string().describe('用户 ID'),
|
|
13
11
|
role_id: z.string().describe('角色 ID'),
|
|
14
12
|
}),
|
|
15
|
-
|
|
13
|
+
adapter: 'qq',
|
|
16
14
|
tags: ['qq'],
|
|
17
15
|
permissions: [platformPermit('manage_roles')],
|
|
18
|
-
async execute({
|
|
19
|
-
const
|
|
20
|
-
const success = await
|
|
16
|
+
async execute({ guild_id, channel_id, user_id, role_id }: { guild_id: string; channel_id: string; user_id: string; role_id: string }, context) {
|
|
17
|
+
const client = context.$client;
|
|
18
|
+
const success = await client.removeMemberRole(guild_id, channel_id, user_id, role_id);
|
|
21
19
|
return { success, message: success ? '已移除成员的角色' : '操作失败' };
|
|
22
20
|
},
|
|
23
21
|
});
|
package/lib/client.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { QqInboundMessage } from './protocol.js';
|
|
2
|
+
import type { QqBotTransport } from './ws.js';
|
|
3
|
+
export type QqClientEventMap = Record<string, QqInboundMessage | unknown>;
|
|
4
|
+
declare module '@zhin.js/feature-kit' {
|
|
5
|
+
interface AdapterClientRegistry {
|
|
6
|
+
readonly qq: {
|
|
7
|
+
readonly client: QqBotTransport;
|
|
8
|
+
readonly events: QqClientEventMap;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export declare const qqClient: import("@zhin.js/adapter").EndpointClientToken<QqBotTransport, QqClientEventMap>;
|
package/lib/client.js
ADDED
package/lib/endpoint.d.ts
CHANGED
|
@@ -1,27 +1,26 @@
|
|
|
1
|
+
import { Endpoint } from 'zhin.js/adapter';
|
|
1
2
|
/**
|
|
2
3
|
* QQ endpoints — lifecycle, outbound, admit, agent tool surface.
|
|
3
4
|
*/
|
|
4
|
-
import { type EndpointControl, type
|
|
5
|
-
import type { MessageGateway, SideEventGateway } from '@zhin.js/core/runtime';
|
|
5
|
+
import { type EndpointControl, type EndpointManagement, type EndpointSendRequest } from 'zhin.js/adapter';
|
|
6
6
|
import type { HttpHost } from '@zhin.js/host-http';
|
|
7
7
|
import type { CapabilityId } from 'zhin.js';
|
|
8
8
|
import { type QqInboundMessage, type ResolvedQqHttpConfig, type ResolvedQqWebsocketConfig } from './protocol.js';
|
|
9
|
-
import { type CreateQqHttpBot } from './webhook.js';
|
|
10
|
-
import { type CreateQqBot } from './ws.js';
|
|
9
|
+
import { type CreateQqHttpBot, type QqHttpBotTransport } from './webhook.js';
|
|
10
|
+
import { type CreateQqBot, type QqBotTransport } from './ws.js';
|
|
11
11
|
export type { CreateQqBot, QqBotTransport } from './ws.js';
|
|
12
12
|
export type { CreateQqHttpBot, QqHttpBotTransport } from './webhook.js';
|
|
13
13
|
export interface QqEndpointOptions {
|
|
14
14
|
readonly id: CapabilityId;
|
|
15
|
-
readonly gateway: MessageGateway;
|
|
16
|
-
readonly sideEvents?: SideEventGateway;
|
|
17
15
|
readonly config: ResolvedQqWebsocketConfig;
|
|
18
16
|
readonly createBot?: CreateQqBot;
|
|
19
17
|
}
|
|
20
|
-
export declare class QqWebsocketEndpoint
|
|
18
|
+
export declare class QqWebsocketEndpoint extends Endpoint<QqBotTransport> {
|
|
21
19
|
#private;
|
|
22
20
|
readonly management: EndpointManagement;
|
|
23
21
|
readonly control: EndpointControl;
|
|
24
22
|
constructor(options: QqEndpointOptions);
|
|
23
|
+
get client(): QqBotTransport;
|
|
25
24
|
/** Live endpoint 名(Console/AdapterIndex 展示用,如 bot appid 别名)。 */
|
|
26
25
|
get name(): string;
|
|
27
26
|
start(): Promise<void>;
|
|
@@ -32,29 +31,20 @@ export declare class QqWebsocketEndpoint implements EndpointInstance {
|
|
|
32
31
|
recallMessage(messageId: string): Promise<void>;
|
|
33
32
|
/** Test / internal: admit a message when open. */
|
|
34
33
|
admit(msg: QqInboundMessage): void;
|
|
35
|
-
getGuilds(): Promise<unknown[]>;
|
|
36
|
-
getChannels(guildId: string): Promise<unknown[]>;
|
|
37
|
-
getChannelInfo(channelId: string): Promise<unknown>;
|
|
38
|
-
getGuildMember(guildId: string, userId: string): Promise<unknown>;
|
|
39
|
-
getGuildRoles(guildId: string): Promise<unknown[]>;
|
|
40
|
-
createGuildRole(guildId: string, name: string, color?: number): Promise<unknown>;
|
|
41
|
-
addMemberRole(guildId: string, channelId: string, userId: string, roleId: string): Promise<boolean>;
|
|
42
|
-
removeMemberRole(guildId: string, channelId: string, userId: string, roleId: string): Promise<boolean>;
|
|
43
34
|
}
|
|
44
35
|
export interface QqHttpEndpointOptions {
|
|
45
36
|
readonly id: CapabilityId;
|
|
46
|
-
readonly gateway: MessageGateway;
|
|
47
|
-
readonly sideEvents?: SideEventGateway;
|
|
48
37
|
readonly http: HttpHost;
|
|
49
38
|
readonly config: ResolvedQqHttpConfig;
|
|
50
39
|
readonly createBot?: CreateQqHttpBot;
|
|
51
40
|
}
|
|
52
41
|
/** Webhook / middleware inbound via httpHostToken POST (qq-official-bot Middleware receiver). */
|
|
53
|
-
export declare class QqHttpEndpoint
|
|
42
|
+
export declare class QqHttpEndpoint extends Endpoint<QqHttpBotTransport> {
|
|
54
43
|
#private;
|
|
55
44
|
readonly management: EndpointManagement;
|
|
56
45
|
readonly control: EndpointControl;
|
|
57
46
|
constructor(options: QqHttpEndpointOptions);
|
|
47
|
+
get client(): QqHttpBotTransport;
|
|
58
48
|
/** Live endpoint 名(Console/AdapterIndex 展示用)。 */
|
|
59
49
|
get name(): string;
|
|
60
50
|
start(): Promise<void>;
|
|
@@ -64,12 +54,4 @@ export declare class QqHttpEndpoint implements EndpointInstance {
|
|
|
64
54
|
send({ conversation, payload }: EndpointSendRequest): Promise<string>;
|
|
65
55
|
recallMessage(messageId: string): Promise<void>;
|
|
66
56
|
admit(msg: QqInboundMessage): void;
|
|
67
|
-
getGuilds(): Promise<unknown[]>;
|
|
68
|
-
getChannels(guildId: string): Promise<unknown[]>;
|
|
69
|
-
getChannelInfo(channelId: string): Promise<unknown>;
|
|
70
|
-
getGuildMember(guildId: string, userId: string): Promise<unknown>;
|
|
71
|
-
getGuildRoles(guildId: string): Promise<unknown[]>;
|
|
72
|
-
createGuildRole(guildId: string, name: string, color?: number): Promise<unknown>;
|
|
73
|
-
addMemberRole(guildId: string, channelId: string, userId: string, roleId: string): Promise<boolean>;
|
|
74
|
-
removeMemberRole(guildId: string, channelId: string, userId: string, roleId: string): Promise<boolean>;
|
|
75
57
|
}
|
package/lib/endpoint.js
CHANGED
|
@@ -1,29 +1,32 @@
|
|
|
1
|
+
import { Endpoint } from 'zhin.js/adapter';
|
|
1
2
|
/**
|
|
2
3
|
* QQ endpoints — lifecycle, outbound, admit, agent tool surface.
|
|
3
4
|
*/
|
|
4
5
|
import { createRecallEndpointControl, } from 'zhin.js/adapter';
|
|
5
6
|
import { formatCompact, getAdapterLogger, truncatePreview } from '@zhin.js/logger';
|
|
6
7
|
import { formatOutbound } from './outbound.js';
|
|
7
|
-
import { registerQqAgentEndpoint } from './qq-agent-deps.js';
|
|
8
8
|
import { formatInboundContent, parseCompoundMessageId, qqInboundConversation, qqOutboundKind, resolveOutboundMessageId, senderDisplayName, } from './protocol.js';
|
|
9
9
|
import { defaultCreateHttpBot, registerQqWebhookRoutes, } from './webhook.js';
|
|
10
10
|
import { bindQqBotInboundEvents, defaultCreateBot, normalizeQqMessage, } from './ws.js';
|
|
11
11
|
import { bindQqBotSideEvents, receiveQqSideEvent, } from './side-event-dispatch.js';
|
|
12
|
-
export class QqWebsocketEndpoint {
|
|
12
|
+
export class QqWebsocketEndpoint extends Endpoint {
|
|
13
13
|
#logger;
|
|
14
14
|
#options;
|
|
15
15
|
#createBot;
|
|
16
16
|
#bot = null;
|
|
17
17
|
#open = false;
|
|
18
18
|
#started = false;
|
|
19
|
-
|
|
20
|
-
management = createQqEndpointManagement(this);
|
|
19
|
+
management = createQqEndpointManagement(() => this.#requireBot());
|
|
21
20
|
control = createRecallEndpointControl((id) => this.recallMessage(id));
|
|
22
21
|
constructor(options) {
|
|
22
|
+
super();
|
|
23
23
|
this.#logger = getAdapterLogger('qq', options.config.id);
|
|
24
24
|
this.#options = options;
|
|
25
25
|
this.#createBot = options.createBot ?? defaultCreateBot;
|
|
26
26
|
}
|
|
27
|
+
get client() {
|
|
28
|
+
return this.#requireBot();
|
|
29
|
+
}
|
|
27
30
|
/** Live endpoint 名(Console/AdapterIndex 展示用,如 bot appid 别名)。 */
|
|
28
31
|
get name() {
|
|
29
32
|
return this.#options.config.id;
|
|
@@ -33,7 +36,6 @@ export class QqWebsocketEndpoint {
|
|
|
33
36
|
return;
|
|
34
37
|
this.#started = true;
|
|
35
38
|
try {
|
|
36
|
-
this.#unregisterAgent = registerQqAgentEndpoint(this.#options.config.id, this);
|
|
37
39
|
this.#bot = this.#createBot(this.#options.config);
|
|
38
40
|
this.#bindBot(this.#bot);
|
|
39
41
|
await this.#bot.start();
|
|
@@ -54,8 +56,6 @@ export class QqWebsocketEndpoint {
|
|
|
54
56
|
}
|
|
55
57
|
async stop() {
|
|
56
58
|
this.#open = false;
|
|
57
|
-
this.#unregisterAgent?.();
|
|
58
|
-
this.#unregisterAgent = undefined;
|
|
59
59
|
if (this.#bot) {
|
|
60
60
|
try {
|
|
61
61
|
this.#bot.removeAllListeners();
|
|
@@ -130,7 +130,7 @@ export class QqWebsocketEndpoint {
|
|
|
130
130
|
+ (msg.authorId ? ` from ${msg.authorId}` : '')
|
|
131
131
|
+ (msg.mentioned ? ' (mentioned)' : '')
|
|
132
132
|
+ ` | ${truncatePreview(content, 80)}`);
|
|
133
|
-
void this
|
|
133
|
+
void this.emit('message.receive', {
|
|
134
134
|
conversation,
|
|
135
135
|
message: { conversation, id: msg.id },
|
|
136
136
|
content,
|
|
@@ -156,38 +156,25 @@ export class QqWebsocketEndpoint {
|
|
|
156
156
|
}));
|
|
157
157
|
});
|
|
158
158
|
}
|
|
159
|
-
getGuilds() {
|
|
160
|
-
return this.#requireBot().getGuilds();
|
|
161
|
-
}
|
|
162
|
-
getChannels(guildId) {
|
|
163
|
-
return this.#requireBot().getChannels(guildId);
|
|
164
|
-
}
|
|
165
|
-
getChannelInfo(channelId) {
|
|
166
|
-
return this.#requireBot().getChannelInfo(channelId);
|
|
167
|
-
}
|
|
168
|
-
getGuildMember(guildId, userId) {
|
|
169
|
-
return this.#requireBot().getGuildMember(guildId, userId);
|
|
170
|
-
}
|
|
171
|
-
getGuildRoles(guildId) {
|
|
172
|
-
return this.#requireBot().getGuildRoles(guildId);
|
|
173
|
-
}
|
|
174
|
-
createGuildRole(guildId, name, color) {
|
|
175
|
-
return this.#requireBot().createGuildRole(guildId, name, color);
|
|
176
|
-
}
|
|
177
|
-
addMemberRole(guildId, channelId, userId, roleId) {
|
|
178
|
-
return this.#requireBot().addMemberRole(guildId, channelId, userId, roleId);
|
|
179
|
-
}
|
|
180
|
-
removeMemberRole(guildId, channelId, userId, roleId) {
|
|
181
|
-
return this.#requireBot().removeMemberRole(guildId, channelId, userId, roleId);
|
|
182
|
-
}
|
|
183
159
|
#bindBot(bot) {
|
|
184
160
|
bindQqBotInboundEvents(bot, (raw) => {
|
|
161
|
+
this.#emitPlatformEvent('message', raw);
|
|
185
162
|
const msg = normalizeQqMessage(raw);
|
|
186
163
|
if (msg)
|
|
187
164
|
this.admit(msg);
|
|
188
165
|
});
|
|
189
166
|
bindQqBotSideEvents(bot, (eventName, raw) => {
|
|
190
|
-
|
|
167
|
+
this.#emitPlatformEvent(eventName, raw);
|
|
168
|
+
receiveQqSideEvent((name, payload) => this.emit(name, payload), this.#options.config.id, bot, eventName, raw, this.#logger);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
#emitPlatformEvent(name, event) {
|
|
172
|
+
void this.emitPlatform(name, event).catch((error) => {
|
|
173
|
+
this.#logger.warn(formatCompact({
|
|
174
|
+
op: 'qq_platform_event_failed',
|
|
175
|
+
event: name,
|
|
176
|
+
error: error instanceof Error ? error.message : String(error),
|
|
177
|
+
}));
|
|
191
178
|
});
|
|
192
179
|
}
|
|
193
180
|
#requireBot() {
|
|
@@ -197,7 +184,7 @@ export class QqWebsocketEndpoint {
|
|
|
197
184
|
}
|
|
198
185
|
}
|
|
199
186
|
/** Webhook / middleware inbound via httpHostToken POST (qq-official-bot Middleware receiver). */
|
|
200
|
-
export class QqHttpEndpoint {
|
|
187
|
+
export class QqHttpEndpoint extends Endpoint {
|
|
201
188
|
#logger;
|
|
202
189
|
#options;
|
|
203
190
|
#createBot;
|
|
@@ -205,14 +192,17 @@ export class QqHttpEndpoint {
|
|
|
205
192
|
#routeReleases = [];
|
|
206
193
|
#open = false;
|
|
207
194
|
#started = false;
|
|
208
|
-
|
|
209
|
-
management = createQqEndpointManagement(this);
|
|
195
|
+
management = createQqEndpointManagement(() => this.#requireBot());
|
|
210
196
|
control = createRecallEndpointControl((id) => this.recallMessage(id));
|
|
211
197
|
constructor(options) {
|
|
198
|
+
super();
|
|
212
199
|
this.#logger = getAdapterLogger('qq', options.config.id);
|
|
213
200
|
this.#options = options;
|
|
214
201
|
this.#createBot = options.createBot ?? defaultCreateHttpBot;
|
|
215
202
|
}
|
|
203
|
+
get client() {
|
|
204
|
+
return this.#requireBot();
|
|
205
|
+
}
|
|
216
206
|
/** Live endpoint 名(Console/AdapterIndex 展示用)。 */
|
|
217
207
|
get name() {
|
|
218
208
|
return this.#options.config.id;
|
|
@@ -222,7 +212,6 @@ export class QqHttpEndpoint {
|
|
|
222
212
|
return;
|
|
223
213
|
this.#started = true;
|
|
224
214
|
try {
|
|
225
|
-
this.#unregisterAgent = registerQqAgentEndpoint(this.#options.config.id, this);
|
|
226
215
|
this.#setupRoutes();
|
|
227
216
|
this.#bot = this.#createBot(this.#options.config);
|
|
228
217
|
this.#bindBot(this.#bot);
|
|
@@ -245,8 +234,6 @@ export class QqHttpEndpoint {
|
|
|
245
234
|
this.#open = false;
|
|
246
235
|
for (const release of this.#routeReleases.splice(0))
|
|
247
236
|
release();
|
|
248
|
-
this.#unregisterAgent?.();
|
|
249
|
-
this.#unregisterAgent = undefined;
|
|
250
237
|
if (this.#bot) {
|
|
251
238
|
try {
|
|
252
239
|
this.#bot.removeAllListeners();
|
|
@@ -320,7 +307,7 @@ export class QqHttpEndpoint {
|
|
|
320
307
|
+ (msg.authorId ? ` from ${msg.authorId}` : '')
|
|
321
308
|
+ (msg.mentioned ? ' (mentioned)' : '')
|
|
322
309
|
+ ` | ${truncatePreview(content, 80)}`);
|
|
323
|
-
void this
|
|
310
|
+
void this.emit('message.receive', {
|
|
324
311
|
conversation,
|
|
325
312
|
message: { conversation, id: msg.id },
|
|
326
313
|
content,
|
|
@@ -346,30 +333,6 @@ export class QqHttpEndpoint {
|
|
|
346
333
|
}));
|
|
347
334
|
});
|
|
348
335
|
}
|
|
349
|
-
getGuilds() {
|
|
350
|
-
return this.#requireBot().getGuilds();
|
|
351
|
-
}
|
|
352
|
-
getChannels(guildId) {
|
|
353
|
-
return this.#requireBot().getChannels(guildId);
|
|
354
|
-
}
|
|
355
|
-
getChannelInfo(channelId) {
|
|
356
|
-
return this.#requireBot().getChannelInfo(channelId);
|
|
357
|
-
}
|
|
358
|
-
getGuildMember(guildId, userId) {
|
|
359
|
-
return this.#requireBot().getGuildMember(guildId, userId);
|
|
360
|
-
}
|
|
361
|
-
getGuildRoles(guildId) {
|
|
362
|
-
return this.#requireBot().getGuildRoles(guildId);
|
|
363
|
-
}
|
|
364
|
-
createGuildRole(guildId, name, color) {
|
|
365
|
-
return this.#requireBot().createGuildRole(guildId, name, color);
|
|
366
|
-
}
|
|
367
|
-
addMemberRole(guildId, channelId, userId, roleId) {
|
|
368
|
-
return this.#requireBot().addMemberRole(guildId, channelId, userId, roleId);
|
|
369
|
-
}
|
|
370
|
-
removeMemberRole(guildId, channelId, userId, roleId) {
|
|
371
|
-
return this.#requireBot().removeMemberRole(guildId, channelId, userId, roleId);
|
|
372
|
-
}
|
|
373
336
|
#setupRoutes() {
|
|
374
337
|
this.#routeReleases.push(...registerQqWebhookRoutes(this.#options.http, {
|
|
375
338
|
config: this.#options.config,
|
|
@@ -378,12 +341,23 @@ export class QqHttpEndpoint {
|
|
|
378
341
|
}
|
|
379
342
|
#bindBot(bot) {
|
|
380
343
|
bindQqBotInboundEvents(bot, (raw) => {
|
|
344
|
+
this.#emitPlatformEvent('message', raw);
|
|
381
345
|
const msg = normalizeQqMessage(raw);
|
|
382
346
|
if (msg)
|
|
383
347
|
this.admit(msg);
|
|
384
348
|
});
|
|
385
349
|
bindQqBotSideEvents(bot, (eventName, raw) => {
|
|
386
|
-
|
|
350
|
+
this.#emitPlatformEvent(eventName, raw);
|
|
351
|
+
receiveQqSideEvent((name, payload) => this.emit(name, payload), this.#options.config.id, bot, eventName, raw, this.#logger);
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
#emitPlatformEvent(name, event) {
|
|
355
|
+
void this.emitPlatform(name, event).catch((error) => {
|
|
356
|
+
this.#logger.warn(formatCompact({
|
|
357
|
+
op: 'qq_platform_event_failed',
|
|
358
|
+
event: name,
|
|
359
|
+
error: error instanceof Error ? error.message : String(error),
|
|
360
|
+
}));
|
|
387
361
|
});
|
|
388
362
|
}
|
|
389
363
|
#requireBot() {
|
|
@@ -392,18 +366,19 @@ export class QqHttpEndpoint {
|
|
|
392
366
|
return this.#bot;
|
|
393
367
|
}
|
|
394
368
|
}
|
|
395
|
-
function createQqEndpointManagement(
|
|
369
|
+
function createQqEndpointManagement(requireClient) {
|
|
396
370
|
return Object.freeze({
|
|
397
371
|
async listChannels() {
|
|
398
372
|
const channels = [];
|
|
399
|
-
const
|
|
373
|
+
const client = requireClient();
|
|
374
|
+
const guilds = await client.getGuilds();
|
|
400
375
|
for (const guildValue of Array.isArray(guilds) ? guilds : []) {
|
|
401
376
|
const guild = asRecord(guildValue);
|
|
402
377
|
const guildId = String(guild.id ?? guild.guild_id ?? guildValue ?? '');
|
|
403
378
|
if (!guildId)
|
|
404
379
|
continue;
|
|
405
380
|
const guildName = String(guild.name ?? guild.guild_name ?? guildId);
|
|
406
|
-
const rows = await
|
|
381
|
+
const rows = await client.getChannels(guildId);
|
|
407
382
|
for (const channelValue of Array.isArray(rows) ? rows : []) {
|
|
408
383
|
const channel = asRecord(channelValue);
|
|
409
384
|
const id = String(channel.id ?? channel.channel_id ?? channelValue ?? '');
|
package/lib/index.d.ts
CHANGED
|
@@ -4,5 +4,5 @@ export { formatOutbound, resolveMediaFile, type QqOutboundElem, type QqOutboundM
|
|
|
4
4
|
export { QqHttpEndpoint, QqWebsocketEndpoint, type CreateQqBot, type CreateQqHttpBot, type QqBotTransport, type QqEndpointOptions, type QqHttpBotTransport, type QqHttpEndpointOptions, } from './endpoint.js';
|
|
5
5
|
export { registerQqWebhookRoutes, handleQqWebhookRequest, readRequestBodyText, defaultCreateHttpBot, type QqWebhookHandler, } from './webhook.js';
|
|
6
6
|
export { bindQqBotInboundEvents, defaultCreateBot, normalizeQqMessage, } from './ws.js';
|
|
7
|
-
export {
|
|
7
|
+
export { qqClient, type QqClientEventMap } from './client.js';
|
|
8
8
|
export { checkQqPlatformPermit, normalizeQqGuildSenderForPermit, platformPermit, qqGuildPermitResolver, } from './platform-permit.js';
|
package/lib/index.js
CHANGED
|
@@ -4,5 +4,5 @@ export { formatOutbound, resolveMediaFile, } from './outbound.js';
|
|
|
4
4
|
export { QqHttpEndpoint, QqWebsocketEndpoint, } from './endpoint.js';
|
|
5
5
|
export { registerQqWebhookRoutes, handleQqWebhookRequest, readRequestBodyText, defaultCreateHttpBot, } from './webhook.js';
|
|
6
6
|
export { bindQqBotInboundEvents, defaultCreateBot, normalizeQqMessage, } from './ws.js';
|
|
7
|
-
export {
|
|
7
|
+
export { qqClient } from './client.js';
|
|
8
8
|
export { checkQqPlatformPermit, normalizeQqGuildSenderForPermit, platformPermit, qqGuildPermitResolver, } from './platform-permit.js';
|
|
@@ -42,4 +42,4 @@ export declare function runQqEndpointRemove(_state: QqRuntimeState, id: string,
|
|
|
42
42
|
* 通用套件生成的 QQ endpoint 命令(add 经 bindFlow 钩子走扫码绑定)。
|
|
43
43
|
* commands/endpoint/ 下的 list / add / remove 直接默认导出这三项;cancel 为 QQ 特化,单独定义。
|
|
44
44
|
*/
|
|
45
|
-
export declare const qqEndpointCommands: import("@zhin.js/adapter").EndpointCommands<Readonly<import("@zhin.js/command").CommandDefinition<unknown, unknown, import("@zhin.js/command").CommandMessage>>>;
|
|
45
|
+
export declare const qqEndpointCommands: import("@zhin.js/adapter").EndpointCommands<Readonly<import("@zhin.js/command").CommandDefinition<unknown, unknown, import("@zhin.js/command").CommandMessage, string | undefined>>>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { EndpointEventEmitter } from 'zhin.js/adapter';
|
|
2
2
|
import { type getAdapterLogger } from '@zhin.js/logger';
|
|
3
3
|
export interface QqSideEventCaller {
|
|
4
4
|
approveGroupJoinRequest?(groupId: string, userId: string, options: {
|
|
@@ -10,4 +10,4 @@ export interface QqSideEventCaller {
|
|
|
10
10
|
export declare function bindQqBotSideEvents(bot: {
|
|
11
11
|
on(event: string, listener: (...args: unknown[]) => void): void;
|
|
12
12
|
}, dispatch: (eventName: string, raw: unknown) => void): void;
|
|
13
|
-
export declare function receiveQqSideEvent(
|
|
13
|
+
export declare function receiveQqSideEvent(emit: EndpointEventEmitter, endpointKey: string, caller: QqSideEventCaller, eventName: string, raw: unknown, logger: ReturnType<typeof getAdapterLogger>): void;
|
|
@@ -51,8 +51,8 @@ function toOneBotLikeRaw(eventName, raw) {
|
|
|
51
51
|
}
|
|
52
52
|
return null;
|
|
53
53
|
}
|
|
54
|
-
export function receiveQqSideEvent(
|
|
55
|
-
if (!
|
|
54
|
+
export function receiveQqSideEvent(emit, endpointKey, caller, eventName, raw, logger) {
|
|
55
|
+
if (!emit)
|
|
56
56
|
return;
|
|
57
57
|
const mapped = toOneBotLikeRaw(eventName, raw);
|
|
58
58
|
if (!mapped)
|
|
@@ -61,7 +61,7 @@ export function receiveQqSideEvent(sideEvents, endpointKey, caller, eventName, r
|
|
|
61
61
|
const joinRaw = isJoinRequest && raw && typeof raw === 'object'
|
|
62
62
|
? raw
|
|
63
63
|
: undefined;
|
|
64
|
-
void receiveOneBotLikeSideEvent(
|
|
64
|
+
void receiveOneBotLikeSideEvent(emit, {
|
|
65
65
|
adapter: 'qq',
|
|
66
66
|
endpointKey,
|
|
67
67
|
platform: 'qq',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/adapter-qq",
|
|
3
|
-
"version": "8.0.
|
|
3
|
+
"version": "8.0.1",
|
|
4
4
|
"description": "Zhin.js QQ Official adapter for Plugin Runtime (WebSocket gateway)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -35,21 +35,22 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"qq-official-bot": "^1.2.3",
|
|
38
|
-
"@zhin.js/adapter": "1.2.
|
|
39
|
-
"@zhin.js/core": "1.5.
|
|
40
|
-
"@zhin.js/
|
|
38
|
+
"@zhin.js/adapter": "1.2.1",
|
|
39
|
+
"@zhin.js/core": "1.5.14",
|
|
40
|
+
"@zhin.js/feature-kit": "1.0.13",
|
|
41
|
+
"@zhin.js/host-http": "1.0.13",
|
|
41
42
|
"@zhin.js/im-contract": "1.0.4",
|
|
42
|
-
"@zhin.js/logger": "1.0.
|
|
43
|
-
"@zhin.js/permission": "1.0.
|
|
43
|
+
"@zhin.js/logger": "1.0.77",
|
|
44
|
+
"@zhin.js/permission": "1.0.4"
|
|
44
45
|
},
|
|
45
46
|
"peerDependencies": {
|
|
46
47
|
"zod": "^4.0.0",
|
|
47
|
-
"@zhin.js/adapter": "1.2.
|
|
48
|
-
"@zhin.js/agent": "1.1.
|
|
49
|
-
"@zhin.js/command": "1.0.
|
|
50
|
-
"@zhin.js/core": "1.5.
|
|
51
|
-
"@zhin.js/middleware": "1.0.
|
|
52
|
-
"zhin.js": "6.0.
|
|
48
|
+
"@zhin.js/adapter": "1.2.1",
|
|
49
|
+
"@zhin.js/agent": "1.1.16",
|
|
50
|
+
"@zhin.js/command": "1.0.16",
|
|
51
|
+
"@zhin.js/core": "1.5.14",
|
|
52
|
+
"@zhin.js/middleware": "1.0.13",
|
|
53
|
+
"zhin.js": "6.0.14"
|
|
53
54
|
},
|
|
54
55
|
"peerDependenciesMeta": {
|
|
55
56
|
"@zhin.js/agent": {
|
|
@@ -73,9 +74,9 @@
|
|
|
73
74
|
"typescript": "^6.0.3",
|
|
74
75
|
"vitest": "^4.1.10",
|
|
75
76
|
"zod": "^4.4.3",
|
|
76
|
-
"@zhin.js/agent": "1.1.
|
|
77
|
-
"@zhin.js/host-http": "1.0.
|
|
78
|
-
"zhin.js": "6.0.
|
|
77
|
+
"@zhin.js/agent": "1.1.16",
|
|
78
|
+
"@zhin.js/host-http": "1.0.13",
|
|
79
|
+
"zhin.js": "6.0.14"
|
|
79
80
|
},
|
|
80
81
|
"files": [
|
|
81
82
|
"adapters",
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineEndpointClient } from 'zhin.js/adapter';
|
|
2
|
+
import type { QqInboundMessage } from './protocol.js';
|
|
3
|
+
import type { QqBotTransport } from './ws.js';
|
|
4
|
+
|
|
5
|
+
export type QqClientEventMap = Record<string, QqInboundMessage | unknown>;
|
|
6
|
+
|
|
7
|
+
declare module '@zhin.js/feature-kit' {
|
|
8
|
+
interface AdapterClientRegistry {
|
|
9
|
+
readonly qq: {
|
|
10
|
+
readonly client: QqBotTransport;
|
|
11
|
+
readonly events: QqClientEventMap;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const qqClient = defineEndpointClient<QqBotTransport, QqClientEventMap>('qq');
|
package/src/endpoint.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Endpoint } from 'zhin.js/adapter';
|
|
1
2
|
/**
|
|
2
3
|
* QQ endpoints — lifecycle, outbound, admit, agent tool surface.
|
|
3
4
|
*/
|
|
@@ -5,16 +6,13 @@ import {
|
|
|
5
6
|
createRecallEndpointControl,
|
|
6
7
|
type EndpointControl,
|
|
7
8
|
type EndpointChannel,
|
|
8
|
-
type EndpointInstance,
|
|
9
9
|
type EndpointManagement,
|
|
10
10
|
type EndpointSendRequest,
|
|
11
11
|
} from 'zhin.js/adapter';
|
|
12
|
-
import type { MessageGateway, SideEventGateway } from '@zhin.js/core/runtime';
|
|
13
12
|
import type { HttpHost } from '@zhin.js/host-http';
|
|
14
13
|
import { formatCompact, getAdapterLogger, truncatePreview } from '@zhin.js/logger';
|
|
15
14
|
import type { CapabilityId } from 'zhin.js';
|
|
16
15
|
import { formatOutbound } from './outbound.js';
|
|
17
|
-
import { registerQqAgentEndpoint } from './qq-agent-deps.js';
|
|
18
16
|
import {
|
|
19
17
|
formatInboundContent,
|
|
20
18
|
parseCompoundMessageId,
|
|
@@ -50,13 +48,11 @@ export type { CreateQqHttpBot, QqHttpBotTransport } from './webhook.js';
|
|
|
50
48
|
|
|
51
49
|
export interface QqEndpointOptions {
|
|
52
50
|
readonly id: CapabilityId;
|
|
53
|
-
readonly gateway: MessageGateway;
|
|
54
|
-
readonly sideEvents?: SideEventGateway;
|
|
55
51
|
readonly config: ResolvedQqWebsocketConfig;
|
|
56
52
|
readonly createBot?: CreateQqBot;
|
|
57
53
|
}
|
|
58
54
|
|
|
59
|
-
export class QqWebsocketEndpoint
|
|
55
|
+
export class QqWebsocketEndpoint extends Endpoint<QqBotTransport> {
|
|
60
56
|
readonly #logger!: ReturnType<typeof getAdapterLogger>;
|
|
61
57
|
|
|
62
58
|
readonly #options: QqEndpointOptions;
|
|
@@ -64,16 +60,20 @@ export class QqWebsocketEndpoint implements EndpointInstance {
|
|
|
64
60
|
#bot: QqBotTransport | null = null;
|
|
65
61
|
#open = false;
|
|
66
62
|
#started = false;
|
|
67
|
-
|
|
68
|
-
readonly management: EndpointManagement = createQqEndpointManagement(this);
|
|
63
|
+
readonly management: EndpointManagement = createQqEndpointManagement(() => this.#requireBot());
|
|
69
64
|
readonly control: EndpointControl = createRecallEndpointControl((id) => this.recallMessage(id));
|
|
70
65
|
|
|
71
66
|
constructor(options: QqEndpointOptions) {
|
|
67
|
+
super();
|
|
72
68
|
this.#logger = getAdapterLogger('qq', options.config.id);
|
|
73
69
|
this.#options = options;
|
|
74
70
|
this.#createBot = options.createBot ?? defaultCreateBot;
|
|
75
71
|
}
|
|
76
72
|
|
|
73
|
+
get client(): QqBotTransport {
|
|
74
|
+
return this.#requireBot();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
77
|
/** Live endpoint 名(Console/AdapterIndex 展示用,如 bot appid 别名)。 */
|
|
78
78
|
get name(): string {
|
|
79
79
|
return this.#options.config.id;
|
|
@@ -83,7 +83,6 @@ export class QqWebsocketEndpoint implements EndpointInstance {
|
|
|
83
83
|
if (this.#started) return;
|
|
84
84
|
this.#started = true;
|
|
85
85
|
try {
|
|
86
|
-
this.#unregisterAgent = registerQqAgentEndpoint(this.#options.config.id, this);
|
|
87
86
|
this.#bot = this.#createBot(this.#options.config);
|
|
88
87
|
this.#bindBot(this.#bot);
|
|
89
88
|
await this.#bot.start();
|
|
@@ -111,8 +110,6 @@ export class QqWebsocketEndpoint implements EndpointInstance {
|
|
|
111
110
|
|
|
112
111
|
async stop(): Promise<void> {
|
|
113
112
|
this.#open = false;
|
|
114
|
-
this.#unregisterAgent?.();
|
|
115
|
-
this.#unregisterAgent = undefined;
|
|
116
113
|
if (this.#bot) {
|
|
117
114
|
try {
|
|
118
115
|
this.#bot.removeAllListeners();
|
|
@@ -191,7 +188,7 @@ export class QqWebsocketEndpoint implements EndpointInstance {
|
|
|
191
188
|
+ (msg.mentioned ? ' (mentioned)' : '')
|
|
192
189
|
+ ` | ${truncatePreview(content, 80)}`,
|
|
193
190
|
);
|
|
194
|
-
void this
|
|
191
|
+
void this.emit('message.receive', {
|
|
195
192
|
conversation,
|
|
196
193
|
message: { conversation, id: msg.id },
|
|
197
194
|
content,
|
|
@@ -218,46 +215,16 @@ export class QqWebsocketEndpoint implements EndpointInstance {
|
|
|
218
215
|
});
|
|
219
216
|
}
|
|
220
217
|
|
|
221
|
-
getGuilds() {
|
|
222
|
-
return this.#requireBot().getGuilds();
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
getChannels(guildId: string) {
|
|
226
|
-
return this.#requireBot().getChannels(guildId);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
getChannelInfo(channelId: string) {
|
|
230
|
-
return this.#requireBot().getChannelInfo(channelId);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
getGuildMember(guildId: string, userId: string) {
|
|
234
|
-
return this.#requireBot().getGuildMember(guildId, userId);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
getGuildRoles(guildId: string) {
|
|
238
|
-
return this.#requireBot().getGuildRoles(guildId);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
createGuildRole(guildId: string, name: string, color?: number) {
|
|
242
|
-
return this.#requireBot().createGuildRole(guildId, name, color);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
addMemberRole(guildId: string, channelId: string, userId: string, roleId: string) {
|
|
246
|
-
return this.#requireBot().addMemberRole(guildId, channelId, userId, roleId);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
removeMemberRole(guildId: string, channelId: string, userId: string, roleId: string) {
|
|
250
|
-
return this.#requireBot().removeMemberRole(guildId, channelId, userId, roleId);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
218
|
#bindBot(bot: QqBotTransport): void {
|
|
254
219
|
bindQqBotInboundEvents(bot, (raw) => {
|
|
220
|
+
this.#emitPlatformEvent('message', raw);
|
|
255
221
|
const msg = normalizeQqMessage(raw);
|
|
256
222
|
if (msg) this.admit(msg);
|
|
257
223
|
});
|
|
258
224
|
bindQqBotSideEvents(bot, (eventName, raw) => {
|
|
225
|
+
this.#emitPlatformEvent(eventName, raw);
|
|
259
226
|
receiveQqSideEvent(
|
|
260
|
-
this
|
|
227
|
+
(name, payload) => this.emit(name, payload),
|
|
261
228
|
this.#options.config.id,
|
|
262
229
|
bot as QqSideEventCaller,
|
|
263
230
|
eventName,
|
|
@@ -267,6 +234,16 @@ export class QqWebsocketEndpoint implements EndpointInstance {
|
|
|
267
234
|
});
|
|
268
235
|
}
|
|
269
236
|
|
|
237
|
+
#emitPlatformEvent(name: string, event: unknown): void {
|
|
238
|
+
void this.emitPlatform(name, event).catch((error) => {
|
|
239
|
+
this.#logger.warn(formatCompact({
|
|
240
|
+
op: 'qq_platform_event_failed',
|
|
241
|
+
event: name,
|
|
242
|
+
error: error instanceof Error ? error.message : String(error),
|
|
243
|
+
}));
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
270
247
|
#requireBot(): QqBotTransport {
|
|
271
248
|
if (!this.#bot) throw new Error('QQ bot not connected');
|
|
272
249
|
return this.#bot;
|
|
@@ -275,15 +252,13 @@ export class QqWebsocketEndpoint implements EndpointInstance {
|
|
|
275
252
|
|
|
276
253
|
export interface QqHttpEndpointOptions {
|
|
277
254
|
readonly id: CapabilityId;
|
|
278
|
-
readonly gateway: MessageGateway;
|
|
279
|
-
readonly sideEvents?: SideEventGateway;
|
|
280
255
|
readonly http: HttpHost;
|
|
281
256
|
readonly config: ResolvedQqHttpConfig;
|
|
282
257
|
readonly createBot?: CreateQqHttpBot;
|
|
283
258
|
}
|
|
284
259
|
|
|
285
260
|
/** Webhook / middleware inbound via httpHostToken POST (qq-official-bot Middleware receiver). */
|
|
286
|
-
export class QqHttpEndpoint
|
|
261
|
+
export class QqHttpEndpoint extends Endpoint<QqHttpBotTransport> {
|
|
287
262
|
readonly #logger!: ReturnType<typeof getAdapterLogger>;
|
|
288
263
|
|
|
289
264
|
readonly #options: QqHttpEndpointOptions;
|
|
@@ -292,16 +267,20 @@ export class QqHttpEndpoint implements EndpointInstance {
|
|
|
292
267
|
#routeReleases: ReturnType<typeof registerQqWebhookRoutes> = [];
|
|
293
268
|
#open = false;
|
|
294
269
|
#started = false;
|
|
295
|
-
|
|
296
|
-
readonly management: EndpointManagement = createQqEndpointManagement(this);
|
|
270
|
+
readonly management: EndpointManagement = createQqEndpointManagement(() => this.#requireBot());
|
|
297
271
|
readonly control: EndpointControl = createRecallEndpointControl((id) => this.recallMessage(id));
|
|
298
272
|
|
|
299
273
|
constructor(options: QqHttpEndpointOptions) {
|
|
274
|
+
super();
|
|
300
275
|
this.#logger = getAdapterLogger('qq', options.config.id);
|
|
301
276
|
this.#options = options;
|
|
302
277
|
this.#createBot = options.createBot ?? defaultCreateHttpBot;
|
|
303
278
|
}
|
|
304
279
|
|
|
280
|
+
get client(): QqHttpBotTransport {
|
|
281
|
+
return this.#requireBot();
|
|
282
|
+
}
|
|
283
|
+
|
|
305
284
|
/** Live endpoint 名(Console/AdapterIndex 展示用)。 */
|
|
306
285
|
get name(): string {
|
|
307
286
|
return this.#options.config.id;
|
|
@@ -311,10 +290,6 @@ export class QqHttpEndpoint implements EndpointInstance {
|
|
|
311
290
|
if (this.#started) return;
|
|
312
291
|
this.#started = true;
|
|
313
292
|
try {
|
|
314
|
-
this.#unregisterAgent = registerQqAgentEndpoint(
|
|
315
|
-
this.#options.config.id,
|
|
316
|
-
this as unknown as QqWebsocketEndpoint,
|
|
317
|
-
);
|
|
318
293
|
this.#setupRoutes();
|
|
319
294
|
this.#bot = this.#createBot(this.#options.config);
|
|
320
295
|
this.#bindBot(this.#bot);
|
|
@@ -340,8 +315,6 @@ export class QqHttpEndpoint implements EndpointInstance {
|
|
|
340
315
|
async stop(): Promise<void> {
|
|
341
316
|
this.#open = false;
|
|
342
317
|
for (const release of this.#routeReleases.splice(0)) release();
|
|
343
|
-
this.#unregisterAgent?.();
|
|
344
|
-
this.#unregisterAgent = undefined;
|
|
345
318
|
if (this.#bot) {
|
|
346
319
|
try {
|
|
347
320
|
this.#bot.removeAllListeners();
|
|
@@ -419,7 +392,7 @@ export class QqHttpEndpoint implements EndpointInstance {
|
|
|
419
392
|
+ (msg.mentioned ? ' (mentioned)' : '')
|
|
420
393
|
+ ` | ${truncatePreview(content, 80)}`,
|
|
421
394
|
);
|
|
422
|
-
void this
|
|
395
|
+
void this.emit('message.receive', {
|
|
423
396
|
conversation,
|
|
424
397
|
message: { conversation, id: msg.id },
|
|
425
398
|
content,
|
|
@@ -446,38 +419,6 @@ export class QqHttpEndpoint implements EndpointInstance {
|
|
|
446
419
|
});
|
|
447
420
|
}
|
|
448
421
|
|
|
449
|
-
getGuilds() {
|
|
450
|
-
return this.#requireBot().getGuilds();
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
getChannels(guildId: string) {
|
|
454
|
-
return this.#requireBot().getChannels(guildId);
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
getChannelInfo(channelId: string) {
|
|
458
|
-
return this.#requireBot().getChannelInfo(channelId);
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
getGuildMember(guildId: string, userId: string) {
|
|
462
|
-
return this.#requireBot().getGuildMember(guildId, userId);
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
getGuildRoles(guildId: string) {
|
|
466
|
-
return this.#requireBot().getGuildRoles(guildId);
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
createGuildRole(guildId: string, name: string, color?: number) {
|
|
470
|
-
return this.#requireBot().createGuildRole(guildId, name, color);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
addMemberRole(guildId: string, channelId: string, userId: string, roleId: string) {
|
|
474
|
-
return this.#requireBot().addMemberRole(guildId, channelId, userId, roleId);
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
removeMemberRole(guildId: string, channelId: string, userId: string, roleId: string) {
|
|
478
|
-
return this.#requireBot().removeMemberRole(guildId, channelId, userId, roleId);
|
|
479
|
-
}
|
|
480
|
-
|
|
481
422
|
#setupRoutes(): void {
|
|
482
423
|
this.#routeReleases.push(...registerQqWebhookRoutes(this.#options.http, {
|
|
483
424
|
config: this.#options.config,
|
|
@@ -487,12 +428,14 @@ export class QqHttpEndpoint implements EndpointInstance {
|
|
|
487
428
|
|
|
488
429
|
#bindBot(bot: QqBotTransport): void {
|
|
489
430
|
bindQqBotInboundEvents(bot, (raw) => {
|
|
431
|
+
this.#emitPlatformEvent('message', raw);
|
|
490
432
|
const msg = normalizeQqMessage(raw);
|
|
491
433
|
if (msg) this.admit(msg);
|
|
492
434
|
});
|
|
493
435
|
bindQqBotSideEvents(bot, (eventName, raw) => {
|
|
436
|
+
this.#emitPlatformEvent(eventName, raw);
|
|
494
437
|
receiveQqSideEvent(
|
|
495
|
-
this
|
|
438
|
+
(name, payload) => this.emit(name, payload),
|
|
496
439
|
this.#options.config.id,
|
|
497
440
|
bot as QqSideEventCaller,
|
|
498
441
|
eventName,
|
|
@@ -502,26 +445,36 @@ export class QqHttpEndpoint implements EndpointInstance {
|
|
|
502
445
|
});
|
|
503
446
|
}
|
|
504
447
|
|
|
505
|
-
#
|
|
448
|
+
#emitPlatformEvent(name: string, event: unknown): void {
|
|
449
|
+
void this.emitPlatform(name, event).catch((error) => {
|
|
450
|
+
this.#logger.warn(formatCompact({
|
|
451
|
+
op: 'qq_platform_event_failed',
|
|
452
|
+
event: name,
|
|
453
|
+
error: error instanceof Error ? error.message : String(error),
|
|
454
|
+
}));
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
#requireBot(): QqHttpBotTransport {
|
|
506
459
|
if (!this.#bot) throw new Error('QQ bot not connected');
|
|
507
460
|
return this.#bot;
|
|
508
461
|
}
|
|
509
462
|
}
|
|
510
463
|
|
|
511
|
-
function createQqEndpointManagement(
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
}): EndpointManagement {
|
|
464
|
+
function createQqEndpointManagement(
|
|
465
|
+
requireClient: () => Pick<QqBotTransport, 'getGuilds' | 'getChannels'>,
|
|
466
|
+
): EndpointManagement {
|
|
515
467
|
return Object.freeze<EndpointManagement>({
|
|
516
468
|
async listChannels(): Promise<readonly EndpointChannel[]> {
|
|
517
469
|
const channels: EndpointChannel[] = [];
|
|
518
|
-
const
|
|
470
|
+
const client = requireClient();
|
|
471
|
+
const guilds = await client.getGuilds();
|
|
519
472
|
for (const guildValue of Array.isArray(guilds) ? guilds : []) {
|
|
520
473
|
const guild = asRecord(guildValue);
|
|
521
474
|
const guildId = String(guild.id ?? guild.guild_id ?? guildValue ?? '');
|
|
522
475
|
if (!guildId) continue;
|
|
523
476
|
const guildName = String(guild.name ?? guild.guild_name ?? guildId);
|
|
524
|
-
const rows = await
|
|
477
|
+
const rows = await client.getChannels(guildId);
|
|
525
478
|
for (const channelValue of Array.isArray(rows) ? rows : []) {
|
|
526
479
|
const channel = asRecord(channelValue);
|
|
527
480
|
const id = String(channel.id ?? channel.channel_id ?? channelValue ?? '');
|
package/src/index.ts
CHANGED
|
@@ -55,13 +55,7 @@ export {
|
|
|
55
55
|
normalizeQqMessage,
|
|
56
56
|
} from './ws.js';
|
|
57
57
|
|
|
58
|
-
export {
|
|
59
|
-
getQqAgentDeps,
|
|
60
|
-
registerQqAgentEndpoint,
|
|
61
|
-
setQqAgentDeps,
|
|
62
|
-
type QqAgentDeps,
|
|
63
|
-
type QqAgentEndpoint,
|
|
64
|
-
} from './qq-agent-deps.js';
|
|
58
|
+
export { qqClient, type QqClientEventMap } from './client.js';
|
|
65
59
|
|
|
66
60
|
export {
|
|
67
61
|
checkQqPlatformPermit,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { receiveOneBotLikeSideEvent, type OneBotLikeRawEvent } from '@zhin.js/core';
|
|
2
|
-
import type {
|
|
2
|
+
import type { EndpointEventEmitter } from 'zhin.js/adapter';
|
|
3
3
|
import { formatCompact, type getAdapterLogger } from '@zhin.js/logger';
|
|
4
4
|
|
|
5
5
|
export interface QqSideEventCaller {
|
|
@@ -66,21 +66,21 @@ function toOneBotLikeRaw(eventName: string, raw: unknown): OneBotLikeRawEvent |
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
export function receiveQqSideEvent(
|
|
69
|
-
|
|
69
|
+
emit: EndpointEventEmitter,
|
|
70
70
|
endpointKey: string,
|
|
71
71
|
caller: QqSideEventCaller,
|
|
72
72
|
eventName: string,
|
|
73
73
|
raw: unknown,
|
|
74
74
|
logger: ReturnType<typeof getAdapterLogger>,
|
|
75
75
|
): void {
|
|
76
|
-
if (!
|
|
76
|
+
if (!emit) return;
|
|
77
77
|
const mapped = toOneBotLikeRaw(eventName, raw);
|
|
78
78
|
if (!mapped) return;
|
|
79
79
|
const isJoinRequest = eventName === 'notice.group.join_request';
|
|
80
80
|
const joinRaw = isJoinRequest && raw && typeof raw === 'object'
|
|
81
81
|
? raw as { group_id?: string | number; user_id?: string | number; join_request_id?: string | number }
|
|
82
82
|
: undefined;
|
|
83
|
-
void receiveOneBotLikeSideEvent(
|
|
83
|
+
void receiveOneBotLikeSideEvent(emit, {
|
|
84
84
|
adapter: 'qq',
|
|
85
85
|
endpointKey,
|
|
86
86
|
platform: 'qq',
|
package/lib/qq-agent-deps.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent tool deps for qq.
|
|
3
|
-
* Endpoints register themselves on start; tools look up by config name / endpoint id.
|
|
4
|
-
*/
|
|
5
|
-
export interface QqAgentEndpoint {
|
|
6
|
-
getGuilds(): Promise<unknown[]>;
|
|
7
|
-
getChannels(guildId: string): Promise<unknown[]>;
|
|
8
|
-
getChannelInfo(channelId: string): Promise<unknown>;
|
|
9
|
-
getGuildMember(guildId: string, userId: string): Promise<unknown>;
|
|
10
|
-
getGuildRoles(guildId: string): Promise<unknown[]>;
|
|
11
|
-
createGuildRole(guildId: string, name: string, color?: number): Promise<unknown>;
|
|
12
|
-
addMemberRole(guildId: string, channelId: string, userId: string, roleId: string): Promise<boolean>;
|
|
13
|
-
removeMemberRole(guildId: string, channelId: string, userId: string, roleId: string): Promise<boolean>;
|
|
14
|
-
}
|
|
15
|
-
export interface QqAgentDeps {
|
|
16
|
-
getEndpoint: (endpointKey: string) => QqAgentEndpoint;
|
|
17
|
-
}
|
|
18
|
-
export declare function registerQqAgentEndpoint(endpointKey: string, endpoint: QqAgentEndpoint): () => void;
|
|
19
|
-
/** Optional override used by tests / transitional callers. Pass `null` to clear. */
|
|
20
|
-
export declare function setQqAgentDeps(deps: QqAgentDeps | null): void;
|
|
21
|
-
export declare function getQqAgentDeps(): QqAgentDeps;
|
package/lib/qq-agent-deps.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent tool deps for qq.
|
|
3
|
-
* Endpoints register themselves on start; tools look up by config name / endpoint id.
|
|
4
|
-
*/
|
|
5
|
-
const endpoints = new Map();
|
|
6
|
-
let override = null;
|
|
7
|
-
export function registerQqAgentEndpoint(endpointKey, endpoint) {
|
|
8
|
-
endpoints.set(endpointKey, endpoint);
|
|
9
|
-
return () => {
|
|
10
|
-
if (endpoints.get(endpointKey) === endpoint) {
|
|
11
|
-
endpoints.delete(endpointKey);
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
/** Optional override used by tests / transitional callers. Pass `null` to clear. */
|
|
16
|
-
export function setQqAgentDeps(deps) {
|
|
17
|
-
override = deps;
|
|
18
|
-
}
|
|
19
|
-
export function getQqAgentDeps() {
|
|
20
|
-
if (override)
|
|
21
|
-
return override;
|
|
22
|
-
return {
|
|
23
|
-
getEndpoint(endpointKey) {
|
|
24
|
-
const registered = endpoints.get(endpointKey);
|
|
25
|
-
if (!registered)
|
|
26
|
-
throw new Error(`Endpoint ${endpointKey} 不存在`);
|
|
27
|
-
return registered;
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
}
|
package/src/qq-agent-deps.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent tool deps for qq.
|
|
3
|
-
* Endpoints register themselves on start; tools look up by config name / endpoint id.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export interface QqAgentEndpoint {
|
|
7
|
-
getGuilds(): Promise<unknown[]>;
|
|
8
|
-
getChannels(guildId: string): Promise<unknown[]>;
|
|
9
|
-
getChannelInfo(channelId: string): Promise<unknown>;
|
|
10
|
-
getGuildMember(guildId: string, userId: string): Promise<unknown>;
|
|
11
|
-
getGuildRoles(guildId: string): Promise<unknown[]>;
|
|
12
|
-
createGuildRole(guildId: string, name: string, color?: number): Promise<unknown>;
|
|
13
|
-
addMemberRole(
|
|
14
|
-
guildId: string,
|
|
15
|
-
channelId: string,
|
|
16
|
-
userId: string,
|
|
17
|
-
roleId: string,
|
|
18
|
-
): Promise<boolean>;
|
|
19
|
-
removeMemberRole(
|
|
20
|
-
guildId: string,
|
|
21
|
-
channelId: string,
|
|
22
|
-
userId: string,
|
|
23
|
-
roleId: string,
|
|
24
|
-
): Promise<boolean>;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface QqAgentDeps {
|
|
28
|
-
getEndpoint: (endpointKey: string) => QqAgentEndpoint;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const endpoints = new Map<string, QqAgentEndpoint>();
|
|
32
|
-
let override: QqAgentDeps | null = null;
|
|
33
|
-
|
|
34
|
-
export function registerQqAgentEndpoint(
|
|
35
|
-
endpointKey: string,
|
|
36
|
-
endpoint: QqAgentEndpoint,
|
|
37
|
-
): () => void {
|
|
38
|
-
endpoints.set(endpointKey, endpoint);
|
|
39
|
-
return () => {
|
|
40
|
-
if (endpoints.get(endpointKey) === endpoint) {
|
|
41
|
-
endpoints.delete(endpointKey);
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/** Optional override used by tests / transitional callers. Pass `null` to clear. */
|
|
47
|
-
export function setQqAgentDeps(deps: QqAgentDeps | null): void {
|
|
48
|
-
override = deps;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export function getQqAgentDeps(): QqAgentDeps {
|
|
52
|
-
if (override) return override;
|
|
53
|
-
return {
|
|
54
|
-
getEndpoint(endpointKey: string): QqAgentEndpoint {
|
|
55
|
-
const registered = endpoints.get(endpointKey);
|
|
56
|
-
if (!registered) throw new Error(`Endpoint ${endpointKey} 不存在`);
|
|
57
|
-
return registered;
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
}
|