8
n8n 中文网amn8n.com

基于SMS的天气警报(OpenWeather + Twilio)

中级

这是一个Personal Productivity, Multimodal AI领域的自动化工作流,包含 9 个节点。主要使用 If, Code, Cron, Twilio, HttpRequest 等节点。 基于SMS的天气警报(OpenWeather + Twilio)

前置要求
  • 可能需要目标 API 的认证凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "meta": {
    "instanceId": "2000c64071c20843606b95c63795bb0797c41036047055a6586498e855b96efc"
  },
  "nodes": [
    {
      "id": "9ababe8e-1ba5-4255-b97c-1b4e9e79ef99",
      "name": "设置说明",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -224,
        -16
      ],
      "parameters": {
        "width": 712,
        "height": 680,
        "content": "🌤️ **需要设置:**"
      },
      "typeVersion": 1
    },
    {
      "id": "31bcbe91-559b-4ad4-bd3a-d0b470c7eda4",
      "name": "每 6 小时检查",
      "type": "n8n-nodes-base.cron",
      "position": [
        144,
        304
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "fef45e7b-e895-43f6-9101-a8aa879304d5",
      "name": "获取当前天气",
      "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": "获取天气预报",
      "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": "分析天气数据",
      "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": "需要警报吗?",
      "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": "格式化短信警报",
      "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": "发送天气短信",
      "type": "n8n-nodes-base.twilio",
      "position": [
        1152,
        272
      ],
      "parameters": {
        "message": "={{ $json.message }}",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "daa67817-5a38-4865-a686-4d94862eecdc",
      "name": "记录已发送警报",
      "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
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

中级 - 个人效率, 多模态 AI

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
中级
节点数量9
分类2
节点类型6
难度说明

适合有一定经验的用户,包含 6-15 个节点的中等复杂度工作流

作者
David Olusola

David Olusola

@dae221

I help ambitious businesses eliminate operational bottlenecks and scale faster with AI automation. My clients typically see 40-60% efficiency gains within 90 days. Currently accepting 3 new projects this quarter - david@daexai.com

外部链接
在 n8n.io 查看

分享此工作流