blog-backup/PODCAST_SETUP.md
OpenClaw Bot 9720390e1a Add podcast feature with TTS, RSS feed, and web player
- Multi-provider TTS service (OpenAI, Piper, macOS say)
- Supabase Storage integration for audio files
- RSS 2.0 feed with iTunes extensions for podcast distribution
- Web audio player at /podcast page
- Integration with daily digest workflow
- Manual TTS generation script
- Complete documentation in PODCAST_SETUP.md
2026-02-23 20:15:27 -06:00

8.4 KiB

Podcast Setup Guide

This guide covers setting up and using the podcast feature for the Daily Digest blog.

Overview

The podcast feature automatically converts Daily Digest blog posts into audio format using Text-to-Speech (TTS) and provides:

  • 🎧 Web Player - Listen directly on the blog
  • 📱 RSS Feed - Subscribe in any podcast app (Apple Podcasts, Spotify, etc.)
  • 🔄 Auto-generation - TTS runs automatically when new posts are created
  • 💾 Audio Storage - Files stored in Supabase Storage (free tier)

Architecture

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│  Daily      │────▶│  TTS API    │────▶│  Supabase   │
│  Digest     │     │ (OpenAI/    │     │  Storage    │
│  Post       │     │  Piper)     │     │             │
└─────────────┘     └─────────────┘     └──────┬──────┘
                                               │
                                               ▼
                                        ┌─────────────┐
                                        │  RSS Feed   │
                                        │  (/api/     │
                                        │  podcast/   │
                                        │  rss)       │
                                        └──────┬──────┘
                                               │
                                               ▼
                                        ┌─────────────┐
                                        │  Podcast    │
                                        │  Apps       │
                                        │ (Apple,     │
                                        │  Spotify)   │
                                        └─────────────┘

Quick Start

1. Configure Environment Variables

Add to your .env.local and .env.production:

# Enable TTS generation
ENABLE_TTS=true

# Choose TTS Provider: "openai" (paid, best quality) or "macsay" (free, macOS only)
TTS_PROVIDER=openai

# For OpenAI TTS (recommended)
OPENAI_API_KEY=sk-your-key-here
TTS_VOICE=alloy  # Options: alloy, echo, fable, onyx, nova, shimmer

2. Update Database Schema

Run this SQL in your Supabase SQL Editor to add audio columns:

-- Add audio URL column
ALTER TABLE blog_messages 
ADD COLUMN IF NOT EXISTS audio_url TEXT;

-- Add audio duration column  
ALTER TABLE blog_messages 
ADD COLUMN IF NOT EXISTS audio_duration INTEGER;

-- Create index for faster RSS feed queries
CREATE INDEX IF NOT EXISTS idx_blog_messages_audio 
ON blog_messages(audio_url) 
WHERE audio_url IS NOT NULL;

3. Create Supabase Storage Bucket

The app will automatically create the podcast-audio bucket on first use, or you can create it manually:

  1. Go to Supabase Dashboard → Storage
  2. Click "New Bucket"
  3. Name: podcast-audio
  4. Check "Public bucket"
  5. Click "Create"

4. Deploy

npm run build
vercel --prod

5. Subscribe to the Podcast

The RSS feed is available at:

https://blog-backup-two.vercel.app/api/podcast/rss

Apple Podcasts:

  1. Open Podcasts app
  2. Tap Library → Edit → Add a Show by URL
  3. Paste the RSS URL

Spotify:

  1. Go to Spotify for Podcasters
  2. Submit RSS feed

Other Apps: Just paste the RSS URL into any podcast app.

TTS Providers

Cost: ~$2-4/month for daily 5-minute episodes

Pros:

  • Excellent voice quality
  • Multiple voices available
  • Simple API integration
  • Fast processing

Cons:

  • Paid service
  • Requires API key

Setup:

TTS_PROVIDER=openai
OPENAI_API_KEY=sk-your-key-here
TTS_VOICE=alloy  # or echo, fable, onyx, nova, shimmer

Option 2: macOS say Command (Free)

Cost: $0

Pros:

  • Free, built into macOS
  • No API key needed
  • Works offline

Cons:

  • Lower voice quality
  • macOS only
  • Limited to macOS deployment

Setup:

TTS_PROVIDER=macsay
TTS_VOICE=Samantha  # or Alex, Victoria, etc.

Option 3: Piper TTS (Free, Local)

Cost: $0

Pros:

  • Free and open source
  • High quality neural voices
  • Runs locally (privacy)
  • No rate limits

Cons:

  • Requires downloading voice models (~100MB)
  • More complex setup
  • Requires local execution

Setup:

  1. Install Piper:

    brew install piper-tts  # or download from GitHub
    
  2. Download voice model:

    mkdir -p models
    cd models
    wget https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/lessac/medium/en_US-lessac-medium.onnx
    wget https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/lessac/medium/en_US-lessac-medium.onnx.json
    
  3. Configure:

    TTS_PROVIDER=piper
    PIPER_MODEL_PATH=./models/en_US-lessac-medium.onnx
    

Usage

Automatic Generation

When ENABLE_TTS=true, audio is automatically generated when a new digest is posted via the /api/digest endpoint.

Manual Generation

Generate audio for a specific post:

npm run generate-tts -- <post_id>

Generate audio for all posts missing audio:

npm run generate-tts:all

Force regeneration (overwrite existing):

npm run generate-tts -- <post_id> --force

API Endpoints

GET /api/podcast/rss

Returns the podcast RSS feed in XML format with iTunes extensions.

Headers:

  • Accept: application/xml

Response: RSS 2.0 XML feed

POST /api/digest (Updated)

Now accepts an optional generateAudio parameter:

{
  "date": "2026-02-23",
  "content": "# Daily Digest\n\nToday's news...",
  "tags": ["daily-digest", "ai"],
  "generateAudio": true  // Optional, defaults to true
}

Database Schema

The blog_messages table now includes:

Column Type Description
audio_url TEXT Public URL to the audio file in Supabase Storage
audio_duration INTEGER Estimated duration in seconds

File Structure

src/
├── app/
│   ├── api/
│   │   ├── digest/route.ts          # Updated with TTS trigger
│   │   └── podcast/
│   │       └── rss/route.ts         # RSS feed endpoint
│   ├── podcast/
│   │   └── page.tsx                 # Podcast web player page
│   └── page.tsx                     # Updated with audio player
├── lib/
│   ├── tts.ts                       # TTS service abstraction
│   ├── storage.ts                   # Supabase storage helpers
│   └── podcast.ts                   # RSS generation utilities
└── scripts/
    └── generate-tts.ts              # Manual TTS generation script

Cost Analysis

OpenAI TTS (Daily Digest ~5 min)

  • Characters per day: ~4,000
  • Cost: $0.015 per 1,000 chars (tts-1)
  • Monthly cost: ~$1.80
  • HD voice (tts-1-hd): ~$3.60/month

Supabase Storage

  • Free tier: 1 GB storage
  • Audio files: ~5 MB per episode
  • Monthly storage: ~150 MB (30 episodes)
  • Well within free tier

Total Monthly Cost

  • OpenAI TTS: ~$2-4/month
  • Supabase Storage: $0 (free tier)
  • RSS Hosting: $0 (Next.js API route)
  • Total: ~$2-4/month

Troubleshooting

TTS not generating

  1. Check ENABLE_TTS=true in environment variables
  2. Check TTS_PROVIDER is set correctly
  3. For OpenAI: Verify OPENAI_API_KEY is valid
  4. Check Vercel logs for errors

Audio not playing

  1. Check Supabase Storage bucket is public
  2. Verify audio_url in database is not null
  3. Check browser console for CORS errors

RSS feed not updating

  1. RSS is cached for 5 minutes (max-age=300)
  2. Check that posts have audio_url set
  3. Verify RSS URL is accessible: /api/podcast/rss

Future Enhancements

  • Background job queue for TTS generation (using Inngest/Upstash)
  • Voice selection per post
  • Chapter markers in audio
  • Transcript generation
  • Podcast analytics

Resources