How to Create Automated Content Performance Reports
Track and report on content performance metrics automatically.
Jay Banlasan
The AI Systems Guy
I stopped manually pulling content metrics when I realized I was spending three hours a week on a report nobody acted on. This automated content performance report analytics system pulls data from Google Analytics, runs it through Claude for interpretation, and emails a plain-English summary every Monday morning. The report tells you what is working, what is dying, and what to do next week.
The difference between a good content team and a great one is not the volume of content they publish. It is whether they know what is working and double down on it fast. This report makes that loop run on autopilot.
What You Need Before Starting
- Python 3.10 or higher
- Google Analytics 4 property with API access enabled
- Google service account JSON credentials
- Anthropic API key
pip install anthropic google-analytics-data python-dotenv
Step 1: Set Up Google Analytics API Access
First, enable the Google Analytics Data API in your Google Cloud Console. Then download your service account key and store the path in your .env:
ANTHROPIC_API_KEY=your_key_here
GA4_PROPERTY_ID=123456789
GOOGLE_CREDENTIALS_PATH=C:/path/to/service-account.json
[email protected]
Then initialize the GA4 client:
import os
from google.analytics.data_v1beta import BetaAnalyticsDataClient
from google.analytics.data_v1beta.types import (
RunReportRequest, DateRange, Dimension, Metric, OrderBy
)
from google.oauth2 import service_account
from dotenv import load_dotenv
load_dotenv()
def get_ga4_client():
credentials = service_account.Credentials.from_service_account_file(
os.getenv("GOOGLE_CREDENTIALS_PATH"),
scopes=["https://www.googleapis.com/auth/analytics.readonly"]
)
return BetaAnalyticsDataClient(credentials=credentials)
Step 2: Pull Top Content Performance Data
def get_top_content(client, property_id: str, days: int = 30) -> list:
request = RunReportRequest(
property=f"properties/{property_id}",
date_ranges=[DateRange(start_date=f"{days}daysAgo", end_date="today")],
dimensions=[
Dimension(name="pagePath"),
Dimension(name="pageTitle")
],
metrics=[
Metric(name="screenPageViews"),
Metric(name="averageSessionDuration"),
Metric(name="bounceRate"),
Metric(name="newUsers")
],
order_bys=[
OrderBy(metric=OrderBy.MetricOrderBy(metric_name="screenPageViews"), desc=True)
],
limit=20
)
response = client.run_report(request)
results = []
for row in response.rows:
results.append({
"path": row.dimension_values[0].value,
"title": row.dimension_values[1].value,
"pageviews": int(row.metric_values[0].value),
"avg_duration_sec": float(row.metric_values[1].value),
"bounce_rate": float(row.metric_values[2].value),
"new_users": int(row.metric_values[3].value)
})
return results
Step 3: Get Traffic Trend Data
You need week-over-week comparison to spot momentum:
def get_traffic_trend(client, property_id: str) -> dict:
def fetch_period(start, end):
request = RunReportRequest(
property=f"properties/{property_id}",
date_ranges=[DateRange(start_date=start, end_date=end)],
metrics=[
Metric(name="screenPageViews"),
Metric(name="newUsers"),
Metric(name="sessions")
]
)
response = client.run_report(request)
row = response.rows[0]
return {
"pageviews": int(row.metric_values[0].value),
"new_users": int(row.metric_values[1].value),
"sessions": int(row.metric_values[2].value)
}
this_week = fetch_period("7daysAgo", "today")
last_week = fetch_period("14daysAgo", "8daysAgo")
def pct_change(current, previous):
if previous == 0:
return 0
return round(((current - previous) / previous) * 100, 1)
return {
"this_week": this_week,
"last_week": last_week,
"pageviews_change": pct_change(this_week["pageviews"], last_week["pageviews"]),
"new_users_change": pct_change(this_week["new_users"], last_week["new_users"]),
"sessions_change": pct_change(this_week["sessions"], last_week["sessions"])
}
Step 4: Generate AI Interpretation
Raw numbers are not a report. This is where Claude turns the data into decisions:
import anthropic
import json
ai_client = anthropic.Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
def generate_insights(top_content: list, trend: dict) -> str:
top_5 = top_content[:5]
content_summary = json.dumps(top_5, indent=2)
prompt = f"""You are a content analytics expert. Analyze this data and write a concise performance report.
WEEKLY TRAFFIC TREND:
- Pageviews this week: {trend['this_week']['pageviews']} ({trend['pageviews_change']:+}% vs last week)
- New users this week: {trend['this_week']['new_users']} ({trend['new_users_change']:+}% vs last week)
- Sessions this week: {trend['this_week']['sessions']} ({trend['sessions_change']:+}% vs last week)
TOP 5 CONTENT PIECES (last 30 days):
{content_summary}
Write a report with these sections:
## This Week's Summary
[2-3 sentences. Overall health. Is traffic growing or declining? What is the trend saying?]
## Top Performers
[List top 3 pieces with one insight about WHY each is likely performing well based on the metrics]
## Warning Signs
[Any pieces with high pageviews but high bounce rate or low session duration that need work]
## Action Items for Next Week
[3 specific, actionable recommendations based on the data. Not generic advice.]
Keep it short. Executives read this. No fluff."""
message = ai_client.messages.create(
model="claude-opus-4-5",
max_tokens=1000,
messages=[{"role": "user", "content": prompt}]
)
return message.content[0].text
Step 5: Send the Report by Email
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from datetime import datetime
def send_report(report_text: str):
sender = os.getenv("GMAIL_ADDRESS")
password = os.getenv("GMAIL_APP_PASSWORD")
recipient = os.getenv("REPORT_EMAIL")
today = datetime.now().strftime("%B %d, %Y")
msg = MIMEMultipart("alternative")
msg["Subject"] = f"Content Performance Report - Week of {today}"
msg["From"] = sender
msg["To"] = recipient
msg.attach(MIMEText(report_text, "plain"))
with smtplib.SMTP("smtp.gmail.com", 587) as server:
server.starttls()
server.login(sender, password)
server.sendmail(sender, recipient, msg.as_string())
print(f"Report sent to {recipient}")
if __name__ == "__main__":
ga_client = get_ga4_client()
property_id = os.getenv("GA4_PROPERTY_ID")
top_content = get_top_content(ga_client, property_id, days=30)
trend = get_traffic_trend(ga_client, property_id)
report = generate_insights(top_content, trend)
print(report)
send_report(report)
What to Build Next
- Schedule this with cron to run every Monday at 8am so the report lands before the team starts work
- Add conversion tracking from your CRM to show which content pieces actually generate leads, not just traffic
- Build a content decay detector that flags articles whose traffic dropped more than 20% month over month
Related Reading
- How to Build an AI Blog Post Generator - Use performance data to brief better articles
- How to Build an AI Product Description Generator - Apply analytics tracking to product page performance
- How to Create an AI-Powered FAQ Generator - Track which FAQ pages drive the most organic traffic
Want this system built for your business?
Get a free assessment. We will map every system your business needs and show you the ROI.
Get Your Free Assessment