n8n Workflow
Expert

Telegram Weather Bot with R-based Image Generation

Create a Telegram bot that fetches weather data from an API, processes it with a custom R script to generate a data visualization, and sends the image back to the user.

Overview

Automates fetching live weather data, generating a custom data visualization using an R script, and delivering it as an image via a Telegram bot.

🤖 Description & Use Case

This workflow creates an interactive Telegram bot that delivers weather data for major European capitals as a custom-generated image. When a user sends the /getweather command, the bot fetches live weather data, uses an R script to create a data visualization (a dumbbell plot), and sends the resulting image back to the user.

⚙️ How It Works:

  1. Telegram Trigger: The workflow starts when a user sends a message to the Telegram bot.
  2. Command Routing: A Switch node checks the user's message for specific commands:
    • /start: Responds with a friendly greeting and instructions.
    • /getweather: Initiates the core weather-fetching logic.
    • Any other text: Returns an error message indicating an unrecognized command.
  3. Data Fetching (/getweather flow):
    • A Telegram node sends a "Please wait" message to the user.
    • A static City List node provides a predefined list of European capitals.
    • The HTTP Request node iterates through the city list, calling the OpenWeatherMap API to get the current weather for each city.
  4. Data Processing & Image Generation:
    • After checking for API errors, a Function node formats the API responses into a clean structure.
    • The structured data is converted into a CSV file and saved locally using the Spreadsheet File and Write Binary File nodes.
    • The Execute Command node runs an external R script. This script reads the CSV file, generates a ggplot2 dumbbell plot visualizing the temperature ranges, and saves it as a PNG image.
  5. Delivery & Error Handling:
    • An If node checks if the R script executed successfully. If not, an error message is sent to the user.
    • If successful, the Read Binary File node reads the generated PNG image.
    • Finally, the Telegram node sends the image back to the user with a caption.

✅ Real-World Use Cases:

  • Interactive Chatbots: Build bots that provide dynamic, custom-generated content like charts, reports, or images.
  • Data Visualization on Demand: Allow users to request and receive up-to-date visualizations without needing access to complex tools.
  • Integrating External Scripts (R, Python): Demonstrates how to leverage powerful external scripts for complex data processing, statistical analysis, or visualization tasks that are not native to n8n.
  • Automated Reporting: This can be adapted to generate and distribute daily or weekly report images to a team channel in Telegram or Slack.

Instructions

Basic steps

  1. Download workflow JSON
  2. Import into n8n
  3. Configure node parameters as needed
  4. Test and enable the workflow

💡 Tips

After importing, verify all connectors and credentials match your environment.

Preview

Workflow Visualization

21 nodes
100%
Switchswitchmsg_greettelegrammsg_wrongcommandtelegramTelegram TriggertelegramTriggermsg_getweathertelegramCity ListfunctionConvert API responsefunctionGet weather datahttpRequestSpreadsheet FilespreadsheetFileWrite csvwriteBinaryFileFilenamesetmsg_errorAPItelegramAny errors API?ifmsg_errorRtelegramRead Binary FilereadBinaryFileR successful?ifMergemergeMerge1mergemsg_pleasewaittelegramMerge2mergeRun R scriptexecuteCommand

Nodes

1

Switch

switch

v1
2

msg_greet

telegram

v1
3

msg_wrongcommand

telegram

v1
4

Telegram Trigger

telegramTrigger

v1
5

msg_getweather

telegram

v1
6

City List

function

v1
7

Convert API response

function

v1
8

Get weather data

httpRequest

v1
9

Spreadsheet File

spreadsheetFile

v1
10

Write csv

writeBinaryFile

v1
11

Filename

set

v1
12

msg_errorAPI

telegram

v1
13

Any errors API?

if

v1
14

msg_errorR

telegram

v1
15

Read Binary File

readBinaryFile

v1
16

R successful?

if

v1
17

Merge

merge

v1
18

Merge1

merge

v1
19

msg_pleasewait

telegram

v1
20

Merge2

merge

v1
21

Run R script

executeCommand

v1

Statistics

Total nodes:21
Disabled nodes:0
Node types:12
Connections:16
View full JSON structure
{
  "nodes": [
    {
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "notes": "check bot commands",
      "position": [
        460,
        480
      ],
      "parameters": {
        "rules": {
          "rules": [
            {
              "value2": "/start"
            },
            {
              "output": 1,
              "value2": "/getweather"
            }
          ]
        },
        "value1": "={{$json[\"message\"][\"text\"]}}",
        "dataType": "string",
        "fallbackOutput": 3
      },
      "notesInFlow": true,
      "typeVersion": 1
    },
    {
      "name": "msg_greet",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1820,
        300
      ],
      "parameters": {
        "text": "=Nice to meet you, {{$node[\"Telegram Trigger\"].json[\"message\"][\"from\"][\"first_name\"]}}.\nI am n8n-powered bot, I can send you a weather data for several European capitals. The data is an image generated in ggplot2 package of R programming language.\nType /getweather to begin.",
        "chatId": "={{$node[\"Telegram Trigger\"].json[\"message\"][\"chat\"][\"id\"]}}",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "id": "17",
          "name": "n8n R test bot"
        }
      },
      "notesInFlow": true,
      "typeVersion": 1
    },
    {
      "name": "msg_wrongcommand",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1820,
        1160
      ],
      "parameters": {
        "text": "=Sorry, {{$node[\"Telegram Trigger\"].json[\"message\"][\"from\"][\"first_name\"]}}, your command was not recognized.\n/getweather - show image with the weather info.",
        "chatId": "={{$node[\"Telegram Trigger\"].json[\"message\"][\"chat\"][\"id\"]}}",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "id": "17",
          "name": "n8n R test bot"
        }
      },
      "notesInFlow": true,
      "typeVersion": 1
    },
    {
      "name": "Telegram Trigger",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        300,
        480
      ],
      "webhookId": "2512ec1e-bcff-4dfb-9ef3-208aaecc5634",
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "id": "17",
          "name": "n8n R test bot"
        }
      },
      "typeVersion": 1
    },
    {
      "name": "msg_getweather",
      "type": "n8n-nodes-base.telegram",
      "position": [
        2020,
        820
      ],
      "parameters": {
        "chatId": "={{$node[\"Telegram Trigger\"].json[\"message\"][\"chat\"][\"id\"]}}",
        "operation": "sendPhoto",
        "binaryData": true,
        "additionalFields": {
          "caption": "=Here's your image, {{$node[\"Telegram Trigger\"].json[\"message\"][\"from\"][\"first_name\"]}}."
        }
      },
      "credentials": {
        "telegramApi": {
          "id": "17",
          "name": "n8n R test bot"
        }
      },
      "notesInFlow": true,
      "typeVersion": 1
    },
    {
      "name": "City List",
      "type": "n8n-nodes-base.function",
      "position": [
        1040,
        640
      ],
      "parameters": {
        "functionCode": "return [{Cityid: 2643743, Cityname:\"London\",    Country: \"GB\"},\r\n        {Cityid: 2950159, Cityname:\"Berlin\",    Country: \"DE\"},\r\n        {Cityid: 3117735, Cityname:\"Madrid\",    Country: \"ES\"},\r\n        {Cityid: 3169070, Cityname:\"Rome\",      Country: \"IT\"},\r\n        {Cityid: 683506,  Cityname:\"Bucharest\", Country: \"RO\"},\r\n        {Cityid: 2968815, Cityname:\"Paris\",     Country: \"FR\"},\r\n        {Cityid: 2761369, Cityname:\"Vienna\",    Country: \"AT\"},\r\n        {Cityid: 756135,  Cityname:\"Warsaw\",    Country: \"PL\"},\r\n        {Cityid: 3054638, Cityname:\"Budapest\",  Country: \"HU\"},\r\n        {Cityid: 792680,  Cityname:\"Belgrade\",  Country: \"RS\"}];"
      },
      "typeVersion": 1
    },
    {
      "name": "Convert API response",
      "type": "n8n-nodes-base.function",
      "position": [
        860,
        840
      ],
      "parameters": {
        "functionCode": "// this data is stored as a CSV file and then processed in the R script. Please check the R code here:\n// https://gist.github.com/ed-parsadanyan/0561cd12d545e642fcef17dcb0872b00\nvar data = [];\n\nfor (item of items) {\n  data.push({CityName: item.json.name+', '+item.json.sys.country,\n             TempCur : item.json.main.temp,\n             TempMin : item.json.main.temp_min,\n             TempMax : item.json.main.temp_max\n  });\n}\n\nreturn data;"
      },
      "typeVersion": 1
    },
    {
      "name": "Get weather data",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1220,
        640
      ],
      "parameters": {
        "url": "=https://api.openweathermap.org/data/2.5/weather?id={{$json[\"Cityid\"]}}&units=metric&appid=6d3fff582a101700576faf74734f9535",
        "options": {}
      },
      "typeVersion": 1,
      "continueOnFail": true
    },
    {
      "name": "Spreadsheet File",
      "type": "n8n-nodes-base.spreadsheetFile",
      "position": [
        1040,
        840
      ],
      "parameters": {
        "options": {
          "fileName": "={{$node[\"Filename\"].json[\"filename\"]}}.{{$parameter[\"fileFormat\"]}}"
        },
        "operation": "toFile",
        "fileFormat": "csv"
      },
      "typeVersion": 1
    },
    {
      "name": "Write csv",
      "type": "n8n-nodes-base.writeBinaryFile",
      "position": [
        1220,
        840
      ],
      "parameters": {
        "fileName": "={{$node[\"Filename\"].json[\"foldername\"]}}{{$binary.data.fileName}}"
      },
      "typeVersion": 1
    },
    {
      "name": "Filename",
      "type": "n8n-nodes-base.set",
      "position": [
        860,
        640
      ],
      "parameters": {
        "values": {
          "string": [
            {
              "name": "filename",
              "value": "=request_from{{$node[\"Telegram Trigger\"].json[\"message\"][\"from\"][\"id\"]}}_{{DateTime.now().toISO({ format: 'basic' }).split('.')[0]}}"
            },
            {
              "name": "foldername",
              "value": "/home/node/.n8n/weather-bot/"
            },
            {
              "name": "imgname",
              "value": "=request_from{{$node[\"Telegram Trigger\"].json[\"message\"][\"from\"][\"id\"]}}"
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "name": "msg_errorAPI",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1820,
        640
      ],
      "parameters": {
        "text": "=Sorry, {{$node[\"Telegram Trigger\"].json[\"message\"][\"from\"][\"first_name\"]}}, an error occurred while fetching weather data. Please try again later.",
        "chatId": "={{$node[\"Telegram Trigger\"].json[\"message\"][\"chat\"][\"id\"]}}",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "credentials": {
        "telegramApi": {
          "id": "17",
          "name": "n8n R test bot"
        }
      },
      "notesInFlow": true,
      "typeVersion": 1
    },
    {
      "name": "Any errors API?",
      "type": "n8n-nodes-base.if",
      "position": [
        1580,
        640
      ],
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{$json[\"error\"][\"name\"]}}",
              "value2": "Error"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "name": "msg_errorR",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1820,
        1000
      ],
      "parameters": {
        "text": "=Sorry, {{$node[\"Telegram Trigger\"].json[\"message\"][\"from\"][\"first_name\"]}}, an error occurred while creating an image. Please try again later.",
        "chatId": "={{$node[\"Telegram Trigger\"].json[\"message\"][\"chat\"][\"id\"]}}",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "credentials": {
        "telegramApi": {
          "id": "17",
          "name": "n8n R test bot"
        }
      },
      "notesInFlow": true,
      "typeVersion": 1
    },
    {
      "name": "Read Binary File",
      "type": "n8n-nodes-base.readBinaryFile",
      "position": [
        1820,
        820
      ],
      "parameters": {
        "filePath": "={{$node[\"Filename\"].json[\"foldername\"]}}{{$node[\"Filename\"].json[\"imgname\"]}}.png"
      },
      "typeVersion": 1
    },
    {
      "name": "R successful?",
      "type": "n8n-nodes-base.if",
      "position": [
        1580,
        840
      ],
      "parameters": {
        "conditions": {
          "number": [
            {
              "value1": "={{$json[\"exitCode\"]}}",
              "operation": "equal"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        680,
        1160
      ],
      "parameters": {
        "mode": "passThrough"
      },
      "typeVersion": 1
    },
    {
      "name": "Merge1",
      "type": "n8n-nodes-base.merge",
      "position": [
        680,
        300
      ],
      "parameters": {
        "mode": "passThrough"
      },
      "typeVersion": 1
    },
    {
      "name": "msg_pleasewait",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1820,
        460
      ],
      "parameters": {
        "text": "=Please wait while your request is being processed...",
        "chatId": "={{$node[\"Telegram Trigger\"].json[\"message\"][\"chat\"][\"id\"]}}",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "credentials": {
        "telegramApi": {
          "id": "17",
          "name": "n8n R test bot"
        }
      },
      "notesInFlow": true,
      "typeVersion": 1
    },
    {
      "name": "Merge2",
      "type": "n8n-nodes-base.merge",
      "position": [
        680,
        640
      ],
      "parameters": {
        "mode": "wait"
      },
      "typeVersion": 1
    },
    {
      "name": "Run R script",
      "type": "n8n-nodes-base.executeCommand",
      "position": [
        1400,
        840
      ],
      "parameters": {
        "command": "=Rscript --vanilla '{{$node[\"Filename\"].json[\"foldername\"]}}dumbbell_plot.R' '{{$node[\"Filename\"].json[\"foldername\"]}}{{$node[\"Filename\"].json[\"filename\"]}}.csv' '{{$node[\"Filename\"].json[\"foldername\"]}}{{$node[\"Filename\"].json[\"imgname\"]}}.png' >& {{$node[\"Filename\"].json[\"foldername\"]}}{{$node[\"Filename\"].json[\"filename\"]}}.log"
      },
      "typeVersion": 1,
      "continueOnFail": true
    }
  ],
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "msg_wrongcommand",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge1": {
      "main": [
        [
          {
            "node": "msg_greet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge2": {
      "main": [
        [
          {
            "node": "Filename",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Merge1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "msg_pleasewait",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge2",
            "type": "main",
            "index": 0
          }
        ],
        null,
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filename": {
      "main": [
        [
          {
            "node": "City List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "City List": {
      "main": [
        [
          {
            "node": "Get weather data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Write csv": {
      "main": [
        [
          {
            "node": "Run R script",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run R script": {
      "main": [
        [
          {
            "node": "R successful?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "R successful?": {
      "main": [
        [
          {
            "node": "Read Binary File",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "msg_errorR",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "msg_pleasewait": {
      "main": [
        [
          {
            "node": "Merge2",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Any errors API?": {
      "main": [
        [
          {
            "node": "msg_errorAPI",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Convert API response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get weather data": {
      "main": [
        [
          {
            "node": "Any errors API?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Binary File": {
      "main": [
        [
          {
            "node": "msg_getweather",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Spreadsheet File": {
      "main": [
        [
          {
            "node": "Write csv",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram Trigger": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert API response": {
      "main": [
        [
          {
            "node": "Spreadsheet File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Actions

Share
Categories:
Tags:
functionifsetmergehttprequesttelegramswitchtelegramtriggerspreadsheetfilewritebinaryfilereadbinaryfile

Technical Specs

Complexity:
Expert
Node Count:
21 nodes
Published:11 months ago
Updated:about 20 hours ago

Compatibility

Platform:
N8N Cloud & Self-hosted
Min Version:
N8N v1.0.0+
Supports cloud and self-hosted deployment

License

This workflow template follows MIT license, you can freely use, modify and distribute.

Please comply with relevant third-party service terms when using.

Related Workflows