The gist
The theory is over; now we build. This lesson walks you step by step through creating a real newsletter automation: from an empty folder to a working system that finds news, writes the email and sends it. We do it live, not on slides.
Key concepts
- Plan Mode for starting from a fuzzy request
- Choosing the stack through a conversation with the agent (an agent is an autonomous AI worker)
- Brand assets as context for the agent (context is the text the AI "sees" at the moment)
- The five tools of a newsletter automation
- Setting up .env with API keys (API: application programming interface)
- A human review point: when the agent must stop
- The launch and your first real send
Theory
Why newsletter automation is the perfect first project
Newsletter automation is a great first project because:
- Clear business value: every business understands why it's useful
- All the WAT components: there's a workflow (a work process), there are tools, the agent coordinates
- A human review point: it's obvious where a person needs to check things before sending
- A real result: by the end of the lesson you'll see a real email in your inbox
- Room to grow: this workflow can be packaged as a ready product or service, but results depend on your niche and your work
The stack we'll choose (and why)
In real work, you explain the task to the agent and it proposes a stack. We'll go through that process. But here's where we'll end up:
| Component | Tool | Why |
|---|---|---|
| News search | Perplexity API | Search with real links and up-to-date data |
| Writing the text | Anthropic Claude API | High-quality writing in English |
| Infographic | Nano Banana (Google's image model, Gemini API) | Image generation from a prompt |
| Sending | Gmail API | Simple integration, free within Google's daily limits (check the Gmail docs for current limits) |
| Archive | Google Sheets | Send log, easy to analyze |
Why Perplexity and not just Google?
Perplexity returns structured data with real links and fresh sources. Regular search through scraping is unreliable: Google blocks it, and its API is expensive. The Perplexity API gives you clean JSON (a data format) with sources.
Why Gmail and not SendGrid?
For a first project Gmail is simpler: you don't need to verify a domain, and you can start in 10 minutes. Dedicated email services (SendGrid, for example) are better for industrial-scale sends to thousands of people.
Step 1: Plan Mode, starting from a fuzzy request
Open Claude Code in a new empty folder called newsletter-automation.
Write this first request:
I want to build an automatic weekly news email about [your topic] for clients. Before you start, ask me clarifying questions, put together a plan, then show me the WAT structure you're going to create.
The agent will ask questions like:
- "Where should the news come from: specific sites or a general search?"
- "How is the recipient list stored?"
- "Do you need an infographic in the email?"
- "What language should the email be in?"
- "Do you need to approve each send?"
Answer honestly. In the end the agent will put together a plan. You sign off on it, and the building begins.
Step 2: Loading brand assets
Before the agent starts generating content, give it brand context.
Create a folder /brand_assets/ and put in it:
logo.png: your logo (or download any placeholder)brand_guidelines.md: a description of the brand
Sample brand_guidelines.md:
# Brand Guidelines ## Tone of Voice - Professional but approachable - No grandstanding - Specifics matter more than pretty words - Short sentences ## Colors - Primary: #1A56DB (blue) - Secondary: #F3F4F6 (light gray) - Accent: #10B981 (green for positive news) ## Typography - Headings: bold, large - Body: 16px, line height 1.6 ## What NOT to write - No "revolutionary" or "unique" - Don't start with "In an era of..." - Don't use the word "innovative"
After loading the assets, tell the agent:
I've added a logo and brand guidelines to /brand_assets/. Use these materials when generating content and laying out the email. Reference the files as @brand_assets/logo.png and @brand_assets/brand_guidelines.md.
Step 3: The agent creates five tools
The agent will write all the tools itself based on the plan. Here's what you'll get:
Tool 1: tools/research_news.py
Calls the Perplexity API with a given query and returns a list of 5–7 news items in the format [{title, description, url, date, source}].
Tool 2: tools/generate_infographic.py
Takes the news list, builds a prompt (a request to the AI) for an image generation API, and returns a URL or a base64 image. Nano Banana (via the Gemini API) takes a text request and returns an image.
Tool 3: tools/assemble_html.py
Takes the news + the infographic + the brand guidelines, calls the Claude API, and generates a finished HTML email template. It inserts the logo and applies the colors from the brand guidelines.
Tool 4: tools/send_via_gmail.py
Takes the HTML, the recipient list and the subject line. Uses the Gmail API through OAuth 2.0. Sends the email to each recipient.
Tool 5: tools/archive_to_sheets.py
Writes a row to Google Sheets: send date, number of recipients, subject line, status. Builds a log for analysis.
Step 4: Configuration files
The agent will create two config files:
config/newsletter_style.json
{
"font_family": "system-ui, -apple-system, sans-serif",
"font_size_body": "16px",
"line_height": "1.6",
"colors": {
"primary": "#1A56DB",
"background": "#F3F4F6",
"accent": "#10B981",
"text": "#111827"
},
"max_width": "600px",
"news_count": 5
}config/recipients.json
{
"test": ["your-email@gmail.com"],
"production": [
"client1@email.com",
"client2@email.com"
]
}Start with test: send to yourself. Once everything is set up, add real recipients to production.
Step 5: Setting up .env with API keys
The agent will create a .env.example template:
# Anthropic API (platform.claude.com → API Keys)
ANTHROPIC_API_KEY=your_key_here
# Perplexity API (perplexity.ai → API)
PERPLEXITY_API_KEY=your_key_here
# Gmail API (Google Cloud Console → Credentials)
GMAIL_CLIENT_ID=your_client_id
GMAIL_CLIENT_SECRET=your_client_secret
GMAIL_REFRESH_TOKEN=your_refresh_token
# Google Sheets (same Google Cloud project)
GOOGLE_SHEETS_ID=your_spreadsheet_id
# Gemini API for image generation with Nano Banana (optional)
GEMINI_API_KEY=your_key_hereHow to get the keys:
- Anthropic API: go to the Console (platform.claude.com) → API Keys → Create Key
- Perplexity API: go to perplexity.ai → Settings → API → Generate
- Gmail API: the hardest one. Google Cloud Console → New Project → Enable Gmail API → Credentials → OAuth 2.0 Client ID → download the JSON → use
google-auth-oauthlibto get a refresh token - Google Sheets API: the same Google Cloud project → Enable Sheets API → you can use the same OAuth
Copy .env.example to .env and fill in the real keys. Make sure .env is listed in .gitignore.
Step 6: The human review point, where the agent stops
This is a critical part of the workflow. Before sending emails, the agent must stop and show you a preview.
In the workflow it looks like an explicit instruction:
### Step 3: ⚠️ MANDATORY HUMAN REVIEW STOP. Do not continue automatically. Show me: 1. An HTML preview of the email 2. The recipient list (which mode: test or production) 3. The subject line 4. The number of news items and their headlines Wait for explicit confirmation: "Send it" or "OK send" or "go" If you get "stop" or "wait", don't send; wait for instructions.
Why this matters: the agent might have generated a news item with a factual error. Or picked an unsuitable topic. Or someone extra ended up on the recipient list. You check once, and then the system runs on its own with periodic spot checks.
A real prompt example for newsletter automation
Here's a complete prompt you can use as a template for your own niche:
Build a weekly newsletter automation for a real estate agency. What the system should do: 1. Every Monday at 10:00 AM, find 5-7 fresh news items for the query "Austin real estate market 2026" through the Perplexity API 2. Based on the news found, generate an HTML email in the style of the brand guidelines in /brand_assets/ 3. Add a "Listing of the week" section with a placeholder to fill in by hand 4. STOP and show me a preview before sending 5. After my "ok", send through the Gmail API to the list in config/recipients.json 6. Write a send log to Google Sheets Important: - Email tone: professional, no grandstanding, concrete numbers - Language: English - Maximum 800 words for the whole newsletter - Always include links to the news sources
Step 7: Launch, "Write me a newsletter about agentic AI"
After all the setup, write to the agent:
Run the newsletter workflow. This week's topic: agentic AI for small business. Use the test recipient list.
The agent will:
- Call
research_newswith your topic - Show the news it found (you can remove some)
- Call
generate_infographic - Call
assemble_html - Stop and show the preview
- After your "Send it", call
send_via_gmail - Call
archive_to_sheets
In about 3–5 minutes there will be a real email in your inbox.
Practice
Exercise: Build a newsletter automation from scratch to the first send.
Step 1, Preparation (15 min):
- Create a folder called
newsletter-automation - Open it in VS Code with Claude Code
- Create
brand_assets/brand_guidelines.mdfor your topic - Create a
.gitignorecontaining.envandlogs/
Step 2, Plan Mode (10 min):
- Write the Plan Mode request (the text from Step 1 of the theory)
- Answer the agent's questions
- Sign off on the plan
Step 3, Building (25 min):
- Give the agent the go-ahead: "Start building according to the plan"
- Watch it create the structure, the workflow, the tools
- Answer clarifying questions now and then if the agent stops
Step 4, API keys (15 min):
- Fill in
.env(at minimum: ANTHROPIC_API_KEY and one email service) - If you don't have Perplexity, use the Anthropic API with WebSearch or just test data
Step 5, First run (10 min):
- Run the test workflow to your own email
- Check the email in your inbox
- Take a screenshot: this is your first agentic product
Tools and resources
- Claude Code in VS Code: the main tool
- Anthropic Console: creating and managing API keys
- Perplexity API: get a key at perplexity.ai/settings
- Google Cloud Console: Gmail and Sheets APIs (free tier)
- Resend: an alternative to the Gmail API for sending email (simpler setup; the service has a free tier)
- SendGrid: industrial-scale email; check the site for free-access terms
- Mailgun: another alternative email API
- trigger.dev: deploying (publishing to a server) workflows to production on a schedule
- Nano Banana (Gemini): infographic generation through the Gemini API
- Claude Code: commands: reference for built-in commands
Common mistakes
Mistake 1: Launching without .gitignore
You created a project, set up .env with keys, ran git add ., and the keys leaked into the repo. Always create .gitignore BEFORE the first commit.
Mistake 2: Skipping the human review point
You wrote "send automatically" in the workflow, and the agent sent an unchecked email with a factual error to every client. For the first 10–20 runs, always check by hand before sending.
Mistake 3: An initial prompt that's too general
"Make me a newsletter," with no details about topic, audience, language or style. The more specific the initial prompt, the fewer rounds of revision later. Use Plan Mode so the agent asks the right questions.
Cross-references
- The WAT framework: the Workflow-Agent-Tools architecture this workflow is built on
- Debugging and self-repair: what to do when the first run breaks (and it will)
- API keys and .env: details on setting up
.envsafely and storing secrets - Deploying to Cloudflare: how to deploy this workflow to production on Cloudflare Workers
Key takeaways
Plan Mode lets you start from a fuzzy idea: the agent asks the right questions itself and puts together a plan.
Brand assets + brand guidelines give the agent context for creating content in the right style.
A human review point is a mandatory stop before any irreversible action (sending, publishing, payment).
At the end you don't just have files: you have a working system that can be packaged into a service or product.
Next lesson
→ Debugging and self-repair: what to do when the first run breaks
The mark stays in this browser only and is never sent anywhere. My progress