AutomationFlowsSlack & Telegram › Deepp Auto P1 V3 - Worker (front)

Deepp Auto P1 V3 - Worker (front)

DEEPP AUTO P1 V3 - Worker (Front). Uses httpRequest, readWriteFile, executeCommand, dataTable. Event-driven trigger; 34 nodes.

Event trigger★★★★★ complexity34 nodesHTTP RequestRead Write FileExecute CommandData TableExecute Workflow Trigger
Slack & Telegram Trigger: Event Nodes: 34 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
{
  "name": "DEEPP AUTO P1 V3 - Worker (Front)",
  "nodes": [
    {
      "parameters": {
        "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/getFile",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "file_id",
              "value": "={{ $json.file_id }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        -20768,
        -3648
      ],
      "id": "aacb2a2e-3158-469b-9f14-28bc371e0cff",
      "name": "HTTP Request - Telegram Get File"
    },
    {
      "parameters": {
        "url": "=https://api.telegram.org/file/bot{{ $env.TELEGRAM_BOT_TOKEN }}/{{ $json.result.file_path }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        -20624,
        -3648
      ],
      "id": "ab3a58f1-b81b-4211-98e0-33bbee07e2e2",
      "name": "HTTP Request - Telegram Download File"
    },
    {
      "parameters": {
        "jsCode": "// \u8d70\u5230\u8fd9\u4e00\u6b65\u7684binary,\u4e0d\u7ba1\u6765\u6e90\u662f\u539f\u59cb\u7167\u7247\u3001\u8fd8\u662fPDF\u8f6c\u51fa\u6765\u7684\u9875\u9762\u56fe\u7247,\n// \u5168\u90e8\u90fd\u5df2\u7ecf\u662fJPG\u4e86,\u4e0d\u7528\u518d\u56de\u5934\u5224\u65ad\u539f\u59cbmime_type\u662f\u4ec0\u4e48\nconst items = $input.all();\n\nfor (const item of items) {\n  if (item.binary) {\n    for (const key of Object.keys(item.binary)) {\n      item.binary[key].mimeType = 'image/jpeg';\n    }\n  }\n}\n\nreturn items;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -19488,
        -3312
      ],
      "id": "a33c9529-7c45-4738-8192-5e1cb92fb642",
      "name": "\u4fee\u6b63\u56fe\u7247MimeType"
    },
    {
      "parameters": {
        "jsCode": "// \u628a\u591a\u4e2a\"\u5404\u81ea\u5e26\u4e00\u4e2a\u6863\u6848(\u56fe\u7247\u6216PDF)\"\u7684item,\u5408\u5e76\u6210\"\u4e00\u4e2aitem\u3001\u5185\u542b\u591a\u4e2a\u6863\u6848\"\n// (\u7eaf\u6587\u5b57\u60c5\u5883\u4e0b,items\u91cc\u53ef\u80fd\u5b8c\u5168\u6ca1\u6709binary,\u8981\u80fd\u6b63\u786e\u5904\u7406)\nconst items = $input.all();\n\nconst mergedBinary = {};\nitems.forEach((item, index) => {\n  if (item.binary && item.binary.data) {\n    mergedBinary[`file_${index}`] = item.binary.data;\n  }\n});\n\n// \u56de\u5934\u6307\u540d\u53bb\u6293\u6700\u65e9\u90a3\u4e2anode,\u62ffchat_id\u8ddftext_content\nconst sourceData = $('\u89e3\u6790Router\u4f20\u6765\u7684items').first().json;\n\nreturn [{\n  json: {\n    chat_id: sourceData.chat_id,\n    text_content: sourceData.text_content,\n    fileCount: Object.keys(mergedBinary).length\n  },\n  binary: mergedBinary\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -19120,
        -3680
      ],
      "id": "5f0fde74-0052-4f84-83db-e2838c58c87e",
      "name": "\u6c47\u5408\u6210\u4e00\u4e2aitem\u7684Code node"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "d49faa9c-ca86-41c6-9124-24cb929683f8",
              "leftValue": "={{ $('\u89e3\u6790Router\u4f20\u6765\u7684items').item.json.mime_type }}",
              "rightValue": "application/pdf",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        -20480,
        -3648
      ],
      "id": "967f38ca-0cb2-407d-b2a5-eba4cfdc5683",
      "name": "\u662f\u5426\u4e3aPDF"
    },
    {
      "parameters": {
        "operation": "write",
        "fileName": "=/home/node/files/{{ $('\u89e3\u6790Router\u4f20\u6765\u7684items').item.json.file_id }}.pdf",
        "options": {}
      },
      "type": "n8n-nodes-base.readWriteFile",
      "typeVersion": 1.1,
      "position": [
        -20224,
        -3664
      ],
      "id": "1acd87f0-4e59-4408-9faf-63c56a26405a",
      "name": "\u5199\u5165PDF\u5230\u78c1\u76d8"
    },
    {
      "parameters": {
        "command": "=pdftoppm -jpeg -r 150 /home/node/files/{{ $('\u89e3\u6790Router\u4f20\u6765\u7684items').item.json.file_id }}.pdf /home/node/files/{{ $('\u89e3\u6790Router\u4f20\u6765\u7684items').item.json.file_id }}"
      },
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        -20016,
        -3664
      ],
      "id": "bfc1a9c8-e274-4c13-8082-cafee379d79f",
      "name": "Execute Command"
    },
    {
      "parameters": {
        "fileSelector": "=/home/node/files/{{ $('\u89e3\u6790Router\u4f20\u6765\u7684items').item.json.file_id }}-*.jpg",
        "options": {}
      },
      "type": "n8n-nodes-base.readWriteFile",
      "typeVersion": 1.1,
      "position": [
        -19808,
        -3664
      ],
      "id": "fd7affcc-af05-4e24-bd18-2d0f2d808985",
      "name": "Read/Write Files from Disk"
    },
    {
      "parameters": {
        "jsCode": "// \u56fa\u5b9a\u7ed9\u8fd9\u4e2aworkflow\u7684\u4ee3\u53f7,\u4e4b\u540e\u590d\u5236\u6210worker2/worker3\u65f6,\u53ea\u9700\u8981\u6539\u8fd9\u4e00\u884c\nconst BOT_ID = 'worker1';\n\n// \u7528\u9a6c\u6765\u897f\u4e9a\u65f6\u95f4\u53d6\"\u4eca\u5929\"\u7684\u65e5\u671f(\u7c97\u7565\u5bf9\u9f50,\u4e0d\u8ffd\u6c42\u8ddfGoogle\u90a3\u8fb9\u7cbe\u786e\u540c\u6b65\u91cd\u7f6e\u65f6\u95f4)\nconst now = new Date();\nconst malaysiaDate = new Intl.DateTimeFormat('en-CA', {\n  timeZone: 'Asia/Kuala_Lumpur',\n  year: 'numeric', month: '2-digit', day: '2-digit'\n}).format(now); // \u683c\u5f0f\u7c7b\u4f3c 2026-07-24\n\nconst usageKey = `${BOT_ID}_${malaysiaDate}`;\n\nconst items = $input.all();\nfor (const item of items) {\n  item.json.bot_id = BOT_ID;\n  item.json.usage_date = malaysiaDate;\n  item.json.usage_key = usageKey;\n}\n\nreturn items;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -18960,
        -3680
      ],
      "id": "942fdc04-a7c5-496c-be2f-b889649affdd",
      "name": "\u7b97\u51fausage_key"
    },
    {
      "parameters": {
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "value": "xe1tWUcTzVf19IBn",
          "mode": "list",
          "cachedResultName": "daily_usage",
          "cachedResultUrl": "/projects/W1Bzh2H8JZecMoTf/datatables/xe1tWUcTzVf19IBn"
        },
        "filters": {
          "conditions": [
            {
              "keyName": "usage_key",
              "keyValue": "={{ $json.usage_key }}"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        -18784,
        -3680
      ],
      "id": "0786aa20-f33b-4559-b295-5c1563ed51b2",
      "name": "\u67e5\u770busage_key",
      "alwaysOutputData": true
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "ceec15b3-1123-4f7b-81cf-e8bceeb5f46b",
              "leftValue": "={{ $json.over_limit }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "false",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        -18400,
        -3680
      ],
      "id": "516bd72c-1dd5-4c92-8425-728568ea96a2",
      "name": "\u662f\u5426\u591f\u6b21\u6570"
    },
    {
      "parameters": {
        "jsCode": "// \u67e5usage_key\u7684\u7ed3\u679c:\u5982\u679c\u4eca\u5929\u7b2c\u4e00\u6b21\u7528,Data Table\u91cc\u8fd8\u6ca1\u6709\u8fd9\u884c\u8d44\u6599,\n// Get\u4f1a\u67e5\u52300\u7b14,\u8fd9\u91cc\u5f53\u4f5ccount=0\u5904\u7406\nconst usageRows = $input.all();\nconst currentCount = usageRows.length > 0 ? (usageRows[0].json.count || 0) : 0;\n\nconst THRESHOLD = 15; // \u6bcf\u65e5\u4e0a\u9650,\u5148\u6293\u4fdd\u5b88\u4e00\u70b9\n\n// \u771f\u6b63\u8981\u7ee7\u7eed\u5f80\u4e0b\u8d70\u7684\u8d44\u6599(chat_id\u3001text_content\u3001\u56fe\u7247binary),\n// \u8981\u56de\u5934\u53bb\u6293\"\u7b97\u51fausage_key\"\u90a3\u4e00\u6b65\u7684\u8f93\u51fa,\u4e0d\u80fd\u76f4\u63a5\u7528\u8fd9\u91cc\u7684$input\n// (\u56e0\u4e3aData Table\u8282\u70b9\u4f1a\u628abinary\u6863\u6848\u5f04\u4e22,\u53ea\u7559json)\nconst sourceItems = $('\u7b97\u51fausage_key').all();\n\nfor (const item of sourceItems) {\n  item.json.current_count = currentCount;\n  item.json.over_limit = currentCount >= THRESHOLD;\n}\n\nreturn sourceItems;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -18592,
        -3680
      ],
      "id": "e180fbd6-0967-46b5-9a9d-f552a01fb652",
      "name": "\u5224\u65ad\u662f\u5426\u591f\u6b21\u6570",
      "alwaysOutputData": false
    },
    {
      "parameters": {
        "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/sendMessage",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "chat_id",
              "value": "={{ $json.chat_id }}"
            },
            {
              "name": "text",
              "value": "\u300c\u4eca\u65e5\u5904\u7406\u91cf\u5df2\u8fbe\u4e0a\u9650\uff0c\u8bf7\u660e\u5929\u518d\u8bd5 \ud83d\ude4f\u300d"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        -18144,
        -3264
      ],
      "id": "8ed45370-550b-44c1-ac3e-7d12aeff812a",
      "name": "\u53d1\u9001\u989d\u5ea6\u5df2\u6ee1\u8baf\u606f"
    },
    {
      "parameters": {
        "jsCode": "const item = $input.first();\nconst sourceData = $('\u6c47\u5408\u6210\u4e00\u4e2aitem\u7684Code node').first().json; // chat_id, text_content\nconst usageData = $('\u5224\u65ad\u662f\u5426\u591f\u6b21\u6570').first().json; // bot_id\n\nconst binaryKeys = Object.keys(item.binary || {});\nconst parts = [];\n\nfor (const key of binaryKeys) {\n  const buffer = await this.helpers.getBinaryDataBuffer(0, key);\n  const base64Data = buffer.toString('base64');\n  const mimeType = item.binary[key].mimeType || 'image/jpeg';\n  parts.push({\n    inline_data: {\n      mime_type: mimeType,\n      data: base64Data\n    }\n  });\n}\n\nconst captionText = sourceData.text_content\n  ? `\u5546\u5bb6\u5907\u6ce8\uff1a${sourceData.text_content}`\n  : '\uff08\u5546\u5bb6\u8fd9\u6b21\u6ca1\u6709\u63d0\u4f9b\u989d\u5916\u5907\u6ce8\uff09';\n\n// \u53ea\u5728\u8bc4\u5206\"\u786e\u5b9e\u504f\u4f4e\"(<=2\u661f)\u7684\u65f6\u5019\u624d\u63d0\u9192AI\u66f4\u4ed4\u7ec6\u2014\u2014\n// \u5546\u5bb6\u5fd8\u8bb0\u8bc4\u5206\u3001\u6216\u8bc4\u52063\u661f\u4ee5\u4e0a,\u4e00\u5f8b\u5f53\u4f5c\u6ca1\u8fd9\u56de\u4e8b,\u4e0d\u989d\u5916\u52a0\u63d0\u793a\u8bed,\n// \u4e0d\u80fd\u8ba9AI\u56e0\u4e3a\"\u4ee5\u4e3a\u81ea\u5df1\u4e0a\u6b21\u8868\u73b0\u4e0d\u597d\"\u800c\u4ea7\u751f\u4e0d\u5fc5\u8981\u7684\u8d1f\u9762\u504f\u5dee\nconst ratingRow = $('\u67e5\u5546\u5bb6\u8bc4\u5206').first().json;\nconst stars = ratingRow.stars;\nconst qualityHint = (typeof stars === 'number' && stars <= 2)\n  ? '\\n\\n\u63d0\u9192\uff1a\u8fd9\u4f4d\u5546\u5bb6\u4e0a\u6b21\u7ed9\u7684\u8bc4\u4ef7\u4e0d\u9ad8,\u8fd9\u6b21\u8bf7\u7279\u522b\u4ed4\u7ec6\u6838\u5bf9\u6bcf\u4e2a\u54c1\u9879\u7684\u540d\u79f0\u3001\u5206\u7c7b\u3001\u4ef7\u683c,\u786e\u4fdd\u4fe1\u606f\u51c6\u786e\u5b8c\u6574\u3002'\n  : '';\n\nconst promptText = `\u4f60\u662f\"Heng_MenuTransfer_bot\"\uff0c\u4e13\u95e8\u5e2e\u52a9\u9910\u996e\u5546\u5bb6\u628a\u83dc\u5355\u8f6c\u6362\u6210POS\u7cfb\u7edf\u53ef\u5bfc\u5165\u7684Excel\u6587\u4ef6\u3002\n\n\u4f60\u4f1a\u6536\u5230\u4e00\u5f20\u6216\u591a\u5f20\u83dc\u5355\u56fe\u7247(\u4e5f\u53ef\u80fd\u5b8c\u5168\u6ca1\u6709\u56fe\u7247,\u5546\u5bb6\u76f4\u63a5\u7528\u6587\u5b57\u63cf\u8ff0\u6574\u4efd\u83dc\u5355)\uff0c\u4ee5\u53ca\u5546\u5bb6\u53ef\u80fd\u63d0\u4f9b\u7684\u989d\u5916\u5907\u6ce8\u6587\u5b57\u3002\n\n\u4f60\u7684\u4efb\u52a1\uff1a\n1. \u4ed4\u7ec6\u9605\u8bfb\u6240\u6709\u56fe\u7247\u5185\u5bb9\uff0c\u8bc6\u522b\u51fa\u5168\u90e8\u5546\u54c1\uff0c\u6574\u7406\u51fa\u6bcf\u4e2a\u5546\u54c1\u7684\uff1a\n   name(\u540d\u79f0)\u3001category(\u5206\u7c7b)\u3001spec(\u89c4\u683c\uff0c\u9009\u586b)\u3001stock_qty(\u5e93\u5b58\u91cf\uff0c\u9009\u586b)\u3001\n   cost_price(\u8fdb\u8d27\u4ef7\uff0c\u9009\u586b\uff0c\u7f3a\u4e86\u76f4\u63a5\u7559\u7a7a\u5373\u53ef)\u3001sell_price(\u9500\u552e\u4ef7)\n2. \u5224\u65adname\u3001category\u3001sell_price\u8fd9\u4e09\u4e2a\u680f\u4f4d\uff0c\u662f\u5426\u6bcf\u4e2a\u54c1\u9879\u90fd\u586b\u5f97\u51fa\u6765\n3. \u5982\u679c\u5546\u5bb6\u63d0\u4f9b\u4e86\u989d\u5916\u5907\u6ce8\uff08\u6bd4\u5982\u5916\u5e26\u52a0\u4ef7\u3001\u5206\u7c7b\u89c4\u5219\u7b49\uff09\uff0c\u7eb3\u5165\u5224\u65ad\uff1b\n   \u5982\u679c\u5907\u6ce8\u8ddf\u5546\u54c1\u8d44\u6599\u6709\u51b2\u7a81\u6216\u770b\u4e0d\u61c2\u8be5\u600e\u4e48\u5957\u7528\uff0c\u4e00\u6837\u5f52\u7c7b\u4e3a\u4fe1\u606f\u4e0d\u5b8c\u6574\n\n${captionText}${qualityHint}\n\n\u8bf7\u4e25\u683c\u53ea\u8f93\u51fa\u4ee5\u4e0bJSON\u683c\u5f0f\uff0c\u4e0d\u8981\u4efb\u4f55\u89e3\u91ca\u6587\u5b57\u3001\u4e0d\u8981markdown\u4ee3\u7801\u5757\u6807\u8bb0\uff1a\n{\n  \"status\": \"complete \u6216 incomplete\",\n  \"items\": [{\"name\":\"\u5546\u54c1\u540d\",\"category\":\"\u5206\u7c7b\",\"spec\":\"\u89c4\u683c\",\"stock_qty\":0,\"cost_price\":0,\"sell_price\":0.00}],\n  \"question\": \"\u53ea\u6709status\u662fincomplete\u65f6\u624d\u9700\u8981\u8fd9\u4e2a\u680f\u4f4d\uff0c\u9488\u5bf9\u6027\u5730\u95ee\u7528\u6237\u7f3a\u7684\u662f\u4ec0\u4e48\"\n}`;\n\nconst geminiRequest = {\n  contents: [{\n    parts: [\n      { text: promptText },\n      ...parts\n    ]\n  }]\n};\n\nreturn [{\n  json: {\n    chat_id: sourceData.chat_id,\n    bot_id: usageData.bot_id,\n    geminiRequest: geminiRequest\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -18192,
        -3696
      ],
      "id": "731b484e-5c87-4473-87e6-455593416b43",
      "name": "\u7ec4\u88c5Gemini\u8bf7\u6c42"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.5-flash:generateContent",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpQueryAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ $json.geminiRequest }}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        -18016,
        -3696
      ],
      "id": "b34fb1c5-fca2-42fb-9e1b-aea3148c4de2",
      "name": "HTTP Request",
      "credentials": {
        "httpQueryAuth": {
          "name": "<your credential>"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "const item = $input.first().json;\nconst chatId = $('\u7ec4\u88c5Gemini\u8bf7\u6c42').first().json.chat_id;\nconst botId = $('\u7ec4\u88c5Gemini\u8bf7\u6c42').first().json.bot_id;\n\nconst notifyFailure = async (reason) => {\n  await this.helpers.httpRequest({\n    method: 'POST',\n    url: `https://api.telegram.org/bot${$env.TELEGRAM_BOT_TOKEN}/sendMessage`,\n    headers: { 'Content-Type': 'application/json' },\n    body: { chat_id: chatId, text: `\u274c \u5904\u7406\u5931\u8d25\uff1a${reason}` },\n    json: true\n  });\n};\n\n// \u68c0\u67e5\u8bf7\u6c42\u672c\u8eab\u662f\u5426\u5931\u8d25(\u7f51\u7edc\u9519\u8bef\u3001Gemini\u62d2\u7edd\u7b49)\nif (item.error || !item.candidates || item.candidates.length === 0) {\n  const errMsg = item.error?.message || '';\n  let reason = 'AI \u670d\u52a1\u6682\u65f6\u51fa\u73b0\u95ee\u9898\uff0c\u8bf7\u7a0d\u540e\u91cd\u8bd5\u3002';\n  if (errMsg.includes('quota') || errMsg.includes('rate') || errMsg.includes('429')) {\n    reason = 'AI \u8bf7\u6c42\u6b21\u6570\u5df2\u8fbe\u4e0a\u9650\uff0c\u8bf7\u7b49\u5f85\u7ea61\u5206\u949f\u540e\u91cd\u65b0\u53d1\u9001\u3002';\n  } else if (errMsg.includes('unavailable') || errMsg.includes('overload') || errMsg.includes('high demand') || errMsg.includes('503')) {\n    reason = 'AI \u670d\u52a1\u5668\u76ee\u524d\u6d41\u91cf\u8fc7\u9ad8\uff0c\u8bf7\u7b49\u5f85\u7ea61\u5206\u949f\u540e\u91cd\u65b0\u53d1\u9001\u3002';\n  }\n  await notifyFailure(reason);\n  return []; // \u5931\u8d25\u65f6\u4e0d\u5f80\u4e0b\u8d70,\u589e\u52a0\u4eca\u65e5\u6b21\u6570\u4e5f\u4e0d\u4f1a\u88ab\u89e6\u53d1\n}\n\nlet parsed;\ntry {\n  const rawText = item.candidates[0].content.parts[0].text;\n  const cleaned = rawText.replace(/```json\\n?/g, '').replace(/```\\n?/g, '').trim();\n  parsed = JSON.parse(cleaned);\n} catch (err) {\n  // Gemini\u5076\u5c14\u4f1a\u5939\u5e26\u89e3\u91ca\u6587\u5b57\u3001\u6216\u56de\u5e94\u7ed3\u6784\u8ddf\u9884\u671f\u4e0d\u4e00\u6837,JSON.parse\u4f1a\u76f4\u63a5throw,\n  // \u4e00\u5f8b\u63a5\u4f4f,\u4e0d\u8ba9\u6574\u4e2anode\u5d29\u6389\u3001\u5546\u5bb6\u6536\u4e0d\u5230\u4efb\u4f55\u56de\u5e94\n  await notifyFailure('AI\u56de\u5e94\u683c\u5f0f\u5f02\u5e38\uff0c\u8bf7\u91cd\u65b0\u53d1\u9001\u4e00\u6b21\u3002');\n  return [];\n}\n\nconst fileCount = $('\u6c47\u5408\u6210\u4e00\u4e2aitem\u7684Code node').first().json.fileCount;\nconst imagePaths = Array.from({length: fileCount}, (_, i) => `/home/node/files/session_${chatId}_${i}.jpg`);\n\nreturn [{\n  json: {\n    chat_id: chatId,\n    bot_id: botId,\n    status: parsed.status,\n    items: parsed.items || [],\n    question: parsed.question || '',\n    image_paths: JSON.stringify(imagePaths)\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -17840,
        -3696
      ],
      "id": "77fb4801-12fc-403a-a92e-1dedcfde6cbc",
      "name": "\u89e3\u6790Gemini\u56de\u5e94"
    },
    {
      "parameters": {
        "operation": "upsert",
        "dataTableId": {
          "__rl": true,
          "value": "xe1tWUcTzVf19IBn",
          "mode": "list",
          "cachedResultName": "daily_usage",
          "cachedResultUrl": "/projects/W1Bzh2H8JZecMoTf/datatables/xe1tWUcTzVf19IBn"
        },
        "filters": {
          "conditions": [
            {
              "keyName": "usage_key",
              "keyValue": "={{ $('\u5224\u65ad\u662f\u5426\u591f\u6b21\u6570').first().json.usage_key }}"
            }
          ]
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "usage_key": "={{ $('\u5224\u65ad\u662f\u5426\u591f\u6b21\u6570').first().json.usage_key }}",
            "bot_id": "={{ $('\u5224\u65ad\u662f\u5426\u591f\u6b21\u6570').first().json.bot_id }}",
            "date": "={{ $('\u5224\u65ad\u662f\u5426\u591f\u6b21\u6570').first().json.usage_date }}",
            "count": "={{ $('\u5224\u65ad\u662f\u5426\u591f\u6b21\u6570').first().json.current_count + 1 }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "usage_key",
              "displayName": "usage_key",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "bot_id",
              "displayName": "bot_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "date",
              "displayName": "date",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "count",
              "displayName": "count",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "readOnly": false,
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        -17664,
        -3696
      ],
      "id": "ae1af804-bfcb-4730-b048-70bca22b9e3d",
      "name": "\u589e\u52a0\u4eca\u65e5\u6b21\u6570"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "6510c025-e112-4112-9429-6cfb9fb605f6",
              "leftValue": "={{ $json.status }}",
              "rightValue": "complete",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        -17488,
        -3696
      ],
      "id": "73b1fa22-64f9-42de-bd68-191d4d530622",
      "name": "If"
    },
    {
      "parameters": {
        "workflowId": {
          "__rl": true,
          "value": "5m7xS062vlea0Cv3",
          "mode": "list",
          "cachedResultUrl": "/workflow/5m7xS062vlea0Cv3",
          "cachedResultName": "Tool - generate_excel_summary (V3)"
        },
        "workflowInputs": {
          "mappingMode": "defineBelow",
          "value": {
            "chat_id": "={{ $('If').item.json.chat_id }}",
            "items": "={{ JSON.stringify($('If').item.json.items) }}",
            "usage_count": "={{ $('If').item.json.usage_count }}",
            "usage_limit": "={{ $('If').item.json.usage_limit }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "chat_id",
              "displayName": "chat_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string"
            },
            {
              "id": "items",
              "displayName": "items",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string"
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        },
        "options": {}
      },
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1.3,
      "position": [
        -17296,
        -3712
      ],
      "id": "b6a4cedd-fbf8-4d9d-a37c-1e35a2944899",
      "name": "Call 'Tool - generate_excel_summary'"
    },
    {
      "parameters": {
        "workflowId": {
          "__rl": true,
          "value": "YRTFbyL20UDGMdPX",
          "mode": "list",
          "cachedResultUrl": "/workflow/YRTFbyL20UDGMdPX",
          "cachedResultName": "Tool - ask_clarifying_question (V3)"
        },
        "workflowInputs": {
          "mappingMode": "defineBelow",
          "value": {
            "chat_id": "={{ $json.chat_id }}",
            "question": "={{ $json.question }}",
            "context": "={{ JSON.stringify($json.items) }}",
            "bot_id": "={{ $json.bot_id }}",
            "image_paths": "={{ $json.image_paths }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "chat_id",
              "displayName": "chat_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string"
            },
            {
              "id": "question",
              "displayName": "question",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string"
            },
            {
              "id": "context",
              "displayName": "context",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string"
            },
            {
              "id": "bot_id",
              "displayName": "bot_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string"
            },
            {
              "id": "image_paths",
              "displayName": "image_paths",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string"
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        },
        "options": {}
      },
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1.3,
      "position": [
        -17280,
        -3312
      ],
      "id": "0759c438-cc4b-4595-88fc-826fe4b12848",
      "name": "Call 'Tool - ask_clarifying_question'"
    },
    {
      "parameters": {
        "inputSource": "passthrough"
      },
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion": 1.2,
      "position": [
        -21152,
        -3648
      ],
      "id": "f3e68155-fdae-4460-bad8-15032e09f1c7",
      "name": "When Executed by Another Workflow"
    },
    {
      "parameters": {
        "jsCode": "// \u4eceTrigger\u62ff\u5230Router\u6574\u7406\u597d\u7684\u6570\u636e\nconst chatId = $json.chat_id;\nconst caption = $json.caption;\nconst items = JSON.parse($json.items);\n\n// \u62c6\u5f00:photo/pdf\u9700\u8981\u4e0b\u8f7dbinary,text\u4e0d\u7528,\u53ea\u662f\u4e00\u6bb5\u6587\u5b57\u8bf4\u660e\nconst fileItems = items.filter(i => i.type === 'photo' || i.type === 'pdf' || i.type === 'excel');\nconst textItems = items.filter(i => i.type === 'text');\n\n// \u628a\u6240\u6709\u6587\u5b57\u7c7b\u578b\u7684\u5185\u5bb9,\u8ddfcaption(\u5907\u6ce8)\u5408\u5e76\u6210\u4e00\u6bb5\u8bf4\u660e,\n// \u4e4b\u540e\u8981\u585e\u8fdbGemini\u7684Prompt\u91cc,\u8ba9AI knows\u6709\u8fd9\u4e9b\u989d\u5916\u4fe1\u606f\nconst textContent = [caption, ...textItems.map(i => i.text_content)]\n  .filter(Boolean)\n  .join('\\n');\n\n// \u6709\u6863\u6848:\u6bcf\u4e2a\u9700\u8981\u4e0b\u8f7d\u7684\u6863\u6848\u5404\u81ea\u8f93\u51fa\u4e00\u4e2aitem,\u8ba9Get File\u81ea\u52a8\u4e00\u4e2a\u4e2a\u8dd1\nif (fileItems.length > 0) {\n  return fileItems.map(f => ({\n    json: {\n      chat_id: chatId,\n      text_content: textContent,\n      file_id: f.file_id,\n      mime_type: f.mime_type\n    }\n  }));\n}\n\n// \u7eaf\u6587\u5b57\u83dc\u5355,\u4e00\u5f20\u56fe/PDF\u90fd\u6ca1\u6709:\u8f93\u51fa\u4e00\u4e2a\u4e0d\u5e26\u6863\u6848\u7684item,\n// \u8ba9\u540e\u9762\u7684\u4e0b\u8f7d/PDF\u8f6c\u6863/\u5b58\u56fe\u8fd9\u6574\u6bb5\u539f\u6837\u8df3\u8fc7,\u76f4\u63a5\u8fdb\u6c47\u5408\u90a3\u6b65\nreturn [{\n  json: {\n    chat_id: chatId,\n    text_content: textContent,\n    file_id: null,\n    mime_type: null\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -20976,
        -3648
      ],
      "id": "c4207497-add4-4e11-97a2-c95550570491",
      "name": "\u89e3\u6790Router\u4f20\u6765\u7684items"
    },
    {
      "parameters": {
        "operation": "write",
        "fileName": "=/home/node/files/session_{{ $('\u89e3\u6790Router\u4f20\u6765\u7684items').first().json.chat_id }}_{{ $itemIndex }}.jpg",
        "options": {}
      },
      "type": "n8n-nodes-base.readWriteFile",
      "typeVersion": 1.1,
      "position": [
        -19344,
        -3312
      ],
      "id": "8a202f84-4be1-4133-aee0-0f8efd82076a",
      "name": "\u4fdd\u5b58\u539f\u56fe\u5230\u78c1\u76d8"
    },
    {
      "parameters": {
        "jsCode": "// \u6539\u7528$json\u76f4\u63a5\u6293,\u4e0d\u518d\u786c\u6307\u540dnode\u2014\u2014\u56e0\u4e3a\u8fd9\u4e00\u6b65\u5728Gemini\u8def\u5f84\u8ddfExcel\u8def\u5f84\n// \u90fd\u4f1a\u88ab\u6267\u884c\u5230,\u4e24\u6761\u8def\u5f84\u7684\u4e0a\u6e38node\u4e0d\u4e00\u6837,\u6307\u540d\u6293\u4f1a\u5728\u5176\u4e2d\u4e00\u6761\u8def\u5f84\u4e0a\u70b8\u6389\nconst decision = $json;\n\nreturn [{\n  json: {\n    chat_id: decision.chat_id,\n    bot_id: decision.bot_id,\n    items: JSON.stringify(decision.items),\n    image_paths: decision.image_paths, // \u4e0a\u6e38(\u89e3\u6790Gemini\u56de\u5e94/\u89e3\u6790Excel\u6a21\u677f)\u5df2\u7ecf\u662fJSON\u5b57\u7b26\u4e32,\u76f4\u63a5\u6cbf\u7528\n    awaiting_modification: true\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -17120,
        -3712
      ],
      "id": "79be4868-9b71-4e1f-888a-17009b288c05",
      "name": "\u7ec4\u88c5last_generation\u8d44\u6599"
    },
    {
      "parameters": {
        "operation": "upsert",
        "dataTableId": {
          "__rl": true,
          "value": "F8XZDNOad3tXgoQJ",
          "mode": "list",
          "cachedResultName": "last_generation"
        },
        "filters": {
          "conditions": [
            {
              "keyName": "chat_id",
              "keyValue": "={{ $json.chat_id }}"
            },
            {
              "keyName": "bot_id",
              "keyValue": "={{ $json.bot_id }}"
            }
          ]
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "chat_id": "={{ $json.chat_id }}",
            "bot_id": "={{ $json.bot_id }}",
            "items": "={{ $json.items }}",
            "image_paths": "={{ $json.image_paths }}",
            "awaiting_modification": true,
            "flagged_at": "={{ new Date().toISOString() }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "chat_id",
              "displayName": "chat_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "bot_id",
              "displayName": "bot_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "items",
              "displayName": "items",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "image_paths",
              "displayName": "image_paths",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "awaiting_modification",
              "displayName": "awaiting_modification",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "boolean",
              "readOnly": false,
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        -16912,
        -3712
      ],
      "id": "d74fa99e-d5e1-4f52-a246-fbd9fa8b21be",
      "name": "\u5199\u5165last_generation"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "87d4a921-b3f7-42f9-a9be-37dd8d23fa77",
              "leftValue": "={{ $json.file_id }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        -20768,
        -3648
      ],
      "id": "670a46ec-e89f-4604-b427-8e64f5d9f276",
      "name": "\u662f\u5426\u6709\u6863\u6848"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "9258d83c-dcf6-46cf-b8eb-d08f0252f18c",
              "leftValue": "={{ $('\u89e3\u6790Router\u4f20\u6765\u7684items').item.json.mime_type }}",
              "rightValue": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        -20272,
        -3776
      ],
      "id": "9d47c975-69ac-4789-8fe0-368435fd0318",
      "name": "\u662f\u5426\u4e3aExcel"
    },
    {
      "parameters": {
        "jsCode": "let items = [];\nlet missingList = [];\nlet parseError = null;\nlet needsAIMapping = false;\nlet headerRowRaw = null;\nlet rawRows = null;\n\ntry {\n  const buffer = await this.helpers.getBinaryDataBuffer(0, 'data');\n  const ExcelJS = require('exceljs');\n  const workbook = new ExcelJS.Workbook();\n  await workbook.xlsx.load(buffer);\n\n  // \u7528\u4f4d\u7f6e\u6293\u7b2c\u4e00\u4e2asheet,\u4e0d\u8981\u7528getWorksheet(1)\u2014\u2014\n  // getWorksheet(id)\u6293\u7684\u662fsheet\u7684\"\u5185\u90e8id\",\u4e0d\u662f\"\u7b2c\u4e00\u4e2asheet\"\u7684\u610f\u601d\u3002\n  // \u6709\u4e9b\u6863\u6848(\u5c24\u5176\u88ab\u522b\u7684\u5de5\u5177\u6c47\u51fa/\u7f16\u8f91\u8fc7\u7684)sheet id\u4e0d\u662f\u4ece1\u5f00\u59cb,\n  // getWorksheet(1)\u4f1a\u6293\u5230undefined,\u540e\u9762.getRow()\u5c31\u76f4\u63a5\u70b8\u3002\n  const ws = workbook.worksheets[0];\n\n  if (!ws) {\n    parseError = '\u6863\u6848\u91cc\u6ca1\u6709\u627e\u5230\u4efb\u4f55\u5de5\u4f5c\u8868(sheet),\u8bf7\u786e\u8ba4\u6863\u6848\u6ca1\u6709\u635f\u574f\u3002';\n  } else {\n    const headerRowValues = ws.getRow(1).values;\n    const headerMap = {};\n    headerRowValues.forEach((h, idx) => {\n      if (h) headerMap[h.toString().trim()] = idx;\n    });\n\n    const requiredHeaders = ['\u540d\u79f0\uff08\u5fc5\u586b\uff09', '\u5206\u7c7b\uff08\u5fc5\u586b\uff09', '\u9500\u552e\u4ef7\uff08\u5fc5\u586b\uff09'];\n    const hasAllRequired = requiredHeaders.every(h => headerMap[h]);\n\n    if (hasAllRequired) {\n      // \u8868\u5934\u6587\u5b57\u8ddf\u5b98\u65b9\u6a21\u677f\u5b8c\u5168\u5bf9\u4e0a,\u8d70\u539f\u672c\u7684\u5b57\u7b26\u4e32\u6bd4\u5bf9\u903b\u8f91,\u96f6AI\u6210\u672c\n      const getCell = (row, headerName) => {\n        const col = headerMap[headerName];\n        return col ? row.getCell(col).value : null;\n      };\n\n      for (let r = 2; r <= ws.rowCount; r++) {\n        const row = ws.getRow(r);\n        const name = getCell(row, '\u540d\u79f0\uff08\u5fc5\u586b\uff09');\n        if (!name) continue; // \u8df3\u8fc7\u7a7a\u884c\n\n        const category = getCell(row, '\u5206\u7c7b\uff08\u5fc5\u586b\uff09') || '';\n        const sell_price = getCell(row, '\u9500\u552e\u4ef7\uff08\u5fc5\u586b\uff09') ?? 0;\n\n        const missingFields = [];\n        if (!category) missingFields.push('\u5206\u7c7b');\n        if (!sell_price) missingFields.push('\u9500\u552e\u4ef7');\n        if (missingFields.length > 0) {\n          missingList.push(`\u7b2c${r}\u884c\u300c${name}\u300d\u7f3a\u5c11\uff1a${missingFields.join('\u3001')}`);\n        }\n\n        items.push({\n          name: name,\n          category: category,\n          spec: getCell(row, '\u89c4\u683c') || '',\n          stock_qty: getCell(row, '\u5e93\u5b58\u91cf') ?? '',\n          cost_price: getCell(row, '\u8fdb\u8d27\u4ef7\uff08\u5fc5\u586b\uff09') ?? 0,\n          sell_price: sell_price\n        });\n      }\n    } else {\n      // \u8868\u5934\u6587\u5b57\u8ddf\u5b98\u65b9\u6a21\u677f\u5bf9\u4e0d\u4e0a,\u4e0d\u76f4\u63a5\u653e\u5f03,\u4ea4\u7ed9\u4e0b\u4e00\u6b65AI\u505a\u680f\u4f4d\u5bf9\u7167\n      // \u8fd9\u91cc\u53ea\u62ff\u8868\u5934+\u5168\u90e8\u8d44\u6599\u5217(\u7eaf\u6587\u5b57/\u6570\u5b57),\u4e0d\u542b\u56fe\u7247/binary,\u8d44\u6599\u91cf\u5f88\u5c0f\n      needsAIMapping = true;\n      headerRowRaw = headerRowValues.slice(1); // \u53bb\u6389ExcelJS\u5f00\u5934\u90a3\u4e2a\u7a7a\u4f4d,\u53d8\u6210\u5e72\u51c0\u76840-index\u9635\u5217\n      rawRows = [];\n      for (let r = 2; r <= ws.rowCount; r++) {\n        const rowValues = ws.getRow(r).values.slice(1);\n        if (rowValues.some(v => v !== null && v !== undefined && v !== '')) {\n          rawRows.push(rowValues); // \u8df3\u8fc7\u5b8c\u5168\u7a7a\u767d\u7684\u5217\n        }\n      }\n    }\n  }\n} catch (err) {\n  // xlsx.load\u672c\u8eab\u4e5f\u53ef\u80fdthrow(\u6863\u6848\u635f\u574f\u3001\u52a0\u5bc6\u3001\u6839\u672c\u4e0d\u662fxlsx\u683c\u5f0f\u7b49),\n  // \u4e00\u5f8b\u63a5\u4f4f,\u4e0d\u8ba9\u6574\u4e2anode\u5d29\u6389\u3001\u5546\u5bb6\u6536\u4e0d\u5230\u4efb\u4f55\u56de\u5e94\n  parseError = err.message || '\u6863\u6848\u8bfb\u53d6\u5931\u8d25,\u683c\u5f0f\u53ef\u80fd\u4e0d\u652f\u63f4';\n}\n\nconst sourceData = $('\u89e3\u6790Router\u4f20\u6765\u7684items').first().json;\n\nlet status = '';\nlet question = '';\n\nif (!needsAIMapping) {\n  if (parseError) {\n    status = 'incomplete';\n    question = `\u274c \u6863\u6848\u5904\u7406\u5931\u8d25\uff1a${parseError}\\n\\n\u8bf7\u786e\u8ba4\u4f7f\u7528\u5b98\u65b9\u6a21\u677f\u3001\u6863\u6848\u6ca1\u6709\u635f\u574f,\u91cd\u65b0\u4e0a\u4f20,\u8c22\u8c22\uff01`;\n  } else {\n    const isComplete = items.length > 0 && missingList.length === 0;\n    status = isComplete ? 'complete' : 'incomplete';\n    if (items.length === 0) {\n      question = '\u6ca1\u6709\u5728\u6863\u6848\u4e2d\u8bc6\u522b\u5230\u4efb\u4f55\u5546\u54c1,\u8bf7\u786e\u8ba4\u4f7f\u7528\u7684\u662f\u5b98\u65b9\u6a21\u677f\u3001\u4e14\u8868\u5934\u540d\u79f0\u6ca1\u6709\u88ab\u4fee\u6539\u8fc7,\u8c22\u8c22\uff01';\n    } else if (!isComplete) {\n      const MAX_LIST = 15;\n      const shown = missingList.slice(0, MAX_LIST);\n      const remain = missingList.length - shown.length;\n      question = `\u83dc\u5355\u4e2d\u6709\u4e9b\u5fc5\u586b\u680f\u4f4d\u8fd8\u6ca1\u586b\u9f50\uff1a\\n${shown.join('\\n')}`\n        + (remain > 0 ? `\\n...\u8fd8\u6709 ${remain} \u9879\u4e5f\u9700\u8981\u8865\u5145` : '')\n        + `\\n\\n\u8bf7\u76f4\u63a5\u56de\u8986\u8865\u5145,\u6216\u8865\u5145\u5b8c\u6574\u540e\u91cd\u65b0\u4e0a\u4f20,\u8c22\u8c22\uff01`;\n    }\n  }\n}\n\nreturn [{\n  json: {\n    chat_id: sourceData.chat_id,\n    bot_id: 'worker1', // Excel\u8fd9\u6761\u8def\u8df3\u8fc7\u4e86\u8282\u6d41\u6d41\u7a0b,\u8fd9\u91cc\u8981\u91cd\u590d\u5b9a\u4e49\u540c\u4e00\u4e2a\u5e38\u6570\n    needsAIMapping: needsAIMapping,\n    headerRowRaw: headerRowRaw,\n    rawRows: rawRows,\n    status: status,\n    items: items,\n    question: question,\n    image_paths: '[]' // Excel\u8fd9\u6761\u8def\u6ca1\u6709\u56fe\u7247,\u7ed9\u7a7a\u9635\u5217,\u8ddfGemini\u90a3\u6761\u8def\u8f93\u51fa\u683c\u5f0f\u4fdd\u6301\u4e00\u81f4\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -19952,
        -3920
      ],
      "id": "4c09ce24-4836-4353-8d1a-7be2e641f393",
      "name": "\u89e3\u6790Excel\u6a21\u677f"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "9f03b078-4bee-435d-91cd-b55b5b0a4cd6",
              "leftValue": "={{ $json.needsAIMapping }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        -19692,
        -3920
      ],
      "id": "8fd461a4-6801-4cad-92da-2465f3b1ac2b",
      "name": "\u662f\u5426\u9700\u8981AI\u680f\u4f4d\u5bf9\u7167"
    },
    {
      "parameters": {
        "jsCode": "const trigger = $json;\n\nconst promptText = `\u4f60\u662f\u4e00\u4e2aExcel\u8868\u5934\u5bf9\u7167\u52a9\u624b\u3002\u4ee5\u4e0b\u662f\u4e00\u4efdExcel\u6863\u6848\u7684\u8868\u5934\u680f\u4f4d,\u4ee5\u53ca\u90e8\u5206\u6837\u672c\u8d44\u6599\u3002\n\n\u8868\u5934\u680f\u4f4d\uff08\u4f9d\u5e8f,index\u4ece0\u5f00\u59cb\uff09\uff1a\n${JSON.stringify(trigger.headerRowRaw)}\n\n\u6837\u672c\u8d44\u6599\uff08\u524d\u51e0\u884c,\u4f9d\u5e8f\u5bf9\u5e94\u4e0a\u9762\u680f\u4f4d\uff09\uff1a\n${JSON.stringify(trigger.rawRows.slice(0, 3))}\n\n\u8bf7\u5224\u65ad\u8fd9\u4efd\u8868\u683c\u91cc,\u54ea\u4e00\u680f\u5bf9\u5e94\u4ee5\u4e0b\u6211\u4eec\u9700\u8981\u7684\u680f\u4f4d,\u7528\u680f\u4f4d\u5728\u9635\u5217\u4e2d\u7684index\u8868\u793a\uff08\u4ece0\u5f00\u59cb\uff09\uff1b\n\u5982\u679c\u8fd9\u4efd\u8868\u683c\u6839\u672c\u6ca1\u6709\u5bf9\u5e94\u7684\u680f\u4f4d,\u8be5\u9879\u76ee\u586b-1,\u4e0d\u8981\u4e71\u731c\uff1a\n- name: \u5546\u54c1/\u54c1\u9879\u540d\u79f0\n- category: \u5546\u54c1\u5206\u7c7b\n- sell_price: \u9500\u552e\u4ef7\u683c/\u5355\u4ef7\n- spec: \u89c4\u683c(\u9009\u586b)\n- stock_qty: \u5e93\u5b58\u6570\u91cf(\u9009\u586b)\n- cost_price: \u8fdb\u8d27\u4ef7/\u6210\u672c\u4ef7(\u9009\u586b)\n\n\u8bf7\u4e25\u683c\u53ea\u8f93\u51fa\u4ee5\u4e0bJSON\u683c\u5f0f,\u4e0d\u8981\u4efb\u4f55\u89e3\u91ca\u6587\u5b57\u3001\u4e0d\u8981markdown\u4ee3\u7801\u5757\u6807\u8bb0\uff1a\n{\n  \"name\": 0,\n  \"category\": -1,\n  \"sell_price\": 2,\n  \"spec\": -1,\n  \"stock_qty\": -1,\n  \"cost_price\": -1\n}`;\n\nconst geminiRequest = { contents: [{ parts: [{ text: promptText }] }] };\n\nreturn [{\n  json: {\n    chat_id: trigger.chat_id,\n    bot_id: trigger.bot_id,\n    headerRowRaw: trigger.headerRowRaw,\n    rawRows: trigger.rawRows,\n    geminiRequest: geminiRequest\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -19692,
        -3680
      ],
      "id": "ab3bf70e-22a6-42e3-aeb2-70df083a2e72",
      "name": "\u7ec4\u88c5\u8868\u5934\u5bf9\u7167\u8bf7\u6c42"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.5-flash:generateContent",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpQueryAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ $json.geminiRequest }}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        -19452,
        -3680
      ],
      "id": "91c0a7be-d8e2-47e0-8b4c-847c55fdf429",
      "name": "HTTP Request \u8868\u5934\u5bf9\u7167Gemini",
      "credentials": {
        "httpQueryAuth": {
          "name": "<your credential>"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "const source = $('\u7ec4\u88c5\u8868\u5934\u5bf9\u7167\u8bf7\u6c42').first().json;\nconst item = $input.first().json;\n\nlet mapping = null;\nlet aiError = null;\n\nif (item.error || !item.candidates) {\n  aiError = item.error?.message || 'AI\u670d\u52a1\u6682\u65f6\u65e0\u6cd5\u4f7f\u7528';\n} else {\n  try {\n    const rawText = item.candidates[0].content.parts[0].text;\n    const cleaned = rawText.replace(/```json\\n?/g, '').replace(/```\\n?/g, '').trim();\n    mapping = JSON.parse(cleaned);\n  } catch (e) {\n    aiError = 'AI\u56de\u5e94\u683c\u5f0f\u65e0\u6cd5\u89e3\u6790';\n  }\n}\n\nconst hasRequiredMapping = mapping &&\n  mapping.name >= 0 && mapping.category >= 0 && mapping.sell_price >= 0;\n\nlet items = [];\nlet missingList = [];\nlet question = '';\nlet status = 'incomplete';\n\nif (!hasRequiredMapping) {\n  // AI\u4e5f\u5224\u65ad\u4e0d\u51fa\u5bf9\u5e94\u680f\u4f4d(\u6216AI\u547c\u53eb\u672c\u8eab\u5931\u8d25\u4e86),\u4e0d\u786c\u731c,\u793c\u8c8c\u62d2\u7edd,\u4e0d\u4ea7\u751f\u9519\u8bef\u8d44\u6599\n  question = aiError\n    ? `\u6863\u6848\u8868\u5934\u65e0\u6cd5\u81ea\u52a8\u8bc6\u522b(${aiError}),\u8bf7\u4f7f\u7528\u5b98\u65b9\u6a21\u677f\u91cd\u65b0\u4e0a\u4f20,\u8c22\u8c22\uff01`\n    : '\u6ca1\u6709\u5728\u6863\u6848\u4e2d\u8bc6\u522b\u5230\u5546\u54c1\u540d\u79f0/\u5206\u7c7b/\u9500\u552e\u4ef7\u5bf9\u5e94\u7684\u680f\u4f4d,\u8bf7\u786e\u8ba4\u4f7f\u7528\u7684\u662f\u5b98\u65b9\u6a21\u677f,\u8c22\u8c22\uff01';\n} else {\n  const rawRows = source.rawRows;\n  for (let i = 0; i < rawRows.length; i++) {\n    const row = rawRows[i];\n    const name = mapping.name >= 0 ? row[mapping.name] : null;\n    if (!name) continue; // \u8df3\u8fc7\u7a7a\u884c\n\n    const category = mapping.category >= 0 ? (row[mapping.category] || '') : '';\n    const sell_price = mapping.sell_price >= 0 ? (row[mapping.sell_price] ?? 0) : 0;\n\n    const missingFields = [];\n    if (!category) missingFields.push('\u5206\u7c7b');\n    if (!sell_price) missingFields.push('\u9500\u552e\u4ef7');\n    if (missingFields.length > 0) {\n      missingList.push(`\u7b2c${i + 2}\u884c\u300c${name}\u300d\u7f3a\u5c11\uff1a${missingFields.join('\u3001')}`);\n    }\n\n    items.push({\n      name: name,\n      category: category,\n      spec: mapping.spec >= 0 ? (row[mapping.spec] || '') : '',\n      stock_qty: mapping.stock_qty >= 0 ? (row[mapping.stock_qty] ?? '') : '',\n      cost_price: mapping.cost_price >= 0 ? (row[mapping.cost_price] ?? 0) : 0,\n      sell_price: sell_price\n    });\n  }\n\n  const isComplete = items.length > 0 && missingList.length === 0;\n  status = isComplete ? 'complete' : 'incomplete';\n\n  if (items.length === 0) {\n    question = '\u867d\u7136AI\u8bc6\u522b\u51fa\u4e86\u680f\u4f4d\u5bf9\u7167,\u4f46\u6863\u6848\u5185\u5bb9\u662f\u7a7a\u7684,\u8bf7\u786e\u8ba4\u6863\u6848\u5185\u5bb9,\u8c22\u8c22\uff01';\n  } else if (!isComplete) {\n    const MAX_LIST = 15;\n    const shown = missingList.slice(0, MAX_LIST);\n    const remain = missingList.length - shown.length;\n    question = `\u8fd9\u4efd\u6863\u6848\u7684\u8868\u5934\u683c\u5f0f\u8ddf\u5b98\u65b9\u6a21\u677f\u4e0d\u540c,\u5df2\u7ecf\u81ea\u52a8\u5e2e\u60a8\u5bf9\u7167\u680f\u4f4d\u3002\u83dc\u5355\u4e2d\u6709\u4e9b\u5fc5\u586b\u680f\u4f4d\u8fd8\u6ca1\u586b\u9f50\uff1a\\n${shown.join('\\n')}`\n      + (remain > 0 ? `\\n...\u8fd8\u6709 ${remain} \u9879\u4e5f\u9700\u8981\u8865\u5145` : '')\n      + `\\n\\n\u8bf7\u76f4\u63a5\u56de\u8986\u8865\u5145,\u6216\u8865\u5145\u5b8c\u6574\u540e\u91cd\u65b0\u4e0a\u4f20,\u8c22\u8c22\uff01`;\n  }\n}\n\nreturn [{\n  json: {\n    chat_id: source.chat_id,\n    bot_id: source.bot_id,\n    status: status,\n    items: items,\n    question: question,\n    image_paths: '[]'\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -19212,
        -3680
      ],
      "id": "1a940671-d310-4460-87b0-0344b2539266",
      "name": "\u89e3\u6790\u8868\u5934\u5bf9\u7167\u56de\u5e94"
    },
    {
      "parameters": {
        "jsCode": "return [{ json: { ...$('\u89e3\u6790Gemini\u56de\u5e94').item.json, usage_count: $json.count, usage_limit: 15 } }];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -17444,
        -3696
      ],
      "id": "84fc2413-99e7-4d94-b15c-efa8177e2156",
      "name": "\u8fd8\u539fGemini\u5224\u65ad\u7ed3\u679c"
    },
    {
      "parameters": {
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "value": "hzaSbVDXvHGFBfh7",
          "mode": "list",
          "cachedResultName": "merchant_feedback"
        },
        "filters": {
          "conditions": [
            {
              "keyName": "chat_id",
              "keyValue": "={{ $('\u6c47\u5408\u6210\u4e00\u4e2aitem\u7684Code node').first().json.chat_id }}"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        -18412,
        -3696
      ],
      "id": "420293e6-3aa3-4f8d-a012-26f5e3ddd376",
      "name": "\u67e5\u5546\u5bb6\u8bc4\u5206",
      "alwaysOutputData": true
    }
  ],
  "connections": {
    "HTTP Request - Telegram Get File": {
      "main": [
        [
          {
            "node": "HTTP Request - Telegram Download File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request - Telegram Download File": {
      "main": [
        [
          {
            "node": "\u662f\u5426\u4e3aExcel",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u4fee\u6b63\u56fe\u7247MimeType": {
      "main": [
        [
          {
            "node": "\u4fdd\u5b58\u539f\u56fe\u5230\u78c1\u76d8",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u6c47\u5408\u6210\u4e00\u4e2aitem\u7684Code node": {
      "main": [
        [
          {
            "node": "\u7b97\u51fausage_key",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u662f\u5426\u4e3aPDF": {
      "main": [
        [
          {
            "node": "\u5199\u5165PDF\u5230\u78c1\u76d8",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\u4fee\u6b63\u56fe\u7247MimeType",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u5199\u5165PDF\u5230\u78c1\u76d8": {
      "main": [
        [
          {
            "node": "Execute Command",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute Command": {
      "main": [
        [
          {
            "node": "Read/Write Files from Disk",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read/Write Files from Disk": {
      "main": [
        [
          {
            "node": "\u4fee\u6b63\u56fe\u7247MimeType",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u7b97\u51fausage_key": {
      "main": [
        [
          {
            "node": "\u67e5\u770busage_key",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u67e5\u770busage_key": {
      "main": [
        [
          {
            "node": "\u5224\u65ad\u662f\u5426\u591f\u6b21\u6570",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u662f\u5426\u591f\u6b21\u6570": {
      "main": [
        [
          {
            "node": "\u7ec4\u88c5Gemini\u8bf7\u6c42",
            "type": "main",
            "index": 0
          },
          {
            "node": "\u67e5\u5546\u5bb6\u8bc4\u5206",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\u53d1\u9001\u989d\u5ea6\u5df2\u6ee1\u8baf\u606f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u5224\u65ad\u662f\u5426\u591f\u6b21\u6570": {
      "main": [
        [
          {
            "node": "\u662f\u5426\u591f\u6b21\u6570",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u7ec4\u88c5Gemini\u8bf7\u6c42": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "main": [
        [
          {
            "node": "\u89e3\u6790Gemini\u56de\u5e94",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u89e3\u6790Gemini\u56de\u5e94": {
      "main": [
        [
          {
            "node": "\u589e\u52a0\u4eca\u65e5\u6b21\u6570",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u589e\u52a0\u4eca\u65e5\u6b21\u6570": {
      "main": [
        [
          {
            "node": "\u8fd8\u539fGemini\u5224\u65ad\u7ed3\u679c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If": {
      "main": [
        [
          {
            "node": "\u7ec4\u88c5last_generation\u8d44\u6599",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Call 'Tool - ask_clarifying_question'",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Executed by Another Workflow": {
      "main": [
        [
          {
            "node": "\u89e3\u6790Router\u4f20\u6765\u7684items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u89e3\u6790Router\u4f20\u6765\u7684items": {
      "main": [
        [
          {
            "node": "\u662f\u5426\u6709\u6863\u6848",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u4fdd\u5b58\u539f\u56fe\u5230\u78c1\u76d8": {
      "main": [
        [
          {
            "node": "\u6c47\u5408\u6210\u4e00\u4e2aitem\u7684Code node",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u7ec4\u88c5last_generation\u8d44\u6599": {
      "main": [
        [
          {
            "node": "\u5199\u5165last_generation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u662f\u5426\u6709\u6863\u6848": {
      "main": [
        [
          {
            "node": "HTTP Request - Telegram Get File",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\u6c47\u5408\u6210\u4e00\u4e2aitem\u7684Code node",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u662f\u5426\u4e3aExcel": {
      "main": [
        [
          {
            "node": "\u89e3\u6790Excel\u6a21\u677f",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\u662f\u5426\u4e3aPDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u89e3\u6790Excel\u6a21\u677f": {
      "main": [
        [
          {
            "node": "\u662f\u5426\u9700\u8981AI\u680f\u4f4d\u5bf9\u7167",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u662f\u5426\u9700\u8981AI\u680f\u4f4d\u5bf9\u7167": {
      "main": [
        [
          {
            "node": "\u7ec4\u88c5\u8868\u5934\u5bf9\u7167\u8bf7\u6c42",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u7ec4\u88c5\u8868\u5934\u5bf9\u7167\u8bf7\u6c42": {
      "main": [
        [
          {
            "node": "HTTP Request \u8868\u5934\u5bf9\u7167Gemini",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request \u8868\u5934\u5bf9\u7167Gemini": {
      "main": [
        [
          {
            "node": "\u89e3\u6790\u8868\u5934\u5bf9\u7167\u56de\u5e94",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u89e3\u6790\u8868\u5934\u5bf9\u7167\u56de\u5e94": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u8fd8\u539fGemini\u5224\u65ad\u7ed3\u679c": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u5199\u5165last_generation": {
      "main": [
        [
          {
            "node": "Call 'Tool - generate_excel_summary'",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate",
    "availableInMCP": false
  },
  "versionId": "3653b343-5989-4987-8d5b-bc65389acc26",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodeGroups": [],
  "id": "oyJXEnSwAiux2k4C",
  "tags": [
    {
      "updatedAt": "2026-07-27T07:50:01.682Z",
      "createdAt": "2026-07-27T07:50:01.682Z",
      "id": "oulTjbe8ViVdh1V7",
      "name": "AUTO-P1-V3"
    },
    {
      "updatedAt": "2026-07-20T07:40:54.445Z",
      "createdAt": "2026-07-20T07:40:54.445Z",
      "id": "sBao71AvdSJ3hx2O",
      "name": "3FS"
    }
  ]
}

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

DEEPP AUTO P1 V3 - Worker (Front). Uses httpRequest, readWriteFile, executeCommand, dataTable. Event-driven trigger; 34 nodes.

Source: https://github.com/Heng1028/pos-telegrambot-v3/blob/main/worker-front-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

DEEPP AUTO P1 V3 - Worker (Back). Uses executeWorkflowTrigger, readWriteFile, httpRequest, dataTable. Event-driven trigger; 20 nodes.

Execute Workflow Trigger, Read Write File, HTTP Request +1
Slack & Telegram

Transcript. Uses httpRequest, telegram, telegramTrigger, readWriteFile. Event-driven trigger; 37 nodes.

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

This workflow contains community nodes that are only compatible with the self-hosted version of n8n.

Telegram Trigger, n8n, Telegram +4
Slack & Telegram

A — Приём и перевод (Челлендж 200 дней). Uses executeWorkflowTrigger, telegram, httpRequest, executeCommand. Event-driven trigger; 32 nodes.

Execute Workflow Trigger, Telegram, HTTP Request +5
Slack & Telegram

Template was created in n8n v1.90.2 Execute Sub-workflow Trigger node Chat Trigger node Redis node Postgres node Telegram node HTTP Request node If node, Code node, Edit Fields (Set) Execute Sub-workf

Execute Workflow Trigger, Chat Trigger, HTTP Request +3