AutomationFlowsSlack & Telegram › Convert LLM Output Into Rich Telegram Messages — Auto-media & Smart Chunking

Convert LLM Output Into Rich Telegram Messages — Auto-media & Smart Chunking

ByDmitry Mikheev @dmitry-expert on n8n.io

Who is this for? Builders of Telegram chat‑bots, AI assistants, or notification services who already run n8n and need to convert long, mixed‑media answers from an LLM (or any upstream source) into Telegram‑friendly messages.

Event trigger★★★★☆ complexity19 nodesTelegramExecute Workflow Trigger
Slack & Telegram Trigger: Event Nodes: 19 Complexity: ★★★★☆ Added:

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

This workflow follows the Execute Workflow Trigger → Telegram recipe pattern — see all workflows that pair these two integrations.

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": "6bKCRgltEQMKck0S",
  "name": "TelegramRichOutput",
  "tags": [],
  "nodes": [
    {
      "id": "a25428d1-d34c-42f4-9a1a-713bef6dc1e9",
      "name": "Send back an image",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -480,
        720
      ],
      "parameters": {
        "file": "={{ $json.url }}",
        "chatId": "={{ $('When Executed by Another Workflow').item.json.chatId }}",
        "operation": "sendPhoto",
        "additionalFields": {
          "parse_mode": "HTML"
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "052643fa-6319-43f3-a052-40ed0e255238",
      "name": "Send back an audio",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -260,
        720
      ],
      "parameters": {
        "file": "={{ $json.url }}",
        "chatId": "={{ $('When Executed by Another Workflow').item.json.chatId }}",
        "operation": "sendAudio",
        "additionalFields": {
          "parse_mode": "HTML"
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "73dfb105-5ffe-4f8a-b96e-b0b556d73956",
      "name": "Send back a video",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -60,
        720
      ],
      "parameters": {
        "file": "={{ $json.url }}",
        "chatId": "={{ $('When Executed by Another Workflow').item.json.chatId }}",
        "operation": "sendVideo",
        "additionalFields": {
          "parse_mode": "HTML"
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "e715f898-1bca-4e4e-a463-f30815664766",
      "name": "Send Text",
      "type": "n8n-nodes-base.telegram",
      "position": [
        140,
        220
      ],
      "parameters": {
        "text": "={{ $('When Executed by Another Workflow').item.json.output }}",
        "chatId": "={{ $('When Executed by Another Workflow').item.json.chatId }}",
        "additionalFields": {
          "parse_mode": "HTML",
          "appendAttribution": false
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "38f15fa8-f9a2-469b-9f30-fed46296bf1f",
      "name": "If text too long",
      "type": "n8n-nodes-base.if",
      "position": [
        -140,
        60
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "a6365c72-9e4c-4b19-b725-9965fdb81e21",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $('When Executed by Another Workflow').item.json.output.length > 1000 }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "286d11cb-f94a-4143-8a27-34b5f4e14192",
      "name": "When Executed by Another Workflow",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        -960,
        -100
      ],
      "parameters": {
        "workflowInputs": {
          "values": [
            {
              "name": "chatId",
              "type": "number"
            },
            {
              "name": "output"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "dab1fb0c-970e-43f7-a335-c48639edaabe",
      "name": "Loop Over Links",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -580,
        220
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "a1f73d92-b61e-41fa-a0c7-50e72078e096",
      "name": "If no links",
      "type": "n8n-nodes-base.if",
      "position": [
        -520,
        -100
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "332d2f85-5f44-4d8b-a5c0-03bda9c3976d",
              "operator": {
                "type": "array",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json.files }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "bd57fe5e-940b-46f9-a76f-ba4d6bae5c7c",
      "name": "Split Out the Links",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -800,
        220
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "files"
      },
      "typeVersion": 1
    },
    {
      "id": "8e14c1e6-ece0-4310-97c2-829a37074706",
      "name": "Split large text by chunks",
      "type": "n8n-nodes-base.code",
      "position": [
        140,
        -120
      ],
      "parameters": {
        "jsCode": "const inputText = $('When Executed by Another Workflow').first().json.output || \"\";\nconst lines = inputText.split(\"\\n\");\n\nlet chunks = [];\nlet currentChunk = \"\";\n\nfor (const line of lines) {\n  // Check if adding the line would exceed the 1000 character limit\n  if ((currentChunk + line + \"\\n\").length > 1000) {\n    // Push current chunk if not empty\n    if (currentChunk) chunks.push(currentChunk.trim());\n    // Start new chunk with current line\n    currentChunk = line + \"\\n\";\n  } else {\n    // Add line to current chunk\n    currentChunk += line + \"\\n\";\n  }\n}\n\n// Push the final chunk if there\u2019s remaining content\nif (currentChunk) chunks.push(currentChunk.trim());\n\n// Return each chunk as a separate item\nreturn { output:chunks.map(chunk => ({ chunk } ))};"
      },
      "typeVersion": 2
    },
    {
      "id": "b08e8087-f155-4747-a5d8-8c9bb5511777",
      "name": "Split Out the Chunks",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        360,
        -120
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "output"
      },
      "typeVersion": 1
    },
    {
      "id": "94b015d0-a1b7-4e13-973a-5a25fe88c209",
      "name": "Loop Over Text Chunks",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        560,
        -120
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "51f2598e-4958-4139-ab00-3836b7a52ed5",
      "name": "Send Text Chunk",
      "type": "n8n-nodes-base.telegram",
      "position": [
        800,
        -120
      ],
      "parameters": {
        "text": "={{ $json.chunk }}",
        "chatId": "={{ $('When Executed by Another Workflow').item.json.chatId }}",
        "additionalFields": {
          "parse_mode": "HTML",
          "appendAttribution": false
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "d7baaaff-a918-487d-970a-d2ef498504b3",
      "name": "Limit",
      "type": "n8n-nodes-base.limit",
      "position": [
        -380,
        220
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "5f724698-027f-4e88-8329-1abd00f8e6c7",
      "name": "Extract Links",
      "type": "n8n-nodes-base.code",
      "position": [
        -740,
        -100
      ],
      "parameters": {
        "jsCode": "// free-text input\nconst text = $input.first().json.output ?? \"\";\n\n/* media extensions grouped by type */\nconst IMG = ['jpg','jpeg','png','gif','bmp','webp','tif','tiff'];\nconst AUD = ['mp3','wav','m4a','flac','ogg','aac','opus'];\nconst VID = ['mp4','mov','mkv','webm','avi','mpeg','mpg'];\n\n/* one regex that grabs any media URL (no lazy quantifier, so the whole link is kept) */\nconst re = /(https?:\\/\\/[^\\s\"'<>]+\\.(?<ext>[A-Za-z0-9]{2,5}))(?:\\?[^\\s\"'<>]*)?/gi;\n\nconst seen  = new Set();\nconst files = [];\n\nfor (const m of text.matchAll(re)) {\n  const url = m[1];\n  if (seen.has(url)) continue;          // de-dupe\n  seen.add(url);\n\n  const ext = (m.groups.ext || '').toLowerCase();\n\n  let type = 'other';\n  if (IMG.includes(ext))  type = 'image';\n  else if (AUD.includes(ext)) type = 'audio';\n  else if (VID.includes(ext)) type = 'video';\n\n  files.push({ url, type });\n}\n\nreturn [{ json: { files } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "45e41a01-68a2-4b64-8830-e05916170a97",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -560,
        420
      ],
      "parameters": {
        "color": 5,
        "width": 660,
        "height": 480,
        "content": "## Send links\nSend links to chat as separate messages \nwith appropriate type (image, audio, video)"
      },
      "typeVersion": 1
    },
    {
      "id": "bbeb6619-4a48-40f5-be75-e99e0c53462e",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        80,
        -220
      ],
      "parameters": {
        "color": 6,
        "width": 900,
        "height": 300,
        "content": "## Send a long message\nSeparate long message by chunks and send them one by one"
      },
      "typeVersion": 1
    },
    {
      "id": "4dbf96c8-fb30-4c22-8fc9-c551cb9893c6",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        80,
        120
      ],
      "parameters": {
        "width": 300,
        "height": 260,
        "content": "## Send a short message\nDeliver a short message (default flow)"
      },
      "typeVersion": 1
    },
    {
      "id": "e13e63e9-331e-458b-8933-4ec608eab00a",
      "name": "Check Link Type",
      "type": "n8n-nodes-base.switch",
      "position": [
        -60,
        480
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "image",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "10ec4538-b5cc-4562-954a-fc4ada846d78",
                    "operator": {
                      "type": "string",
                      "operation": "endsWith"
                    },
                    "leftValue": "={{ $json.type }}",
                    "rightValue": "image"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "audio",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "9e0cee56-b281-4d01-9196-eb6495be9641",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.type }}",
                    "rightValue": "audio"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "video",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "007d1c92-0cd0-4dd6-ab9b-8c869e20797d",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.type }}",
                    "rightValue": "video"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "1901c6ab-e8db-40ee-81a2-6dd7967d2dd8",
  "connections": {
    "Limit": {
      "main": [
        [
          {
            "node": "If text too long",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If no links": {
      "main": [
        [
          {
            "node": "If text too long",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Split Out the Links",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Links": {
      "main": [
        [
          {
            "node": "If no links",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Link Type": {
      "main": [
        [
          {
            "node": "Send back an image",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send back an audio",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send back a video",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Links": {
      "main": [
        [
          {
            "node": "Limit",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Check Link Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Text Chunk": {
      "main": [
        [
          {
            "node": "Loop Over Text Chunks",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If text too long": {
      "main": [
        [
          {
            "node": "Split large text by chunks",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send back a video": {
      "main": [
        [
          {
            "node": "Loop Over Links",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send back an audio": {
      "main": [
        [
          {
            "node": "Loop Over Links",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send back an image": {
      "main": [
        [
          {
            "node": "Loop Over Links",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out the Links": {
      "main": [
        [
          {
            "node": "Loop Over Links",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out the Chunks": {
      "main": [
        [
          {
            "node": "Loop Over Text Chunks",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Text Chunks": {
      "main": [
        [],
        [
          {
            "node": "Send Text Chunk",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split large text by chunks": {
      "main": [
        [
          {
            "node": "Split Out the Chunks",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Executed by Another Workflow": {
      "main": [
        [
          {
            "node": "Extract Links",
            "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

Who is this for? Builders of Telegram chat‑bots, AI assistants, or notification services who already run n8n and need to convert long, mixed‑media answers from an LLM (or any upstream source) into Telegram‑friendly messages.

Source: https://n8n.io/workflows/3961/ — 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

This workflow provides a complete solution for handling Telegram Stars payments, invoicing and refunds using n8n. It automates the process of sending invoices, managing pre-checkout approvals, recordi

HTTP Request, Execute Workflow Trigger, Google Sheets +2
Slack & Telegram

VIVID v5.0 — Chapter Sub-workflow. Uses executeWorkflowTrigger, executeCommand, itemLists, httpRequest. Event-driven trigger; 21 nodes.

Execute Workflow Trigger, Execute Command, Item Lists +2
Slack & Telegram

[HUB] Жора Action. Uses executeWorkflowTrigger, supabase, telegram, httpRequest. Event-driven trigger; 19 nodes.

Execute Workflow Trigger, Supabase, Telegram +1
Slack & Telegram

Telegram User Registration Workflow. Uses stickyNote, executeWorkflowTrigger, googleSheets, telegram. Event-driven trigger; 15 nodes.

Execute Workflow Trigger, Google Sheets, Telegram
Slack & Telegram

02_Audio_Extractor. Uses executeWorkflowTrigger, telegram, httpRequest. Event-driven trigger; 13 nodes.

Execute Workflow Trigger, Telegram, HTTP Request