AutomationFlowsAI & RAG › Hourly Proactive Weather Alerts Workflow

Hourly Proactive Weather Alerts Workflow

Original n8n title: Alertas Proactivas

Alertas Proactivas. Uses httpRequest, lmChatGoogleGemini, agent, gmailTool. Scheduled trigger; 11 nodes.

Cron / scheduled trigger★★★★☆ complexityAI-powered11 nodesHTTP RequestGoogle Gemini ChatAgentGmail Tool
AI & RAG Trigger: Cron / scheduled Nodes: 11 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the Agent → Gmail Tool 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 →

Download .json
{
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 * * * *"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.3,
      "position": [
        0,
        300
      ],
      "id": "alerta-001-schedule",
      "name": "Trigger Cada Hora"
    },
    {
      "parameters": {
        "url": "https://tuclima-mundial.onrender.com/api/alertas/usuarios/",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "X-Alertas-Secret",
              "value": "REEMPLAZAR_CON_N8N_ALERTAS_SECRET"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        240,
        300
      ],
      "id": "alerta-002-get-users",
      "name": "Obtener Usuarios"
    },
    {
      "parameters": {
        "jsCode": "// Convertir el array de usuarios en items separados (uno por usuario)\nconst data = $input.first().json;\nif (!data.usuarios || data.usuarios.length === 0) {\n  return [];\n}\nreturn data.usuarios.map(u => ({ json: u }));"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        480,
        300
      ],
      "id": "alerta-003-expand",
      "name": "Expandir Usuarios"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": false,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 3
          },
          "conditions": [
            {
              "id": "filter-hora-alerta",
              "leftValue": "={{ $json.hora_alerta }}",
              "rightValue": "={{ $now.setZone('America/Argentina/Buenos_Aires').hour }}",
              "operator": {
                "type": "number",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "looseTypeValidation": true,
        "options": {}
      },
      "type": "n8n-nodes-base.filter",
      "typeVersion": 2.3,
      "position": [
        720,
        300
      ],
      "id": "alerta-004-filter-hora",
      "name": "Filtrar por Hora"
    },
    {
      "parameters": {
        "url": "https://geocoding-api.open-meteo.com/v1/search",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "name",
              "value": "={{ $json.ubicacion_nombre }}"
            },
            {
              "name": "count",
              "value": "1"
            },
            {
              "name": "language",
              "value": "es"
            },
            {
              "name": "format",
              "value": "json"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        960,
        300
      ],
      "id": "alerta-005-geocoding",
      "name": "Geocodificar Ubicacion"
    },
    {
      "parameters": {
        "jsCode": "// Verificar que la geocodificaci\u00f3n tuvo resultado\nconst geo = $input.first().json;\nif (!geo.results || geo.results.length === 0) {\n  // Ciudad no encontrada: saltar este usuario\n  return [];\n}\nconst loc = geo.results[0];\nreturn [{\n  json: {\n    lat: loc.latitude,\n    lon: loc.longitude,\n    city_resolved: `${loc.name}, ${loc.country_code || loc.country || ''}`\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1200,
        300
      ],
      "id": "alerta-006-verify-geo",
      "name": "Verificar Geocodificacion"
    },
    {
      "parameters": {
        "url": "https://api.open-meteo.com/v1/forecast",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "latitude",
              "value": "={{ $json.lat }}"
            },
            {
              "name": "longitude",
              "value": "={{ $json.lon }}"
            },
            {
              "name": "timezone",
              "value": "America/Argentina/Buenos_Aires"
            },
            {
              "name": "forecast_days",
              "value": "3"
            },
            {
              "name": "current",
              "value": "temperature_2m,relative_humidity_2m,precipitation,rain,weather_code,wind_speed_10m,wind_gusts_10m,visibility"
            },
            {
              "name": "daily",
              "value": "weather_code,temperature_2m_max,temperature_2m_min,precipitation_sum,precipitation_probability_max,wind_speed_10m_max,et0_fao_evapotranspiration"
            },
            {
              "name": "hourly",
              "value": "cape,lifted_index,shortwave_radiation,cloud_cover"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "User-Agent",
              "value": "TuClimaApp-Alertas"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        1440,
        300
      ],
      "id": "alerta-007-forecast",
      "name": "Obtener Pronostico"
    },
    {
      "parameters": {
        "jsCode": "// Evaluar umbrales clim\u00e1ticos por sector y preparar datos para el AI Agent\nconst usuario = $('Filtrar por Hora').item.json;\nconst geo     = $('Verificar Geocodificacion').item.json;\nconst fc      = $input.first().json;  // forecast\n\nconst sectores = (usuario.sectores || 'agro').split(',').map(s => s.trim().toLowerCase());\nconst alertas  = [];\nconst current  = fc.current  || {};\nconst daily    = fc.daily    || {};\nconst hourly   = fc.hourly   || {};\n\n// --- Valores clave del pron\u00f3stico ---\nconst tempMin3d   = daily.temperature_2m_min?.length ? Math.min(...daily.temperature_2m_min) : 99;\nconst tempMax3d   = daily.temperature_2m_max?.length ? Math.max(...daily.temperature_2m_max) : 0;\nconst lluviaMax   = daily.precipitation_sum?.length  ? Math.max(...daily.precipitation_sum)  : 0;\nconst vientoMax3d = daily.wind_speed_10m_max?.length ? Math.max(...daily.wind_speed_10m_max) : 0;\nconst vientoActual  = current.wind_speed_10m  || 0;\nconst rafagaActual  = current.wind_gusts_10m  || 0;\nconst visibilidad   = current.visibility      || 99999;\nconst capePico      = hourly.cape?.length    ? Math.max(...hourly.cape.slice(0, 48))                        : 0;\nconst radMedia      = hourly.shortwave_radiation?.length\n  ? hourly.shortwave_radiation.slice(0, 24).reduce((a, b) => a + b, 0) / 24\n  : 200;\n\n// --- Umbrales por sector ---\nif (sectores.includes('agro')) {\n  if (tempMin3d <= 2)   alertas.push(`\ud83e\udd76 HELADA: m\u00ednima de ${tempMin3d.toFixed(1)}\u00b0C en los pr\u00f3ximos 3 d\u00edas`);\n  if (lluviaMax >= 30)  alertas.push(`\ud83c\udf27\ufe0f LLUVIA INTENSA: ${lluviaMax.toFixed(0)} mm m\u00e1x pronosticados`);\n  if (vientoMax3d >= 60) alertas.push(`\ud83d\udca8 VIENTO FUERTE: r\u00e1fagas de hasta ${vientoMax3d.toFixed(0)} km/h`);\n}\n\nif (sectores.includes('naval')) {\n  if (vientoActual > 40)  alertas.push(`\u2693 VIENTO PELIGROSO: ${vientoActual.toFixed(0)} km/h \u2014 operaciones en riesgo`);\n  if (visibilidad < 1000) alertas.push(`\ud83c\udf2b\ufe0f NIEBLA ESPESA: visibilidad ${Math.round(visibilidad)} m`);\n  if (lluviaMax >= 20 && rafagaActual > 35)\n    alertas.push(`\ud83c\udf0a MAL TIEMPO COMBINADO: lluvia + r\u00e1fagas de ${rafagaActual.toFixed(0)} km/h`);\n}\n\nif (sectores.includes('aereo')) {\n  if (capePico > 1500)    alertas.push(`\u26a1 ALTA INESTABILIDAD: CAPE ${Math.round(capePico)} J/kg \u2014 tormentas posibles`);\n  if (vientoActual > 60)  alertas.push(`\u2708\ufe0f VIENTOS INTENSOS: ${vientoActual.toFixed(0)} km/h en superficie`);\n  if (visibilidad < 3000) alertas.push(`\ud83c\udf2b\ufe0f VISIBILIDAD REDUCIDA: ${(visibilidad / 1000).toFixed(1)} km`);\n}\n\nif (sectores.includes('energia')) {\n  if (radMedia < 50)       alertas.push(`\u2601\ufe0f BAJA RADIACI\u00d3N SOLAR: ${radMedia.toFixed(0)} W/m\u00b2 promedio \u2014 impacto en paneles`);\n  if (vientoMax3d > 80)    alertas.push(`\ud83c\udf00 VIENTO EXTREMO: ${vientoMax3d.toFixed(0)} km/h \u2014 revisar turbinas e\u00f3licas`);\n}\n\nreturn [{\n  json: {\n    ...usuario,\n    alertas,\n    nivel: alertas.length > 0 ? 'alerta' : 'normal',\n    alertas_texto: alertas.length > 0 ? alertas.join('\\n') : 'Sin condiciones cr\u00edticas hoy.',\n    ubicacion_resuelta: geo.city_resolved || usuario.ubicacion_nombre,\n    clima_resumen: {\n      temp_actual:  current.temperature_2m,\n      temp_min_3d:  tempMin3d,\n      temp_max_3d:  tempMax3d,\n      lluvia_max_3d: lluviaMax,\n      viento_actual: vientoActual,\n      rafaga_actual: rafagaActual,\n      humedad:      current.relative_humidity_2m,\n    }\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1680,
        300
      ],
      "id": "alerta-008-umbrales",
      "name": "Evaluar Umbrales"
    },
    {
      "parameters": {
        "modelName": "models/gemini-2.0-flash",
        "options": {
          "maxOutputTokens": 700
        }
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "typeVersion": 1,
      "position": [
        1800,
        520
      ],
      "id": "alerta-009-gemini",
      "name": "Google Gemini Chat Model",
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "Sos el asistente clim\u00e1tico profesional de TuClima.\n\nDatos del usuario:\n- Nombre: {{ $json.nombre }}\n- Sectores: {{ $json.sectores }}\n- Ubicaci\u00f3n: {{ $json.ubicacion_resuelta }}\n- Nivel: {{ $json.nivel }}\n\nAlertas detectadas:\n{{ $json.alertas_texto }}\n\nClima actual y pron\u00f3stico 3 d\u00edas:\n- Temperatura actual: {{ $json.clima_resumen.temp_actual }}\u00b0C | Humedad: {{ $json.clima_resumen.humedad }}%\n- M\u00ednima pr\u00f3x. 3d: {{ $json.clima_resumen.temp_min_3d }}\u00b0C | M\u00e1xima: {{ $json.clima_resumen.temp_max_3d }}\u00b0C\n- Lluvia m\u00e1x. 3d: {{ $json.clima_resumen.lluvia_max_3d }} mm | Viento: {{ $json.clima_resumen.viento_actual }} km/h\n\nRedact\u00e1 un email en espa\u00f1ol profesional y conciso (m\u00e1x 200 palabras):\n- Si nivel='alerta': asunto '\u26a0\ufe0f Alerta clim\u00e1tica para tu sector \u2014 TuClima' \u2014 destac\u00e1 cada alerta con UNA acci\u00f3n concreta por sector\n- Si nivel='normal': asunto '\u2600\ufe0f Tu resumen clim\u00e1tico del d\u00eda \u2014 TuClima' \u2014 tono positivo con 2-3 recomendaciones pr\u00e1cticas\n- Inici\u00e1 con 'Hola {{ $json.nombre }},'\n- Cerr\u00e1 con 'El equipo de TuClima'\n- NO uses markdown, NO uses HTML \u2014 texto plano con saltos de l\u00ednea\n\nLuego envi\u00e1 el email inmediatamente usando la herramienta enviar_correo. Destinatario: {{ $json.email }}",
        "options": {
          "maxIterations": 3
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3.1,
      "position": [
        1920,
        300
      ],
      "id": "alerta-010-agent",
      "name": "AI Agent Email"
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Env\u00eda el email de reporte o alerta clim\u00e1tica al usuario. \u00dasala exactamente UNA vez. Pas\u00e1 el asunto y el cuerpo del mensaje.",
        "sendTo": "={{ $('Filtrar por Hora').item.json.email }}",
        "subject": "={{ $fromAI('subject', 'Reporte clim\u00e1tico TuClima') }}",
        "message": "={{ $fromAI('mensaje', 'Cuerpo del email') }}",
        "options": {}
      },
      "type": "n8n-nodes-base.gmailTool",
      "typeVersion": 2.2,
      "position": [
        2160,
        520
      ],
      "id": "alerta-011-gmail",
      "name": "enviar_correo",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Trigger Cada Hora": {
      "main": [
        [
          {
            "node": "Obtener Usuarios",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Obtener Usuarios": {
      "main": [
        [
          {
            "node": "Expandir Usuarios",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Expandir Usuarios": {
      "main": [
        [
          {
            "node": "Filtrar por Hora",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filtrar por Hora": {
      "main": [
        [
          {
            "node": "Geocodificar Ubicacion",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Geocodificar Ubicacion": {
      "main": [
        [
          {
            "node": "Verificar Geocodificacion",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Verificar Geocodificacion": {
      "main": [
        [
          {
            "node": "Obtener Pronostico",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Obtener Pronostico": {
      "main": [
        [
          {
            "node": "Evaluar Umbrales",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Evaluar Umbrales": {
      "main": [
        [
          {
            "node": "AI Agent Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent Email",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "enviar_correo": {
      "ai_tool": [
        [
          {
            "node": "AI Agent Email",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    }
  },
  "meta": {
    "templateCredsSetupCompleted": true
  }
}

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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Alertas Proactivas. Uses httpRequest, lmChatGoogleGemini, agent, gmailTool. Scheduled trigger; 11 nodes.

Source: https://github.com/santinote9-droid/tuclima-mundial/blob/8a042ba155cd628889eb8eef2b54df6fdde37101/n8n/alertas_proactivas.json — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

This workflow monitors Bitcoin price changes every 30 minutes. If the price increases or decreases by 3% or more, it fetches recent Bitcoin-related news, summarizes it using AI (Google Gemini) and sen

Agent, Google Gemini Chat, Gmail Tool +2
AI & RAG

This workflow makes it easier to keep track of the stocks market and get an email with a summary of the daily highlights on what happened, key insights and trends Define the schedule (days, times, int

HTTP Request, Google Sheets, Google Gemini Chat +2
AI & RAG

LinkedIn_Job_Hunt_and_Cover_Letter. Uses outputParserStructured, outputParserAutofixing, googleDrive, agent. Scheduled trigger; 85 nodes.

Output Parser Structured, Output Parser Autofixing, Google Drive +6
AI & RAG

Automatically scan major financial newswires for biotech catalyst events, score them with AI sentiment analysis, and surface ranked trade candidates — all without manual monitoring.

RSS Feed Read, Data Table, HTTP Request +4
AI & RAG

Author: Nguyen Thieu Toan Category: Community & Knowledge Automation Tags: Telegram, Reddit, n8n Forum, AI Summarization, Gemini, Groq

Groq Chat, Output Parser Structured, Memory Mongo Db Chat +5