This workflow follows the Agent → 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": "Desafio Fase 2 - Bot de Clima no Telegram com N8N",
"nodes": [
{
"parameters": {
"promptType": "define",
"text": "=# ROLE\nAtue como um assistente meteorol\u00f3gico amig\u00e1vel e prestativo para um bot de Telegram.\n\n# CONTEXTO\nVoc\u00ea receber\u00e1 dados clim\u00e1ticos brutos em formato JSON. Sua tarefa \u00e9 transformar esses dados em uma mensagem leg\u00edvel, emp\u00e1tica e organizada para o usu\u00e1rio final.\n\n# DADOS DE ENTRADA\nCidade: {{ $json.name }}\nTemperatura m\u00e1xima: {{ $json.main.temp_max.round(1) }}\nTemperatura m\u00ednima: {{ $json.main.temp_min.round(1) }}\nC\u00e9u {{ $json.weather[0].description }}\nSensa\u00e7\u00e3o t\u00e9rmica: {{ $json.main.feels_like.round(1) }}\nTemperatura: {{ $json.main.temp.round(1) }}\n\n\n# DIRETRIZES DE RESPOSTA\n1. Identifique a cidade, estado, temperatura atual, sensa\u00e7\u00e3o t\u00e9rmica e descri\u00e7\u00e3o do tempo.\n2. Utilize Emojis pertinentes ao clima relatado.\n3. Mantenha um tom cordial (ex: \"Tenha um excelente dia\" ou \"N\u00e3o esque\u00e7a o guarda-chuva\").\n4. Se houver chuva ou temperaturas extremas, inclua uma breve recomenda\u00e7\u00e3o amig\u00e1vel.\n5. Use sempre emojis de acordo com as condi\u00e7\u00f5es clim\u00e1ticas\n6. Termine sempre com alguma frase estrovertida de cada cidade ou estado\n7. Na sua resposta, quando for citar o nome da cidade, n\u00e3o responda com a UF, somente o nome da cidade mesmo.\n8. N\u00e3o use mais do que 100 tokens na sua resposta. Ajuste sempre para que sua resposta caiba nesta quantidade de tokens.\n\n# EXEMPLOS DE ESTILO (Siga um destes padr\u00f5es conforme a varia\u00e7\u00e3o do clima)\n- Estilo Informativo: \"\ud83c\udf24\ufe0f Previs\u00e3o para S\u00e3o Paulo, SP. A temperatura atual \u00e9 de 24\u00baC...\"\n- Estilo Detalhado: \"\ud83d\udccd Clima em Curitiba, PR. Atualmente faz 18\u00baC, mas a sensa\u00e7\u00e3o \u00e9 de 16\u00baC...\"\n- Estilo Minimalista: \"\ud83c\udf24\ufe0f Salvador, BA | 28\u00baC. O tempo est\u00e1 com c\u00e9u limpo...\"\n- Em caso de erro, retorne a resposta com o erro gerado\n\n# FORMATO DE SA\u00cdDA OBRIGAT\u00d3RIO\nRetorne estritamente um JSON no seguinte formato, sem textos explicativos fora do bloco:\n{\n \"Response\": \"Texto da mensagem formatada aqui\"\n}",
"hasOutputParser": true,
"needsFallback": true,
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 3,
"position": [
272,
400
],
"id": "c95e724b-cd5e-4573-b7cf-3cb6c5c50141",
"name": "AI Agent",
"alwaysOutputData": true,
"retryOnFail": false,
"notesInFlow": true,
"onError": "continueErrorOutput",
"notes": "Respons\u00e1vel por receber as informa\u00e7\u00f5es e formatar uma resposta para o usu\u00e1rio. Caso aconte\u00e7a algum tipo de erro e o agente retorne um objeto vazio, este erro ser\u00e1 tratado no n\u00f3s seguinte"
},
{
"parameters": {
"jsonSchemaExample": "\n{\n \"response\": \"\ud83d\udccd Clima em Hortol\u00e2ndia. Atualmente faz 25.5\u00baC, com sensa\u00e7\u00e3o t\u00e9rmica de 25.8\u00baC. O c\u00e9u est\u00e1 nublado \u2601\ufe0f. Aproveite a tranquilidade da cidade! Tenha um excelente dia!\"\n}"
},
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"typeVersion": 1.3,
"position": [
496,
624
],
"id": "2cdcb420-bf67-4b7e-8847-183da5366d36",
"name": "Structured Output Parser"
},
{
"parameters": {
"options": {
"maxOutputTokens": 100,
"temperature": 0.2
}
},
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"typeVersion": 1,
"position": [
240,
624
],
"id": "ededb46b-ae6c-4bd3-817b-54e1eb599be8",
"name": "Google Gemini Chat Model1",
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "={{ $('Mensagem do usu\u00e1rio').item.json.message.chat.id }}",
"text": "={{ $json.output.response }}",
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
928,
416
],
"id": "c0749fbc-5341-41fa-80f4-4d6e31cf3ffd",
"name": "Resposta para o usu\u00e1rio",
"notesInFlow": true,
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"notes": "Responde para o usu\u00e1rio com a mensagem criada pelo agente"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "1003eb54-cc56-4432-b7e2-7d0db857bf1d",
"leftValue": "={{ $json.output }}",
"rightValue": "",
"operator": {
"type": "object",
"operation": "notEmpty",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
704,
504
],
"id": "eff106c4-c655-46f2-bf1d-f2df0a01a383",
"name": "Verifica se existe a resposta do agente",
"notesInFlow": true,
"notes": "Valida se o agente retornou alguma resposta e em caso de erro, encaminha o fluxo para a mensagem padr\u00e3o do sistema. Dessa forma, o usu\u00e1rio receber\u00e1 as informa\u00e7\u00f5es mesmo em caso de erro do agente ou modelo conectado a ele, mas de forma mais simplificada"
},
{
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"type": "n8n-nodes-base.telegramTrigger",
"typeVersion": 1.2,
"position": [
-880,
748
],
"id": "99ff5062-1bab-479a-81cc-feaa7ec24fb5",
"name": "Mensagem do usu\u00e1rio",
"notesInFlow": true,
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"notes": "Este n\u00f3 \u00e9 respons\u00e1vel por receber o nome da cidade e estado para consultar a api da OpenWeather"
},
{
"parameters": {
"jsCode": "// Captura o texto enviado pelo usu\u00e1rio no Telegram\nconst rawText = $json.message.text || \"\";\n\n// 1. Remove espa\u00e7os desnecess\u00e1rios nas extremidades\nlet cleanText = rawText.trim();\n\n// 2. Divide a string pela v\u00edrgula\nlet parts = cleanText.split(\",\");\n\n// 3. Normaliza\u00e7\u00e3o\nlet cidade = parts[0] ? parts[0].trim() : \"\";\nlet estado = parts[1] ? parts[1].trim().toUpperCase() : \"\"; // Estado sempre em MAI\u00daSCULO\n\n// 4. Monta a string final para a API (Cidade,UF,BR)\n// A API lida bem com acentua\u00e7\u00e3o, ent\u00e3o mantemos o nome da cidade original, apenas com trim.\nconst buscaApi = `${cidade},${estado},BR`;\n\nreturn {\n cidade: cidade,\n estado: estado,\n termoBusca: buscaApi,\n valido: (cidade !== \"\" && estado.length === 2) // Valida\u00e7\u00e3o simples\n};"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-656,
748
],
"id": "833b7e4d-68d8-4ee6-b489-ce5f77a4ce69",
"name": "Cria JSON para consulta na API"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "d22d275d-ae27-4483-ad56-f34341a7016a",
"leftValue": "={{ $json.valido }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
-432,
748
],
"id": "7f18d4a8-7c68-4903-b0aa-511d01a8a1cd",
"name": "Verifica validade do JSON"
},
{
"parameters": {
"chatId": "={{ $('Mensagem do usu\u00e1rio').item.json.message.chat.id }}",
"text": "=\u274c Formato inv\u00e1lido. Use o formato Cidade,UF(ex.: S\u00e3o Paulo,SP). Certifique-se de que tenha digitado corretamente.",
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
-208,
844
],
"id": "ee185cb7-28c7-4bf1-bbbf-8ed37ee99286",
"name": "Envia erro para usu\u00e1rio",
"notesInFlow": true,
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"notes": "Caso algum erro aconte\u00e7a, a mensagem de erro \u00e9 enviada para p usu\u00e1rio pedindo para que envie as informa\u00e7\u00f5es on formato correto"
},
{
"parameters": {
"url": "https://api.openweathermap.org/data/2.5/weather",
"authentication": "genericCredentialType",
"genericAuthType": "httpQueryAuth",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "q",
"value": "={{ $json.termoBusca }}"
},
{
"name": "units",
"value": "metric"
},
{
"name": "lang",
"value": "pt_br"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
-208,
652
],
"id": "176e5c6f-2533-4276-a174-56ea7fd2abed",
"name": "Consulta OpenWeather",
"notesInFlow": true,
"alwaysOutputData": true,
"credentials": {
"httpQueryAuth": {
"name": "<your credential>"
}
},
"onError": "continueErrorOutput",
"notes": "Busca as informa\u00e7\u00f5es do clina da cidade que o usu\u00e1rio informou"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "e3dc2231-126e-435b-8895-228ddab0912a",
"leftValue": "={{ $json.name }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
}
},
{
"id": "e8cf3a3e-fa17-4deb-ad9b-bd64f40091f7",
"leftValue": "={{ $json.main.temp }}",
"rightValue": 0,
"operator": {
"type": "number",
"operation": "exists",
"singleValue": true
}
},
{
"id": "58363bc1-e9c5-484d-acac-ebcebbea1b3a",
"leftValue": "={{ $json.cod }}",
"rightValue": 200,
"operator": {
"type": "number",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
16,
652
],
"id": "e29f418a-11df-4928-85b9-77672d58806a",
"name": "Valida\u00e7\u00e3o das informa\u00e7\u00f5es",
"notesInFlow": true,
"notes": "Valida se o retorno possui todos os campos e informa\u00e7\u00f5es necess\u00e1rias para seguir com o fluxo"
},
{
"parameters": {
"chatId": "={{ $('Mensagem do usu\u00e1rio').item.json.message.chat.id }}",
"text": "=\u274c Cidade n\u00e3o encontrada. Use o formato Cidade,UF (ex.: S\u00e3o Paulo,SP).",
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
360,
800
],
"id": "e8e6b7ee-8dc8-4677-b1af-8bc15e4ee46f",
"name": "Envia erro para o usu\u00e1rio",
"notesInFlow": true,
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"notes": "Caso aconte\u00e7a algum tipo de erro no momento da consulta \u00e0 API, o erro \u00e9 retornado para o usu\u00e1rio pedindo para que envie as informa\u00e7\u00f5es no formato desejado."
},
{
"parameters": {
"jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nfor (const item of $input.all()) {\n item.json.myNewField = 1;\n}\n\nreturn $input.all();"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
928,
600
],
"id": "c2d36a22-6042-44d8-9fd4-b47ea439e422",
"name": "Ajusta resposta para o usu\u00e1rio",
"notesInFlow": true,
"notes": "Este n\u00f3 vai \"fingir\" ser o Gemini quando ele falhar."
},
{
"parameters": {
"chatId": "={{ $('Mensagem do usu\u00e1rio').item.json.message.chat.id }}",
"text": "=\ud83c\udf24\ufe0f A temperatura em {{ $json.name }} \u00e9 de {{ $json.main.temp.round(1)+\"\u00baC\" }}",
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1152,
600
],
"id": "e52e5155-3991-4846-8c3b-4f5546d4fbc8",
"name": "Resposta para o usu\u00e1rio1",
"notesInFlow": true,
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"notes": "Responde para o usu\u00e1rio com a mensagem padr\u00e3o, por conta da falha do Gemini."
},
{
"parameters": {
"options": {
"maxTokens": 200,
"temperature": 0.2
}
},
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"typeVersion": 1,
"position": [
368,
624
],
"id": "826ef1c2-7ea6-4baa-b965-a14d7bed0bf8",
"name": "OpenRouter Chat Model",
"credentials": {
"openRouterApi": {
"name": "<your credential>"
}
}
}
],
"connections": {
"AI Agent": {
"main": [
[
{
"node": "Verifica se existe a resposta do agente",
"type": "main",
"index": 0
}
],
[]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "AI Agent",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Google Gemini Chat Model1": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Verifica se existe a resposta do agente": {
"main": [
[
{
"node": "Resposta para o usu\u00e1rio",
"type": "main",
"index": 0
}
],
[
{
"node": "Ajusta resposta para o usu\u00e1rio",
"type": "main",
"index": 0
}
]
]
},
"Mensagem do usu\u00e1rio": {
"main": [
[
{
"node": "Cria JSON para consulta na API",
"type": "main",
"index": 0
}
]
]
},
"Cria JSON para consulta na API": {
"main": [
[
{
"node": "Verifica validade do JSON",
"type": "main",
"index": 0
}
]
]
},
"Verifica validade do JSON": {
"main": [
[
{
"node": "Consulta OpenWeather",
"type": "main",
"index": 0
}
],
[
{
"node": "Envia erro para usu\u00e1rio",
"type": "main",
"index": 0
}
]
]
},
"Consulta OpenWeather": {
"main": [
[
{
"node": "Valida\u00e7\u00e3o das informa\u00e7\u00f5es",
"type": "main",
"index": 0
}
]
]
},
"Valida\u00e7\u00e3o das informa\u00e7\u00f5es": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
],
[
{
"node": "Envia erro para o usu\u00e1rio",
"type": "main",
"index": 0
}
]
]
},
"Ajusta resposta para o usu\u00e1rio": {
"main": [
[
{
"node": "Resposta para o usu\u00e1rio1",
"type": "main",
"index": 0
}
]
]
},
"OpenRouter Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 1
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "8fa901b6-d21f-4c25-b889-07e3b21f632c",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "Vg07qQJsJ5EHAUMc",
"tags": [
{
"updatedAt": "2025-10-30T12:11:07.961Z",
"createdAt": "2025-10-30T12:11:07.961Z",
"id": "xjSM5R04IJQI3e0A",
"name": "Study"
},
{
"updatedAt": "2026-01-17T23:14:30.627Z",
"createdAt": "2026-01-17T23:14:30.627Z",
"id": "RKxbvzdjPL9o1G19",
"name": "Challenge"
}
]
}
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.
googlePalmApihttpQueryAuthopenRouterApitelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Desafio Fase 2 - Bot de Clima no Telegram com N8N. Uses agent, outputParserStructured, lmChatGoogleGemini, telegram. Event-driven trigger; 15 nodes.
Source: https://github.com/adriano-klein/chatbot-telegram/blob/8a66b5029556f73d04f3b09082ca0243f4f470bc/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.
Arvifund - Supabase (Fixed v6). Uses httpRequest, telegram, supabase, telegramTrigger. Event-driven trigger; 92 nodes.
Arvifund - Supabase (Fixed v5). Uses httpRequest, telegram, googleSheets, telegramTrigger. Event-driven trigger; 91 nodes.
Arvifund - Supabase. Uses httpRequest, telegram, googleSheets, telegramTrigger. Event-driven trigger; 90 nodes.
Arvifund - Supabase (Fixed v2). Uses httpRequest, telegram, googleSheets, telegramTrigger. Event-driven trigger; 90 nodes.
Arvifund - Supabase (Fixed v4). Uses httpRequest, telegram, googleSheets, telegramTrigger. Event-driven trigger; 90 nodes.