AutomationFlowsSlack & Telegram › Automated Weather Reports with Openweathermap and Telegram

Automated Weather Reports with Openweathermap and Telegram

Original n8n title: Automated Weather Reports with Openweathermap and Telegram ☀️

ByM Sayed @msayed-cs on n8n.io

This little bot wakes up, checks the weather for you, and builds a super simple summary of your day.

Cron / scheduled trigger★★★★☆ complexity12 nodesOpenWeatherMapTelegram
Slack & Telegram Trigger: Cron / scheduled Nodes: 12 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #6176 — we link there as the canonical source.

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
{
  "id": "BiCF5Nmdl7SK4qjp",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "MS_WEATHER",
  "tags": [],
  "nodes": [
    {
      "id": "4a9e2697-2172-4e55-bd17-96170d5640a8",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -360,
        0
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 12
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "8474a7c2-523f-4da8-a9e5-bfdfa6b432df",
      "name": "Set Location",
      "type": "n8n-nodes-base.set",
      "position": [
        -80,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "b9f4869a-2059-4b09-84e3-26c7d1e95d30",
              "name": "lat",
              "type": "string",
              "value": "={{ $env.lat }}"
            },
            {
              "id": "cc1b0b3a-4c99-4220-bfcb-439f817980a8",
              "name": "long",
              "type": "string",
              "value": "={{ $env.long }}"
            },
            {
              "id": "7d1ace36-bd24-43b1-928c-3e3b9c2dc655",
              "name": "telegram_chat_id",
              "type": "string",
              "value": "={{ $env.telegram_chat_id }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "6c789184-4971-4407-8401-334b47165daf",
      "name": "Weather: Current",
      "type": "n8n-nodes-base.openWeatherMap",
      "position": [
        320,
        -180
      ],
      "parameters": {
        "language": "en",
        "latitude": "={{ $json.lat }}",
        "longitude": "={{ $json.long }}",
        "locationSelection": "coordinates"
      },
      "credentials": {
        "openWeatherMapApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "1bab62d5-d884-46e8-94af-9484a5ba2fbf",
      "name": "Weather: 5Days",
      "type": "n8n-nodes-base.openWeatherMap",
      "position": [
        320,
        180
      ],
      "parameters": {
        "language": "en",
        "latitude": "={{ $json.lat }}",
        "longitude": "={{ $json.long }}",
        "operation": "5DayForecast",
        "locationSelection": "coordinates"
      },
      "credentials": {
        "openWeatherMapApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "cb860b7f-2dc6-4aaf-8d7b-01d391437342",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        660,
        0
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "43d58689-f6fa-4a88-8a3c-04cfc212b498",
      "name": "Report: Prepare",
      "type": "n8n-nodes-base.code",
      "position": [
        920,
        0
      ],
      "parameters": {
        "jsCode": "/* \u2500\u2500 Weather-to-Telegram Markdown  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n   Input:  $json  \u2190 OpenWeatherMap /forecast (5-day / 3-hour) single object\n   Output: telegram-ready markdown string in  msg.markdown_report\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\nconst data = $json;                // full API response\nconst city = data.city;            // city block\nconst blocks = data.list ?? [];    // 3-hour forecasts\n\n/* \u2500\u2500 helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nconst esc = t => t.toString().replace(/[_*[\\]()~`>#+\\-=|{}.!]/g, '\\\\$&');\nconst fmtT = t => `${Math.round(t)}\u00b0C`;\nconst fmtDay = ts => new Date(ts * 1000)\n\t.toLocaleDateString('en-US', { weekday:'short', month:'short', day:'numeric' });\nconst emoji = id => (\n\tid === 800 ? '\u2600\ufe0f' :\n\tid >= 801 && id <= 804 ? '\u2601\ufe0f' :\n\tid >= 200 && id <= 232 ? '\u26c8\ufe0f' :\n\tid >= 300 && id <= 321 ? '\ud83c\udf26\ufe0f' :\n\tid >= 500 && id <= 531 ? '\ud83c\udf27\ufe0f' :\n\tid >= 600 && id <= 622 ? '\u2744\ufe0f'  :\n\tid >= 700 && id <= 781 ? '\ud83c\udf2b\ufe0f'  : '\ud83c\udf24\ufe0f'\n);\n\n/* \u2500\u2500 aggregate daily lows / highs (and grab a noon sample for the icon) \u2500\u2500\u2500\u2500 */\nconst days = {};   // key = yyyy-mm-dd\n\nfor (const b of blocks) {\n\tconst d = new Date(b.dt * 1000);\n\tconst key = d.toISOString().slice(0,10);           // YYYY-MM-DD\n\tconst bucket = days[key] ?? (days[key] = {\n\t\ttsNoon : b.dt,          // will be overwritten until closest to 12:00\n\t\ticonId : b.weather[0].id,\n\t\tdesc   : b.weather[0].main,\n\t\tlo     : b.main.temp_min,\n\t\thi     : b.main.temp_max\n\t});\n\n\tbucket.lo = Math.min(bucket.lo, b.main.temp_min);\n\tbucket.hi = Math.max(bucket.hi, b.main.temp_max);\n\n\t// keep icon sample closest to noon (12:00 \u00b11h)\n\tconst hr = d.getHours();\n\tif (Math.abs(hr - 12) < Math.abs(new Date(bucket.tsNoon*1000).getHours() - 12)) {\n\t\tbucket.tsNoon = b.dt;\n\t\tbucket.iconId = b.weather[0].id;\n\t\tbucket.desc   = b.weather[0].main;\n\t}\n}\n\n/* sort days & take first 5 */\nconst dayKeys = Object.keys(days).sort().slice(0,5);\n\n/* today\u2019s range (index 0) */\nconst today = days[dayKeys[0]];\n\n/* \u2500\u2500 build markdown \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nconst ln = '\\n';\nconst hr = '\\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\\n';\n\nlet md  = `*${esc(city.name)}, ${esc(city.country)} \u2013 Weather*${hr}`;\n\nmd += '*Now*\\n';\nmd += `\ud83c\udf21\ufe0f Temp: \\`${fmtT(data.list[0].main.temp)}\\`  (feels like \\`${fmtT(data.list[0].main.feels_like)}\\`)${ln}`;\nmd += `\ud83d\udcc9 Low / High today: \\`${fmtT(today.lo)} \u2013 ${fmtT(today.hi)}\\`${ln}`;\nmd += `\ud83d\udef0\ufe0f Condition: \\`${esc(data.list[0].weather[0].description)}\\`${ln}`;\nmd += `\ud83d\udca7 Humidity: \\`${data.list[0].main.humidity}%\\`    `;\nmd += `\ud83d\udca8 Wind: \\`${Math.round(data.list[0].wind.speed*3.6)} km/h\\`${hr}`;\n\nmd += '*5-Day Forecast*' + ln;\nfor (const k of dayKeys) {\n\tconst d = days[k];\n\tmd += `\u27a1\ufe0f *${esc(fmtDay(d.tsNoon))}* `;\n\tmd += `\\`${fmtT(d.lo)} \u2013 ${fmtT(d.hi)}\\` `;\n\tmd += `${emoji(d.iconId)} _${esc(d.desc)}_\\n`;\n}\n\n/* \u2500\u2500 return for Telegram node \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nreturn { json: { markdown_report: md }};"
      },
      "typeVersion": 2
    },
    {
      "id": "7cab6251-db7f-4fb0-ad08-bf0e060cfc64",
      "name": "Send a text message",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1240,
        0
      ],
      "parameters": {
        "text": "={{ $json.markdown_report }}",
        "chatId": "={{ $('Set Location').item.json.telegram_chat_id }}",
        "additionalFields": {
          "parse_mode": "Markdown",
          "appendAttribution": false
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "c4f57a04-c22d-4f7b-a0aa-dd08c384d4bd",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -140,
        -140
      ],
      "parameters": {
        "color": 5,
        "width": 220,
        "height": 340,
        "content": "## Set inputs \n- lat\n- long\n- telegram_chat_id"
      },
      "typeVersion": 1
    },
    {
      "id": "8b144fce-d64a-42ec-b381-c49ff7f5fc89",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        260,
        -240
      ],
      "parameters": {
        "color": 4,
        "width": 220,
        "height": 220,
        "content": "## Current Weather"
      },
      "typeVersion": 1
    },
    {
      "id": "440fb2e0-148a-4d4c-85f3-1031f13e0554",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        260,
        120
      ],
      "parameters": {
        "color": 4,
        "width": 220,
        "height": 220,
        "content": "## 5-Day Weather"
      },
      "typeVersion": 1
    },
    {
      "id": "a537e327-dfcc-455c-a821-1d5d2f4cae21",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        860,
        -60
      ],
      "parameters": {
        "color": 3,
        "width": 220,
        "height": 220,
        "content": "## Report"
      },
      "typeVersion": 1
    },
    {
      "id": "493b915f-b04b-445f-b603-6378463b6e91",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1180,
        -60
      ],
      "parameters": {
        "color": 6,
        "width": 220,
        "height": 220,
        "content": "## Send"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "a7059c98-a414-42fb-a0b5-5991d90e4dcf",
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "Report: Prepare",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Location": {
      "main": [
        [
          {
            "node": "Weather: Current",
            "type": "main",
            "index": 0
          },
          {
            "node": "Weather: 5Days",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Weather: 5Days": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Report: Prepare": {
      "main": [
        [
          {
            "node": "Send a text message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Set Location",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Weather: Current": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

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

This little bot wakes up, checks the weather for you, and builds a super simple summary of your day.

Source: https://n8n.io/workflows/6176/ — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

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

Slack & Telegram

Get automated weather updates delivered directly to your Telegram chat at scheduled intervals. This workflow fetches current weather data from OpenWeatherMap and sends formatted weather reports via a

OpenWeatherMap, Telegram
Slack & Telegram

Auto Hunt. Uses httpRequest, googleSheets, rssFeedRead, telegram. Scheduled trigger; 78 nodes.

HTTP Request, Google Sheets, RSS Feed Read +1
Slack & Telegram

Auto-Hunt. Uses httpRequest, googleSheets, rssFeedRead, telegram. Scheduled trigger; 78 nodes.

HTTP Request, Google Sheets, RSS Feed Read +1
Slack & Telegram

Solo founders and spreadsheet gremlins who track everything in Notion and want crisp Telegram pings without opening a single page.

Telegram, Notion
Slack & Telegram

This workflow runs daily at 9 AM, uses Perplexity to compile vaping industry news, optionally captures article screenshots via Browserless, and generates a HeyGen avatar video from a template. It then

Telegram, Google Drive, HTTP Request