koishi-plugin-echo-cave 1.1.1 → 1.3.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,4 @@
1
+ import { CQCode } from '@pynickle/koishi-plugin-adapter-onebot';
2
+ import { Message } from '@pynickle/koishi-plugin-adapter-onebot/lib/types';
3
+ import { Context } from 'koishi';
4
+ export declare function reconstructForwardMsg(ctx: Context, message: Message[]): Promise<CQCode[]>;
@@ -1,2 +1,2 @@
1
- import { Context, Session, h } from 'koishi';
2
- export declare function saveImages(ctx: Context, session: Session, imgElement: h): Promise<string>;
1
+ import { Context } from 'koishi';
2
+ export declare function saveImages(ctx: Context, imgElement: Record<string, any>): Promise<string>;
package/lib/index.cjs CHANGED
@@ -35,15 +35,17 @@ __export(index_exports, {
35
35
  name: () => name
36
36
  });
37
37
  module.exports = __toCommonJS(index_exports);
38
+ var import_koishi_plugin_adapter_onebot = require("@pynickle/koishi-plugin-adapter-onebot");
39
+ var import_fs = __toESM(require("fs"), 1);
38
40
  var import_koishi = require("koishi");
39
- var import_koishi_plugin_adapter_onebot = require("koishi-plugin-adapter-onebot");
41
+ var import_node_path2 = __toESM(require("node:path"), 1);
40
42
 
41
43
  // src/image-helper.ts
42
44
  var import_node_fs = require("node:fs");
43
45
  var import_node_path = __toESM(require("node:path"), 1);
44
- async function saveImages(ctx, session, imgElement) {
45
- const imgUrl = imgElement.attrs.src;
46
- const originalImgName = imgElement.attrs.file;
46
+ async function saveImages(ctx, imgElement) {
47
+ const imgUrl = imgElement.url;
48
+ const originalImgName = imgElement.file;
47
49
  const lastDotIndex = originalImgName.lastIndexOf(".");
48
50
  let imgExt = "";
49
51
  if (lastDotIndex === -1) {
@@ -52,20 +54,77 @@ async function saveImages(ctx, session, imgElement) {
52
54
  imgExt = originalImgName.substring(lastDotIndex + 1);
53
55
  }
54
56
  const imgPath = import_node_path.default.join(ctx.baseDir, "data", "cave", "images");
55
- const imgName = (/* @__PURE__ */ new Date()).toISOString();
57
+ const imgName = (/* @__PURE__ */ new Date()).getTime().toString();
56
58
  let fullImgPath = import_node_path.default.join(imgPath, `${imgName}.${imgExt}`);
57
- ctx.logger.info(`Saving image from URL: ${imgUrl} to path: ${fullImgPath}`);
59
+ ctx.logger.info(
60
+ `Saving image from URL: ${imgUrl} to path: ${imgName}.${imgExt}`
61
+ );
58
62
  const buffer = await ctx.http.get(imgUrl);
59
63
  if (buffer.byteLength === 0) throw new Error("Image download failed");
60
64
  await import_node_fs.promises.writeFile(fullImgPath, Buffer.from(buffer));
61
65
  return fullImgPath;
62
66
  }
63
67
 
68
+ // src/forward-helper.ts
69
+ async function reconstructForwardMsg(ctx, message) {
70
+ return Promise.all(
71
+ message.map(async (msg) => {
72
+ const content = await processMessageContent(ctx, msg);
73
+ return {
74
+ type: "node",
75
+ data: {
76
+ user_id: msg.sender.user_id,
77
+ nick_name: msg.sender.nickname,
78
+ content
79
+ }
80
+ };
81
+ })
82
+ );
83
+ }
84
+ async function processMessageContent(ctx, msg) {
85
+ if (typeof msg.message === "string") {
86
+ return msg.message;
87
+ }
88
+ const firstElement = msg.message[0];
89
+ if (firstElement?.type === "forward") {
90
+ return reconstructForwardMsg(ctx, firstElement.data.content);
91
+ }
92
+ return Promise.all(
93
+ msg.message.map(async (element) => {
94
+ if (element.type === "image") {
95
+ return {
96
+ ...element,
97
+ data: {
98
+ ...element.data,
99
+ url: await saveImages(ctx, element.data)
100
+ }
101
+ };
102
+ }
103
+ return element;
104
+ })
105
+ );
106
+ }
107
+
108
+ // src/msg-helper.ts
109
+ async function sendCaveMsg(session, caveMsg) {
110
+ const { channelId } = session;
111
+ const content = JSON.parse(caveMsg.content);
112
+ if (caveMsg.type === "forward") {
113
+ await session.onebot.sendGroupForwardMsg(channelId, content);
114
+ } else {
115
+ await session.onebot.sendGroupMsg(channelId, content);
116
+ }
117
+ }
118
+
64
119
  // src/index.ts
65
120
  var name = "echo-cave";
66
121
  var inject = ["database"];
67
122
  var Config = import_koishi.Schema.object({});
68
123
  function apply(ctx) {
124
+ const imgPath = import_node_path2.default.join(ctx.baseDir, "data", "cave", "images");
125
+ if (!import_fs.default.existsSync(imgPath)) {
126
+ import_fs.default.mkdirSync(imgPath, { recursive: true });
127
+ }
69
128
  ctx.model.extend(
70
129
  "echo_cave",
71
130
  {
@@ -74,7 +133,8 @@ function apply(ctx) {
74
133
  createTime: "timestamp",
75
134
  userId: "string",
76
135
  originUserId: "string",
77
- content: "string"
136
+ type: "string",
137
+ content: "text"
78
138
  },
79
139
  {
80
140
  primary: "id",
@@ -82,25 +142,50 @@ function apply(ctx) {
82
142
  unique: ["content"]
83
143
  }
84
144
  );
85
- ctx.command("cave", "\u968F\u673A\u83B7\u53D6\u56DE\u58F0\u6D1E\u6D88\u606F").action(
86
- async ({ session }) => await getCave(ctx, session)
87
- );
145
+ ctx.command(
146
+ "cave [id:number]",
147
+ "\u968F\u673A\u83B7\u53D6 / \u83B7\u53D6\u7279\u5B9A id \u7684\u56DE\u58F0\u6D1E\u4FE1\u606F"
148
+ ).action(async ({ session }, id) => await getCave(ctx, session, id));
88
149
  ctx.command("cave.echo", "\u5C06\u6D88\u606F\u5B58\u5165\u56DE\u58F0\u6D1E\u7A74").action(
89
150
  async ({ session }) => await addCave(ctx, session)
90
151
  );
152
+ ctx.command("cave.wipe <id:number>", "\u62B9\u53BB\u7279\u5B9A id \u7684\u56DE\u58F0\u6D1E\u4FE1\u606F", {
153
+ authority: 4
154
+ }).action(async ({ session }, id) => await deleteCave(ctx, session, id));
91
155
  }
92
- async function getCave(ctx, session) {
156
+ async function getCave(ctx, session, id) {
93
157
  if (!session.guildId) {
94
158
  return "\u274C \u8BF7\u5728\u7FA4\u804A\u4E2D\u4F7F\u7528\u8BE5\u547D\u4EE4\uFF01";
95
159
  }
96
- const { channelId } = session;
97
- const caves = await ctx.database.get("echo_cave", {
98
- channelId
99
- });
160
+ let caveMsg;
161
+ if (!id) {
162
+ const { channelId } = session;
163
+ const caves = await ctx.database.get("echo_cave", {
164
+ channelId
165
+ });
166
+ if (caves.length === 0) {
167
+ return '\u{1F680} \u56DE\u58F0\u6D1E\u4E2D\u6682\u65E0\u6D88\u606F\uFF0C\u5FEB\u4F7F\u7528 "cave.echo" \u547D\u4EE4\u6DFB\u52A0\u7B2C\u4E00\u6761\u6D88\u606F\u5427\uFF01';
168
+ }
169
+ caveMsg = caves[Math.floor(Math.random() * caves.length)];
170
+ } else {
171
+ const caves = await ctx.database.get("echo_cave", id);
172
+ if (caves.length === 0) {
173
+ return "\u{1F50D} \u672A\u627E\u5230\u8BE5 ID \u7684\u56DE\u58F0\u6D1E\u6D88\u606F";
174
+ }
175
+ caveMsg = caves[0];
176
+ }
177
+ await sendCaveMsg(session, caveMsg);
178
+ }
179
+ async function deleteCave(ctx, session, id) {
180
+ if (!session.guildId) {
181
+ return "\u274C \u8BF7\u5728\u7FA4\u804A\u4E2D\u4F7F\u7528\u8BE5\u547D\u4EE4\uFF01";
182
+ }
183
+ const caves = await ctx.database.get("echo_cave", id);
100
184
  if (caves.length === 0) {
101
- return '\u{1F680} \u56DE\u58F0\u6D1E\u4E2D\u6682\u65E0\u6D88\u606F\uFF0C\u5FEB\u4F7F\u7528 "cave.echo" \u547D\u4EE4\u6DFB\u52A0\u7B2C\u4E00\u6761\u6D88\u606F\u5427\uFF01';
185
+ return "\u{1F50D} \u672A\u627E\u5230\u8BE5 ID \u7684\u56DE\u58F0\u6D1E\u6D88\u606F";
102
186
  }
103
- return import_koishi.h.parse(caves[Math.floor(Math.random() * caves.length)].content);
187
+ await ctx.database.remove("echo_cave", id);
188
+ return `\u2705 \u5DF2\u6210\u529F\u62B9\u53BB\u56DE\u58F0\u6D1E\u6D88\u606F ID\uFF1A${id}`;
104
189
  }
105
190
  async function addCave(ctx, session) {
106
191
  if (!session.guildId) {
@@ -110,16 +195,22 @@ async function addCave(ctx, session) {
110
195
  return "\u{1F4A1} \u8BF7\u5F15\u7528\u4E00\u6761\u6D88\u606F\u540E\u518D\u4F7F\u7528\u6B64\u547D\u4EE4\uFF01";
111
196
  }
112
197
  const { userId, channelId, quote } = session;
113
- const elements = quote.elements;
114
- elements.forEach((element) => {
115
- ctx.logger("echo-cave").info(
116
- `Processing element type: ${element.type}`
198
+ const messageId = quote.id;
199
+ let content;
200
+ let type;
201
+ if (quote.elements[0].type === "forward") {
202
+ type = "forward";
203
+ const message = await reconstructForwardMsg(
204
+ ctx,
205
+ await session.onebot.getForwardMsg(messageId)
117
206
  );
118
- if (element.type === "img") {
119
- element.attrs.src = saveImages(ctx, session, element);
120
- }
121
- });
122
- const content = JSON.stringify(elements);
207
+ content = JSON.stringify(message);
208
+ } else {
209
+ type = "msg";
210
+ content = JSON.stringify(
211
+ (await session.onebot.getMsg(messageId)).message
212
+ );
213
+ }
123
214
  await ctx.database.get("echo_cave", { content }).then((existing) => {
124
215
  if (existing) {
125
216
  return "\u267B\uFE0F \u8BE5\u6D88\u606F\u5DF2\u5B58\u5728\u4E8E\u56DE\u58F0\u6D1E\u7A74\u4E2D\uFF01";
@@ -131,20 +222,17 @@ async function addCave(ctx, session) {
131
222
  createTime: /* @__PURE__ */ new Date(),
132
223
  userId,
133
224
  originUserId: quote.user.id,
225
+ type,
134
226
  content
135
227
  });
136
- if (session.onebot) {
137
- const messageId = await session.onebot.sendGroupMsg(
138
- session.channelId,
139
- `\u2705 \u56DE\u58F0\u6D1E\u6D88\u606F\u5DF2\u6210\u529F\u5B58\u5165\uFF0C\u6D88\u606F ID\uFF1A${result.id}`
140
- );
141
- ctx.setTimeout(
142
- async () => await session.onebot.deleteMsg(messageId),
143
- 5e3
144
- );
145
- } else {
146
- return `\u2705 \u56DE\u58F0\u6D1E\u6D88\u606F\u5DF2\u6210\u529F\u5B58\u5165\uFF0C\u6D88\u606F ID\uFF1A${result.id}`;
147
- }
228
+ const messageId2 = await session.onebot.sendGroupMsg(
229
+ session.channelId,
230
+ `\u2705 \u56DE\u58F0\u6D1E\u6D88\u606F\u5DF2\u6210\u529F\u5B58\u5165\uFF0C\u6D88\u606F ID\uFF1A${result.id}`
231
+ );
232
+ ctx.setTimeout(
233
+ async () => await session.onebot.deleteMsg(messageId2),
234
+ 5e3
235
+ );
148
236
  } catch (error) {
149
237
  this.ctx.logger.warn("\u4E0A\u67B6\u5546\u54C1\u5931\u8D25:", error);
150
238
  return "\u274C \u4E0A\u67B6\u5546\u54C1\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\uFF01";
package/lib/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
+ import '@pynickle/koishi-plugin-adapter-onebot';
1
2
  import { Context, Schema } from 'koishi';
2
- import 'koishi-plugin-adapter-onebot';
3
3
  export declare const name = "echo-cave";
4
4
  export declare const inject: string[];
5
5
  export interface Config {
@@ -11,6 +11,7 @@ export interface EchoCave {
11
11
  createTime: Date;
12
12
  userId: string;
13
13
  originUserId: string;
14
+ type: 'forward' | 'msg';
14
15
  content: string;
15
16
  }
16
17
  declare module 'koishi' {
@@ -0,0 +1,3 @@
1
+ import { Session } from 'koishi';
2
+ import { EchoCave } from './index';
3
+ export declare function sendCaveMsg(session: Session, caveMsg: EchoCave): Promise<void>;
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.1.1",
4
+ "version": "1.3.0",
5
5
  "main": "lib/index.cjs",
6
6
  "typings": "lib/index.d.ts",
7
7
  "type": "module",
@@ -23,8 +23,8 @@
23
23
  "cave"
24
24
  ],
25
25
  "peerDependencies": {
26
- "koishi": "^4.18.9",
27
- "koishi-plugin-adapter-onebot": "^6.8.0"
26
+ "@pynickle/koishi-plugin-adapter-onebot": "^1.0.0",
27
+ "koishi": "^4.18.9"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@semantic-release/changelog": "^6.0.3",