@ryantest/openclaw-qqbot 0.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.
Files changed (197) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +483 -0
  3. package/README.zh.md +478 -0
  4. package/bin/qqbot-cli.js +243 -0
  5. package/clawdbot.plugin.json +16 -0
  6. package/dist/index.d.ts +17 -0
  7. package/dist/index.js +26 -0
  8. package/dist/src/admin-resolver.d.ts +27 -0
  9. package/dist/src/admin-resolver.js +122 -0
  10. package/dist/src/api.d.ts +156 -0
  11. package/dist/src/api.js +599 -0
  12. package/dist/src/channel.d.ts +11 -0
  13. package/dist/src/channel.js +354 -0
  14. package/dist/src/config.d.ts +25 -0
  15. package/dist/src/config.js +161 -0
  16. package/dist/src/credential-backup.d.ts +31 -0
  17. package/dist/src/credential-backup.js +66 -0
  18. package/dist/src/gateway.d.ts +18 -0
  19. package/dist/src/gateway.js +1265 -0
  20. package/dist/src/image-server.d.ts +68 -0
  21. package/dist/src/image-server.js +462 -0
  22. package/dist/src/inbound-attachments.d.ts +58 -0
  23. package/dist/src/inbound-attachments.js +234 -0
  24. package/dist/src/known-users.d.ts +100 -0
  25. package/dist/src/known-users.js +263 -0
  26. package/dist/src/message-queue.d.ts +50 -0
  27. package/dist/src/message-queue.js +115 -0
  28. package/dist/src/onboarding.d.ts +10 -0
  29. package/dist/src/onboarding.js +203 -0
  30. package/dist/src/outbound-deliver.d.ts +48 -0
  31. package/dist/src/outbound-deliver.js +462 -0
  32. package/dist/src/outbound.d.ts +203 -0
  33. package/dist/src/outbound.js +1102 -0
  34. package/dist/src/proactive.d.ts +170 -0
  35. package/dist/src/proactive.js +399 -0
  36. package/dist/src/ref-index-store.d.ts +70 -0
  37. package/dist/src/ref-index-store.js +273 -0
  38. package/dist/src/reply-dispatcher.d.ts +35 -0
  39. package/dist/src/reply-dispatcher.js +311 -0
  40. package/dist/src/runtime.d.ts +3 -0
  41. package/dist/src/runtime.js +10 -0
  42. package/dist/src/session-store.d.ts +52 -0
  43. package/dist/src/session-store.js +254 -0
  44. package/dist/src/slash-commands.d.ts +71 -0
  45. package/dist/src/slash-commands.js +1179 -0
  46. package/dist/src/startup-greeting.d.ts +30 -0
  47. package/dist/src/startup-greeting.js +78 -0
  48. package/dist/src/stt.d.ts +21 -0
  49. package/dist/src/stt.js +70 -0
  50. package/dist/src/tools/channel.d.ts +16 -0
  51. package/dist/src/tools/channel.js +234 -0
  52. package/dist/src/tools/remind.d.ts +2 -0
  53. package/dist/src/tools/remind.js +247 -0
  54. package/dist/src/types.d.ts +175 -0
  55. package/dist/src/types.js +1 -0
  56. package/dist/src/typing-keepalive.d.ts +27 -0
  57. package/dist/src/typing-keepalive.js +64 -0
  58. package/dist/src/update-checker.d.ts +34 -0
  59. package/dist/src/update-checker.js +166 -0
  60. package/dist/src/user-messages.d.ts +8 -0
  61. package/dist/src/user-messages.js +8 -0
  62. package/dist/src/utils/audio-convert.d.ts +89 -0
  63. package/dist/src/utils/audio-convert.js +704 -0
  64. package/dist/src/utils/file-utils.d.ts +55 -0
  65. package/dist/src/utils/file-utils.js +150 -0
  66. package/dist/src/utils/image-size.d.ts +51 -0
  67. package/dist/src/utils/image-size.js +234 -0
  68. package/dist/src/utils/media-tags.d.ts +14 -0
  69. package/dist/src/utils/media-tags.js +164 -0
  70. package/dist/src/utils/payload.d.ts +112 -0
  71. package/dist/src/utils/payload.js +186 -0
  72. package/dist/src/utils/platform.d.ts +137 -0
  73. package/dist/src/utils/platform.js +390 -0
  74. package/dist/src/utils/text-parsing.d.ts +32 -0
  75. package/dist/src/utils/text-parsing.js +80 -0
  76. package/dist/src/utils/upload-cache.d.ts +34 -0
  77. package/dist/src/utils/upload-cache.js +93 -0
  78. package/index.ts +31 -0
  79. package/moltbot.plugin.json +16 -0
  80. package/node_modules/@eshaz/web-worker/LICENSE +201 -0
  81. package/node_modules/@eshaz/web-worker/README.md +134 -0
  82. package/node_modules/@eshaz/web-worker/browser.js +17 -0
  83. package/node_modules/@eshaz/web-worker/cjs/browser.js +16 -0
  84. package/node_modules/@eshaz/web-worker/cjs/node.js +219 -0
  85. package/node_modules/@eshaz/web-worker/index.d.ts +4 -0
  86. package/node_modules/@eshaz/web-worker/node.js +223 -0
  87. package/node_modules/@eshaz/web-worker/package.json +54 -0
  88. package/node_modules/@wasm-audio-decoders/common/index.js +5 -0
  89. package/node_modules/@wasm-audio-decoders/common/package.json +36 -0
  90. package/node_modules/@wasm-audio-decoders/common/src/WASMAudioDecoderCommon.js +231 -0
  91. package/node_modules/@wasm-audio-decoders/common/src/WASMAudioDecoderWorker.js +129 -0
  92. package/node_modules/@wasm-audio-decoders/common/src/puff/README +67 -0
  93. package/node_modules/@wasm-audio-decoders/common/src/puff/build_puff.js +31 -0
  94. package/node_modules/@wasm-audio-decoders/common/src/puff/puff.c +863 -0
  95. package/node_modules/@wasm-audio-decoders/common/src/puff/puff.h +35 -0
  96. package/node_modules/@wasm-audio-decoders/common/src/utilities.js +3 -0
  97. package/node_modules/@wasm-audio-decoders/common/types.d.ts +7 -0
  98. package/node_modules/mpg123-decoder/README.md +265 -0
  99. package/node_modules/mpg123-decoder/dist/mpg123-decoder.min.js +185 -0
  100. package/node_modules/mpg123-decoder/dist/mpg123-decoder.min.js.map +1 -0
  101. package/node_modules/mpg123-decoder/index.js +8 -0
  102. package/node_modules/mpg123-decoder/package.json +58 -0
  103. package/node_modules/mpg123-decoder/src/EmscriptenWasm.js +464 -0
  104. package/node_modules/mpg123-decoder/src/MPEGDecoder.js +200 -0
  105. package/node_modules/mpg123-decoder/src/MPEGDecoderWebWorker.js +21 -0
  106. package/node_modules/mpg123-decoder/types.d.ts +30 -0
  107. package/node_modules/silk-wasm/LICENSE +21 -0
  108. package/node_modules/silk-wasm/README.md +85 -0
  109. package/node_modules/silk-wasm/lib/index.cjs +16 -0
  110. package/node_modules/silk-wasm/lib/index.d.ts +70 -0
  111. package/node_modules/silk-wasm/lib/index.mjs +16 -0
  112. package/node_modules/silk-wasm/lib/silk.wasm +0 -0
  113. package/node_modules/silk-wasm/lib/utils.d.ts +4 -0
  114. package/node_modules/silk-wasm/package.json +39 -0
  115. package/node_modules/simple-yenc/.github/FUNDING.yml +1 -0
  116. package/node_modules/simple-yenc/.prettierignore +1 -0
  117. package/node_modules/simple-yenc/LICENSE +7 -0
  118. package/node_modules/simple-yenc/README.md +163 -0
  119. package/node_modules/simple-yenc/dist/esm.js +1 -0
  120. package/node_modules/simple-yenc/dist/index.js +1 -0
  121. package/node_modules/simple-yenc/package.json +50 -0
  122. package/node_modules/simple-yenc/rollup.config.js +27 -0
  123. package/node_modules/simple-yenc/src/simple-yenc.js +302 -0
  124. package/node_modules/ws/LICENSE +20 -0
  125. package/node_modules/ws/README.md +548 -0
  126. package/node_modules/ws/browser.js +8 -0
  127. package/node_modules/ws/index.js +13 -0
  128. package/node_modules/ws/lib/buffer-util.js +131 -0
  129. package/node_modules/ws/lib/constants.js +19 -0
  130. package/node_modules/ws/lib/event-target.js +292 -0
  131. package/node_modules/ws/lib/extension.js +203 -0
  132. package/node_modules/ws/lib/limiter.js +55 -0
  133. package/node_modules/ws/lib/permessage-deflate.js +528 -0
  134. package/node_modules/ws/lib/receiver.js +706 -0
  135. package/node_modules/ws/lib/sender.js +602 -0
  136. package/node_modules/ws/lib/stream.js +161 -0
  137. package/node_modules/ws/lib/subprotocol.js +62 -0
  138. package/node_modules/ws/lib/validation.js +152 -0
  139. package/node_modules/ws/lib/websocket-server.js +554 -0
  140. package/node_modules/ws/lib/websocket.js +1393 -0
  141. package/node_modules/ws/package.json +69 -0
  142. package/node_modules/ws/wrapper.mjs +8 -0
  143. package/openclaw.plugin.json +16 -0
  144. package/package.json +76 -0
  145. package/scripts/cleanup-legacy-plugins.sh +124 -0
  146. package/scripts/proactive-api-server.ts +369 -0
  147. package/scripts/send-proactive.ts +293 -0
  148. package/scripts/set-markdown.sh +156 -0
  149. package/scripts/test-sendmedia.ts +116 -0
  150. package/scripts/upgrade-via-alt-pkg.sh +307 -0
  151. package/scripts/upgrade-via-npm.ps1 +296 -0
  152. package/scripts/upgrade-via-npm.sh +301 -0
  153. package/scripts/upgrade-via-source.sh +774 -0
  154. package/skills/qqbot-channel/SKILL.md +263 -0
  155. package/skills/qqbot-channel/references/api_references.md +521 -0
  156. package/skills/qqbot-media/SKILL.md +56 -0
  157. package/skills/qqbot-remind/SKILL.md +149 -0
  158. package/src/admin-resolver.ts +140 -0
  159. package/src/api.ts +819 -0
  160. package/src/bot-logs-2026-03-21T11-21-47(2).txt +46 -0
  161. package/src/channel.ts +381 -0
  162. package/src/config.ts +187 -0
  163. package/src/credential-backup.ts +72 -0
  164. package/src/gateway.log +43 -0
  165. package/src/gateway.ts +1404 -0
  166. package/src/image-server.ts +539 -0
  167. package/src/inbound-attachments.ts +304 -0
  168. package/src/known-users.ts +353 -0
  169. package/src/message-queue.ts +169 -0
  170. package/src/onboarding.ts +274 -0
  171. package/src/openclaw-2026-03-21.log +3729 -0
  172. package/src/openclaw-plugin-sdk.d.ts +522 -0
  173. package/src/outbound-deliver.ts +552 -0
  174. package/src/outbound.ts +1266 -0
  175. package/src/proactive.ts +530 -0
  176. package/src/ref-index-store.ts +357 -0
  177. package/src/reply-dispatcher.ts +334 -0
  178. package/src/runtime.ts +14 -0
  179. package/src/session-store.ts +303 -0
  180. package/src/slash-commands.ts +1305 -0
  181. package/src/startup-greeting.ts +98 -0
  182. package/src/stt.ts +86 -0
  183. package/src/tools/channel.ts +281 -0
  184. package/src/tools/remind.ts +296 -0
  185. package/src/types.ts +183 -0
  186. package/src/typing-keepalive.ts +59 -0
  187. package/src/update-checker.ts +179 -0
  188. package/src/user-messages.ts +7 -0
  189. package/src/utils/audio-convert.ts +803 -0
  190. package/src/utils/file-utils.ts +167 -0
  191. package/src/utils/image-size.ts +266 -0
  192. package/src/utils/media-tags.ts +182 -0
  193. package/src/utils/payload.ts +265 -0
  194. package/src/utils/platform.ts +435 -0
  195. package/src/utils/text-parsing.ts +82 -0
  196. package/src/utils/upload-cache.ts +128 -0
  197. package/tsconfig.json +16 -0
@@ -0,0 +1,254 @@
1
+ /**
2
+ * Session 持久化存储
3
+ * 将 WebSocket 连接状态(sessionId、lastSeq)持久化到文件
4
+ * 支持进程重启后通过 Resume 机制快速恢复连接
5
+ */
6
+ import fs from "node:fs";
7
+ import path from "node:path";
8
+ import { getQQBotDataDir } from "./utils/platform.js";
9
+ // Session 文件目录
10
+ const SESSION_DIR = getQQBotDataDir("sessions");
11
+ // Session 过期时间(5分钟)- Resume 要求在断开后一定时间内恢复
12
+ const SESSION_EXPIRE_TIME = 5 * 60 * 1000;
13
+ // 写入节流时间(避免频繁写入)
14
+ const SAVE_THROTTLE_MS = 1000;
15
+ // 每个账户的节流状态
16
+ const throttleState = new Map();
17
+ /**
18
+ * 确保目录存在
19
+ */
20
+ function ensureDir() {
21
+ if (!fs.existsSync(SESSION_DIR)) {
22
+ fs.mkdirSync(SESSION_DIR, { recursive: true });
23
+ }
24
+ }
25
+ /**
26
+ * 获取 Session 文件路径
27
+ */
28
+ function getSessionPath(accountId) {
29
+ // 清理 accountId 中的特殊字符
30
+ const safeId = accountId.replace(/[^a-zA-Z0-9_-]/g, "_");
31
+ return path.join(SESSION_DIR, `session-${safeId}.json`);
32
+ }
33
+ /**
34
+ * 加载 Session 状态
35
+ * @param accountId 账户 ID
36
+ * @param expectedAppId 当前使用的 appId,如果与保存时的 appId 不匹配则视为失效
37
+ * @returns Session 状态,如果不存在、已过期或 appId 不匹配返回 null
38
+ */
39
+ export function loadSession(accountId, expectedAppId) {
40
+ const filePath = getSessionPath(accountId);
41
+ try {
42
+ if (!fs.existsSync(filePath)) {
43
+ return null;
44
+ }
45
+ const data = fs.readFileSync(filePath, "utf-8");
46
+ const state = JSON.parse(data);
47
+ // 检查是否过期
48
+ const now = Date.now();
49
+ if (now - state.savedAt > SESSION_EXPIRE_TIME) {
50
+ console.log(`[session-store] Session expired for ${accountId}, age: ${Math.round((now - state.savedAt) / 1000)}s`);
51
+ try {
52
+ fs.unlinkSync(filePath);
53
+ }
54
+ catch {
55
+ // 忽略删除错误
56
+ }
57
+ return null;
58
+ }
59
+ // 检查 appId 是否匹配(凭据变更检测)
60
+ if (expectedAppId && state.appId && state.appId !== expectedAppId) {
61
+ console.log(`[session-store] appId mismatch for ${accountId}: saved=${state.appId}, current=${expectedAppId}. Discarding stale session.`);
62
+ try {
63
+ fs.unlinkSync(filePath);
64
+ }
65
+ catch {
66
+ // 忽略删除错误
67
+ }
68
+ return null;
69
+ }
70
+ // 验证必要字段
71
+ if (!state.sessionId || state.lastSeq === null || state.lastSeq === undefined) {
72
+ console.log(`[session-store] Invalid session data for ${accountId}`);
73
+ return null;
74
+ }
75
+ console.log(`[session-store] Loaded session for ${accountId}: sessionId=${state.sessionId}, lastSeq=${state.lastSeq}, appId=${state.appId ?? "unknown"}, age=${Math.round((now - state.savedAt) / 1000)}s`);
76
+ return state;
77
+ }
78
+ catch (err) {
79
+ console.error(`[session-store] Failed to load session for ${accountId}: ${err}`);
80
+ return null;
81
+ }
82
+ }
83
+ /**
84
+ * 保存 Session 状态(带节流,避免频繁写入)
85
+ * @param state Session 状态
86
+ */
87
+ export function saveSession(state) {
88
+ const { accountId } = state;
89
+ // 获取或初始化节流状态
90
+ let throttle = throttleState.get(accountId);
91
+ if (!throttle) {
92
+ throttle = {
93
+ pendingState: null,
94
+ lastSaveTime: 0,
95
+ throttleTimer: null,
96
+ };
97
+ throttleState.set(accountId, throttle);
98
+ }
99
+ const now = Date.now();
100
+ const timeSinceLastSave = now - throttle.lastSaveTime;
101
+ // 如果距离上次保存时间足够长,立即保存
102
+ if (timeSinceLastSave >= SAVE_THROTTLE_MS) {
103
+ doSaveSession(state);
104
+ throttle.lastSaveTime = now;
105
+ throttle.pendingState = null;
106
+ // 清除待定的节流定时器
107
+ if (throttle.throttleTimer) {
108
+ clearTimeout(throttle.throttleTimer);
109
+ throttle.throttleTimer = null;
110
+ }
111
+ }
112
+ else {
113
+ // 记录待保存的状态
114
+ throttle.pendingState = state;
115
+ // 如果没有设置定时器,设置一个
116
+ if (!throttle.throttleTimer) {
117
+ const delay = SAVE_THROTTLE_MS - timeSinceLastSave;
118
+ throttle.throttleTimer = setTimeout(() => {
119
+ const t = throttleState.get(accountId);
120
+ if (t && t.pendingState) {
121
+ doSaveSession(t.pendingState);
122
+ t.lastSaveTime = Date.now();
123
+ t.pendingState = null;
124
+ }
125
+ if (t) {
126
+ t.throttleTimer = null;
127
+ }
128
+ }, delay);
129
+ }
130
+ }
131
+ }
132
+ /**
133
+ * 实际执行保存操作
134
+ */
135
+ function doSaveSession(state) {
136
+ const filePath = getSessionPath(state.accountId);
137
+ try {
138
+ ensureDir();
139
+ // 更新保存时间
140
+ const stateToSave = {
141
+ ...state,
142
+ savedAt: Date.now(),
143
+ };
144
+ fs.writeFileSync(filePath, JSON.stringify(stateToSave, null, 2), "utf-8");
145
+ console.log(`[session-store] Saved session for ${state.accountId}: sessionId=${state.sessionId}, lastSeq=${state.lastSeq}`);
146
+ }
147
+ catch (err) {
148
+ console.error(`[session-store] Failed to save session for ${state.accountId}: ${err}`);
149
+ }
150
+ }
151
+ /**
152
+ * 清除 Session 状态
153
+ * @param accountId 账户 ID
154
+ */
155
+ export function clearSession(accountId) {
156
+ const filePath = getSessionPath(accountId);
157
+ // 清除节流状态
158
+ const throttle = throttleState.get(accountId);
159
+ if (throttle) {
160
+ if (throttle.throttleTimer) {
161
+ clearTimeout(throttle.throttleTimer);
162
+ }
163
+ throttleState.delete(accountId);
164
+ }
165
+ try {
166
+ if (fs.existsSync(filePath)) {
167
+ fs.unlinkSync(filePath);
168
+ console.log(`[session-store] Cleared session for ${accountId}`);
169
+ }
170
+ }
171
+ catch (err) {
172
+ console.error(`[session-store] Failed to clear session for ${accountId}: ${err}`);
173
+ }
174
+ }
175
+ /**
176
+ * 更新 lastSeq(轻量级更新)
177
+ * @param accountId 账户 ID
178
+ * @param lastSeq 最新的消息序号
179
+ */
180
+ export function updateLastSeq(accountId, lastSeq) {
181
+ const existing = loadSession(accountId);
182
+ if (existing && existing.sessionId) {
183
+ saveSession({
184
+ ...existing,
185
+ lastSeq,
186
+ });
187
+ }
188
+ }
189
+ /**
190
+ * 获取所有保存的 Session 状态
191
+ */
192
+ export function getAllSessions() {
193
+ const sessions = [];
194
+ try {
195
+ ensureDir();
196
+ const files = fs.readdirSync(SESSION_DIR);
197
+ for (const file of files) {
198
+ if (file.startsWith("session-") && file.endsWith(".json")) {
199
+ const filePath = path.join(SESSION_DIR, file);
200
+ try {
201
+ const data = fs.readFileSync(filePath, "utf-8");
202
+ const state = JSON.parse(data);
203
+ sessions.push(state);
204
+ }
205
+ catch {
206
+ // 忽略解析错误
207
+ }
208
+ }
209
+ }
210
+ }
211
+ catch {
212
+ // 目录不存在等错误
213
+ }
214
+ return sessions;
215
+ }
216
+ /**
217
+ * 清理过期的 Session 文件
218
+ */
219
+ export function cleanupExpiredSessions() {
220
+ let cleaned = 0;
221
+ try {
222
+ ensureDir();
223
+ const files = fs.readdirSync(SESSION_DIR);
224
+ const now = Date.now();
225
+ for (const file of files) {
226
+ if (file.startsWith("session-") && file.endsWith(".json")) {
227
+ const filePath = path.join(SESSION_DIR, file);
228
+ try {
229
+ const data = fs.readFileSync(filePath, "utf-8");
230
+ const state = JSON.parse(data);
231
+ if (now - state.savedAt > SESSION_EXPIRE_TIME) {
232
+ fs.unlinkSync(filePath);
233
+ cleaned++;
234
+ console.log(`[session-store] Cleaned expired session: ${file}`);
235
+ }
236
+ }
237
+ catch {
238
+ // 忽略解析错误,但也删除损坏的文件
239
+ try {
240
+ fs.unlinkSync(filePath);
241
+ cleaned++;
242
+ }
243
+ catch {
244
+ // 忽略
245
+ }
246
+ }
247
+ }
248
+ }
249
+ }
250
+ catch {
251
+ // 目录不存在等错误
252
+ }
253
+ return cleaned;
254
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * QQBot 插件级斜杠指令处理器
3
+ *
4
+ * 设计原则:
5
+ * 1. 在消息入队前拦截,匹配到插件级指令后直接回复,不进入 AI 处理队列
6
+ * 2. 不匹配的 "/" 消息照常入队,交给 OpenClaw 框架处理
7
+ * 3. 每个指令通过 SlashCommand 接口注册,易于扩展
8
+ *
9
+ * 时间线追踪:
10
+ * 开平推送时间戳 → 插件收到(Date.now()) → 指令处理完成(Date.now())
11
+ * 从而计算「开平→插件」和「插件处理」两段耗时
12
+ */
13
+ import type { QQBotAccountConfig } from "./types.js";
14
+ /** 斜杠指令上下文(消息元数据 + 运行时状态) */
15
+ export interface SlashCommandContext {
16
+ /** 消息类型 */
17
+ type: "c2c" | "guild" | "dm" | "group";
18
+ /** 发送者 ID */
19
+ senderId: string;
20
+ /** 发送者昵称 */
21
+ senderName?: string;
22
+ /** 消息 ID(用于被动回复) */
23
+ messageId: string;
24
+ /** 开平推送的事件时间戳(ISO 字符串) */
25
+ eventTimestamp: string;
26
+ /** 插件收到消息的本地时间(ms) */
27
+ receivedAt: number;
28
+ /** 原始消息内容 */
29
+ rawContent: string;
30
+ /** 指令参数(去掉指令名后的部分) */
31
+ args: string;
32
+ /** 频道 ID(guild 类型) */
33
+ channelId?: string;
34
+ /** 群 openid(group 类型) */
35
+ groupOpenid?: string;
36
+ /** 账号 ID */
37
+ accountId: string;
38
+ /** Bot App ID */
39
+ appId: string;
40
+ /** 账号配置(供指令读取可配置项) */
41
+ accountConfig?: QQBotAccountConfig;
42
+ /** 当前用户队列状态快照 */
43
+ queueSnapshot: QueueSnapshot;
44
+ }
45
+ /** 队列状态快照 */
46
+ export interface QueueSnapshot {
47
+ /** 各用户队列中的消息总数 */
48
+ totalPending: number;
49
+ /** 正在并行处理的用户数 */
50
+ activeUsers: number;
51
+ /** 最大并发用户数 */
52
+ maxConcurrentUsers: number;
53
+ /** 当前发送者在队列中的待处理消息数 */
54
+ senderPending: number;
55
+ }
56
+ /** 斜杠指令返回值:文本、带文件的结果、或 null(不处理) */
57
+ export type SlashCommandResult = string | SlashCommandFileResult | null;
58
+ /** 带文件的指令结果(先回复文本,再发送文件) */
59
+ export interface SlashCommandFileResult {
60
+ text: string;
61
+ /** 要发送的本地文件路径 */
62
+ filePath: string;
63
+ }
64
+ /**
65
+ * 尝试匹配并执行插件级斜杠指令
66
+ *
67
+ * @returns 回复文本(匹配成功),null(不匹配,应入队正常处理)
68
+ */
69
+ export declare function matchSlashCommand(ctx: SlashCommandContext): Promise<SlashCommandResult>;
70
+ /** 获取插件版本号(供外部使用) */
71
+ export declare function getPluginVersion(): string;