{
  "id": "lmotacwXoBreGo6VcVh5-",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Query GA4 data with AI and natural language in Slack channel",
  "tags": [
    {
      "id": "aUJ0jmgTbUJikuZl",
      "name": "slack",
      "createdAt": "2026-01-25T15:28:51.109Z",
      "updatedAt": "2026-01-25T15:28:51.109Z"
    },
    {
      "id": "dA7L2nOfM12IEvMj",
      "name": "google analytics",
      "createdAt": "2026-01-25T15:28:54.487Z",
      "updatedAt": "2026-01-25T15:28:54.487Z"
    },
    {
      "id": "m5iCWoJAMNpsodp3",
      "name": "ga4",
      "createdAt": "2026-01-25T15:28:48.821Z",
      "updatedAt": "2026-01-25T15:28:48.821Z"
    }
  ],
  "nodes": [
    {
      "id": "5f649028-62b1-4ebe-a1ec-02eca7d007aa",
      "name": "Slack Trigger",
      "type": "n8n-nodes-base.slackTrigger",
      "position": [
        -1456,
        -2064
      ],
      "parameters": {
        "options": {},
        "trigger": [
          "app_mention"
        ],
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0AA6U5F095",
          "cachedResultName": "all-ga4-n8n-llm"
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "47fb84b8-1a4a-4ad5-9aea-cb9169d7a25f",
      "name": "Edit Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        -1248,
        -2064
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "32a37711-d394-4ff3-8fb0-b01d1c49e25f",
              "name": "text",
              "type": "string",
              "value": "={{ $json.text.replace(/<@.*?>/g, '').trim() }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "5c980803-2e81-4770-9a72-64c00859c384",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -1040,
        -2064
      ],
      "parameters": {
        "text": "={{ $node[\"Edit Fields\"].json[\"text\"] }}",
        "options": {
          "systemMessage": "=### ROLE\nYou are the Scalo AI Labs Senior GA4 Analyst. You are prohibited from estimating or inventing data.\n\n### TIME & DATA INTEGRITY\n- Today is {{ $now.toFormat('cccc, MMMM dd, yyyy') }}.\n-CRITICAL: You are only allowed to report numbers returned by the 'Get a report in Google Analytics' tool. If the tool returns no data, you MUST say '0' or 'No data found.' Under no circumstances should you estimate the number. \n\n### THE SCHEMA LOOKUP RULE (MANDATORY)\nYou have access to the full GA4 API Schema (~300 items). Before calling a tool, you must perform a semantic match:\n\n1. ACQUISITION: \n   - Visits/Traffic -> sessions\n   - Where they came from -> sessionSource / sessionMedium\n   - Channel Groups -> defaultChannelGroup\n\n2. ENGAGEMENT:\n   - Views/Hits -> screenPageViews\n   - Engagement Rate -> engagementRate\n   - Time on Site -> averageSessionDuration\n   - Bounce -> bounceRate\n\n3. REVENUE & ECOMMERCE:\n   - Total Sales/Income -> purchaseRevenue\n   - Product Revenue -> grossItemRevenue\n   - Items -> itemName, itemId, itemCategory (1-5)\n   - Cart Actions -> addToCarts, checkouts\n\n4. UNLISTED ITEMS:\n   - If the user asks for a specific dimension or metric not listed above (e.g., \"Ad format\", \"Language\"), you MUST find the exact camelCase API Name from the official schema (e.g., adFormat, language).\n\n### EXECUTION GUARDRAIL\n- Only call the tool with valid camelCase strings.\n- If a metric name like \"product_revenue\" is sent, it will FAIL. Use \"grossItemRevenue\".\nAlways include the start/end dates used in your reply to avoid any confusion with the user"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "43787510-2642-4c58-8835-85801c1699f0",
      "name": "Get a report in Google Analytics",
      "type": "n8n-nodes-base.googleAnalyticsTool",
      "position": [
        -800,
        -1856
      ],
      "parameters": {
        "endDate": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('End', ``, 'string') }}",
        "dateRange": "custom",
        "returnAll": true,
        "startDate": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start', ``, 'string') }}",
        "metricsGA4": {
          "metricValues": [
            {
              "name": "custom_metric",
              "listName": "={{ $fromAI(\"metric\", \"The GA4 metric to retrieve such as sessions or activeUsers\") }}"
            }
          ]
        },
        "propertyId": {
          "__rl": true,
          "mode": "id",
          "value": "521315571"
        },
        "dimensionsGA4": {
          "dimensionValues": [
            {
              "listName": "={{ $fromAI(\"dimension\", \"The GA4 dimension like date or pagePath\") }}"
            }
          ]
        },
        "additionalFields": {}
      },
      "credentials": {
        "googleAnalyticsOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "fa360f13-2343-4aed-8e67-2b0163453848",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -1184,
        -1840
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-2.5-pro"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "59037e5c-7658-42c3-9f98-fb1d137c8ca0",
      "name": "Simple Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "onError": "continueRegularOutput",
      "position": [
        -992,
        -1840
      ],
      "parameters": {
        "sessionKey": "=JAN_26_FINAL_ACTUAL",
        "sessionIdType": "customKey",
        "contextWindowLength": 10
      },
      "typeVersion": 1.3
    },
    {
      "id": "73c0219f-4251-4af5-b7d4-f4a1ac82ac27",
      "name": "Send a message",
      "type": "n8n-nodes-base.slack",
      "position": [
        -688,
        -2064
      ],
      "parameters": {
        "text": "={{ $node[\"AI Agent\"].json[\"output\"] }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $node[\"Slack Trigger\"].json[\"channel\"] }}"
        },
        "otherOptions": {
          "thread_ts": {
            "replyValues": {
              "thread_ts": "={{ $node[\"Slack Trigger\"].json[\"ts\"] }}"
            }
          }
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "798a2455-e09b-4b63-bb51-408bc8d787a7",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1664,
        -2512
      ],
      "parameters": {
        "width": 1440,
        "height": 848,
        "content": "## How it works\n\nThis workflow seamlessly integrates Google Analytics 4 (GA4) with Slack, allowing users to query their website data using natural language inside a dedicated Slack channel. Video walkthrough: https://www.youtube.com/watch?v=oWXDc6uASfA\n\n## Setup steps\n\n1.  **Slack trigger**: Configure Slack API inside n8n to watch out for new messages that are sent in a specific channel. \n2.  **Credentials**: Configure credentials for Slack, GA4, Gemini .\n3.  **AI agent system prompt**: Create an AI agent that is not allowed to estimate or lie on data. If GA4 is unavailable, inform so. Also map natural language metrics to GA4 metrics (e.g. when the user mentions leads, they mean conversions in GA4)\n4.  **Slack reply**: Send a short natural text inside Slack as a reply to the user containing the numbers and dates used while fetching data"
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "6d8b192e-8751-4514-b640-3d9acf2952ac",
  "connections": {
    "AI Agent": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Slack Trigger": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Get a report in Google Analytics": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    }
  }
}