From 64107b897570bdf019e89400140b40bca9d44909 Mon Sep 17 00:00:00 2001 From: Nick Yu Date: Wed, 25 Mar 2026 14:28:25 -0700 Subject: [PATCH] Return "pending" for voice media not yet available in DB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When voice data hasn't been written to media_*.db yet, return type="pending" instead of "unsupported". The extension's pollMedia already retries when data is missing — but short-circuits on "unsupported". This lets voice messages be retried correctly. Co-Authored-By: Claude Opus 4.6 (1M context) --- .changeset/voice-media-pending.md | 6 ++++ .../src/tools/wechat_media.rs | 30 +++++++++---------- packages/cli/src/cli.ts | 4 +++ packages/shared/src/types/index.ts | 2 +- 4 files changed, 25 insertions(+), 17 deletions(-) create mode 100644 .changeset/voice-media-pending.md diff --git a/.changeset/voice-media-pending.md b/.changeset/voice-media-pending.md new file mode 100644 index 0000000..b7493be --- /dev/null +++ b/.changeset/voice-media-pending.md @@ -0,0 +1,6 @@ +--- +"@agent-wechat/agent-server": patch +"@agent-wechat/wechat": patch +--- + +Return "pending" instead of "unsupported" when voice data is not yet available in the database, so the extension retries instead of giving up. diff --git a/packages/agent-server-rust/src/tools/wechat_media.rs b/packages/agent-server-rust/src/tools/wechat_media.rs index babe77a..e0eecd2 100644 --- a/packages/agent-server-rust/src/tools/wechat_media.rs +++ b/packages/agent-server-rust/src/tools/wechat_media.rs @@ -25,6 +25,16 @@ fn unsupported() -> MediaResult { } } +fn pending() -> MediaResult { + MediaResult { + media_type: "pending".into(), + data: None, + url: None, + format: String::new(), + filename: String::new(), + } +} + fn account_base_paths(account_dir: &str) -> [String; 2] { [ format!("/home/wechat/xwechat_files/{account_dir}"), @@ -582,15 +592,9 @@ fn get_video_data( return thumb; } - // Video exists but no file found on disk + // Video exists but no file found on disk yet tracing::warn!("[media:video] no video file found for local_id={}", local_id); - MediaResult { - media_type: "video".into(), - data: None, - url: None, - format: "mp4".into(), - filename: format!("msg_{local_id}.mp4"), - } + pending() } /// Extract the 32-char hex file hash from a MessageResourceInfo packed_info blob. @@ -855,7 +859,7 @@ fn get_voice_data( }; } - unsupported() + pending() } // ── File attachment ────────────────────────────────────────────────────────── @@ -895,13 +899,7 @@ fn get_file_attachment( } // File not yet downloaded by WeChat - MediaResult { - media_type: "file".into(), - data: None, - url: None, - format: ext, - filename, - } + pending() } // ── Public entry point ─────────────────────────────────────────────────────── diff --git a/packages/cli/src/cli.ts b/packages/cli/src/cli.ts index ef2997a..4443abe 100644 --- a/packages/cli/src/cli.ts +++ b/packages/cli/src/cli.ts @@ -692,6 +692,10 @@ async function cmdMedia(client: WeChatClient, chatId: string, localId: number, o console.error("No media found for this message (unsupported type or not found)."); process.exit(1); } + if (result.type === "pending") { + console.error("Media not yet available. WeChat may still be downloading it — try again shortly."); + process.exit(1); + } const outFile = outputPath ?? result.filename; diff --git a/packages/shared/src/types/index.ts b/packages/shared/src/types/index.ts index 050a797..cdb56fd 100644 --- a/packages/shared/src/types/index.ts +++ b/packages/shared/src/types/index.ts @@ -132,7 +132,7 @@ export interface GetMediaParams { // Note: MediaResult kept handwritten (Rust uses plain string for type, // TS has richer string literal union) export interface MediaResult { - type: "image" | "emoji" | "voice" | "file" | "video" | "unsupported"; + type: "image" | "emoji" | "voice" | "file" | "video" | "pending" | "unsupported"; data?: string; // base64 for image/voice/file url?: string; // CDN URL for emoji format: string;