8
n8n 中文网amn8n.com

BMKG天气监控和Telegram警报系统

中级

这是一个自动化工作流,包含 14 个节点。主要使用 If, Code, Telegram, HttpRequest, ManualTrigger 等节点。 使用BMKG数据和Telegram通知自动发送印尼天气警报

前置要求
  • Telegram Bot Token
  • 可能需要目标 API 的认证凭证

分类

-
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "oezF9oCv3tPecrSv",
  "meta": {
    "instanceId": "b14f5dd921befc4584084cc386aea593f73c7c2b00b50933075d7967a4d1c502",
    "templateCredsSetupCompleted": true
  },
  "name": "BMKG天气监控和Telegram警报系统",
  "tags": [
    {
      "id": "5elPMuYGw7BLPyD5",
      "name": "Weather Monitoring EN",
      "createdAt": "2025-10-15T00:58:29.022Z",
      "updatedAt": "2025-10-15T00:58:29.022Z"
    }
  ],
  "nodes": [
    {
      "id": "a7760673-0f36-4693-b0e2-b12ec5319247",
      "name": "计划触发器",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -448,
        -16
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 6
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "bf292408-48a2-4fb8-baf5-38c7b5f36862",
      "name": "获取BMKG天气数据",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        112,
        192
      ],
      "parameters": {
        "url": "https://api.bmkg.go.id/publik/prakiraan-cuaca",
        "options": {}
      },
      "typeVersion": 4.1
    },
    {
      "id": "af473f94-7a67-4023-94b5-3bdf8015280a",
      "name": "处理天气数据",
      "type": "n8n-nodes-base.code",
      "position": [
        304,
        0
      ],
      "parameters": {
        "jsCode": "// Process BMKG weather data\nconst inputData = $input.all();\nconst weatherData = inputData[0].json;\n\n// Check if data exists\nif (!weatherData || !weatherData.data || !weatherData.data[0] || !weatherData.data[0].cuaca) {\n    return [{\n        json: {\n            success: false,\n            error: 'Weather data not available from BMKG API',\n            timestamp: new Date().toISOString()\n        }\n    }];\n}\n\n// Extract location information\nconst location = weatherData.lokasi || {};\nconst cuacaData = weatherData.data[0].cuaca;\n\n// Process current and upcoming weather\nlet processedData = {\n    success: true,\n    timestamp: new Date().toISOString(),\n    location: {\n        desa: location.desa || 'Unknown',\n        kecamatan: location.kecamatan || 'Unknown',\n        kotkab: location.kotkab || 'Unknown',\n        provinsi: location.provinsi || 'Unknown',\n        lat: location.lat || 0,\n        lon: location.lon || 0,\n        timezone: location.timezone || 'Asia/Jakarta'\n    },\n    current_weather: {},\n    forecast_24hour: [],\n    summary: {\n        avg_temperature: 0,\n        avg_humidity: 0,\n        dominant_condition: '',\n        warnings: []\n    }\n};\n\n// Process current weather (first data point)\nif (cuacaData[0] && cuacaData[0][0]) {\n    const current = cuacaData[0][0];\n    processedData.current_weather = {\n        time: current.local_datetime || current.datetime,\n        temperature: current.t || 0,\n        humidity: current.hu || 0,\n        condition: current.weather_desc || current.weather_desc_en || 'Unknown',\n        wind_speed: current.ws || 0,\n        wind_direction: current.wd || 'N/A',\n        visibility: current.vs_text || 'N/A',\n        cloud_cover: current.tcc || 0,\n        rain_probability: current.tp || 0,\n        icon_url: current.image || ''\n    };\n}\n\n// Process 24-hour forecast\nlet totalTemperature = 0;\nlet totalHumidity = 0;\nlet count = 0;\nlet conditionCount = {};\n\n// Collect data from first day (today)\nif (cuacaData[0]) {\n    cuacaData[0].forEach(jam => {\n        if (jam && jam.t !== undefined) {\n            processedData.forecast_24hour.push({\n                time: jam.local_datetime || jam.datetime,\n                temperature: jam.t,\n                humidity: jam.hu || 0,\n                condition: jam.weather_desc || jam.weather_desc_en || 'Unknown',\n                wind_speed: jam.ws || 0,\n                wind_direction: jam.wd || 'N/A',\n                rain_probability: jam.tp || 0,\n                icon_url: jam.image || ''\n            });\n            \n            totalTemperature += jam.t;\n            totalHumidity += jam.hu || 0;\n            count++;\n            \n            const condition = jam.weather_desc || jam.weather_desc_en || 'Unknown';\n            conditionCount[condition] = (conditionCount[condition] || 0) + 1;\n        }\n    });\n}\n\n// Calculate averages and dominant condition\nif (count > 0) {\n    processedData.summary.avg_temperature = Math.round(totalTemperature / count * 10) / 10;\n    processedData.summary.avg_humidity = Math.round(totalHumidity / count);\n}\n\n// Find dominant weather condition\nlet maxCount = 0;\nfor (const [condition, conditionNum] of Object.entries(conditionCount)) {\n    if (conditionNum > maxCount) {\n        maxCount = conditionNum;\n        processedData.summary.dominant_condition = condition;\n    }\n}\n\n// Generate warnings\nconst warnings = [];\nif (processedData.summary.avg_temperature > 35) {\n    warnings.push('⚠️ Very hot temperature, avoid outdoor activities');\n}\nif (processedData.summary.avg_temperature < 20) {\n    warnings.push('🧥 Cold temperature, wear warm clothes');\n}\n\n// Check for rain probability\nconst avgRainProb = processedData.forecast_24hour.reduce((sum, item) => sum + (item.rain_probability || 0), 0) / processedData.forecast_24hour.length;\nif (avgRainProb > 60) {\n    warnings.push('☔ High rain probability, bring umbrella or raincoat');\n}\nif (avgRainProb > 30 && avgRainProb <= 60) {\n    warnings.push('🌦️ Possible rain, prepare rain gear');\n}\n\nprocessedData.summary.warnings = warnings;\n\nreturn [{ json: processedData }];"
      },
      "typeVersion": 2
    },
    {
      "id": "1ef3b9f1-5837-4ca4-90e6-b39bc37b778d",
      "name": "格式化Telegram消息",
      "type": "n8n-nodes-base.code",
      "position": [
        608,
        16
      ],
      "parameters": {
        "jsCode": "// Format weather data for Telegram message\nconst data = $input.all()[0].json;\n\nif (!data.success) {\n    return [{\n        json: {\n            telegram_message: `❌ *BMKG Weather Monitoring Error*\\n\\n${data.error}\\n\\nTime: ${data.timestamp}\\n\\n_Powered by BMKG API & n8n_`,\n            parse_mode: 'Markdown'\n        }\n    }];\n}\n\n// Create beautiful Telegram message\nlet message = `🌤️ *BMKG Weather Report*\\n`;\nmessage += `📍 *${data.location.desa}, ${data.location.kecamatan}*\\n`;\nmessage += `🏙️ ${data.location.kotkab}, ${data.location.provinsi}\\n\\n`;\n\n// Current weather\nmessage += `🌡️ *Current Weather*\\n`;\nmessage += `• Temperature: *${data.current_weather.temperature}°C*\\n`;\nmessage += `• Condition: ${data.current_weather.condition}\\n`;\nmessage += `• Humidity: ${data.current_weather.humidity}%\\n`;\nmessage += `• Wind: ${data.current_weather.wind_speed} km/h from ${data.current_weather.wind_direction}\\n`;\nmessage += `• Visibility: ${data.current_weather.visibility}\\n`;\n\nif (data.current_weather.rain_probability > 0) {\n    message += `• Rain Prob.: ${data.current_weather.rain_probability}%\\n`;\n}\nmessage += `\\n`;\n\n// Summary\nmessage += `📊 *24 Hour Summary*\\n`;\nmessage += `• Average Temperature: *${data.summary.avg_temperature}°C*\\n`;\nmessage += `• Average Humidity: ${data.summary.avg_humidity}%\\n`;\nmessage += `• Dominant Condition: ${data.summary.dominant_condition}\\n\\n`;\n\n// Warnings\nif (data.summary.warnings.length > 0) {\n    message += `⚠️ *Warnings & Suggestions:*\\n`;\n    data.summary.warnings.forEach(warning => {\n        message += `• ${warning}\\n`;\n    });\n    message += `\\n`;\n}\n\n// Next few hours forecast (first 6 hours)\nmessage += `⏰ *6 Hour Forecast:*\\n`;\nconst nextHours = data.forecast_24hour.slice(0, 6);\nnextHours.forEach((forecast, index) => {\n    const time = new Date(forecast.time).toLocaleTimeString('en-US', { \n        hour: '2-digit', \n        minute: '2-digit',\n        timeZone: data.location.timezone \n    });\n    message += `• ${time}: ${forecast.temperature}°C, ${forecast.condition}`;\n    if (forecast.rain_probability > 30) {\n        message += ` (☔${forecast.rain_probability}%)`;\n    }\n    message += `\\n`;\n});\n\nmessage += `\\n📅 Updated: ${new Date(data.timestamp).toLocaleString('en-US', {\n    timeZone: data.location.timezone,\n    year: 'numeric',\n    month: 'long',\n    day: 'numeric',\n    hour: '2-digit',\n    minute: '2-digit'\n})} ${data.location.timezone}`;\n\nmessage += `\\n\\n_🤖 Automated by n8n | 📡 Data: BMKG_`;\n\nreturn [{\n    json: {\n        telegram_message: message,\n        parse_mode: 'Markdown',\n        weather_data: data\n    }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "ddc33a20-96a8-40bc-9788-6e12f40f88ef",
      "name": "发送天气报告",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1264,
        400
      ],
      "webhookId": "594b5594-af4a-4dfd-8a93-15a5683919cd",
      "parameters": {
        "text": "={{ $json.telegram_message }}",
        "chatId": "{{TELEGRAM_CHAT_ID}}",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "credentials": {
        "telegramApi": {
          "id": "5UNbimarOaH1QxRo",
          "name": "Telegram account 2"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "fdd12bf7-a818-41ef-9c94-65638fd9dac4",
      "name": "手动测试",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -480,
        240
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "3d011775-063e-4a17-ae84-c6c45bc5f3f1",
      "name": "检查成功",
      "type": "n8n-nodes-base.if",
      "position": [
        368,
        224
      ],
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{ $json.success }}",
              "value2": true
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "bfd54738-c07c-4f0e-9acf-e96971e21210",
      "name": "错误处理器",
      "type": "n8n-nodes-base.code",
      "position": [
        624,
        224
      ],
      "parameters": {
        "jsCode": "// Log error details\nconst inputData = $input.all()[0].json;\n\nconsole.error('Weather monitoring error:', inputData);\n\nlet errorMessage = `❌ *Weather Monitoring System Error*\\n\\n`;\nerrorMessage += `🕐 Time: ${new Date().toLocaleString('en-US')}\\n`;\nerrorMessage += `❗ Details: ${inputData.error || 'Unknown error'}\\n\\n`;\nerrorMessage += `_System will try again on next schedule_`;\n\nreturn [{\n    json: {\n        telegram_message: errorMessage,\n        parse_mode: 'Markdown',\n        error_logged: true\n    }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "c80c80f8-6f09-4112-8928-9552b6a6ee04",
      "name": "发送错误警报",
      "type": "n8n-nodes-base.telegram",
      "position": [
        864,
        400
      ],
      "webhookId": "ed4ebdc5-39cf-4d7c-9c52-1a3b9008b28c",
      "parameters": {
        "text": "={{ $json.telegram_message }}",
        "chatId": "{{TELEGRAM_CHAT_ID}}",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "credentials": {
        "telegramApi": {
          "id": "5UNbimarOaH1QxRo",
          "name": "Telegram account 2"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "c84af71c-e6b8-465e-b968-9f7eda7f4eaf",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1312,
        -64
      ],
      "parameters": {
        "width": 432,
        "height": 416,
        "content": "## 🎓 **学习资源**"
      },
      "typeVersion": 1
    },
    {
      "id": "2581be27-b445-43ba-bc5d-534febc19d38",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        48,
        -160
      ],
      "parameters": {
        "width": 784,
        "height": 80,
        "content": "## 🌤️ **BMKG天气监控和Telegram警报系统**"
      },
      "typeVersion": 1
    },
    {
      "id": "889ea56c-10e2-4901-9889-868ed741bf48",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        848,
        -64
      ],
      "parameters": {
        "width": 512,
        "height": 560,
        "content": "### **创建您的机器人**"
      },
      "typeVersion": 1
    },
    {
      "id": "f496550d-b5ea-4d73-bf9b-a38ea9ec3027",
      "name": "便签3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -864,
        -64
      ],
      "parameters": {
        "width": 528,
        "height": 288,
        "content": "### **启用自动模式:**"
      },
      "typeVersion": 1
    },
    {
      "id": "13d5c622-9b20-46b6-861a-36cb9babcb1c",
      "name": "便签4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -304,
        -64
      ],
      "parameters": {
        "width": 528,
        "height": 368,
        "content": "### **更新聊天ID**"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "c83de10d-8b0b-48ed-bb16-f095f85580fe",
  "connections": {
    "Manual Test": {
      "main": [
        [
          {
            "node": "Get BMKG Weather Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Success": {
      "main": [
        [
          {
            "node": "Format Telegram Message",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Error Handler",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Error Handler": {
      "main": [
        [
          {
            "node": "Send Error Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get BMKG Weather Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Weather Data": {
      "main": [
        [
          {
            "node": "Check Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get BMKG Weather Data": {
      "main": [
        [
          {
            "node": "Process Weather Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Telegram Message": {
      "main": [
        [
          {
            "node": "Send Weather Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

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

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

中级

需要付费吗?

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

工作流信息
难度等级
中级
节点数量14
分类-
节点类型7
难度说明

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

作者
Tegar karunia ilham

Tegar karunia ilham

@tegarkaruniailham

Developer | Flowgrammer | Promt Engineering | Helping business owners & marketers automate their processes with n8n. Specialist in custom workflows, API integrations, and template development.

外部链接
在 n8n.io 查看

分享此工作流