{
  "name": "Monitor Google Ads Campaigns Daily with n8n (free workflow JSON)",
  "nodes": [
    {
      "id": "97e85725-b387-480e-a9d1-8066a5aef2de",
      "name": "Schedule Daily Check",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -960,
        240
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "days",
              "daysInterval": 1,
              "triggerAtHour": 9
            }
          ]
        }
      }
    },
    {
      "id": "ac8ed47a-01cd-46b9-aff3-6fb6297f0b33",
      "name": "Fetch Google Ads Data",
      "type": "n8n-nodes-base.googleAds",
      "typeVersion": 1,
      "position": [
        -736,
        240
      ],
      "parameters": {
        "managerCustomerId": "",
        "clientCustomerId": "",
        "additionalOptions": {
          "dateRange": "LAST_7_DAYS",
          "campaignStatus": "ENABLED"
        },
        "requestOptions": {}
      }
    },
    {
      "id": "ae7508bf-4292-4db2-93ac-be1af7bf73d0",
      "name": "AI Performance Analysis",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -512,
        240
      ],
      "parameters": {
        "jsCode": "// AI-powered campaign performance analysis\nconst items = $input.all();\nconst analyzedItems = [];\n\nfor (const item of items) {\n  const data = item.json;\n  let performanceScore = 0;\n  let insights = [];\n  let recommendations = [];\n  let alertLevel = 'normal';\n  \n  // Extract metrics.\n  // The Google Ads node can return fields nested (campaign / metrics) or flat (id, name, costMicros...).\n  // This block reads both. If your numbers come out as 0, open the output of \"Fetch Google Ads Data\"\n  // and adjust the field names below. Clicks fall back to interactions when clicks is not returned.\n  const m = data.metrics || data;\n  const camp = data.campaign || data;\n  const clicks = Number(m.clicks ?? m.interactions ?? 0);\n  const impressions = Number(m.impressions ?? 0);\n  const cost = Number(m.cost_micros ?? m.costMicros ?? 0) / 1000000;\n  const conversions = Number(m.conversions ?? 0);\n  const ctr = impressions > 0 ? (clicks / impressions) * 100 : 0;\n  const conversionRate = clicks > 0 ? (conversions / clicks) * 100 : 0;\n  const costPerConversion = conversions > 0 ? cost / conversions : 0;\n  const avgCpc = clicks > 0 ? cost / clicks : 0;\n  \n  // CTR Analysis (Click-Through Rate)\n  if (ctr >= 5) {\n    performanceScore += 30;\n    insights.push(`Excellent CTR: ${ctr.toFixed(2)}% (+30 points)`);\n  } else if (ctr >= 3) {\n    performanceScore += 20;\n    insights.push(`Good CTR: ${ctr.toFixed(2)}% (+20 points)`);\n  } else if (ctr >= 1.5) {\n    performanceScore += 10;\n    insights.push(`Average CTR: ${ctr.toFixed(2)}% (+10 points)`);\n    recommendations.push('Consider A/B testing ad copy to improve CTR');\n  } else {\n    insights.push(`Low CTR: ${ctr.toFixed(2)}% (0 points)`);\n    recommendations.push('URGENT: Review ad relevance and targeting');\n    alertLevel = 'warning';\n  }\n  \n  // Conversion Rate Analysis\n  if (conversionRate >= 10) {\n    performanceScore += 35;\n    insights.push(`Outstanding conversion rate: ${conversionRate.toFixed(2)}% (+35 points)`);\n  } else if (conversionRate >= 5) {\n    performanceScore += 25;\n    insights.push(`Strong conversion rate: ${conversionRate.toFixed(2)}% (+25 points)`);\n  } else if (conversionRate >= 2) {\n    performanceScore += 15;\n    insights.push(`Moderate conversion rate: ${conversionRate.toFixed(2)}% (+15 points)`);\n    recommendations.push('Optimize landing pages for better conversions');\n  } else {\n    insights.push(`Low conversion rate: ${conversionRate.toFixed(2)}% (0 points)`);\n    recommendations.push('CRITICAL: Review landing page experience and targeting');\n    alertLevel = 'critical';\n  }\n  \n  // Cost Efficiency Analysis\n  if (costPerConversion > 0) {\n    if (costPerConversion <= 25) {\n      performanceScore += 25;\n      insights.push(`Excellent cost per conversion: $${costPerConversion.toFixed(2)} (+25 points)`);\n    } else if (costPerConversion <= 50) {\n      performanceScore += 15;\n      insights.push(`Good cost per conversion: $${costPerConversion.toFixed(2)} (+15 points)`);\n    } else if (costPerConversion <= 100) {\n      performanceScore += 8;\n      insights.push(`Fair cost per conversion: $${costPerConversion.toFixed(2)} (+8 points)`);\n      recommendations.push('Look for ways to reduce cost per conversion');\n    } else {\n      insights.push(`High cost per conversion: $${costPerConversion.toFixed(2)} (0 points)`);\n      recommendations.push('URGENT: Review bid strategy and audience targeting');\n      alertLevel = alertLevel === 'critical' ? 'critical' : 'warning';\n    }\n  }\n  \n  // Volume Analysis\n  if (clicks >= 1000) {\n    performanceScore += 10;\n    insights.push(`High traffic volume: ${clicks} clicks (+10 points)`);\n  } else if (clicks >= 500) {\n    performanceScore += 5;\n    insights.push(`Good traffic volume: ${clicks} clicks (+5 points)`);\n  } else if (clicks < 100) {\n    insights.push(`Low traffic volume: ${clicks} clicks (0 points)`);\n    recommendations.push('Consider increasing budget or expanding targeting');\n  }\n  \n  // Determine performance tier\n  let performanceTier = 'Underperforming';\n  if (performanceScore >= 75) {\n    performanceTier = 'Excellent';\n  } else if (performanceScore >= 55) {\n    performanceTier = 'Good';\n  } else if (performanceScore >= 35) {\n    performanceTier = 'Fair';\n  }\n  \n  // Add strategic recommendations\n  if (performanceTier === 'Excellent') {\n    recommendations.push('Scale this campaign - increase budget by 20-30%');\n    recommendations.push('Use this as a template for new campaigns');\n  } else if (performanceTier === 'Good') {\n    recommendations.push('Test incremental budget increases');\n    recommendations.push('Identify top-performing ad groups to scale');\n  }\n  \n  analyzedItems.push({\n    json: {\n      ...data,\n      campaignId: camp.id,\n      campaignName: camp.name,\n      campaignStatus: camp.status,\n      performanceScore: performanceScore,\n      performanceTier: performanceTier,\n      alertLevel: alertLevel,\n      insights: insights,\n      recommendations: recommendations,\n      metrics: {\n        clicks: clicks,\n        impressions: impressions,\n        cost: cost.toFixed(2),\n        conversions: conversions,\n        ctr: ctr.toFixed(2),\n        conversionRate: conversionRate.toFixed(2),\n        costPerConversion: costPerConversion.toFixed(2),\n        avgCpc: avgCpc.toFixed(2)\n      },\n      analyzedAt: new Date().toISOString()\n    }\n  });\n}\n\nreturn analyzedItems;"
      }
    },
    {
      "id": "cc1a1556-0544-4588-8259-b41891aae4fd",
      "name": "Route by Performance",
      "type": "n8n-nodes-base.if",
      "position": [
        -288,
        240
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "excellent",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.performanceTier }}",
              "rightValue": "Excellent"
            },
            {
              "id": "good",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.performanceTier }}",
              "rightValue": "Good"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "0be284fc-c850-4e6c-921c-17507e3bfd38",
      "name": "Update Campaign Dashboard",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        160,
        48
      ],
      "parameters": {
        "operation": "appendOrUpdate",
        "documentId": {
          "__rl": true,
          "value": "",
          "mode": "list"
        },
        "sheetName": {
          "__rl": true,
          "value": "Dashboard",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Campaign ID": "={{ $json.campaignId }}",
            "Campaign Name": "={{ $json.campaignName }}",
            "Status": "={{ $json.campaignStatus }}",
            "Score": "={{ $json.performanceScore }}",
            "Tier": "={{ $json.performanceTier }}",
            "Alert Level": "={{ $json.alertLevel }}",
            "Spend": "={{ $json.metrics.cost }}",
            "Conversions": "={{ $json.metrics.conversions }}",
            "CTR %": "={{ $json.metrics.ctr }}",
            "Conversion Rate %": "={{ $json.metrics.conversionRate }}",
            "Cost per Conversion": "={{ $json.metrics.costPerConversion }}",
            "Updated At": "={{ $json.analyzedAt }}"
          },
          "matchingColumns": [
            "Campaign ID"
          ],
          "schema": [
            {
              "id": "Campaign ID",
              "displayName": "Campaign ID",
              "required": false,
              "defaultMatch": true,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Campaign Name",
              "displayName": "Campaign Name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "displayName": "Status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Score",
              "displayName": "Score",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Tier",
              "displayName": "Tier",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Alert Level",
              "displayName": "Alert Level",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Spend",
              "displayName": "Spend",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Conversions",
              "displayName": "Conversions",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "CTR %",
              "displayName": "CTR %",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Conversion Rate %",
              "displayName": "Conversion Rate %",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Cost per Conversion",
              "displayName": "Cost per Conversion",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Updated At",
              "displayName": "Updated At",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "e92b8a04-20a2-431a-9662-1365a87657ec",
      "name": "Log All Campaigns",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        -64,
        432
      ],
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "",
          "mode": "list"
        },
        "sheetName": {
          "__rl": true,
          "value": "Log",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Campaign ID": "={{ $json.campaignId }}",
            "Campaign Name": "={{ $json.campaignName }}",
            "Status": "={{ $json.campaignStatus }}",
            "Score": "={{ $json.performanceScore }}",
            "Tier": "={{ $json.performanceTier }}",
            "Alert Level": "={{ $json.alertLevel }}",
            "Spend": "={{ $json.metrics.cost }}",
            "Conversions": "={{ $json.metrics.conversions }}",
            "CTR %": "={{ $json.metrics.ctr }}",
            "Conversion Rate %": "={{ $json.metrics.conversionRate }}",
            "Cost per Conversion": "={{ $json.metrics.costPerConversion }}",
            "Updated At": "={{ $json.analyzedAt }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "Campaign ID",
              "displayName": "Campaign ID",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Campaign Name",
              "displayName": "Campaign Name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "displayName": "Status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Score",
              "displayName": "Score",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Tier",
              "displayName": "Tier",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Alert Level",
              "displayName": "Alert Level",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Spend",
              "displayName": "Spend",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Conversions",
              "displayName": "Conversions",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "CTR %",
              "displayName": "CTR %",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Conversion Rate %",
              "displayName": "Conversion Rate %",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Cost per Conversion",
              "displayName": "Cost per Conversion",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Updated At",
              "displayName": "Updated At",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "c47437f1-c24f-41ae-8a78-cfa9afa73f86",
      "name": "Alert: Scale Opportunity",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.3,
      "position": [
        -64,
        -96
      ],
      "parameters": {
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "",
          "mode": "list"
        },
        "text": "=:rocket: Scale opportunity: {{ $json.campaignName }} scored {{ $json.performanceScore }}/100 ({{ $json.performanceTier }}). Spend {{ $json.metrics.cost }}, conversions {{ $json.metrics.conversions }}, cost per conversion {{ $json.metrics.costPerConversion }}.",
        "otherOptions": {}
      }
    },
    {
      "id": "776c44d4-1e01-42e4-b42b-163e1d1cfa73",
      "name": "Generate Action Plan",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -64,
        240
      ],
      "parameters": {
        "jsCode": "// Generate detailed action plan based on performance\nconst items = $input.all();\nconst actionPlanItems = [];\n\nfor (const item of items) {\n  const data = item.json;\n  const tier = data.performanceTier || 'Fair';\n  const campaignName = data.campaignName || 'Campaign';\n  const alertLevel = data.alertLevel || 'normal';\n  \n  let emailSubject = '';\n  let emailBody = '';\n  let priority = 'Medium';\n  \n  if (tier === 'Excellent' || tier === 'Good') {\n    priority = 'High';\n    emailSubject = `✅ ${campaignName}: Scaling Opportunity Detected`;\n    emailBody = `Hi PPC Team,\n\nGreat news! Your campaign \"${campaignName}\" is performing exceptionally well.\n\n📊 PERFORMANCE SUMMARY\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nPerformance Score: ${data.performanceScore}/100\nPerformance Tier: ${tier}\nSpend (selected date range): $${data.metrics.cost}\nConversions: ${data.metrics.conversions}\nConversion Rate: ${data.metrics.conversionRate}%\nCost per Conversion: $${data.metrics.costPerConversion}\n\n💡 KEY INSIGHTS\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n${data.insights.map((insight, i) => `${i + 1}. ${insight}`).join('\\n')}\n\n🎯 RECOMMENDED ACTIONS\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n${data.recommendations.map((rec, i) => `${i + 1}. ${rec}`).join('\\n')}\n\n📈 SCALING STRATEGY\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n• Increase daily budget by 20-30%\n• Monitor performance closely for next 3-5 days\n• If metrics hold, continue scaling gradually\n• Consider duplicating successful ad groups\n• Test expansion to similar audiences\n\nThis campaign is ready to scale. Let's capitalize on this momentum!\n\nBest,\nAutomated PPC Intelligence System`;\n  } else if (alertLevel === 'critical' || alertLevel === 'warning') {\n    priority = 'Urgent';\n    emailSubject = `⚠️ ${campaignName}: Performance Issues Detected`;\n    emailBody = `Hi PPC Team,\n\n⚠️ ATTENTION REQUIRED\n\nYour campaign \"${campaignName}\" requires immediate attention due to performance concerns.\n\n📊 PERFORMANCE SUMMARY\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nPerformance Score: ${data.performanceScore}/100\nPerformance Tier: ${tier}\nAlert Level: ${alertLevel.toUpperCase()}\nSpend (selected date range): $${data.metrics.cost}\nConversions: ${data.metrics.conversions}\nConversion Rate: ${data.metrics.conversionRate}%\nCost per Conversion: $${data.metrics.costPerConversion}\n\n⚠️ IDENTIFIED ISSUES\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n${data.insights.map((insight, i) => `${i + 1}. ${insight}`).join('\\n')}\n\n🔧 REQUIRED ACTIONS\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n${data.recommendations.map((rec, i) => `${i + 1}. ${rec}`).join('\\n')}\n\n🚨 IMMEDIATE NEXT STEPS\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n1. Review campaign settings and targeting\n2. Analyze recent changes that may have impacted performance\n3. Check landing page experience and load times\n4. Review competitor activity\n5. Consider pausing low-performing ad groups\n6. Test new ad variations\n\nPlease address these issues within 24 hours to prevent budget waste.\n\nBest,\nAutomated PPC Intelligence System`;\n  } else {\n    emailSubject = `📊 ${campaignName}: Daily Performance Report`;\n    emailBody = `Hi PPC Team,\n\nHere's your daily performance summary for \"${campaignName}\".\n\n📊 PERFORMANCE SUMMARY\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nPerformance Score: ${data.performanceScore}/100\nPerformance Tier: ${tier}\nSpend (selected date range): $${data.metrics.cost}\nConversions: ${data.metrics.conversions}\nConversion Rate: ${data.metrics.conversionRate}%\nCost per Conversion: $${data.metrics.costPerConversion}\n\n💡 INSIGHTS\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n${data.insights.map((insight, i) => `${i + 1}. ${insight}`).join('\\n')}\n\n📋 RECOMMENDATIONS\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n${data.recommendations.map((rec, i) => `${i + 1}. ${rec}`).join('\\n')}\n\nContinue monitoring and optimizing for best results.\n\nBest,\nAutomated PPC Intelligence System`;\n  }\n  \n  actionPlanItems.push({\n    json: {\n      ...data,\n      emailSubject: emailSubject,\n      emailBody: emailBody,\n      priority: priority,\n      actionRequired: alertLevel === 'critical' || alertLevel === 'warning',\n      scaleRecommended: tier === 'Excellent' || tier === 'Good'\n    }\n  });\n}\n\nreturn actionPlanItems;"
      }
    },
    {
      "id": "b2b2389c-05b5-49c2-824a-50817acf150e",
      "name": "Email Performance Report",
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 2.1,
      "position": [
        160,
        240
      ],
      "parameters": {
        "fromEmail": "CHANGE-ME@example.com",
        "toEmail": "CHANGE-ME@example.com",
        "subject": "={{ $json.emailSubject }}",
        "emailFormat": "text",
        "text": "={{ $json.emailBody }}",
        "options": {}
      }
    },
    {
      "id": "65a1623b-f9a9-415d-849a-42f779c3a766",
      "name": "Alert: Issues Detected",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.3,
      "position": [
        -64,
        624
      ],
      "parameters": {
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "",
          "mode": "list"
        },
        "text": "=:warning: Attention needed: {{ $json.campaignName }} scored {{ $json.performanceScore }}/100 ({{ $json.performanceTier }}, alert level {{ $json.alertLevel }}). {{ $json.recommendations.join('; ') }}",
        "otherOptions": {}
      }
    },
    {
      "id": "53086c74-d3f7-4761-91f1-706dd04aeda7",
      "name": "Generate Daily Summary",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        384,
        144
      ],
      "parameters": {
        "jsCode": "// Build one summary for the whole run, from the analyzed campaigns.\n// It reads the analysis node directly, so it works whichever branch triggered it.\nconst items = $('AI Performance Analysis').all();\nconst countTier = (tier) => items.filter(item => item.json.performanceTier === tier).length;\n\nconst totalSpend = items.reduce((sum, item) => sum + parseFloat(item.json.metrics.cost || 0), 0);\nconst totalConversions = items.reduce((sum, item) => sum + Number(item.json.metrics.conversions || 0), 0);\n\nconst summary = {\n  totalCampaigns: items.length,\n  excellentCampaigns: countTier('Excellent'),\n  goodCampaigns: countTier('Good'),\n  fairCampaigns: countTier('Fair'),\n  underperformingCampaigns: countTier('Underperforming'),\n  totalSpend: totalSpend.toFixed(2),\n  totalConversions: totalConversions\n};\n\nsummary.dailySummary = `📊 Daily PPC Performance Summary\n\n${summary.totalCampaigns} ${summary.totalCampaigns === 1 ? 'campaign' : 'campaigns'} analyzed:\n• ${summary.excellentCampaigns} Excellent 🚀\n• ${summary.goodCampaigns} Good ✅\n• ${summary.fairCampaigns} Fair ⚠️\n• ${summary.underperformingCampaigns} Underperforming 🔴\n\nTotal Spend (selected date range): $${summary.totalSpend}\nTotal Conversions: ${summary.totalConversions}`;\n\nreturn [{ json: summary }];"
      },
      "executeOnce": true
    },
    {
      "id": "7936c950-f1d7-4f1a-9ea3-ea693a9955fd",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -1552,
        64
      ],
      "parameters": {
        "width": 500,
        "height": 572,
        "content": "## Google Ads daily check\n\nEvery day at 9 AM the workflow reads your Google Ads campaigns, scores each one from 0 to 100 with a fixed formula, saves the results to Google Sheets, alerts Slack and emails a report.\n\n**Before you run it:**\n- Add credentials: Google Ads, Google Sheets, Slack, SMTP (email)\n- Fill in your Google Ads customer ID in Fetch Google Ads Data\n- Choose your spreadsheet (tabs Dashboard and Log) and your Slack channel\n- Set the sender and recipient in Email Performance Report\n- Adjust the scoring thresholds in AI Performance Analysis if needed\n\nSource: based on a template from the n8n Library at n8n.io, adjusted and documented by LeenLabs."
      }
    },
    {
      "id": "ef8d2d41-a0ef-4b1d-818e-f5a7d7226537",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -992,
        112
      ],
      "parameters": {
        "width": 160,
        "height": 96,
        "content": "Runs every day at 9 AM (time zone of your n8n settings)"
      }
    },
    {
      "id": "fa399e33-4467-47c1-9348-cb158ee868a2",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -768,
        112
      ],
      "parameters": {
        "width": 160,
        "height": 96,
        "content": "Reads your campaigns and their metrics from Google Ads"
      }
    },
    {
      "id": "fb6102c7-dc3e-4c25-971d-06466655d812",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -544,
        112
      ],
      "parameters": {
        "width": 160,
        "height": 96,
        "content": "Scores each campaign from 0 to 100 with a fixed formula (a rule-based score, not an AI model)"
      }
    },
    {
      "id": "0a0be77c-952d-4b11-ba26-65572a0e736a",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -320,
        112
      ],
      "parameters": {
        "width": 160,
        "height": 96,
        "content": "Excellent or Good goes up, Fair or Underperforming goes down"
      }
    },
    {
      "id": "7ffd9913-010f-4cb0-9254-bbbb90871c2e",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -256,
        432
      ],
      "parameters": {
        "width": 160,
        "height": 96,
        "content": "Adds every campaign to the Log tab (history)"
      }
    },
    {
      "id": "81f36a32-5ee6-4dbf-b84e-b00677bb0264",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        128,
        -80
      ],
      "parameters": {
        "width": 160,
        "height": 96,
        "content": "Updates one row per campaign in the Dashboard tab"
      }
    },
    {
      "id": "19224e33-b214-421e-b867-73f7e8434669",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -272,
        -96
      ],
      "parameters": {
        "width": 160,
        "height": 128,
        "content": "Slack message for campaigns scored Excellent or Good"
      }
    },
    {
      "id": "a0a6c66c-167f-4bb7-9e88-d15abf368632",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -256,
        624
      ],
      "parameters": {
        "width": 160,
        "height": 128,
        "content": "Slack message for campaigns scored Fair or Underperforming"
      }
    },
    {
      "id": "1f7e7fcd-258b-4bc1-ba66-a6775f5b165c",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -96,
        112
      ],
      "parameters": {
        "width": 160,
        "height": 96,
        "content": "Writes the email text for each campaign"
      }
    },
    {
      "id": "caa7a611-c83b-4936-bc34-86ee7a405754",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        128,
        416
      ],
      "parameters": {
        "width": 160,
        "height": 96,
        "content": "Sends the report email (set sender and recipient)"
      }
    },
    {
      "id": "a15c7d78-b442-4af0-a02c-97a46f8fc623",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        352,
        16
      ],
      "parameters": {
        "width": 160,
        "height": 96,
        "content": "Adds up spend, conversions and how many campaigns fall in each tier"
      }
    }
  ],
  "connections": {
    "Generate Action Plan": {
      "main": [
        [
          {
            "node": "Email Performance Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Performance": {
      "main": [
        [
          {
            "node": "Update Campaign Dashboard",
            "type": "main",
            "index": 0
          },
          {
            "node": "Log All Campaigns",
            "type": "main",
            "index": 0
          },
          {
            "node": "Alert: Scale Opportunity",
            "type": "main",
            "index": 0
          },
          {
            "node": "Generate Action Plan",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update Campaign Dashboard",
            "type": "main",
            "index": 0
          },
          {
            "node": "Log All Campaigns",
            "type": "main",
            "index": 0
          },
          {
            "node": "Alert: Issues Detected",
            "type": "main",
            "index": 0
          },
          {
            "node": "Generate Action Plan",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Daily Check": {
      "main": [
        [
          {
            "node": "Fetch Google Ads Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Google Ads Data": {
      "main": [
        [
          {
            "node": "AI Performance Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Performance Analysis": {
      "main": [
        [
          {
            "node": "Route by Performance",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Email Performance Report": {
      "main": [
        [
          {
            "node": "Generate Daily Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Campaign Dashboard": {
      "main": [
        [
          {
            "node": "Generate Daily Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}