I Automated My Content Workflow with Python — Here's the cron + SQLite Setup I Use
I publish 3+ times a week. I have 84+ digital products. I have zero sales.
Wait — that's not the flex you expected, is it?
Here's the truth: I can build products faster than I can get eyes on them. Content production isn't my bottleneck. Distribution is.
So I built an automated content workflow that helps me publish consistently. It hasn't generated revenue yet (that's the distribution part I'm still solving). But it has removed the "I don't have time to post" excuse.
Here's the exact system I run:
The Core Loop
# Every 4 hours: check my content queue, publish whatever's ready
0 */4 * * * cd /home/income && node scripts/content_pipeline.js
# Every morning: check yesterday's metrics
0 8 * * * cd /home/income && node scripts/morning_briefing.js
# Every evening: log the day's work + plan tomorrow
0 20 * * * cd /home/income && node scripts/evening_review.js
SQLite: My Business Brain
Everything flows through one SQLite database. No Postgres, no MongoDB, no Supabase — just a file.
const Database = require('better-sqlite3');
const db = new Database('business.db');
The Content Pipeline
My pipeline script does four things:
1. Check Queue
function getPendingContent() {
return db.prepare(`
SELECT * FROM content_queue
WHERE status = 'ready'
AND scheduled_for <= datetime('now')
ORDER BY scheduled_for ASC
`).all();
}
2. Generate with AI (Free Tier)
async function generateBody(title, platform) {
const response = await fetch('https://api.groq.com/openai/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.GROQ_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'llama-3.3-70b-versatile',
messages: [{
role: 'user',
content: `Write a 2000-word ${platform} blog post about: ${title}.`
}]
})
});
const data = await response.json();
return data.choices[0].message.content;
}
3. Publish via Dev.to API
async function publishToDevTo(title, body, tags) {
const res = await fetch('https://dev.to/api/articles', {
method: 'POST',
headers: {
'api-key': process.env.DEVTO_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
article: { title, body_markdown: body, tags, published: true }
})
});
return res.json();
}
4. Log Everything
function logPublication(platform, title, url) {
db.prepare(`INSERT INTO published_content (platform, title, url) VALUES (?, ?, ?)`).run(platform, title, url);
db.prepare(`UPDATE content_queue SET status = 'published', published_at = datetime('now') WHERE title = ? AND platform = ?`).run(title, platform);
}
The Dashboard
Every morning I run a quick status check:
function morningBriefing() {
const yesterday = db.prepare(`
SELECT platform, COUNT(*) as posts, COALESCE(SUM(views), 0) as total_views
FROM published_content
WHERE published_at >= datetime('now', '-1 day')
GROUP BY platform
`).all();
console.log('=== Yesterday ===');
yesterday.forEach(row => {
console.log(`${row.platform}: ${row.posts} posts, ${row.total_views} views`);
});
const pending = db.prepare(`SELECT COUNT(*) as count FROM content_queue WHERE status = 'ready'`).get();
console.log(`In queue: ${pending.count} pieces of content`);
}
What This Has Actually Done
Running this for the last month:
- 60+ articles published across dev.to and other platforms
- 84+ digital products created (too many, honestly)
- $0 in revenue (still solving distribution)
The automation keeps me consistent. But consistency alone doesn't pay bills — you need distribution strategy on top of it.
The Missing Piece: Distribution
- Cross-posting — One piece of content gets reformatted for 4 platforms
- Community engagement — Commenting on other people's content (not just broadcasting mine)
- Product bundling — Making my Gumroad products more targeted
Want the Full Setup?
I packaged the complete pipeline into an AI Automation Toolkit. Plug in your API keys and go.
I build tools, write code, and share what works. Follow for more indie developer content.
Top comments (0)