DEV Community

Alex Wu
Alex Wu

Posted on

How We Automated Weekly Client Reports for a Small Marketing Agency (And Saved 6 Hours/Week)

Running a small marketing agency means your Monday morning is usually eaten alive by one thing: report assembly. Pulling numbers from Google Analytics, Facebook Ads, and a spreadsheet, formatting them, writing the summary, sending to 8 clients. Sound familiar?

We helped a 4-person agency automate this entirely. Here's exactly how it works — tools, code, and what we learned.


The Before State

Every Monday, one account manager spent 3–4 hours doing the following:

  1. Log into Google Analytics for each client → export CSV
  2. Log into Facebook Ads Manager → screenshot or export
  3. Copy numbers into a Google Sheet template
  4. Write a 2-paragraph summary ("traffic was up 12%, leads were flat")
  5. Export to PDF, send via email

Eight clients. Same process. Every. Single. Week.

The painful part wasn't the data — it was the formatting and the "summary writing" that felt creative but was actually 90% templated.


The Automation Stack

We built this with three pieces:

  • Google Analytics Data API (GA4) — pulls sessions, conversions, traffic by source
  • Facebook Marketing API — pulls spend, impressions, clicks, CPM
  • OpenAI GPT-4o — writes the summary paragraph given the numbers
  • Resend — sends the final HTML report to each client

Total build time: ~2 days. Total cost per week: ~$0.80 in API calls.


The Core Script (Simplified)

import openai
import resend
from google.analytics.data_v1beta import BetaAnalyticsDataClient

def get_ga4_summary(property_id, start_date, end_date):
    client = BetaAnalyticsDataClient()
    # ... run the report
    return parse_response(response)

def write_summary(client_name, metrics):
    prompt = f"Write a 2-paragraph client update. Client: {client_name}. Metrics: {metrics}"
    response = openai.chat.completions.create(model="gpt-4o", messages=[{"role":"user","content":prompt}])
    return response.choices[0].message.content

def send_report(client_email, client_name, summary, metrics):
    html = build_html_report(client_name, summary, metrics)
    resend.Emails.send({"from": "hello@anythoughts.ai", "to": [client_email], "subject": f"Weekly Report — {client_name}", "html": html})
Enter fullscreen mode Exit fullscreen mode

The build_html_report() function just formats a clean HTML table with key metrics and drops in the AI-written summary.


What Actually Surprised Us

1. GPT-4o writes better summaries than the account manager did.

Not because the AM was bad — but because when you're doing the same task for 8 clients, your writing gets lazy. The AI always starts fresh. Clients actually mentioned the reports felt "more polished."

2. The hardest part was Facebook's API rate limits.

Their Marketing API is slow. We had to add batching logic and a 1-second sleep between client pulls. Expected 20 minutes of runtime, got 35 minutes initially.

3. We added a "human review" step anyway.

The agency wanted to add a custom note before sending — a deal won, a creative test that flopped, something the API couldn't know. We built a simple web form: the script drafts the report, shows a preview, waits for a one-click "approve + send."

That approval step takes 2 minutes per client now instead of 20. The 6 hours became 20 minutes total.


The Lesson

Not every automation should remove humans entirely. Sometimes the goal is to change the quality of human involvement — from "typing the same paragraph for the 8th time" to "reviewing and adding real context."

The agency isn't using AI to cut headcount. They're using it so their account managers can spend time on strategy, client calls, and new business — not reformatting the same CSV every Monday.

That's the automation that actually gets adopted.


We build these kinds of workflows at Anythoughts.ai. If you're doing manual, repetitive reporting work for clients, reach out — we'll scope it in a 20-minute call.

Top comments (0)