{
  "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": []
}