@zhin.js/adapter-icqq 6.0.3 → 7.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.
@@ -0,0 +1,129 @@
1
+ /** post_type=request / request.* 判定(OneBot 事件壳)。 */
2
+ export function isIcqqRequestPayload(payload) {
3
+ const postType = payload?.post_type;
4
+ return typeof postType === 'string'
5
+ && (postType === 'request' || postType.startsWith('request.'));
6
+ }
7
+ /** post_type=notice / notice.* 判定。 */
8
+ export function isIcqqNoticePayload(payload) {
9
+ const postType = payload?.post_type;
10
+ return typeof postType === 'string'
11
+ && (postType === 'notice' || postType.startsWith('notice.'));
12
+ }
13
+ /**
14
+ * request 事件载荷 → unified_inbox_request 行。
15
+ * platform_request_id 取 flag(审批回执句柄),缺省回退 seq;两者皆无则无法审批,丢弃。
16
+ */
17
+ export function buildIcqqInboxRequestRow(payload, base) {
18
+ const userId = payload.user_id ?? payload.actor_id;
19
+ if (userId == null)
20
+ return null;
21
+ const flag = asNonEmptyString(payload.flag);
22
+ const platformRequestId = flag ?? (payload.seq != null ? String(payload.seq) : '');
23
+ if (!platformRequestId)
24
+ return null;
25
+ const requestType = asNonEmptyString(payload.request_type) ?? asNonEmptyString(payload.type);
26
+ const groupId = payload.group_id;
27
+ const isGroup = requestType === 'group' || groupId != null;
28
+ return {
29
+ adapter: base.adapter,
30
+ endpoint_id: base.endpointId,
31
+ platform_request_id: platformRequestId,
32
+ type: isGroup ? 'group' : (requestType ?? 'friend'),
33
+ scene_type: isGroup ? 'group' : null,
34
+ scene_id: String(groupId ?? userId),
35
+ sub_type: asNonEmptyString(payload.sub_type),
36
+ actor_id: String(userId),
37
+ actor_name: asNonEmptyString(payload.nickname),
38
+ comment: asNonEmptyString(payload.comment),
39
+ created_at: toMillis(payload.time),
40
+ resolved: 0,
41
+ resolved_at: null,
42
+ consumed: 0,
43
+ consumed_at: null,
44
+ };
45
+ }
46
+ /**
47
+ * notice 事件载荷 → unified_inbox_notice 行。
48
+ * 事件本身无稳定 id,platform_notice_id 由 time + actor + type 合成(配合去重)。
49
+ */
50
+ export function buildIcqqInboxNoticeRow(payload, base) {
51
+ const noticeType = asNonEmptyString(payload.notice_type) ?? asNonEmptyString(payload.type);
52
+ if (!noticeType)
53
+ return null;
54
+ const subType = asNonEmptyString(payload.sub_type);
55
+ const userId = payload.user_id;
56
+ const operatorId = payload.operator_id;
57
+ const groupId = payload.group_id;
58
+ const createdAt = toMillis(payload.time);
59
+ const actorId = operatorId ?? userId;
60
+ const platformNoticeId = asNonEmptyString(payload.notice_id)
61
+ ?? (payload.seq != null ? String(payload.seq) : undefined)
62
+ ?? `${createdAt}_${String(actorId ?? '')}_${noticeType}${subType ? `.${subType}` : ''}`;
63
+ const targetId = userId != null && String(userId) !== String(actorId ?? '') ? userId : undefined;
64
+ return {
65
+ adapter: base.adapter,
66
+ endpoint_id: base.endpointId,
67
+ platform_notice_id: platformNoticeId,
68
+ type: noticeType,
69
+ scene_type: groupId != null ? 'group' : null,
70
+ scene_id: String(groupId ?? userId ?? operatorId ?? ''),
71
+ sub_type: subType,
72
+ actor_id: actorId != null ? String(actorId) : null,
73
+ actor_name: asNonEmptyString(payload.nickname),
74
+ target_id: targetId != null ? String(targetId) : null,
75
+ target_name: null,
76
+ payload: safeJson(payload),
77
+ created_at: createdAt,
78
+ consumed: 0,
79
+ consumed_at: null,
80
+ };
81
+ }
82
+ /**
83
+ * GET_SYSTEM_MSG 返回项 → unified_inbox_request 行(启动时首次拉取)。
84
+ * friend 列表项 type 语义即好友请求;group 列表项 type 为 add/invite(记 sub_type)。
85
+ */
86
+ export function buildIcqqSystemRequestRow(message, kind, base) {
87
+ if (message.user_id == null)
88
+ return null;
89
+ const platformRequestId = asNonEmptyString(message.flag)
90
+ ?? (message.seq != null ? String(message.seq) : '');
91
+ if (!platformRequestId)
92
+ return null;
93
+ return {
94
+ adapter: base.adapter,
95
+ endpoint_id: base.endpointId,
96
+ platform_request_id: platformRequestId,
97
+ type: kind,
98
+ scene_type: kind === 'group' ? 'group' : null,
99
+ scene_id: String(kind === 'group' ? (message.group_id ?? message.user_id) : message.user_id),
100
+ sub_type: kind === 'group' ? (asNonEmptyString(message.type) ?? null) : null,
101
+ actor_id: String(message.user_id),
102
+ actor_name: asNonEmptyString(message.nickname),
103
+ comment: asNonEmptyString(message.comment),
104
+ created_at: toMillis(message.time),
105
+ resolved: 0,
106
+ resolved_at: null,
107
+ consumed: 0,
108
+ consumed_at: null,
109
+ };
110
+ }
111
+ function asNonEmptyString(value) {
112
+ if (typeof value !== 'string')
113
+ return null;
114
+ const trimmed = value.trim();
115
+ return trimmed ? trimmed : null;
116
+ }
117
+ /** oicq 事件 time 为秒;缺失时回退当前时间。 */
118
+ function toMillis(time) {
119
+ const seconds = Number(time);
120
+ return Number.isFinite(seconds) && seconds > 0 ? seconds * 1000 : Date.now();
121
+ }
122
+ function safeJson(value) {
123
+ try {
124
+ return JSON.stringify(value ?? {});
125
+ }
126
+ catch {
127
+ return '{}';
128
+ }
129
+ }
package/lib/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { Actions, formatInboundContent, formatInboundTarget, formatOutboundBody, parseSendTarget, resolveIcqqConfig, type IcqqAdapterConfig, type IcqqInboundMessage, type IcqqWireSegment, type IpcEvent, type IpcMessage, type IpcRequest, type IpcResponse, type ParsedIcqqSendTarget, type ResolvedIcqqConfig, } from './protocol.js';
2
- export { IcqqIpcEndpoint, type CreateIcqqIpc, type IcqqEndpointOptions, type IcqqIpcTransport, } from './endpoint.js';
2
+ export { IcqqIpcEndpoint, type CreateIcqqIpc, type IcqqEndpointOptions, type IcqqInboxHooks, type IcqqIpcTransport, } from './endpoint.js';
3
3
  export * from './types.js';
4
4
  export { getIcqqAgentDeps, registerIcqqAgentEndpoint, setIcqqAgentDeps, type IcqqAgentDeps, type IcqqAgentEndpoint, } from './icqq-agent-deps.js';
5
5
  export { IpcClient } from './ipc-client.js';
package/lib/types.d.ts CHANGED
@@ -70,3 +70,18 @@ export interface IpcMemberInfo {
70
70
  last_sent_time?: number;
71
71
  shutup_time?: number;
72
72
  }
73
+ /**
74
+ * GET_SYSTEM_MSG 归一后的待处理请求(@icqqjs/cli NormalizedSystemMessage)。
75
+ * friendRequests 与 groupRequests 均为该形状,按 flag 处理。
76
+ */
77
+ export interface IpcSystemMessage {
78
+ type: string;
79
+ user_id?: number;
80
+ nickname?: string;
81
+ group_id?: number;
82
+ group_name?: string;
83
+ comment?: string;
84
+ flag?: string;
85
+ seq?: number;
86
+ time?: number;
87
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/adapter-icqq",
3
- "version": "6.0.3",
3
+ "version": "7.0.0",
4
4
  "description": "Zhin.js ICQQ adapter for Plugin Runtime (IPC daemon client)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -34,18 +34,18 @@
34
34
  "directory": "plugins/adapters/icqq"
35
35
  },
36
36
  "dependencies": {
37
- "@zhin.js/adapter": "1.0.1",
38
- "@zhin.js/core": "1.3.5",
37
+ "@zhin.js/adapter": "1.1.0",
38
+ "@zhin.js/core": "1.4.0",
39
39
  "@zhin.js/logger": "1.0.75",
40
- "@zhin.js/plugin-runtime": "1.0.1"
40
+ "@zhin.js/plugin-runtime": "1.1.0"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "zod": "^4.0.0",
44
- "@zhin.js/adapter": "1.0.1",
45
- "@zhin.js/agent": "1.0.4",
46
- "@zhin.js/core": "1.3.5",
47
- "@zhin.js/plugin-runtime": "1.0.1",
48
- "zhin.js": "4.1.3"
44
+ "@zhin.js/adapter": "1.1.0",
45
+ "@zhin.js/agent": "1.0.5",
46
+ "@zhin.js/core": "1.4.0",
47
+ "@zhin.js/plugin-runtime": "1.1.0",
48
+ "zhin.js": "5.0.0"
49
49
  },
50
50
  "peerDependenciesMeta": {
51
51
  "zhin.js": {
@@ -63,8 +63,8 @@
63
63
  "typescript": "^6.0.3",
64
64
  "vitest": "^4.1.10",
65
65
  "zod": "^4.4.3",
66
- "@zhin.js/agent": "1.0.4",
67
- "zhin.js": "4.1.3"
66
+ "@zhin.js/agent": "1.0.5",
67
+ "zhin.js": "5.0.0"
68
68
  },
69
69
  "files": [
70
70
  "adapters",
package/schema.json CHANGED
@@ -3,33 +3,102 @@
3
3
  "type": "object",
4
4
  "additionalProperties": false,
5
5
  "properties": {
6
- "name": {
7
- "type": "string",
8
- "description": "QQ uin (must match icqq login account)"
9
- },
10
6
  "master": {
11
- "type": ["string", "number"],
7
+ "type": [
8
+ "string",
9
+ "number"
10
+ ],
12
11
  "description": "Endpoint Owner QQ uin (for /approve bash and master role)"
13
12
  },
13
+ "trusted": {
14
+ "type": "array",
15
+ "items": {
16
+ "type": [
17
+ "string",
18
+ "number"
19
+ ],
20
+ "description": "Trusted QQ uin"
21
+ },
22
+ "description": "Trusted QQ uin list"
23
+ },
14
24
  "autoReconnect": {
15
25
  "type": "boolean",
16
26
  "default": true
17
27
  },
18
28
  "outboundMedia": {
19
29
  "type": "string",
20
- "enum": ["file", "base64"],
30
+ "enum": [
31
+ "file",
32
+ "base64"
33
+ ],
21
34
  "description": "file=local path (same host as daemon); base64=CQ base64:// (default when rpc set)"
22
35
  },
23
- "rpc": {
24
- "type": "object",
25
- "additionalProperties": false,
26
- "properties": {
27
- "host": { "type": "string" },
28
- "port": { "type": "number" },
29
- "token": { "type": "string" }
30
- },
31
- "required": ["host", "port", "token"]
36
+ "endpoints": {
37
+ "type": "array",
38
+ "description": "多账号:一个插件实例挂多个 endpoint。每项与顶层字段同构(name 必填,其余覆盖顶层)",
39
+ "items": {
40
+ "type": "object",
41
+ "additionalProperties": true,
42
+ "properties": {
43
+ "name": {
44
+ "type": "string",
45
+ "description": "QQ uin (must match icqq login account)"
46
+ },
47
+ "master": {
48
+ "type": [
49
+ "string",
50
+ "number"
51
+ ],
52
+ "description": "Endpoint Owner QQ uin (for /approve bash and master role)"
53
+ },
54
+ "trusted": {
55
+ "type": "array",
56
+ "items": {
57
+ "type": [
58
+ "string",
59
+ "number"
60
+ ],
61
+ "description": "Trusted QQ uin"
62
+ },
63
+ "description": "Trusted QQ uin list"
64
+ },
65
+ "rpc": {
66
+ "type": "object",
67
+ "additionalProperties": false,
68
+ "properties": {
69
+ "host": {
70
+ "type": "string",
71
+ "description": "RPC host"
72
+ },
73
+ "port": {
74
+ "type": "number",
75
+ "description": "RPC port"
76
+ },
77
+ "token": {
78
+ "type": "string",
79
+ "description": "RPC token"
80
+ }
81
+ },
82
+ "required": [
83
+ "host",
84
+ "port",
85
+ "token"
86
+ ]
87
+ }
88
+ },
89
+ "required": [
90
+ "name"
91
+ ]
92
+ }
93
+ },
94
+ "commandPrefix": {
95
+ "type": "string",
96
+ "default": "",
97
+ "description": "命令前缀(默认 '' 无前缀,任意文本按命令匹配;如 '/' 要求 / 开头)。endpoints[i] 可逐项覆盖"
32
98
  }
33
99
  },
34
- "required": ["name"]
35
- }
100
+ "required": [
101
+ "master",
102
+ "endpoints"
103
+ ]
104
+ }