@zhin.js/adapter-qq 7.0.2 → 7.0.5
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 +96 -0
- package/README.md +36 -9
- package/adapters/qq.js +9 -7
- package/adapters/qq.ts +9 -7
- package/commands/endpoint/cancel.js +1 -1
- package/commands/endpoint/cancel.ts +1 -1
- package/lib/endpoint.d.ts +3 -9
- package/lib/endpoint.js +79 -75
- package/lib/index.d.ts +3 -2
- package/lib/index.js +3 -2
- package/lib/platform-permit.d.ts +2 -3
- package/lib/platform-permit.js +3 -11
- package/lib/protocol.d.ts +14 -11
- package/lib/protocol.js +26 -19
- package/lib/qq-agent-deps.d.ts +2 -2
- package/lib/qq-agent-deps.js +7 -7
- package/lib/qq-bind-persist.d.ts +2 -2
- package/lib/qq-bind-persist.js +5 -5
- package/lib/qq-bot-kind-prompt.d.ts +9 -0
- package/lib/qq-bot-kind-prompt.js +37 -0
- package/lib/qq-endpoint-commands.d.ts +13 -6
- package/lib/qq-endpoint-commands.js +89 -31
- package/lib/qq-endpoint-config.d.ts +4 -4
- package/lib/qq-endpoint-config.js +4 -4
- package/lib/qq-intents.d.ts +27 -0
- package/lib/qq-intents.js +50 -0
- package/lib/qq-runtime-state.d.ts +17 -4
- package/lib/qq-runtime-state.js +3 -2
- package/lib/webhook.js +2 -0
- package/lib/ws.js +2 -2
- package/middlewares/bot-kind-reply.js +46 -0
- package/middlewares/bot-kind-reply.ts +60 -0
- package/package.json +23 -15
- package/plugin.js +6 -4
- package/schema.json +66 -9
- package/src/endpoint.ts +95 -79
- package/src/index.ts +10 -4
- package/src/platform-permit.ts +4 -9
- package/src/protocol.ts +34 -28
- package/src/qq-agent-deps.ts +8 -8
- package/src/qq-bind-persist.ts +5 -5
- package/src/qq-bot-kind-prompt.ts +47 -0
- package/src/qq-endpoint-commands.ts +125 -34
- package/src/qq-endpoint-config.ts +5 -5
- package/src/qq-intents.ts +76 -0
- package/src/qq-runtime-state.ts +21 -6
- package/src/webhook.ts +2 -0
- package/src/ws.ts +2 -2
- /package/commands/endpoint/add/{[name:string=].js → [[id]].js} +0 -0
- /package/commands/endpoint/add/{[name:string=].ts → [[id]].ts} +0 -0
- /package/commands/endpoint/remove/{[name:string].js → [id].js} +0 -0
- /package/commands/endpoint/remove/{[name:string].ts → [id].ts} +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QQ 官方机器人 intents 与公域/私域映射。
|
|
3
|
+
*
|
|
4
|
+
* 群聊无公/私域之分,两类都订阅 `GROUP_AND_C2C_EVENT`。
|
|
5
|
+
* 频道消息 intent 不同:
|
|
6
|
+
* - public(公域):`PUBLIC_GUILD_MESSAGES`(仅 @ 机器人)
|
|
7
|
+
* - private(私域):`GUILD_MESSAGES`(频道全量消息;公域订阅会 Identify 失败)
|
|
8
|
+
*/
|
|
9
|
+
/** 扫码绑定 / 未声明 botKind 时的默认(公域更常见)。 */
|
|
10
|
+
export const DEFAULT_QQ_BOT_KIND = 'public';
|
|
11
|
+
/** 公/私域共用:群@+私聊 C2C、频道基础事件、频道私信。 */
|
|
12
|
+
const QQ_SHARED_INTENTS = Object.freeze([
|
|
13
|
+
'GROUP_AND_C2C_EVENT',
|
|
14
|
+
'GUILDS',
|
|
15
|
+
'GUILD_MEMBERS',
|
|
16
|
+
'DIRECT_MESSAGE',
|
|
17
|
+
]);
|
|
18
|
+
export const QQ_INTENTS_BY_KIND = Object.freeze({
|
|
19
|
+
public: Object.freeze([
|
|
20
|
+
...QQ_SHARED_INTENTS,
|
|
21
|
+
'PUBLIC_GUILD_MESSAGES',
|
|
22
|
+
]),
|
|
23
|
+
private: Object.freeze([
|
|
24
|
+
...QQ_SHARED_INTENTS,
|
|
25
|
+
'GUILD_MESSAGES',
|
|
26
|
+
]),
|
|
27
|
+
});
|
|
28
|
+
/** 解析 botKind:仅接受 `public` / `private`。 */
|
|
29
|
+
export function parseQqBotKind(value) {
|
|
30
|
+
if (value === 'public' || value === 'private')
|
|
31
|
+
return value;
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 解析最终 intents:显式 `intents` 优先;否则按 `botKind`(默认 public)展开。
|
|
36
|
+
*/
|
|
37
|
+
export function resolveQqIntents(input) {
|
|
38
|
+
if (Array.isArray(input.intents) && input.intents.length > 0) {
|
|
39
|
+
return Object.freeze(input.intents.map(String));
|
|
40
|
+
}
|
|
41
|
+
const kind = parseQqBotKind(input.botKind) ?? DEFAULT_QQ_BOT_KIND;
|
|
42
|
+
return QQ_INTENTS_BY_KIND[kind];
|
|
43
|
+
}
|
|
44
|
+
/** 添加 endpoint 时写入配置的默认字段(显式展开,便于用户改)。 */
|
|
45
|
+
export function defaultQqEndpointIntentFields(botKind = DEFAULT_QQ_BOT_KIND) {
|
|
46
|
+
return Object.freeze({
|
|
47
|
+
botKind,
|
|
48
|
+
intents: QQ_INTENTS_BY_KIND[botKind],
|
|
49
|
+
});
|
|
50
|
+
}
|
|
@@ -1,17 +1,30 @@
|
|
|
1
1
|
export interface QqRunningEndpoint {
|
|
2
|
-
|
|
2
|
+
id: string;
|
|
3
3
|
mode: string;
|
|
4
4
|
}
|
|
5
5
|
export interface QqBindFlowHandle {
|
|
6
|
-
/** 绑定期望的 endpoint
|
|
7
|
-
|
|
6
|
+
/** 绑定期望的 endpoint id(未指定时为 undefined,成功后取 appId) */
|
|
7
|
+
id?: string;
|
|
8
8
|
stop: () => void;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* 扫码成功后暂存在内存:确认公域/私域后再一次性写 .env + yaml。
|
|
12
|
+
* (提前写 .env 会触发 HMR,冲掉 pending。)
|
|
13
|
+
*/
|
|
14
|
+
export interface QqPendingBotKind {
|
|
15
|
+
readonly endpointId: string;
|
|
16
|
+
readonly appId: string;
|
|
17
|
+
readonly appSecret: string;
|
|
18
|
+
/** 发起 add 的会话键;仅同会话回复可完成选择 */
|
|
19
|
+
readonly sessionKey: string;
|
|
20
|
+
}
|
|
10
21
|
export interface QqRuntimeState {
|
|
11
|
-
/** 当前 generation 已成功创建的 endpoint(
|
|
22
|
+
/** 当前 generation 已成功创建的 endpoint(id → 描述) */
|
|
12
23
|
readonly endpoints: Map<string, QqRunningEndpoint>;
|
|
13
24
|
/** 全局单例:同一时间只允许一个扫码绑定流程 */
|
|
14
25
|
bindFlow: QqBindFlowHandle | null;
|
|
26
|
+
/** 扫码完成后等待 botKind 选择(凭据仅在内存) */
|
|
27
|
+
pendingBotKind: QqPendingBotKind | null;
|
|
15
28
|
}
|
|
16
29
|
export declare function createQqRuntimeState(): QqRuntimeState;
|
|
17
30
|
export declare const qqRuntimeStateToken: import("@zhin.js/plugin-runtime").Token<QqRuntimeState>;
|
package/lib/qq-runtime-state.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* QQ 插件实例的运行时状态:adapter create() 注册的 endpoint 列表 +
|
|
3
|
-
*
|
|
4
|
-
* adapter create 与 commands 通过 use(qqRuntimeStateToken)
|
|
3
|
+
* 扫码绑定 / 待选 botKind 流程。由 plugin.ts setup() provide,
|
|
4
|
+
* adapter create 与 commands / middleware 通过 use(qqRuntimeStateToken) 共享。
|
|
5
5
|
*/
|
|
6
6
|
import { createToken } from '@zhin.js/plugin-runtime';
|
|
7
7
|
export function createQqRuntimeState() {
|
|
8
8
|
return {
|
|
9
9
|
endpoints: new Map(),
|
|
10
10
|
bindFlow: null,
|
|
11
|
+
pendingBotKind: null,
|
|
11
12
|
};
|
|
12
13
|
}
|
|
13
14
|
export const qqRuntimeStateToken = createToken('zhin.qq.runtime-state', 'QQ adapter runtime state (running endpoints + bind flow singleton)');
|
package/lib/webhook.js
CHANGED
|
@@ -60,6 +60,8 @@ export function defaultCreateHttpBot(config) {
|
|
|
60
60
|
platform: 'koa',
|
|
61
61
|
sandbox: config.sandbox,
|
|
62
62
|
dataDir: path.join(process.cwd(), 'data', 'qq'),
|
|
63
|
+
// 关闭内置 log4js,与 WebSocket 模式一致走 zhin adapter logger
|
|
64
|
+
logLevel: 'off',
|
|
63
65
|
});
|
|
64
66
|
return {
|
|
65
67
|
start: () => bot.start().then(() => undefined),
|
package/lib/ws.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { Bot, ReceiverMode } from 'qq-official-bot';
|
|
6
|
-
import { getLevel, toLog4jsLevel } from '@zhin.js/logger';
|
|
7
6
|
/**
|
|
8
7
|
* qq-official-bot 1.2.x keeps a second `userClose` flag in Connection.
|
|
9
8
|
* Session.stop() does not update it, so a normal shutdown is treated as an
|
|
@@ -190,7 +189,8 @@ export function defaultCreateBot(config) {
|
|
|
190
189
|
mode: ReceiverMode.WEBSOCKET,
|
|
191
190
|
sandbox: config.sandbox,
|
|
192
191
|
dataDir: path.join(process.cwd(), 'data', 'qq'),
|
|
193
|
-
|
|
192
|
+
// 关闭 qq-official-bot 内置 log4js,入/出站由 getAdapterLogger('qq', …) 统一格式
|
|
193
|
+
logLevel: 'off',
|
|
194
194
|
...(config.intents ? { intents: config.intents } : {}),
|
|
195
195
|
...(config.accessTokenUrl ? { accessTokenUrl: config.accessTokenUrl } : {}),
|
|
196
196
|
...(config.gatewayUrl ? { gatewayUrl: config.gatewayUrl } : {}),
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
|
+
import { defineMiddleware } from '@zhin.js/middleware';
|
|
3
|
+
import { completeQqPendingBotKind, } from "../lib/qq-endpoint-commands.js";
|
|
4
|
+
import { parseQqBotKindAnswer, qqCommandSessionKey, QQ_BOT_KIND_PROMPT, } from "../lib/qq-bot-kind-prompt.js";
|
|
5
|
+
import { qqRuntimeStateToken } from "../lib/qq-runtime-state.js";
|
|
6
|
+
/**
|
|
7
|
+
* 扫码绑定成功后,在同一会话收取 public/private(或 公域/私域)回复并写入 intents。
|
|
8
|
+
* 非待确认会话、或内容无法识别为 botKind 时放行后续中间件/命令。
|
|
9
|
+
*/
|
|
10
|
+
export default defineMiddleware({
|
|
11
|
+
target: 'inbound',
|
|
12
|
+
phase: 'before-dispatch',
|
|
13
|
+
order: -50,
|
|
14
|
+
async handle(context, next) {
|
|
15
|
+
const state = context.use(qqRuntimeStateToken);
|
|
16
|
+
const pending = state.pendingBotKind;
|
|
17
|
+
if (!pending) {
|
|
18
|
+
await next();
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const sessionKey = qqCommandSessionKey(context.input);
|
|
22
|
+
if (!sessionKey || sessionKey !== pending.sessionKey) {
|
|
23
|
+
await next();
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const raw = String(context.input.content ?? '').trim();
|
|
27
|
+
// 让 qq.endpoint cancel 等命令继续走命令链
|
|
28
|
+
if (raw.toLowerCase().startsWith('qq.endpoint')) {
|
|
29
|
+
await next();
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const botKind = parseQqBotKindAnswer(raw);
|
|
33
|
+
if (!botKind) {
|
|
34
|
+
await context.input.$reply?.(`未识别「${raw}」。${QQ_BOT_KIND_PROMPT}`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const text = completeQqPendingBotKind(pending, botKind);
|
|
39
|
+
state.pendingBotKind = null;
|
|
40
|
+
await context.input.$reply?.(text);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
await context.input.$reply?.(`写入配置失败:${error instanceof Error ? error.message : String(error)}`);
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { defineMiddleware } from '@zhin.js/middleware';
|
|
2
|
+
import type { CommandMessage } from '@zhin.js/command';
|
|
3
|
+
import {
|
|
4
|
+
completeQqPendingBotKind,
|
|
5
|
+
} from '../src/qq-endpoint-commands.js';
|
|
6
|
+
import {
|
|
7
|
+
parseQqBotKindAnswer,
|
|
8
|
+
qqCommandSessionKey,
|
|
9
|
+
QQ_BOT_KIND_PROMPT,
|
|
10
|
+
} from '../src/qq-bot-kind-prompt.js';
|
|
11
|
+
import { qqRuntimeStateToken } from '../src/qq-runtime-state.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 扫码绑定成功后,在同一会话收取 public/private(或 公域/私域)回复并写入 intents。
|
|
15
|
+
* 非待确认会话、或内容无法识别为 botKind 时放行后续中间件/命令。
|
|
16
|
+
*/
|
|
17
|
+
export default defineMiddleware<CommandMessage>({
|
|
18
|
+
target: 'inbound',
|
|
19
|
+
phase: 'before-dispatch',
|
|
20
|
+
order: -50,
|
|
21
|
+
async handle(context, next) {
|
|
22
|
+
const state = context.use(qqRuntimeStateToken);
|
|
23
|
+
const pending = state.pendingBotKind;
|
|
24
|
+
if (!pending) {
|
|
25
|
+
await next();
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const sessionKey = qqCommandSessionKey(context.input);
|
|
30
|
+
if (!sessionKey || sessionKey !== pending.sessionKey) {
|
|
31
|
+
await next();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const raw = String(context.input.content ?? '').trim();
|
|
36
|
+
// 让 qq.endpoint cancel 等命令继续走命令链
|
|
37
|
+
if (raw.toLowerCase().startsWith('qq.endpoint')) {
|
|
38
|
+
await next();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const botKind = parseQqBotKindAnswer(raw);
|
|
43
|
+
if (!botKind) {
|
|
44
|
+
await context.input.$reply?.(
|
|
45
|
+
`未识别「${raw}」。${QQ_BOT_KIND_PROMPT}`,
|
|
46
|
+
);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
const text = completeQqPendingBotKind(pending, botKind);
|
|
52
|
+
state.pendingBotKind = null;
|
|
53
|
+
await context.input.$reply?.(text);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
await context.input.$reply?.(
|
|
56
|
+
`写入配置失败:${error instanceof Error ? error.message : String(error)}`,
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/adapter-qq",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.5",
|
|
4
4
|
"description": "Zhin.js QQ Official adapter for Plugin Runtime (WebSocket gateway)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -35,20 +35,23 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"qq-official-bot": "^1.2.3",
|
|
38
|
-
"@zhin.js/adapter": "1.1.
|
|
39
|
-
"@zhin.js/command": "1.0.
|
|
40
|
-
"@zhin.js/core": "1.5.
|
|
41
|
-
"@zhin.js/host-http": "1.0.
|
|
42
|
-
"@zhin.js/
|
|
43
|
-
"@zhin.js/
|
|
38
|
+
"@zhin.js/adapter": "1.1.7",
|
|
39
|
+
"@zhin.js/command": "1.0.9",
|
|
40
|
+
"@zhin.js/core": "1.5.4",
|
|
41
|
+
"@zhin.js/host-http": "1.0.8",
|
|
42
|
+
"@zhin.js/im-contract": "1.0.3",
|
|
43
|
+
"@zhin.js/logger": "1.0.76",
|
|
44
|
+
"@zhin.js/middleware": "1.0.8",
|
|
45
|
+
"@zhin.js/permission": "1.0.1",
|
|
46
|
+
"@zhin.js/plugin-runtime": "1.1.5"
|
|
44
47
|
},
|
|
45
48
|
"peerDependencies": {
|
|
46
49
|
"zod": "^4.0.0",
|
|
47
|
-
"@zhin.js/adapter": "1.1.
|
|
48
|
-
"@zhin.js/agent": "1.1.
|
|
49
|
-
"@zhin.js/core": "1.5.
|
|
50
|
-
"@zhin.js/plugin-runtime": "1.1.
|
|
51
|
-
"zhin.js": "6.0.
|
|
50
|
+
"@zhin.js/adapter": "1.1.7",
|
|
51
|
+
"@zhin.js/agent": "1.1.5",
|
|
52
|
+
"@zhin.js/core": "1.5.4",
|
|
53
|
+
"@zhin.js/plugin-runtime": "1.1.5",
|
|
54
|
+
"zhin.js": "6.0.4"
|
|
52
55
|
},
|
|
53
56
|
"peerDependenciesMeta": {
|
|
54
57
|
"zhin.js": {
|
|
@@ -66,13 +69,14 @@
|
|
|
66
69
|
"typescript": "^6.0.3",
|
|
67
70
|
"vitest": "^4.1.10",
|
|
68
71
|
"zod": "^4.4.3",
|
|
69
|
-
"@zhin.js/agent": "1.1.
|
|
70
|
-
"@zhin.js/host-http": "1.0.
|
|
71
|
-
"zhin.js": "6.0.
|
|
72
|
+
"@zhin.js/agent": "1.1.5",
|
|
73
|
+
"@zhin.js/host-http": "1.0.8",
|
|
74
|
+
"zhin.js": "6.0.4"
|
|
72
75
|
},
|
|
73
76
|
"files": [
|
|
74
77
|
"adapters",
|
|
75
78
|
"commands",
|
|
79
|
+
"middlewares",
|
|
76
80
|
"plugin.js",
|
|
77
81
|
"schema.json",
|
|
78
82
|
"src",
|
|
@@ -102,6 +106,10 @@
|
|
|
102
106
|
{
|
|
103
107
|
"package": "@zhin.js/command",
|
|
104
108
|
"api": "^1.0.0"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"package": "@zhin.js/middleware",
|
|
112
|
+
"api": "^1.0.0"
|
|
105
113
|
}
|
|
106
114
|
],
|
|
107
115
|
"plugins": []
|
package/plugin.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
2
|
import { definePlugin } from '@zhin.js/plugin-runtime';
|
|
3
|
-
import {
|
|
3
|
+
import { permissionHostToken } from '@zhin.js/permission';
|
|
4
|
+
import { checkQqPlatformPermit } from "./lib/platform-permit.js";
|
|
4
5
|
import { createQqRuntimeState, qqRuntimeStateToken } from "./lib/qq-runtime-state.js";
|
|
5
6
|
export default definePlugin({
|
|
6
7
|
name: 'qq',
|
|
@@ -8,9 +9,10 @@ export default definePlugin({
|
|
|
8
9
|
displayName: 'QQ Official WebSocket Adapter',
|
|
9
10
|
},
|
|
10
11
|
setup(context) {
|
|
11
|
-
// 运行中 endpoint 注册表 + 扫码绑定单例,供 adapter create 与 `qq.endpoint` 命令共享
|
|
12
12
|
context.resources.provide(qqRuntimeStateToken, createQqRuntimeState());
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
if (context.resources.has(permissionHostToken)) {
|
|
14
|
+
const host = context.resources.use(permissionHostToken);
|
|
15
|
+
return host.registerPlatform('qq', checkQqPlatformPermit);
|
|
16
|
+
}
|
|
15
17
|
},
|
|
16
18
|
});
|
package/schema.json
CHANGED
|
@@ -17,15 +17,39 @@
|
|
|
17
17
|
"type": "boolean",
|
|
18
18
|
"default": false
|
|
19
19
|
},
|
|
20
|
+
"botKind": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"enum": [
|
|
23
|
+
"public",
|
|
24
|
+
"private"
|
|
25
|
+
],
|
|
26
|
+
"default": "public",
|
|
27
|
+
"description": "公域/私域:均含 GROUP_AND_C2C_EVENT;频道消息分别为 PUBLIC_GUILD_MESSAGES / GUILD_MESSAGES。未显式配置 intents 时按此展开"
|
|
28
|
+
},
|
|
20
29
|
"master": {
|
|
21
|
-
"type": [
|
|
22
|
-
|
|
30
|
+
"type": [
|
|
31
|
+
"string",
|
|
32
|
+
"number"
|
|
33
|
+
],
|
|
34
|
+
"description": "框架 master(endpoint 管理命令、AI/工具权限);openid。endpoints[i].master 可逐项覆盖"
|
|
35
|
+
},
|
|
36
|
+
"trusted": {
|
|
37
|
+
"type": "array",
|
|
38
|
+
"items": {
|
|
39
|
+
"type": [
|
|
40
|
+
"string",
|
|
41
|
+
"number"
|
|
42
|
+
],
|
|
43
|
+
"description": "Trusted openid"
|
|
44
|
+
},
|
|
45
|
+
"description": "框架 trusted 用户列表(弱于 master)。endpoints[i].trusted 可逐项追加"
|
|
23
46
|
},
|
|
24
47
|
"intents": {
|
|
25
48
|
"type": "array",
|
|
26
49
|
"items": {
|
|
27
50
|
"type": "string"
|
|
28
|
-
}
|
|
51
|
+
},
|
|
52
|
+
"description": "WebSocket Identify intents;省略时按 botKind 自动生成(public→含 PUBLIC_GUILD_MESSAGES)"
|
|
29
53
|
},
|
|
30
54
|
"accessTokenUrl": {
|
|
31
55
|
"type": "string"
|
|
@@ -48,15 +72,11 @@
|
|
|
48
72
|
},
|
|
49
73
|
"endpoints": {
|
|
50
74
|
"type": "array",
|
|
51
|
-
"description": "多账号:一个插件实例挂多个 endpoint。每项与顶层字段同构(
|
|
75
|
+
"description": "多账号:一个插件实例挂多个 endpoint。每项与顶层字段同构(id 必填,其余覆盖顶层)",
|
|
52
76
|
"items": {
|
|
53
77
|
"type": "object",
|
|
54
78
|
"additionalProperties": true,
|
|
55
79
|
"properties": {
|
|
56
|
-
"name": {
|
|
57
|
-
"type": "string",
|
|
58
|
-
"description": "QQ bot name"
|
|
59
|
-
},
|
|
60
80
|
"appid": {
|
|
61
81
|
"type": "string",
|
|
62
82
|
"description": "QQ official bot app ID"
|
|
@@ -64,10 +84,47 @@
|
|
|
64
84
|
"secret": {
|
|
65
85
|
"type": "string",
|
|
66
86
|
"description": "QQ official bot secret"
|
|
87
|
+
},
|
|
88
|
+
"master": {
|
|
89
|
+
"type": [
|
|
90
|
+
"string",
|
|
91
|
+
"number"
|
|
92
|
+
],
|
|
93
|
+
"description": "本 endpoint 的框架 master(openid);覆盖顶层 master"
|
|
94
|
+
},
|
|
95
|
+
"trusted": {
|
|
96
|
+
"type": "array",
|
|
97
|
+
"items": {
|
|
98
|
+
"type": [
|
|
99
|
+
"string",
|
|
100
|
+
"number"
|
|
101
|
+
],
|
|
102
|
+
"description": "Trusted openid"
|
|
103
|
+
},
|
|
104
|
+
"description": "本 endpoint 的 trusted 列表"
|
|
105
|
+
},
|
|
106
|
+
"botKind": {
|
|
107
|
+
"type": "string",
|
|
108
|
+
"enum": [
|
|
109
|
+
"public",
|
|
110
|
+
"private"
|
|
111
|
+
],
|
|
112
|
+
"description": "覆盖顶层 botKind(公域/私域),用于按 endpoint 生成 intents"
|
|
113
|
+
},
|
|
114
|
+
"intents": {
|
|
115
|
+
"type": "array",
|
|
116
|
+
"items": {
|
|
117
|
+
"type": "string"
|
|
118
|
+
},
|
|
119
|
+
"description": "覆盖顶层 intents"
|
|
120
|
+
},
|
|
121
|
+
"id": {
|
|
122
|
+
"type": "string",
|
|
123
|
+
"description": "QQ bot name"
|
|
67
124
|
}
|
|
68
125
|
},
|
|
69
126
|
"required": [
|
|
70
|
-
"
|
|
127
|
+
"id",
|
|
71
128
|
"appid",
|
|
72
129
|
"secret"
|
|
73
130
|
]
|