AutomationFlowsSlack & Telegram › Telegram-command-interface.n8n

Telegram-command-interface.n8n

Telegram-Command-Interface.N8N. Uses telegramTrigger, httpRequest, googleSheets, telegram. Event-driven trigger; 25 nodes.

Event trigger★★★★☆ complexity25 nodesTelegram TriggerHTTP RequestGoogle SheetsTelegram
Slack & Telegram Trigger: Event Nodes: 25 Complexity: ★★★★☆ Added:

This workflow follows the Google Sheets → HTTP Request 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
{
  "nodes": [
    {
      "parameters": {
        "content": "## Telegram Command Interface\n\n**Purpose:** Command-line style interface via Telegram for monitoring the home lab automation system.\n\n**Commands:**\n- `/help` - List available commands\n- `/status` - Show recent execution status\n- `/failures` - List failures from FailedItems sheet\n- `/retry <execution_id>` - Retry a failed execution\n- `/search <query>` - Search invoices by supplier\n\n**Security:** Chat ID whitelist check before processing commands.\n\n**Message Handling:** Long responses (>4000 chars) are automatically split into multiple Telegram messages with part numbers.",
        "height": 360,
        "width": 400
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -100,
        -200
      ],
      "id": "overview-sticky-note",
      "name": "Overview"
    },
    {
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.telegramTrigger",
      "typeVersion": 1.2,
      "position": [
        -100,
        200
      ],
      "id": "telegram-trigger-node",
      "name": "Telegram Trigger",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "whitelist-check-condition",
              "leftValue": "={{ ['YOUR_CHAT_ID_1', 'YOUR_CHAT_ID_2'].includes(String($json.message.chat.id)) }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        120,
        200
      ],
      "id": "whitelist-check-node",
      "name": "Whitelist Check"
    },
    {
      "parameters": {
        "jsCode": "// Parse Command\n// Extracts command name and arguments from Telegram message\n\nconst text = ($json.message.text || '').trim();\nconst chatId = String($json.message.chat.id);\n\n// Match /command or /command args\nconst match = text.match(/^\\/([\\w]+)(?:\\s+(.*))?$/);\n\nif (match) {\n  return [{\n    json: {\n      chatId: chatId,\n      command: match[1].toLowerCase(),\n      args: (match[2] || '').trim(),\n      rawText: text\n    }\n  }];\n}\n\n// Not a command - return fallback\nreturn [{\n  json: {\n    chatId: chatId,\n    command: '_not_a_command',\n    args: '',\n    rawText: text\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        340,
        200
      ],
      "id": "parse-command-node",
      "name": "Parse Command"
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.command }}",
                    "rightValue": "help",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "help"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.command }}",
                    "rightValue": "status",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "status"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.command }}",
                    "rightValue": "failures",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "failures"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.command }}",
                    "rightValue": "retry",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "retry"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.command }}",
                    "rightValue": "search",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "search"
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        560,
        200
      ],
      "id": "command-router-node",
      "name": "Command Router"
    },
    {
      "parameters": {
        "jsCode": "// Format Help Message\nconst chatId = $json.chatId;\n\nconst helpText = `*Available Commands*\n\n/help - Show this help message\n/status - Show recent workflow executions\n/failures - List pending failures from FailedItems\n/retry <id> - Retry a failed execution by ID\n/search <query> - Search invoices by supplier name\n\n_Examples:_\n\\`/status\\`\n\\`/retry 36001\\`\n\\`/search Acme\\``;\n\nreturn [{\n  json: {\n    chatId: chatId,\n    response: helpText\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        800,
        -80
      ],
      "id": "help-handler-node",
      "name": "Format Help"
    },
    {
      "parameters": {
        "method": "GET",
        "url": "https://YOUR_N8N_INSTANCE.up.railway.app/api/v1/executions",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "limit",
              "value": "10"
            }
          ]
        },
        "options": {
          "response": {
            "response": {
              "neverError": true
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        800,
        80
      ],
      "id": "status-api-node",
      "name": "Get Executions",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Format Status Response\nconst chatId = $('Parse Command').item.json.chatId;\nconst apiResponse = $json;\n\n// Handle API errors\nif (apiResponse.message && apiResponse.code) {\n  return [{\n    json: {\n      chatId: chatId,\n      response: `Error fetching executions: ${apiResponse.message}`\n    }\n  }];\n}\n\nconst executions = apiResponse.data || [];\n\nif (executions.length === 0) {\n  return [{\n    json: {\n      chatId: chatId,\n      response: 'No recent executions found.'\n    }\n  }];\n}\n\n// Status emoji mapping\nconst statusEmoji = {\n  success: '\\u2705',   // Green check\n  error: '\\u274C',     // Red X\n  running: '\\u23F3',   // Hourglass\n  waiting: '\\u23F8',   // Pause\n  canceled: '\\u26D4'   // No entry\n};\n\nlet lines = ['*Recent Executions*', ''];\n\nfor (const exec of executions.slice(0, 10)) {\n  const emoji = statusEmoji[exec.status] || '\\u2753';\n  const workflow = exec.workflowData?.name || exec.workflowId || 'Unknown';\n  const id = exec.id;\n  const status = exec.status;\n  const startedAt = exec.startedAt ? new Date(exec.startedAt).toLocaleString() : 'N/A';\n  \n  lines.push(`${emoji} \\`${id}\\` ${workflow}`);\n  lines.push(`   ${status} | ${startedAt}`);\n}\n\nreturn [{\n  json: {\n    chatId: chatId,\n    response: lines.join('\\n')\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1020,
        80
      ],
      "id": "format-status-node",
      "name": "Format Status"
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "value": "YOUR_FAILEDITEMS_SHEET_ID",
          "mode": "list",
          "cachedResultName": "007_Error-handler.n8n-sheet",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_FAILEDITEMS_SHEET_ID/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "FailedItems",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_FAILEDITEMS_SHEET_ID/edit#gid=0"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4,
      "position": [
        800,
        240
      ],
      "id": "read-failures-node",
      "name": "Read FailedItems",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Format Failures Response\nconst chatId = $('Parse Command').item.json.chatId;\nconst items = $input.all();\n\nif (!items || items.length === 0) {\n  return [{\n    json: {\n      chatId: chatId,\n      response: 'No failures in FailedItems sheet.'\n    }\n  }];\n}\n\n// Filter for pending_retry and escalated only\nconst failures = items\n  .map(i => i.json)\n  .filter(f => f.status === 'pending_retry' || f.status === 'escalated')\n  .sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp))\n  .slice(0, 10);\n\nif (failures.length === 0) {\n  return [{\n    json: {\n      chatId: chatId,\n      response: 'No pending failures.'\n    }\n  }];\n}\n\n// Severity emoji mapping\nconst severityEmoji = {\n  critical: '\\uD83D\\uDD34',\n  high: '\\uD83D\\uDFE0',\n  medium: '\\uD83D\\uDFE1',\n  low: '\\uD83D\\uDFE2'\n};\n\nlet lines = ['*Pending Failures*', ''];\n\nfor (const f of failures) {\n  const emoji = severityEmoji[f.severity] || '\\u26AA';\n  const escalatedMarker = f.status === 'escalated' ? ' \\u26A0\\uFE0F ESCALATED' : '';\n  \n  lines.push(`${emoji} \\`${f.execution_id}\\`${escalatedMarker}`);\n  lines.push(`   ${f.workflow_name || 'Unknown workflow'}`);\n  lines.push(`   ${f.error_type}: ${(f.error_message || '').substring(0, 60)}...`);\n  lines.push(`   Retries: ${f.retry_count || 0} | ${f.timestamp || 'N/A'}`);\n  lines.push('');\n}\n\nreturn [{\n  json: {\n    chatId: chatId,\n    response: lines.join('\\n')\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1020,
        240
      ],
      "id": "format-failures-node",
      "name": "Format Failures"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "has-exec-id-condition",
              "leftValue": "={{ $json.args }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        800,
        400
      ],
      "id": "retry-has-id-check",
      "name": "Has Execution ID?"
    },
    {
      "parameters": {
        "jsCode": "// Missing execution ID error\nreturn [{\n  json: {\n    chatId: $json.chatId,\n    response: 'Usage: /retry <execution_id>\\n\\nExample: /retry 36001'\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1020,
        480
      ],
      "id": "retry-missing-id-node",
      "name": "Retry Missing ID"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://YOUR_N8N_INSTANCE.up.railway.app/api/v1/executions/{{ $json.args }}/retry",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "response": {
            "response": {
              "neverError": true
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1020,
        360
      ],
      "id": "execute-retry-node",
      "name": "Execute Retry",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Format Retry Response\nconst chatId = $('Parse Command').item.json.chatId;\nconst originalId = $('Parse Command').item.json.args;\nconst apiResponse = $json;\n\n// Check if retry started successfully\nif (apiResponse.id) {\n  return [{\n    json: {\n      chatId: chatId,\n      response: `\\u2705 Retry started!\\n\\nOriginal: \\`${originalId}\\`\\nNew execution: \\`${apiResponse.id}\\`\\nStatus: ${apiResponse.status}\\n\\n_Use /status to check progress_`\n    }\n  }];\n}\n\n// Error case\nconst errorMsg = apiResponse.message || 'Unknown error';\nreturn [{\n  json: {\n    chatId: chatId,\n    response: `\\u274C Retry failed for \\`${originalId}\\`\\n\\nError: ${errorMsg}`\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1240,
        360
      ],
      "id": "format-retry-node",
      "name": "Format Retry"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "has-search-query-condition",
              "leftValue": "={{ $json.args }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        800,
        560
      ],
      "id": "search-has-query-check",
      "name": "Has Search Query?"
    },
    {
      "parameters": {
        "jsCode": "// Missing search query error\nreturn [{\n  json: {\n    chatId: $json.chatId,\n    response: 'Usage: /search <supplier_name>\\n\\nExample: /search Acme'\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1020,
        640
      ],
      "id": "search-missing-query-node",
      "name": "Search Missing Query"
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "value": "YOUR_BILLING_LEDGER_SHEET_ID",
          "mode": "list",
          "cachedResultName": "Billing_Ledger",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_BILLING_LEDGER_SHEET_ID/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "Sheet1",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_BILLING_LEDGER_SHEET_ID/edit#gid=0"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4,
      "position": [
        1020,
        520
      ],
      "id": "read-invoices-node",
      "name": "Read Invoices",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Format Search Response\nconst chatId = $('Parse Command').item.json.chatId;\nconst query = $('Parse Command').item.json.args.toLowerCase();\nconst items = $input.all();\n\nif (!items || items.length === 0) {\n  return [{\n    json: {\n      chatId: chatId,\n      response: 'No invoices found in database.'\n    }\n  }];\n}\n\n// Filter by supplier_name (case-insensitive partial match)\nconst matches = items\n  .map(i => i.json)\n  .filter(inv => {\n    const supplier = (inv.supplier_name || '').toLowerCase();\n    return supplier.includes(query);\n  })\n  .slice(0, 10);\n\nif (matches.length === 0) {\n  return [{\n    json: {\n      chatId: chatId,\n      response: `No invoices found for \"${query}\".`\n    }\n  }];\n}\n\nlet lines = [`*Search Results for \"${query}\"*`, ''];\n\nfor (const inv of matches) {\n  lines.push(`\\uD83D\\uDCDD ${inv.supplier_name || 'Unknown'}`);\n  lines.push(`   Date: ${inv.invoice_date || 'N/A'}`);\n  lines.push(`   Amount: ${inv.total_amount_due || 'N/A'} ${inv.currency_code || ''}`);\n  if (inv.invoice_number) lines.push(`   Invoice #: ${inv.invoice_number}`);\n  lines.push('');\n}\n\nreturn [{\n  json: {\n    chatId: chatId,\n    response: lines.join('\\n')\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1240,
        520
      ],
      "id": "format-search-node",
      "name": "Format Search"
    },
    {
      "parameters": {
        "jsCode": "// Fallback for unknown commands\nconst chatId = $json.chatId;\nconst command = $json.command;\n\nlet response;\nif (command === '_not_a_command') {\n  response = 'I only respond to commands. Try /help to see available commands.';\n} else {\n  response = `Unknown command: /${command}\\n\\nTry /help to see available commands.`;\n}\n\nreturn [{\n  json: {\n    chatId: chatId,\n    response: response\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        800,
        720
      ],
      "id": "fallback-handler-node",
      "name": "Unknown Command"
    },
    {
      "parameters": {
        "mode": "combine",
        "mergeByFields": {
          "values": []
        },
        "options": {}
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.1,
      "position": [
        1460,
        200
      ],
      "id": "merge-responses-node",
      "name": "Merge Responses"
    },
    {
      "parameters": {
        "jsCode": "// Split Long Message into Chunks\n// Telegram max message length is ~4096 chars, using 4000 to be safe\n\nconst message = $json.response || 'No response';\nconst chatId = $json.chatId;\nconst maxLength = 4000;\nconst chunks = [];\n\nfor (let i = 0; i < message.length; i += maxLength) {\n  chunks.push(message.substring(i, i + maxLength));\n}\n\nreturn chunks.map((chunk, idx) => ({\n  json: {\n    chatId: chatId,\n    chunk: chunk,\n    part: idx + 1,\n    total: chunks.length\n  }\n}));"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1680,
        200
      ],
      "id": "split-long-message-node",
      "name": "Split Long Message"
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        1900,
        200
      ],
      "id": "loop-over-chunks-node",
      "name": "Loop Over Chunks"
    },
    {
      "parameters": {
        "chatId": "={{ $json.chatId }}",
        "text": "={{ $json.total > 1 ? '[' + $json.part + '/' + $json.total + '] ' : '' }}{{ $json.chunk }}",
        "additionalFields": {
          "appendAttribution": false,
          "parse_mode": "Markdown"
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        2120,
        200
      ],
      "id": "send-telegram-response-node",
      "name": "Send Response",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "content": "### Command Handlers\n\nEach command branch processes the request and returns:\n```\n{\n  chatId: \"...\",\n  response: \"formatted message\"\n}\n```\n\nAll branches merge before the response pipeline.",
        "height": 200,
        "width": 280
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        780,
        -200
      ],
      "id": "handlers-sticky-note",
      "name": "Handlers Note"
    },
    {
      "parameters": {
        "content": "### Response Pipeline\n\n1. Merge all command outputs\n2. Split messages >4000 chars\n3. Loop and send each chunk\n4. Add part numbers for multi-part messages",
        "height": 160,
        "width": 280
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1460,
        -40
      ],
      "id": "pipeline-sticky-note",
      "name": "Pipeline Note"
    }
  ],
  "connections": {
    "Telegram Trigger": {
      "main": [
        [
          {
            "node": "Whitelist Check",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Whitelist Check": {
      "main": [
        [
          {
            "node": "Parse Command",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Parse Command": {
      "main": [
        [
          {
            "node": "Command Router",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Command Router": {
      "main": [
        [
          {
            "node": "Format Help",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get Executions",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Read FailedItems",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Has Execution ID?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Has Search Query?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Unknown Command",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Help": {
      "main": [
        [
          {
            "node": "Merge Responses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Executions": {
      "main": [
        [
          {
            "node": "Format Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Status": {
      "main": [
        [
          {
            "node": "Merge Responses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read FailedItems": {
      "main": [
        [
          {
            "node": "Format Failures",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Failures": {
      "main": [
        [
          {
            "node": "Merge Responses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Execution ID?": {
      "main": [
        [
          {
            "node": "Execute Retry",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Retry Missing ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Retry Missing ID": {
      "main": [
        [
          {
            "node": "Merge Responses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute Retry": {
      "main": [
        [
          {
            "node": "Format Retry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Retry": {
      "main": [
        [
          {
            "node": "Merge Responses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Search Query?": {
      "main": [
        [
          {
            "node": "Read Invoices",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Search Missing Query",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search Missing Query": {
      "main": [
        [
          {
            "node": "Merge Responses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Invoices": {
      "main": [
        [
          {
            "node": "Format Search",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Search": {
      "main": [
        [
          {
            "node": "Merge Responses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Unknown Command": {
      "main": [
        [
          {
            "node": "Merge Responses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Responses": {
      "main": [
        [
          {
            "node": "Split Long Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Long Message": {
      "main": [
        [
          {
            "node": "Loop Over Chunks",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Chunks": {
      "main": [
        [],
        [
          {
            "node": "Send Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Response": {
      "main": [
        [
          {
            "node": "Loop Over Chunks",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "meta": {
    "templateCredsSetupCompleted": true
  }
}

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

Telegram-Command-Interface.N8N. Uses telegramTrigger, httpRequest, googleSheets, telegram. Event-driven trigger; 25 nodes.

Source: https://github.com/runfish5/micro-services/blob/main/projects/n8n/11_n8n-ops-center/telegram-command-interface.n8n.json — 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

clients kept booking meetings during my prayer times. i'd either miss a prayer or scramble to reschedule. the problem wasn't the clients — it was that my calendar had no blocked windows for salah. i n

Telegram Trigger, HTTP Request, Google Calendar +3
Slack & Telegram

Generate 360° product videos from a single photo using Google Veo 3 and Telegram

Telegram, Telegram Trigger, HTTP Request +1
Slack & Telegram

02b — Article callback. Uses telegramTrigger, googleSheets, telegram, httpRequest. Event-driven trigger; 30 nodes.

Telegram Trigger, Google Sheets, Telegram +1
Slack & Telegram

Automates LinkedIn job searches across multiple countries and categories, filters results with AI, stores data in Google Sheets, and sends weekly Telegram notifications. Perfect for professionals seek

Telegram Trigger, Item Lists, HTTP Request +3