Guide: Automated Newsletter Assembly
Step-by-step guide to building an automated newsletter assembly pipeline. Pull content, draft missing sections with AI, assemble, preview, and distribute.
This guide walks through building a complete automated newsletter assembly pipeline that runs on a schedule.
Overview
The pipeline runs weekly (or on your cadence) and:
- Collects ready content blocks
- Checks upcoming events
- Drafts any missing standard sections with AI
- Creates a newsletter and assembles blocks
- Sends a preview for approval
Step 1: Collect available content
# Get all ready content blocks
curl -s "$BASE_URL/content_blocks?status=ready&per_page=50" \\
-H "Authorization: Bearer $API_KEY"
# Get events for the coming week
curl -s "$BASE_URL/events?upcoming=true&days_ahead=7" \\
-H "Authorization: Bearer $API_KEY"
Step 2: Draft missing sections
Check what block types are covered. If there's no ceo_update, draft one:
curl -s "$BASE_URL/content_blocks/ai_draft" \\
-X POST \\
-H "Authorization: Bearer $API_KEY" \\
-H "Content-Type: application/json" \\
-d '{"context": "Write a brief CEO update for the weekly newsletter. Mention the team hitting Q1 targets and the upcoming company offsite."}'
If there are events without content blocks, draft those too:
curl -s "$BASE_URL/content_blocks/ai_draft" \\
-X POST \\
-H "Authorization: Bearer $API_KEY" \\
-H "Content-Type: application/json" \\
-d '{"context": "Write an event announcement for Mental Health Awareness Week starting May 18. Include links to the EAP and suggest mindfulness resources."}'
Step 3: Create and assemble the newsletter
# Create the newsletter
NEWSLETTER=$(curl -s "$BASE_URL/newsletters" \\
-X POST \\
-H "Authorization: Bearer $API_KEY" \\
-H "Content-Type: application/json" \\
-d "{
\\"title\\": \\"Weekly Update — $(date +%B\\ %d)\\",
\\"subject_line\\": \\"Your weekly update is here\\",
\\"template_slug\\": \\"clean\\",
\\"scheduled_date\\": \\"$(date +%Y-%m-%d)\\"
}")
NEWSLETTER_ID=$(echo $NEWSLETTER | jq -r '.newsletter.id')
# Add blocks in order: CEO update first, then ready blocks, then events
for BLOCK_ID in $CEO_BLOCK $READY_BLOCKS $EVENT_BLOCKS; do
curl -s "$BASE_URL/newsletters/$NEWSLETTER_ID/blocks" \\
-X POST \\
-H "Authorization: Bearer $API_KEY" \\
-H "Content-Type: application/json" \\
-d "{\\"content_block_id\\": \\"$BLOCK_ID\\"}"
done
Step 4: Send preview
curl -s "$BASE_URL/newsletters/$NEWSLETTER_ID/send_preview" \\
-X POST \\
-H "Authorization: Bearer $API_KEY" \\
-H "Content-Type: application/json" \\
-d '{"email": "comms-lead@company.com"}'
Running on a schedule
Use cron, GitHub Actions, or any scheduler:
# .github/workflows/newsletter.yml
name: Assemble weekly newsletter
on:
schedule:
- cron: '0 8 * * 1' # Every Monday at 8am
jobs:
assemble:
runs-on: ubuntu-latest
steps:
- run: ./scripts/assemble-newsletter.sh
env:
API_KEY: ${{ secrets.NEWSLETTER_API_KEY }}
BASE_URL: https://your-app.com/api/v1
With MCP (simpler)
If you're using Claude with the MCP server, the entire pipeline is a single prompt:
"Check what content we have ready, look at upcoming events, draft a CEO update about Q1 results, assemble a newsletter using the Clean template, and send a preview to me."
See MCP Server docs for setup.