8
n8n 中文网amn8n.com

使用Channable Feed和Relevance AI自动化Google广告文案优化

高级

这是一个Content Creation, Multimodal AI领域的自动化工作流,包含 16 个节点。主要使用 Code, Slack, HttpRequest, GoogleSheets, SplitInBatches 等节点。 使用Channable Feed和Relevance AI自动化Google广告文案优化

前置要求
  • Slack Bot Token 或 Webhook URL
  • 可能需要目标 API 的认证凭证
  • Google Sheets API 凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "meta": {
    "instanceId": "04fd795d32aabb18b913b4a3350b5cd0e9313a422ea0e7bdac0da2fb76cac9f7",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "cdb4f09e-e52a-4d5f-ad12-519db50c1234",
      "name": "每月计划触发器",
      "type": "n8n-nodes-base.scheduleTrigger",
      "notes": "Triggers on 1st of every month at midnight for 30-day performance review",
      "position": [
        300,
        1720
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 0 1 * *"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "8e3a3528-4cce-49c8-8b9d-412d24a5a595",
      "name": "获取 Google Ads 表现数据",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "CORRECTED: Uses HTTP Request with GAQL query instead of limited native Google Ads node. Returns all ads with min 100 impressions for statistical validity.",
      "position": [
        660,
        1740
      ],
      "parameters": {
        "url": "=https://googleads.googleapis.com/{{$env.GOOGLE_ADS_API_VERSION}}/customers/{{$env.GOOGLE_ADS_CUSTOMER_ID}}/googleAds:search",
        "method": "POST",
        "options": {
          "timeout": 60000
        },
        "jsonBody": "={\n  \"query\": \"SELECT ad_group_ad.ad.id, ad_group_ad.ad.responsive_search_ad.headlines, ad_group_ad.ad.responsive_search_ad.descriptions, ad_group.name, campaign.name, metrics.impressions, metrics.clicks, metrics.ctr, metrics.conversions, metrics.cost_micros FROM ad_group_ad WHERE segments.date DURING LAST_30_DAYS AND metrics.impressions > 100 ORDER BY metrics.clicks DESC LIMIT 10000\"\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "googleAdsOAuth2Api"
      },
      "credentials": {
        "googleAdsOAuth2Api": {
          "id": "x3Atp2GWGOjlhMz9",
          "name": "Google Ads account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "78baf9e9-5e1b-424c-ac5c-6bf33c3a9fa5",
      "name": "计算表现指标",
      "type": "n8n-nodes-base.code",
      "notes": "Analyzes GAQL response to identify patterns by category and theme. Calculates CTR, conversion rates, top/bottom performers.",
      "position": [
        1060,
        1760
      ],
      "parameters": {
        "jsCode": "// Calculate performance metrics and identify patterns\n\nconst items = $input.all();\nconst results = items[0].json.results || [];\n\n// Group ads by category and theme\nconst categoryPerformance = {};\nconst themePerformance = {};\n\nresults.forEach(result => {\n  const adGroup = result.adGroup?.name || 'Unknown';\n  const headlines = result.adGroupAd?.ad?.responsiveSearchAd?.headlines || [];\n  const headline = headlines[0]?.text || '';\n  const ctr = parseFloat(result.metrics?.ctr || 0);\n  const impressions = parseInt(result.metrics?.impressions || 0);\n  const clicks = parseInt(result.metrics?.clicks || 0);\n  const conversions = parseFloat(result.metrics?.conversions || 0);\n  const cost = parseFloat(result.metrics?.costMicros || 0) / 1000000;\n  \n  // Only include ads with sufficient data\n  if (impressions < 100) return;\n  \n  // Aggregate by category (ad group)\n  if (!categoryPerformance[adGroup]) {\n    categoryPerformance[adGroup] = {\n      total_impressions: 0,\n      total_clicks: 0,\n      total_conversions: 0,\n      total_cost: 0,\n      ad_count: 0\n    };\n  }\n  \n  categoryPerformance[adGroup].total_impressions += impressions;\n  categoryPerformance[adGroup].total_clicks += clicks;\n  categoryPerformance[adGroup].total_conversions += conversions;\n  categoryPerformance[adGroup].total_cost += cost;\n  categoryPerformance[adGroup].ad_count += 1;\n  \n  // Extract themes from headlines\n  const themes = ['vegan', 'organic', 'natural', 'premium', 'budget', 'sale', 'new', 'bestseller', 'free shipping'];\n  const headlineLower = headline.toLowerCase();\n  \n  themes.forEach(theme => {\n    if (headlineLower.includes(theme)) {\n      if (!themePerformance[theme]) {\n        themePerformance[theme] = {\n          total_impressions: 0,\n          total_clicks: 0,\n          total_conversions: 0,\n          ad_count: 0\n        };\n      }\n      themePerformance[theme].total_impressions += impressions;\n      themePerformance[theme].total_clicks += clicks;\n      themePerformance[theme].total_conversions += conversions;\n      themePerformance[theme].ad_count += 1;\n    }\n  });\n});\n\n// Calculate averages\nconst categoryMetrics = Object.entries(categoryPerformance).map(([category, data]) => ({\n  category,\n  avg_ctr: ((data.total_clicks / data.total_impressions) * 100).toFixed(2),\n  total_impressions: data.total_impressions,\n  total_clicks: data.total_clicks,\n  conversion_rate: data.total_clicks > 0 ? ((data.total_conversions / data.total_clicks) * 100).toFixed(2) : '0.00',\n  avg_cost_per_click: data.total_clicks > 0 ? (data.total_cost / data.total_clicks).toFixed(2) : '0.00',\n  ad_count: data.ad_count\n}));\n\nconst themeMetrics = Object.entries(themePerformance).map(([theme, data]) => ({\n  theme,\n  avg_ctr: ((data.total_clicks / data.total_impressions) * 100).toFixed(2),\n  total_impressions: data.total_impressions,\n  total_clicks: data.total_clicks,\n  conversion_rate: data.total_clicks > 0 ? ((data.total_conversions / data.total_clicks) * 100).toFixed(2) : '0.00',\n  ad_count: data.ad_count\n}));\n\n// Sort by CTR\ncategoryMetrics.sort((a, b) => parseFloat(b.avg_ctr) - parseFloat(a.avg_ctr));\nthemeMetrics.sort((a, b) => parseFloat(b.avg_ctr) - parseFloat(a.avg_ctr));\n\n// Identify top 20% and bottom 20%\nconst topCategories = categoryMetrics.slice(0, Math.max(1, Math.ceil(categoryMetrics.length * 0.2)));\nconst bottomCategories = categoryMetrics.slice(-Math.max(1, Math.ceil(categoryMetrics.length * 0.2)));\n\nconst topThemes = themeMetrics.slice(0, Math.max(1, Math.ceil(themeMetrics.length * 0.2)));\nconst bottomThemes = themeMetrics.slice(-Math.max(1, Math.ceil(themeMetrics.length * 0.2)));\n\nreturn {\n  overall_metrics: {\n    total_ads_analyzed: results.length,\n    date_range: 'Last 30 days',\n    analysis_date: new Date().toISOString()\n  },\n  category_performance: categoryMetrics,\n  theme_performance: themeMetrics,\n  top_performers: {\n    categories: topCategories,\n    themes: topThemes\n  },\n  bottom_performers: {\n    categories: bottomCategories,\n    themes: bottomThemes\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "d5ad62d0-fff7-4d75-8ca4-128f21a3183c",
      "name": "AI 表现分析",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "CORRECTED: Uses /agents/trigger with agent_id. AI analyzes patterns and provides insights like 'vegan messaging +23% CTR vs natural'.",
      "position": [
        1560,
        1660
      ],
      "parameters": {
        "url": "={{$env.RELEVANCE_AI_API_URL}}/agents/trigger",
        "method": "POST",
        "options": {
          "timeout": 90000
        },
        "jsonBody": "={\n  \"message\": {\n    \"role\": \"user\",\n    \"content\": \"Analyze this performance data and provide actionable insights. Data: \" + JSON.stringify($json)\n  },\n  \"agent_id\": \"{{$env.RELEVANCE_AGENT_PERFORMANCE_ID}}\"\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "luTyM3gZSgwhM8i0",
          "name": "Header Auth account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "15b0f40c-3422-47f6-b8d8-e901444e5209",
      "name": "更新知识库",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "CORRECTED: Uses knowledge source ID from env var. Feeds insights to Relevance AI for future ad generation.",
      "position": [
        1840,
        1660
      ],
      "parameters": {
        "url": "={{$env.RELEVANCE_AI_API_URL}}/knowledge/{{$env.RELEVANCE_KNOWLEDGE_SOURCE_ID}}/update",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"data\": {\n    \"insights\": {{JSON.stringify($json.insights || $json.output)}},\n    \"updated_at\": \"{{$now.toISO()}}\",\n    \"top_themes\": {{JSON.stringify($node['Calculate Performance Metrics'].json.top_performers.themes)}}\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "luTyM3gZSgwhM8i0",
          "name": "Header Auth account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "d9352d9b-16d9-45e2-9ed5-294d49d2faee",
      "name": "获取更新的产品源",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Retrieves latest product feed for regenerating ads with performance insights",
      "position": [
        2140,
        1660
      ],
      "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": "2a185395-90da-4a6c-a951-9cc8308df67e",
      "name": "分批处理",
      "type": "n8n-nodes-base.splitInBatches",
      "notes": "Process 50 products at a time",
      "position": [
        2460,
        1660
      ],
      "parameters": {
        "options": {},
        "batchSize": 50
      },
      "typeVersion": 3
    },
    {
      "id": "7e26aa2c-0630-43c6-80a3-6e873d8614bb",
      "name": "根据洞察重新生成广告文案",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "CORRECTED: Uses /trigger endpoint. AI now automatically uses performance insights from knowledge base.",
      "position": [
        2760,
        1660
      ],
      "parameters": {
        "url": "={{$env.RELEVANCE_AI_API_URL}}/tools/{{$env.RELEVANCE_TOOL_AD_COPY_ID}}/trigger",
        "method": "POST",
        "options": {
          "timeout": 60000
        },
        "jsonBody": "={\n  \"params\": {\n    \"product_title\": \"{{$json.title}}\",\n    \"product_description\": \"{{$json.description}}\",\n    \"price\": \"{{$json.price}}\",\n    \"category\": \"{{$json.category}}\",\n    \"brand\": \"{{$json.brand}}\",\n    \"use_performance_insights\": true\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "luTyM3gZSgwhM8i0",
          "name": "Header Auth account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "9645459f-f2fe-4bd1-abdc-b393a2d0282d",
      "name": "将优化后的广告保存到表格",
      "type": "n8n-nodes-base.googleSheets",
      "notes": "CORRECTED: Saves optimized ads to Google Sheets for review before publishing",
      "position": [
        3120,
        1660
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Optimized Ads"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{$env.GOOGLE_SHEET_ID}}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "0xHwEMloLvs9YH5S",
          "name": "Google Sheets account"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "e5484057-503a-4cf5-968c-000c64b0fd04",
      "name": "生成表现报告",
      "type": "n8n-nodes-base.code",
      "notes": "Creates detailed performance report with insights and changes made",
      "position": [
        3480,
        1660
      ],
      "parameters": {
        "jsCode": "// Generate performance report\nconst performanceData = $node['AI Performance Analysis'].json;\nconst metricsData = $node['Calculate Performance Metrics'].json;\n\nconst topThemes = metricsData.top_performers?.themes || [];\nconst bottomThemes = metricsData.bottom_performers?.themes || [];\n\nconst report = `# 30-Day Performance Optimization Report\n\n## Executive Summary\nDate: ${new Date().toISOString().split('T')[0]}\nAnalysis Period: Last 30 days\nAds Analyzed: ${metricsData.overall_metrics?.total_ads_analyzed || 0}\n\n## Top Performing Themes\n${topThemes.map((t, i) => `${i+1}. ${t.theme}: ${t.avg_ctr}% CTR (${t.ad_count} ads)`).join('\\n')}\n\n## Underperforming Themes\n${bottomThemes.map((t, i) => `${i+1}. ${t.theme}: ${t.avg_ctr}% CTR (${t.ad_count} ads)`).join('\\n')}\n\n## AI Insights\n${performanceData.output || performanceData.insights || 'Analysis complete'}\n\n## Next Optimization Cycle\nScheduled for: ${new Date(Date.now() + 30*24*60*60*1000).toISOString().split('T')[0]}\n`;\n\nreturn {\n  report_text: report,\n  report_html: report.replace(/\\n/g, '<br>'),\n  generated_at: new Date().toISOString(),\n  top_themes: topThemes,\n  bottom_themes: bottomThemes\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "f3096b96-3daa-4eee-bd52-666d5edb9d21",
      "name": "电子邮件表现报告",
      "type": "n8n-nodes-base.slack",
      "notes": "Sends performance report to team",
      "position": [
        3740,
        1660
      ],
      "webhookId": "7f13c699-7b46-4800-a05f-708e317c3f48",
      "parameters": {
        "text": "={{$json.report_text}}",
        "otherOptions": {}
      },
      "typeVersion": 2.1
    },
    {
      "id": "4dfc8a9d-039e-457e-96df-12811d2e5afb",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -860,
        1600
      ],
      "parameters": {
        "width": 1040,
        "height": 240,
        "content": "# 🧠 Google Ads 月度优化(Channable + Google Ads + Relevance AI)"
      },
      "typeVersion": 1
    },
    {
      "id": "d6c75f5e-bd70-46c8-b02f-48176f69b347",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        280,
        1920
      ],
      "parameters": {
        "width": 960,
        "content": "## 🟨 阶段 1 — 数据收集与触发"
      },
      "typeVersion": 1
    },
    {
      "id": "c0bca487-73de-4b13-89dc-de8a59e3bdca",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1400,
        1400
      ],
      "parameters": {
        "width": 960,
        "content": "## 🟨 阶段 2 — AI 分析与知识更新"
      },
      "typeVersion": 1
    },
    {
      "id": "65852982-9233-491d-b9ab-2a25cb712056",
      "name": "便签3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2400,
        1880
      ],
      "parameters": {
        "width": 940,
        "height": 140,
        "content": "## 🟨 阶段 3 — 广告文案重新生成与存储"
      },
      "typeVersion": 1
    },
    {
      "id": "de84f6a1-a333-4df9-b6a4-d9684396596d",
      "name": "便签说明4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3980,
        1640
      ],
      "parameters": {
        "width": 620,
        "height": 140,
        "content": "## 🟨 阶段 4 — 报告与沟通"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "Split Into Batches": {
      "main": [
        [
          {
            "node": "Regenerate Ad Copy with Insights",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Knowledge Base": {
      "main": [
        [
          {
            "node": "Get Updated Product Feed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Performance Analysis": {
      "main": [
        [
          {
            "node": "Update Knowledge Base",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Updated Product Feed": {
      "main": [
        [
          {
            "node": "Split Into Batches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Monthly Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get Google Ads Performance Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Performance Report": {
      "main": [
        [
          {
            "node": "Email Performance Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Optimized Ads to Sheets": {
      "main": [
        [
          {
            "node": "Generate Performance Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Performance Metrics": {
      "main": [
        [
          {
            "node": "AI Performance Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Google Ads Performance Data": {
      "main": [
        [
          {
            "node": "Calculate Performance Metrics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Regenerate Ad Copy with Insights": {
      "main": [
        [
          {
            "node": "Save Optimized Ads to Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

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

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

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

需要付费吗?

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

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

适合高级用户,包含 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 查看

分享此工作流