GA4 Traffic Report — AI Workflow Plan | Diaphora
GA4 Traffic Report
Pull GA4 acquisition, engagement, and cohort-retention data through an API connection point and turn it into chart-ready, day-by-day structured insights.
Best for
- Marketing
- Growth
- Founders
Runs with
- Google Analytics 4
- Acquisition
- Retention cohorts
At a glance
Outputs
- Acquisition insights
- Engagement insights
- Retention cohorts
- Chart-ready rows
Capability requirements
- API CP
What it solves
Clicking through GA4 every week, hand-copying numbers into a deck. Instead of a typed dataset.
- A repeatable blueprint. Not a weekly manual export.
- Raw numeric values preserved — charts you can actually trust.
- Chart-ready rows, dropped straight into a report.
Workflow
- Fetch acquisition, engagement, and cohort-retention reports from GA4.
- Aggregate each into per-day chart rows with exact numeric values.
- Return structured summaries and trends for acquisition, engagement, retention.
Implementation
Review the underlying FML blueprint — the sessions, tools, and typed schemas that define this workflow — and see exactly how it is instructed for repeatable execution.
FML Blueprint
google-analytics.fml
system(`You are an expert data analyst. Review the provided Google Analytics 4 data and generate clear, insightful, structured reports for the end user. When extracting rows for chart data, preserve raw numeric values verbatim — never round or invent figures.
`)
parameter("property", type=string, default="484780505") # A Google Analytics GA4 property identifier (numeric ID only, e.g. 484780505).
require apicp google_analytics
call("google_analytics_runReport") -> acquisitionData {
property = "{{ .params.property }}"
body = {dateRanges: [{startDate: "7daysAgo", endDate: "today"}], dimensions: [{name: "date"}, {name: "firstUserDefaultChannelGroup"}], metrics: [{name: "newUsers"}, {name: "sessions"}, {name: "totalUsers"}], orderBys: [{dimension: {dimensionName: "date"}}]}
}
call("google_analytics_runReport") -> engagementData {
property = "{{ .params.property }}"
body = {dateRanges: [{startDate: "7daysAgo", endDate: "today"}], dimensions: [{name: "date"}, {name: "sessionDefaultChannelGroup"}], metrics: [{name: "engagedSessions"}, {name: "engagementRate"}, {name: "averageSessionDuration"}, {name: "screenPageViews"}], orderBys: [{dimension: {dimensionName: "date"}}]}
}
# Retention uses a `code:` block instead of declarative args because GA4
# cohortSpec requires absolute YYYY-MM-DD dates (relative "7daysAgo"
# strings are rejected). Diaphora's `{{ .params.X }}` substitution only
# works on top-level args, not deeply-nested body fields, so the dates are
# computed in JS at runtime here and passed to the apicp tool with a fully
# resolved body.
call("ga_runReport_retention") -> retentionData {
property = "{{ .params.property }}"
code( const today = new Date();
const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(today.getDate() - 7);
const fmt = (d) => d.toISOString().slice(0, 10);
runFunction("google_analytics_runReport", {
property: args.property,
body: {
cohortSpec: {
cohorts: [{
name: "last_7_days",
dimension: "firstSessionDate",
dateRange: {
startDate: fmt(sevenDaysAgo),
endDate: fmt(today),
},
}],
cohortsRange: { granularity: "DAILY", endOffset: 6 },
},
dimensions: [{ name: "cohort" }, { name: "cohortNthDay" }],
metrics: [
{ name: "cohortActiveUsers" },
{ name: "cohortTotalUsers" },
],
orderBys: [{ dimension: { dimensionName: "cohortNthDay" } }],
},
}); )
}
session("analyze_acquisition", target="acquisition") {
- Analyze the following Google Analytics User Acquisition data (last 7 days, broken down by date AND channel) and extract structured insights.
For `summary` and `keyChannels`: identify the top performing acquisition channels across the entire week (aggregate newUsers across days).
For `data` (chart-ready rows): emit ONE row per day, in chronological order. `label` = a short date like "Nov 19" derived from the `date` dimension (GA returns YYYYMMDD strings — convert to "MMM D"). `value` = the SUM of `newUsers` across ALL channels for that day (integer). `detail` = the top channel that day plus its share, e.g. "Direct led with 58 (62%)".
Data: {{ .vars.acquisitionData }}
schema {
summary: string # Executive summary of acquisition performance.
keyChannels: string[] # Top performing acquisition channels based on new users and sessions.
data: {
label: string # Channel name (e.g. "Organic Search", "Direct", "Referral").
value: int # New users for this channel (integer, taken directly from the report).
detail?: string # Secondary metrics for this channel (e.g. sessions, total users).
}[]
}
}
session("analyze_engagement", target="engagement") {
- Analyze the following Google Analytics Engagement data (last 7 days, broken down by date AND channel) and extract structured insights.
For `summary` and `topChannels`: identify the top channels driving engaged sessions across the entire week.
For `data` (chart-ready rows): emit ONE row per day, in chronological order. `label` = a short date like "Nov 19" (convert YYYYMMDD → "MMM D"). `value` = the SUM of `engagedSessions` across ALL channels for that day (integer). `detail` = an engagement-rate hint for that day, e.g. "engagement rate ~64.2% · avg session 1m 42s".
Data: {{ .vars.engagementData }}
schema {
summary: string # Analysis of engagement metrics.
topChannels: string[] # Channels driving the most engaged sessions.
data: {
label: string # Channel name.
value: int # Engaged sessions for this channel (integer, taken directly from the report).
detail?: string # Engagement rate, average session duration, and pageviews for this channel.
}[]
}
}
session("analyze_retention", target="retention") {
- Analyze the following Google Analytics Retention/Cohort data (last 7 days) and extract structured insights AND chart-ready rows. For each cohortNthDay bucket, emit a `data` row with `label` = "Day N" (e.g. "Day 0", "Day 1") and `value` = the raw `cohortActiveUsers` count (integer). Put a short detail like "of 3,201 cohort users · 24.1% retained" in `detail`. Data: {{ .vars.retentionData }}
schema {
summary: string # Summary of user retention over the 7 day cohort.
retentionTrend: string # Trend analysis of retention.
data: {
value: int # Active users in this cohort day (integer).
detail?: string # Cohort size and retention percentage.
label: string # Cohort day label (e.g. "Day 0", "Day 1").
}[]
}
}