koishi-plugin-forward-hime 1.4.2-alpha.2 → 1.4.4-alpha.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 (2) hide show
  1. package/lib/index.js +56 -5
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -411,12 +411,23 @@ function pickDefaultMime(kind) {
411
411
  return DEFAULT_IMAGE_MIME;
412
412
  case "audio":
413
413
  return DEFAULT_AUDIO_MIME;
414
- case "video":
415
- return DEFAULT_VIDEO_MIME;
416
414
  default:
417
415
  return DEFAULT_FILE_MIME;
418
416
  }
419
417
  }
418
+ function detectVideoMime(buffer) {
419
+ if (buffer.toString("ascii", 4, 8) === "ftyp") {
420
+ return buffer.toString("ascii", 8, 12) === "qt " ? "video/quicktime" : DEFAULT_VIDEO_MIME;
421
+ }
422
+ if (buffer.subarray(0, 4).equals(Buffer.from([26, 69, 223, 163]))) {
423
+ const header = buffer.toString("ascii", 0, 64);
424
+ if (header.includes("webm")) return "video/webm";
425
+ if (header.includes("matroska")) return "video/x-matroska";
426
+ }
427
+ if (buffer.toString("ascii", 0, 4) === "RIFF" && buffer.toString("ascii", 8, 12) === "AVI ") {
428
+ return "video/x-msvideo";
429
+ }
430
+ }
420
431
  function pickFilename(element, src) {
421
432
  const nameAttrs = ["filename", "name", "title", "file"];
422
433
  for (const key of nameAttrs) {
@@ -433,6 +444,18 @@ function pickFilename(element, src) {
433
444
  return "relay-file";
434
445
  }
435
446
  }
447
+ function pickVideoFilename(element, src, mime) {
448
+ const filename = pickFilename(element, src);
449
+ if (/^[^/\\:]+\.(mp4|mov|webm|mkv|avi)$/i.test(filename)) return filename;
450
+ const extensions = {
451
+ "video/mp4": "mp4",
452
+ "video/quicktime": "mov",
453
+ "video/webm": "webm",
454
+ "video/x-matroska": "mkv",
455
+ "video/x-msvideo": "avi"
456
+ };
457
+ return `video.${extensions[mime] || "bin"}`;
458
+ }
436
459
  function getCacheKey(element) {
437
460
  const mediaType = normalizeMediaType(element.type);
438
461
  const src = mediaUrlFromElement(element);
@@ -459,6 +482,13 @@ function createRelayElement(kind, mime, buffer, filename, targetPlatform) {
459
482
  const attrs = { file: filename, filename, title: filename };
460
483
  return targetPlatform === "discord" ? import_koishi5.h.image(buffer, mime, attrs) : helperMap.file(buffer, mime, attrs);
461
484
  }
485
+ if (kind === "video" && targetPlatform === "discord") {
486
+ return import_koishi5.h.image(buffer, mime, {
487
+ file: filename,
488
+ filename,
489
+ mode: "download"
490
+ });
491
+ }
462
492
  if (helperMap[kind]) {
463
493
  return helperMap[kind](buffer, mime);
464
494
  }
@@ -569,8 +599,9 @@ async function downloadAndRelay(element, traceId, session, node) {
569
599
  `\u5A92\u4F53\u6587\u4EF6\u8FC7\u5927\uFF08>${relayConfig.MaxFileSizeMB} MB\uFF09\uFF0C\u65E0\u6CD5\u4E2D\u8F6C\u53D1\u9001\u3002`
570
600
  );
571
601
  }
572
- const mime = response.headers.get("content-type")?.split(";")[0].trim() || pickDefaultMime(kind);
573
- const filename = kind === "file" || kind === "audio" ? pickFilename(element, src) : void 0;
602
+ const responseMime = response.headers.get("content-type")?.split(";")[0].trim();
603
+ const mime = kind === "video" && (!responseMime || responseMime === DEFAULT_FILE_MIME) ? detectVideoMime(buffer) || DEFAULT_FILE_MIME : responseMime || pickDefaultMime(kind);
604
+ const filename = kind === "video" ? pickVideoFilename(element, src, mime) : kind === "file" || kind === "audio" ? pickFilename(element, src) : void 0;
574
605
  const relayed = createRelayElement(kind, mime, buffer, filename, node?.Platform);
575
606
  relayCache.set(cacheKey, {
576
607
  expiresAt: Date.now() + relayConfig.CacheMinutes * 60 * 1e3,
@@ -631,9 +662,15 @@ async function relayForwardContent(content, traceId, session, node) {
631
662
  }
632
663
 
633
664
  // src/message.ts
665
+ var DeliveryUncertainError = class extends Error {
666
+ constructor(cause) {
667
+ super("message delivery status unknown", { cause });
668
+ }
669
+ };
634
670
  async function MessageSendWithDecorator(ctx2, node, session, Deco, traceId, attempt) {
635
671
  const startedAt = Date.now();
636
672
  const uuid = session.channelId + ":" + session.messageId;
673
+ let submitted = false;
637
674
  writeDiagnostic({
638
675
  traceId,
639
676
  phase: "send-attempt",
@@ -644,6 +681,7 @@ async function MessageSendWithDecorator(ctx2, node, session, Deco, traceId, atte
644
681
  });
645
682
  try {
646
683
  const content = await Deco(session, node, traceId);
684
+ submitted = true;
647
685
  const res = await ctx2.bots[`${node.Platform}:${node.BotID}`].sendMessage(
648
686
  node.Guild,
649
687
  content
@@ -686,7 +724,7 @@ async function MessageSendWithDecorator(ctx2, node, session, Deco, traceId, atte
686
724
  logger.error(
687
725
  `ERROR:<MessageSendWithDecorator ${node.Platform}> ctx=${ctx2} ${error}`
688
726
  );
689
- throw error;
727
+ throw submitted ? new DeliveryUncertainError(error) : error;
690
728
  }
691
729
  }
692
730
  function sessionTypeArray(session) {
@@ -771,6 +809,10 @@ async function MessageForward(ctx2, node, session, timeoutSec, relayEnabled) {
771
809
  logger.error(
772
810
  `ERROR:<MessageSend ${node.Platform}> ctx=${ctx2} ${sessionTypeArray(session)} ${firstError}`
773
811
  );
812
+ if (firstError instanceof DeliveryUncertainError) {
813
+ writeDiagnostic({ traceId, phase: "forward-uncertain", source, target });
814
+ return;
815
+ }
774
816
  if (relayEnabled !== false && firstError instanceof MediaRelayError) {
775
817
  logger.info(
776
818
  `[MessageForward] relay failed, retrying without relay: ${node.Platform}`
@@ -788,6 +830,15 @@ async function MessageForward(ctx2, node, session, timeoutSec, relayEnabled) {
788
830
  logger.error(
789
831
  `ERROR:<MessageSendDirect ${node.Platform}> ctx=${ctx2} ${sessionTypeArray(session)} ${secondError}`
790
832
  );
833
+ if (secondError instanceof DeliveryUncertainError) {
834
+ writeDiagnostic({
835
+ traceId,
836
+ phase: "forward-uncertain",
837
+ source,
838
+ target
839
+ });
840
+ return;
841
+ }
791
842
  sendDegraded(reasonFromError(secondError));
792
843
  });
793
844
  } else {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-forward-hime",
3
3
  "description": "多群组消息互通",
4
- "version": "1.4.2-alpha.2",
4
+ "version": "1.4.4-alpha.0",
5
5
  "author": {
6
6
  "name": "xianii",
7
7
  "email": "jiyucheng007@gmail.com"