通过Gmail审批自动禁用一年未售出的Magento 2产品

高级

这是一个Document Extraction领域的自动化工作流,包含 22 个节点。主要使用 If、Code、Gmail、Merge、SplitOut 等节点。 通过Gmail审批自动禁用一年未售出的Magento 2产品

前置要求
  • Google 账号和 Gmail API 凭证
  • 可能需要目标 API 的认证凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "meta": {
    "instanceId": "54d8e296590faa0bb0e9d6290ad6ee2f19b78aa7b248ecb45c5f7c5ff622d210",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "af991423-1760-4a50-aee3-e090ff436eaf",
      "name": "计划触发器",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1340,
        -80
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "months",
              "triggerAtHour": 8
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "99a30399-cc1c-4687-bc32-607a89815326",
      "name": "如果",
      "type": "n8n-nodes-base.if",
      "position": [
        -740,
        -80
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "61173acd-0f6c-4dd6-9cdf-bc8f166d6c63",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.items.length }}",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "f3161640-ce57-4439-ab03-3b4859d5e5db",
      "name": "获取一年内的订单",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -920,
        -80
      ],
      "parameters": {
        "url": "=https://magekwik.com/rest/V1/orders?searchCriteria[filter_groups][0][filters][0][field]=created_at&searchCriteria[filter_groups][0][filters][0][value]={{$json[\"sixMonthsAgo\"]}} 00:00:00&searchCriteria[filter_groups][0][filters][0][condition_type]=gteq&searchCriteria[pageSize]=0",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "6b053d22-682d-4fae-9569-4eb51d838163",
      "name": "计算一年前的日期(ISO 格式)",
      "type": "n8n-nodes-base.code",
      "position": [
        -1140,
        -80
      ],
      "parameters": {
        "jsCode": "const date = new Date();\ndate.setMonth(date.getMonth() - 12);\nreturn [{ json: { sixMonthsAgo: date.toISOString().split('T')[0] } }];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "34243a56-cab5-40a8-85f7-fd3229058760",
      "name": "从订单中提取已售 SKU",
      "type": "n8n-nodes-base.code",
      "position": [
        -440,
        -80
      ],
      "parameters": {
        "jsCode": "const soldSkusSet = new Set();\n// orders response is in items\nconst orders = items[0].json.items || [];\n\norders.forEach(order => {\n  if (order.items && Array.isArray(order.items)) {\n    order.items.forEach(item => {\n      if(item.sku) soldSkusSet.add(item.sku);\n    });\n  }\n});\n\nreturn [{ json: { soldSkus: Array.from(soldSkusSet) } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "91bfa661-893f-4940-84b4-a3f61bb098c0",
      "name": "获取所有产品 SKU",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -220,
        -80
      ],
      "parameters": {
        "url": "=https://magekwik.com/rest/V1/products?searchCriteria[pageSize]=0",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "ad8c0611-3465-4b0e-bc99-6c8eb4cdb304",
      "name": "筛选过去一年未售出的产品",
      "type": "n8n-nodes-base.code",
      "position": [
        0,
        -80
      ],
      "parameters": {
        "jsCode": "const allProducts =  $input.first().json.items || [];\nconst soldSkus = new Set($('Extract Sold SKUs from orders').first().json.soldSkus || []);\n\nconst unsoldProducts = allProducts.filter(product => {\n  return !soldSkus.has(product.sku);\n});\n\nreturn [{\n  json: {\n    unsold: unsoldProducts\n  }\n}];\n//return unsoldProducts.map(product => ({ json: product }));"
      },
      "typeVersion": 2
    },
    {
      "id": "7b2f1534-4a11-4d8e-a69f-b13cbcf82660",
      "name": "Gmail 用户审批",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -1300,
        160
      ],
      "webhookId": "c46cf421-ddb6-45a8-b83b-80b381666f0e",
      "parameters": {
        "sendTo": "kmyprojects@gmail.com",
        "message": "=The following products have recorded zero sales over the past 12 months. To optimise inventory, we propose disabling these items in our system.\n\nNext Steps:\n\nApprove: If you agree to remove these items from active inventory.\nDecline: If you wish to retain them for sale.\n\nPlease review the list and advise on your decision within 30 minutes. Thank you for your prompt attention.\n\nBest regards,\n\n{{ $json.htmlBody }}\n",
        "options": {
          "appendAttribution": false
        },
        "subject": "=Approve disabling {{ $json.count }} unsold products ",
        "operation": "sendAndWait",
        "approvalOptions": {
          "values": {
            "approvalType": "double"
          }
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "f0a9aac6-cc5f-4905-9016-e6e46463f2f7",
      "name": "遍历项目",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -440,
        160
      ],
      "parameters": {
        "options": {
          "reset": false
        }
      },
      "typeVersion": 3,
      "alwaysOutputData": false
    },
    {
      "id": "3949b0fc-2a0b-4f71-9301-221c121b0f93",
      "name": "如果1",
      "type": "n8n-nodes-base.if",
      "position": [
        -1140,
        160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "a5d805ae-81cd-42e9-a4ef-5e41f7c1960b",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.data.approved }}",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "bd82188f-6ad7-4c47-a1ba-8bf7ca468c95",
      "name": "合并",
      "type": "n8n-nodes-base.merge",
      "position": [
        -920,
        160
      ],
      "parameters": {
        "mode": "chooseBranch",
        "useDataOfInput": 2
      },
      "typeVersion": 3.2
    },
    {
      "id": "081eb734-de23-4988-9faa-c65e4f09db13",
      "name": "拆分输出",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -740,
        160
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "unsold"
      },
      "typeVersion": 1
    },
    {
      "id": "c0bf16d9-6aa9-40e8-9053-98e5c5fb912e",
      "name": "禁用产品",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -180,
        400
      ],
      "parameters": {
        "url": "=https://magekwik.com/rest/default/V1/products/{{ $json.sku }}",
        "method": "PUT",
        "options": {},
        "jsonBody": "{\n  \"product\": {\n    \"status\": 1\n  }\n}\n",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "088874ad-4ed2-4005-a5e9-3ce76ab7c8cf",
      "name": "发送消息",
      "type": "n8n-nodes-base.gmail",
      "position": [
        220,
        140
      ],
      "webhookId": "417c52fb-502c-48a2-8f5c-3c16cbac6fd3",
      "parameters": {
        "sendTo": "kmyprojects@gmail.com",
        "message": "=The following  {{ $json.count }} products have been disabled.\n\n{{ $json.htmlBody }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "={{ $json.count }} products have been deactivated"
      },
      "typeVersion": 2.1
    },
    {
      "id": "b4abc4dc-ca5b-41a7-bcad-ec842c348574",
      "name": "聚合",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        -160,
        160
      ],
      "parameters": {
        "include": "specifiedFields",
        "options": {},
        "aggregate": "aggregateAllItemData",
        "fieldsToInclude": "sku,name,price,status"
      },
      "typeVersion": 1
    },
    {
      "id": "9523619b-b2ca-43f0-b045-f68379eada33",
      "name": "构建报告邮件",
      "type": "n8n-nodes-base.code",
      "position": [
        40,
        140
      ],
      "parameters": {
        "jsCode": "const headers = ['sku', 'name', 'price', 'status'];\n\nconst unsold = $input.first().json.data || [];\n\n// Start the HTML table\nlet html = `<table border=\"1\" cellpadding=\"6\" cellspacing=\"0\" style=\"border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px;\">`;\n\n// Add table header\nhtml += '<tr style=\"background-color: #f2f2f2;\">' + headers.map(h => `<th>${h}</th>`).join('') + '</tr>';\n\n// Add rows\nfor (const product of unsold) {\n  html += '<tr>' + headers.map(field => {\n    const value = product[field] ?? '';\n    return `<td>${String(value).replace(/</g, '&lt;').replace(/>/g, '&gt;')}</td>`;\n  }).join('') + '</tr>';\n}\n\n// Close table\nhtml += '</table>';\n\nreturn [{\n  json: {\n    htmlBody: html,\n    count: unsold.length,\n    subject: `Unsold Products Report (${unsold.length})`\n  }\n}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "affccc45-e966-4952-9136-2f19b82ac61d",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1380,
        -220
      ],
      "parameters": {
        "color": 7,
        "width": 840,
        "height": 300,
        "content": "获取过去一年所有已订购的 SKU"
      },
      "typeVersion": 1
    },
    {
      "id": "bce6fc94-f30f-479e-8d4a-dcd946ed5e0b",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -500,
        -220
      ],
      "parameters": {
        "color": 6,
        "width": 840,
        "height": 300,
        "content": "筛选过去一年所有未订购的 SKU"
      },
      "typeVersion": 1
    },
    {
      "id": "e24162fe-a07b-422c-9417-09ac72fbb534",
      "name": "构建决策邮件",
      "type": "n8n-nodes-base.code",
      "position": [
        220,
        -80
      ],
      "parameters": {
        "jsCode": "const headers = ['sku', 'name', 'price', 'status'];\n\nconst unsold = $json.unsold || [];\n\n// Start the HTML table\nlet html = `<table border=\"1\" cellpadding=\"6\" cellspacing=\"0\" style=\"border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px;\">`;\n\n// Add table header\nhtml += '<tr style=\"background-color: #f2f2f2;\">' + headers.map(h => `<th>${h}</th>`).join('') + '</tr>';\n\n// Add rows\nfor (const product of unsold) {\n  html += '<tr>' + headers.map(field => {\n    const value = product[field] ?? '';\n    return `<td>${String(value).replace(/</g, '&lt;').replace(/>/g, '&gt;')}</td>`;\n  }).join('') + '</tr>';\n}\n\n// Close table\nhtml += '</table>';\n\nreturn [{\n  json: {\n    htmlBody: html,\n    count: unsold.length,\n    subject: `Unsold Products Report (${unsold.length})`\n  }\n}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "cccc4f30-ad84-472a-8c05-8f52c5692f31",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1380,
        100
      ],
      "parameters": {
        "color": 5,
        "width": 840,
        "height": 280,
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "689407c1-c09c-44d0-a162-e42cb48aac93",
      "name": "便签3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -500,
        100
      ],
      "parameters": {
        "color": 4,
        "width": 840,
        "height": 500,
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "b6051a73-aa8e-405e-aaaa-bbf444856a2f",
      "name": "便签4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1380,
        -460
      ],
      "parameters": {
        "width": 1720,
        "height": 220,
        "content": "# Magento 2 库存清理:审批后禁用一年未售陈旧产品"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Extract Sold SKUs from orders",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If1": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "Built Reporting Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Disable Products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Disable Products": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Calculate date an year ago (ISO)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Decision Email": {
      "main": [
        [
          {
            "node": "Gmail User for Approval",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get All Product Skus": {
      "main": [
        [
          {
            "node": "Filter products NOT sold in last year",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Built Reporting Email": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail User for Approval": {
      "main": [
        [
          {
            "node": "If1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Sold SKUs from orders": {
      "main": [
        [
          {
            "node": "Get All Product Skus",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Orders since 1 year ago": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate date an year ago (ISO)": {
      "main": [
        [
          {
            "node": "Fetch Orders since 1 year ago",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter products NOT sold in last year": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          },
          {
            "node": "Build Decision Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

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

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

这是一个高级难度的工作流,适用于Document Extraction等场景。适合高级用户,包含 16+ 个节点的复杂工作流

需要付费吗?

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

工作流信息
难度等级
高级
节点数量22
分类1
节点类型10
难度说明

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

作者
Kanaka Kishore Kandregula

Kanaka Kishore Kandregula

@kmyprojects

Experienced Magento 2 Developer with 10+ years of expertise in building and optimizing eCommerce solutions. Over the past year, I’ve expanded my skills into workflow automation using n8n, streamlining business processes and integrating systems for efficiency. Passionate about solving complex problems, enhancing performance, and leveraging automation to drive smarter workflows.

外部链接
在 n8n.io 上查看 →

分享此工作流