(quoteMessages: any[], args: QuoteArgs)
| 990 | : kind === "voice" || kind === "audio" |
| 991 | ? duration |
| 992 | : undefined; |
| 993 | |
| 994 | // Glass: voice/document/audio → in-bubble rows; photo/sticker/video/gif → mediaCanvas + badges |
| 995 | const wantsVisual = |
| 996 | args.media || |
| 997 | args.img || |
| 998 | kind === "photo" || |
| 999 | kind === "sticker" || |
| 1000 | kind === "animation" || |
| 1001 | kind === "video" || |
| 1002 | kind === "round"; |
| 1003 | const mediaBuffer = await downloadMessageMedia(msg, !!wantsVisual); |
| 1004 | const mediaCanvas = await mediaBufferToCanvas(mediaBuffer, kind); |
| 1005 | const isSticker = kind === "sticker"; |
| 1006 | |
| 1007 | let document: { file_name: string; file_size?: number } | undefined; |
| 1008 | let audio: { title?: string; performer?: string; duration?: number; thumb?: any } | undefined; |
| 1009 | if (kind === "document") { |
| 1010 | const doc = (msg as any).document ?? (msg as any).media?.document; |
| 1011 | const attrs = Array.isArray(doc?.attributes) ? doc.attributes : getDocumentAttributes(msg); |
| 1012 | const fn = attrs.find( |
| 1013 | (a: any) => |
| 1014 | (a.className || a.constructor?.name || "").includes("Filename") || |
| 1015 | a.fileName || |
| 1016 | a.file_name, |
| 1017 | ); |
| 1018 | const name = String(fn?.fileName || fn?.file_name || "file"); |
| 1019 | document = { |
| 1020 | file_name: name, |
| 1021 | file_size: Number(doc?.size ?? 0) || undefined, |
| 1022 | }; |
| 1023 | } else if (kind === "audio") { |
| 1024 | const title = voiceAttr?.title || voiceAttr?.fileName || voiceAttr?.file_name || "Audio"; |
| 1025 | const performer = voiceAttr?.performer || voiceAttr?.artist; |
| 1026 | audio = { title, performer, duration }; |
| 1027 | } |
| 1028 | |
| 1029 | // Normalize mediaType for vendor badges (video play / GIF chip) |
| 1030 | let mediaType = mediaCanvas ? (kind || "photo") : kind; |
| 1031 | if (mediaType === "animation") mediaType = "gif"; |
| 1032 | if (mediaType === "round") mediaType = "video"; |
| 1033 | |
| 1034 | return { |
| 1035 | mediaBuffer, |
| 1036 | mediaCanvas, |
| 1037 | mediaType, |
| 1038 | mediaMaxSize: isSticker ? 220 * (args.scale || 2) : undefined, |
| 1039 | mediaCrop: isSticker ? false : args.crop, |
| 1040 | mediaDuration, |
| 1041 | voice: waveform ? { waveform, duration } : undefined, |
| 1042 | document, |
| 1043 | audio, |
| 1044 | }; |
| 1045 | } |
| 1046 | |
| 1047 | |
| 1048 | function execFileAsync(cmd: string, args: string[], timeout = 10000): Promise<void> { |
| 1049 | return new Promise((resolve, reject) => { |
nothing calls this directly
no test coverage detected