Olá a todos,
Estou construindo um workflow no n8n para um projeto de curso e estou preso na etapa final de transcrição de áudio.
O objetivo é:
Receber uma mensagem de voz do Telegram
Baixar o áudio usando Telegram → Get a File (via file_id)
Converter o áudio em texto (speech-to-text)
Enviar a transcrição para um AI Agent
Pergunta
Qual é a forma recomendada e confiável no n8n para: pegar uma mensagem de voz do Telegram (.oga / opus) enviar para uma API de speech-to-text que não seja OpenAI (ex: Groq Whisper ou similar) e obter um resultado de transcrição estável
Especialmente interessado em:
melhores práticas para lidar com arquivos de áudio binários do Telegram
se existe alguma limitação conhecida com multipart/form-data no nó HTTP Request
workaround recomendado se o upload de arquivo binário direto não for confiável
Qualquer padrão funcional ou exemplo de workflow seria muito apreciado
Qual é a mensagem de erro (se houver)?
Onde estou preso
Nesta etapa:
Telegram → Get a File funciona corretamente
Recebo o arquivo de áudio binário (.oga, audio/ogg)
O workflow quebra ao tentar enviar esse arquivo para uma API Whisper/STT
Testei múltiplas abordagens:
Nó HTTP Request com Form-Data + arquivo binário
Nó Code com fetch + FormData
diferentes mapeamentos de binário no n8n
Mas sempre recebo erros como:
file must be one of [flac mp3 mp4 mpeg mpga m4a ogg opus wav webm]
file not received
problemas com multipart/form-data
invalid request / bad request
Neste ponto, posso baixar o arquivo com sucesso, mas não consigo enviá-lo de forma confiável para uma API de transcrição.
Por favor, compartilhe seu workflow
Workflow esperado (do tutorial)
O tutorial que estou seguindo sugere:
Telegram → Get a File
OpenAI → Whisper → Transcribe a Recording
Conectar a saída do Whisper a um AI Agent
Usar esta expressão no AI Agent:
{{$json.message.text ?? $node["OpenAI"].json.text}}
Para que o agent possa lidar com:
mensagens de texto
transcrições de áudio
MAS eu NÃO estou usando OpenAI!!
Quero evitar usar OpenAI (por razões de custo), então estou tentando usar uma solução de speech-to-text alternativa (ex: Groq Whisper API ou similar).
Primeira, remove o nó Code com fetch/FormData, é frágil para binário. Usa o nó HTTP Request: coloca Body em Form-Data, adiciona um parâmetro chamado file com tipo n8n Binary File, e coloca Input Data Field Name com a tua propriedade binária, geralmente data. Adiciona um campo model com whisper-large-v3, e aponta pro endpoint da Groq https://api.groq.com/openai/v1/audio/transcriptions com um header de Bearer token.
Segunda, o erro “file must be one of” é sobre o nome do arquivo, não do áudio. O Whisper lê o formato pela extensão, e o Telegram manda .oga, que não tá na lista. Renomeia o nome do arquivo do binário pra terminar em .ogg e esse erro some.
Depois, no nó HTTP Request, defina Body como Form-Data, adicione um parâmetro file com tipo “n8n Binary File”, Input Data Field Name = data, e adicione model como um campo de string definido como whisper-large-v3. Essa combinação funciona consistentemente com o endpoint do Groq.
Boas notícias: seu arquivo está perfeito - .oga É ogg/opus, que já está nessa lista de permitidos. O erro “file must be one of […ogg opus…]” é enganoso: Groq/OpenAI Whisper detectam o formato pela EXTENSÃO DO NOME DO ARQUIVO no upload multipart, e o “Get a File” do Telegram fornece o binário com um nome sem extensão utilizável. Então você está enviando os bytes corretamente, mas a API os rejeita porque o nome do arquivo da parte não é *.ogg. Corrija o nome do arquivo e pronto - nenhuma conversão necessária.
Passo 1 - corrija o nome do arquivo binário. Logo após Telegram -\u003e Get a File, adicione um nó Code (Run Once for Each Item)
item.binary.data.fileName = 'audio.ogg';
item.binary.data.mimeType = 'audio/ogg';
return item;
```
(use o nome da sua propriedade binária - geralmente é `data`).
Passo 2 - envie para Groq com o nó HTTP Request (use o nó nativo, não um nó Code + fetch - o nó nativo constrói o multipart corretamente):
- Method: POST
- URL: https://api.groq.com/openai/v1/audio/transcriptions
- Authentication -\u003e Generic -\u003e Header Auth: name `Authorization`, value `Bearer YOUR_GROQ_KEY`
- Send Body: ON, Body Content Type: Form-Data (multipart/form-data)
- Parameters:
- `file` -\u003e Parameter Type: n8n Binary File (versões antigas chamam de "Form Binary Data") -\u003e Input Data Field Name: `data`
- `model` -\u003e (form field) -\u003e whisper-large-v3 (ou whisper-large-v3-turbo)
- opcional `response_format` -\u003e json
Isso é tudo. Groq é compatível com OpenAI, rápido e tem um tier gratuito generoso - perfeito para evitar OpenAI por custo.
Passo 3 - a expressão do AI Agent, apenas troque o nome do nó:
`{{ $json.message.text ?? $node["HTTP Request"].json.text }}`
(Groq retorna a transcrição em `.text`, mesma estrutura que OpenAI.)
Os problemas que causam seus erros exatos:
- "file not received" -\u003e o parâmetro Form-Data deve ser tipo Binary File, não um campo de texto, e Input Field Name deve corresponder à propriedade binária (`data`).
- "file must be one of [...]" -\u003e extensão de nome em branco/ausente -\u003e a renomeação com o nó Code corrige.
- NÃO configure um header manual `Content-Type: multipart/...` - deixe o n8n definir o boundary automaticamente; um manual quebra a requisição.
Estável no n8n cloud 2.23.x.
Para confirmar o que @work6 apresentou, esse é o padrão de funcionamento completo. Uma coisa a acrescentar se você ainda está recebendo “file not received” mesmo após a renomeação:
O nó Get a File do Telegram às vezes retorna application/octet-stream como tipo MIME em vez de audio/ogg. A API do Groq pode rejeitar isso. Force ambos os campos no seu nó Code:
item.binary.data.fileName = 'audio.ogg';
@Work6 incluiu isso, apenas garantindo que não seja pulado já que é fácil de perder de vista.
Também para a expressão do AI Agent, se seu nó HTTP Request tiver um nome personalizado, atualize-o adequadamente.
Opa @SilvyElba — aquela dança de .oga + multipart/form-data manual é genuinamente a parte dolorosa de usar a rota raw HTTP Request. O renomeamento de .oga → .ogg + o ajuste de Form-Data acima é sólido se você quiser ficar na Groq.
Se você está aberto a uma opção multi-provider gerenciada que contorna toda a tubulação binária, aqui vai outra perspectiva.
Disclosure: trabalho na Eden AI, então considere isso como uma opção entre outras — mas resolve exatamente seu bloqueio, então achei que valia a pena compartilhar.
Eden AI é um agregador (uma API/chave única na frente de Deepgram, AssemblyAI, Gladia, Amazon, Google, Whisper…), e tem um nó de comunidade: n8n-nodes-edenai. A parte relevante para você: seu nó Expert Models aceita uma propriedade binária diretamente e faz upload do arquivo para você — sem Form-Data manual, sem renomeação de .oga, sem “arquivo não recebido”.
Recita rápida:
Settings → Community Nodes → Installn8n-nodes-edenai (e adicione sua chave de API da Eden AI como uma credencial).
Telegram Trigger → Telegram (Get File) para ter o arquivo de voz como binário.
Nó Eden AI – Expert Models:
Feature:audio
Subfeature:speech to text (async) — é um job assíncrono, o nó faz polling até terminar automaticamente.
Input Type:File → File Source:Binary Property → aponte para seu campo binário do Telegram (ex: data). Essa é a parte inteira de “manipulação binária”.
Provider: escolha qual você preferir — Deepgram e Gladia são rápidos/econômicos, AssemblyAI é forte em precisão + diarização. Você pode trocar providers de um dropdown sem replumbar nada.
(Opcional) Configure um par de Fallback Models em Options, para que se seu provider primário der erro ele tente novamente com o próximo — útil para aquele tipo de instabilidade 4xx que você está enfrentando.
A transcrição volta na saída do nó (sem necessidade de você lidar com a resposta multipart).
Em termos de custo, já que essa é sua principal razão para sair do OpenAI: Eden AI cobra preço pass-through do provider — sem markup no preço por requisição. A única margem é ~5,5%, aplicada quando você recarrega créditos. Então você não vai bater o Groq-direto no preço bruto, mas consegue escolher o provider mais barato por job (Deepgram/Gladia são muito competitivos) e trocar livremente de um nó. O grande ganho aqui é eliminar a complexidade binária/form-data + flexibilidade multi-provider e fallback. Fico feliz em compartilhar um exemplo de workflow JSON se útil.