Système de surveillance météo BMKG et alertes Telegram

Intermédiaire

Ceci est uncontenant 14 nœuds.Utilise principalement des nœuds comme If, Code, Telegram, HttpRequest, ManualTrigger. Alertes météo indonésiennes envoyées automatiquement via les données BMKG et les notifications Telegram

Prérequis
  • Token Bot Telegram
  • Peut nécessiter les informations d'identification d'authentification de l'API cible

Catégorie

-
Aperçu du workflow
Visualisation des connexions entre les nœuds, avec support du zoom et du déplacement
Exporter le workflow
Copiez la configuration JSON suivante dans n8n pour importer et utiliser ce workflow
{
  "id": "oezF9oCv3tPecrSv",
  "meta": {
    "instanceId": "b14f5dd921befc4584084cc386aea593f73c7c2b00b50933075d7967a4d1c502",
    "templateCredsSetupCompleted": true
  },
  "name": "BMKG Weather Monitoring & Telegram Alert System",
  "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": "Déclencheur programmé",
      "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": "Obtenir les données météo 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": "Traiter les données météo",
      "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": "Formater le message 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": "Envoyer le rapport météo",
      "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": "Test manuel",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -480,
        240
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "3d011775-063e-4a17-ae84-c6c45bc5f3f1",
      "name": "Vérifier la réussite",
      "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": "Gestionnaire d'erreurs",
      "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": "Envoyer une alerte d'erreur",
      "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": "Note adhésive",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1312,
        -64
      ],
      "parameters": {
        "width": 432,
        "height": 416,
        "content": "## 🎓 **LEARNING RESOURCES**\n\n### **n8n Documentation:**\n- **Official Docs**: https://docs.n8n.io\n- **Node Reference**: https://docs.n8n.io/integrations/\n- **Workflow Examples**: https://n8n.io/workflows/\n\n### **BMKG API Information:**\n- **API Documentation**: https://api.bmkg.go.id\n- **Region Codes**: Available in API response\n- **Data Format**: JSON structure documentation\n\n### **Telegram Bot API:**\n- **Bot Creation**: https://core.telegram.org/bots\n- **API Reference**: https://core.telegram.org/bots/api\n\n***\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "2581be27-b445-43ba-bc5d-534febc19d38",
      "name": "Note adhésive 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        48,
        -160
      ],
      "parameters": {
        "width": 784,
        "height": 80,
        "content": "## 🌤️ **BMKG WEATHER MONITORING & TELEGRAM ALERT SYSTEM**"
      },
      "typeVersion": 1
    },
    {
      "id": "889ea56c-10e2-4901-9889-868ed741bf48",
      "name": "Note adhésive 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        848,
        -64
      ],
      "parameters": {
        "width": 512,
        "height": 560,
        "content": "### **Create Your Bot**\n- Open Telegram and find @BotFather\n\n- Start a chat and send /newbot\n\n- Follow instructions to set bot name and username\n\n- Copy the Bot Token provided (format: 123456789:ABCdef...)\n\n- Save the token securely for configuration\n\n### **Get Your Chat ID**\n- Start a chat with your new bot and send any message\n\n- Visit https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates in a browser (replace <YOUR_BOT_TOKEN> with your bot token)\n\n- Find the Chat ID number in the JSON response under \"chat\": {\"id\": 123456789, ...}\n\n- Copy the Chat ID for use in your workflow or configuration"
      },
      "typeVersion": 1
    },
    {
      "id": "f496550d-b5ea-4d73-bf9b-a38ea9ec3027",
      "name": "Note adhésive 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -864,
        -64
      ],
      "parameters": {
        "width": 528,
        "height": 288,
        "content": "\n### **Enable Automatic Mode:**\n1. **Click workflow name** at top of canvas\n2. **Toggle \"Active\" switch** to ON position\n3. **Workflow status** should show \"Active\"\n4. **Schedule Trigger** will run every 6 hours automatically\n\n### **Schedule Settings:**\n- **Default**: Every 6 hours (4 reports per day)\n- **Modify timing**: Edit \"Schedule Trigger\" node\n- **Options**: 1, 3, 6, 12, or 24 hours\n- **Peak times**: 6AM, 12PM, 6PM, 12AM (with 6-hour interval)"
      },
      "typeVersion": 1
    },
    {
      "id": "13d5c622-9b20-46b6-861a-36cb9babcb1c",
      "name": "Note adhésive 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -304,
        -64
      ],
      "parameters": {
        "width": 528,
        "height": 368,
        "content": "### **Update Chat IDs**\nReplace {{TELEGRAM_CHAT_ID}} with your actual Chat ID in both \"Send Weather Report\" and \"Send Error Alert\" nodes (e.g., 123456789).\n\n### **Link Telegram Credentials**\n**Select your saved Telegram credential in the \"Credential\" dropdown of both \"Send Weather Report\" and \"Send Error Alert\" nodes.**\n\n### **Configure Location (Optional)**\n**In \"Get BMKG Weather Data\" node, add a Query parameter named adm4 with your BMKG region code (e.g., 31.71.03.1001).**"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "c83de10d-8b0b-48ed-bb16-f095f85580fe",
  "connections": {
    "fdd12bf7-a818-41ef-9c94-65638fd9dac4": {
      "main": [
        [
          {
            "node": "bf292408-48a2-4fb8-baf5-38c7b5f36862",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3d011775-063e-4a17-ae84-c6c45bc5f3f1": {
      "main": [
        [
          {
            "node": "1ef3b9f1-5837-4ca4-90e6-b39bc37b778d",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "bfd54738-c07c-4f0e-9acf-e96971e21210",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "bfd54738-c07c-4f0e-9acf-e96971e21210": {
      "main": [
        [
          {
            "node": "c80c80f8-6f09-4112-8928-9552b6a6ee04",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "a7760673-0f36-4693-b0e2-b12ec5319247": {
      "main": [
        [
          {
            "node": "bf292408-48a2-4fb8-baf5-38c7b5f36862",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "af473f94-7a67-4023-94b5-3bdf8015280a": {
      "main": [
        [
          {
            "node": "3d011775-063e-4a17-ae84-c6c45bc5f3f1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "bf292408-48a2-4fb8-baf5-38c7b5f36862": {
      "main": [
        [
          {
            "node": "af473f94-7a67-4023-94b5-3bdf8015280a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1ef3b9f1-5837-4ca4-90e6-b39bc37b778d": {
      "main": [
        [
          {
            "node": "ddc33a20-96a8-40bc-9788-6e12f40f88ef",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Foire aux questions

Comment utiliser ce workflow ?

Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.

Dans quelles scénarios ce workflow est-il adapté ?

Intermédiaire

Est-ce payant ?

Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.

Informations sur le workflow
Niveau de difficulté
Intermédiaire
Nombre de nœuds14
Catégorie-
Types de nœuds7
Description de la difficulté

Adapté aux utilisateurs expérimentés, avec des workflows de complexité moyenne contenant 6-15 nœuds

Auteur
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.

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34