8
n8n 中文网amn8n.com

餐厅食物浪费预测系统

高级

这是一个Document Extraction, AI Summarization领域的自动化工作流,包含 21 个节点。主要使用 Code, Gmail, GoogleSheets, Agent, ScheduleTrigger 等节点。 使用Gemini AI和Google Sheets报告预测餐厅食物浪费

前置要求
  • Google 账号和 Gmail API 凭证
  • Google Sheets API 凭证
  • Google Gemini API Key
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "ER0P5gVPl7ARd3cU",
  "meta": {
    "instanceId": "dd69efaf8212c74ad206700d104739d3329588a6f3f8381a46a481f34c9cc281",
    "templateCredsSetupCompleted": true
  },
  "name": "餐厅食物浪费预测系统",
  "tags": [],
  "nodes": [
    {
      "id": "7ecc2319-ee53-4b62-b529-666c82fb88b6",
      "name": "每日触发器",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -280,
        420
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 22
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "fa199f84-c3da-4e05-867f-20cab560c633",
      "name": "获取历史销售数据",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -60,
        420
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1621929706,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1QZXX_gjNTTZ0vqPozNysjASQS3UcgwwWVpYvN7r-T_I/edit#gid=1621929706",
          "cachedResultName": "food wastage data"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1QZXX_gjNTTZ0vqPozNysjASQS3UcgwwWVpYvN7r-T_I",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1QZXX_gjNTTZ0vqPozNysjASQS3UcgwwWVpYvN7r-T_I/edit?usp=drivesdk",
          "cachedResultName": "Restaurant stock predictions"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "id": "ScSS2KxGQULuPtdy",
          "name": "Google Sheets- test"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "d186b482-008a-45b1-a766-963ead9bc4de",
      "name": "为 AI 预测格式化数据",
      "type": "n8n-nodes-base.code",
      "position": [
        160,
        420
      ],
      "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 } }];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "4f401f04-a17e-4dfc-874f-d5e7e0983316",
      "name": "AI 预测生成器",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        380,
        420
      ],
      "parameters": {
        "text": "={{ $json.data }}",
        "options": {
          "systemMessage": "You are a demand forecasting and optimisation AI assistant for a restaurant. \n\nYou will receive data items, each with fields:\n- Date (YYYY-MM-DD)\n- Dish\n- Sales (number of dishes sold)\n- Raw Material\n- Used (kg)\n- Wastage (kg)\n\nYour tasks are:\n1. Analyze the past 5 days per dish and per raw material.\n2. Identify trends (e.g., increasing/decreasing sales, stable/wasteful usage).\n3. Predict next-day sales per dish and raw material usage (in kg) using simple time-series methods (like moving average or linear trend).\n4. Adjust raw material predictions to reduce expected wastage—aim for coverage with ~5% buffer.\n5. Calculate \"predicted food waste reduce\" as: (predicted raw material use) − (optimal raw material procurement). This indicates how much waste you’re avoiding.\n6. Return output as JSON array with:\n   - Date (next day’s date, YYYY-MM-DD)\n   - Dish\n   - predicted Sales (number)\n   - Raw Material\n   - predicted Use (kg)\n   - predicted food waste reduce (kg)\n\nConstraints:\n- Use clear numerical rounding (one decimal place).\n- Prioritize realistic, small improvements (justified by data).\n\nExample output item:\n{\n  \"Date\": \"2025-07-14\",\n  \"Dish\": \"Pasta\",\n  \"predicted Sales\": 60,\n  \"Raw Material\": \"Tomato\",\n  \"predicted Use (kg)\": 12.0,\n  \"predicted food waste reduce (kg)\": 0.5\n}\n\nWrite a JSON array containing one item per (Dish × Raw Material), sorted alphabetically by Dish.\n"
        },
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "c1888087-d468-4f25-bf3d-5b5185e34719",
      "name": "清理和结构化 AI 输出",
      "type": "n8n-nodes-base.code",
      "position": [
        760,
        420
      ],
      "parameters": {
        "jsCode": "// 1. Grab the AI agent output (assuming it's in item.json.output or item.json.content)\nconst raw = $input.item.json.output || $input.item.json.content;\n\n// 2. Clean it by removing triple backticks, optional \"json\" tag, and any common prefixes\nlet cleaned = raw\n  .replace(/```json/, '')\n  .replace(/```/g, '')\n  .replace(/^(Here is (the )?JSON[:\\s]*)/, '')\n  .trim();\n\n// 3. Parse JSON safely\nlet parsed;\ntry {\n  parsed = JSON.parse(cleaned);\n} catch (e) {\n  throw new Error('Failed to parse AI JSON: ' + e.message + '\\nRaw cleaned text: ' + cleaned);\n}\n\n// 4. Return each JSON object as its own item for downstream nodes\nreturn parsed.map(obj => ({ json: obj }));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "d766931a-e722-402e-aa88-58c1b39935d5",
      "name": "记录预测到 Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        980,
        420
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Dish",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Dish",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "predicted Sales",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "predicted Sales",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Raw Material",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Raw Material",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "predicted Use (kg)",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "predicted Use (kg)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "predicted food waste reduce (kg)",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "predicted food waste reduce (kg)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1653513259,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1QZXX_gjNTTZ0vqPozNysjASQS3UcgwwWVpYvN7r-T_I/edit#gid=1653513259",
          "cachedResultName": "predicted food data for low wastage"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1QZXX_gjNTTZ0vqPozNysjASQS3UcgwwWVpYvN7r-T_I",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1QZXX_gjNTTZ0vqPozNysjASQS3UcgwwWVpYvN7r-T_I/edit?usp=drivesdk",
          "cachedResultName": "Restaurant stock predictions"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "id": "ScSS2KxGQULuPtdy",
          "name": "Google Sheets- test"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "a9f91c73-41e6-4955-bbd5-1e9ff658df1e",
      "name": "创建电子邮件摘要",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1200,
        420
      ],
      "parameters": {
        "text": "={{ $('AI Forecast Generator\t').item.json.output }}",
        "options": {
          "systemMessage": "You are an intelligent assistant tasked with drafting a clear, concise and professional summary email based on forecast data for a restaurant. You’ll receive an array of forecast objects in this format:\n\n[\n  {\n    \"Date\": \"2025-07-14\",\n    \"Dish\": \"Pasta\",\n    \"predicted Sales\": 60,\n    \"Raw Material\": \"Cream\",\n    \"predicted Use (kg)\": 3.6,\n    \"predicted food waste reduce (kg)\": 0.1\n  },\n  ...\n]\n\nYour goal:\n1. Open with a friendly greeting.\n2. Provide a one-sentence overview: mention the date, how many dishes are forecasted, and overall expected food waste reduction.\n3. List each dish in its own bullet point. For each dish list:\n   - Total predicted sales.\n   - The raw materials needed with predicted usage.\n   - Highlight expected waste reduction (if >0).\n4. Conclude with a recommended action, something like: “Please adjust tomorrow’s procurement based on these forecasts to minimize waste.” Offer to discuss specifics if needed.\n5. Keep tone professional but warm.\n\nExample style:\n\n“Hi [Manager Name],\n\nHere’s your forecast summary for July 14, 2025:\n\n- **Pasta (60 servings):** You will need Cream (3.6 kg), Flour (6 kg) and Tomato (12 kg), reducing expected food waste by approx. 1.9 kg.\n- **Pizza (50 servings):** Cheese 10 kg, waste reduction ~0.5 kg.\n- **Salad (40 servings):** Lettuce 8 kg, no predicted waste reduction.\n\nOverall, this forecast anticipates around 2.4 kg less waste across all dishes.\n\nPlease adjust tomorrow’s orders accordingly to minimize waste. Let me know if you'd like a deeper breakdown!”\n\nReturn only the email body text (no JSON or markdown fences).\n"
        },
        "promptType": "define"
      },
      "executeOnce": true,
      "typeVersion": 1.9,
      "alwaysOutputData": true
    },
    {
      "id": "1c9cec9e-d90b-4479-b569-9ef2726a6987",
      "name": "发送电子邮件预测报告",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1560,
        420
      ],
      "webhookId": "29a66a86-3fbb-49c3-bcd1-e697edfb19ce",
      "parameters": {
        "sendTo": "abc@gmail.com",
        "message": "={{ $json.output }}",
        "options": {},
        "subject": "Next monday prediction",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "PcTqvGU9uCunfltE",
          "name": "Gmail account - test"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "1f400e94-9bc2-414c-aedc-6f7f86c887d0",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -300,
        140
      ],
      "parameters": {
        "width": 150,
        "height": 480,
        "content": "每天启动工作流以执行食物浪费预测。"
      },
      "typeVersion": 1
    },
    {
      "id": "65a5d131-945b-40ee-bf66-b33f4600d97c",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -80,
        140
      ],
      "parameters": {
        "color": 3,
        "width": 150,
        "height": 480,
        "content": "从 Google Sheets 读取过去的食物使用和销售数据以了解趋势。"
      },
      "typeVersion": 1
    },
    {
      "id": "8cc25bd0-38bf-485a-a75b-7bed2ae24b1e",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        360,
        140
      ],
      "parameters": {
        "color": 6,
        "width": 290,
        "height": 480,
        "content": "使用 Gemini AI 预测食物需求并推荐减少浪费的方法。"
      },
      "typeVersion": 1
    },
    {
      "id": "3afb2901-aeaa-49a2-920a-806ce0e5dc9d",
      "name": "便签3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        140
      ],
      "parameters": {
        "color": 4,
        "width": 150,
        "height": 480,
        "content": "将 AI 生成的预测存储回专门的预测 Google Sheet。"
      },
      "typeVersion": 1
    },
    {
      "id": "458c1f5e-0a7a-4981-afd6-efc64c286e5d",
      "name": "便签4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        740,
        140
      ],
      "parameters": {
        "color": 3,
        "width": 150,
        "height": 480,
        "content": "将 AI 响应解析为结构化和干净的格式以进行报告。"
      },
      "typeVersion": 1
    },
    {
      "id": "5917d966-9260-4ace-baf9-4ecd666021f4",
      "name": "便签5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        140,
        140
      ],
      "parameters": {
        "color": 4,
        "width": 150,
        "height": 480,
        "content": "清理和组织原始数据为适合 AI 处理的结构。"
      },
      "typeVersion": 1
    },
    {
      "id": "16b34b52-3d0e-4dc5-95eb-8eaecd7fdfa3",
      "name": "便签6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1540,
        140
      ],
      "parameters": {
        "width": 150,
        "height": 480,
        "content": "通过电子邮件向决策者(厨房、经理等)传递预测报告。"
      },
      "typeVersion": 1
    },
    {
      "id": "08d6406a-b9ef-4b10-90cf-7d4c98a60921",
      "name": "便签7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1180,
        140
      ],
      "parameters": {
        "color": 5,
        "width": 290,
        "height": 480,
        "content": "创建简洁、人性化的预测摘要。"
      },
      "typeVersion": 1
    },
    {
      "id": "5a088b10-604f-475f-a611-3b147ae9ce0c",
      "name": "便签8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        220,
        -340
      ],
      "parameters": {
        "width": 640,
        "height": 260,
        "content": "## 📌 工作流目的:餐厅食物浪费预测系统"
      },
      "typeVersion": 1
    },
    {
      "id": "28b4b3dc-5e7c-41a7-8dda-4cf67eacef0a",
      "name": "聊天模型",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        400,
        640
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-2.5-pro"
      },
      "credentials": {
        "googlePalmApi": {
          "id": "RvSkIBjP48ORJKhU",
          "name": "Google Gemini(PaLM) Api account - test"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f0e9f8d4-4a86-4167-b833-5ac3ab3a5545",
      "name": "思维",
      "type": "@n8n/n8n-nodes-langchain.toolThink",
      "position": [
        520,
        640
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "f7e04c0c-cba5-46f4-bc47-fb26731f2375",
      "name": "查询用聊天模型",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        1220,
        640
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-2.5-pro"
      },
      "credentials": {
        "googlePalmApi": {
          "id": "RvSkIBjP48ORJKhU",
          "name": "Google Gemini(PaLM) Api account - test"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "dbddf020-ef31-43b4-85a9-3f459ac56d6b",
      "name": "思考用思维",
      "type": "@n8n/n8n-nodes-langchain.toolThink",
      "position": [
        1340,
        640
      ],
      "parameters": {},
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "f6380285-b1c9-49e1-82bf-12c2db027369",
  "connections": {
    "Mind": {
      "ai_tool": [
        [
          {
            "node": "AI Forecast Generator\t",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Forecast Generator\t",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Daily Trigger": {
      "main": [
        [
          {
            "node": "Fetch Historical Sales Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mind For Think": {
      "ai_tool": [
        [
          {
            "node": "Create Email Summary\t",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Chat Model for Query ": {
      "ai_languageModel": [
        [
          {
            "node": "Create Email Summary\t",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Create Email Summary\t": {
      "main": [
        [
          {
            "node": "Send Email Forecast Report\t",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Forecast Generator\t": {
      "main": [
        [
          {
            "node": "Clean & Structure AI Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clean & Structure AI Output": {
      "main": [
        [
          {
            "node": "Log Forecast to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Historical Sales Data": {
      "main": [
        [
          {
            "node": "Format Data for AI Forecasting",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Forecast to Google Sheets": {
      "main": [
        [
          {
            "node": "Create Email Summary\t",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Data for AI Forecasting": {
      "main": [
        [
          {
            "node": "AI Forecast Generator\t",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

高级 - 文档提取, AI 摘要总结

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
高级
节点数量21
分类2
节点类型8
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

作者
Oneclick AI Squad

Oneclick AI Squad

@oneclick-ai

The 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.

外部链接
在 n8n.io 查看

分享此工作流