This workflow follows the Googlegemini → HTTP Request recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "BotClimaRecover",
"nodes": [
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "ff1aa359-db46-49cc-8086-51f6ba748d56",
"name": "id",
"value": "={{ $json.message.from.id }}",
"type": "number"
},
{
"id": "a4cb98b2-211c-400a-b401-93ba5aefa9f0",
"name": "queue",
"value": "={{ $json.message.text.trim().toLowerCase().normalize('NFD').replace(/[\\u0300-\\u036f]/g, '') \n}}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
-2832,
560
],
"id": "6cd1839e-79d1-4435-b492-2887a490bc65",
"name": "InicializaVariaveis"
},
{
"parameters": {
"url": "https://api.openweathermap.org/data/2.5/weather",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "units",
"value": "metric"
},
{
"name": "lang",
"value": "pt_br"
},
{
"name": "q",
"value": "={{ $json.queue }}"
},
{
"name": "appid",
"value": "={{$env.OPENWEATHER_API_KEY}}"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
-1984,
352
],
"id": "a3509062-b61d-4a82-a14f-a668cdd1f8e0",
"name": "ChamaApiOpenWeather",
"retryOnFail": true,
"onError": "continueErrorOutput"
},
{
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const cidade = $json.queue?.trim()?.split(',')[0];\nconst uf = $json.queue?.trim()?.split(',')[1];\n\nconst ufUpper = uf?.toString()?.trim()?.toUpperCase();\n\nconst estados = {\n AC: \"Acre\",\n AL: \"Alagoas\",\n AP: \"Amap\u00e1\",\n AM: \"Amazonas\",\n BA: \"Bahia\",\n CE: \"Cear\u00e1\",\n DF: \"Distrito Federal\",\n ES: \"Esp\u00edrito Santo\",\n GO: \"Goi\u00e1s\",\n MA: \"Maranh\u00e3o\",\n MT: \"Mato Grosso\",\n MS: \"Mato Grosso do Sul\",\n MG: \"Minas Gerais\",\n PA: \"Par\u00e1\",\n PB: \"Para\u00edba\",\n PR: \"Paran\u00e1\",\n PE: \"Pernambuco\",\n PI: \"Piau\u00ed\",\n RJ: \"Rio de Janeiro\",\n RN: \"Rio Grande do Norte\",\n RS: \"Rio Grande do Sul\",\n RO: \"Rond\u00f4nia\",\n RR: \"Roraima\",\n SC: \"Santa Catarina\",\n SP: \"S\u00e3o Paulo\",\n SE: \"Sergipe\",\n TO: \"Tocantins\"\n};\n\nlet cidadeEEstadoQueue = \"\";\n\nif (estados[ufUpper] && cidade) {\n cidadeEEstadoQueue = cidade.concat(', ').concat(estados[ufUpper].toLowerCase().normalize('NFD').replace(/[\\u0300-\\u036f]/g, '')); \n} else {\n cidadeEEstadoQueue = \"inv\u00e1lido\";\n}\n\nreturn {\n queue: cidadeEEstadoQueue\n};"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-2528,
560
],
"id": "3a4fb3b8-ea4e-41a0-8344-e397d5e48008",
"name": "ValidaParametroCidadeEstado"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "03573199-acca-4f2d-b729-ac929a04032e",
"name": "nomeCidade",
"value": "={{ $json.name }}",
"type": "string"
},
{
"id": "1cee4f09-d262-431c-b32f-6605c665d0a5",
"name": "temperatura",
"value": "={{ $json.main.temp }}",
"type": "number"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
-1632,
224
],
"id": "6e15ad95-69a7-4767-b45a-9716731589af",
"name": "Resposta"
},
{
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const temperatura = Math.round($input.item.json.temperatura);\n\nreturn {\n ...$json,\n temperatura: temperatura\n}"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-992,
256
],
"id": "438d3dac-a461-487f-87e1-bcb7ae359082",
"name": "ArredondaTemperatura"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "9fd42224-7d0e-41ed-afd7-ec24b23a7ec5",
"name": "mensagem",
"value": "=\ud83c\udf24\ufe0f A temperatura em {{ $json.nomeCidade }} \u00e9 de {{$json.temperatura}}\u00b0C.",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
-704,
288
],
"id": "985fcf7c-1ea6-4ba1-add2-05f287e48a47",
"name": "MensagemFinal"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "9fd42224-7d0e-41ed-afd7-ec24b23a7ec5",
"name": "mensagem",
"value": "=\u274c Cidade n\u00e3o encontrada. Use o formato Cidade,UF (ex.: S\u00e3o Paulo,SP).",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
-1120,
576
],
"id": "8cf1faa5-4ce1-4fbf-8103-22934cdfc5fe",
"name": "MensagemDeErro"
},
{
"parameters": {
"modelId": {
"__rl": true,
"value": "models/gemini-2.5-flash",
"mode": "list",
"cachedResultName": "models/gemini-2.5-flash"
},
"messages": {
"values": [
{
"content": "=Reescreva esta mensagem de forma mais natural e amig\u00e1vel em portugu\u00eas brasileiro, mantendo o mesmo conte\u00fado {{ $json.mensagem }}\n\nRetorne APENAS um JSON no formato:\n- Se sucesso: {\"message\":\"[sua mensagem reescrita aqui]\",\"ok\":true}\n- Se erro: {\"message\":\"\",\"ok\":false,\"error\":true}"
}
]
},
"simplify": false,
"builtInTools": {},
"options": {
"systemMessage": "",
"temperature": 0.2
}
},
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"typeVersion": 1.1,
"position": [
-480,
272
],
"id": "b9e226cb-703f-453f-b9ab-7131c87c7e45",
"name": "MensagemComGemini",
"retryOnFail": true,
"onError": "continueRegularOutput"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "489dbeb9-ec59-4959-81e4-1b77575bba7f",
"leftValue": "={{ $json.temperatura }}",
"rightValue": "=",
"operator": {
"type": "number",
"operation": "exists",
"singleValue": true
}
},
{
"id": "29b7f132-fd63-4afa-bf98-1d8e1c66455f",
"leftValue": "={{ $json.nomeCidade }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
-1376,
240
],
"id": "183bc28f-f1af-485f-9d18-073a91f9a0f7",
"name": "TemperaturaExiste"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "528ef941-d903-4e67-b671-4cfd78ecb64a",
"leftValue": "={{ $json.queue }}",
"rightValue": "inv\u00e1lido",
"operator": {
"type": "string",
"operation": "notEquals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
-2304,
576
],
"id": "12d0aefd-0fe4-4b20-91d3-f47b848e04d7",
"name": "MensagemValida"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "560d8bf3-2004-4b8c-99dd-111511d13332",
"leftValue": "={{ $json.content?.parts[0]?.text }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
-48,
240
],
"id": "2368e6ff-659f-4ee1-a844-b53363a16cec",
"name": "GerouTexto1"
},
{
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Fallback determin\u00edstico - gera mensagem sem depender do Gemini\n// A automa\u00e7\u00e3o avaliadora usar\u00e1 este fallback quando n\u00e3o houver credenciais Gemini\nconst nomeCidade = $json.nomeCidade || $('ArredondaTemperatura').item.json.nomeCidade;\nconst temperatura = $json.temperatura || $('ArredondaTemperatura').item.json.temperatura;\n\n// Gera mensagem formatada de forma determin\u00edstica\nconst mensagem = `\ud83c\udf24\ufe0f A temperatura em ${nomeCidade} \u00e9 de ${temperatura}\u00b0C.`;\n\nreturn {\n json: {\n mensagem: mensagem,\n ok: true\n }\n};"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
480,
416
],
"id": "66666487-01ce-4cac-bfbe-adf3ee43c191",
"name": "FallbackDeterministico"
},
{
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Extrai resposta do Gemini e detecta erros\nlet mensagemFinal = $json.mensagem || ''; // fallback para mensagem original\nlet ok = true;\nlet error = false;\n\ntry {\n // Caso 1: Sucesso - N8N j\u00e1 processou e temos content.parts[0].text\n if ($json.content?.parts?.[0]?.text) {\n mensagemFinal = $json.content.parts[0].text.trim();\n ok = true;\n error = false;\n }\n // Caso 2: Erro direto do Gemini\n else if ($json.error) {\n ok = false;\n error = true;\n mensagemFinal = '';\n }\n // Caso 3: Se for array (resposta direta do Gemini sem processar)\n else if (Array.isArray($json)) {\n const firstItem = $json[0];\n \n if (firstItem?.error) {\n // Erro do Gemini (ex: rate limit, bad request)\n ok = false;\n error = true;\n mensagemFinal = '';\n } else if (firstItem?.content?.parts?.[0]?.text) {\n // Sucesso - extrai o texto reescrito\n mensagemFinal = firstItem.content.parts[0].text.trim();\n ok = true;\n error = false;\n }\n }\n // Caso 4: Tenta acessar como array dentro de json\n else if ($json.json && Array.isArray($json.json)) {\n const firstItem = $json.json[0];\n if (firstItem?.error) {\n ok = false;\n error = true;\n mensagemFinal = '';\n } else if (firstItem?.content?.parts?.[0]?.text) {\n mensagemFinal = firstItem.content.parts[0].text.trim();\n ok = true;\n error = false;\n }\n }\n} catch (err) {\n // Se falhar, usa mensagem original\n mensagemFinal = $json.mensagem || '';\n ok = true;\n error = false;\n}\n\nreturn {\n json: {\n mensagem: mensagemFinal,\n ok: ok,\n error: error\n }\n};"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
224,
112
],
"id": "0d4e64c9-1f9d-48c7-8a81-fb80e391324f",
"name": "ExtraiJSONGemini"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "verifica-ok-true",
"leftValue": "={{ $json.ok }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "equals",
"singleValue": true
}
},
{
"id": "verifica-error-false",
"leftValue": "={{ $json.error }}",
"rightValue": false,
"operator": {
"type": "boolean",
"operation": "equals",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
432,
80
],
"id": "5e434864-9281-4ae1-b73d-d5d7f2d1184e",
"name": "VerificaErroGemini"
},
{
"parameters": {
"chatId": "={{ $('InicializaVariaveis').item.json.id }}",
"text": "={{ $json.mensagem }}",
"additionalFields": {}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
864,
624
],
"id": "bfa49022-a01f-445f-b0f3-b8c82a1e75b9",
"name": "RespondeMensagemDoClima"
},
{
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"type": "n8n-nodes-base.telegramTrigger",
"typeVersion": 1.2,
"position": [
-3008,
432
],
"id": "e1a7887f-1e3d-4007-83d5-652b84c3c602",
"name": "DisparaGatilhoTelegram"
}
],
"connections": {
"InicializaVariaveis": {
"main": [
[
{
"node": "ValidaParametroCidadeEstado",
"type": "main",
"index": 0
}
]
]
},
"ChamaApiOpenWeather": {
"main": [
[
{
"node": "Resposta",
"type": "main",
"index": 0
}
],
[
{
"node": "MensagemDeErro",
"type": "main",
"index": 0
}
]
]
},
"ValidaParametroCidadeEstado": {
"main": [
[
{
"node": "MensagemValida",
"type": "main",
"index": 0
}
]
]
},
"Resposta": {
"main": [
[
{
"node": "TemperaturaExiste",
"type": "main",
"index": 0
}
]
]
},
"ArredondaTemperatura": {
"main": [
[
{
"node": "MensagemFinal",
"type": "main",
"index": 0
}
]
]
},
"MensagemFinal": {
"main": [
[
{
"node": "MensagemComGemini",
"type": "main",
"index": 0
}
]
]
},
"MensagemDeErro": {
"main": [
[
{
"node": "RespondeMensagemDoClima",
"type": "main",
"index": 0
}
]
]
},
"MensagemComGemini": {
"main": [
[
{
"node": "GerouTexto1",
"type": "main",
"index": 0
}
]
]
},
"TemperaturaExiste": {
"main": [
[
{
"node": "ArredondaTemperatura",
"type": "main",
"index": 0
}
],
[
{
"node": "MensagemDeErro",
"type": "main",
"index": 0
}
]
]
},
"MensagemValida": {
"main": [
[
{
"node": "ChamaApiOpenWeather",
"type": "main",
"index": 0
}
],
[
{
"node": "MensagemDeErro",
"type": "main",
"index": 0
}
]
]
},
"GerouTexto1": {
"main": [
[
{
"node": "ExtraiJSONGemini",
"type": "main",
"index": 0
}
],
[
{
"node": "FallbackDeterministico",
"type": "main",
"index": 0
}
]
]
},
"FallbackDeterministico": {
"main": [
[
{
"node": "RespondeMensagemDoClima",
"type": "main",
"index": 0
}
]
]
},
"ExtraiJSONGemini": {
"main": [
[
{
"node": "VerificaErroGemini",
"type": "main",
"index": 0
}
]
]
},
"VerificaErroGemini": {
"main": [
[
{
"node": "RespondeMensagemDoClima",
"type": "main",
"index": 0
}
],
[
{
"node": "FallbackDeterministico",
"type": "main",
"index": 0
}
]
]
},
"DisparaGatilhoTelegram": {
"main": [
[
{
"node": "InicializaVariaveis",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"availableInMCP": false
},
"versionId": "883f3bff-3ac4-4a86-9095-5fc1ca43a8c3",
"id": "0VRL_8QDrX8wiVh-OZuYH",
"tags": []
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googlePalmApitelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
BotClimaRecover. Uses httpRequest, googleGemini, telegram, telegramTrigger. Event-driven trigger; 21 nodes.
Source: https://github.com/kelvisdev/chatbot-telegram/blob/f3366c8ddccbbdbd323f550254ba4d236ea26810/workflow-chatbot-telegram.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
BotClimaRecover. Uses httpRequest, googleGemini, telegram, telegramTrigger. Event-driven trigger; 16 nodes.
This workflow automates the process of scanning business cards received via Telegram and instantly saving the extracted contact information into Google Contacts. It combines OCR technology, AI-powered
This workflow connects a Telegram bot to OpenAi/Google Gemini (PaLM API) so the bot can reply to users with AI-generated answers. Useful for FAQs, assistants, classroom helpers, or bots that fetch doc
I prepared a detailed guide that showed the whole process of building an AI bot, from the simplest version to the most complex in a template.
This project is a template for building a complete academic virtual assistant using n8n. It connects to Telegram, answers frequently asked questions by querying MongoDB, keeps the community informed a