Hola a todos,
Estoy construyendo un flujo de trabajo en n8n para un proyecto de curso y estoy atascado en el paso final de transcripción de audio.
El objetivo es:
Recibir un mensaje de voz desde Telegram
Descargar el audio usando Telegram → Get a File (via file_id)
Convertir el audio a texto (speech-to-text)
Enviar la transcripción a un Agente de IA
Pregunta
¿Cuál es la forma recomendada y confiable en n8n para: tomar un mensaje de voz de Telegram (.oga / opus) enviarlo a una API de speech-to-text que no sea de OpenAI (por ejemplo, Groq Whisper o similar) y obtener una salida de transcripción estable
Especialmente interesado en:
buenas prácticas para manejar archivos de audio binarios de Telegram
si hay limitaciones conocidas con multipart/form-data en el nodo HTTP Request
soluciones alternativas recomendadas si la carga binaria directa no es confiable
Cualquier patrón funcional o ejemplo de flujo de trabajo sería muy apreciado
¿Cuál es el mensaje de error (si corresponde)?
Dónde estoy atascado
En esta etapa:
Telegram → Get a File funciona correctamente
Recibo el archivo de audio binario (.oga, audio/ogg)
El flujo de trabajo se interrumpe al intentar enviar este archivo a una API Whisper/STT
Probé múltiples enfoques:
Nodo HTTP Request con Form-Data + archivo binario
Nodo Code con fetch + FormData
diferentes asignaciones binarias en n8n
Pero siempre obtengo errores como:
file must be one of [flac mp3 mp4 mpeg mpga m4a ogg opus wav webm]
file not received
problemas con multipart/form-data
invalid request / bad request
En este punto, puedo descargar el archivo exitosamente, pero no puedo enviar de forma confiable a una API de transcripción.
Por favor, comparte tu flujo de trabajo
Flujo de trabajo esperado (del tutorial)
El tutorial que estoy siguiendo sugiere:
Telegram → Get a File
OpenAI → Whisper → Transcribe a Recording
Conectar la salida de Whisper a un Agente de IA
Usar esta expresión en el Agente de IA:
{{$json.message.text ?? $node["OpenAI"].json.text}}
Así el agente puede manejar ambos:
mensajes de texto
transcripciones de audio
¡PERO no estoy usando OpenAI!
Quiero evitar usar OpenAI (por razones de costo), así que estoy intentando usar una solución alternativa de speech-to-text (por ejemplo, la API de Groq Whisper o similar).
Comparte la salida devuelta por el último nodo
Información sobre tu configuración de n8n
Versión de n8n: 2.23.4
Base de datos (predeterminado: SQLite): predeterminado
Configuración EXECUTIONS_PROCESS de n8n (predeterminado: own, main): predeterminado
Ejecutando n8n a través de (Docker, npm, n8n cloud, desktop app): web
Primero, elimina el nodo Code con fetch/FormData, es frágil para archivos binarios. Usa el nodo HTTP Request: establece Body en Form-Data, añade un parámetro llamado file con tipo n8n Binary File, e establece Input Data Field Name en tu propiedad binaria, normalmente data. Añade un campo model establecido en whisper-large-v3, y apunta al endpoint de Groq https://api.groq.com/openai/v1/audio/transcriptions con un header de token Bearer.
Segundo, el error “file must be one of” se refiere al nombre del archivo, no al audio. Whisper lee el formato de la extensión, y Telegram envía .oga, que no está en la lista. Renombra el archivo binario para que termine en .ogg y ese error desaparece.
Luego en el nodo HTTP Request, establece Body en Form-Data, añade un parámetro file con tipo «n8n Binary File», Input Data Field Name = data, y añade model como campo de cadena establecido en whisper-large-v3. Esa combinación funciona constantemente con el endpoint de Groq.
Buenas noticias: tu archivo está bien - .oga ES ogg/opus, que ya está en esa lista permitida. El error “file must be one of […ogg opus…]” es engañoso: Groq/OpenAI Whisper detectan el formato de la EXTENSIÓN DEL NOMBRE DE ARCHIVO en la carga multipart, y el “Get a File” de Telegram le da al binario un nombre sin extensión utilizable. Así que estás enviando los bytes correctamente, pero la API los rechaza porque el nombre de archivo de la parte no es *.ogg. Arregla el nombre de archivo y simplemente funciona - no se necesita conversión.
Paso 1 - arregla el nombre de archivo binario. Justo después de Telegram → Get a File, añade un nodo Code (Run Once for Each Item)
item.binary.data.fileName = 'audio.ogg';
item.binary.data.mimeType = 'audio/ogg';
return item;
```
(usa cualquier nombre que tenga tu propiedad binaria - normalmente es `data`).
Paso 2 - envía a Groq con el nodo HTTP Request (usa el nodo nativo, no un nodo Code + fetch - el nativo construye multipart correctamente):
- Method: POST
- URL: https://api.groq.com/openai/v1/audio/transcriptions
- Authentication → Generic → Header Auth: nombre `Authorization`, valor `Bearer YOUR_GROQ_KEY`
- Send Body: ON, Body Content Type: Form-Data (multipart/form-data)
- Parameters:
- `file` → Parameter Type: n8n Binary File (versiones antiguas lo llaman "Form Binary Data") → Input Data Field Name: `data`
- `model` → (form field) → whisper-large-v3 (o whisper-large-v3-turbo)
- opcional `response_format` → json
Eso es todo. Groq es compatible con OpenAI, rápido y tiene un nivel gratuito generoso - perfecto para evitar OpenAI por costos.
Paso 3 - la expresión AI Agent, simplemente cambia el nombre del nodo:
`{{ $json.message.text ?? $node["HTTP Request"].json.text }}`
(Groq devuelve la transcripción en `.text`, la misma estructura que OpenAI.)
Los problemas que causan exactamente tus errores:
- "file not received" → el parámetro Form-Data debe ser de tipo Binary File, no un campo de texto, e Input Field Name debe coincidir con la propiedad binaria (`data`).
- "file must be one of [...]" → extensión de nombre de archivo en blanco/faltante → el renombrado del nodo Code lo arregla.
- NO establezas manualmente un encabezado `Content-Type: multipart/...` - deja que n8n establezca el límite automáticamente; uno manual rompe la solicitud.
Estable en n8n cloud 2.23.x.
Para confirmar lo que @work6 explicó, ese es el patrón de funcionamiento completo. Una cosa más que añadir si aún recibes el error “file not received” incluso después de cambiar el nombre:
El nodo Get a File de Telegram a veces devuelve application/octet-stream como tipo MIME en lugar de audio/ogg. La API de Groq puede rechazar esto. Fuerza ambos campos en tu nodo Code:
item.binary.data.fileName = 'audio.ogg';
@Work6 incluyó esto, solo me aseguro de que no se pase por alto ya que es fácil de perder.
También para la expresión del AI Agent, si tu nodo HTTP Request tiene un nombre personalizado, actualízalo en consecuencia.
Hola @SilvyElba — ese baile de .oga + multipart/form-data manual es genuinamente la parte dolorosa de ir por la ruta de HTTP Request sin procesar. El renombrado .oga → .ogg + arreglo de Form-Data anterior es sólido si quieres quedarte en Groq.
Si estás abierto a una opción multi-proveedor administrada que evite completamente la tubería binaria, aquí hay otro enfoque.
Divulgación: trabajo en Eden AI, así que tómalo como una opción entre otras — pero resuelve tu bloqueo exacto, así que pensé que valía la pena compartirlo.
Eden AI es un agregador (una API/clave en frente de Deepgram, AssemblyAI, Gladia, Amazon, Google, Whisper…), y hay un nodo comunitario: n8n-nodes-edenai. La parte relevante para ti: su nodo Expert Models toma una propiedad binaria directamente y carga el archivo por ti — sin Form-Data manual, sin renombrados .oga, sin «archivo no recibido».
Receta rápida:
Settings → Community Nodes → Installn8n-nodes-edenai (y añade tu clave API de Eden AI como credencial).
Telegram Trigger → Telegram (Get File) para que tengas el archivo de voz como binario.
Nodo Eden AI – Expert Models:
Feature:audio
Subfeature:speech to text (async) — es un trabajo asincrónico, el nodo consulta hasta que se completa automáticamente.
Input Type:File → File Source:Binary Property → apúntalo a tu campo binario de Telegram (p. ej. data). Esa es toda la parte de «manejo binario».
Provider: elige el que prefieras — Deepgram y Gladia son rápidos/rentables, AssemblyAI es fuerte en precisión + diarización. Puedes cambiar proveedores desde un menú desplegable sin replantear nada.
(Opcional) Establece un par de Fallback Models en Opciones, para que si tu proveedor principal falla reintentos con el siguiente — útil para el tipo de inestabilidad 4xx que estás recibiendo.
La transcripción vuelve en la salida del nodo (no necesitas manejar la respuesta multipart tú mismo).
En cuanto a costo, ya que esa es tu razón principal para dejar OpenAI: Eden AI cobra precios de paso directo del proveedor — sin margen en el precio por solicitud. El único margen es ~5,5%, aplicado cuando recargas créditos. Así que no vencerás a Groq-directo en precio bruto, pero sí tienes la posibilidad de elegir el proveedor más barato por trabajo (Deepgram/Gladia son muy competitivos) y cambiar libremente de uno a otro desde un nodo. La verdadera ganancia aquí es eliminar la lucha binaria/form-data + flexibilidad multi-proveedor y respaldo. Estoy feliz de compartir un JSON de flujo de trabajo de ejemplo si es útil.