koishi-plugin-echo-cave 1.10.3 → 1.11.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.
@@ -1,2 +1,3 @@
1
1
  import { Context } from 'koishi';
2
- export declare function saveImages(ctx: Context, imgElement: Record<string, any>): Promise<string>;
2
+ export declare function saveMedia(ctx: Context, mediaElement: Record<string, any>, type: 'image' | 'video' | 'file'): Promise<string>;
3
+ export declare function processMediaElement(ctx: Context, element: any): Promise<any>;
package/lib/index.cjs CHANGED
@@ -167,7 +167,8 @@ async function sendCaveMsg(ctx, session, caveMsg) {
167
167
  id: caveMsg.id.toString(),
168
168
  date,
169
169
  originName,
170
- userName
170
+ userName,
171
+ nl: "\n"
171
172
  };
172
173
  const TEMPLATE_COUNT = 5;
173
174
  if (caveMsg.type === "forward") {
@@ -218,44 +219,66 @@ function formatDate(date) {
218
219
  var import_axios = __toESM(require("axios"), 1);
219
220
  var import_node_fs = require("node:fs");
220
221
  var import_node_path = __toESM(require("node:path"), 1);
221
- async function saveImages(ctx, imgElement) {
222
- const imgUrl = imgElement.url;
223
- const originalImgName = imgElement.file;
222
+ async function saveMedia(ctx, mediaElement, type) {
223
+ const mediaUrl = mediaElement.url;
224
+ const originalMediaName = mediaElement.file;
224
225
  const ext = (() => {
225
- const i = originalImgName.lastIndexOf(".");
226
- return i === -1 ? "png" : originalImgName.slice(i + 1).toLowerCase();
226
+ const i = originalMediaName.lastIndexOf(".");
227
+ return i === -1 ? type === "image" ? "png" : type === "video" ? "mp4" : "bin" : originalMediaName.slice(i + 1).toLowerCase();
227
228
  })();
228
- const imgDir = import_node_path.default.join(ctx.baseDir, "data", "cave", "images");
229
- const imgName = Date.now().toString();
230
- const fullImgPath = import_node_path.default.join(imgDir, `${imgName}.${ext}`);
231
- ctx.logger.info(`Saving image from ${imgUrl} -> ${fullImgPath}`);
229
+ const mediaDir = import_node_path.default.join(ctx.baseDir, "data", "cave", type + "s");
230
+ const mediaName = Date.now().toString();
231
+ const fullMediaPath = import_node_path.default.join(mediaDir, `${mediaName}.${ext}`);
232
+ ctx.logger.info(`Saving ${type} from ${mediaUrl} -> ${fullMediaPath}`);
232
233
  try {
233
- await import_node_fs.promises.mkdir(imgDir, { recursive: true });
234
- const res = await import_axios.default.get(imgUrl, {
234
+ await import_node_fs.promises.mkdir(mediaDir, { recursive: true });
235
+ const res = await import_axios.default.get(mediaUrl, {
235
236
  responseType: "arraybuffer",
236
237
  validateStatus: () => true
237
238
  });
238
239
  if (res.status < 200 || res.status >= 300) {
239
- ctx.logger.warn(`Image download failed: HTTP ${res.status}`);
240
- return imgUrl;
240
+ ctx.logger.warn(
241
+ `${type.charAt(0).toUpperCase() + type.slice(1)} download failed: HTTP ${res.status}`
242
+ );
243
+ return mediaUrl;
241
244
  }
242
- const type = res.headers["content-type"];
243
- if (!type || !type.startsWith("image/")) {
244
- ctx.logger.warn(`Invalid image content-type: ${type}`);
245
- return imgUrl;
245
+ const contentType = res.headers["content-type"];
246
+ if (contentType) {
247
+ if (type === "image" && !contentType.startsWith("image/")) {
248
+ ctx.logger.warn(`Invalid image content-type: ${contentType}`);
249
+ return mediaUrl;
250
+ }
251
+ if (type === "video" && !contentType.startsWith("video/")) {
252
+ ctx.logger.warn(`Invalid video content-type: ${contentType}`);
253
+ return mediaUrl;
254
+ }
246
255
  }
247
256
  const buffer = Buffer.from(res.data);
248
257
  if (!buffer || buffer.length === 0) {
249
- ctx.logger.warn("Downloaded image buffer is empty");
250
- return imgUrl;
258
+ ctx.logger.warn(`Downloaded ${type} buffer is empty`);
259
+ return mediaUrl;
251
260
  }
252
- await import_node_fs.promises.writeFile(fullImgPath, buffer);
253
- ctx.logger.info(`Image saved successfully: ${fullImgPath}`);
254
- return fullImgPath;
261
+ await import_node_fs.promises.writeFile(fullMediaPath, buffer);
262
+ ctx.logger.info(
263
+ `${type.charAt(0).toUpperCase() + type.slice(1)} saved successfully: ${fullMediaPath}`
264
+ );
265
+ return fullMediaPath;
255
266
  } catch (err) {
256
- ctx.logger.error(`Failed to save image: ${err}`);
257
- return imgUrl;
267
+ ctx.logger.error(`Failed to save ${type}: ${err}`);
268
+ return mediaUrl;
269
+ }
270
+ }
271
+ async function processMediaElement(ctx, element) {
272
+ if (element.type === "image" || element.type === "video" || element.type === "file") {
273
+ return {
274
+ ...element,
275
+ data: {
276
+ ...element.data,
277
+ url: await saveMedia(ctx, element.data, element.type)
278
+ }
279
+ };
258
280
  }
281
+ return element;
259
282
  }
260
283
 
261
284
  // src/forward-helper.ts
@@ -284,41 +307,21 @@ async function processForwardMessageContent(ctx, msg) {
284
307
  }
285
308
  return Promise.all(
286
309
  msg.message.map(async (element) => {
287
- if (element.type === "image") {
288
- return {
289
- ...element,
290
- data: {
291
- ...element.data,
292
- url: await saveImages(ctx, element.data)
293
- }
294
- };
295
- }
296
- return element;
310
+ return processMediaElement(ctx, element);
297
311
  })
298
312
  );
299
313
  }
300
314
 
301
315
  // src/msg-helper.ts
302
316
  async function processMessageContent(ctx, msg) {
303
- const result = [];
304
- for (const element of msg) {
305
- if (element.type === "reply") {
306
- continue;
307
- }
308
- if (element.type === "image") {
309
- const newUrl = await saveImages(ctx, element.data);
310
- result.push({
311
- ...element,
312
- data: {
313
- ...element.data,
314
- url: newUrl
315
- }
316
- });
317
- } else {
318
- result.push(element);
319
- }
320
- }
321
- return result;
317
+ return Promise.all(
318
+ msg.map(async (element) => {
319
+ if (element.type === "reply") {
320
+ return element;
321
+ }
322
+ return processMediaElement(ctx, element);
323
+ })
324
+ );
322
325
  }
323
326
 
324
327
  // src/index.ts
@@ -495,6 +498,9 @@ async function addCave(ctx, session) {
495
498
  if (typeof message === "string") {
496
499
  msgJson = import_koishi_plugin_adapter_onebot2.CQCode.parse(message);
497
500
  } else {
501
+ if (message[0].type === "video" || message[0].type === "file") {
502
+ type = "forward";
503
+ }
498
504
  msgJson = message;
499
505
  }
500
506
  content = JSON.stringify(await processMessageContent(ctx, msgJson));
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.10.3",
4
+ "version": "1.11.0",
5
5
  "main": "lib/index.cjs",
6
6
  "typings": "lib/index.d.ts",
7
7
  "type": "module",