Há 3 meses eu não tinha nem um pingo de conhecimento em programação de aplicações, estou há 8 meses na Espanha e vim com uma ideia na cabeça, com o apoio da IA Gemini desde Antigravity comecei a materializar minha ideia de Aplicação de tradução de linguagem para me comunicar com uns amigos da Alemanha, meu fluxo é composto por 4 nós (Webhook1+HTTP REQUEST+JavaScript+Respond to Webhook), ao clicar em executar fluxo de trabalho ele se executa em menos de 3 segundos mas minha aplicação que ainda está incompleta e por enquanto é Web a qual se ativa a partir de um arquivo index que está hospedado localmente na minha área de trabalho do computador, ela não consegue fazer a tradução para o idioma destino e acaba me entregando a mensagem original sempre; Já não sei o que mais fazer
Seu workflow sendo executado em menos de 3 segundos significa que a automação está funcionando, mas não prova que a saída da tradução está sendo passada corretamente. O problema provavelmente não é a “tradução” em si; é provável que seja um problema de mapeamento de dados entre sua página web, o webhook, a requisição HTTP, o nó JavaScript e a resposta final.
Eu depuraria nó por nó:
-
Verifique a saída do nó Webhook. Confirme que ele recebe tanto o texto original quanto o idioma de destino.
-
Verifique a entrada do nó HTTP Request. Confirme que ele envia o texto e o idioma de destino corretos para a API de tradução.
-
Verifique a saída do nó HTTP Request. Confirme que a API realmente retorna o texto traduzido.
-
Verifique o nó JavaScript. Ele pode estar extraindo o campo JSON errado ou caindo de volta para a mensagem original.
-
Verifique o nó Respond to Webhook. Confirme que ele retorna
translatedText, não o texto original. -
Verifique o JavaScript do frontend. Confirme que ele exibe o campo traduzido da resposta do webhook.
Como seu app sempre retorna o texto original, suspeito que há uma lógica de fallback como translatedText || originalText, ou o nó de resposta/frontend está exibindo a variável de texto original. Remova o fallback durante a depuração para que o workflow falhe claramente quando nenhuma tradução for encontrada.
A tradução em si deve ser direta. Já construímos um pipeline no estilo transcrição, e traduzir texto de transcrição geralmente é apenas mais uma etapa de processamento. A parte mais difícil é garantir que a variável correta percorra a cadeia. Se você compartilhar a saída do Webhook, a saída do HTTP Request, o código do nó JavaScript e o código fetch do frontend, provavelmente podemos identificar o ponto exato de falha.
É bastante impressionante sair de zero conhecimento em programação para um pipeline de webhook funcionando, então você não deveria desistir, você está mais perto do que pensa.
A resposta acima cobre bem todos os passos de depuração, embora uma coisa valha a pena adicionar: a causa mais comum de “retorna a mensagem original” nesta configuração é o nó JavaScript pegando o campo errado da resposta da API.
Você deveria tentar adicionar um console.log ou usar a visualização de saída integrada do n8n para ver exatamente o que o nó HTTP Request retorna. Tente especificamente olhar para a estrutura JSON. O texto traduzido geralmente está aninhado um nível mais profundo do que esperado, então algo como response.data.translations[0].translatedText dependendo de qual API você está usando.
Se você compartilhar qual API de tradução você está acessando e colar o código JavaScript que foi usado, alguém provavelmente conseguirá identificar o problema em 2 minutos.
"Muito obrigado @pratham_gupta e @AnthonyAtXRay por dedicarem tempo para responder! Seus pontos de depuração são excelentes.
Para dar um pouco mais de contexto: no início, quando eu fazia testes iniciais, todo o fluxo parecia responder bem. No entanto, os problemas reais no navegador começaram a se tornar mais evidentes recentemente. Após analisá-lo a fundo, suspeitamos que a lógica interna do n8n está funcionando corretamente, mas a falha ocorre na comunicação final: estou executando a aplicação web localmente abrindo o arquivo index.html diretamente do meu computador (file://). Tudo indica que o Google Chrome ou as políticas de rede locais estão bloqueando por CORS a resposta que vem do IP do n8n.
Além disso, para completar, meus créditos de pré-pagamento da API do Google acabaram de esgotar-se, então o fluxo ficou pausado.
Para validar se o mapeamento de variáveis está tão refinado quanto sugerem, compartilho aqui embaixo a estrutura do meu nó JavaScript e o fluxo geral (sem credenciais). Vocês acham que minha teoria de que o formato file:// e CORS são os culpados do bloqueio no navegador faz sentido, ou veem algum erro de lógica nas variáveis?"
{
“nodes”: [
{
“parameters”: {
“respondWith”: “json”,
“responseBody”: “={{ $json }}”,
“options”: {
“responseCode”: 200,
“responseHeaders”: {
“entries”: [
{
“name”: “Content-Type”,
“value”: “application/json”
},
{
“name”: “Access-Control-Allow-Origin”,
“value”: “"
},
{
“name”: “Access-Control-Allow-Headers”,
“value”: "”
}
]
}
}
},
“type”: “n8n-nodes-base.respondToWebhook”,
“typeVersion”: 1.5,
“position”: [
752,
112
],
“id”: “7eb0364c-e218-47a7-ba7e-f9d8fe8bb8f8”,
“name”: “Responder ao Webhook”
},
{
“parameters”: {
“httpMethod”: “POST”,
“path”: “98bd0d2c-fcf4-49b7-b501-72c81c5d9d44”,
“responseMode”: “responseNode”,
“options”: {
“allowedOrigins”: “*”
}
},
“type”: “n8n-nodes-base.webhook”,
“typeVersion”: 2.1,
“position”: [
80,
112
],
“id”: “0af6f18b-0e1a-4d5c-bca6-7573f4a31cb9”,
“name”: “Webhook1”,
“webhookId”: “c1603781-563f-4655-9b6d-1170e847c6f0”
},
{
“parameters”: {
“method”: “POST”,
“url”: “https://generativelanguage.googleapis.com/v1/models/gemini-2.5-flash:generateContent?key=SUA_CHAVE_DE_API_AQUI”,
“sendBody”: true,
“specifyBody”: “json”,
“jsonBody”: “={{ { “contents”: [{ “parts”: [{ “text”: $json.body.text + " - Traduzir isto para " + $json.body.target_lang }] }] } }}”,
“options”: {}
},
“id”: “06da87ea-d639-41fa-a859-50ae26c35224”,
“name”: “Requisição HTTP”,
“type”: “n8n-nodes-base.httpRequest”,
“typeVersion”: 4.4,
“position”: [
304,
112
]
},
{
“parameters”: {
“jsCode”: “const geminiResponse = $input.first().json;\nconst translatedText = geminiResponse.candidates[0].content.parts[0].text.trim();\n\nreturn [\n {\n json: {\n status: "sucesso",\n original_text: $(‘Webhook1’).item.json.body.text,\n translated_text: translatedText,\n audio_base64: ""\n }\n }\n];”
},
“id”: “576fa8a4-896f-4d33-ad1a-8cfe5d204ec8”,
“name”: “Código em JavaScript”,
“type”: “n8n-nodes-base.code”,
“typeVersion”: 2,
“position”: [
528,
112
]
}
],
“connections”: {
“Webhook1”: {
“main”: [
[
{
“node”: “Requisição HTTP”,
“type”: “main”,
“index”: 0
}
]
]
},
“Requisição HTTP”: {
“main”: [
[
{
“node”: “Código em JavaScript”,
“type”: “main”,
“index”: 0
}
]
]
},
“Código em JavaScript”: {
“main”: [
[
{
“node”: “Responder ao Webhook”,
“type”: “main”,
“index”: 0
}
]
]
}
},
“pinData”: {},
“meta”: {
“templateCredsSetupCompleted”: true,
“instanceId”: “ANONYMOUS_INSTANCE_ID”
}
}
Freddy, os screenshots ajudariam, mas baseado no que você descreveu, eu reduziria isso a uma pergunta específica:
Em que ponto o texto traduzido desaparece?
Seu workflow n8n pode estar funcionando corretamente, mas o aplicativo web pode ainda estar lendo o campo errado.
Eu testaria nesta ordem:
- Nó Webhook
Confirme que os dados recebidos contêm algo como:
{
"text": "hello",
"targetLanguage": "German"
}
- Nó HTTP Request
Abra a saída de execução do nó e verifique se a API de tradução retorna o texto traduzido.
Por exemplo, algo como:
{
"translatedText": "Hallo"
}
ou às vezes pode estar aninhado mais profundamente, como:
{
"data": {
"translation": "Hallo"
}
}
- Nó JavaScript
Este é um ponto de falha comum. O código pode estar lendo o campo errado.
Para depuração, não retorne a mensagem original como fallback. Retorne um erro óbvio em vez disso:
const output = $json.translatedText;
if (!output) {
throw new Error("No translated text found. Check HTTP Request output field name.");
}
return [
{
json: {
translatedText: output
}
}
];
Se o texto traduzido estiver aninhado, você precisa ajustar o caminho do campo baseado na saída real do HTTP Request.
- Nó Respond to Webhook
Certifique-se de que ele retorna o valor traduzido, não a entrada original.
Exemplo de resposta:
{
"translatedText": "={{$json.translatedText}}"
}
- Código fetch do frontend
Sua página web local pode estar fazendo algo assim:
resultBox.innerText = data.text;
quando deveria ser:
resultBox.innerText = data.translatedText;
Como seu app sempre retorna a mensagem original, meu palpite mais forte é um destes:
-
o nó JavaScript está retornando para o texto original
-
o nó Respond to Webhook está mapeado para o campo original
-
o frontend está exibindo o campo original em vez do campo traduzido
-
o nó HTTP Request está retornando a tradução em um caminho JSON aninhado, mas o nó JS está lendo o caminho errado
Melhor movimento de depuração: retorne temporariamente a saída completa do HTTP Request diretamente do Respond to Webhook. Então teste a partir do aplicativo web e verifique qual JSON seu navegador realmente recebe. Uma vez que você vê a estrutura JSON real, mapear o campo traduzido deve ser fácil.
Sua teoria sobre CORS está exatamente certa, o JSON do seu workflow expõe o problema específico.
Seu nó Webhook tem “allowedOrigins” definido como “asterisk”, que é o que deveria ser. Mas seu nó Respond to Webhook tem “Access-Control-Allow-Origin” definido como uma string vazia. Isso precisará ser alterado para “asterisk” também, senão o Chrome bloqueará a resposta mesmo quando a solicitação passar.
O próximo problema é o próprio protocolo file://. O Chrome acaba bloqueando as solicitações de fetch de páginas file:// para URLs externas independentemente dos cabeçalhos CORS. É uma solução simples: em vez de abrir index.html diretamente, você o serve de um servidor local.
Se você tiver Python instalado: python -m http.server 8080 na pasta contendo seu index.html e depois abra http://localhost:8080
Quanto aos créditos da Google API, depois que você preenchê-los, a lógica do nó JavaScript em si parece estar correta. E o mapeamento de variável para candidates[0].content.parts[0].text é o caminho certo para respostas do Gemini.