Automating YouTube Analytics Reports — Daily Email Pipeline
Build a system that pulls channel metrics nightly via YouTube Data API and turns them into a human-readable daily email — no manual dashboard checking.
A client with a YouTube channel used to spend 15 minutes every morning in YouTube Studio — views, subs, retention, revenue. Often the numbers were forgotten by lunchtime. Now every night at 23:30 they get an email: 'Today's key metrics, what changed vs yesterday, three insights worth noting.' Small system, big time saver.
The layers
- Auth — Google OAuth for YouTube Data + YouTube Analytics APIs
- Data fetcher — cron job pulling daily metrics
- Storage — historical data in Postgres
- AI summary — GPT-4o-mini turns numbers into prose
- Email sender — Resend handles delivery
YouTube API — gotchas to know
Two separate APIs: YouTube Data API (video metadata, comments) and YouTube Analytics API (views, retention, revenue). Same OAuth, different scopes. Different quotas too: Data API 10,000 units/day, Analytics 50,000/day. A typical nightly run uses 50-100 units, plenty of headroom.
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from datetime import date, timedelta
creds = Credentials.from_authorized_user_file("token.json", [
"https://www.googleapis.com/auth/youtube.readonly",
"https://www.googleapis.com/auth/yt-analytics.readonly",
])
analytics = build("youtubeAnalytics", "v2", credentials=creds)
today = date.today() - timedelta(days=1) # son tam gün
response = analytics.reports().query(
ids="channel==MINE",
startDate=str(today),
endDate=str(today),
metrics="views,estimatedMinutesWatched,averageViewDuration,subscribersGained,subscribersLost,estimatedRevenue",
).execute()
metrics = dict(zip(
[h["name"] for h in response["columnHeaders"]],
response["rows"][0],
))AI summary — this is where it gets useful
Raw numbers ('1,234 views, $8.40 revenue') aren't useful. I send the AI the last 7 days plus today, with the prompt: 'Owner of a YouTube channel. Review the data and pull out 3 insights worth noticing. Trend direction, anomalies, and one recommendation. Friendly but factual tone.'
summary_prompt = f"""
Son 7 günün YouTube metric tarixçəsi (JSON):
{last_7_days_json}
Bugünkü metric-lər:
{today_metrics_json}
Tapşırıq: 3 vacib insight yaz. Qısa, konkret, faktiki.
1. Trend (yaxşıya/pisə doğru hansı metric gedir)
2. Qeyri-adi şey (orta göstəricidən fərqli)
3. Bir tövsiyə (nəyə baxmaq lazımdır)
"""
response = openai.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": summary_prompt}],
max_tokens=400,
)
insights = response.choices[0].message.contentEmail format — the HTML template
Simple but effective layout: 5 key metrics at the top (views, watch time, net subs, revenue, retention), each showing yesterday-vs-today delta in green/red. Then the AI's 3 insights. Then the top-viewed video with a link. Plain HTML, no external CSS, renders fine in every email client.
Schedule and monitoring
Cron on Hetzner: 30 23 * * * /usr/bin/python3 /home/deploy/youtube-report/main.py. Sends a health-check ping at end of a successful run. If no ping arrives within 24 hours, Healthchecks.io alerts me. This simple setup has run for 8 months, failed once (OAuth token expired and the refresh logic threw on a quota error).
This pattern works for other platforms too
- Instagram — Graph API, same structure
- TikTok — TikTok Business API (pricey)
- Twitter/X — basic tweet metrics
- Google Analytics — email summary instead of Looker Studio
- Stripe — daily sales digest
AI insights are 90% accurate, 10% hallucinated — sometimes it says 'views are up 50%' when they're up 5%. I parse the AI response, extract numeric claims, and verify against the real data. If they don't match, the AI section gets dropped from the email.
Need help on a project?
If something in this post hits close to a project you're working on, let's hop on a 30-minute call — I'll come back with concrete advice.