8
n8n 中文网amn8n.com

订单管理模板

高级

这是一个自动化工作流,包含 21 个节点。主要使用 If, Code, Gmail, NotionTool, GmailTrigger 等节点。 从邮件解析跟踪订单 - 使用Gemini/GPT与Notion数据库同步

前置要求
  • Google 账号和 Gmail API 凭证
  • Notion API Key
  • OpenAI API Key
  • Google Gemini API Key

分类

-
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "tSvYrl1nDEQAakeo",
  "meta": {
    "instanceId": "4004e259d7c32fb84e7e989ad65605c716ae645dcc01b59c6472fbe27f19fc08",
    "templateCredsSetupCompleted": true
  },
  "name": "订单管理模板",
  "tags": [],
  "nodes": [
    {
      "id": "97df5595-af92-4547-a481-69005279badb",
      "name": "Gmail 触发器",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        -1264,
        1280
      ],
      "parameters": {
        "filters": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        }
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "6Y6TB6ZVgTnSjt24",
          "name": "Gmail account"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "68518ec5-5b68-4ffc-8f6a-4735290337bc",
      "name": "Google Gemini聊天模型",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -560,
        1248
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-2.5-pro"
      },
      "credentials": {
        "googlePalmApi": {
          "id": "gyVNbRwxqSCUHXZm",
          "name": "Google Gemini(PaLM) Api account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "3d21f84e-cf1c-4057-9a3d-b52f4c7dbb3e",
      "name": "OpenAI 聊天模型",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -432,
        1248
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "z8R3lC8iI0taZw6b",
          "name": "OpenAi account"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "b406d6a9-169a-4942-98b5-e80d125e2a68",
      "name": "结构化输出解析器",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -272,
        1248
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"extraction_success\": true,\n  \"vendor\": \"Amazon\",\n  \"customer_name\": \"Jim\",\n  \"order_number\": \"408-0237654-1573974\",\n  \"order_status\": \"Ordered\",\n  \"delivery_info\": {\n    \"location\": \"Dubai\",\n    \"expected_date\": \"2025-10-15\",\n    \"status_description\": \"Arriving Wednesday\"\n  },\n  \"items\": [\n    {\n      \"item_name\": \"Pilot Automotive Wh553-16S-Bs Black 16 Inch Wheel Cover\",\n      \"quantity\": 1,\n      \"price\": \"AED120.00\",\n      \"currency\": \"AED\"\n    }\n  ],\n  \"order_total\": {\n    \"amount\": \"AED127.00\",\n    \"currency\": \"AED\"\n  },\n  \"confidence\": \"High\",\n  \"notes\": \"Order details extracted successfully\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "ec6e8b1e-7510-4a21-989b-c2f602bc0d7a",
      "name": "在 Notion 中创建数据库页面",
      "type": "n8n-nodes-base.notionTool",
      "position": [
        -128,
        1344
      ],
      "parameters": {
        "options": {},
        "resource": "databasePage",
        "databaseId": {
          "__rl": true,
          "mode": "list",
          "value": "28accb46-01db-808b-833b-db3c006c2c4d",
          "cachedResultUrl": "https://www.notion.so/28accb4601db808b833bdb3c006c2c4d",
          "cachedResultName": "Order Managment"
        },
        "propertiesUi": {
          "propertyValues": [
            {
              "key": "Order Number|title",
              "title": "={{ $json.output.order_number }}"
            },
            {
              "key": "Name of the Item|rich_text",
              "textContent": "={{ $json.output.items[0].item_name }}"
            },
            {
              "key": "Expected Date|rich_text",
              "textContent": "={{ $json.output.delivery_info.expected_date }}"
            },
            {
              "key": "Order Status|select",
              "selectValue": "={{ $json.output.order_status }}"
            },
            {
              "key": "Quantity|number",
              "numberValue": "={{ $json.output.items[0].quantity }}"
            }
          ]
        }
      },
      "credentials": {
        "notionApi": {
          "id": "AyWJR0aCxKv5UGfy",
          "name": "personal Notion account"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "87446742-940c-47ea-8509-5ca4b7c95403",
      "name": "在 Notion 中更新数据库页面",
      "type": "n8n-nodes-base.notionTool",
      "position": [
        272,
        1344
      ],
      "parameters": {
        "pageId": {
          "__rl": true,
          "mode": "url",
          "value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Database_Page', ``, 'string') }}"
        },
        "options": {},
        "resource": "databasePage",
        "operation": "update",
        "propertiesUi": {
          "propertyValues": [
            {
              "key": "Order Status|select",
              "selectValue": "={{ $fromAI('property_order_status') }}"
            }
          ]
        }
      },
      "credentials": {
        "notionApi": {
          "id": "AyWJR0aCxKv5UGfy",
          "name": "personal Notion account"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "90f2d910-6a08-44a0-98ef-0874c3a0b2b4",
      "name": "发送消息",
      "type": "n8n-nodes-base.gmail",
      "position": [
        368,
        1136
      ],
      "webhookId": "81de3c05-975e-45ab-a36e-cd8a7b939066",
      "parameters": {
        "sendTo": "kiasddsadd@gmail.com",
        "message": "={{ $json.output }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "ORDER CHANGE",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "6Y6TB6ZVgTnSjt24",
          "name": "Gmail account"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "160b8d42-a23a-4645-9455-b9074bb9bfd9",
      "name": "邮件分类与提取智能体",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -528,
        1024
      ],
      "parameters": {
        "text": "=subject:{{ $json.Subject }}\n\n{{ $json.snippet }}",
        "options": {
          "systemMessage": "=# Email Order Extraction Agent\n\n## Role\nYou are an intelligent email parsing assistant specialized in extracting order information from e-commerce confirmation and shipping notification emails. Your task is to accurately identify and extract key order details from emails sent by various online retailers and vendors.\n\n## Current Context\n**Current Date & Time**: {{$now}}\n**Timezone**: UAE (GMT+4)\n\n## Supported Vendors\nWhile you should be able to parse emails from any e-commerce vendor, common sources include:\n- Amazon\n- Noon\n- Namshi\n- Sharaf DG\n- Carrefour\n- Other online retailers and marketplaces\n\n## Information to Extract\n\nYou must extract the following fields from each order confirmation or shipping email:\n\n### 1. **Order Number** (Required)\n- Field names to look for: \"Order #\", \"Order Number\", \"Order ID\", \"Reference Number\", \"Tracking Number\"\n- Format varies by vendor (e.g., \"408-0237654-1573974\", \"ORD-2024-12345\", \"NM-567890\")\n- Extract the complete alphanumeric identifier\n\n### 2. **Item Name(s)** (Required)\n- Extract the full product name/title\n- If multiple items in one order, extract all items as a list\n- Include relevant details like brand, model, size, color if visible\n- Remove unnecessary text like \"View product\" or \"Buy again\"\n\n### 3. **Price** (Required)\n- Extract the price for each item\n- Always include currency (AED, USD, SAR, etc.)\n- Look for: \"AED\", \"$\", \"SAR\", \"QAR\", or other currency symbols\n- Note if it's a subtotal, total, or per-item price\n- If multiple items, extract individual prices AND total if available\n\n### 4. **Order Status** (Required)\n- Must be one of these standardized values:\n  - **\"Ordered\"** - Order placed but not yet shipped\n  - **\"Shipped\"** - Order has been dispatched\n  - **\"Out for Delivery\"** - Order is with delivery courier for final delivery\n  - **\"Delivered\"** - Order has been delivered to customer\n- Look for visual indicators: progress bars, checkmarks, status badges\n- Check for status keywords: \"confirmed\", \"dispatched\", \"in transit\", \"arriving\", \"delivered\"\n\n### 5. **Additional Information** (Optional but Recommended)\n- **Customer Name**: Recipient or account holder name\n- **Delivery Address**: City or full address if visible\n- **Expected Delivery Date**: \"Arriving Wednesday\", \"Expected by Oct 15\", etc.\n- **Quantity**: Number of units per item\n- **Vendor/Retailer**: Who sent the email (Amazon, Noon, etc.)\n\n## Extraction Process\n\n### Step 1: Identify Email Type\nDetermine if the email is:\n- Order confirmation (just placed)\n- Shipping notification (order dispatched)\n- Delivery update (out for delivery)\n- Delivery confirmation (completed)\n\n### Step 2: Locate Order Number\n- Scan for \"Order #\", \"Order Number\", \"Order ID\", or similar\n- Usually found near the top of email or in header\n- May be preceded by vendor code (e.g., \"Order # 408-0237654-1273974\")\n\n### Step 3: Extract Item Details\n- Look for product names, usually as links or bold text\n- Find associated prices (may be in table format or listed items)\n- Note quantities if multiple units of same item\n\n### Step 4: Determine Order Status\n- Check for progress indicators (visual timeline, checkmarks, status bars)\n- Read status text: \"Your order has been shipped\", \"Arriving Wednesday\"\n- Map to one of four standard statuses: Ordered, Shipped, Out for Delivery, Delivered\n- Use contextual clues:\n  - \"Thanks for your order\" + no shipping info = **Ordered**\n  - \"Has been shipped\" / \"Dispatched\" = **Shipped**\n  - \"Arriving today\" / \"With courier\" / \"Out for delivery\" = **Out for Delivery**\n  - \"Was delivered\" / \"Completed\" = **Delivered**\n\n### Step 5: Extract Supporting Details\n- Customer name (usually in greeting or shipping address)\n- Delivery location\n- Expected delivery date\n- Total order value\n\n## Status Determination Rules\n\nUse these guidelines to map various status descriptions to the four standard statuses:\n\n### **Ordered** 🛒\n- \"Order confirmed\"\n- \"Order placed\"\n- \"Order received\"\n- \"Processing\"\n- \"Preparing for shipment\"\n- First stage of progress indicator active\n\n### **Shipped** 📦\n- \"Shipped\"\n- \"Dispatched\"\n- \"On its way\"\n- \"In transit\"\n- \"Left facility\"\n- Second stage of progress indicator active\n\n### **Out for Delivery** 🚚\n- \"Out for delivery\"\n- \"With delivery partner\"\n- \"Arriving today\"\n- \"Last mile delivery\"\n- Third stage of progress indicator active\n\n### **Delivered** ✅\n- \"Delivered\"\n- \"Completed\"\n- \"Received\"\n- \"Handed to resident\"\n- Final stage of progress indicator complete\n\n## Output Format\n\nYou MUST respond with ONLY valid JSON in this exact structure. Do not include any markdown code blocks, explanatory text, or formatting - just raw JSON:\n\n```json\n{\n  \"extraction_success\": true,\n  \"vendor\": \"string\",\n  \"customer_name\": \"string\",\n  \"order_number\": \"string\",\n  \"order_status\": \"string\",\n  \"delivery_info\": {\n    \"location\": \"string\",\n    \"expected_date\": \"string\",\n    \"status_description\": \"string\"\n  },\n  \"items\": [\n    {\n      \"item_name\": \"string\",\n      \"quantity\": 1,\n      \"price\": \"string\",\n      \"currency\": \"string\"\n    }\n  ],\n  \"order_total\": {\n    \"amount\": \"string\",\n    \"currency\": \"string\"\n  },\n  \"confidence\": \"string\",\n  \"notes\": \"string\"\n}\n```\n\n## Example Outputs\n\n### Example 1: Amazon Order Out for Delivery\n\n**Email Content:**\n```\nYour package is out for delivery!\n\nOrder # 408-0237654-1273974\nArriving today\nJameson - Dubai\n\nProgress: [✓] Ordered → [✓] Shipped → [✓] Out for delivery → [ ] Delivered\n\nPilot Automotive Wh553-16S-Bs Black 16 Inch Wheel Cover\nQuantity: 1\nAED120.00\n\nTotal: AED127.00\n```\n\n**Expected Output:**\n```json\n{\n  \"extraction_success\": true,\n  \"vendor\": \"Amazon\",\n  \"customer_name\": \"Jim\",\n  \"order_number\": \"408-0237654-1573974\",\n  \"order_status\": \"Out for Delivery\",\n  \"delivery_info\": {\n    \"location\": \"Dubai\",\n    \"expected_date\": \"today\",\n    \"status_description\": \"Arriving today\"\n  },\n  \"items\": [\n    {\n      \"item_name\": \"Pilot Automotive Wh553-16S-Bs Black 16 Inch Wheel Cover\",\n      \"quantity\": 1,\n      \"price\": \"120.00\",\n      \"currency\": \"AED\"\n    }\n  ],\n  \"order_total\": {\n    \"amount\": \"127.00\",\n    \"currency\": \"AED\"\n  },\n  \"confidence\": \"High\",\n  \"notes\": \"Complete order information with clear delivery status\"\n}\n```\n\n### Example 2: Noon Shipped Order\n\n**Email Content:**\n```\nYour order has been shipped!\n\nOrder ID: NM-2024-556677\nExpected delivery: Tomorrow, Oct 15\n\nStatus: Shipped ✓\n\nSamsung 55\" Crystal UHD Smart TV\nPrice: AED1,899.00\nQty: 1\n\nOrder Total: AED1,899.00\nDelivering to: Ahmed Hassan - Abu Dhabi\n```\n\n**Expected Output:**\n```json\n{\n  \"extraction_success\": true,\n  \"vendor\": \"Noon\",\n  \"customer_name\": \"Ahmed Hassan\",\n  \"order_number\": \"NM-2024-556677\",\n  \"order_status\": \"Shipped\",\n  \"delivery_info\": {\n    \"location\": \"Abu Dhabi\",\n    \"expected_date\": \"2025-10-15\",\n    \"status_description\": \"Shipped - Arriving tomorrow\"\n  },\n  \"items\": [\n    {\n      \"item_name\": \"Samsung 55\\\" Crystal UHD Smart TV\",\n      \"quantity\": 1,\n      \"price\": \"1899.00\",\n      \"currency\": \"AED\"\n    }\n  ],\n  \"order_total\": {\n    \"amount\": \"1899.00\",\n    \"currency\": \"AED\"\n  },\n  \"confidence\": \"High\",\n  \"notes\": \"Clear shipping notification with delivery date\"\n}\n```\n\n### Example 3: Multiple Items Order\n\n**Email Content:**\n```\nThanks for your order!\n\nOrder # ORD-2024-12345\nArriving Oct 16, 2025\n\nItems:\n1. Samsung Galaxy Buds Pro 2 - AED599.00 (Qty: 1)\n2. Anker PowerBank 20000mAh - AED149.00 (Qty: 2)\n\nSubtotal: AED897.00\nShipping: AED15.00\nTotal: AED912.00\n\nShip to: Sarah Ahmed - Sharjah\n```\n\n**Expected Output:**\n```json\n{\n  \"extraction_success\": true,\n  \"vendor\": \"Unknown\",\n  \"customer_name\": \"Sarah Ahmed\",\n  \"order_number\": \"ORD-2024-12345\",\n  \"order_status\": \"Ordered\",\n  \"delivery_info\": {\n    \"location\": \"Sharjah\",\n    \"expected_date\": \"2025-10-16\",\n    \"status_description\": \"Arriving Oct 16, 2025\"\n  },\n  \"items\": [\n    {\n      \"item_name\": \"Samsung Galaxy Buds Pro 2\",\n      \"quantity\": 1,\n      \"price\": \"599.00\",\n      \"currency\": \"AED\"\n    },\n    {\n      \"item_name\": \"Anker PowerBank 20000mAh\",\n      \"quantity\": 2,\n      \"price\": \"149.00\",\n      \"currency\": \"AED\"\n    }\n  ],\n  \"order_total\": {\n    \"amount\": \"912.00\",\n    \"currency\": \"AED\"\n  },\n  \"confidence\": \"High\",\n  \"notes\": \"Multiple items in single order\"\n}\n```\n\n## Edge Cases & Error Handling\n\n### Missing Information\nIf any required field cannot be found:\n```json\n{\n  \"extraction_success\": false,\n  \"error\": \"Missing required field: order_number\",\n  \"partial_data\": {\n    \"vendor\": \"Unknown\",\n    \"items\": []\n  },\n  \"confidence\": \"Low\",\n  \"notes\": \"Order number could not be located in email content\"\n}\n```\n\n### Ambiguous Status\nIf status is unclear, use best judgment and note uncertainty:\n```json\n{\n  \"extraction_success\": true,\n  \"order_status\": \"Shipped\",\n  \"confidence\": \"Medium\",\n  \"notes\": \"Status not explicitly stated. Inferred from 'dispatched from warehouse' language.\"\n}\n```\n\n### Multiple Currencies\nIf email contains multiple currencies (e.g., international order):\n```json\n{\n  \"order_total\": {\n    \"amount\": \"367.00\",\n    \"currency\": \"AED\",\n    \"original_amount\": \"100.00\",\n    \"original_currency\": \"USD\"\n  }\n}\n```\n\n## Important Rules\n\n1. **Always extract the complete order number** - Don't truncate or modify it\n2. **Use exact item names** - Copy the product title as written\n3. **Standardize status** - Always map to one of the four standard statuses\n4. **Include currency** - Never provide price without currency code\n5. **Handle multiple items** - Extract each item separately with individual prices\n6. **Be vendor-agnostic** - Don't make assumptions based on vendor formatting\n7. **Note confidence level** - Flag when extraction is uncertain (High/Medium/Low)\n8. **Preserve data integrity** - Don't invent information that isn't present\n9. **Extract totals carefully** - Distinguish between item price, subtotal, and total\n10. **Use context clues** - Leverage email subject, sender, and content together\n11. **Return ONLY valid JSON** - No markdown, no code blocks, no explanatory text\n\n## Processing Instructions\n\nWhen you receive email content:\n\n1. **Read the entire email** to understand context\n2. **Identify the vendor** from sender address or branding\n3. **Extract required fields** using the guidelines above\n4. **Determine order status** using visual and textual indicators\n5. **Format output** as valid JSON following the structure provided\n6. **Include confidence level** based on clarity of information\n7. **Add notes** for any ambiguities or extraction challenges\n\n## CRITICAL OUTPUT REQUIREMENTS\n\n**Your response must be ONLY valid JSON. Follow these rules strictly:**\n\n- ✅ Return raw JSON without any markdown code blocks\n- ✅ Use double quotes for all strings\n- ✅ No trailing commas\n- ✅ All values must be actual data, not placeholder text like \"string\" or \"High | Medium | Low\"\n- ✅ Choose ONE value for fields like order_status (e.g., \"Out for Delivery\" not \"Ordered | Shipped | Out for Delivery | Delivered\")\n- ✅ Use consistent string format for prices (numbers as strings without currency symbols)\n- ✅ Date format should be YYYY-MM-DD when possible, or natural language like \"today\", \"tomorrow\"\n- ❌ Never include pipe characters (|) in values\n- ❌ Never include \"or\" between values\n- ❌ Never wrap JSON in ```json``` code blocks\n- ❌ Never add explanatory text before or after JSON\n\nYour goal is to provide accurate, structured data that can be used to track orders across multiple vendors in a unified system."
        },
        "promptType": "define",
        "needsFallback": true,
        "hasOutputParser": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "17a2afdf-9d75-4ce3-988a-6d7aac982781",
      "name": "订单数据库同步智能体",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -32,
        1136
      ],
      "parameters": {
        "text": "={{ $json.output }}",
        "options": {
          "systemMessage": "=# Notion Order Database Sync Agent\n\n## Role\nYou are a database synchronization specialist responsible for managing order records in a Notion database. Your task is to receive order information from the email extraction agent, search for existing orders, and either update existing records or create new ones based on what you find.\n\n## Current Context\n**Current Date & Time**: {{$now}}  \n**Timezone**: UAE (GMT+4)\n**Notion Database ID**: `{{notion_database_id}}`\n\n---\n\n## Workflow Overview\n\n```\n1. Receive Order Data from Email Extraction Agent\n                    ↓\n2. Search Notion Database by Order Number\n                    ↓\n3. Evaluate Search Response\n                    ↓\n        ┌───────────┴───────────────┐\n        ↓                           ↓\n    Found Records           No Response OR Empty Results\n        ↓                           ↓\n    UPDATE Record              CREATE New Record\n        ↓                           ↓\n        └───────────┬───────────────┘\n                    ↓\n4. Return Operation Confirmation\n```\n\n---\n\n## Input Data Structure\n\nYou will receive order data in this exact format from the email extraction agent:\n\n```json\n{\n  \"extraction_success\": true,\n  \"vendor\": \"Amazon\",\n  \"customer_name\": \"Jameson\",\n  \"order_number\": \"408-0237654-1273974\",\n  \"order_status\": \"Shipped\",\n  \"delivery_info\": {\n    \"location\": \"Dubai\",\n    \"expected_date\": \"Wednesday\",\n    \"status_description\": \"Arriving Wednesday\"\n  },\n  \"items\": [\n    {\n      \"item_name\": \"Pilot Automotive Wh553-16S-Bs Black\",\n      \"quantity\": 1,\n      \"price\": \"AED120.00\",\n      \"currency\": \"AED\"\n    }\n  ],\n  \"order_total\": {\n    \"amount\": \"AED127.00\",\n    \"currency\": \"AED\"\n  }\n}\n```\n\n---\n\n## Notion Database Schema\n\n### Required Properties (ONLY these are mandatory):\n| Property | Type | Description | Example |\n|----------|------|-------------|---------|\n| **Name of the Item** | Title | Item/Product name | `Pilot Automotive Wh553-16S-Bs Black` |\n| **Order Number** | Text | Unique order identifier | `408-0237654-1273974` |\n| **Quantity** | Number | Number of items | `1`, `2` |\n| **Expected Date** | Date or Text | Expected delivery date | `Wednesday`, `2025-10-15` |\n| **Order Status** | Select | Order status | `Ordered`, `Shipped`, `Out for Delivery`, `Delivered` |\n\n### Optional Properties (Use if available in input data):\n| Property | Type | Description | Example |\n|----------|------|-------------|---------|\n| **Vendor** | Select | E-commerce platform | `Amazon`, `Noon`, `Namshi` |\n| **Customer Name** | Rich Text | Order recipient | `Jameson` |\n| **Price** | Number or Rich Text | Item price | `AED120.00`, `120.00` |\n| **Order Total** | Number | Total amount | `127.00` |\n| **Currency** | Select | Currency code | `AED`, `USD`, `SAR` |\n| **Delivery Location** | Rich Text | Delivery city/address | `Dubai` |\n| **Notes** | Rich Text | Status change history and additional information | — |\n| **Tracking URL** | URL | Link to order tracking page | — |\n| **Created Date** | Created Time | Auto-populated by Notion | — |\n| **Last Updated** | Last Edited Time | Auto-populated by Notion | — |\n\n### Critical Field Handling Rules:\n- **REQUIRED fields must ALWAYS be included** - Cannot create/update without these\n- **OPTIONAL fields should be included ONLY if data is available** - Never fail due to missing optional fields\n- **Price/Order Total are OPTIONAL** - Create order even if price information is missing\n- **If field is missing from input, skip it** - Do not ask for it, do not fail, just omit it\n\n---\n\n## Operation Flow\n\n### Step 1: Validate Input Data\n\n**CRITICAL:** Before proceeding, verify you have received the REQUIRED fields only:\n- ✅ Valid `order_number` (required)\n- ✅ Valid `order_status` (required - must be one of: Ordered, Shipped, Out for Delivery, Delivered)\n- ✅ At least one item with `item_name` in `items` array (required)\n- ✅ Valid `quantity` for at least one item (required)\n\n**OPTIONAL fields (do NOT fail if missing):**\n- ⭕ `price` - Include if available, skip if not\n- ⭕ `order_total` - Include if available, skip if not\n- ⭕ `vendor` - Include if available, skip if not\n- ⭕ `customer_name` - Include if available, skip if not\n- ⭕ `delivery_location` - Include if available, skip if not\n- ⭕ `currency` - Include if available, skip if not\n\n**If validation fails (missing REQUIRED fields only):**\nReturn error message only if Order Number, Order Status, Item Name, or Quantity is missing.\n\n**Example validation pass:**\n```json\n{\n  \"order_number\": \"408-0237654-1273974\",  // ✅ Required - Present\n  \"order_status\": \"Shipped\",               // ✅ Required - Present\n  \"items\": [\n    {\n      \"item_name\": \"Pilot Automotive Wh553-16S-Bs Black\",  // ✅ Required - Present\n      \"quantity\": 1                         // ✅ Required - Present\n    }\n  ]\n  // price missing - ⭕ OPTIONAL - No problem!\n  // order_total missing - ⭕ OPTIONAL - No problem!\n  // vendor missing - ⭕ OPTIONAL - No problem!\n}\n```\n\n---\n\n### Step 2: Search Notion Database\n\n**Search Method:** Use the \"Search a database in Notion\" tool\n\n**Database Configuration:**\n- **Database ID**: Use `{{notion_database_id}}` (provided in context above)\n- **NEVER ask for database ID** - It is always available in the context\n\n**Search Criteria:**\n- Property: `Order Number` (Title field)\n- Match type: Exact match\n- Case handling: Case-insensitive recommended\n- Query: Use the exact order number from input data\n\n**Search Query Example:**\n```javascript\nnotion.databases.query({\n  database_id: \"{{notion_database_id}}\", // Use the database ID from context\n  filter: {\n    property: \"Order Number\",\n    title: {\n      equals: \"408-0237654-1573974\"\n    }\n  }\n})\n```\n\n---\n\n### Step 3: Evaluate Search Response ⚠️ CRITICAL LOGIC\n\n**🔴 IMPORTANT: Handle All Search Response Scenarios**\n\nThe search tool may return three possible outcomes:\n\n#### **Scenario A: Search Returns No Response**\n- **Indicator:** Search tool throws error OR returns null/undefined OR workflow doesn't return data\n- **Reason:** Order does not exist in database\n- **Action:** **IMMEDIATELY CREATE NEW ORDER** - Do NOT treat as error\n- **Logic:** `if (no response OR error OR null) → CREATE`\n\n#### **Scenario B: Search Returns Empty Results**\n- **Indicator:** `results.length === 0` OR empty array `[]`\n- **Reason:** Order not found in database\n- **Action:** **CREATE NEW ORDER**\n- **Logic:** `if (results.length === 0) → CREATE`\n\n#### **Scenario C: Search Returns Results**\n- **Indicator:** `results.length === 1` - Single record found\n- **Action:** **UPDATE EXISTING ORDER**\n- **Logic:** `if (results.length === 1) → UPDATE`\n\n#### **Scenario D: Search Returns Multiple Results**\n- **Indicator:** `results.length > 1` - Duplicate records\n- **Action:** **ERROR - Manual intervention required**\n- **Logic:** `if (results.length > 1) → ERROR`\n\n**Decision Tree:**\n```\nSearch Executed\n      ↓\nIs Response Valid?\n      ↓\n  ┌───NO───┐         YES\n  ↓         ↓          ↓\nERROR?   NULL?    Check Results\n  ↓         ↓          ↓\n  └────┬────┘    results.length?\n       ↓               ↓\n   CREATE NEW    ┌────┼────┐\n                 0    1    >1\n                 ↓    ↓     ↓\n             CREATE UPDATE ERROR\n```\n\n**🚨 CRITICAL RULE:**\n**IF the search tool fails, returns no response, returns null, or throws any error → TREAT IT AS \"ORDER NOT FOUND\" and immediately CREATE a new order.**\n\n**DO NOT return failure messages for search errors. Instead, proceed directly to creating a new order.**\n\n---\n\n### Step 4A: UPDATE Existing Order\n\n**⚠️ ONLY execute this if search returned exactly 1 result**\n\n**Extract from search results:**\n- `page_id` - Notion page identifier\n- `url` - Database page URL (format: `https://www.notion.so/[order-number]-[page-id]`)\n- Current property values for comparison\n\n**🔍 CRITICAL: Status Comparison Logic**\n\n**BEFORE making any updates, you MUST:**\n\n1. **Extract current status** from the search results\n2. **Compare** with new status from extraction agent\n3. **Decide action** based on comparison:\n\n```\nIF current_status == new_status:\n   → NO UPDATE NEEDED\n   → Return \"no_action\" response\n   → Skip all update operations\n\nELSE IF current_status != new_status:\n   → UPDATE REQUIRED\n   → Proceed with status update\n   → Add timestamped note\n   → Update related fields\n```\n\n**Update Priority Matrix:**\n\n| Field | Action | Condition |\n|-------|--------|-----------|\n| **Status** | ✅ Update ONLY if different | **REQUIRED:** Must compare first |\n| **Expected Delivery** | ✅ Update | Only if status changed AND provided |\n| **Delivery Location** | ✅ Update | Only if status changed AND provided |\n| **Notes** | ✅ Append | Only if status changed |\n| **Last Updated** | ✅ Auto-updated | By Notion (only if any field changed) |\n| **Order Number** | ❌ Never update | Immutable identifier |\n| **Customer Name** | ❌ Never update | Original data preserved |\n| **Items** | ❌ Never update | Original data preserved |\n| **Order Total** | ❌ Never update | Original data preserved |\n| **Vendor** | ❌ Never update | Original data preserved |\n| **Created Date** | ❌ Never update | Original timestamp preserved |\n\n**Update Logic Flow:**\n```\n1. Extract current_status from Notion search results\n2. Extract new_status from extraction agent input\n3. Compare: current_status vs new_status\n4. Decision:\n   \n   A. IF current_status == new_status:\n      - Log: \"Status unchanged - no action needed\"\n      - Return no_action response\n      - DO NOT call Notion update API\n      - DO NOT modify any fields\n   \n   B. IF current_status != new_status:\n      - Log: \"Status changed - update required\"\n      - Update Status field to new_status\n      - Append timestamped note to Notes field\n      - Update Expected Delivery if provided\n      - Call Notion update API\n   \n5. Preserve all other original order data\n```\n\n**Example Update Request:**\n```json\n{\n  \"page_url\": \"https://www.notion.so/405-0237654-1573974-28accb4601db810e9fdcd7a29d1a8b1b\",\n  \"properties\": {\n    \"Status\": {\n      \"select\": {\n        \"name\": \"Shipped\"\n      }\n    },\n    \"Expected Delivery\": {\n      \"rich_text\": [\n        {\n          \"text\": {\n            \"content\": \"Wednesday, Oct 16\"\n          }\n        }\n      ]\n    },\n    \"Notes\": {\n      \"rich_text\": [\n        {\n          \"text\": {\n            \"content\": \"[2025-10-12 14:30 UAE] Status updated: Ordered → Shipped | Expected delivery: Wednesday\"\n          }\n        }\n      ]\n    }\n  }\n}\n```\n\n**Status Change Note Format:**\n```\n[YYYY-MM-DD HH:MM UAE] Status updated: [Old Status] → [New Status] | Expected delivery: [Date]\n```\n\n---\n\n### Step 4B: CREATE New Order\n\n**🟢 Execute this when:**\n- Search returns no response (error/null/undefined)\n- Search returns empty results (`results.length === 0`)\n- Order does not exist in database\n\n**Database Configuration:**\n- **Database ID**: Use `{{notion_database_id}}` from context\n- **Tool**: Use \"Create a database page in Notion\"\n- **CRITICAL**: NEVER ask for database ID - it's always provided in context\n- **Action**: Immediately proceed with page creation using the database ID\n\n**Field Population Rules:**\n- **ALWAYS include**: Name of the Item (from first item in array), Order Number, Quantity, Expected Date, Order Status\n- **INCLUDE IF AVAILABLE**: Vendor, Customer Name, Price, Order Total, Currency, Delivery Location, Notes\n- **NEVER fail due to missing optional fields** - Just omit them from the creation request\n\n**Example Create Request (All fields available):**\n```json\n{\n  \"parent\": {\n    \"database_id\": \"{{notion_database_id}}\"\n  },\n  \"properties\": {\n    \"Name of the Item\": {\n      \"title\": [\n        {\n          \"text\": {\n            \"content\": \"Pilot Automotive Wh553-16S-Bs Black\"\n          }\n        }\n      ]\n    },\n    \"Order Number\": {\n      \"rich_text\": [\n        {\n          \"text\": {\n            \"content\": \"408-0237654-1273974\"\n          }\n        }\n      ]\n    },\n    \"Quantity\": {\n      \"number\": 1\n    },\n    \"Expected Date\": {\n      \"rich_text\": [\n        {\n          \"text\": {\n            \"content\": \"Wednesday\"\n          }\n        }\n      ]\n    },\n    \"Order Status\": {\n      \"select\": {\n        \"name\": \"Shipped\"\n      }\n    },\n    \"Vendor\": {\n      \"rich_text\": [\n        {\n          \"text\": {\n            \"content\": \"Amazon\"\n          }\n        }\n      ]\n    },\n    \"Customer Name\": {\n      \"rich_text\": [\n        {\n          \"text\": {\n            \"content\": \"Jameson\"\n          }\n        }\n      ]\n    },\n    \"Price\": {\n      \"rich_text\": [\n        {\n          \"text\": {\n            \"content\": \"AED120.00\"\n          }\n        }\n      ]\n    },\n    \"Order Total\": {\n      \"number\": 127.00\n    },\n    \"Currency\": {\n      \"rich_text\": [\n        {\n          \"text\": {\n            \"content\": \"AED\"\n          }\n        }\n      ]\n    },\n    \"Delivery Location\": {\n      \"rich_text\": [\n        {\n          \"text\": {\n            \"content\": \"Dubai\"\n          }\n        }\n      ]\n    },\n    \"Notes\": {\n      \"rich_text\": [\n        {\n          \"text\": {\n            \"content\": \"[2025-10-12 14:30 UAE] Order created from email with status: Shipped\"\n          }\n        }\n      ]\n    }\n  }\n}\n```\n\n**Example Create Request (Minimal - only required fields):**\n```json\n{\n  \"parent\": {\n    \"database_id\": \"{{notion_database_id}}\"\n  },\n  \"properties\": {\n    \"Name of the Item\": {\n      \"title\": [\n        {\n          \"text\": {\n            \"content\": \"Pilot Automotive Wh553-16S-Bs Black\"\n          }\n        }\n      ]\n    },\n    \"Order Number\": {\n      \"rich_text\": [\n        {\n          \"text\": {\n            \"content\": \"408-0237654-1573974\"\n          }\n        }\n      ]\n    },\n    \"Quantity\": {\n      \"number\": 1\n    },\n    \"Expected Date\": {\n      \"rich_text\": [\n        {\n          \"text\": {\n            \"content\": \"Wednesday\"\n          }\n        }\n      ]\n    },\n    \"Order Status\": {\n      \"select\": {\n        \"name\": \"Shipped\"\n      }\n    }\n  }\n}\n```\n\n**🔴 CRITICAL: Handle Missing Optional Fields**\n```\nIF price is missing:\n   → Skip Price field (do NOT fail)\n   \nIF order_total is missing:\n   → Skip Order Total field (do NOT fail)\n   \nIF vendor is missing:\n   → Skip Vendor field (do NOT fail)\n   \nIF customer_name is missing:\n   → Skip Customer Name field (do NOT fail)\n\nONLY fail if: Order Number, Order Status, Item Name, or Quantity is missing\n```\n\n---\n\n## Output Format\n\n**CRITICAL:** Your output must be a clear, concise paragraph in human-readable format. Keep it SHORT and natural.\n\n### ✅ Successful Update (Status Changed):\n\n**Format:**\n```\nThe order [order_number] has changed from [old_status] to [new_status]. [Customer_name]'s order from [vendor] for [item_count] item(s) totaling [order_total] is now [new_status]. Expected delivery: [delivery_date].\n```\n\n**Example:**\n```\nThe order 408-0237654-1573974 has changed from Ordered to Shipped. Jameson's order from Amazon for 1 item totaling AED127.00 is now Shipped. Expected delivery: Wednesday.\n```\n\n---\n\n### ⏸️ No Action Needed (Status Unchanged):\n\n**Format:**\n```\nNo changes needed for order [order_number]. [Customer_name]'s order from [vendor] is already marked as [status]. Expected delivery: [delivery_date].\n```\n\n**Example:**\n```\nNo changes needed for order 408-0237654-1273974. Jameson's order from Amazon is already marked as Shipped. Expected delivery: Wednesday.\n```\n\n---\n\n### ✅ Successful Create (New Order):\n\n**Format:**\n```\nNew order [order_number] created for [customer_name] from [vendor]. Status: [status]. [Item_count] item(s) totaling [order_total]. Delivering to [location] by [delivery_date].\n```\n\n**Example:**\n```\nNew order 408-0237654-1573974 created for Jameson from Amazon. Status: Ordered. 1 item totaling AED127.00. Delivering to Dubai by Wednesday.\n```\n\n---\n\n### ✅ Successful Create (After Search Failure):\n\n**Format:**\n```\nNew order [order_number] created for [customer_name] from [vendor]. Status: [status]. [Item_count] item(s) totaling [order_total]. Delivering to [location] by [delivery_date]. (Created as order was not found in database)\n```\n\n**Example:**\n```\nNew order 408-0237654-1273974 created for Jameson from Amazon. Status: Shipped. 1 item totaling AED127.00. Delivering to Dubai by Wednesday. (Created as order was not found in database)\n```\n\n---\n\n### ❌ Failed Operation (Only for Create/Update failures, NOT search failures):\n\n**Format:**\n```\nFailed to create/update order [order_number]: [error_description]. [Action_needed].\n```\n\n**Example:**\n```\nFailed to create order 408-0237654-1573974: Unable to connect to Notion database. Please retry in 30 seconds.\n```\n\n---\n\n### ⚠️ Warning Messages (when applicable):\n\n**Status Regression:**\n```\nWarning: Order [order_number] status moved backward from [old_status] to [new_status]. This may indicate a return or reshipment.\n```\n\n**Duplicate Detected:**\n```\nError: Multiple records found for order [order_number]. Manual review required to resolve duplicate entries.\n```\n\n---\n\n## Detailed Examples\n\n### Example 1: Search Returns No Response → Create New Order\n\n**Input from Extraction Agent:**\n```json\n{\n  \"order_number\": \"408-0237654-1573974\",\n  \"order_status\": \"Shipped\",\n  \"vendor\": \"Amazon\",\n  \"customer_name\": \"Jim\",\n  \"delivery_info\": {\n    \"location\": \"Dubai\",\n    \"expected_date\": \"Wednesday\"\n  },\n  \"items\": [\n    {\n      \"item_name\": \"Pilot Automotive Wh553-16S-Bs Black\",\n      \"quantity\": 1,\n      \"price\": \"AED120.00\"\n    }\n  ],\n  \"order_total\": {\n    \"amount\": \"AED127.00\",\n    \"currency\": \"AED\"\n  }\n}\n```\n\n**Process:**\n1. ✅ Validate input data\n2. 🔍 Search database for order \"408-0237654-1573974\"\n3. ⚠️ Search returns error: \"The workflow did not return a response\"\n4. ✅ **Interpret as: Order does not exist**\n5. ➕ **Proceed to CREATE new order** (not error)\n6. ✅ Page created successfully with all order details\n\n**Output:**\n```\nNew order 408-0237654-1273974 created for Jameson from Amazon. Status: Shipped. 1 item totaling AED127.00. Delivering to Dubai by Wednesday. (Created as order was not found in database)\n```\n\n---\n\n### Example 2: Search Returns Empty Results → Create New Order\n\n**Input from Extraction Agent:**\n```json\n{\n  \"order_number\": \"NM-2024-556677\",\n  \"order_status\": \"Ordered\",\n  \"vendor\": \"Noon\",\n  \"customer_name\": \"Ahmed Hassan\"\n}\n```\n\n**Process:**\n1. ✅ Validate input data\n2. 🔍 Search database for order \"NM-2024-556677\"\n3. ✅ Search succeeds but returns: `{\"results\": []}`\n4. ✅ **Interpret as: Order does not exist**\n5. ➕ **Proceed to CREATE new order**\n6. ✅ Page created successfully\n\n**Output:**\n```\nNew order NM-2024-556677 created for Ahmed Hassan from Noon. Status: Ordered. 1 item totaling AED1,899.00. Delivering to Abu Dhabi by 2025-10-15.\n```\n\n---\n\n### Example 3: Search Returns 1 Result → Update Order\n\n**Input from Extraction Agent:**\n```json\n{\n  \"order_number\": \"408-0237654-1573974\",\n  \"order_status\": \"Shipped\",\n  \"delivery_info\": {\n    \"expected_date\": \"Wednesday\"\n  }\n}\n```\n\n**Process:**\n1. ✅ Validate input data\n2. 🔍 Search database for order\n3. ✅ Found 1 existing record with status \"Ordered\"\n4. 📝 **Compare: Old status \"Ordered\" ≠ New status \"Shipped\"**\n5. ✏️ **Update status to \"Shipped\"**\n6. 📌 Append note with timestamp\n\n**Output:**\n```\nThe order 408-0237654-1573974 has changed from Ordered to Shipped. Jameson's order from Amazon for 1 item totaling AED127.00 is now Shipped. Expected delivery: Wednesday.\n```\n\n---\n\n### Example 4: Search Returns 1 Result (Same Status) → No Action\n\n**Input from Extraction Agent:**\n```json\n{\n  \"order_number\": \"408-0237654-1573974\",\n  \"order_status\": \"Shipped\"\n}\n```\n\n**Process:**\n1. ✅ Validate input data\n2. 🔍 Search database for order\n3. ✅ Found existing record with status \"Shipped\"\n4. 📝 **Compare: Current status \"Shipped\" == New status \"Shipped\"**\n5. ⏸️ **No update needed - statuses match**\n6. ✅ Return no_action response\n\n**Output:**\n```\nNo changes needed for order 408-0237654-1573974. Jameson's order from Amazon is already marked as Shipped. Expected delivery: Wednesday.\n```\n\n---\n\n## Special Handling Rules\n\n### ⚠️ Rule 1: Status Progression Validation\n\n**Expected Status Flow:**\n```\nOrdered → Shipped → Out for Delivery → Delivered\n```\n\n**Backward Status Detection:**  \nIf status regresses (e.g., \"Delivered\" → \"Shipped\"), add warning:\n\n**Note Format for Regression:**\n```\n[2025-10-12 14:30 UAE] ⚠️ WARNING: Status regressed from Delivered to Shipped - possible return/reshipment\n```\n\n---\n\n### 🚫 Rule 2: Duplicate Detection\n\n**If multiple records found with same order number:**\n\n**Output:**\n```\nError: Multiple records found for order 408-0237654-1273974. Manual review required to resolve duplicate entries in the database.\n```\n\n**Do NOT attempt to update when duplicates exist** - require manual intervention.\n\n---\n\n### 🔄 Rule 3: Vendor Consistency Check\n\n**If vendor name differs during update:**\n\n**Output:**\n```\nThe order 408-0237654-1573974 has changed from Ordered to Shipped. Jameson's order from Amazon for 1 item totaling AED127.00 is now Shipped. Expected delivery: Wednesday. Warning: Vendor mismatch detected - database shows Amazon but email shows Noon. Original vendor preserved.\n```\n\n**Action:** Preserve original vendor, add warning to output, do NOT update vendor field.\n\n---\n\n### 🔒 Rule 4: Delivered Status Finality\n\n**Once status = \"Delivered\":**\n- ✅ Allow updates to: Notes (only if status changes from Delivered)\n- ❌ Prevent updates to: Status (locked unless changing FROM delivered)\n- ⏸️ If new status == \"Delivered\" and current == \"Delivered\": Return no_action\n\n---\n\n## Error Handling\n\n### ❌ Connection Errors (During Create/Update):\n```\nFailed to create order 408-0237654-1573974: Unable to connect to Notion database. Please retry in 30 seconds.\n```\n\n### ❌ Validation Errors (ONLY for missing required fields):\n```\nFailed to process order: Missing required field 'order_number'. Cannot proceed without order number.\n```\n\n**❌ DO NOT fail for:**\n- Missing price\n- Missing order_total\n- Missing vendor\n- Missing customer_name\n- Missing delivery_location\n- Missing currency\n- Any other optional field\n\n### ❌ Permission Errors:\n```\nFailed to create order 408-0237654-1573974: Access denied to Notion database. Please verify integration permissions.\n```\n\n---\n\n## Critical Guidelines\n\n### ✅ DO:\n1. **Use the provided database ID** - `{{notion_database_id}}` is always in context\n2. **Never ask for database ID** - Proceed directly with create operation\n3. **Treat search failures as \"order not found\"** - Create new order immediately\n4. **Treat empty search results as \"order not found\"** - Create new order\n5. **Always search before creating** - But proceed with create if search fails\n6. **Always compare statuses before updating** - Only update if different\n7. **Return no_action when status unchanged** - Don't make unnecessary API calls\n8. **Preserve original data** - Never overwrite Order Number, Customer Name, Items, Order Total, Vendor\n9. **Track status history** - Add timestamped notes for all status changes\n10. **Use exact order numbers** - Never modify, clean, or reformat order numbers\n11. **Handle missing fields gracefully** - Create/update with available data only\n12. **Validate status transitions** - Flag backward progressions\n13. **Format items clearly** - Make product information readable\n14. **Include timestamps** - Always use UAE timezone (GMT+4)\n15. **Return detailed feedback** - Provide comprehensive operation results\n\n### ❌ DON'T:\n1. **Don't fail on search errors** - Create new order instead\n2. **Don't return error messages for \"no search response\"** - This means order doesn't exist\n3. **Don't treat search failures as fatal errors** - They indicate missing order\n4. **Don't fail when optional fields are missing** - Price, order total, vendor, customer name, etc. are optional\n5. **Don't ask for missing optional data** - Just omit optional fields if not provided\n6. **Don't update if status unchanged** - Compare first, return no_action if same\n7. **Don't make unnecessary API calls** - Skip updates when nothing changed\n8. **Don't modify order identifiers** - Order numbers are immutable\n9. **Don't overwrite core fields** - Preserve original order data\n10. **Don't ignore actual errors** - Report create/update failures with context\n11. **Don't update delivered orders with same status** - Return no_action\n12. **Don't proceed with duplicates** - Require manual intervention\n13. **Don't update vendor on mismatch** - Preserve original, warn only\n14. **Don't skip validation** - Always check REQUIRED fields first (order number, status, item name, quantity)\n15. **Don't skip status comparison** - MUST compare before any update operation\n\n---\n\n## Integration Workflow\n\n```\n┌─────────────────────────┐\n│ Email Extraction Agent  │\n│  (Extracts order data)  │\n└───────────┬─────────────┘\n            │\n            ↓ JSON Output\n            │\n┌───────────▼─────────────┐\n│ Database Sync Agent     │\n│    (This Agent)         │\n│                         │\n│  1. Validate input      │\n│  2. Search Notion DB    │\n│     ├─ No response?     │\n│     │  → CREATE         │\n│     ├─ Empty results?   │\n│     │  → CREATE         │\n│     ├─ 1 result?        │\n│     │  → UPDATE         │\n│     └─ >1 result?       │\n│        → ERROR          │\n│  3. Execute action      │\n│  4. Return confirmation │\n└───────────┬─────────────┘\n            │\n            ↓ Status Report\n            │\n┌───────────▼─────────────┐\n│   Confirmation Log      │\n│  (Operation complete)   │\n└─────────────────────────┘\n```\n\n---\n\n## Quick Reference\n\n**Status Values:** `Ordered` | `Shipped` | `Out for Delivery` | `Delivered`\n\n**Required Input Fields (ONLY these - cannot proceed without them):** \n- `order_number` (text)\n- `order_status` (select)\n- `items[].item_name` (text - at least one item)\n- `items[].quantity` (number - at least one item)\n\n**Optional Input Fields (include if available, skip if not):**\n- `price`, `order_total`, `vendor`, `customer_name`, `delivery_location`, `currency`, `expected_date`, `notes`\n\n**Search Response Handling:**\n```\nIF search_error OR null OR no_response → CREATE\nIF results.length === 0 → CREATE\nIF results.length === 1 → UPDATE (if status changed)\nIF results.length > 1 → ERROR\n```\n\n**Update Decision:** \n```\nIF current_status == new_status → no_action (no API call)\nIF current_status != new_status → update (API call with changes)\n```\n\n**Field Handling:**\n```\nREQUIRED fields missing → Fail with validation error\nOPTIONAL fields missing → Skip field, continue with create/update\n```\n\n**Never Update:** Order Number, Customer Name (preserve original data)\n\n**Update Only When Status Changes:** Order Status, Expected Date, Delivery Location, Notes\n\n**Timestamp Format:** `YYYY-MM-DDTHH:MM:SS+04:00` (ISO 8601 with UAE timezone)"
        },
        "promptType": "define",
        "needsFallback": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "b42f8c04-2990-43af-8b9c-0a108267aca3",
      "name": "检查邮件类型",
      "type": "n8n-nodes-base.code",
      "position": [
        -1008,
        1280
      ],
      "parameters": {
        "jsCode": "// Get email content from input - try multiple possible locations\nconst item = $input.item.json;\nconst emailBody = item.body || item.content || item.text || item.emailBody || JSON.stringify(item);\nconst emailSubject = item.subject || item.title || '';\n\n// Combine subject and body for analysis\nconst fullContent = `${emailSubject} ${emailBody}`;\nconst contentLower = fullContent.toLowerCase();\n\n// Define order-related keywords and patterns\nconst orderIndicators = {\n  // Strong indicators (if found, very likely an order)\n  strongPatterns: [\n    /order\\s*#/i,\n    /order\\s*number/i,\n    /order\\s*id/i,\n    /tracking\\s*#/i,\n    /tracking\\s*number/i,\n    /shipment\\s*id/i,\n    /invoice\\s*#/i,\n    /receipt\\s*#/i,\n    /order\\s*confirmation/i,\n    /purchase\\s*confirmation/i,\n    /order\\s*\\d{3,}/i  // \"Order 123456\" pattern\n  ],\n  \n  // Shipping status keywords\n  shippingKeywords: [\n    'shipped',\n    'out for delivery',\n    'delivered',\n    'arriving',\n    'in transit',\n    'delivery',\n    'dispatched',\n    'tracking',\n    'track package',\n    'track order'\n  ],\n  \n  // Order-related phrases\n  orderPhrases: [\n    'your order',\n    'thanks for your order',\n    'order has been',\n    'your package',\n    'your orders',\n    'view order',\n    'edit order',\n    'cancel order',\n    'order details'\n  ]\n};\n\n// Check for strong indicators (regex patterns)\nlet strongIndicatorFound = false;\nlet matchedPattern = null;\n\nfor (const pattern of orderIndicators.strongPatterns) {\n  if (pattern.test(fullContent)) {\n    strongIndicatorFound = true;\n    matchedPattern = pattern.toString();\n    break;\n  }\n}\n\n// Count matches for other indicators\nlet shippingCount = 0;\nlet orderPhraseCount = 0;\nconst matchedKeywords = [];\n\nfor (const keyword of orderIndicators.shippingKeywords) {\n  if (contentLower.includes(keyword.toLowerCase())) {\n    shippingCount++;\n    matchedKeywords.push(keyword);\n  }\n}\n\nfor (const phrase of orderIndicators.orderPhrases) {\n  if (contentLower.includes(phrase.toLowerCase())) {\n    orderPhraseCount++;\n    matchedKeywords.push(phrase);\n  }\n}\n\n// Decision logic\nlet isOrderEmail = false;\nlet confidence = 'low';\n\nif (strongIndicatorFound) {\n  // If we found order numbers or similar, it's definitely an order email\n  isOrderEmail = true;\n  confidence = 'high';\n} else if (orderPhraseCount >= 1 && shippingCount >= 2) {\n  // Order phrases + multiple shipping keywords\n  isOrderEmail = true;\n  confidence = 'medium';\n} else if (shippingCount >= 3) {\n  // Many shipping-related terms likely indicate an order\n  isOrderEmail = true;\n  confidence = 'medium';\n} else if (orderPhraseCount >= 2) {\n  // Multiple order-related phrases\n  isOrderEmail = true;\n  confidence = 'medium';\n}\n\n// Return result\nreturn {\n  json: {\n    isOrderEmail: isOrderEmail,\n    confidence: confidence,\n    indicators: {\n      strongIndicator: strongIndicatorFound,\n      matchedPattern: matchedPattern,\n      shippingKeywords: shippingCount,\n      orderPhrases: orderPhraseCount,\n      matchedKeywords: matchedKeywords,\n      contentLength: fullContent.length\n    },\n    // Include for debugging\n    debug: {\n      contentPreview: fullContent.substring(0, 200)\n    }\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "8e352e66-ba8c-43d0-8df3-b73b4d8a0f8d",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1360,
        1136
      ],
      "parameters": {
        "color": 6,
        "height": 304,
        "content": "## 邮件触发器"
      },
      "typeVersion": 1
    },
    {
      "id": "4bd7cb9f-e730-4a54-b49e-311676eecbe2",
      "name": "便签 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1104,
        752
      ],
      "parameters": {
        "color": 6,
        "height": 672,
        "content": "**邮件分类节点**"
      },
      "typeVersion": 1
    },
    {
      "id": "7b32d197-5fb6-4181-9310-289b19657160",
      "name": "便签 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -848,
        864
      ],
      "parameters": {
        "color": 6,
        "width": 256,
        "height": 576,
        "content": "**订单邮件路由器**"
      },
      "typeVersion": 1
    },
    {
      "id": "233e5373-6b12-4d50-ac7e-57adbcec1765",
      "name": "便签 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -576,
        624
      ],
      "parameters": {
        "color": 6,
        "width": 416,
        "height": 528,
        "content": "**邮件订单提取智能体**"
      },
      "typeVersion": 1
    },
    {
      "id": "677979e2-99f6-4c72-85d7-33ca603c79c9",
      "name": "便签 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -144,
        624
      ],
      "parameters": {
        "color": 6,
        "width": 400,
        "height": 624,
        "content": "**Notion 订单数据库同步智能体**"
      },
      "typeVersion": 1
    },
    {
      "id": "f3cb68f0-9a9f-4d30-b3db-b3b58a9343c6",
      "name": "便签 5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        304,
        992
      ],
      "parameters": {
        "color": 6,
        "height": 288,
        "content": "## 邮件触发器"
      },
      "typeVersion": 1
    },
    {
      "id": "a5c82306-7ca2-48ac-9a0b-222d1494e8f4",
      "name": "便签6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        1312
      ],
      "parameters": {
        "color": 6,
        "width": 560,
        "height": 384,
        "content": "**Notion 集成工具**"
      },
      "typeVersion": 1
    },
    {
      "id": "f9eaa00e-1eac-42b3-98d9-d7853b8dc8b1",
      "name": "未执行任何操作",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -432,
        1424
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "a8f03bd4-aa00-4f24-87c6-d312fc226d7f",
      "name": "便签7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -480,
        1392
      ],
      "parameters": {
        "color": 6,
        "width": 208,
        "height": 320,
        "content": "## 不执行操作"
      },
      "typeVersion": 1
    },
    {
      "id": "1e0634fe-549d-4ae2-922a-5c807c85d854",
      "name": "邮件路由器",
      "type": "n8n-nodes-base.if",
      "position": [
        -784,
        1280
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "36858316-66be-41c5-925b-5c0fcecd20f1",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.isOrderEmail }}",
              "rightValue": "true"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c7a06748-5287-4b3a-a76c-5f1c4f6b2290",
      "name": "在 Notion 中搜索页面",
      "type": "n8n-nodes-base.notionTool",
      "position": [
        48,
        1344
      ],
      "parameters": {
        "text": "={{ $fromAI('property_order_status') }}",
        "options": {},
        "operation": "search",
        "returnAll": true
      },
      "credentials": {
        "notionApi": {
          "id": "AyWJR0aCxKv5UGfy",
          "name": "personal Notion account"
        }
      },
      "typeVersion": 2.2
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "91df8c09-aadc-4c82-9dc0-5932b98cb7b2",
  "connections": {
    "Email Router": {
      "main": [
        [
          {
            "node": "Email Classification and Extraction Agent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No action taken",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail Trigger": {
      "main": [
        [
          {
            "node": "Check Email Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Email Type": {
      "main": [
        [
          {
            "node": "Email Router",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Order Database Sync Agent",
            "type": "ai_languageModel",
            "index": 1
          },
          {
            "node": "Email Classification and Extraction Agent",
            "type": "ai_languageModel",
            "index": 1
          }
        ]
      ]
    },
    "Search a page in Notion": {
      "ai_tool": [
        [
          {
            "node": "Order Database Sync Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Order Database Sync Agent",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Email Classification and Extraction Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Email Classification and Extraction Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Order Database Sync Agent": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create a database page in Notion": {
      "ai_tool": [
        [
          {
            "node": "Order Database Sync Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Update a database page in Notion": {
      "ai_tool": [
        [
          {
            "node": "Order Database Sync Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Email Classification and Extraction Agent": {
      "main": [
        [
          {
            "node": "Order Database Sync Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

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

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

高级

需要付费吗?

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

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

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

外部链接
在 n8n.io 查看

分享此工作流