koishi-plugin-echo-cave 1.12.0 → 1.12.2

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/README.md CHANGED
@@ -19,6 +19,11 @@
19
19
  - 🔍 **发言回溯**:支持查看自己被他人投稿的消息列表
20
20
  - 🎨 **精美展示**:消息展示时自带多种风格的外部包裹信息,显示消息详情
21
21
  - 🔒 **管理员保护**:可配置管理员消息保护,确保管理员发布的消息安全
22
+ - 📏 **媒体限制**:支持配置媒体文件大小限制
23
+ - 🌐 **多语言支持**:支持中文语言包
24
+ - 🔄 **嵌套转发**:支持嵌套转发消息的递归处理
25
+ - 📝 **模板化展示**:支持多种风格的消息展示模板
26
+ - 🔁 **重复检测**:自动检测重复消息,避免存储重复内容
22
27
 
23
28
  ## 📋 命令列表
24
29
 
@@ -55,11 +60,14 @@ npm install koishi-plugin-echo-cave
55
60
  ```
56
61
  src/
57
62
  ├── index.ts # 插件主入口,命令注册和核心功能
63
+ ├── cave-helper.ts # 回声洞消息发送辅助函数
58
64
  ├── forward-helper.ts # 转发消息处理辅助函数
59
- ├── image-helper.ts # 图片保存辅助函数
60
- ├── msg-helper.ts # 消息发送辅助函数,包含多种风格的外部包裹信息模板
65
+ ├── media-helper.ts # 媒体文件保存辅助函数
66
+ ├── msg-helper.ts # 消息发送辅助函数
61
67
  ├── cqcode-helper.ts # CQ 码处理辅助函数
62
- └── onebot-helper.ts # OneBot 适配器辅助函数
68
+ ├── onebot-helper.ts # OneBot 适配器辅助函数
69
+ └── locales/
70
+ └── zh-CN.json # 中文语言包
63
71
  ```
64
72
 
65
73
  ## 🔧 技术说明
@@ -68,16 +76,34 @@ src/
68
76
  - 图片会保存在 `data/cave/images` 目录下
69
77
  - 支持嵌套转发消息的处理
70
78
  - 自动检测重复消息,避免存储重复内容
79
+ - 支持媒体文件大小限制
80
+ - 支持多语言配置(中文)
81
+ - 支持嵌套转发消息的递归处理
82
+
83
+ ## 🛠️ 配置选项
84
+
85
+ | 配置项 | 类型 | 默认值 | 说明 |
86
+ |-------|------|-------|------|
87
+ | `adminMessageProtection` | boolean | `false` | 开启管理员消息保护,使管理员发布的消息只能由其他管理员删除 |
88
+ | `allowContributorDelete` | boolean | `true` | 允许消息投稿者删除自己投稿的消息 |
89
+ | `allowSenderDelete` | boolean | `true` | 允许原始消息发送者删除自己被投稿的消息 |
90
+ | `enableSizeLimit` | boolean | `false` | 启用媒体文件大小限制 |
91
+ | `maxImageSize` | number | `2048` | 最大图片大小(KB) |
92
+ | `maxVideoSize` | number | `512` | 最大视频大小(MB) |
93
+ | `maxFileSize` | number | `512` | 最大文件大小(MB) |
71
94
 
72
95
  ## 📝 注意事项
73
96
 
74
97
  - 插件只能在群聊中使用,私聊模式下无法正常工作
75
98
  - 使用 `cave.echo` 命令前必须先引用一条消息
76
- - 删除消息需要消息存储者、原始发送者或管理员权限(权限等级 4)
99
+ - 删除消息权限可通过配置项灵活控制,包括管理员保护、投稿者删除权限和原始发送者删除权限
77
100
  - 存储的转发消息会保留原始发送者信息
78
101
  - 消息展示时会自动添加精美的外部包裹信息,包括消息 ID、创建时间、原始发送者和投递者信息
79
102
  - 外部包裹信息有多种随机风格,为每次消息展示带来不同的视觉体验
80
- - 可通过配置开启管理员消息保护,使管理员发布的消息只能由其他管理员删除
103
+ - 支持媒体文件大小限制,可通过配置项调整不同类型文件的大小限制
104
+ - 自动检测重复消息,避免存储重复内容
105
+ - 支持嵌套转发消息的递归处理
106
+ - 支持多语言配置,目前已提供中文语言包
81
107
 
82
108
  ## 🤝 贡献指南
83
109
 
@@ -1,5 +1,5 @@
1
1
  import { Config } from './index';
2
2
  import { CQCode } from '@pynickle/koishi-plugin-adapter-onebot';
3
3
  import { Message } from '@pynickle/koishi-plugin-adapter-onebot/lib/types';
4
- import { Context } from 'koishi';
5
- export declare function reconstructForwardMsg(ctx: Context, message: Message[], cfg: Config): Promise<CQCode[]>;
4
+ import { Context, Session } from 'koishi';
5
+ export declare function reconstructForwardMsg(ctx: Context, session: Session, message: Message[], cfg: Config): Promise<CQCode[]>;
package/lib/index.cjs CHANGED
@@ -219,7 +219,7 @@ function formatDate(date) {
219
219
  });
220
220
  }
221
221
 
222
- // src/image-helper.ts
222
+ // src/media-helper.ts
223
223
  var import_axios = __toESM(require("axios"), 1);
224
224
  var import_node_fs = require("node:fs");
225
225
  var import_node_path = __toESM(require("node:path"), 1);
@@ -275,16 +275,20 @@ async function saveMedia(ctx, mediaElement, type, cfg) {
275
275
  }
276
276
  async function processMediaElement(ctx, element, cfg) {
277
277
  if (element.type === "image" || element.type === "video" || element.type === "file") {
278
+ const savedPath = await saveMedia(
279
+ ctx,
280
+ element.data,
281
+ element.type,
282
+ cfg
283
+ );
284
+ const fileUri = `file:///${savedPath.replace(/\\/g, "/")}`;
278
285
  return {
279
286
  ...element,
280
287
  data: {
281
288
  ...element.data,
282
- url: await saveMedia(
283
- ctx,
284
- element.data,
285
- element.type,
286
- cfg
287
- )
289
+ file: fileUri,
290
+ // Remove the url field
291
+ url: void 0
288
292
  }
289
293
  };
290
294
  }
@@ -356,28 +360,39 @@ async function checkAndCleanMediaFiles(ctx, cfg, type) {
356
360
  }
357
361
 
358
362
  // src/forward-helper.ts
359
- async function reconstructForwardMsg(ctx, message, cfg) {
363
+ async function reconstructForwardMsg(ctx, session, message, cfg) {
360
364
  return Promise.all(
361
365
  message.map(async (msg) => {
362
- const content = await processForwardMessageContent(ctx, msg, cfg);
366
+ const content = await processForwardMessageContent(ctx, session, msg, cfg);
367
+ const senderNickname = msg.sender.nickname;
368
+ let senderUserId = msg.sender.user_id;
369
+ senderUserId = senderUserId === 1094950020 ? await getUserIdFromNickname(session, senderNickname, senderUserId) : senderUserId;
363
370
  return {
364
371
  type: "node",
365
372
  data: {
366
- user_id: msg.sender.user_id,
367
- nickname: msg.sender.nickname,
373
+ user_id: senderUserId,
374
+ nickname: senderNickname,
368
375
  content
369
376
  }
370
377
  };
371
378
  })
372
379
  );
373
380
  }
374
- async function processForwardMessageContent(ctx, msg, cfg) {
381
+ async function getUserIdFromNickname(session, nickname, userId) {
382
+ const memberInfos = await session.onebot.getGroupMemberList(session.channelId);
383
+ const matches = memberInfos.filter((m) => m.nickname === nickname);
384
+ if (matches.length === 1) {
385
+ return matches[0].user_id;
386
+ }
387
+ return userId;
388
+ }
389
+ async function processForwardMessageContent(ctx, session, msg, cfg) {
375
390
  if (typeof msg.message === "string") {
376
391
  return msg.message;
377
392
  }
378
393
  const firstElement = msg.message[0];
379
394
  if (firstElement?.type === "forward") {
380
- return reconstructForwardMsg(ctx, firstElement.data.content, cfg);
395
+ return reconstructForwardMsg(ctx, session, firstElement.data.content, cfg);
381
396
  }
382
397
  return Promise.all(
383
398
  msg.message.map(async (element) => {
@@ -400,9 +415,7 @@ async function processMessageContent(ctx, msg, cfg) {
400
415
 
401
416
  // src/index.ts
402
417
  var import_koishi_plugin_adapter_onebot2 = require("@pynickle/koishi-plugin-adapter-onebot");
403
- var import_fs = __toESM(require("fs"), 1);
404
418
  var import_koishi = require("koishi");
405
- var import_node_path2 = __toESM(require("node:path"), 1);
406
419
  var name = "echo-cave";
407
420
  var inject = ["database"];
408
421
  var Config = import_koishi.Schema.object({
@@ -418,10 +431,6 @@ var Config = import_koishi.Schema.object({
418
431
  });
419
432
  function apply(ctx, cfg) {
420
433
  ctx.i18n.define("zh-CN", require_zh_CN());
421
- const imgPath = import_node_path2.default.join(ctx.baseDir, "data", "cave", "images");
422
- if (!import_fs.default.existsSync(imgPath)) {
423
- import_fs.default.mkdirSync(imgPath, { recursive: true });
424
- }
425
434
  ctx.model.extend(
426
435
  "echo_cave",
427
436
  {
@@ -566,6 +575,7 @@ async function addCave(ctx, session, cfg) {
566
575
  type = "forward";
567
576
  const message = await reconstructForwardMsg(
568
577
  ctx,
578
+ session,
569
579
  await session.onebot.getForwardMsg(messageId),
570
580
  cfg
571
581
  );
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-echo-cave",
3
3
  "description": "Group echo cave",
4
- "version": "1.12.0",
4
+ "version": "1.12.2",
5
5
  "main": "lib/index.cjs",
6
6
  "typings": "lib/index.d.ts",
7
7
  "type": "module",
File without changes