8
n8n 한국어amn8n.com

Channable 피드와 Relevance AI를 사용한 Google 광고 카피 최적화 자동화

고급

이것은Content Creation, Multimodal AI분야의자동화 워크플로우로, 16개의 노드를 포함합니다.주로 Code, Slack, HttpRequest, GoogleSheets, SplitInBatches 등의 노드를 사용하며. Channable 피드와 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": "최적화된 광고를 Sheets에 저장",
      "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 Monthly Optimization (Channable + Google Ads + Relevance AI)\nAutomates your monthly Google Ads optimization using Relevance AI and Channable.  \nAnalyzes ad performance, identifies top/bottom performers, generates AI insights, and refreshes ad copies with data-driven improvements.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "d6c75f5e-bd70-46c8-b02f-48176f69b347",
      "name": "스티커 메모1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        280,
        1920
      ],
      "parameters": {
        "width": 960,
        "content": "## 🟨 Stage 1 — Data Collection & Trigger\n| ⏰ Monthly Schedule Trigger | 📊 Get Google Ads Performance Data | 🧮 Calculate Performance Metrics |\n|-----------------------------|-----------------------------------|--------------------------------|\n| Runs automatically on the 1st of each month at midnight to review the past 30 days. | Retrieves Google Ads data using GAQL via the API — includes impressions, clicks, CTR, conversions, and costs. | Processes raw data to compute performance metrics (CTR, conversion rate, CPC). Groups results by ad category and creative theme. |"
      },
      "typeVersion": 1
    },
    {
      "id": "c0bca487-73de-4b13-89dc-de8a59e3bdca",
      "name": "스티커 메모2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1400,
        1400
      ],
      "parameters": {
        "width": 960,
        "content": "## 🟨 Stage 2 — AI Analysis & Knowledge Update\n| 🤖 AI Performance Analysis | 🧠 Update Knowledge Base | 📦 Get Updated Product Feed |\n|----------------------------|--------------------------|-----------------------------|\n| Uses Relevance AI’s `/agents/trigger` endpoint to analyze metrics and extract actionable insights. Example: *“Vegan-themed ads show +23% CTR vs average.”* | Feeds AI-generated insights back into your Relevance AI knowledge base for future ad optimization cycles. | Retrieves the latest Channable product feed to prepare updated ads using the new performance insights. |"
      },
      "typeVersion": 1
    },
    {
      "id": "65852982-9233-491d-b9ab-2a25cb712056",
      "name": "스티커 메모3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2400,
        1880
      ],
      "parameters": {
        "width": 940,
        "height": 140,
        "content": "## 🟨 Stage 3 — Ad Copy Regeneration & Storage\n| ✂️ Split Into Batches | ✍️ Regenerate Ad Copy with Insights | 📄 Save Optimized Ads to Sheets |\n|------------------------|------------------------------------|--------------------------------|\n| Splits the product feed into batches of 50 to optimize efficiently. | Uses Relevance AI `/tools/{id}/trigger` to rewrite ad copy for each product, incorporating fresh performance data. | Saves regenerated ads to a Google Sheet for QA review or manual approval before publishing. |"
      },
      "typeVersion": 1
    },
    {
      "id": "de84f6a1-a333-4df9-b6a4-d9684396596d",
      "name": "스티커 메모4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3980,
        1640
      ],
      "parameters": {
        "width": 620,
        "height": 140,
        "content": "## 🟨 Stage 4 — Reporting & Communication\n| 📈 Generate Performance Report | 📢 Email Performance Report |\n|-------------------------------|-----------------------------|\n| Generates a comprehensive monthly performance report summarizing top/bottom themes, CTR trends, and AI recommendations. | Sends a Slack message (or email) to the marketing team containing the full report and optimization insights. |"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "2a185395-90da-4a6c-a951-9cc8308df67e": {
      "main": [
        [
          {
            "node": "7e26aa2c-0630-43c6-80a3-6e873d8614bb",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "15b0f40c-3422-47f6-b8d8-e901444e5209": {
      "main": [
        [
          {
            "node": "d9352d9b-16d9-45e2-9ed5-294d49d2faee",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d5ad62d0-fff7-4d75-8ca4-128f21a3183c": {
      "main": [
        [
          {
            "node": "15b0f40c-3422-47f6-b8d8-e901444e5209",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d9352d9b-16d9-45e2-9ed5-294d49d2faee": {
      "main": [
        [
          {
            "node": "2a185395-90da-4a6c-a951-9cc8308df67e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "cdb4f09e-e52a-4d5f-ad12-519db50c1234": {
      "main": [
        [
          {
            "node": "8e3a3528-4cce-49c8-8b9d-412d24a5a595",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e5484057-503a-4cf5-968c-000c64b0fd04": {
      "main": [
        [
          {
            "node": "f3096b96-3daa-4eee-bd52-666d5edb9d21",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9645459f-f2fe-4bd1-abdc-b393a2d0282d": {
      "main": [
        [
          {
            "node": "e5484057-503a-4cf5-968c-000c64b0fd04",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "78baf9e9-5e1b-424c-ac5c-6bf33c3a9fa5": {
      "main": [
        [
          {
            "node": "d5ad62d0-fff7-4d75-8ca4-128f21a3183c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8e3a3528-4cce-49c8-8b9d-412d24a5a595": {
      "main": [
        [
          {
            "node": "78baf9e9-5e1b-424c-ac5c-6bf33c3a9fa5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7e26aa2c-0630-43c6-80a3-6e873d8614bb": {
      "main": [
        [
          {
            "node": "9645459f-f2fe-4bd1-abdc-b393a2d0282d",
            "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에서 보기

이 워크플로우 공유

카테고리

카테고리: 34