N
n8n Store
Workflow Market
Weather Alerts via SMS (OpenWeather + Twilio)

Weather Alerts via SMS (OpenWeather + Twilio)

by dae2210 views

描述

分类

📊 Productivity🤖 AI & Machine Learning

使用的节点

n8n-nodes-base.ifn8n-nodes-base.coden8n-nodes-base.coden8n-nodes-base.coden8n-nodes-base.cronn8n-nodes-base.twilion8n-nodes-base.stickyNoten8n-nodes-base.httpRequestn8n-nodes-base.httpRequest
价格免费
浏览量0
最后更新11/28/2025
workflow.json
{
  "meta": {
    "instanceId": "2000c64071c20843606b95c63795bb0797c41036047055a6586498e855b96efc"
  },
  "nodes": [
    {
      "id": "9ababe8e-1ba5-4255-b97c-1b4e9e79ef99",
      "name": "Setup Instructions",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -224,
        -16
      ],
      "parameters": {
        "width": 712,
        "height": 680,
        "content": "🌤️ **SETUP REQUIRED:**\n\n1. **OpenWeather API:**\n   - Get FREE API key: openweathermap.org\n   - Update city/coordinates below\n   - 1000 calls/day free tier\n\n2. **Twilio Account:**\n   - Sign up at twilio.com\n   - Get Account SID & Auth Token\n   - Buy phone number ($1/month)\n   - Add to n8n credentials\n\n3. **Recipients:**\n   - Update phone numbers in SMS node\n   - Format: +1234567890\n\n4. **Alert Conditions:**\n   - Currently: rain, snow, extreme temps\n   - Customize in condition nodes\n\n⚡ Runs every 6 hours for timely alerts!"
      },
      "typeVersion": 1
    },
    {
      "id": "31bcbe91-559b-4ad4-bd3a-d0b470c7eda4",
      "name": "Check Every 6 Hours",
      "type": "n8n-nodes-base.cron",
      "position": [
        144,
        304
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "fef45e7b-e895-43f6-9101-a8aa879304d5",
      "name": "Get Current Weather",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        352,
        304
      ],
      "parameters": {
        "url": "https://api.openweathermap.org/data/2.5/weather",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "q",
              "value": "New York,US"
            },
            {
              "name": "appid",
              "value": "YOUR_OPENWEATHER_API_KEY"
            },
            {
              "name": "units",
              "value": "imperial"
            }
          ]
        }
      },
      "typeVersion": 4.1
    },
    {
      "id": "3b0b3916-e46d-4bb3-bc43-660e3da9ac98",
      "name": "Get Weather Forecast",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        352,
        448
      ],
      "parameters": {
        "url": "https://api.openweathermap.org/data/2.5/forecast",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "q",
              "value": "New York,US"
            },
            {
              "name": "appid",
              "value": "YOUR_OPENWEATHER_API_KEY"
            },
            {
              "name": "units",
              "value": "imperial"
            },
            {
              "name": "cnt",
              "value": "8"
            }
          ]
        }
      },
      "typeVersion": 4.1
    },
    {
      "id": "f1ec579d-ca05-4ab2-bdcb-ba13e43fe32c",
      "name": "Analyze Weather Data",
      "type": "n8n-nodes-base.code",
      "position": [
        544,
        384
      ],
      "parameters": {
        "jsCode": "// Normalize weather data and determine if alerts are needed\nconst currentWeather = $('Get Current Weather').item.json;\nconst forecast = $('Get Weather Forecast').item.json;\n\n// Current weather analysis\nconst current = {\n  temperature: Math.round(currentWeather.main.temp),\n  feels_like: Math.round(currentWeather.main.feels_like),\n  humidity: currentWeather.main.humidity,\n  description: currentWeather.weather[0].description,\n  main_condition: currentWeather.weather[0].main.toLowerCase(),\n  wind_speed: Math.round(currentWeather.wind.speed),\n  city: currentWeather.name,\n  country: currentWeather.sys.country\n};\n\n// Forecast analysis (next 24 hours)\nconst upcoming = [];\nforecast.list.slice(0, 8).forEach(item => {\n  upcoming.push({\n    time: new Date(item.dt * 1000).toLocaleString(),\n    temp: Math.round(item.main.temp),\n    condition: item.weather[0].main.toLowerCase(),\n    description: item.weather[0].description,\n    rain_probability: Math.round((item.pop || 0) * 100)\n  });\n});\n\n// Alert conditions\nconst alerts = [];\n\n// Temperature alerts\nif (current.temperature >= 95) {\n  alerts.push(`🔥 EXTREME HEAT: ${current.temperature}°F (feels like ${current.feels_like}°F)`);\n} else if (current.temperature <= 20) {\n  alerts.push(`🥶 EXTREME COLD: ${current.temperature}°F (feels like ${current.feels_like}°F)`);\n}\n\n// Severe weather alerts\nif (['thunderstorm', 'tornado'].includes(current.main_condition)) {\n  alerts.push(`⛈️ SEVERE WEATHER: ${current.description}`);\n}\n\n// Precipitation alerts\nif (['rain', 'drizzle'].includes(current.main_condition)) {\n  alerts.push(`🌧️ RAIN ALERT: ${current.description}`);\n} else if (current.main_condition === 'snow') {\n  alerts.push(`❄️ SNOW ALERT: ${current.description}`);\n}\n\n// Wind alerts\nif (current.wind_speed >= 25) {\n  alerts.push(`💨 HIGH WINDS: ${current.wind_speed} mph`);\n}\n\n// Check upcoming severe weather\nconst upcomingBad = upcoming.filter(item => \n  ['thunderstorm', 'snow', 'rain'].includes(item.condition) || \n  item.rain_probability >= 70\n);\n\nif (upcomingBad.length > 0) {\n  alerts.push(`⚠️ UPCOMING: ${upcomingBad[0].description} at ${upcomingBad[0].time.split(',')[1]} (${upcomingBad[0].rain_probability}% chance)`);\n}\n\nconst weatherData = {\n  location: `${current.city}, ${current.country}`,\n  current_weather: current,\n  forecast_24h: upcoming,\n  alerts: alerts,\n  has_alerts: alerts.length > 0,\n  alert_count: alerts.length,\n  timestamp: new Date().toLocaleString()\n};\n\nconsole.log(`Weather check for ${weatherData.location}: ${weatherData.alert_count} alerts found`);\n\nreturn {\n  json: weatherData\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "5524be11-f80e-4710-85cf-3eb5f6ee8cf8",
      "name": "Alert Needed?",
      "type": "n8n-nodes-base.if",
      "position": [
        752,
        384
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition-1",
              "operator": {
                "type": "boolean",
                "operation": "equal"
              },
              "leftValue": "={{ $json.has_alerts }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "e903afab-78c9-424a-aa6a-8a985abc8aae",
      "name": "Format SMS Alert",
      "type": "n8n-nodes-base.code",
      "position": [
        944,
        272
      ],
      "parameters": {
        "jsCode": "// Format weather alert SMS message\nconst weatherData = $input.first().json;\n\nlet smsMessage = `🌤️ WEATHER ALERT - ${weatherData.location}\\n\\n`;\n\n// Add current conditions\nsmsMessage += `NOW: ${weatherData.current_weather.temperature}°F, ${weatherData.current_weather.description}\\n\\n`;\n\n// Add alerts\nsmsMessage += `🚨 ALERTS (${weatherData.alert_count}):\\n`;\nweatherData.alerts.forEach(alert => {\n  smsMessage += `${alert}\\n`;\n});\n\n// Add next few hours preview\nconst next3Hours = weatherData.forecast_24h.slice(0, 3);\nsmsMessage += `\\n📅 NEXT 3 HOURS:\\n`;\nnext3Hours.forEach(forecast => {\n  const time = forecast.time.split(' ')[1]; // Get just time part\n  smsMessage += `${time}: ${forecast.temp}°F, ${forecast.description}\\n`;\n});\n\nsmsMessage += `\\n⏰ Alert sent: ${weatherData.timestamp}`;\n\n// Keep SMS under 160 characters if possible, or split into multiple\nconst formattedAlert = {\n  message: smsMessage,\n  location: weatherData.location,\n  alert_type: weatherData.alerts[0] ? weatherData.alerts[0].split(':')[0] : 'GENERAL',\n  urgency: weatherData.alerts.some(alert => \n    alert.includes('EXTREME') || alert.includes('SEVERE')\n  ) ? 'HIGH' : 'MEDIUM'\n};\n\nconsole.log(`Formatted SMS alert (${formattedAlert.urgency} urgency):`, formattedAlert.alert_type);\n\nreturn {\n  json: formattedAlert\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "49355489-755c-47b7-ba89-a1a9254dd2ef",
      "name": "Send Weather SMS",
      "type": "n8n-nodes-base.twilio",
      "position": [
        1152,
        272
      ],
      "parameters": {
        "message": "={{ $json.message }}",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "daa67817-5a38-4865-a686-4d94862eecdc",
      "name": "Log Alert Sent",
      "type": "n8n-nodes-base.code",
      "position": [
        1344,
        272
      ],
      "parameters": {
        "jsCode": "// Log successful weather alert\nconst alertData = $('Format SMS Alert').item.json;\n\nconsole.log(`✅ Weather alert sent successfully!`);\nconsole.log(`📍 Location: ${alertData.location}`);\nconsole.log(`⚠️ Alert Type: ${alertData.alert_type}`);\nconsole.log(`🔥 Urgency: ${alertData.urgency}`);\n\nreturn {\n  json: {\n    status: 'sent',\n    alert_summary: `Weather alert sent for ${alertData.location} - ${alertData.alert_type}`,\n    urgency: alertData.urgency,\n    timestamp: new Date().toISOString()\n  }\n};"
      },
      "typeVersion": 2
    }
  ],
  "pinData": {},
  "connections": {
    "Alert Needed?": {
      "main": [
        [
          {
            "node": "Format SMS Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format SMS Alert": {
      "main": [
        [
          {
            "node": "Send Weather SMS",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Weather SMS": {
      "main": [
        [
          {
            "node": "Log Alert Sent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Every 6 Hours": {
      "main": [
        [
          {
            "node": "Get Current Weather",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get Weather Forecast",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Current Weather": {
      "main": [
        [
          {
            "node": "Analyze Weather Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze Weather Data": {
      "main": [
        [
          {
            "node": "Alert Needed?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Weather Forecast": {
      "main": [
        [
          {
            "node": "Analyze Weather Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

相关工作流