---
title: "Automate Weekly Marketing Reports from GA4 with n8n + AI"
description: "Build a scheduled n8n workflow that pulls GA4 metrics, writes an AI summary with insights, and emails your team — AI credits included, no API key setup."
canonical: https://agentroost.app/en/blog/weekly-marketing-reports-ga4-n8n-ai
date: 2026-06-02T04:00:00Z
---

[Canonical URL](https://agentroost.app/en/blog/weekly-marketing-reports-ga4-n8n-ai)

Every marketing team has a version of the same Monday ritual: someone opens GA4, exports last week's numbers, pastes them into a doc, writes two paragraphs of context, formats the table, and sends it to the distribution list. It takes 30–60 minutes and it happens 52 times a year. This post shows you how to build that workflow in n8n so it runs itself — and how an AI node writes the narrative paragraph so the output is actually readable, not just a raw data dump.

## What the finished workflow does

1. Fires every Monday at 08:00 (your time zone).
2. Fetches last week's GA4 data: sessions, new users, bounce/engagement rate, goal completions, and top channel groupings.
3. Optionally fetches spend data from Google Ads or Meta Ads (same pattern, different node).
4. Passes the metrics to an AI/LLM node that writes a 150–200 word plain-English summary with a "What worked", "What to watch", and "Suggested next steps" structure.
5. Sends the finished report as a formatted HTML email to your stakeholders.

Total node count: 6–8 nodes. Build time: roughly 45 minutes the first time.

---

## Step 1 — Schedule Trigger

Drop a **Schedule Trigger** node. Set it to **Cron** mode and use:

```
0 8 * * 1
```

That fires at 08:00 every Monday. Set the **Timezone** field to match your team (e.g. `Europe/Istanbul` or `America/New_York`) — n8n respects it exactly, no UTC math needed.

---

## Step 2 — Pull GA4 data with the Google Analytics node

Add a **Google Analytics** node (search "Google Analytics" in the node panel — it's the first-party one, not a custom HTTP Request).

**Authentication:** create a **Google Analytics OAuth2** credential. You need a Google Cloud project with the Analytics Data API enabled, plus an OAuth 2.0 Client ID scoped to `https://www.googleapis.com/auth/analytics.readonly`. Paste the client ID and secret into n8n's credential modal, click Connect, and authorize. n8n handles token refresh from that point on.

**Node config:**

| Field | Value |
|---|---|
| Property ID | Your GA4 numeric property ID (find it in GA4 → Admin → Property Settings) |
| Date Range | `last7Days` (or use expressions: `{{ $today.minus({days: 7}).toFormat('yyyy-MM-dd') }}` for the start) |
| Dimensions | `sessionDefaultChannelGroup`, `country` |
| Metrics | `sessions`, `newUsers`, `bounceRate`, `conversions`, `engagedSessions` |
| Limit | 20 |

The node outputs one item per dimension combination. A **Summarize** or **Aggregate** node can roll them up by channel group before passing to the AI step.

---

## Step 3 — (Optional) Pull ad spend from Google Ads or Meta

If you run paid campaigns, add a second data fetch in parallel. For **Google Ads**, use an HTTP Request node hitting the Google Ads API:

```
POST https://googleads.googleapis.com/v18/customers/{customer_id}/googleAds:search
```

Body (minimal, returns last 7 days of campaign cost + impressions + clicks):

```json
{
  "query": "SELECT campaign.name, metrics.cost_micros, metrics.impressions, metrics.clicks FROM campaign WHERE segments.date DURING LAST_7_DAYS"
}
```

Divide `cost_micros` by 1,000,000 for actual spend. A **Set** node can reshape the fields into clean labels before the merge step.

Use a **Merge** node (mode: **Merge by Index** or **Append**) to combine GA4 output with the ads data into a single payload.

---

## Step 4 — Build the AI prompt with a Set node

Before calling the LLM, use a **Set** node to construct a structured prompt string. This keeps your prompt readable and lets you inject live values cleanly:

```
You are a marketing analyst. Below are last week's website and paid media metrics.

GA4 Summary:
- Sessions: {{ $json.sessions }}
- New Users: {{ $json.newUsers }}
- Bounce Rate: {{ $json.bounceRate }}%
- Conversions: {{ $json.conversions }}
- Top Channel: {{ $json.topChannel }}

Ad Spend: ${{ $json.totalSpend }} | Clicks: {{ $json.totalClicks }} | Impressions: {{ $json.impressions }}

Write a concise 150-200 word marketing performance summary with three sections:
1. What worked this week
2. What to watch (anomalies or drops)
3. Two specific recommended next steps

Tone: direct, data-backed, no filler.
```

Storing the prompt in a Set node (rather than inline in the AI node) also makes it easy to version and tweak without touching the node logic.

---

## Step 5 — AI/LLM node writes the narrative

Add an **AI** node (labeled "Basic LLM Chain" or "Chat Model" depending on your n8n version). Point it at the prompt output from the previous Set node.

- **Model:** any chat model in the list — GPT-4o, Claude 3.5 Sonnet, and Mistral Large all produce good analytical prose. Switch models without touching the rest of the workflow.
- **System prompt:** "You are a concise marketing analyst. Return only the report text, no preamble."
- **Max tokens:** 400 is enough for a 200-word summary.

The node outputs `{{ $json.text }}` — the finished paragraph.

---

## Step 6 — Send the email

Add a **Gmail** node (or **Send Email** for SMTP). Build the HTML body by combining a header, a metrics table, and the AI narrative:

```html
<h2>Weekly Marketing Report — {{ $today.minus({days:7}).toFormat('dd MMM') }} to {{ $today.minus({days:1}).toFormat('dd MMM yyyy') }}</h2>

<table>
  <tr><td>Sessions</td><td>{{ $('GA4 Fetch').item.json.sessions }}</td></tr>
  <tr><td>New Users</td><td>{{ $('GA4 Fetch').item.json.newUsers }}</td></tr>
  <tr><td>Conversions</td><td>{{ $('GA4 Fetch').item.json.conversions }}</td></tr>
</table>

<hr/>
<h3>AI Summary</h3>
<p>{{ $('AI Node').item.json.text }}</p>
```

Set **To** to a comma-separated list of stakeholder addresses, or pull them from a **Google Sheets** node if your list changes.

---

## Common pitfalls

- **GA4 sampling on large date ranges.** The Data API applies sampling for properties on the free tier with high-cardinality queries. Keep dimensions to 2–3 and use date ranges ≤ 30 days to stay in unsampled territory.
- **Merge node item count mismatch.** If GA4 returns 12 rows and the Ads node returns 5 campaigns, "Merge by Index" will truncate. Use **Append** mode and let the AI node receive all rows, or aggregate both sides first.
- **OAuth token expiry.** n8n auto-refreshes the GA4 token, but if the credential is dormant for more than 6 months Google may revoke it. Add an **Error Trigger** node that sends you a Slack or email alert when the workflow fails — catches this before a Monday report silently skips.

---

## Running this on AgentRoost

This workflow needs to run reliably every Monday whether your laptop is on or not. That means an always-on instance, not a local n8n process you manually restart.

On AgentRoost you get **your own n8n instance** — your login, your data, your workflows — hosted on a public subdomain (`https://<your-id>.agentroost.app`). You own it: self-hosting without the DevOps. The Schedule Trigger fires on time because the instance is always running. Webhook URLs work immediately with no reverse-proxy setup.

The part that usually blocks teams: the AI node requires an OpenAI or Anthropic API key, another billing account, and BYOK configuration. **On AgentRoost that step doesn't exist.** LLM credits are included in the subscription. Drop the AI node, pick your model, write your prompt, and run — no API key, no second billing account.

Getting started takes about two minutes:

1. [Sign up at AgentRoost](/en/agents/n8n) with email, Google, Microsoft, or Discord.
2. Pick the **n8n** framework, name your instance.
3. Your private n8n editor opens at `https://<your-id>.agentroost.app`.
4. Build the workflow above — the AI node already has credits.

Pricing starts at **$19.99/mo all-in** with a 14-day money-back guarantee. [Compare plans](/en/pricing) to see which tier fits your report volume and model preferences.

---

A weekly marketing report that writes itself and lands in inboxes before the team's Monday standup is not a complex automation project — it's eight n8n nodes and one afternoon of setup. The only thing that usually makes it feel harder than it is: the AI writing step requires a separate API account everywhere except here.
