On a schedule
Log daily GA4 traffic by source to Google Sheets
Each morning yesterday's GA4 sessions, users and key events per source / medium are appended to a Traffic tab.
- Runs
- On a schedule
- Apps
- Google Analytics, Google Sheets
- AI
- Not needed
- Access
- analytics.readonly; Google Sheets read+write
Send this to your assistant
Create a ClickRuntime automation: every morning at 6:30, add yesterday's GA4 sessions, users, engaged sessions and key events by source / medium to the Traffic tab of my sheet, one row per source.
First time? Adding ClickRuntime to your assistant takes about two minutes.
Why use it
Why teams use this automation
GA4 answers questions inside its own interface, but most teams want daily traffic by channel next to their spend, sales or leads in a spreadsheet. The old Sheets add-on for Universal Analytics no longer works with GA4.
This automation adds a block of rows every morning: one per source / medium, with sessions, users, engaged sessions and key events for the previous day.
Marketers, founders and agencies use it to build channel reports and compare traffic with results from other tools.
What you get out of it
Channel trends over time
A daily row per source makes it easy to chart organic, paid and email traffic side by side.
Joins with your other data
Put ad spend or sales in the next tab and work out cost per session or conversion per channel.
No sampling or exports
The GA4 Data API returns the numbers directly, without manual downloads.
Stable numbers
Logging the previous day avoids partial same-day data.
Easy to change the split
Swap the dimension for campaign or landing page in one line.
How it works
What happens, step by step
Every morning ClickRuntime runs a GA4 report for the previous day.
The report is split by source / medium, such as google / organic or newsletter / email.
One row per source is added to the Traffic tab with the date, sessions, users, engaged sessions and key events.
Before it runs live
- Connect Google Analytics
- Connect your Google Sheets account and pick the spreadsheets it may use
What you get
Build your own
Need it to work differently?
Your own rules
Conditions, thresholds, filters and exceptions, written the way you'd explain them to a colleague.
Any number of apps
One automation can read from one app and update several others. Over 248 apps are ready, and anything with an API works too.
AI where it helps
Summaries, classification, extraction and drafts use ClickRuntime's built-in AI, with no extra key.
On a schedule or on each event
Runs as often as every 5 minutes, or the moment an app sends an event, and keeps track of what it already handled.
Changes you can ask for
- Run it at a different time, more or less often, or only on weekdays
- Add an AI step, for example to summarize, sort or draft a reply
- Add another app, for example also send it to Slack
- Combine it with other Google Analytics and Google Sheets steps into one automation
Under the hood
The code that runs this automation
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from datetime import date, timedelta
from clickruntime import on_trigger, credentials, http
PROPERTY = "123456789"
SHEET_ID = "your-spreadsheet-id"
METRICS = ["sessions", "totalUsers", "engagedSessions", "keyEvents"]
def ga(body):
r = http.post(f"https://analyticsdata.googleapis.com/v1beta/properties/{PROPERTY}:runReport", json=body,
headers={"Authorization": f"Bearer {credentials.connection('google', 'work')}"})
r.raise_for_status()
return r.json().get("rows", [])
@on_trigger
def run(event):
day = (date.today() - timedelta(days=1)).isoformat()
rows = ga({"dateRanges": [{"startDate": day, "endDate": day}], "dimensions": [{"name": "sessionSourceMedium"}],
"metrics": [{"name": m} for m in METRICS], "orderBys": [{"metric": {"metricName": "sessions"}, "desc": True}],
"limit": 100})
values = [[day, r["dimensionValues"][0]["value"]] + [round(float(v["value"]), 2) for v in r["metricValues"]] for r in rows]
if values:
build("sheets", "v4", credentials=Credentials(credentials.connection("google", "work")), cache_discovery=False) \
.spreadsheets().values().append(spreadsheetId=SHEET_ID, range="Traffic!A:F", valueInputOption="RAW",
body={"values": values}).execute()
return {"date": day, "sources": len(values)}FAQ
Common questions
Why log yesterday rather than today?
What are key events?
Can I split by campaign or landing page instead?
What permissions does it need?
Does it need AI?
How many runs does it use?
Can I change how it works?
Related
You might also like
Weekly GA4 top pages report in Google Sheets
Every Monday a new tab lists last week's top 50 pages by views, with users, engagement time and change against the week before.
See how it worksLog your weekly website numbers to a sheet
Every week your key GA4 numbers are added as a row in your reporting sheet, and you get an email summarising what changed.
See how it worksLog daily website KPIs and get alerted when one drops
Every day yesterday's key numbers go into a sheet, and you are alerted in Slack and by email if any falls well below its recent average.
See how it worksKeep exploring
Set up “Log daily GA4 traffic by source to Google Sheets” from your assistant
Copy the prompt above, or connect your assistant first. Free plan, no credit card.