I haven't manually published an article in weeks.
This is the stack that does it for me — with real costs, real output numbers, and honest revenue figures.
The Problem I Was Solving
Writing and publishing technical content takes time. If you're consistent, it can build an audience. But "consistent" means showing up every day, and most people — including me — can't do that manually long-term.
So I automated it.
The goal: a system that writes, validates, publishes, and distributes technical Python articles daily, without me touching it. The output feeds an audience. The audience (eventually) buys a product.
The Stack
Claude API (claude-opus-4-5)
→ Generates article drafts from topic definitions
→ ~$0.40 per article at current usage
Dev.to API
→ Publishes articles (free)
→ 46 articles live, 496 total views
Hashnode API
→ Cross-posts with canonical URL (free)
→ 69 articles live (some pre-queue)
→ Dev.to keeps SEO credit
Imgur API (anonymous upload)
→ Cover images generated with Pillow → uploaded (free)
→ 42 covers in the map
launchd (macOS)
→ Fires publish job at 19:00 daily
→ Fires on wake if Mac was sleeping
→ Cost: $0
Gumroad
→ Product listing ($9.99)
→ 10% transaction fee
→ ~$18 per sale
Total monthly cost: ~$12-20 (Claude API, depending on generation volume)
What the Pipeline Actually Does
Every day at 7pm, this runs:
# auto_publish_queue.py — simplified
def cmd_publish_next():
q = load_queue()
item = q['pending'][0]
# 1. Publish to Dev.to
result = publish_article(item['filename'])
url = f"https://dev.to{result['path']}"
# 2. Add UTM tracking to Gumroad links
add_utm_tracking(result['id'], url)
# 3. Cross-post to Hashnode (canonical URL = Dev.to)
crosspost(url, item['filename'])
# 4. Attach cover image from cover_map.json
attach_cover(result['id'], item['filename'])
# 5. Fix stale links in older articles
patch_stale_links(url, item['filename'])
# 6. Update queue state
q['pending'].pop(0)
q['published'].append({...})
save_queue(q)
# 7. Check queue depth — auto-generate if < 7 articles
if len(q['pending']) < 7:
auto_extend_queue() # Uses Claude API
Seven steps, fully automatic, every day.
The Real Numbers (After 3 Months)
| Metric | Value |
|---|---|
| Articles published | 48 |
| Total views | 496 |
| Avg views/article | 10.3 |
| Reactions | 3 |
| Hashnode articles | 69 |
| API cost (total) | ~$35 |
| Sales | 0 |
| Time spent daily | ~0 min |
The honest number: zero sales after three months. The pipeline is working. The conversion isn't there yet.
Why: The content attracts Python beginners (high volume, low purchase intent). The product is for developers who want to automate publishing pipelines (lower volume, higher intent). Fixing that audience mismatch is the current work.
The fix: add buyer-intent articles every 3-4 tutorials. Show developers how the pipeline works, not just how Python works.
The Content Strategy Shift
Original queue (100% tutorial):
1. Python argparse
2. Python pathlib
3. Python logging
...46 more beginner tutorials
Current queue (mixed):
1. Python decorators (tutorial → SEO)
2. Python error handling (tutorial → SEO)
3. Python os module (tutorial → SEO)
4. Passive Income for Python Devs ← buyer-intent
5. Python sets (tutorial → SEO)
...
7. Python Scripts → Side Income ← buyer-intent
The tutorials build search traffic. The buyer-intent articles convert. Both are needed.
Auto-Generation When Queue Runs Low
The newest addition: when the queue drops below 7 articles, the system auto-generates new ones using Claude:
# auto_extend_queue.py
def run():
q = load_queue()
if len(q['pending']) >= MIN_QUEUE_SIZE:
return # Queue healthy, nothing to do
topics = get_next_topics(q, BATCH_SIZE)
for topic in topics:
body = generate_article(topic) # Claude API call
filename = filename_from_title(topic['title'])
with open(filename, 'w') as f:
f.write(body + GUMROAD_CTA)
q['pending'].append({"filename": filename, "title": topic['title']})
save_queue(q)
The queue now self-heals. It never runs empty.
What I'd Do Differently
Start with buyer-intent content. The first 20 articles were about the pipeline itself. They got better views and probably attract more buyers than the beginner tutorials. I should have done more of those from the start.
Add UTM tracking from day one. I added it on article 46. I have no idea which of the first 45 articles has driven traffic to Gumroad.
Use launchd from the start. I used cron for weeks. It skipped jobs when the Mac was sleeping. Switched to launchd — it fires missed jobs on wake. No lost days.
Price higher. $9.99 for a complete automation pipeline might be under-priced. Testing $29.99 next.
The Compounding Effect
Here's what the view graph looks like after 3 months of daily publishing:
Month 1: 350 views from 25 articles (April)
Month 2: 146 views from 23 articles (May, still accumulating)
Month 3: (publishing now)
Each article is a permanent asset. The April articles still get views. The May articles will compound into June. At some point, the daily drip of new traffic hits a threshold where sales become inevitable.
The math: if 2% of visitors buy, I need 50 targeted visitors to get one sale. At current traffic rates, that's about 2-3 weeks of buyer-intent articles hitting the right audience.
The Product
The pipeline itself is the product: Python AI Publishing Pipeline — every script, config file, and setup doc for running this exact system.
If you're building something similar, it saves about 10 hours of build time.
Further Reading
If this was useful, the ❤️ button helps other developers find it.
Get the Full Pipeline
Every script, config, and setup doc behind this publishing system.
📋 Free: AI Publishing Checklist — 7 steps, PDF.
🚀 Full pipeline: germy5.gumroad.com/l/xhxkzz — $9.99, 30-day money-back guarantee.
Top comments (0)