8
n8n 中文网amn8n.com

🛍️ 使用 Channable、Relevance AI 和 Merchant API 优化 Google Shopping Feed

高级

这是一个Content Creation, Multimodal AI领域的自动化工作流,包含 19 个节点。主要使用 If, Code, Slack, Aggregate, ItemLists 等节点。 🛍️ 使用 Channable、Relevance AI 和 Merchant API 优化 Google Shopping Feed

前置要求
  • Slack Bot Token 或 Webhook URL
  • 可能需要目标 API 的认证凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "meta": {
    "instanceId": "04fd795d32aabb18b913b4a3350b5cd0e9313a422ea0e7bdac0da2fb76cac9f7",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "34eafce0-026c-416e-99b8-fd6d012d758f",
      "name": "每日触发器 - 早上 6 点",
      "type": "n8n-nodes-base.scheduleTrigger",
      "notes": "Triggers daily at 6 AM for feed optimization before Merchant Center sync",
      "position": [
        -4200,
        460
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 6 * * *"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "698d4143-e209-4c81-94ce-01094c4b1f14",
      "name": "获取产品 Feed",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Retrieves product feed. Can replace with your e-commerce platform API endpoint.",
      "position": [
        -4000,
        460
      ],
      "parameters": {
        "url": "={{$env.CHANNABLE_API_URL}}/companies/{{$env.CHANNABLE_COMPANY_ID}}/projects/{{$env.CHANNABLE_PROJECT_ID}}/feeds/{{$env.FEED_ID}}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "luTyM3gZSgwhM8i0",
          "name": "Header Auth account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "a88adbdf-2712-42cb-afe0-328f84038941",
      "name": "数据质量检查",
      "type": "n8n-nodes-base.code",
      "notes": "Validates: GTINs, images, categories, pricing, title/description length. Assigns quality score.",
      "position": [
        -3800,
        460
      ],
      "parameters": {
        "jsCode": "// Data quality checks for Shopping feed\n\nconst items = $input.all();\nconst qualityIssues = [];\nconst validProducts = [];\n\nitems.forEach(item => {\n  const product = item.json;\n  const issues = [];\n  \n  // Check for missing GTIN\n  if (!product.gtin || product.gtin === '') {\n    issues.push('Missing GTIN');\n  }\n  \n  // Check image\n  if (!product.image_link || product.image_link === '') {\n    issues.push('Missing image link');\n  }\n  \n  // Check for missing category\n  if (!product.google_product_category || product.google_product_category === '') {\n    issues.push('Missing Google product category');\n  }\n  \n  // Check for pricing errors\n  const price = parseFloat(product.price);\n  if (isNaN(price) || price <= 0) {\n    issues.push('Invalid price');\n  }\n  \n  // Check title length (30-150 chars optimal)\n  const title = product.title || '';\n  if (title.length < 30) {\n    issues.push('Title too short (recommend 30-150 chars)');\n  }\n  if (title.length > 150) {\n    issues.push('Title too long (max 150 chars)');\n  }\n  \n  // Check for missing description\n  if (!product.description || product.description.length < 160) {\n    issues.push('Description missing or too short (recommend 160-500 chars)');\n  }\n  \n  // Check availability\n  if (!product.availability || !['in stock', 'out of stock', 'preorder', 'backorder'].includes(product.availability.toLowerCase())) {\n    issues.push('Invalid availability status');\n  }\n  \n  // Quality score\n  const maxIssues = 7;\n  const qualityScore = Math.round(((maxIssues - issues.length) / maxIssues) * 100);\n  \n  const result = {\n    ...product,\n    quality_score: qualityScore,\n    quality_issues: issues,\n    needs_optimization: issues.length > 0\n  };\n  \n  if (qualityScore < 80) {\n    qualityIssues.push(result);\n  } else {\n    validProducts.push(result);\n  }\n});\n\nreturn {\n  total_products: items.length,\n  products_with_issues: qualityIssues.length,\n  valid_products: validProducts.length,\n  all_products: [...validProducts, ...qualityIssues]\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "4ba2eb7c-ce9d-4219-8adb-823f0e14dac8",
      "name": "优化标题",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "CORRECTED: Uses /trigger with tool ID. Optimizes title: Brand + Type + Features + Attributes. Max 150 chars.",
      "position": [
        -3400,
        460
      ],
      "parameters": {
        "url": "={{$env.RELEVANCE_AI_API_URL}}/tools/{{$env.RELEVANCE_TOOL_TITLE_OPTIMIZER_ID}}/trigger",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"params\": {\n    \"current_title\": \"{{$json.title}}\",\n    \"category\": \"{{$json.google_product_category}}\",\n    \"brand\": \"{{$json.brand}}\",\n    \"color\": \"{{$json.color}}\",\n    \"size\": \"{{$json.size}}\",\n    \"material\": \"{{$json.material}}\"\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "luTyM3gZSgwhM8i0",
          "name": "Header Auth account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "f505b7a4-9bb9-44fd-8ecd-ddfe94a4926d",
      "name": "生成描述",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "CORRECTED: Uses /trigger with tool ID. Generates 300-400 char benefit-focused description.",
      "position": [
        -3200,
        460
      ],
      "parameters": {
        "url": "={{$env.RELEVANCE_AI_API_URL}}/tools/{{$env.RELEVANCE_TOOL_DESCRIPTION_ID}}/trigger",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"params\": {\n    \"product_title\": \"{{$json.optimized_title || $json.title}}\",\n    \"product_features\": \"{{$json.description}}\",\n    \"category\": \"{{$json.google_product_category}}\"\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "luTyM3gZSgwhM8i0",
          "name": "Header Auth account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "a74d968c-c188-47fa-86da-448382eeaea9",
      "name": "分配自定义标签",
      "type": "n8n-nodes-base.code",
      "notes": "Assigns 5 custom labels for segmented bidding: margin, performance, seasonality, stock, category",
      "position": [
        -3000,
        460
      ],
      "parameters": {
        "jsCode": "// Assign custom labels for campaign segmentation\n\nconst product = $input.item.json;\nconst price = parseFloat(product.price);\nconst cost = parseFloat(product.cost || 0);\n\n// Calculate margin\nconst margin = cost > 0 ? ((price - cost) / price) * 100 : 0;\n\n// Custom Label 0: Margin Tier\nlet marginTier = 'low';\nif (margin > 40) marginTier = 'high';\nelse if (margin > 25) marginTier = 'mid';\n\n// Custom Label 1: Performance\nlet performanceLabel = 'standard';\nif (product.sales_rank && product.sales_rank < 100) {\n  performanceLabel = 'bestseller';\n} else if (product.created_date && new Date(product.created_date) > new Date(Date.now() - 30*24*60*60*1000)) {\n  performanceLabel = 'new';\n} else if (product.availability === 'limited stock') {\n  performanceLabel = 'clearance';\n}\n\n// Custom Label 2: Seasonality\nconst month = new Date().getMonth() + 1;\nlet seasonality = 'evergreen';\nif ([11, 12].includes(month)) seasonality = 'holiday';\nelse if ([6, 7, 8].includes(month)) seasonality = 'summer';\nelse if ([3, 4, 5].includes(month)) seasonality = 'spring';\n\n// Custom Label 3: Stock Level\nlet stockLevel = 'in-stock';\nif (product.quantity) {\n  const qty = parseInt(product.quantity);\n  if (qty === 0) stockLevel = 'out-of-stock';\n  else if (qty < 10) stockLevel = 'low-stock';\n  else if (qty > 100) stockLevel = 'high-stock';\n}\n\n// Custom Label 4: Category\nconst category = product.google_product_category || product.product_type || 'uncategorized';\nconst categoryShort = category.split('>')[0].trim().toLowerCase().replace(/\\s+/g, '-');\n\nreturn {\n  ...product,\n  optimized_title: $input.item.json.optimized_title || product.title,\n  optimized_description: $input.item.json.optimized_description || product.description,\n  custom_label_0: marginTier,\n  custom_label_1: performanceLabel,\n  custom_label_2: seasonality,\n  custom_label_3: stockLevel,\n  custom_label_4: categoryShort,\n  margin_percent: margin.toFixed(2)\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "bc0cc114-262f-4594-a4d2-793926ab1e54",
      "name": "聚合产品",
      "type": "n8n-nodes-base.aggregate",
      "notes": "Combines all optimized products",
      "position": [
        -2800,
        460
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "1116b030-6b5d-40c0-b871-7fea79fb7c46",
      "name": "检查产品状态(新 API)",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "CORRECTED: Uses NEW Merchant API to list products and check for issues. PageSize now supports up to 1000.",
      "position": [
        -2240,
        460
      ],
      "parameters": {
        "url": "=={{$env.MERCHANT_API_URL}}/{{$env.MERCHANT_ACCOUNT_ID}}/products",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "googleApi"
      },
      "typeVersion": 4.2
    },
    {
      "id": "3ea2945d-d376-4c72-9aed-c7da9529c772",
      "name": "分析产品问题",
      "type": "n8n-nodes-base.code",
      "notes": "CORRECTED: Parses NEW Merchant API response format for issues",
      "position": [
        -2040,
        460
      ],
      "parameters": {
        "jsCode": "// Monitor for disapprovals and quality issues\n\nconst items = $input.all();\nconst products = items[0]?.json?.products || [];\nconst disapprovals = [];\nconst warnings = [];\n\nproducts.forEach(product => {\n  // Check for issues in NEW Merchant API format\n  if (product.issues && product.issues.length > 0) {\n    product.issues.forEach(issue => {\n      if (issue.severity === 'error' || issue.applicability === 'DISAPPROVED') {\n        disapprovals.push({\n          product_id: product.offerId,\n          product_title: product.title,\n          issue: issue.description || issue.detail,\n          severity: 'CRITICAL'\n        });\n      } else if (issue.severity === 'warning') {\n        warnings.push({\n          product_id: product.offerId,\n          product_title: product.title,\n          issue: issue.description || issue.detail,\n          severity: 'WARNING'\n        });\n      }\n    });\n  }\n});\n\nreturn {\n  total_products_checked: products.length,\n  disapprovals: disapprovals,\n  warnings: warnings,\n  disapproval_count: disapprovals.length,\n  warning_count: warnings.length,\n  check_timestamp: new Date().toISOString()\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "7766d9c2-5967-4984-a9ff-5448b19fd51d",
      "name": "如果发现 disapprovals",
      "type": "n8n-nodes-base.if",
      "notes": "Check if any critical disapprovals exist",
      "position": [
        -1840,
        460
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "number": [
            {
              "value1": "={{$json.disapproval_count}}",
              "value2": 0,
              "operation": "larger"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "7ad9791b-2c14-4fee-bac2-b35ce882745d",
      "name": "警报 - disapprovals",
      "type": "n8n-nodes-base.slack",
      "notes": "Sends alert if disapprovals found",
      "position": [
        -1380,
        380
      ],
      "webhookId": "affe0e89-ef4a-4813-9a51-d6e096a7d774",
      "parameters": {
        "text": "=🚨 *Merchant Center Disapprovals Alert*\n\n*Total Disapprovals:* {{$json.disapproval_count}}\n*Total Warnings:* {{$json.warning_count}}\n\n*Critical Issues:*\n{{$json.disapprovals.slice(0,10).map(d => `• Product: ${d.product_title} (${d.product_id})\\n  Issue: ${d.issue}`).join('\\n\\n')}}\n\n*Action Required:* Review and fix disapproved products in Merchant Center.\n\n*Timestamp:* {{$json.check_timestamp}}",
        "otherOptions": {}
      },
      "typeVersion": 2.1
    },
    {
      "id": "e7d48164-e460-4f7e-bf8d-53f99df36e1e",
      "name": "成功摘要",
      "type": "n8n-nodes-base.slack",
      "notes": "Sends daily summary of feed optimization",
      "position": [
        -1380,
        580
      ],
      "webhookId": "84c5cd8c-521b-4982-81ca-fe0e7d24dff0",
      "parameters": {
        "text": "=✅ *Shopping Feed Optimization Complete*\n\n📊 *Summary:*\n• Total Products Processed: {{$node['Aggregate Products'].json.length}}\n• Products with Quality Issues: {{$node['Data Quality Checks'].json.products_with_issues}}\n• Disapprovals: {{$json.disapproval_count}}\n• Warnings: {{$json.warning_count}}\n\n🎯 *Optimizations Applied:*\n• Titles optimized for SEO\n• Descriptions enhanced\n• Custom labels assigned for segmented bidding\n\n*API Used:* NEW Merchant API (merchantapi.googleapis.com)\n*Next optimization:* Tomorrow 6 AM\n*Timestamp:* {{$now.toISO()}}",
        "otherOptions": {}
      },
      "typeVersion": 2.1
    },
    {
      "id": "7d1494bd-00c4-4aee-bda2-1f7a88e70109",
      "name": "上传到 Merchant Center(Content API v2.1)",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "CRITICAL CORRECTION: Uses NEW Merchant API (merchantapi.googleapis.com) instead of deprecated Content API. Endpoint: /products:insert. Max 1000 products per batch.",
      "position": [
        -2440,
        460
      ],
      "parameters": {
        "url": "=={{$env.MERCHANT_API_URL}}/{{$env.MERCHANT_ACCOUNT_ID}}/products",
        "method": "POST",
        "options": {
          "batching": {
            "batch": {
              "batchSize": 1000
            }
          }
        },
        "jsonBody": "={\n  \"productId\": \"{{$json.id}}\",\n  \"contentLanguage\": \"en\",\n  \"targetCountry\": \"US\",\n  \"channel\": \"online\",\n  \"offerId\": \"{{$json.id}}\",\n  \"title\": \"{{$json.optimized_title}}\",\n  \"description\": \"{{$json.optimized_description}}\",\n  \"link\": \"{{$json.link}}\",\n  \"imageLink\": \"{{$json.image_link}}\",\n  \"price\": {\n    \"value\": \"{{$json.price}}\",\n    \"currency\": \"{{$json.currency || 'USD'}}\"\n  },\n  \"availability\": \"{{$json.availability}}\",\n  \"brand\": \"{{$json.brand}}\",\n  \"gtin\": \"{{$json.gtin}}\",\n  \"condition\": \"{{$json.condition || 'new'}}\",\n  \"googleProductCategory\": \"{{$json.google_product_category}}\",\n  \"productTypes\": [\"{{$json.product_type}}\"],\n  \"customLabel0\": \"{{$json.custom_label_0}}\",\n  \"customLabel1\": \"{{$json.custom_label_1}}\",\n  \"customLabel2\": \"{{$json.custom_label_2}}\",\n  \"customLabel3\": \"{{$json.custom_label_3}}\",\n  \"customLabel4\": \"{{$json.custom_label_4}}\"\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "googleApi"
      },
      "typeVersion": 4.2
    },
    {
      "id": "0f405975-1874-4a86-8f6e-8cadac48922d",
      "name": "分离产品1",
      "type": "n8n-nodes-base.itemLists",
      "notes": "Splits the 'all_products' array from Data Quality Checks into individual product items for further processing (Relevance AI optimization, labeling, etc).",
      "position": [
        -3600,
        460
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "all_products"
      },
      "typeVersion": 3
    },
    {
      "id": "0fdb96fb-cbfc-4a0e-b5cc-adf8f6d4c35f",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -5060,
        340
      ],
      "parameters": {
        "width": 640,
        "height": 300,
        "content": "# 🛍️ 使用 Relevance AI + Google Merchant API 进行 Google Shopping Feed 优化"
      },
      "typeVersion": 1
    },
    {
      "id": "58d75113-8d09-4dbe-93d4-7f61f6a2c51f",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4240,
        680
      ],
      "parameters": {
        "width": 820,
        "height": 220,
        "content": "## 🟨 阶段 1 — 工作流开始"
      },
      "typeVersion": 1
    },
    {
      "id": "e474c0ae-303d-4038-b395-4288c83b1d30",
      "name": "便签3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3420,
        160
      ],
      "parameters": {
        "width": 680,
        "height": 240,
        "content": "## 🟨 阶段 2 — AI 优化阶段"
      },
      "typeVersion": 1
    },
    {
      "id": "4653db9a-6b15-4882-a55a-717e010fb0bc",
      "name": "便签4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2660,
        760
      ],
      "parameters": {
        "width": 1220,
        "height": 220,
        "content": "## 🟨 阶段 3 — Merchant Center 同步"
      },
      "typeVersion": 1
    },
    {
      "id": "fe61502c-d105-4610-a3fd-f6b1786ce661",
      "name": "便签5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1120,
        400
      ],
      "parameters": {
        "width": 440,
        "height": 240,
        "content": "## 🟨 阶段 4 — 通知"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "Optimize Title": {
      "main": [
        [
          {
            "node": "Generate Description",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Products1": {
      "main": [
        [
          {
            "node": "Optimize Title",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Product Feed": {
      "main": [
        [
          {
            "node": "Data Quality Checks",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Products": {
      "main": [
        [
          {
            "node": "Upload to Merchant Center (Content API v2.1)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Data Quality Checks": {
      "main": [
        [
          {
            "node": "Split Products1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Assign Custom Labels": {
      "main": [
        [
          {
            "node": "Aggregate Products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily Trigger - 6 AM": {
      "main": [
        [
          {
            "node": "Get Product Feed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Description": {
      "main": [
        [
          {
            "node": "Assign Custom Labels",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF Disapprovals Found": {
      "main": [
        [
          {
            "node": "Alert - Disapprovals",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Success Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze Product Issues": {
      "main": [
        [
          {
            "node": "IF Disapprovals Found",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Product Status (NEW API)": {
      "main": [
        [
          {
            "node": "Analyze Product Issues",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload to Merchant Center (Content API v2.1)": {
      "main": [
        [
          {
            "node": "Check Product Status (NEW API)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

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

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

高级 - 内容创作, 多模态 AI

需要付费吗?

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

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

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

作者
Nikan Noorafkan

Nikan Noorafkan

@nikkannoora

Hey, I’m Nikan Noorafkan — a creator passionate about building smart, automated workflows that drive business outcomes. With a background in performance marketing, user acquisition, and retention strategies, I use n8n to connect data, automate repetitive tasks, and scale growth across the funnel.

外部链接
在 n8n.io 查看

分享此工作流