Gemini AI 및 Telegram 기반 스마트 레스토랑 주문 및 추천 시스템
이것은Lead Nurturing, Multimodal AI분야의자동화 워크플로우로, 21개의 노드를 포함합니다.주로 Code, Telegram, FormTrigger, GoogleSheets, Agent 등의 노드를 사용하며. Gemini 및 Telegram을 통한 AI 메뉴 추천 레스토랑 주문 자동화
- •Telegram Bot Token
- •Google Sheets API 인증 정보
- •Google Gemini API Key
{
"id": "aDRgA0zAqjUD2yvU",
"meta": {
"instanceId": "dd69efaf8212c74ad206700d104739d3329588a6f3f8381a46a481f34c9cc281",
"templateCredsSetupCompleted": true
},
"name": "Smart Restaurant Order & Suggestion System with Gemini AI and Telegram",
"tags": [],
"nodes": [
{
"id": "4492f7c4-0f63-4cc9-9772-b1d8194dd2fb",
"name": "새 주문 트리거 (폼)",
"type": "n8n-nodes-base.formTrigger",
"position": [
-880,
360
],
"webhookId": "cab910e4-9ffd-483b-8fc7-c1f4973ea948",
"parameters": {
"options": {},
"formTitle": "Oneclick Restaurant Order - Table number 1",
"formFields": {
"values": [
{
"fieldLabel": "Please enter your name",
"placeholder": "John doe",
"requiredField": true
},
{
"fieldType": "number",
"fieldLabel": "Please enter your phone number",
"placeholder": "123456789"
},
{
"fieldType": "number",
"fieldLabel": "Tandoori Chicken - 250 Rupees"
},
{
"fieldType": "number",
"fieldLabel": "Biryani - 200 Rupees"
},
{
"fieldType": "number",
"fieldLabel": "Masala Dosa - 150 Rupees"
},
{
"fieldType": "number",
"fieldLabel": "Idli vada - 100 Rupees"
},
{
"fieldType": "number",
"fieldLabel": "Dal Tadka - 150 Rupees"
},
{
"fieldType": "number",
"fieldLabel": "Steam Rice - 100 Rupees"
},
{
"fieldLabel": "Paratha - 30 Rupees"
},
{
"fieldType": "number",
"fieldLabel": "Paneer butter masal - 250 Rupees"
},
{
"fieldType": "number",
"fieldLabel": "Fix Thali - 150 Rupees"
}
]
},
"formDescription": "Please add your dish quantity and submit to place your order"
},
"typeVersion": 2.2
},
{
"id": "1e2209ba-20d6-4d2a-9f03-6a62b3c98f4e",
"name": "주문 데이터 추출 및 형식화",
"type": "n8n-nodes-base.code",
"position": [
-660,
360
],
"parameters": {
"jsCode": "const input = $input.all();\nconst formData = input[0].json;\n\nconst name = formData[\"Please enter your name\"];\nconst mobile = String(formData[\"Please enter your phone number\"]);\n\nfunction generateCustomerId() {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n let id = '';\n for (let i = 0; i < 6; i++) {\n id += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return `CUST-${id}`;\n}\n\nconst customerId = generateCustomerId();\n\nconst dishes = Object.entries(formData)\n .map(([key, value]) => {\n const match = key.match(/^(.*)\\s*-\\s*(\\d+)\\s*Rupees$/);\n if (!match) return null;\n const rawQty = Number(value);\n if (isNaN(rawQty) || rawQty < 1) return null; // only >1\n const unitPrice = Number(match[2]);\n return {\n dishName: match[1].trim(),\n quantity: rawQty,\n unitPrice,\n totalPrice: rawQty * unitPrice\n };\n })\n .filter(item => item !== null);\n\nreturn [\n {\n json: {\n customerId,\n name,\n mobile,\n dishes,\n },\n },\n];\n"
},
"typeVersion": 2
},
{
"id": "fc25b5bf-717a-40b9-9cf3-69bd12c3fc52",
"name": "고객 정보 저장",
"type": "n8n-nodes-base.googleSheets",
"position": [
-440,
360
],
"parameters": {
"columns": {
"value": {
"Customer id": "={{ $json.customerId }}",
"Customer name": "={{ $json.name }}",
"costomer mobile number": "={{ $json.mobile }}"
},
"schema": [
{
"id": "Customer id",
"type": "string",
"display": true,
"required": false,
"displayName": "Customer id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Customer name",
"type": "string",
"display": true,
"required": false,
"displayName": "Customer name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "costomer mobile number",
"type": "string",
"display": true,
"required": false,
"displayName": "costomer mobile number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1QztyOVgP8vIAQGLeBNErIHqJ77fq4vDRVD1DvHJdGaI/edit#gid=0",
"cachedResultName": "customer details"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1QztyOVgP8vIAQGLeBNErIHqJ77fq4vDRVD1DvHJdGaI",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1QztyOVgP8vIAQGLeBNErIHqJ77fq4vDRVD1DvHJdGaI/edit?usp=drivesdk",
"cachedResultName": "restaurant order placement "
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"id": "ScSS2KxGQULuPtdy",
"name": "Google Sheets- test"
}
},
"typeVersion": 4.6
},
{
"id": "844defa5-d868-4397-a52e-9a165932aba0",
"name": "요리 정보 저장",
"type": "n8n-nodes-base.code",
"position": [
-220,
360
],
"parameters": {
"jsCode": "// Input comes from the previous node\nconst data = $('Extract & Format Order Data').first().json.dishes;\n\nreturn data;\n"
},
"typeVersion": 2
},
{
"id": "c5d5435a-2d99-48f0-b5c2-48531fb12670",
"name": "AI를 위한 요리 상세 정보 준비",
"type": "n8n-nodes-base.googleSheets",
"position": [
0,
360
],
"parameters": {
"columns": {
"value": {
"dish name": "={{ $json.dishName }}",
"Customer id": "={{ $('Extract & Format Order Data').item.json.customerId }}",
"actual price": "={{ $json.totalPrice }}",
"dish quantity": "={{ $json.quantity }}",
"per unit price": "={{ $json.unitPrice }}"
},
"schema": [
{
"id": "Customer id",
"type": "string",
"display": true,
"required": false,
"displayName": "Customer id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "dish name",
"type": "string",
"display": true,
"required": false,
"displayName": "dish name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "dish quantity",
"type": "string",
"display": true,
"required": false,
"displayName": "dish quantity",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "per unit price",
"type": "string",
"display": true,
"required": false,
"displayName": "per unit price",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "actual price",
"type": "string",
"display": true,
"required": false,
"displayName": "actual price",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1326050181,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1QztyOVgP8vIAQGLeBNErIHqJ77fq4vDRVD1DvHJdGaI/edit#gid=1326050181",
"cachedResultName": "customer order details"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1QztyOVgP8vIAQGLeBNErIHqJ77fq4vDRVD1DvHJdGaI",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1QztyOVgP8vIAQGLeBNErIHqJ77fq4vDRVD1DvHJdGaI/edit?usp=drivesdk",
"cachedResultName": "restaurant order placement "
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"id": "ScSS2KxGQULuPtdy",
"name": "Google Sheets- test"
}
},
"typeVersion": 4.6
},
{
"id": "560536c7-a876-4418-9ad7-f4d3461d85f3",
"name": "AI 입력을 위한 데이터 정리",
"type": "n8n-nodes-base.code",
"position": [
220,
360
],
"parameters": {
"jsCode": "// Fetch all incoming items\nconst items = $input.all();\n\n// Extract the raw row data (each item.json is one row)\nconst rawRows = items.map(item => item.json);\n\n// Bundle everything into a single field\nconst payload = { rows: rawRows };\n\n// Return a single output item whose json contains your full dataset\nreturn [{ json: { data: payload } }];"
},
"typeVersion": 2
},
{
"id": "c0a4ab92-9ae3-45ca-806c-f4e1e5e396cc",
"name": "Gemini AI 요리 추천 에이전트",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
440,
360
],
"parameters": {
"text": "={{ $json.data }}",
"options": {
"systemMessage": "You are a friendly AI assistant for a restaurant, designed to suggest dishes that customers might enjoy based on their recent order. \n\nWe will provide you with structured JSON input representing a customer’s previous order, for example:\n\nYou are a friendly AI assistant for a restaurant, designed to suggest dishes that customers might enjoy based on their recent order. \n\nWe will provide you with structured JSON input representing a customer’s previous order, for example:\n\n{\n \"customerId\": \"CUST-1D0RWH\",\n \"name\": \"ajay\",\n \"mobile\": \"9898989898\",\n \"dishes\": [\n { \"dishName\": \"Tandoori Chicken\", \"quantity\": 1, \"unitPrice\": 250, \"totalPrice\": 250 },\n { \"dishName\": \"Masala Dosa\", \"quantity\": 1, \"unitPrice\": 150, \"totalPrice\": 150 },\n { \"dishName\": \"Idli vada\", \"quantity\": 1, \"unitPrice\": 100, \"totalPrice\": 100 },\n { \"dishName\": \"Dal Tadka\", \"quantity\": 1, \"unitPrice\": 150, \"totalPrice\": 150 },\n { \"dishName\": \"Paratha\", \"quantity\": 2, \"unitPrice\": 30, \"totalPrice\": 60 },\n { \"dishName\": \"Paneer butter masal\",\"quantity\":1, \"unitPrice\": 250,\"totalPrice\":250 }\n ]\n}\n\nYour job:\n1. Analyze the dishes—look at cuisine types, flavors, categories, and quantities.\n2. Recommend **3–5 other dishes** likely to appeal to this customer, explaining *why* (e.g., complementary flavors, similar cuisines, balancing variety).\n3. Output JSON with:\n - `suggestions`: an array of objects each with `dishName` and `reason`\n\n**Important formatting rules:**\n- Output must be strictly valid JSON (no extra text).\n- Follow this structure exactly:\n\n\nYour job:\n1. Analyze the dishes—look at cuisine types, flavors, categories, and quantities.\n2. Recommend **3–5 other dishes** likely to appeal to this customer, explaining *why* (e.g., complementary flavors, similar cuisines, balancing variety).\n3. Output JSON with:\n - `suggestions`: an array of objects each with `dishName` and `reason`\n\n**Important formatting rules:**\n- Output must be strictly valid JSON (no extra text).\n- Follow this structure exactly:"
},
"promptType": "define"
},
"typeVersion": 1.9
},
{
"id": "d80e5505-1f6d-4904-b497-b62530f284e2",
"name": "Telegram 전송을 위한 AI 추천 형식화",
"type": "n8n-nodes-base.code",
"position": [
816,
360
],
"parameters": {
"jsCode": "// Step 1: Fetch the raw output from the AI Agent node\nconst aiResponse = $node[\"Gemini AI Dish Suggestion Agent\"].json.output; // Update \"AI Agent\" to your node name\n\n// Step 2: Strip Markdown fences if present\nconst markdownPattern = /^```json\\s*([\\s\\S]*)\\s*```$/;\nconst cleaned = aiResponse.replace(markdownPattern, \"$1\");\n\n// Step 3: Parse JSON safely\nlet parsed;\ntry {\n parsed = JSON.parse(cleaned);\n} catch (err) {\n throw new Error(`Failed to parse AI response JSON: ${err.message}`);\n}\n\n// Step 4: Return each suggestion as its own item (n8n format)\nreturn parsed.suggestions.map(s => ({\n json: {\n customerId: parsed.customerId,\n ...s\n }\n}));\n"
},
"typeVersion": 2
},
{
"id": "c902fee2-f89a-42c8-92ea-4bced23561b7",
"name": "Telegram을 통한 추천 전송",
"type": "n8n-nodes-base.telegram",
"position": [
1036,
360
],
"webhookId": "73247e26-45a7-4c4a-8a52-4a8fcc1d110d",
"parameters": {
"text": "={{ $json.dishName }}\n\n{{ $json.reason }}",
"chatId": "newchatid",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"id": "3ubbGgZx2YzylQZu",
"name": "Telegram account - test"
}
},
"typeVersion": 1.2
},
{
"id": "068d712a-eddc-4021-8c3f-b601e767af92",
"name": "채팅 모델",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
468,
580
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.5-pro"
},
"credentials": {
"googlePalmApi": {
"id": "RvSkIBjP48ORJKhU",
"name": "Google Gemini(PaLM) Api account - test"
}
},
"typeVersion": 1
},
{
"id": "29206de4-5ee1-44e0-9e48-6440f390a981",
"name": "Think 도구",
"type": "@n8n/n8n-nodes-langchain.toolThink",
"position": [
588,
580
],
"parameters": {},
"typeVersion": 1
},
{
"id": "9f542a6c-37d5-4acb-a27d-64c1043e7b2e",
"name": "스티커 메모",
"type": "n8n-nodes-base.stickyNote",
"position": [
-910,
0
],
"parameters": {
"color": 5,
"width": 160,
"height": 520,
"content": "Triggered when a customer submits their dish order form."
},
"typeVersion": 1
},
{
"id": "4d847217-066e-4323-afbd-03fe71074cc3",
"name": "스티커 메모1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-470,
0
],
"parameters": {
"color": 4,
"width": 160,
"height": 520,
"content": "Adds customer details to the Google Sheet.\n"
},
"typeVersion": 1
},
{
"id": "63dd550d-71bd-4599-858d-6c1336bd4aed",
"name": "스티커 메모2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-30,
0
],
"parameters": {
"color": 5,
"width": 160,
"height": 520,
"content": "Gathers final dish data to send to the AI agent.\n"
},
"typeVersion": 1
},
{
"id": "a954f2da-409f-4a5e-b31e-70ffd34ff718",
"name": "스티커 메모3",
"type": "n8n-nodes-base.stickyNote",
"position": [
190,
0
],
"parameters": {
"width": 160,
"height": 520,
"content": "Reformats the data to improve AI understanding."
},
"typeVersion": 1
},
{
"id": "f85f9bc1-c82a-475d-bfd5-5e1cc68b67c3",
"name": "스티커 메모4",
"type": "n8n-nodes-base.stickyNote",
"position": [
786,
0
],
"parameters": {
"color": 4,
"width": 160,
"height": 520,
"content": "Converts Gemini output into Telegram-friendly message format."
},
"typeVersion": 1
},
{
"id": "7ba85c44-5f48-482b-b385-81f819290c54",
"name": "스티커 메모5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1006,
0
],
"parameters": {
"color": 3,
"width": 160,
"height": 520,
"content": "Sends dish suggestions directly to the customer."
},
"typeVersion": 1
},
{
"id": "7e499f3f-1037-4d71-a40a-45669b4ac16c",
"name": "스티커 메모6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-250,
0
],
"parameters": {
"color": 3,
"width": 160,
"height": 520,
"content": "Stores ordered dish quantities and types to a separate sheet."
},
"typeVersion": 1
},
{
"id": "587a6136-fc12-4c0a-8fb1-a3b06026cb11",
"name": "스티커 메모7",
"type": "n8n-nodes-base.stickyNote",
"position": [
440,
0
],
"parameters": {
"color": 6,
"width": 260,
"height": 520,
"content": "Uses Gemini AI to recommend related dishes or offers."
},
"typeVersion": 1
},
{
"id": "5f0d16a4-be36-4a56-8b4e-05093cfeaa68",
"name": "스티커 메모8",
"type": "n8n-nodes-base.stickyNote",
"position": [
-690,
0
],
"parameters": {
"width": 160,
"height": 520,
"content": "Formats incoming form fields for further processing."
},
"typeVersion": 1
},
{
"id": "286198a1-70dc-4d08-babf-dc24b127bf72",
"name": "스티커 메모9",
"type": "n8n-nodes-base.stickyNote",
"position": [
-360,
-540
],
"parameters": {
"color": 2,
"width": 800,
"height": 320,
"content": "### This workflow helps automate restaurant order processing and customer engagement by:\n\n- Saving Time: Automatically records customer and dish data without manual entry.\n\n- Personalizing Experience: AI suggests relevant dishes or combos to upsell or enhance the order.\n\n- Centralized Tracking: All order data is logged into Google Sheets for real-time access and analytics.\n\n- Instant Outreach: Sends dish suggestions directly to customers via Telegram within seconds.\n\n- Scalability: Easily handles multiple orders with AI-driven intelligence—ideal for growing restaurants.\n\n"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "3910b529-9989-490f-ba6d-ed97e80f157a",
"connections": {
"068d712a-eddc-4021-8c3f-b601e767af92": {
"ai_languageModel": [
[
{
"node": "c0a4ab92-9ae3-45ca-806c-f4e1e5e396cc",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"29206de4-5ee1-44e0-9e48-6440f390a981": {
"ai_tool": [
[
{
"node": "c0a4ab92-9ae3-45ca-806c-f4e1e5e396cc",
"type": "ai_tool",
"index": 0
}
]
]
},
"844defa5-d868-4397-a52e-9a165932aba0": {
"main": [
[
{
"node": "c5d5435a-2d99-48f0-b5c2-48531fb12670",
"type": "main",
"index": 0
}
]
]
},
"fc25b5bf-717a-40b9-9cf3-69bd12c3fc52": {
"main": [
[
{
"node": "844defa5-d868-4397-a52e-9a165932aba0",
"type": "main",
"index": 0
}
]
]
},
"560536c7-a876-4418-9ad7-f4d3461d85f3": {
"main": [
[
{
"node": "c0a4ab92-9ae3-45ca-806c-f4e1e5e396cc",
"type": "main",
"index": 0
}
]
]
},
"4492f7c4-0f63-4cc9-9772-b1d8194dd2fb": {
"main": [
[
{
"node": "1e2209ba-20d6-4d2a-9f03-6a62b3c98f4e",
"type": "main",
"index": 0
}
]
]
},
"1e2209ba-20d6-4d2a-9f03-6a62b3c98f4e": {
"main": [
[
{
"node": "fc25b5bf-717a-40b9-9cf3-69bd12c3fc52",
"type": "main",
"index": 0
}
]
]
},
"c5d5435a-2d99-48f0-b5c2-48531fb12670": {
"main": [
[
{
"node": "560536c7-a876-4418-9ad7-f4d3461d85f3",
"type": "main",
"index": 0
}
]
]
},
"c0a4ab92-9ae3-45ca-806c-f4e1e5e396cc": {
"main": [
[
{
"node": "d80e5505-1f6d-4904-b497-b62530f284e2",
"type": "main",
"index": 0
}
]
]
},
"d80e5505-1f6d-4904-b497-b62530f284e2": {
"main": [
[
{
"node": "c902fee2-f89a-42c8-92ea-4bced23561b7",
"type": "main",
"index": 0
}
]
]
}
}
}이 워크플로우를 어떻게 사용하나요?
위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.
이 워크플로우는 어떤 시나리오에 적합한가요?
고급 - 리드 육성, 멀티모달 AI
유료인가요?
이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.
관련 워크플로우 추천
Oneclick AI Squad
@oneclick-aiThe AI Squad Initiative is a pioneering effort to build, automate and scale AI-powered workflows using n8n.io. Our mission is to help individuals and businesses integrate AI agents seamlessly into their daily operations from automating tasks and enhancing productivity to creating innovative, intelligent solutions. We design modular, reusable AI workflow templates that empower creators, developers and teams to supercharge their automation with minimal effort and maximum impact.
이 워크플로우 공유