fix(talkbot): retry failed voice message processing

Este commit está contenido en:
2026-09-05 15:18:42 +02:00
padre 11d64a600d
commit 6062c76cf8
+46 -31
Ver fichero
@@ -4,6 +4,7 @@ import os
import re
import sqlite3
import subprocess
import tempfile
import threading
from datetime import datetime, timedelta, timezone
from typing import Optional
@@ -492,40 +493,53 @@ def is_blank_transcription(text: str) -> bool:
def convert_audio_to_wav(audio_bytes: bytes) -> bytes:
"""Convert any FFmpeg-supported audio format to Whisper's WAV format."""
try:
result = subprocess.run(
[
"ffmpeg",
"-hide_banner",
"-loglevel",
"error",
"-i",
"pipe:0",
"-vn",
"-ac",
"1",
"-ar",
"16000",
"-c:a",
"pcm_s16le",
"-f",
"wav",
"pipe:1",
],
input=audio_bytes,
capture_output=True,
check=False,
timeout=120,
)
except FileNotFoundError as exc:
raise RuntimeError("ffmpeg is not installed in the talkbot container") from exc
except subprocess.TimeoutExpired as exc:
raise RuntimeError("Audio conversion with ffmpeg timed out") from exc
# Use a temporary file instead of stdin: MP4-based audio often has its
# metadata (moov atom) at the end and requires seeking during probing.
with tempfile.NamedTemporaryFile(
prefix="talkbot-input-",
suffix=".audio",
) as input_file:
input_file.write(audio_bytes)
input_file.flush()
try:
result = subprocess.run(
[
"ffmpeg",
"-hide_banner",
"-loglevel",
"error",
"-i",
input_file.name,
"-vn",
"-ac",
"1",
"-ar",
"16000",
"-c:a",
"pcm_s16le",
"-f",
"wav",
"pipe:1",
],
capture_output=True,
check=False,
timeout=120,
)
except FileNotFoundError as exc:
raise RuntimeError(
"ffmpeg is not installed in the talkbot container"
) from exc
except subprocess.TimeoutExpired as exc:
raise RuntimeError("Audio conversion with ffmpeg timed out") from exc
if result.returncode != 0 or not result.stdout:
error = result.stderr.decode("utf-8", errors="replace").strip()
raise RuntimeError(f"Unable to convert audio to WAV: {error[:500]}")
if len(result.stdout) <= 78:
raise RuntimeError("Audio conversion produced an empty WAV file")
log.info(
"Audio converted to WAV: %s -> %s bytes",
len(audio_bytes),
@@ -1198,8 +1212,9 @@ def process_event(job: dict) -> None:
message_id,
exc,
)
return
# Let event_worker() reschedule the queued job. If we return here,
# the worker considers the event successful and removes it.
raise
if message_text:
log.info(