AutomationFlowsAI & RAG › Gourmet Bistro Customer Service

Gourmet Bistro Customer Service

Gourmet Bistro Customer Service. Uses telegramTrigger, lmChatOllama, embeddingsOllama, memoryPostgresChat. Event-driven trigger; 32 nodes.

Event trigger★★★★★ complexityAI-powered32 nodesTelegram TriggerOllama ChatOllama EmbeddingsMemory Postgres ChatSupabase Vector StoreGoogle SheetsTelegramAgent
AI & RAG Trigger: Event Nodes: 32 Complexity: ★★★★★ AI nodes: yes Added:
Gourmet Bistro Customer Service — n8n workflow card showing Telegram Trigger, Ollama Chat, Ollama Embeddings integration

This workflow follows the Agent → Chainllm 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
{
  "updatedAt": "2026-07-18T12:06:29.598Z",
  "createdAt": "2026-07-03T13:06:16.201Z",
  "id": "VlIW3f7STg7kVnWn",
  "name": "Gourmet Bistro Customer Service",
  "description": null,
  "active": false,
  "isArchived": false,
  "nodes": [
    {
      "parameters": {
        "updates": [
          "message",
          "callback_query"
        ],
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.telegramTrigger",
      "typeVersion": 1.3,
      "position": [
        1632,
        -14176
      ],
      "id": "d3296747-79ae-4f07-b1c2-60d1bb54497f",
      "name": "Telegram Trigger",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "8cbadeef-2f6e-45a2-ac79-e0e0c507e134",
              "name": "chat_id",
              "value": "={{ $json.message?.chat?.id || $json.callback_query?.message?.chat?.id }}",
              "type": "number"
            },
            {
              "id": "d9f949c3-ba90-4435-a057-4d87ddf7d16b",
              "name": "user_text",
              "value": "={{ $json.message?.text || $json.callback_query?.data }}",
              "type": "string"
            },
            {
              "id": "4170fb1c-1fee-4f64-85a0-10c5a75e1495",
              "name": "username",
              "value": "={{ $json.message?.from?.username || 'Customer' }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1856,
        -14176
      ],
      "id": "0cf0c64c-5d02-484c-a3f5-17dcdaf3f126",
      "name": "Normalize Input"
    },
    {
      "parameters": {
        "model": "qwen2.5:1.5b",
        "options": {
          "numCtx": 2048
        }
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOllama",
      "typeVersion": 1,
      "position": [
        2608,
        -14192
      ],
      "id": "fa10a7df-4682-4741-8247-807c032c79df",
      "name": "Ollama Chat Model",
      "credentials": {
        "ollamaApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.employee }}",
                    "rightValue": "Menu & FAQ Expert",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "id": "748e8483-f6b9-4e6e-b01d-5e50f411b78f"
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Output 0"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "creation-specialist-check",
                    "leftValue": "={{ $json.employee }}",
                    "rightValue": "Order Creation Specialist",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  },
                  {
                    "id": "item-extracted-check",
                    "leftValue": "={{ $json.output.extracted_items.length }}",
                    "rightValue": 0,
                    "operator": {
                      "type": "number",
                      "operation": "greaterThan"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Output 1"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "0cc85335-1173-4bf9-9183-92bb3157f732",
                    "leftValue": "={{ $json.employee }}",
                    "rightValue": "Order Cancellation Specialist",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Output 2"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "61b9702f-d4b1-4b91-8f41-786f8aee0f9c",
                    "leftValue": "={{ $json.employee }}",
                    "rightValue": "General Receptionist",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Output 3"
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.4,
      "position": [
        2880,
        -14464
      ],
      "id": "453a3995-f531-4d40-b587-4863437b36c0",
      "name": "Employee Dispatcher"
    },
    {
      "parameters": {
        "model": "qwen2.5:1.5b",
        "options": {
          "temperature": 0,
          "numCtx": 2048
        }
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOllama",
      "typeVersion": 1,
      "position": [
        4480,
        -14688
      ],
      "id": "0c575d2d-581f-464e-96cd-a98686fada1c",
      "name": "Ollama Chat Model1",
      "credentials": {
        "ollamaApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": "nomic-embed-text:latest"
      },
      "type": "@n8n/n8n-nodes-langchain.embeddingsOllama",
      "typeVersion": 1,
      "position": [
        4816,
        -14480
      ],
      "id": "e43f8456-159b-436f-9cb9-049fc6ea3601",
      "name": "Embeddings Ollama",
      "credentials": {
        "ollamaApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "sessionIdType": "customKey",
        "sessionKey": "={{ $('Normalize Input').item.json.chat_id }}"
      },
      "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
      "typeVersion": 1.4,
      "position": [
        4608,
        -14688
      ],
      "id": "fd8b41de-ffeb-4a00-8c86-efec0842d664",
      "name": "Postgres Chat Memory",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "mode": "retrieve-as-tool",
        "toolDescription": "Use this tool to search for restaurant opening hours, delivery rules, payment methods, dietary options, and menu item descriptions, prices, or allergens.",
        "tableName": {
          "__rl": true,
          "value": "knowledge_base",
          "mode": "list",
          "cachedResultName": "knowledge_base"
        },
        "options": {
          "queryName": "match_kb",
          "metadata": {
            "metadataValues": [
              {
                "name": "is_available",
                "value": "true"
              }
            ]
          }
        }
      },
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "typeVersion": 1.3,
      "position": [
        4736,
        -14688
      ],
      "id": "1fb64cb3-f156-4a5c-ad07-fca8b1a1a375",
      "name": "search_restaurant_knowledge_base",
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "value": "1mKSOBh0l5t5D5isQbpwYxT8KU-aeSvJyyo89t9Fj0SY",
          "mode": "list",
          "cachedResultName": "Gourmet Bistro - Knowledge Base & Menu",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1mKSOBh0l5t5D5isQbpwYxT8KU-aeSvJyyo89t9Fj0SY/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 1522240775,
          "mode": "list",
          "cachedResultName": "Gourmet Bistro - Knowledge Base & Menu",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1mKSOBh0l5t5D5isQbpwYxT8KU-aeSvJyyo89t9Fj0SY/edit#gid=1522240775"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        3104,
        -14256
      ],
      "id": "83b67d6e-f0da-4ac4-b253-2163fe7861b2",
      "name": "Google Sheets: Lookup",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const userText = $('Normalize Input').first().json.user_text.toLowerCase();\nconst extractedItems = $('Manager').first().json.output.extracted_items || [];\nconst menuItems = $input.all();\nlet totalPrice = 0;\nconst validatedItems = [];\n\nfor (const item of menuItems) {\n  const row = item.json;\n  const isAvailable = row.is_available === true || String(row.is_available).toLowerCase() === 'true';\n  if (!isAvailable) continue;\n  \n  // Check if this canonical item was extracted by the manager\n  const hasItem = extractedItems.some(ei => ei.toLowerCase() === row.title_or_question.toLowerCase());\n  if (!hasItem) continue;\n  \n  // Basic word-number or digit matching for quantities (defaults to 1 if unspecified)\n  const regex = new RegExp(`(\\\\d+)\\\\s*(?:x|of)?\\\\s*${row.title_or_question.toLowerCase()}`, 'i');\n  const match = userText.match(regex);\n  const quantity = match ? parseInt(match[1], 10) : 1;\n  \n  const price = parseFloat(row.price) || 0;\n  const itemTotal = price * quantity;\n  totalPrice += itemTotal;\n  \n  validatedItems.push({\n    id: row.id || row.title_or_question,\n    name: row.title_or_question,\n    quantity: quantity,\n    unit_price: price,\n    subtotal: itemTotal\n  });\n}\n\nreturn [{\n  json: {\n    items_summary: validatedItems.map(i => `${i.quantity}x ${i.name}`).join(', '),\n    total_price: totalPrice.toFixed(2),\n    is_valid_order: validatedItems.length > 0\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3328,
        -14256
      ],
      "id": "a4a66d12-78de-4c9e-bc66-d3e61c859059",
      "name": "Code Node: Calculate Totals & Quantities"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "cb75ac62-e051-43c2-8dcc-495e23556fb9",
              "leftValue": "={{ $('Normalize Input').item.json.user_text.match(/(010|011|012|015)\\d{8}/)?.[0] || '' }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              }
            },
            {
              "id": "635a6937-6ddc-450e-90c5-6ac69a08f946",
              "leftValue": "={{ $('Normalize Input').item.json.user_text.replace(/(010|011|012|015)\\d{8}/g, '').length > 25 }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        3968,
        -14256
      ],
      "id": "965a8ca5-9415-48f1-8799-b20034b845fa",
      "name": "Check Delivery Info"
    },
    {
      "parameters": {
        "chatId": "={{ $('Normalize Input').item.json.chat_id }}",
        "text": "={{ $json.output }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        5104,
        -14912
      ],
      "id": "eda73f4f-7740-42de-b5fc-7f70be2e7dd8",
      "name": "Menu & FAQ Message",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $('Normalize Input').first().json.user_text }}",
        "options": {
          "systemMessage": "You are the Menu & FAQ Expert for Gourmet Bistro. Your ONLY job is to answer customer questions accurately using our database.\n\nCRITICAL OPERATIONAL RULES:\n1. YOU MUST NEVER ANSWER FROM MEMORY. You are strictly forbidden from generating an answer without calling the Supabase Vector Store tool first.\n2. Always execute a vector search query against the user's text before writing your response.\n3. If the retrieved database context does not contain the answer, state explicitly: \"I do not have that information in our current menu or policy database. Please contact our host desk directly.\"\n4. Never invent prices, ingredients, or policies. Only state what is explicitly returned by the tool (e.g., our 10 km delivery radius or free delivery over 250 EGP)."
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3.1,
      "position": [
        4544,
        -14912
      ],
      "id": "6cf307a2-09c3-4f10-b7e4-7576c22d35a3",
      "name": "Menu & FAQ Expert"
    },
    {
      "parameters": {
        "tableId": "orders",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "customer_chat_id",
              "fieldValue": "={{ $('Normalize Input').item.json.chat_id }}"
            },
            {
              "fieldId": "items",
              "fieldValue": "={{ $('Code Node: Calculate Totals & Quantities').item.json.items_summary }}"
            },
            {
              "fieldId": "total_price",
              "fieldValue": "={{ $('Code Node: Calculate Totals & Quantities').item.json.total_price }}"
            },
            {
              "fieldId": "status",
              "fieldValue": "Draft"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        3616,
        -14256
      ],
      "id": "8dc4cc93-e3cf-4afd-9fe1-f8c18225512b",
      "name": "Supabase (Store the Order)",
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "chatId": "={{ $('Normalize Input').item.json.chat_id }}",
        "text": "=\ud83d\udea8 NEW ORDER #${{ $('Check Active').item.json.order_id || $('Supabase (Store the Order)').item.json.order_id || $json.order_id }} \ud83d\udea8  \ud83c\udf7d\ufe0f Order Details: {{ $('Code Node: Calculate Totals & Quantities').item.json.items_summary || $json.items }}  \ud83d\udcb5 Total Amount: {{ $('Code Node: Calculate Totals & Quantities').item.json.total_price || $json.total_price }} EGP (COD)  \ud83d\udccd Delivery Address: {{ $json.delivery_address }}  \ud83d\udcde Contact Phone: {{ $json.phone_number }}  \u26a1 STATUS: PENDING PREPARATION \u2014 Please acknowledge!",
        "replyMarkup": "forceReply",
        "forceReply": {
          "force_reply": true
        },
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        4688,
        -14064
      ],
      "id": "bb7c5094-8ff9-4cc1-b517-9426015ae0ea",
      "name": "Telegram (Kitchen Alert)",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "chatId": "={{ $('Normalize Input').item.json.chat_id }}",
        "text": "=\u2705 Your order has been placed successfully!\n\n\ud83d\udce6 Order Tracking ID: #{{ $('Check Active').item.json.order_id || $('Supabase (Store the Order)').item.json.order_id || $json.order_id }}\n\ud83d\udcb5 Total to Pay: {{ $('Code Node: Calculate Totals & Quantities').item.json.total_price || $json.total_price }} EGP\n\ud83d\udcb3 Payment Method: Cash on Delivery / InstaPay upon arrival\n\nEstimated delivery time: 35-45 minutes. We will notify you if we need any clarifications!",
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        5104,
        -14064
      ],
      "id": "f03bf0d6-f3cf-4abb-838e-111f90179df7",
      "name": "Telegram (Customer Confirmation)",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $('Normalize Input').item.json.user_text }}",
        "options": {
          "systemMessage": "You are the Order Cancellation Specialist for Gourmet Bistro. Your goal is to assist customers wishing to cancel or modify their orders.\n\nThe current customer's Telegram Chat ID is {{ $('Normalize Input').item.json.chat_id }}.\n\nMANDATORY OPERATIONAL PROTOCOL:\n1. INVESTIGATE FIRST: You must NEVER attempt to cancel an order or promise a cancellation without executing the `check_order_eligibility` tool first.\n2. VERIFY OWNERSHIP: Ensure the order ID requested belongs to the customer contacting you by comparing the order's customer_chat_id with the customer's Telegram Chat ID.\n3. THE 5-MINUTE GRACE PERIOD: If the `check_order_eligibility` tool returns that an order is older than 5 minutes OR its status is not 'Pending' or 'Draft', you are STRICTLY FORBIDDEN from calling the `cancel_order` tool.\n4. GRACEFUL REFUSAL: If an order cannot be cancelled, explain objectively: \"I cannot cancel Order #[ID] automatically because our kitchen has already begun preparation or it has exceeded the 5-minute grace period. Please contact our host desk directly at 010-XXXX-XXXX for escalation.\""
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3.1,
      "position": [
        3552,
        -14656
      ],
      "id": "747fecb1-7ba8-4575-a4f8-877e0bcf6668",
      "name": "AI Agent: Cancellation Specialist"
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Use this tool immediately whenever a customer complains about food quality, delivery delays, missing items, or requests to speak to a human manager.",
        "chatId": "={{ $env.TELEGRAM_MANAGER_CHAT_ID || $('Normalize Input').item.json.chat_id }}",
        "text": "=\u26a0\ufe0f HUMAN ESCALATION REQUIRED \u26a0\ufe0f\n   Customer ID: {{ $('Normalize Input').item.json.chat_id }}\n   Username: @{{ $('Normalize Input').item.json.username }}\n   \n   Last Customer Message:\n   \"{{ $('Normalize Input').item.json.user_text }}\"\n   \n   Reason: Agent detected service complaint or complex anomaly. Please intervene in chat!",
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.telegramTool",
      "typeVersion": 1.2,
      "position": [
        3632,
        -14432
      ],
      "id": "9a6ebf6a-4fc0-4cc5-8d29-90b1ebabc259",
      "name": "escalate_to_human_manager",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "792e86c3-1a01-4855-ba88-0c00d4f79c10",
              "leftValue": "={{ $('Manager').item.json.output.employee }}",
              "rightValue": "Order Creation Specialist",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        4256,
        -13872
      ],
      "id": "93106b63-bf31-42e7-994c-e10b6db15987",
      "name": "Validate Intent Drift"
    },
    {
      "parameters": {
        "chatId": "={{ $('Normalize Input').item.json.chat_id }}",
        "text": "I see you want to place an order, but I didn't recognize the items you listed. Please check our menu and use exact item names, like 'Classic Angus Smash Burger' or 'Signature Passionfruit Mojito'.",
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        5104,
        -13680
      ],
      "id": "00fc61c2-41eb-4166-92de-eebe1afaf914",
      "name": "Error Recovery",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $('Normalize Input').first().json.user_text }}",
        "options": {
          "systemMessage": "You are the Front Desk Concierge for Gourmet Bistro.\nThe current customer's Telegram Chat ID is {{ $('Normalize Input').item.json.chat_id }}.\n\n   RULES:\n   1. GREETINGS: Respond to simple \"Hello\" or \"Thanks\" warmly in 1-2 sentences. Do NOT use tools.\n   2. QUESTIONS: If the user asks about hours, delivery, allergens, or ingredients, you MUST use the 'search_restaurant_knowledge_base' tool. Do NOT guess.\n   3. COMPLAINTS: If the user is angry, mentions bad food, or explicitly asks for a human manager, use the 'escalate_to_human_manager' tool and reply: \"I have alerted our host desk manager to assist you immediately.\""
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3.1,
      "position": [
        4624,
        -13872
      ],
      "id": "391c635d-2f92-4948-afbb-ff81ee10ce81",
      "name": "Bistro Concierge"
    },
    {
      "parameters": {
        "chatId": "={{ $('Telegram Trigger').first().json.message.chat.id }}",
        "text": "={{ $json.output }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        5104,
        -13872
      ],
      "id": "b1b92cbe-533f-4e3e-bca4-82330fde65b3",
      "name": "Customer Reply",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.timeSaved",
      "typeVersion": 1,
      "position": [
        5328,
        -14288
      ],
      "id": "f842a601-5fd5-475b-be14-42d475de8db6",
      "name": "Time Saved"
    },
    {
      "parameters": {
        "operation": "getAll",
        "tableId": "orders",
        "returnAll": true,
        "matchType": "allFilters",
        "filters": {
          "conditions": [
            {
              "keyName": "customer_chat_id",
              "condition": "eq",
              "keyValue": "={{ $('Normalize Input').item.json.chat_id }}"
            },
            {
              "keyName": "status",
              "condition": "eq",
              "keyValue": "Draft"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        2080,
        -14176
      ],
      "id": "ac67204d-f5e0-4ae3-b02a-995ba1f2f4ff",
      "name": "Check Active",
      "alwaysOutputData": true,
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "33bff14c-1abd-4159-9657-d8fe9193f980",
              "leftValue": "={{ $('Check Active').item.json.order_id }}",
              "rightValue": "",
              "operator": {
                "type": "number",
                "operation": "notEmpty",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        2304,
        -14176
      ],
      "id": "24493605-8443-4d8d-820c-8d9c8dece94a",
      "name": "Is Waiting for Address?"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $('Normalize Input').item.json.user_text }}",
        "messages": {
          "messageValues": [
            {
              "message": "### ROLE\nYou are the Restaurant Customer Support Manager for Gourmet Bistro. Analyze the customer message, classify it into exactly one employee role, and extract any canonical menu items.\n\n### RULES\nYou must respond ONLY with a raw JSON object. Do not include markdown formatting like \n```json or ```. Do not include conversational text.\n\n### EMPLOYEES\n- \"Menu & FAQ Expert\": For questions about hours, delivery, reservations, payment, or menu details.\n- \"Order Creation Specialist\": For placing orders or buying food/drinks.\n- \"Order Cancellation Specialist\": For cancelling existing orders.\n- \"General Receptionist\": For basic greetings (\"Hi\", \"Thanks\").\n\n### EXTRACTION\nExtract ONLY these exact names if mentioned:\n\"Truffle Arancini\", \"Burrata & Heirloom Tomato Salad\", \"Classic Angus Smash Burger\", \"Pan-Seared Atlantic Salmon\", \"Wild Mushroom Truffle Risotto\", \"Molten Lava Chocolate Cake\", \"Classic Tiramisu\", \"Signature Passionfruit Mojito\", \"Artisanal Iced Spanish Latte\"\n\nIf no food is mentioned, use [].\n\n### OUTPUT FORMAT\n{\n  \"employee\": \"Menu & FAQ Expert\",\n  \"extracted_items\": []\n}"
            }
          ]
        },
        "batching": {}
      },
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.9,
      "position": [
        2528,
        -14416
      ],
      "id": "2efbb37a-aad0-4bbd-9946-dd395d570495",
      "name": "Manager"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "cancel-intent-check",
              "leftValue": "={{ /cancel|abort|stop|delete|no longer want/i.test($('Normalize Input').item.json.user_text) }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        3328,
        -13728
      ],
      "id": "a5831fe7-fb55-4ee8-a53c-e1c2688fa999",
      "name": "Check Cancel Intent"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "2322dac4-c428-44ae-8ab6-c62a583c1fcd",
              "leftValue": "={{ $('Normalize Input').item.json.user_text.match(/(010|011|012|015)\\d{8}/)?.[0] || '' }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        3616,
        -13632
      ],
      "id": "9da37b9c-d1c9-4f77-9800-5208d63f92db",
      "name": "Validate Address Reply"
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "orders",
        "matchType": "allFilters",
        "filters": {
          "conditions": [
            {
              "keyName": "order_id",
              "condition": "eq",
              "keyValue": "={{ $('Check Active').item.json.order_id || $('Supabase (Store the Order)').item.json.order_id }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "phone_number",
              "fieldValue": "={{ $('Normalize Input').item.json.user_text.match(/(010|011|012|015)\\d{8}/)?.[0] }}"
            },
            {
              "fieldId": "delivery_address",
              "fieldValue": "={{ $('Information Extractor').item.json.delivery_address || $('Normalize Input').item.json.user_text.replace(/(010|011|012|015)\\d{8}/g, '').trim() }}"
            },
            {
              "fieldId": "status",
              "fieldValue": "Pending"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        4256,
        -14064
      ],
      "id": "3db65088-212e-4bbf-966d-99edd4498fa9",
      "name": "Update a row",
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "chatId": "={{ $('Normalize Input').item.json.chat_id }}",
        "text": "I still need a valid Egyptian mobile number (starting with 010, 011, 012, or 015) and your street address to send this to the kitchen. Please reply with both!",
        "replyMarkup": "forceReply",
        "forceReply": {
          "force_reply": true
        },
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        3968,
        -13520
      ],
      "id": "44bbeebf-d7c0-485b-b45b-9d82fe7d743a",
      "name": "Invalid Contact Info",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "chatId": "={{ $('Normalize Input').item.json.chat_id }}",
        "text": "=\u26a0\ufe0f We have your order summary: {{ $json.items_summary }} \ud83d\udcb0 Total Amount: {{ $json.total_price }} EGP  To dispatch this to the kitchen, we need your delivery details. Please reply to this message with: 1. Your exact physical address (Street, Building, Floor) 2. A valid mobile contact number (e.g., 010xxxxxxxx)",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        5104,
        -14336
      ],
      "id": "4baa6e80-0a76-4552-b742-cd15f7ffd732",
      "name": "Order Summary",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "text": "={{ $('Normalize Input').item.json.user_text }}",
        "schemaType": "fromJson",
        "jsonSchemaExample": "{\n     \"delivery_address\": \"55 Nile Corniche Road, Damietta\"\n   }",
        "options": {
          "systemPromptTemplate": "You are an expert extraction algorithm.\nOnly extract relevant information from the text.\nIf you do not know the value of an attribute asked to extract, you may omit the attribute's value."
        }
      },
      "type": "@n8n/n8n-nodes-langchain.informationExtractor",
      "typeVersion": 1.2,
      "position": [
        3904,
        -13712
      ],
      "id": "343d7da9-d5ab-46fe-9195-ae19a67b155b",
      "name": "Information Extractor"
    }
  ],
  "connections": {
    "Telegram Trigger": {
      "main": [
        [
          {
            "node": "Normalize Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ollama Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Manager",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Information Extractor",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Input": {
      "main": [
        [
          {
            "node": "Check Active",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Employee Dispatcher": {
      "main": [
        [
          {
            "node": "Menu & FAQ Expert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Google Sheets: Lookup",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "AI Agent: Cancellation Specialist",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Validate Intent Drift",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Validate Intent Drift",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ollama Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Menu & FAQ Expert",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "AI Agent: Cancellation Specialist",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Bistro Concierge",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings Ollama": {
      "ai_embedding": [
        [
          {
            "node": "search_restaurant_knowledge_base",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Postgres Chat Memory": {
      "ai_memory": [
        [
          {
            "node": "Menu & FAQ Expert",
            "type": "ai_memory",
            "index": 0
          },
          {
            "node": "AI Agent: Cancellation Specialist",
            "type": "ai_memory",
            "index": 0
          },
          {
            "node": "Bistro Concierge",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "search_restaurant_knowledge_base": {
      "ai_tool": [
        [
          {
            "node": "Menu & FAQ Expert",
            "type": "ai_tool",
            "index": 0
          },
          {
            "node": "AI Agent: Cancellation Specialist",
            "type": "ai_tool",
            "index": 0
          },
          {
            "node": "Bistro Concierge",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets: Lookup": {
      "main": [
        [
          {
            "node": "Code Node: Calculate Totals & Quantities",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code Node: Calculate Totals & Quantities": {
      "main": [
        [
          {
            "node": "Supabase (Store the Order)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Delivery Info": {
      "main": [
        [
          {
            "node": "Update a row",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Order Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Menu & FAQ Expert": {
      "main": [
        [
          {
            "node": "Menu & FAQ Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Supabase (Store the Order)": {
      "main": [
        [
          {
            "node": "Check Delivery Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram (Kitchen Alert)": {
      "main": [
        [
          {
            "node": "Telegram (Customer Confirmation)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "escalate_to_human_manager": {
      "ai_tool": [
        [
          {
            "node": "AI Agent: Cancellation Specialist",
            "type": "ai_tool",
            "index": 0
          },
          {
            "node": "Bistro Concierge",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Validate Intent Drift": {
      "main": [
        [
          {
            "node": "Error Recovery",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Bistro Concierge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Bistro Concierge": {
      "main": [
        [
          {
            "node": "Customer Reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Menu & FAQ Message": {
      "main": [
        [
          {
            "node": "Time Saved",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent: Cancellation Specialist": {
      "main": [
        [
          {
            "node": "Time Saved",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram (Customer Confirmation)": {
      "main": [
        [
          {
            "node": "Time Saved",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Customer Reply": {
      "main": [
        [
          {
            "node": "Time Saved",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Error Recovery": {
      "main": [
        [
          {
            "node": "Time Saved",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Active": {
      "main": [
        [
          {
            "node": "Is Waiting for Address?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Waiting for Address?": {
      "main": [
        [
          {
            "node": "Check Cancel Intent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Manager",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Cancel Intent": {
      "main": [
        [
          {
            "node": "AI Agent: Cancellation Specialist",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Validate Address Reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Manager": {
      "main": [
        [
          {
            "node": "Employee Dispatcher",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Address Reply": {
      "main": [
        [
          {
            "node": "Information Extractor",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Invalid Contact Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update a row": {
      "main": [
        [
          {
            "node": "Telegram (Kitchen Alert)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Order Summary": {
      "main": [
        [
          {
            "node": "Time Saved",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Information Extractor": {
      "main": [
        [
          {
            "node": "Update a row",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate",
    "availableInMCP": true,
    "timeSavedMode": "fixed",
    "timezone": "Africa/Cairo",
    "saveDataErrorExecution": "all",
    "saveDataSuccessExecution": "all",
    "saveExecutionProgress": true,
    "saveManualExecutions": true,
    "callerPolicy": "workflowsFromSameOwner"
  },
  "staticData": null,
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodeGroups": [],
  "versionId": "37f21ec5-69c6-4c1d-b42f-65e33dc3c114",
  "activeVersionId": null,
  "versionCounter": 477,
  "triggerCount": 1,
  "sourceWorkflowId": null,
  "tags": [
    {
      "updatedAt": "2026-07-05T20:54:10.312Z",
      "createdAt": "2026-07-05T20:54:10.312Z",
      "id": "YPOBiRLmef0fLiKM",
      "name": "RAG"
    },
    {
      "updatedAt": "2026-07-16T16:03:28.540Z",
      "createdAt": "2026-07-16T16:03:28.540Z",
      "id": "90acb56ef2f84a89",
      "name": "Event-Driven"
    },
    {
      "updatedAt": "2026-07-16T16:03:28.786Z",
      "createdAt": "2026-07-16T16:03:28.786Z",
      "id": "6e30f4ffb71d4b65",
      "name": "Data Pipeline"
    },
    {
      "updatedAt": "2026-07-16T16:03:29.020Z",
      "createdAt": "2026-07-16T16:03:29.020Z",
      "id": "9a8d1d753df54ed1",
      "name": "Production Automation"
    },
    {
      "updatedAt": "2026-07-16T16:03:28.284Z",
      "createdAt": "2026-07-16T16:03:28.284Z",
      "id": "e1c954be4bee474d",
      "name": "Data Transformation"
    },
    {
      "updatedAt": "2026-07-16T16:03:29.217Z",
      "createdAt": "2026-07-16T16:03:29.217Z",
      "id": "08f43634238e406b",
      "name": "Agentic AI"
    },
    {
      "updatedAt": "2026-07-16T16:03:28.033Z",
      "createdAt": "2026-07-16T16:03:28.033Z",
      "id": "07e54c18d20c43bb",
      "name": "Vector Storage"
    }
  ],
  "shared": [
    {
      "updatedAt": "2026-07-03T13:06:16.201Z",
      "createdAt": "2026-07-03T13:06:16.201Z",
      "role": "workflow:owner",
      "workflowId": "VlIW3f7STg7kVnWn",
      "projectId": "7Kuw5RaGwePDWMtJ",
      "project": {
        "updatedAt": "2026-06-09T16:37:14.049Z",
        "createdAt": "2026-06-09T16:15:53.210Z",
        "id": "7Kuw5RaGwePDWMtJ",
        "name": "Sohila Abbas <sohila.k.data@gmail.com>",
        "type": "personal",
        "icon": null,
        "description": null,
        "customTelemetryTags": [],
        "creatorId": "ef255f89-7c87-4d14-8714-7469755d5486"
      }
    }
  ],
  "versionMetadata": {
    "name": null,
    "description": null
  }
}

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

Gourmet Bistro Customer Service. Uses telegramTrigger, lmChatOllama, embeddingsOllama, memoryPostgresChat. Event-driven trigger; 32 nodes.

Source: https://github.com/Sohila-Khaled-Abbas/n8n-workflow-gourmet-bistro-customer-service/blob/main/workflow.json — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

A lightweight, self-hosted AI assistant built entirely in n8n. Multi-channel messaging (Telegram, WhatsApp, Gmail), persistent memory, task management, and autonomous work — all in a single visual wor

Telegram Trigger, OpenRouter Chat, Data Table +20
AI & RAG

🛠️ How It Works: System Architecture Workflow ini bekerja melalui empat lapisan proses utama yang terintegrasi secara otomatis: Input Processing & Routing Telegram Trigger: Menangkap setiap pesan masu

Telegram Trigger, HTTP Request, Telegram +13
AI & RAG

Page Management. Uses documentDefaultDataLoader, embeddingsOpenAi, googleDrive, googleDriveTrigger. Event-driven trigger; 37 nodes.

Document Default Data Loader, OpenAI Embeddings, Google Drive +12
AI & RAG

BTL AI Page Management. Uses documentDefaultDataLoader, embeddingsOpenAi, googleDrive, googleDriveTrigger. Event-driven trigger; 37 nodes.

Document Default Data Loader, OpenAI Embeddings, Google Drive +12
AI & RAG

Answers should given only within provided text. Chat interface powered by LLM (Ollama) Retrieval-Augmented Generation (RAG) using Supabase Vector DB Multi-format file support (PDF, Excel, Google Docs,

Document Default Data Loader, Google Drive, Google Drive Trigger +10