Files
openswarm/backend/apps/channels/media_handler.py
T

61 lines
1.8 KiB
Python

"""Audio attachment processing for WhatsApp voice notes and media messages."""
import logging
from typing import Optional
import httpx
from backend.apps.channels.models import STTConfig
from backend.apps.channels import stt_service
logger = logging.getLogger(__name__)
SUPPORTED_FORMATS = {
"audio/ogg", "audio/mpeg", "audio/wav", "audio/mp4",
"audio/flac", "audio/webm", "audio/x-wav",
}
MAX_MEDIA_BYTES = 20 * 1024 * 1024
async def process_audio_attachment(
url: str,
content_type: str,
stt_config: STTConfig,
auth: tuple[str, str] | None = None,
) -> Optional[str]:
"""Download an audio attachment and return its transcript.
Args:
url: URL to download the audio from.
content_type: MIME type of the audio.
stt_config: STT configuration for transcription.
auth: Optional (username, password) tuple for basic auth (e.g. Twilio).
Returns:
Transcript string, or None on failure.
"""
if content_type not in SUPPORTED_FORMATS:
logger.warning("Unsupported audio format: %s", content_type)
return None
try:
async with httpx.AsyncClient(timeout=60) as client:
kwargs = {"follow_redirects": True}
if auth:
kwargs["auth"] = auth
resp = await client.get(url, **kwargs)
resp.raise_for_status()
audio_bytes = resp.content
except Exception:
logger.exception("Failed to download audio from %s", url)
return None
if len(audio_bytes) > MAX_MEDIA_BYTES:
logger.warning("Audio attachment exceeds %d bytes", MAX_MEDIA_BYTES)
return None
if len(audio_bytes) < 1024:
logger.debug("Audio attachment too small, skipping")
return None
return await stt_service.transcribe(audio_bytes, stt_config, content_type)