AutomationFlowsSlack & Telegram › N8n Approval Workflow

N8n Approval Workflow

N8N-Approval-Workflow. Uses telegram, telegramTrigger, httpRequest, dataTable. Webhook trigger; 18 nodes.

Webhook trigger★★★★☆ complexity18 nodesTelegramTelegram TriggerHTTP RequestData Table
Slack & Telegram Trigger: Webhook Nodes: 18 Complexity: ★★★★☆ Added:

This workflow follows the Datatable → 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": {
        "httpMethod": "POST",
        "path": "koc-approval",
        "responseMode": "responseNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        0,
        64
      ],
      "id": "98ccf50f-e6bb-4909-bd38-0524be579201",
      "name": "Webhook"
    },
    {
      "parameters": {
        "jsCode": "const body =\n  ($json && typeof $json === 'object' && $json.body && typeof $json.body === 'object')\n    ? $json.body\n    : $json;\n\nconst action = String(body.action || '').trim();\n\nconst headers = ($json && $json.headers && typeof $json.headers === 'object') ? $json.headers : {};\nconst query = ($json && $json.query && typeof $json.query === 'object') ? $json.query : {};\n\nreturn [{ json: { ...body, action, headers, query } }];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        224,
        64
      ],
      "id": "9bd293aa-04d6-46e3-82b5-c8841bfb650a",
      "name": "Normalize input"
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.action }}",
                    "rightValue": "request",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "id": "d75d8239-7fc4-4f97-af2d-82da37640154"
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Request"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "a9abf42c-c8b6-4f53-8227-d953c57d0fb8",
                    "leftValue": "={{ $json.action }}",
                    "rightValue": "status",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Status"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "4aef9034-0e00-4cad-9501-5fbc4589efef",
                    "leftValue": "={{ $json.action }}",
                    "rightValue": "notify",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Notify"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.4,
      "position": [
        448,
        48
      ],
      "id": "079e64c4-1dd2-4dbb-8ac8-636f925f050c",
      "name": "Switch"
    },
    {
      "parameters": {
        "jsCode": "const b = $json;\n\nconst approvalId = String(b.approvalId || '').trim();\nif (!approvalId) throw new Error('approvalId is required');\n\nconst summary = String(b.summary || '').trim();\nconst operation = String(b.operation || '').trim();\nconst target = String(b.target || '').trim();\nconst planPath = String(b.planPath || '').trim();\n\nlet details = String(b.details || '').trim();\nif (details.length > 500) details = details.slice(0, 500) + '\u2026';\n\nconst publicBase = String($env.KOC_PUBLIC_BASE_URL || '').replace(/\\/+$/, '');\nif (!publicBase) throw new Error('KOC_PUBLIC_BASE_URL is required');\n\nconst decisionSecret = String($env.KOC_DECISION_SECRET || '').trim();\nif (!decisionSecret) throw new Error('KOC_DECISION_SECRET is required');\n\nconst approveUrl =\n  `${publicBase}/webhook/koc-approval-decision?approvalId=${encodeURIComponent(approvalId)}&decision=approved&token=${encodeURIComponent(decisionSecret)}`;\nconst denyUrl =\n  `${publicBase}/webhook/koc-approval-decision?approvalId=${encodeURIComponent(approvalId)}&decision=denied&token=${encodeURIComponent(decisionSecret)}`;\n\nreturn [{\n  json: {\n    approvalId,\n    decision: 'pending',\n    approver: '',\n    reason: 'awaiting decision',\n    createdAt: new Date().toISOString(),\n    summary,\n    operation,\n    target,\n    planPath,\n    details,\n    approveUrl,\n    denyUrl,\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        672,
        -128
      ],
      "id": "b7f88a90-1834-4a1f-bb7b-563bda621634",
      "name": "Store pending + build decision URLs"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "{\n  \"approvalId\": \"{{$json.approvalId}}\",\n  \"decision\": \"pending\",\n  \"approver\": \"\",\n  \"reason\": \"awaiting decision\"\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [
        1344,
        -128
      ],
      "id": "2a81b5cc-ed1a-46f7-8a7c-dcf52e813798",
      "name": "Respond to Webhook"
    },
    {
      "parameters": {
        "jsCode": "const approvalId = String($json.approvalId || '').trim();\n\n// \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043d\u043e\u0434\u044b Data Tables, \u0437\u0430\u043f\u0438\u0441\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0432 items[] \u0438\u043b\u0438 \u0432 $json.data.\n// \u0421\u0430\u043c\u044b\u0439 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431: \u0431\u0435\u0440\u0451\u043c \u043f\u0435\u0440\u0432\u0443\u044e \u0432\u0445\u043e\u0434\u044f\u0449\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u043a\u0430\u043a row, \u0438\u043d\u0430\u0447\u0435 pending.\nconst row = items[0]?.json || {};\n\nif (!row || Object.keys(row).length === 0 || !row.approvalId) {\n  return [{ json: { approvalId, decision: 'pending', approver: '', reason: 'unknown approval id' } }];\n}\n\nreturn [{\n  json: {\n    approvalId: String(row.approvalId || approvalId),\n    decision: String(row.decision || 'pending'),\n    approver: String(row.approver || ''),\n    reason: String(row.reason || ''),\n    raw: row,\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        896,
        64
      ],
      "id": "071c78e8-7a8f-490b-94e3-52a99fc6e263",
      "name": "Read status"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify($json) }}",
        "options": {}
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [
        1120,
        64
      ],
      "id": "d6a318d2-ff34-47eb-bb8e-ec5cf9b758e2",
      "name": "Respond to Webhook1"
    },
    {
      "parameters": {
        "jsCode": "const root = items[0].json;\nconst action = root.body && root.body.action || root.action;\n\n// 1. \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0442\u043e\u043a\u0435\u043d\u0430 (\u043e\u0431\u0449\u0430\u044f \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0432\u0435\u0442\u043e\u043a)\nconst got = root.headers && root.headers.authorization;\nconst expected = `Bearer ${$env.KOC_DECISION_SECRET}`;\nif (!got || !expected || got !== expected) {\n  return [{ json: { ok: false, message: 'unauthorized', got, expected } }];\n}\n\n// 2. \u0412\u0435\u0442\u043a\u0430 notify \u2014 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u043a\u0435\u043d, \u043d\u0438\u0447\u0435\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e\nif (action === 'notify') {\n  return [{ json: { ok: true, message: 'notify accepted' } }];\n}\n\n// 3. \u0412\u0435\u0442\u043a\u0430 approval \u2014 \u0442\u0443\u0442 \u043d\u0443\u0436\u043d\u044b approvalId \u0438 decision\nconst q = (root && typeof root === 'object' && root.query && typeof root.query === 'object') ? root.query : root;\nconst approvalId = String(q.approvalId || '').trim();\nconst decision = String(q.decision || '').trim().toLowerCase();\n\nif (!approvalId) return [{ json: { ok: false, message: 'missing approvalId' } }];\nif (!['approved', 'denied'].includes(decision)) return [{ json: { ok: false, message: 'invalid decision' } }];\n\n// ...\u043e\u0441\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0434\u043b\u044f approval...\nreturn [{ json: { ok: true, approvalId, decision } }];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        672,
        256
      ],
      "id": "33d10e21-1f5b-4142-a241-29f27b91e40c",
      "name": "Normalize notify"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "{\"ok\": true}",
        "options": {}
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [
        1120,
        256
      ],
      "id": "f6655d56-92eb-48fb-be23-206722cc97ad",
      "name": "Respond: \u201cnotify response\""
    },
    {
      "parameters": {
        "chatId": "={{$env.KOC_TELEGRAM_CHAT_ID}}",
        "text": "={{\"<b>K8S AI Agent</b>\\n\" + \"Approval requested: <code>\" + $json.approvalId + \"</code>\\n\\n\" + \"<b>Change</b>\\n\" + $json.operation + \" \u2192 <code>\" + $json.target + \"</code>\\n\\n\" + \"<b>Why</b>\\n\" + ($json.details || \"n/a\") + \"\\n\"}}",
        "replyMarkup": "inlineKeyboard",
        "inlineKeyboard": {
          "rows": [
            {
              "row": {
                "buttons": [
                  {
                    "text": "Approve",
                    "additionalFields": {
                      "callback_data": "=approve:{{$json.approvalId}}"
                    }
                  },
                  {
                    "text": "Deny",
                    "additionalFields": {
                      "callback_data": "=deny:{{$json.approvalId}}"
                    }
                  }
                ]
              }
            }
          ]
        },
        "additionalFields": {
          "appendAttribution": false,
          "disable_web_page_preview": true,
          "parse_mode": "HTML"
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        1120,
        -128
      ],
      "id": "b8421055-fd25-4904-8b13-50a15c06993b",
      "name": "Send a text message",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "updates": [
          "callback_query"
        ],
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.telegramTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        480
      ],
      "id": "893486e5-6d12-4714-8776-531c77e9fd98",
      "name": "Telegram Trigger",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const u = $json;\nconst cq = u.callback_query;\nif (!cq) return [{ json: { ok: true, kind: \"ignore\" } }];\n\nconst data = String(cq.data || \"\").trim();\nconst callbackQueryId = String(cq.id || \"\").trim();\n\nconst msg = cq.message || {};\nconst chatId = msg.chat?.id;\nconst messageId = msg.message_id;\n\nlet decision = \"\";\nlet approvalId = \"\";\n\nif (data.startsWith(\"approve:\")) {\n  decision = \"approved\";\n  approvalId = data.slice(\"approve:\".length).trim();\n} else if (data.startsWith(\"deny:\")) {\n  decision = \"denied\";\n  approvalId = data.slice(\"deny:\".length).trim();\n}\n\nif (!approvalId || !decision) return [{ json: { ok: true, kind: \"ignore\" } }];\n\nreturn [{\n  json: { approvalId, decision, callbackQueryId, chatId, messageId }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        224,
        480
      ],
      "id": "130affbf-7a25-460c-a4c1-b61b764d315b",
      "name": "Parse Callback"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.telegram.org/bot{{$env.KOC_TELEGRAM_BOT_TOKEN}}/answerCallbackQuery",
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "callback_query_id",
              "value": "={{ $('Parse Callback').item.json.callbackQueryId }}"
            },
            {
              "name": "text",
              "value": "={{$json.decision === 'approved' ? 'Approved' : 'Denied'}}"
            },
            {
              "name": "show_alert",
              "value": "false"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        672,
        480
      ],
      "id": "6e915dfb-25a0-43ee-860a-0287f604a707",
      "name": "HTTP Request"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.telegram.org/bot{{$env.KOC_TELEGRAM_BOT_TOKEN}}/editMessageReplyMarkup",
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "chat_id",
              "value": "={{ $('Parse Callback').item.json.chatId }}"
            },
            {
              "name": "message_id",
              "value": "={{ $('Parse Callback').item.json.messageId }}"
            },
            {
              "name": "reply_markup",
              "value": "={{ JSON.stringify({ inline_keyboard: [] }) }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        896,
        480
      ],
      "id": "26eb2fb6-bbee-48cb-a9e3-a0a4b79c46de",
      "name": "HTTP Request1"
    },
    {
      "parameters": {
        "operation": "upsert",
        "dataTableId": {
          "__rl": true,
          "value": "9VmKMQaUAL5FeUAE",
          "mode": "list",
          "cachedResultName": "k8s-bot",
          "cachedResultUrl": "/projects/oae4C2E1F9eaRsa6/datatables/9VmKMQaUAL5FeUAE"
        },
        "filters": {
          "conditions": [
            {
              "keyName": "approvalId",
              "keyValue": "={{$json.approvalId}}"
            }
          ]
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "approvalId": "={{ $json.approvalId }}",
            "decision": "={{ $json.decision }}",
            "approver": "={{ $json.approver }}",
            "reason": "={{ $json.reason }}",
            "summary": "={{ $json.summary }}",
            "operation": "={{ $json.operation }}",
            "target": "={{ $json.target }}",
            "planPath": "={{ $json.planPath }}",
            "details": "={{ $json.details }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "approvalId",
              "displayName": "approvalId",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "decision",
              "displayName": "decision",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "approver",
              "displayName": "approver",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "reason",
              "displayName": "reason",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "summary",
              "displayName": "summary",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "operation",
              "displayName": "operation",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "target",
              "displayName": "target",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "planPath",
              "displayName": "planPath",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "details",
              "displayName": "details",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1,
      "position": [
        896,
        -128
      ],
      "id": "d400366d-b1ad-4b7a-8163-81286170744c",
      "name": "Upsert row(s)"
    },
    {
      "parameters": {
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "value": "9VmKMQaUAL5FeUAE",
          "mode": "list",
          "cachedResultName": "k8s-bot",
          "cachedResultUrl": "/projects/oae4C2E1F9eaRsa6/datatables/9VmKMQaUAL5FeUAE"
        },
        "filters": {
          "conditions": [
            {
              "keyName": "approvalId",
              "keyValue": "={{$json.approvalId}}"
            }
          ]
        },
        "limit": 1
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1,
      "position": [
        672,
        64
      ],
      "id": "8f6af6f5-ee26-42c0-9ca9-2591c0eee1c4",
      "name": "Data Tables(Get)"
    },
    {
      "parameters": {
        "operation": "update",
        "dataTableId": {
          "__rl": true,
          "value": "9VmKMQaUAL5FeUAE",
          "mode": "list",
          "cachedResultName": "k8s-bot",
          "cachedResultUrl": "/projects/oae4C2E1F9eaRsa6/datatables/9VmKMQaUAL5FeUAE"
        },
        "filters": {
          "conditions": [
            {
              "keyName": "approvalId",
              "keyValue": "={{ $json.approvalId }}"
            }
          ]
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "reason": "={{\"clicked \" + $json.decision}}",
            "approver": "={{$json.callbackQueryId}}",
            "decision": "={{$json.decision}}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "approvalId",
              "displayName": "approvalId",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "decision",
              "displayName": "decision",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "approver",
              "displayName": "approver",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "reason",
              "displayName": "reason",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "summary",
              "displayName": "summary",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "operation",
              "displayName": "operation",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "target",
              "displayName": "target",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "planPath",
              "displayName": "planPath",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "details",
              "displayName": "details",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1,
      "position": [
        448,
        480
      ],
      "id": "3eaa550a-78a1-463f-b71c-f02e6c7d07e9",
      "name": "Data Tables: Update row"
    },
    {
      "parameters": {
        "chatId": "={{$env.KOC_TELEGRAM_CHAT_ID}}",
        "text": "={{$('Switch').item.json.title + \"\\n\" + $('Switch').item.json.body}}",
        "additionalFields": {
          "appendAttribution": false,
          "disable_web_page_preview": true,
          "parse_mode": "HTML"
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        896,
        256
      ],
      "id": "91031394-8250-40fa-a71e-814883eafd01",
      "name": "Send a text message1",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Normalize input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize input": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Store pending + build decision URLs",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Data Tables(Get)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Normalize notify",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Store pending + build decision URLs": {
      "main": [
        [
          {
            "node": "Upsert row(s)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read status": {
      "main": [
        [
          {
            "node": "Respond to Webhook1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize notify": {
      "main": [
        [
          {
            "node": "Send a text message1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send a text message": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram Trigger": {
      "main": [
        [
          {
            "node": "Parse Callback",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Callback": {
      "main": [
        [
          {
            "node": "Data Tables: Update row",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "main": [
        [
          {
            "node": "HTTP Request1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upsert row(s)": {
      "main": [
        [
          {
            "node": "Send a text message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Data Tables(Get)": {
      "main": [
        [
          {
            "node": "Read status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Data Tables: Update row": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send a text message1": {
      "main": [
        [
          {
            "node": "Respond: \u201cnotify response\"",
            "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

N8N-Approval-Workflow. Uses telegram, telegramTrigger, httpRequest, dataTable. Webhook trigger; 18 nodes.

Source: https://github.com/gurgenyegoryan/kube-ops-copilot/blob/9a51b727a5fd893e9692d7225d75364d9caf5551/examples/n8n-approval-workflow.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

N8N Complete Final. Uses telegramTrigger, dataTable, telegram, mqtt. Event-driven trigger; 58 nodes.

Telegram Trigger, Data Table, Telegram +3
Slack & Telegram

TextMain. Uses telegramTrigger, stopAndError, telegram, httpRequest. Event-driven trigger; 56 nodes.

Telegram Trigger, Stop And Error, Telegram +2
Slack & Telegram

WF_UNIFIED_LEGAL_AUTOMATION. Uses googleSheets, httpRequest, telegram, telegramTrigger. Webhook trigger; 53 nodes.

Google Sheets, HTTP Request, Telegram +1
Slack & Telegram

Telegram B-1 (Variant A): submit -> finalize in n8n. Uses telegramTrigger, telegram, googleDrive, dataTable. Event-driven trigger; 43 nodes.

Telegram Trigger, Telegram, Google Drive +2
Slack & Telegram

AIPA - BMF Work Logging. Uses telegram, telegramTrigger, supabase, httpRequest. Webhook trigger; 19 nodes.

Telegram, Telegram Trigger, Supabase +1