基于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": "基于 Gemini AI 和 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": "思考工具",
"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": "当客户提交菜品订单表单时触发。"
},
"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": "将客户详情添加到 Google Sheets。"
},
"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": "收集最终菜品数据以发送给 AI 代理。"
},
"typeVersion": 1
},
{
"id": "a954f2da-409f-4a5e-b31e-70ffd34ff718",
"name": "便签3",
"type": "n8n-nodes-base.stickyNote",
"position": [
190,
0
],
"parameters": {
"width": 160,
"height": 520,
"content": "重新格式化数据以提高 AI 理解能力。"
},
"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": "将 Gemini 输出转换为 Telegram 友好的消息格式。"
},
"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": "直接向客户发送菜品建议。"
},
"typeVersion": 1
},
{
"id": "7e499f3f-1037-4d71-a40a-45669b4ac16c",
"name": "### 需要帮助?",
"type": "n8n-nodes-base.stickyNote",
"position": [
-250,
0
],
"parameters": {
"color": 3,
"width": 160,
"height": 520,
"content": "将订购的菜品数量和类型存储到单独的工作表。"
},
"typeVersion": 1
},
{
"id": "587a6136-fc12-4c0a-8fb1-a3b06026cb11",
"name": "## 试试看!",
"type": "n8n-nodes-base.stickyNote",
"position": [
440,
0
],
"parameters": {
"color": 6,
"width": 260,
"height": 520,
"content": "使用 Gemini AI 推荐相关菜品或优惠。"
},
"typeVersion": 1
},
{
"id": "5f0d16a4-be36-4a56-8b4e-05093cfeaa68",
"name": "GET 模型",
"type": "n8n-nodes-base.stickyNote",
"position": [
-690,
0
],
"parameters": {
"width": 160,
"height": 520,
"content": "格式化传入的表单字段以供进一步处理。"
},
"typeVersion": 1
},
{
"id": "286198a1-70dc-4d08-babf-dc24b127bf72",
"name": "## 1. 创建新的自定义 OpenAI 凭据",
"type": "n8n-nodes-base.stickyNote",
"position": [
-360,
-540
],
"parameters": {
"color": 2,
"width": 800,
"height": 320,
"content": "### 此工作流通过以下方式帮助自动化餐厅订单处理和客户互动:"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "3910b529-9989-490f-ba6d-ed97e80f157a",
"connections": {
"Chat Model": {
"ai_languageModel": [
[
{
"node": "Gemini AI Dish Suggestion Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Think Tool": {
"ai_tool": [
[
{
"node": "Gemini AI Dish Suggestion Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Save Dish Info": {
"main": [
[
{
"node": "Prepare Dish Details for AI",
"type": "main",
"index": 0
}
]
]
},
"Save Customer Info": {
"main": [
[
{
"node": "Save Dish Info",
"type": "main",
"index": 0
}
]
]
},
"Clean Data for AI Input": {
"main": [
[
{
"node": "Gemini AI Dish Suggestion Agent",
"type": "main",
"index": 0
}
]
]
},
"New Order Trigger (Form)": {
"main": [
[
{
"node": "Extract & Format Order Data",
"type": "main",
"index": 0
}
]
]
},
"Extract & Format Order Data": {
"main": [
[
{
"node": "Save Customer Info",
"type": "main",
"index": 0
}
]
]
},
"Prepare Dish Details for AI": {
"main": [
[
{
"node": "Clean Data for AI Input",
"type": "main",
"index": 0
}
]
]
},
"Gemini AI Dish Suggestion Agent": {
"main": [
[
{
"node": "Format AI Suggestions for Telegram",
"type": "main",
"index": 0
}
]
]
},
"Format AI Suggestions for Telegram": {
"main": [
[
{
"node": "Send Suggestions via Telegram",
"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.
分享此工作流