{
  "id": "ZrMZ6kmAjmMVe3MWBht-W",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Manage Supabase database with Telegram commands",
  "tags": [],
  "nodes": [
    {
      "id": "489db1e4-058f-4c8a-b570-6aec40dbe3a5",
      "name": "Telegram Trigger",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        -1840,
        368
      ],
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "c42dbc91-8b38-422c-9121-6a1bb1171097",
      "name": "Extract Message Data",
      "type": "n8n-nodes-base.set",
      "position": [
        -1616,
        368
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "field-chatId",
              "name": "chatId",
              "type": "number",
              "value": "={{ $json.message.chat.id }}"
            },
            {
              "id": "field-text",
              "name": "text",
              "type": "string",
              "value": "={{ $json.message.text }}"
            },
            {
              "id": "field-firstName",
              "name": "firstName",
              "type": "string",
              "value": "={{ $json.message.from.first_name }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "0c7cf41a-0950-4985-88e5-26e5c79305e7",
      "name": "Is Authorized?",
      "type": "n8n-nodes-base.if",
      "position": [
        -1392,
        368
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "condition-auth-1",
              "operator": {
                "type": "number",
                "operation": "equals"
              },
              "leftValue": "={{ $json.chatId }}",
              "rightValue": 123456789
            },
            {
              "id": "condition-auth-2",
              "operator": {
                "type": "number",
                "operation": "equals"
              },
              "leftValue": "={{ $json.chatId }}",
              "rightValue": 987654321
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "28e1ac01-179b-4203-8e2a-a6d5edaf31f9",
      "name": "Parse Command and Parameters",
      "type": "n8n-nodes-base.code",
      "position": [
        -1168,
        368
      ],
      "parameters": {
        "jsCode": "/*\n * Parse Telegram Command\n * ======================\n * Purpose: Extracts the command and parameters from the Telegram message.\n *          Supports: /add, /list, /get, /update, /delete, /search, /help\n * \n * Input: Telegram message text\n * Output: Parsed command object with command name and parameters\n */\n\nconst text = $input.first().json.text || '';\nconst chatId = $input.first().json.chatId;\n\nconst commandMatch = text.match(/^\\/([a-z]+)/i);\nconst command = commandMatch ? commandMatch[1].toLowerCase() : 'unknown';\nconst paramsText = text.replace(/^\\/[a-z]+\\s*/i, '').trim();\n\nlet parsed = {\n  command: command,\n  chatId: chatId,\n  rawParams: paramsText,\n  params: {}\n};\n\nswitch (command) {\n  case 'add':\n    const addParts = paramsText.split(',').map(p => p.trim());\n    if (addParts.length >= 4) {\n      parsed.params = {\n        name: addParts[0],\n        price: parseFloat(addParts[1]) || 0,\n        quantity: parseInt(addParts[2]) || 0,\n        category: addParts[3]\n      };\n    } else {\n      parsed.params.error = 'Invalid format. Use: /add name, price, quantity, category';\n    }\n    break;\n  case 'list':\n    parsed.params.category = paramsText || null;\n    break;\n  case 'get':\n    parsed.params.id = parseInt(paramsText) || null;\n    if (!parsed.params.id) parsed.params.error = 'Invalid format. Use: /get id';\n    break;\n  case 'update':\n    const updateParts = paramsText.split(' ');\n    parsed.params.id = parseInt(updateParts[0]) || null;\n    parsed.params.updates = {};\n    if (parsed.params.id) {\n      for (let i = 1; i < updateParts.length; i++) {\n        const [field, value] = updateParts[i].split('=');\n        if (field && value !== undefined) {\n          if (field === 'price') parsed.params.updates[field] = parseFloat(value);\n          else if (field === 'quantity') parsed.params.updates[field] = parseInt(value);\n          else parsed.params.updates[field] = value;\n        }\n      }\n      if (Object.keys(parsed.params.updates).length === 0) {\n        parsed.params.error = 'No valid updates. Use: /update id field=value';\n      }\n    } else {\n      parsed.params.error = 'Invalid format. Use: /update id field=value';\n    }\n    break;\n  case 'delete':\n    parsed.params.id = parseInt(paramsText) || null;\n    if (!parsed.params.id) parsed.params.error = 'Invalid format. Use: /delete id';\n    break;\n  case 'search':\n    parsed.params.searchText = paramsText;\n    if (!paramsText) parsed.params.error = 'Invalid format. Use: /search text';\n    break;\n  case 'help':\n    break;\n  default:\n    parsed.params.error = 'Unknown command. Use /help to see available commands.';\n}\n\nreturn [{ json: parsed }];"
      },
      "typeVersion": 2
    },
    {
      "id": "c591a0af-a344-4a68-acdc-9fb79a43fdf5",
      "name": "Route by Command",
      "type": "n8n-nodes-base.switch",
      "position": [
        -944,
        272
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "add",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "b56d6ee5-28ed-4bdb-b8fa-4ca2180a66a9",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.command }}",
                    "rightValue": "add"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "list",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "95a0ed9b-9638-4e21-9c19-f2397499da93",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.command }}",
                    "rightValue": "list"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "get",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "275caeec-ffe6-40d2-8556-0889df27746c",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.command }}",
                    "rightValue": "get"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "update",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "0e0e9994-9efa-4a91-ae90-9680217ba67e",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.command }}",
                    "rightValue": "update"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "delete",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "7874ddd3-8c0f-4851-b5e7-c69c35761179",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.command }}",
                    "rightValue": "delete"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "search",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "5c96f930-9866-4f54-abf9-5ccef8ed8717",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.command }}",
                    "rightValue": "search"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "help",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "07cf0917-9987-4330-ab8f-34aa15c59a73",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.command }}",
                    "rightValue": "help"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "typeVersion": 3.2
    },
    {
      "id": "2d73fe4d-5cc1-4a09-ba63-d42bd5e885cb",
      "name": "Add Has Error?",
      "type": "n8n-nodes-base.if",
      "position": [
        -720,
        -976
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition-error",
              "operator": {
                "type": "string",
                "operation": "exists"
              },
              "leftValue": "={{ $json.params.error }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "55fb6dea-5fd1-40e1-8f15-5adda8057f28",
      "name": "Supabase Insert Product",
      "type": "n8n-nodes-base.supabase",
      "position": [
        -496,
        -880
      ],
      "parameters": {
        "tableId": "products",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldValue": "={{ $json.params.name }}"
            },
            {
              "fieldValue": "={{ $json.params.price }}"
            },
            {
              "fieldValue": "={{ $json.params.quantity }}"
            },
            {
              "fieldValue": "={{ $json.params.category }}"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "1b62e61f-dfad-4c95-8dde-5f8496e1295b",
      "name": "Send Add Success",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -272,
        -880
      ],
      "parameters": {
        "text": "=\u2705 Product added successfully!\n\n\ud83d\udce6 Name: {{ $json.name }}\n\ud83d\udcb0 Price: ${{ $json.price }}\n\ud83d\udcca Quantity: {{ $json.quantity }}\n\ud83c\udff7\ufe0f Category: {{ $json.category }}\n\ud83c\udd94 ID: {{ $json.id }}",
        "chatId": "={{ $('Parse Command and Parameters').item.json.chatId }}",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "c4623db7-78b7-453c-bb8e-49748cb7ec35",
      "name": "Send Add Error",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -496,
        -1072
      ],
      "parameters": {
        "text": "=\u274c Error: {{ $json.params.error }}\n\n\ud83d\udcdd Correct format:\n/add name, price, quantity, category\n\nExample:\n/add iPhone 15, 999.99, 50, electronics",
        "chatId": "={{ $json.chatId }}",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "687c5ea4-d7f8-4eb3-ab17-2dfb77b0fe3b",
      "name": "Filter by Category?",
      "type": "n8n-nodes-base.if",
      "position": [
        -720,
        -592
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition-category",
              "operator": {
                "type": "string",
                "operation": "exists"
              },
              "leftValue": "={{ $json.params.category }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "4f0e9584-9da4-443d-9d39-06b201a4fde2",
      "name": "Supabase List Filtered",
      "type": "n8n-nodes-base.supabase",
      "position": [
        -496,
        -688
      ],
      "parameters": {
        "tableId": "products",
        "operation": "getAll",
        "returnAll": true,
        "filterType": "string",
        "filterString": "category=eq.{{ $json.params.category }}"
      },
      "typeVersion": 1
    },
    {
      "id": "1f2f0ffa-a240-48c4-959d-998b662e194c",
      "name": "Supabase List All",
      "type": "n8n-nodes-base.supabase",
      "position": [
        -496,
        -496
      ],
      "parameters": {
        "tableId": "products",
        "operation": "getAll",
        "returnAll": true
      },
      "typeVersion": 1
    },
    {
      "id": "740c9210-44dc-4cd6-9f76-44d2170018bc",
      "name": "Format Product List",
      "type": "n8n-nodes-base.code",
      "position": [
        -272,
        -592
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nconst chatId = $('Parse Command and Parameters').first().json.chatId;\nconst category = $('Parse Command and Parameters').first().json.params.category;\n\nif (items.length === 0) {\n  return [{\n    json: {\n      chatId: chatId,\n      message: category \n        ? `\ud83d\udced No products found in category \"${category}\"`\n        : '\ud83d\udced No products in database'\n    }\n  }];\n}\n\nlet message = category \n  ? `\ud83d\udce6 Products in \"${category}\" (${items.length}):\\n\\n`\n  : `\ud83d\udce6 All Products (${items.length}):\\n\\n`;\n\nitems.forEach((item, index) => {\n  const p = item.json;\n  message += `${index + 1}. [ID: ${p.id}] ${p.name}\\n`;\n  message += `   \ud83d\udcb0 $${p.price} | \ud83d\udcca Qty: ${p.quantity} | \ud83c\udff7\ufe0f ${p.category}\\n\\n`;\n});\n\nreturn [{ json: { chatId, message } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "98596398-5e01-45f6-9c0b-3da66360eab5",
      "name": "Send Product List",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -48,
        -592
      ],
      "parameters": {
        "text": "={{ $json.message }}",
        "chatId": "={{ $json.chatId }}",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "ba38d3a8-ccb3-4c4f-9109-9a9538e246d8",
      "name": "Get Has Error?",
      "type": "n8n-nodes-base.if",
      "position": [
        -720,
        -208
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition-error-get",
              "operator": {
                "type": "string",
                "operation": "exists"
              },
              "leftValue": "={{ $json.params.error }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "50649ea2-0d2e-402d-a9f4-d03294922ddb",
      "name": "Supabase Get Product",
      "type": "n8n-nodes-base.supabase",
      "position": [
        -512,
        -112
      ],
      "parameters": {
        "limit": 1,
        "tableId": "products",
        "operation": "getAll",
        "filterType": "string",
        "filterString": "id=eq.{{ $json.params.id }}"
      },
      "typeVersion": 1
    },
    {
      "id": "8f30e94f-162c-4bc7-ba5b-6a653361adfd",
      "name": "Send Product Details",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -288,
        -112
      ],
      "parameters": {
        "text": "=\ud83d\udce6 Product Details:\n\n\ud83c\udd94 ID: {{ $json.id }}\n\ud83d\udce6 Name: {{ $json.name }}\n\ud83d\udcb0 Price: ${{ $json.price }}\n\ud83d\udcca Quantity: {{ $json.quantity }}\n\ud83c\udff7\ufe0f Category: {{ $json.category }}",
        "chatId": "={{ $('Parse Command and Parameters').item.json.chatId }}",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "fe7e3537-d833-4533-a271-54ccec98f9af",
      "name": "Send Get Error",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -512,
        -304
      ],
      "parameters": {
        "text": "=\u274c Error: {{ $json.params.error }}\n\n\ud83d\udcdd Correct format:\n/get id\n\nExample:\n/get 15",
        "chatId": "={{ $json.chatId }}",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "68c690c1-54b1-4330-87aa-eb525b58b259",
      "name": "Update Has Error?",
      "type": "n8n-nodes-base.if",
      "position": [
        -720,
        176
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition-error-update",
              "operator": {
                "type": "string",
                "operation": "exists"
              },
              "leftValue": "={{ $json.params.error }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c17faffe-664c-4ebe-beba-eb6a1d0d106c",
      "name": "Prepare Update Data",
      "type": "n8n-nodes-base.set",
      "position": [
        -512,
        288
      ],
      "parameters": {
        "options": {
          "ignoreConversionErrors": true
        },
        "assignments": {
          "assignments": [
            {
              "id": "update-id",
              "name": "id",
              "type": "number",
              "value": "={{ $json.params.id }}"
            },
            {
              "id": "update-name",
              "name": "name",
              "type": "string",
              "value": "={{ $json.params.updates.name }}"
            },
            {
              "id": "update-price",
              "name": "price",
              "type": "number",
              "value": "={{ $json.params.updates.price }}"
            },
            {
              "id": "update-quantity",
              "name": "quantity",
              "type": "number",
              "value": "={{ $json.params.updates.quantity }}"
            },
            {
              "id": "update-category",
              "name": "category",
              "type": "string",
              "value": "={{ $json.params.updates.category }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "2fb60504-55bf-44bb-827e-509a6094f824",
      "name": "Supabase Update Product",
      "type": "n8n-nodes-base.supabase",
      "position": [
        -288,
        288
      ],
      "parameters": {
        "tableId": "products",
        "operation": "update",
        "filterType": "string",
        "filterString": "id=eq.{{ $json.id }}"
      },
      "typeVersion": 1
    },
    {
      "id": "569b1d21-1f0d-4efb-beb8-a380696e6a8c",
      "name": "Send Update Success",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -64,
        288
      ],
      "parameters": {
        "text": "=\u2705 Product updated successfully!\n\n\ud83c\udd94 ID: {{ $json.id }}\nUpdated fields have been saved.",
        "chatId": "={{ $('Parse Command and Parameters').item.json.chatId }}",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "adb1157b-a0f7-40c7-983d-c9e6e4049889",
      "name": "Send Update Error",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -528,
        112
      ],
      "parameters": {
        "text": "=\u274c Error: {{ $json.params.error }}\n\n\ud83d\udcdd Correct format:\n/update id field=value field=value\n\nExample:\n/update 15 price=899 quantity=45\n\nValid fields: name, price, quantity, category",
        "chatId": "={{ $json.chatId }}",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "5c85a5e0-c854-48b0-884b-9de3500d1cff",
      "name": "Delete Has Error?",
      "type": "n8n-nodes-base.if",
      "position": [
        -720,
        560
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition-error-delete",
              "operator": {
                "type": "string",
                "operation": "exists"
              },
              "leftValue": "={{ $json.params.error }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "2b747995-9ad7-45af-83aa-52e29b8d1a67",
      "name": "Supabase Delete Product",
      "type": "n8n-nodes-base.supabase",
      "position": [
        -496,
        656
      ],
      "parameters": {
        "tableId": "products",
        "operation": "delete",
        "filterType": "string",
        "filterString": "id=eq.{{ $json.params.id }}"
      },
      "typeVersion": 1
    },
    {
      "id": "874359fc-363d-43bf-aece-bad14b0cee5f",
      "name": "Send Delete Success",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -272,
        656
      ],
      "parameters": {
        "text": "=\ud83d\uddd1\ufe0f Product deleted successfully!\n\nID {{ $('Parse Command and Parameters').item.json.params.id }} has been removed from the database.",
        "chatId": "={{ $('Parse Command and Parameters').item.json.chatId }}",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "ea553b05-a0f2-423e-846c-bd653ff3d63a",
      "name": "Send Delete Error",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -496,
        464
      ],
      "parameters": {
        "text": "=\u274c Error: {{ $json.params.error }}\n\n\ud83d\udcdd Correct format:\n/delete id\n\nExample:\n/delete 15",
        "chatId": "={{ $json.chatId }}",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "da42f0e5-5858-40e7-bcee-1a38a28bbe17",
      "name": "Search Has Error?",
      "type": "n8n-nodes-base.if",
      "position": [
        -720,
        944
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition-error-search",
              "operator": {
                "type": "string",
                "operation": "exists"
              },
              "leftValue": "={{ $json.params.error }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "cfe21419-6e35-4ce3-9191-db448f8122a6",
      "name": "Supabase Search Products",
      "type": "n8n-nodes-base.supabase",
      "position": [
        -496,
        1040
      ],
      "parameters": {
        "tableId": "products",
        "operation": "getAll",
        "returnAll": true,
        "filterType": "string",
        "filterString": "name=ilike.*{{ $json.params.searchText }}*"
      },
      "typeVersion": 1
    },
    {
      "id": "51ca1339-0864-4fdd-a068-f3aaba97d36f",
      "name": "Format Search Results",
      "type": "n8n-nodes-base.code",
      "position": [
        -272,
        1040
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nconst chatId = $('Parse Command and Parameters').first().json.chatId;\nconst searchText = $('Parse Command and Parameters').first().json.params.searchText;\n\nif (items.length === 0) {\n  return [{\n    json: {\n      chatId: chatId,\n      message: `\ud83d\udd0d No products found matching \"${searchText}\"`\n    }\n  }];\n}\n\nlet message = `\ud83d\udd0d Search results for \"${searchText}\" (${items.length}):\\n\\n`;\n\nitems.forEach((item, index) => {\n  const p = item.json;\n  message += `${index + 1}. [ID: ${p.id}] ${p.name}\\n`;\n  message += `   \ud83d\udcb0 $${p.price} | \ud83d\udcca Qty: ${p.quantity} | \ud83c\udff7\ufe0f ${p.category}\\n\\n`;\n});\n\nreturn [{ json: { chatId, message } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "d6b791df-df03-4aba-93a3-4bbbd6c142d3",
      "name": "Send Search Results",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -48,
        1040
      ],
      "parameters": {
        "text": "={{ $json.message }}",
        "chatId": "={{ $json.chatId }}",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "c572235c-384e-4e39-94c1-c1e418170b3c",
      "name": "Send Search Error",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -496,
        848
      ],
      "parameters": {
        "text": "\u274c Error: {{ $json.params.error }}\n\n\ud83d\udcdd Correct format:\n/search text\n\nExample:\n/search iPhone",
        "chatId": "={{ $json.chatId }}",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "00d4fabb-b25d-41e9-8fd5-96395624b1bc",
      "name": "Send Help Message",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -720,
        1136
      ],
      "parameters": {
        "text": "=\ud83d\udcda *Available Commands*\n\n\u2795 */add* name, price, quantity, category\nAdd a new product to the database\nExample: `/add iPhone 15, 999.99, 50, electronics`\n\n\ud83d\udccb */list* \\[category\\]\nList all products or filter by category\nExample: `/list` or `/list electronics`\n\n\ud83d\udd0d */get* id\nGet details of a specific product\nExample: `/get 15`\n\n\u270f\ufe0f */update* id field=value\nUpdate product fields\nExample: `/update 15 price=899 quantity=45`\n\n\ud83d\uddd1\ufe0f */delete* id\nDelete a product\nExample: `/delete 15`\n\n\ud83d\udd0e */search* text\nSearch products by name\nExample: `/search iPhone`\n\n\u2753 */help*\nShow this help message",
        "chatId": "={{ $json.chatId }}",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "12d7c984-6daa-4fa7-8abb-5354efbf225c",
      "name": "Send Unknown Command",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -720,
        1328
      ],
      "parameters": {
        "text": "=\u2753 Unknown command.\n\nUse /help to see available commands.",
        "chatId": "={{ $json.chatId }}",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "8bb58b4c-aeb7-47a1-bf59-d9a5b9dd419d",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2672,
        -480
      ],
      "parameters": {
        "width": 576,
        "height": 1300,
        "content": "## How it works\nThis workflow turns Telegram into a database management interface for Supabase. Send commands to your bot to create, read, update, delete, and search records in your database - all from your phone.\n\n1. **Receive message** - Telegram trigger captures incoming messages\n2. **Validate user** - Checks if sender's chat ID matches authorized list\n3. **Parse command** - Extracts command type and parameters\n4. **Route & execute** - Performs the appropriate Supabase operation\n5. **Respond** - Sends formatted results back to Telegram\n\n## Setup steps\n1. Create a Telegram bot via @BotFather and get your API token\n2. Configure Telegram credentials in n8n\n3. Create a Supabase project and get your API credentials\n4. Create your `products` table (see SQL below)\n5. Edit the \"Is Authorized?\" node and add your Telegram chat ID(s)\n6. Activate the workflow and test with /help\n\n## Supabase table SQL\n```sql\nCREATE TABLE products (\n  id SERIAL PRIMARY KEY,\n  name TEXT NOT NULL,\n  price DECIMAL(10,2),\n  quantity INTEGER DEFAULT 0,\n  category TEXT,\n  created_at TIMESTAMP DEFAULT NOW()\n);\n```\n\n## Add authorized users\nTo authorize more users, edit the \"Is Authorized?\" node and add more OR conditions with their chat IDs.\n\n## Customization Guide\n\n**To use a different table:**\n1. Change `products` to your table name in all Supabase nodes\n2. Update field names in \"Parse Command\" node\n3. Update field mappings in \"Supabase Insert\" node\n4. Adjust response formatting in Code nodes\n\n**To add more authorized users:**\n1. Open the \"Is Authorized?\" node\n2. Add another OR condition\n3. Set it to check chatId equals the new user's ID"
      },
      "typeVersion": 1
    },
    {
      "id": "564354f4-db78-4911-9e50-5ae3ed89062f",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1686,
        256
      ],
      "parameters": {
        "color": 7,
        "width": 412,
        "height": 272,
        "content": "### \ud83d\udd10 Authorization\nExtracts chat ID from message and validates against authorized list using OR conditions. To add more users, edit the If node and add more conditions."
      },
      "typeVersion": 1
    },
    {
      "id": "22d93087-692b-4901-9e49-688005af6cb1",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1248,
        80
      ],
      "parameters": {
        "color": 7,
        "width": 472,
        "height": 576,
        "content": "### \ud83d\udd00 Command Router\nParses the message to extract the command and routes to the appropriate handler. Supports: /add, /list, /get, /update, /delete, /search, /help"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "e6913d36-9002-42b6-be32-9a71209b6466",
  "connections": {
    "Add Has Error?": {
      "main": [
        [
          {
            "node": "Send Add Error",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Supabase Insert Product",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Has Error?": {
      "main": [
        [
          {
            "node": "Send Get Error",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Supabase Get Product",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Authorized?": {
      "main": [
        [
          {
            "node": "Parse Command and Parameters",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Route by Command": {
      "main": [
        [
          {
            "node": "Add Has Error?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Filter by Category?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get Has Error?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update Has Error?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Delete Has Error?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Search Has Error?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Help Message",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Unknown Command",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram Trigger": {
      "main": [
        [
          {
            "node": "Extract Message Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Delete Has Error?": {
      "main": [
        [
          {
            "node": "Send Delete Error",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Supabase Delete Product",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search Has Error?": {
      "main": [
        [
          {
            "node": "Send Search Error",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Supabase Search Products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Product List": {
      "main": [
        []
      ]
    },
    "Supabase List All": {
      "main": [
        [
          {
            "node": "Format Product List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Has Error?": {
      "main": [
        [
          {
            "node": "Send Update Error",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Prepare Update Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter by Category?": {
      "main": [
        [
          {
            "node": "Supabase List Filtered",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Supabase List All",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Product List": {
      "main": [
        [
          {
            "node": "Send Product List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Update Data": {
      "main": [
        [
          {
            "node": "Supabase Update Product",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Message Data": {
      "main": [
        [
          {
            "node": "Is Authorized?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Supabase Get Product": {
      "main": [
        [
          {
            "node": "Send Product Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Search Results": {
      "main": [
        [
          {
            "node": "Send Search Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Supabase List Filtered": {
      "main": [
        [
          {
            "node": "Format Product List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Supabase Delete Product": {
      "main": [
        [
          {
            "node": "Send Delete Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Supabase Insert Product": {
      "main": [
        [
          {
            "node": "Send Add Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Supabase Update Product": {
      "main": [
        [
          {
            "node": "Send Update Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Supabase Search Products": {
      "main": [
        [
          {
            "node": "Format Search Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Command and Parameters": {
      "main": [
        [
          {
            "node": "Route by Command",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}