@lmcl/ailo-mcp-feishu 0.0.3 → 0.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.
@@ -491,21 +491,28 @@ export class FeishuHandler {
491
491
  }
492
492
  /**
493
493
  * 下载消息资源到本地缓存,返回 path。失败时返回 null(调用方传 ref)。
494
+ * 路径按年/月组织:blobs/YYYY/MM/
495
+ * 文件名:时间戳_原始file_name(必须提供 file_name,否则不保存,走 ref)
494
496
  */
495
- async downloadToCache(messageId, fileKey, resourceType, aidoType) {
497
+ async downloadToCache(messageId, fileKey, resourceType, aidoType, fileName) {
498
+ const trimmed = fileName?.trim();
499
+ if (!trimmed)
500
+ return null;
496
501
  const workDir = getWorkDir();
497
502
  if (!workDir)
498
503
  return null;
499
- const cacheDir = path.join(workDir, "blobs");
504
+ const now = new Date();
505
+ const year = String(now.getFullYear());
506
+ const month = String(now.getMonth() + 1).padStart(2, "0");
507
+ const cacheDir = path.join(workDir, "blobs", year, month);
500
508
  try {
501
509
  await fs.promises.mkdir(cacheDir, { recursive: true });
502
510
  }
503
511
  catch {
504
512
  return null;
505
513
  }
506
- const safeMsg = messageId.replace(/[^a-zA-Z0-9_-]/g, "_");
507
- const safeKey = fileKey.replace(/[^a-zA-Z0-9_-]/g, "_");
508
- const filename = `ref_feishu_${safeMsg}_${safeKey}_${aidoType}`;
514
+ const sanitized = trimmed.replace(/[/\\?*:|"<>]/g, "_").slice(0, 200);
515
+ const filename = `${Date.now()}_${sanitized}`;
509
516
  const outPath = path.join(cacheDir, filename);
510
517
  const tryMessageResource = async () => {
511
518
  const res = await this.client.im.v1.messageResource.get({
@@ -535,18 +542,21 @@ export class FeishuHandler {
535
542
  }
536
543
  }
537
544
  /**
538
- * 获取消息资源并转为 attachment。优先下载到 cache 传 path;失败则传 ref
545
+ * 获取消息资源并转为 attachment。有 file_name 时下载到 cache 传 path;无则传 ref(不保存)。
539
546
  */
540
547
  async fetchMessageResourceAttachment(messageId, fileKey, resourceType, aidoType, fileName) {
541
- const pathOrNull = await this.downloadToCache(messageId, fileKey, resourceType, aidoType);
548
+ if (!fileName?.trim()) {
549
+ return { type: aidoType, ref: `im:${messageId}:${fileKey}:${aidoType}`, channel: "feishu" };
550
+ }
551
+ const pathOrNull = await this.downloadToCache(messageId, fileKey, resourceType, aidoType, fileName);
542
552
  if (pathOrNull) {
543
- const out = { type: aidoType, path: pathOrNull };
544
- if (fileName)
545
- out.name = fileName;
546
- return out;
553
+ return {
554
+ type: aidoType,
555
+ path: pathOrNull,
556
+ name: path.basename(pathOrNull),
557
+ };
547
558
  }
548
- const ref = `im:${messageId}:${fileKey}:${aidoType}`;
549
- return { type: aidoType, ref, channel: "feishu", name: fileName };
559
+ return { type: aidoType, ref: `im:${messageId}:${fileKey}:${aidoType}`, channel: "feishu" };
550
560
  }
551
561
  /**
552
562
  * 使用飞书 WebSocket 长连接接收事件,无需配置回调地址。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lmcl/ailo-mcp-feishu",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Ailo 飞书/Lark 通道 MCP",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "@larksuiteoapi/node-sdk": "^1.56.1",
17
- "@lmcl/ailo-mcp-sdk": "^0.0.2",
17
+ "@lmcl/ailo-mcp-sdk": "^0.0.3",
18
18
  "@modelcontextprotocol/sdk": "^1.26.0",
19
19
  "dotenv": "^16.4.5",
20
20
  "form-data": "^4.0.0",