@tencent-connect/dsh-qqbot 0.3.0 → 0.5.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.
Files changed (183) hide show
  1. package/.orange-ci.yml +2 -68
  2. package/CHANGELOG.md +45 -0
  3. package/CHANGELOG_EN.md +84 -0
  4. package/README.md +107 -17
  5. package/README_EN.md +107 -17
  6. package/cordis.patch.yml +1 -1
  7. package/cordis.yml +46 -3
  8. package/dist/commands/help.d.ts +6 -7
  9. package/dist/commands/help.d.ts.map +1 -1
  10. package/dist/commands/help.js +23 -7
  11. package/dist/commands/help.js.map +1 -1
  12. package/dist/commands/index.d.ts +7 -5
  13. package/dist/commands/index.d.ts.map +1 -1
  14. package/dist/commands/index.js +12 -12
  15. package/dist/commands/index.js.map +1 -1
  16. package/dist/commands/misc.d.ts +10 -8
  17. package/dist/commands/misc.d.ts.map +1 -1
  18. package/dist/commands/misc.js +45 -8
  19. package/dist/commands/misc.js.map +1 -1
  20. package/dist/commands/model.d.ts +3 -4
  21. package/dist/commands/model.d.ts.map +1 -1
  22. package/dist/commands/model.js +8 -7
  23. package/dist/commands/model.js.map +1 -1
  24. package/dist/commands/preset.d.ts +8 -0
  25. package/dist/commands/preset.d.ts.map +1 -0
  26. package/dist/commands/preset.js +52 -0
  27. package/dist/commands/preset.js.map +1 -0
  28. package/dist/commands/session.d.ts +11 -7
  29. package/dist/commands/session.d.ts.map +1 -1
  30. package/dist/commands/session.js +29 -13
  31. package/dist/commands/session.js.map +1 -1
  32. package/dist/commands/status.d.ts +3 -4
  33. package/dist/commands/status.d.ts.map +1 -1
  34. package/dist/commands/status.js +2 -1
  35. package/dist/commands/status.js.map +1 -1
  36. package/dist/commands/types.d.ts +9 -2
  37. package/dist/commands/types.d.ts.map +1 -1
  38. package/dist/config.d.ts +38 -0
  39. package/dist/config.d.ts.map +1 -1
  40. package/dist/config.js +35 -1
  41. package/dist/config.js.map +1 -1
  42. package/dist/features/answer-parser.d.ts +9 -0
  43. package/dist/features/answer-parser.d.ts.map +1 -0
  44. package/dist/features/answer-parser.js +23 -0
  45. package/dist/features/answer-parser.js.map +1 -0
  46. package/dist/features/approval-channel.d.ts +76 -0
  47. package/dist/features/approval-channel.d.ts.map +1 -0
  48. package/dist/features/approval-channel.js +142 -0
  49. package/dist/features/approval-channel.js.map +1 -0
  50. package/dist/features/approval-renderer.d.ts +18 -0
  51. package/dist/features/approval-renderer.d.ts.map +1 -0
  52. package/dist/features/approval-renderer.js +52 -0
  53. package/dist/features/approval-renderer.js.map +1 -0
  54. package/dist/features/button-utils.d.ts +33 -0
  55. package/dist/features/button-utils.d.ts.map +1 -0
  56. package/dist/features/button-utils.js +27 -0
  57. package/dist/features/button-utils.js.map +1 -0
  58. package/dist/features/history-store.d.ts.map +1 -1
  59. package/dist/features/history-store.js +0 -1
  60. package/dist/features/history-store.js.map +1 -1
  61. package/dist/features/question-channel.d.ts +96 -0
  62. package/dist/features/question-channel.d.ts.map +1 -0
  63. package/dist/features/question-channel.js +234 -0
  64. package/dist/features/question-channel.js.map +1 -0
  65. package/dist/features/question-renderer.d.ts +20 -0
  66. package/dist/features/question-renderer.d.ts.map +1 -0
  67. package/dist/features/question-renderer.js +70 -0
  68. package/dist/features/question-renderer.js.map +1 -0
  69. package/dist/gateway/bootstrap.d.ts +3 -3
  70. package/dist/gateway/bootstrap.d.ts.map +1 -1
  71. package/dist/gateway/bootstrap.js +76 -8
  72. package/dist/gateway/bootstrap.js.map +1 -1
  73. package/dist/gateway/index.d.ts +2 -2
  74. package/dist/gateway/index.js +2 -2
  75. package/dist/gateway/middleware-setup.d.ts +3 -3
  76. package/dist/gateway/middleware-setup.d.ts.map +1 -1
  77. package/dist/gateway/middleware-setup.js +9 -7
  78. package/dist/gateway/middleware-setup.js.map +1 -1
  79. package/dist/index.d.ts +2 -2
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +16 -11
  82. package/dist/index.js.map +1 -1
  83. package/dist/media/media-cleaner.d.ts +19 -0
  84. package/dist/media/media-cleaner.d.ts.map +1 -0
  85. package/dist/media/media-cleaner.js +81 -0
  86. package/dist/media/media-cleaner.js.map +1 -0
  87. package/dist/media/send-file-tool.d.ts +35 -0
  88. package/dist/media/send-file-tool.d.ts.map +1 -0
  89. package/dist/media/send-file-tool.js +150 -0
  90. package/dist/media/send-file-tool.js.map +1 -0
  91. package/dist/media/vision-tool.d.ts +16 -0
  92. package/dist/media/vision-tool.d.ts.map +1 -0
  93. package/dist/media/vision-tool.js +241 -0
  94. package/dist/media/vision-tool.js.map +1 -0
  95. package/dist/middleware/attachment.d.ts +3 -3
  96. package/dist/middleware/attachment.d.ts.map +1 -1
  97. package/dist/middleware/attachment.js +17 -4
  98. package/dist/middleware/attachment.js.map +1 -1
  99. package/dist/middleware/question-answer.d.ts +10 -0
  100. package/dist/middleware/question-answer.d.ts.map +1 -0
  101. package/dist/middleware/question-answer.js +19 -0
  102. package/dist/middleware/question-answer.js.map +1 -0
  103. package/dist/model/index.d.ts +4 -4
  104. package/dist/model/index.js +3 -3
  105. package/dist/model/model-resolver.d.ts +27 -13
  106. package/dist/model/model-resolver.d.ts.map +1 -1
  107. package/dist/model/model-resolver.js +82 -27
  108. package/dist/model/model-resolver.js.map +1 -1
  109. package/dist/model/prefs-store.d.ts +6 -1
  110. package/dist/model/prefs-store.d.ts.map +1 -1
  111. package/dist/model/prefs-store.js +25 -1
  112. package/dist/model/prefs-store.js.map +1 -1
  113. package/dist/model/settings-reader.d.ts +1 -1
  114. package/dist/session/idle-evictor.d.ts +2 -2
  115. package/dist/session/idle-evictor.d.ts.map +1 -1
  116. package/dist/session/idle-evictor.js +1 -1
  117. package/dist/session/idle-evictor.js.map +1 -1
  118. package/dist/session/index.d.ts +3 -3
  119. package/dist/session/index.d.ts.map +1 -1
  120. package/dist/session/index.js +2 -2
  121. package/dist/session/session-manager.d.ts +67 -9
  122. package/dist/session/session-manager.d.ts.map +1 -1
  123. package/dist/session/session-manager.js +216 -20
  124. package/dist/session/session-manager.js.map +1 -1
  125. package/dist/session/types.d.ts +47 -1
  126. package/dist/session/types.d.ts.map +1 -1
  127. package/dist/setup.d.ts +4 -4
  128. package/dist/setup.d.ts.map +1 -1
  129. package/dist/setup.js +63 -28
  130. package/dist/setup.js.map +1 -1
  131. package/dist/shared/index.d.ts +3 -3
  132. package/dist/shared/index.d.ts.map +1 -1
  133. package/dist/shared/index.js +3 -3
  134. package/dist/shared/index.js.map +1 -1
  135. package/dist/shared/send-helper.js +1 -1
  136. package/dist/shared/utils.d.ts +8 -1
  137. package/dist/shared/utils.d.ts.map +1 -1
  138. package/dist/shared/utils.js +18 -7
  139. package/dist/shared/utils.js.map +1 -1
  140. package/dist/transport/attachment.d.ts +18 -7
  141. package/dist/transport/attachment.d.ts.map +1 -1
  142. package/dist/transport/attachment.js +77 -30
  143. package/dist/transport/attachment.js.map +1 -1
  144. package/dist/transport/inbound.d.ts +5 -4
  145. package/dist/transport/inbound.d.ts.map +1 -1
  146. package/dist/transport/inbound.js +120 -80
  147. package/dist/transport/inbound.js.map +1 -1
  148. package/dist/transport/index.d.ts +4 -4
  149. package/dist/transport/index.js +4 -4
  150. package/dist/transport/msgid-cache.d.ts +23 -0
  151. package/dist/transport/msgid-cache.d.ts.map +1 -0
  152. package/dist/transport/msgid-cache.js +57 -0
  153. package/dist/transport/msgid-cache.js.map +1 -0
  154. package/dist/transport/outbound-buffer.d.ts +9 -6
  155. package/dist/transport/outbound-buffer.d.ts.map +1 -1
  156. package/dist/transport/outbound-buffer.js +5 -5
  157. package/dist/transport/outbound-buffer.js.map +1 -1
  158. package/dist/transport/outbound.d.ts +9 -9
  159. package/dist/transport/outbound.d.ts.map +1 -1
  160. package/dist/transport/outbound.js +7 -7
  161. package/dist/transport/outbound.js.map +1 -1
  162. package/dist/transport/reply-limiter.d.ts +31 -0
  163. package/dist/transport/reply-limiter.d.ts.map +1 -0
  164. package/dist/transport/reply-limiter.js +50 -0
  165. package/dist/transport/reply-limiter.js.map +1 -0
  166. package/dist/transport/reply-target.d.ts +29 -0
  167. package/dist/transport/reply-target.d.ts.map +1 -0
  168. package/dist/transport/reply-target.js +55 -0
  169. package/dist/transport/reply-target.js.map +1 -0
  170. package/dist/transport/streaming-writer.d.ts +3 -3
  171. package/dist/transport/streaming-writer.d.ts.map +1 -1
  172. package/dist/transport/streaming-writer.js +1 -1
  173. package/dist/transport/streaming-writer.js.map +1 -1
  174. package/dist/transport/tool-presenter.d.ts +0 -1
  175. package/dist/transport/tool-presenter.d.ts.map +1 -1
  176. package/dist/transport/tool-presenter.js +0 -1
  177. package/dist/transport/tool-presenter.js.map +1 -1
  178. package/dist/types.d.ts +9 -15
  179. package/dist/types.d.ts.map +1 -1
  180. package/docs/assets/qqchannel.jpg +0 -0
  181. package/docs/assets/qqgroup.jpg +0 -0
  182. package/docs/assets/qrcode.png +0 -0
  183. package/package.json +21 -4
package/dist/setup.js CHANGED
@@ -5,14 +5,18 @@
5
5
  * 唤起终端扫码流程获取凭据,并写入 dsh profile 配置。
6
6
  */
7
7
  import { resolve } from 'node:path';
8
- import { readFileSync, writeFileSync, existsSync } from 'node:fs';
8
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
9
9
  import yaml from 'js-yaml';
10
- import { qrConnect } from '@tencent-connect/qqbot-connector';
10
+ import { startQrConnect } from '@tencent-connect/qqbot-connector';
11
+ /** 终端可点击的 OSC 8 超链接(不支持 OSC 8 的终端会忽略控制序列,退化为纯 URL 文本) */
12
+ function clickableLink(url) {
13
+ return `\u001b]8;;${url}\u001b\\${url}\u001b]8;;\u001b\\`;
14
+ }
11
15
  /**
12
16
  * 执行 QR 扫码绑定,获取 QQ Bot 凭据
13
17
  *
14
- * 使用动态 import 加载 qqbot-connector(可能未安装),
15
- * 在终端打印二维码等待用户扫码。
18
+ * 在终端打印二维码等待用户扫码;同时输出扫码 URL,
19
+ * 供二维码因系统字符问题渲染错位时点击/复制到浏览器打开扫码。
16
20
  */
17
21
  export async function runQrSetup(source = 'dsh-qqbot') {
18
22
  console.log('\n══════════════════════════════════════════════════════');
@@ -20,7 +24,21 @@ export async function runQrSetup(source = 'dsh-qqbot') {
20
24
  console.log('══════════════════════════════════════════════════════\n');
21
25
  try {
22
26
  console.log('请使用手机 QQ 扫描下方二维码完成绑定...\n');
23
- const credentials = await qrConnect({ source });
27
+ // 回调风格:onQrDisplayed 会在二维码打印后、轮询开始前回调扫码 URL,
28
+ // 让用户在二维码错位时也能通过链接打开扫码页(二维码过期刷新会再次触发)。
29
+ const credentials = await new Promise((resolve, reject) => {
30
+ startQrConnect({
31
+ onSuccess: resolve,
32
+ onFailure: reject,
33
+ onQrDisplayed: (url) => {
34
+ console.log('二维码显示异常?点击下方链接,用浏览器打开即可完成扫码:');
35
+ console.log(` ${clickableLink(url)}\n`);
36
+ },
37
+ onQrExpired: () => {
38
+ console.log('二维码已过期,正在刷新…\n');
39
+ },
40
+ }, { source });
41
+ });
24
42
  if (!credentials || credentials.length === 0) {
25
43
  console.error('[im-qqbot] 扫码未返回凭据');
26
44
  return null;
@@ -54,22 +72,23 @@ export async function runQrSetup(source = 'dsh-qqbot') {
54
72
  * 将凭据写入 dsh profile 的 cordis.patch.yml
55
73
  *
56
74
  * 用 js-yaml 解析现有文件后更新/追加 im-qqbot 条目,再 dump 写回,
57
- * 保证输出始终是合法 YAML。兼容空数组 `[]`、条目列表,以及
58
- * `[]` 与条目混合导致解析失败等异常情况(失败时重建)。
75
+ * 保证输出始终是合法 YAML。文件不存在或为空时安全重建;
76
+ * 解析失败或结构异常时拒绝写入、保留原文件(避免覆盖用户其他配置)。
59
77
  */
60
78
  export function persistCredentialsToProfile(credentials, profileDir, logger) {
61
79
  const log = logger ?? console;
62
80
  const dir = profileDir;
63
81
  if (!dir) {
64
- printManualInstructions(credentials);
82
+ // 开发模式:插件从源码加载、不在 node_modules 下,无法定位 profile 目录
83
+ printEnvInstructions(credentials);
65
84
  return false;
66
85
  }
67
86
  const patchPath = resolve(dir, 'cordis.patch.yml');
68
87
  try {
69
- // 1. 解析现有条目(容错处理)
88
+ // 1. 解析现有条目(文件不存在/为空才重建;解析失败会抛错,保留原文件)
70
89
  let entries = [];
71
90
  if (existsSync(patchPath)) {
72
- entries = parsePatchEntries(readFileSync(patchPath, 'utf8'), log);
91
+ entries = parsePatchEntries(readFileSync(patchPath, 'utf8'));
73
92
  }
74
93
  // 2. 查找已有 im-qqbot 条目
75
94
  const existing = entries.find((e) => e.id === 'im-qqbot');
@@ -92,7 +111,9 @@ export function persistCredentialsToProfile(credentials, profileDir, logger) {
92
111
  });
93
112
  }
94
113
  // 3. dump 写回(保证合法 YAML)
114
+ // 先确保 profile 目录存在(文件不存在时也能正常创建,而非误入 ENOENT)
95
115
  const output = `# QQ Bot 凭据(扫码绑定自动生成)\n${yaml.dump(entries)}`;
116
+ mkdirSync(dir, { recursive: true });
96
117
  writeFileSync(patchPath, output, 'utf8');
97
118
  log.info(`✔ 凭据已写入: ${patchPath}`);
98
119
  log.info(` 下次启动将自动使用保存的凭据`);
@@ -100,36 +121,50 @@ export function persistCredentialsToProfile(credentials, profileDir, logger) {
100
121
  }
101
122
  catch (err) {
102
123
  log.warn(`写入配置失败: ${err instanceof Error ? err.message : String(err)}`);
103
- printManualInstructions(credentials);
124
+ printYamlInstructions(credentials, patchPath);
104
125
  return false;
105
126
  }
106
127
  }
107
128
  /**
108
129
  * 解析 cordis.patch.yml 为条目数组
109
130
  *
110
- * 容错处理:
111
- * - 空内容 / 空数组 `[]` → 空数组
112
- * - 条目列表 → 过滤出含 id 的对象
113
- * - 解析失败(如 `[]` 与条目混合的多文档)→ 返回空数组(重建)
131
+ * - 空内容 / 仅注释(yaml.load 返回 null/undefined)→ 空数组(允许安全重建)
132
+ * - 空数组 `[]` / 条目列表 → 过滤出含 id 的对象
133
+ * - 非数组结构 / YAML 语法错误 → 抛错(由调用方保留原文件,避免覆盖用户其他配置)
114
134
  */
115
- function parsePatchEntries(content, log) {
135
+ function parsePatchEntries(content) {
116
136
  if (!content.trim())
117
137
  return [];
118
- try {
119
- const parsed = yaml.load(content);
120
- if (Array.isArray(parsed)) {
121
- return parsed.filter((e) => typeof e === 'object' && e !== null && typeof e.id === 'string');
122
- }
138
+ const parsed = yaml.load(content);
139
+ // 仅注释/空白 → null/undefined,等价于空文件,允许重建
140
+ if (parsed === null || parsed === undefined)
123
141
  return [];
142
+ if (!Array.isArray(parsed)) {
143
+ throw new Error('cordis.patch.yml 顶层必须是 YAML 数组');
124
144
  }
125
- catch (err) {
126
- log.warn(`cordis.patch.yml 解析失败,将重建: ${err instanceof Error ? err.message : String(err)}`);
127
- return [];
145
+ return parsed.filter((e) => typeof e === 'object' && e !== null && typeof e.id === 'string');
146
+ }
147
+ /** 开发模式引导:未定位到 profile 目录,引导用环境变量配置(console.log 确保可见) */
148
+ function printEnvInstructions(credentials) {
149
+ console.log('未检测到 profile 目录(开发模式),请通过环境变量配置凭据:');
150
+ if (process.platform === 'win32') {
151
+ // Windows CMD 语法(PowerShell 请用 $env:QQBOT_APPID="xxx")
152
+ console.log(` set QQBOT_APPID=${credentials.appId}`);
153
+ console.log(` set QQBOT_SECRET=${credentials.appSecret}`);
154
+ }
155
+ else {
156
+ console.log(` export QQBOT_APPID="${credentials.appId}"`);
157
+ console.log(` export QQBOT_SECRET="${credentials.appSecret}"`);
128
158
  }
129
159
  }
130
- function printManualInstructions(credentials) {
131
- console.log('无法自动保存凭据,请手动设置环境变量:');
132
- console.log(` export QQBOT_APPID="${credentials.appId}"`);
133
- console.log(` export QQBOT_SECRET="${credentials.appSecret}"`);
160
+ /** 正式安装引导:自动写入失败,引导手动在 cordis.patch.yml 配置(console.log 确保可见) */
161
+ function printYamlInstructions(credentials, patchPath) {
162
+ console.log('无法自动保存凭据,请手动打开以下文件添加配置:');
163
+ console.log(` ${patchPath}`);
164
+ console.log('');
165
+ console.log(' - id: im-qqbot');
166
+ console.log(' config:');
167
+ console.log(` appId: "${credentials.appId}"`);
168
+ console.log(` appSecret: "${credentials.appSecret}"`);
134
169
  }
135
170
  //# sourceMappingURL=setup.js.map
package/dist/setup.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * 共享工具层
3
3
  */
4
- export { getProfileDir, resolveEnv, formatRelativeTime, buildUserAgent } from './utils.js';
5
- export { getScopePeer } from './scope.js';
6
- export { sendMarkdownChunked } from './send-helper.js';
4
+ export { getProfileDir, resolveEnv, formatRelativeTime, buildUserAgent, PLUGIN_VERSION } from './utils.ts';
5
+ export { getScopePeer } from './scope.ts';
6
+ export { sendMarkdownChunked } from './send-helper.ts';
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shared/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shared/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,kBAAkB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC3G,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * 共享工具层
3
3
  */
4
- export { getProfileDir, resolveEnv, formatRelativeTime, buildUserAgent } from './utils.js';
5
- export { getScopePeer } from './scope.js';
6
- export { sendMarkdownChunked } from './send-helper.js';
4
+ export { getProfileDir, resolveEnv, formatRelativeTime, buildUserAgent, PLUGIN_VERSION } from "./utils.js";
5
+ export { getScopePeer } from "./scope.js";
6
+ export { sendMarkdownChunked } from "./send-helper.js";
7
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/shared/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/shared/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,kBAAkB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC3G,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1,4 +1,4 @@
1
- import { chunkMarkdownText } from '../transport/chunker.js';
1
+ import { chunkMarkdownText } from "../transport/chunker.js";
2
2
  /**
3
3
  * 分块发送 markdown(长内容自动切分)
4
4
  */
@@ -1,3 +1,5 @@
1
+ /** 插件版本号(从 package.json 读取,供 help/version 等展示真实版本) */
2
+ export declare const PLUGIN_VERSION: string;
1
3
  /**
2
4
  * 构造 User-Agent 头
3
5
  *
@@ -6,8 +8,13 @@
6
8
  export declare function buildUserAgent(): string;
7
9
  /**
8
10
  * 从插件安装路径推导 profile 目录(node_modules 的父目录)
11
+ *
12
+ * 逐级向上查找名为 node_modules 的目录并返回其父目录。
13
+ * 用 basename/dirname 而非字符串分隔符匹配,兼容 Windows(\)与 pnpm 嵌套结构。
14
+ *
15
+ * @param baseDir - 起始目录,缺省为插件根(可注入便于测试)
9
16
  */
10
- export declare function getProfileDir(): string | null;
17
+ export declare function getProfileDir(baseDir?: string): string | null;
11
18
  /**
12
19
  * 解析环境变量占位配置
13
20
  */
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/shared/utils.ts"],"names":[],"mappings":"AA2BA;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAI7C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKtE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAOtD"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/shared/utils.ts"],"names":[],"mappings":"AAcA,sDAAsD;AACtD,eAAO,MAAM,cAAc,QAAsB,CAAC;AAYlD;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,MAAoB,GAAG,MAAM,GAAG,IAAI,CAS1E;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKtE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAOtD"}
@@ -6,12 +6,12 @@
6
6
  import { readFileSync } from 'node:fs';
7
7
  import os from 'node:os';
8
8
  import { fileURLToPath } from 'node:url';
9
- import { dirname, resolve } from 'node:path';
9
+ import { basename, dirname, resolve } from 'node:path';
10
10
  const __filename = fileURLToPath(import.meta.url);
11
11
  const __dirname = dirname(__filename);
12
12
  const PLUGIN_ROOT = resolve(__dirname, '../..');
13
- /** 插件版本号(从 package.json 读取) */
14
- const PLUGIN_VERSION = readPluginVersion();
13
+ /** 插件版本号(从 package.json 读取,供 help/version 等展示真实版本) */
14
+ export const PLUGIN_VERSION = readPluginVersion();
15
15
  function readPluginVersion() {
16
16
  try {
17
17
  const pkgPath = resolve(PLUGIN_ROOT, 'package.json');
@@ -32,11 +32,22 @@ export function buildUserAgent() {
32
32
  }
33
33
  /**
34
34
  * 从插件安装路径推导 profile 目录(node_modules 的父目录)
35
+ *
36
+ * 逐级向上查找名为 node_modules 的目录并返回其父目录。
37
+ * 用 basename/dirname 而非字符串分隔符匹配,兼容 Windows(\)与 pnpm 嵌套结构。
38
+ *
39
+ * @param baseDir - 起始目录,缺省为插件根(可注入便于测试)
35
40
  */
36
- export function getProfileDir() {
37
- const nmIdx = PLUGIN_ROOT.lastIndexOf('/node_modules/');
38
- if (nmIdx > 0)
39
- return PLUGIN_ROOT.slice(0, nmIdx);
41
+ export function getProfileDir(baseDir = PLUGIN_ROOT) {
42
+ let dir = baseDir;
43
+ for (let i = 0; i < 32; i++) {
44
+ if (basename(dir) === 'node_modules')
45
+ return dirname(dir);
46
+ const parent = dirname(dir);
47
+ if (parent === dir)
48
+ break;
49
+ dir = parent;
50
+ }
40
51
  return null;
41
52
  }
42
53
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/shared/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE7C,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAEhD,+BAA+B;AAC/B,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;AAE3C,SAAS,iBAAiB;IACxB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAyB,CAAC;QAC9E,OAAO,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,aAAa,cAAc,UAAU,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC,QAAQ,EAAE,GAAG,CAAC;AACzF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;IACxD,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAClD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,WAAmB,EAAE,MAAc;IAC5D,IAAI,WAAW,IAAI,WAAW,KAAK,cAAc,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC5F,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAW;IAC5C,IAAI,CAAC,EAAE;QAAE,OAAO,GAAG,CAAC;IACpB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;IAC7B,IAAI,IAAI,GAAG,MAAM;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;IAC1D,IAAI,IAAI,GAAG,SAAS;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC;IAC/D,IAAI,IAAI,GAAG,UAAU;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC;IACnE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC;AAC/C,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/shared/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEvD,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAEhD,sDAAsD;AACtD,MAAM,CAAC,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;AAElD,SAAS,iBAAiB;IACxB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAyB,CAAC;QAC9E,OAAO,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,aAAa,cAAc,UAAU,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC,QAAQ,EAAE,GAAG,CAAC;AACzF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,UAAkB,WAAW;IACzD,IAAI,GAAG,GAAG,OAAO,CAAC;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,cAAc;YAAE,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,WAAmB,EAAE,MAAc;IAC5D,IAAI,WAAW,IAAI,WAAW,KAAK,cAAc,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC5F,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAW;IAC5C,IAAI,CAAC,EAAE;QAAE,OAAO,GAAG,CAAC;IACpB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;IAC7B,IAAI,IAAI,GAAG,MAAM;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;IAC1D,IAAI,IAAI,GAAG,SAAS;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC;IAC/D,IAAI,IAAI,GAAG,UAAU;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC;IACnE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC;AAC/C,CAAC"}
@@ -1,18 +1,29 @@
1
- import type { Logger, RawAttachment } from '../types.js';
1
+ import type { Logger, RawAttachment } from '../types.ts';
2
+ import type { MediaConfig } from '../config.ts';
2
3
  /** 下载结果 */
3
4
  export interface DownloadedFile {
4
5
  /** 原始文件名(用于与消息附件关联) */
5
6
  filename: string;
7
+ /** 附件类型 */
8
+ contentType: 'image' | 'video' | 'file';
6
9
  /** 本地绝对路径 */
7
10
  localPath: string;
8
- /** 相对 cwd 的显示路径(@提及 / 工具访问用) */
9
- displayPath: string;
10
11
  }
12
+ /** 附件归类(QQ 网关的 content_type 是 MIME 类型,如 image/png、video/mp4、audio/silk) */
13
+ export type MediaKind = 'image' | 'video' | 'voice' | 'file';
14
+ /** 是否为图片(兼容裸值 'image' 与 MIME 'image/png') */
15
+ export declare function isImageContentType(contentType?: string): boolean;
16
+ /** 是否为视频(兼容裸值 'video' 与 MIME 'video/mp4') */
17
+ export declare function isVideoContentType(contentType?: string): boolean;
18
+ /** 是否为语音(兼容裸值 'voice' 与 MIME 'audio/silk') */
19
+ export declare function isVoiceContentType(contentType?: string): boolean;
20
+ /** 归类附件 content_type 为统一类型 */
21
+ export declare function classifyContentType(contentType?: string): MediaKind;
11
22
  /**
12
- * 下载消息中的 file 附件到本地
23
+ * 下载消息中的富媒体附件(image/video/file)到本地
13
24
  *
14
- * 下载目录为 {cwd}/.qqbot/{messageId},用 messageId 隔离跨消息重名。
15
- * 下载失败不返回(由调用方回退描述),下载成功仅保留路径供模型用工具读取。
25
+ * 下载目录固定为 ~/.dsh-qqbot/media,文件名用时间戳+随机数防重名。
26
+ * 下载失败不阻断(由调用方回退描述)。
16
27
  */
17
- export declare function downloadFileAttachments(attachments: RawAttachment[] | undefined, cwd: string, messageId: string, logger: Logger): Promise<DownloadedFile[]>;
28
+ export declare function downloadMediaAttachments(attachments: RawAttachment[] | undefined, media: MediaConfig, logger: Logger): Promise<DownloadedFile[]>;
18
29
  //# sourceMappingURL=attachment.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"attachment.d.ts","sourceRoot":"","sources":["../../src/transport/attachment.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAOzD,WAAW;AACX,MAAM,WAAW,cAAc;IAC7B,uBAAuB;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;CACrB;AAkED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,aAAa,EAAE,GAAG,SAAS,EACxC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,cAAc,EAAE,CAAC,CAgC3B"}
1
+ {"version":3,"file":"attachment.d.ts","sourceRoot":"","sources":["../../src/transport/attachment.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAQhD,WAAW;AACX,MAAM,WAAW,cAAc;IAC7B,uBAAuB;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW;IACX,WAAW,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;IACxC,aAAa;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,2EAA2E;AAC3E,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAE7D,6CAA6C;AAC7C,wBAAgB,kBAAkB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED,6CAA6C;AAC7C,wBAAgB,kBAAkB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED,8CAA8C;AAC9C,wBAAgB,kBAAkB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED,8BAA8B;AAC9B,wBAAgB,mBAAmB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAKnE;AA0FD;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,WAAW,EAAE,aAAa,EAAE,GAAG,SAAS,EACxC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,cAAc,EAAE,CAAC,CAmC3B"}
@@ -1,22 +1,69 @@
1
1
  /**
2
- * 附件下载 — 将 QQ 文件附件安全下载到本地
2
+ * 富媒体下载 — 将 QQ 图片/视频/file 附件安全下载到本地
3
3
  *
4
- * 下载后仅通过 @路径 提示模型,由模型通过 tool-bash / tool-fs 自行读取,
5
- * 不内联内容(避免 token 浪费与上下文污染)。
4
+ * 下载后仅通过本地绝对路径提示模型,由模型通过 qqbot_describe_image / ffmpeg / tool-fs 等工具自行分析,
5
+ *
6
+ * 下载目录固定为 ~/.dsh-qqbot/media,
7
+ * 文件名用时间戳+随机数防重名,不依赖 agent cwd,便于 qqbot_describe_image / tool-fs 等工具稳定访问。
6
8
  */
7
9
  import { mkdirSync, writeFileSync } from 'node:fs';
8
- import { basename, join } from 'node:path';
10
+ import { basename, extname, join, sep } from 'node:path';
11
+ import { randomBytes } from 'node:crypto';
9
12
  import * as dns from 'node:dns';
10
- /** 下载大小上限(超过则跳过下载,仅保留路径提示) */
11
- const MAX_DOWNLOAD_BYTES = 20 * 1024 * 1024;
13
+ import { MEDIA_ROOT } from "../media/media-cleaner.js";
14
+ /** 默认富媒体下载大小上限(MB),可被 media.maxMB 覆盖 */
15
+ const DEFAULT_MAX_MB = 200;
12
16
  /** 下载超时(毫秒) */
13
- const DOWNLOAD_TIMEOUT_MS = 15_000;
14
- /** 文件名净化:去路径、过滤危险字符,防止路径穿越 */
17
+ const DOWNLOAD_TIMEOUT_MS = 120_000;
18
+ /** 是否为图片(兼容裸值 'image' 与 MIME 'image/png') */
19
+ export function isImageContentType(contentType) {
20
+ return contentType === 'image' || contentType?.startsWith('image/') === true;
21
+ }
22
+ /** 是否为视频(兼容裸值 'video' 与 MIME 'video/mp4') */
23
+ export function isVideoContentType(contentType) {
24
+ return contentType === 'video' || contentType?.startsWith('video/') === true;
25
+ }
26
+ /** 是否为语音(兼容裸值 'voice' 与 MIME 'audio/silk') */
27
+ export function isVoiceContentType(contentType) {
28
+ return contentType === 'voice' || contentType?.startsWith('audio/') === true;
29
+ }
30
+ /** 归类附件 content_type 为统一类型 */
31
+ export function classifyContentType(contentType) {
32
+ if (isImageContentType(contentType))
33
+ return 'image';
34
+ if (isVideoContentType(contentType))
35
+ return 'video';
36
+ if (isVoiceContentType(contentType))
37
+ return 'voice';
38
+ return 'file';
39
+ }
40
+ /** 处理 `//` 开头的协议相对 URL(补 https:) */
41
+ function normalizeUrl(url) {
42
+ return url.startsWith('//') ? `https:${url}` : url;
43
+ }
44
+ /** 文件名净化:去路径、移除非法字符(保留中文等 Unicode 字符),防止路径穿越 */
15
45
  function sanitizeFilename(name) {
16
46
  const base = basename(name.replace(/\\/g, '/'));
17
- const safe = base.replace(/[^a-zA-Z0-9._-]/g, '_');
47
+ // 仅替换文件系统非法字符(Windows 保留字符 + 控制字符),保留中文/空格等
48
+ // normalize NFC:统一 Unicode 规范化,避免 macOS(NFD) 与 Linux/Windows(NFC) 存储差异导致路径对不上
49
+ const safe = base
50
+ .replace(/[<>:"|?*\x00-\x1f]/g, '_')
51
+ .trim()
52
+ .normalize('NFC');
18
53
  return safe || 'attachment';
19
54
  }
55
+ /** 统一路径分隔符为 `/`(POSIX),Node fs 在 Windows 也接受正斜杠,保证注入路径跨平台一致 */
56
+ function toPosixPath(p) {
57
+ return p.split(sep).join('/');
58
+ }
59
+ /** 防重名:文件名 + 时间戳 + 随机数 */
60
+ function uniqueFilename(name) {
61
+ const base = sanitizeFilename(name);
62
+ const ext = extname(base);
63
+ const stem = basename(base, ext);
64
+ const rand = randomBytes(4).toString('hex');
65
+ return `${stem}_${Date.now()}_${rand}${ext}`;
66
+ }
20
67
  /** 字节数格式化 */
21
68
  function formatSize(bytes) {
22
69
  if (bytes >= 1024 * 1024)
@@ -53,7 +100,7 @@ async function assertSafeHostname(hostname) {
53
100
  }
54
101
  /** 安全下载:仅 HTTPS + SSRF 防护 + 大小上限 + 超时,返回下载字节数 */
55
102
  async function download(url, destPath, maxBytes) {
56
- const parsed = new URL(url);
103
+ const parsed = new URL(normalizeUrl(url));
57
104
  if (parsed.protocol !== 'https:') {
58
105
  throw new Error(`Only HTTPS allowed: ${parsed.protocol}`);
59
106
  }
@@ -69,37 +116,37 @@ async function download(url, destPath, maxBytes) {
69
116
  return buf.length;
70
117
  }
71
118
  /**
72
- * 下载消息中的 file 附件到本地
119
+ * 下载消息中的富媒体附件(image/video/file)到本地
73
120
  *
74
- * 下载目录为 {cwd}/.qqbot/{messageId},用 messageId 隔离跨消息重名。
75
- * 下载失败不返回(由调用方回退描述),下载成功仅保留路径供模型用工具读取。
121
+ * 下载目录固定为 ~/.dsh-qqbot/media,文件名用时间戳+随机数防重名。
122
+ * 下载失败不阻断(由调用方回退描述)。
76
123
  */
77
- export async function downloadFileAttachments(attachments, cwd, messageId, logger) {
78
- const files = (attachments ?? []).filter(a => a.content_type === 'file' && a.url);
79
- if (files.length === 0)
124
+ export async function downloadMediaAttachments(attachments, media, logger) {
125
+ if (!media.enabled)
126
+ return [];
127
+ const targets = (attachments ?? []).filter(a => classifyContentType(a.content_type) !== 'voice' && a.url);
128
+ if (targets.length === 0)
80
129
  return [];
81
- const dir = join(cwd, '.qqbot', messageId);
82
- mkdirSync(dir, { recursive: true });
130
+ mkdirSync(MEDIA_ROOT, { recursive: true });
131
+ const maxBytes = (media.maxMB ?? DEFAULT_MAX_MB) * 1024 * 1024;
83
132
  const results = [];
84
- for (const file of files) {
85
- const safeName = sanitizeFilename(file.filename);
86
- const localPath = join(dir, safeName);
87
- const displayPath = `.qqbot/${messageId}/${safeName}`;
88
- if (file.size > MAX_DOWNLOAD_BYTES) {
89
- logger.debug(`im-qqbot: skip download (${file.size}B too large): ${file.filename}`);
90
- results.push({ filename: file.filename, localPath, displayPath });
91
- continue;
133
+ for (const att of targets) {
134
+ const contentType = classifyContentType(att.content_type);
135
+ const localPath = toPosixPath(join(MEDIA_ROOT, uniqueFilename(att.filename)));
136
+ if (att.size > maxBytes) {
137
+ logger.debug(`im-qqbot: skip download (${att.size}B too large): ${att.filename}`);
138
+ continue; // 超限不下载,由 buildDynamicCtx 回退为描述
92
139
  }
93
140
  let bytes;
94
141
  try {
95
- bytes = await download(file.url, localPath, MAX_DOWNLOAD_BYTES);
142
+ bytes = await download(att.url, localPath, maxBytes);
96
143
  }
97
144
  catch (err) {
98
- logger.warn(`im-qqbot: download failed: ${file.filename} — ${err instanceof Error ? err.message : String(err)}`);
145
+ logger.warn(`im-qqbot: download failed: ${att.filename} — ${err instanceof Error ? err.message : String(err)}`);
99
146
  continue; // 下载失败不加入结果,由 buildDynamicCtx 回退为描述
100
147
  }
101
- logger.debug(`im-qqbot: attachment downloaded: ${file.filename} (${formatSize(bytes)}) → ${displayPath}`);
102
- results.push({ filename: file.filename, localPath, displayPath });
148
+ logger.debug(`im-qqbot: attachment downloaded: ${att.filename} (${formatSize(bytes)}) → ${localPath}`);
149
+ results.push({ filename: att.filename, contentType, localPath });
103
150
  }
104
151
  return results;
105
152
  }
@@ -1 +1 @@
1
- {"version":3,"file":"attachment.js","sourceRoot":"","sources":["../../src/transport/attachment.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"attachment.js","sourceRoot":"","sources":["../../src/transport/attachment.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,9 @@
1
- import type { SessionManager } from '../session/index.js';
2
- import type { ImQQBotConfig } from '../config.js';
3
- import type { Logger } from '../types.js';
1
+ import type { SessionManager } from '../session/index.ts';
2
+ import type { ImQQBotConfig } from '../config.ts';
3
+ import type { Logger } from '../types.ts';
4
+ import type { MiddlewareContext } from '@tencent-connect/qqbot-nodejs';
4
5
  /**
5
6
  * 处理 QQ 入站消息(已经过 SDK 中间件链)
6
7
  */
7
- export declare function handleInbound(rawMsg: unknown, manager: SessionManager, config: ImQQBotConfig, logger: Logger, state?: Record<string, unknown>): Promise<void>;
8
+ export declare function handleInbound(ctx: MiddlewareContext, manager: SessionManager, config: ImQQBotConfig, logger: Logger): Promise<void>;
8
9
  //# sourceMappingURL=inbound.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"inbound.d.ts","sourceRoot":"","sources":["../../src/transport/inbound.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAa,MAAM,EAA8B,MAAM,aAAa,CAAC;AA+DjF;;GAEG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,IAAI,CAAC,CA+Cf"}
1
+ {"version":3,"file":"inbound.d.ts","sourceRoot":"","sources":["../../src/transport/inbound.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAa,MAAM,EAAgD,MAAM,aAAa,CAAC;AAQnG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AA8DvE;;GAEG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,iBAAiB,EACtB,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CA0Df"}