• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
larryhudson

larryhudson

saveTextToPodcast

Public
Like
5
saveTextToPodcast
Home
Code
6
README.md
C
cleanup.ts
H
index.ts
C
process_chunks.ts
C
process_openai_jobs.ts
test.html
Branches
1
Pull requests
Remixes
History
Environment variables
3
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
README.md
Code
/
README.md
Search
7/6/2025
Viewing readonly version of main branch: v80
View latest version
README.md

Text-to-Speech API

This HTTP Val converts text files to speech using OpenAI's TTS API and stores the results for podcast generation.

Setup

  1. Set the OPENAI_API_KEY environment variable in your Val Town settings
  2. Set the AUTH_TOKEN environment variable for API authorization
  3. The SQLite database table will be created automatically on first use

Quick Start

  1. Visit /test for a web interface to upload and convert text files
  2. Or use the API endpoints directly (see below)

API Endpoints

GET /test

Web interface for testing file uploads and conversions.

POST /convert

Converts a text file to speech and stores it. Requires authorization.

Headers:

  • Authorization: Bearer YOUR_AUTH_TOKEN

Parameters:

  • file (File): Text file to convert
  • name (string): Name/title for the episode

Example using curl:

curl -X POST https://your-val-url.web.val.run/convert \ -H "Authorization: Bearer your-auth-token-here" \ -F "file=@your-text-file.txt" \ -F "name=My First Episode"

Response:

{ "success": true, "message": "Text converted to speech successfully", "data": { "name": "My First Episode", "mp3_url": "https://your-val-url.web.val.run/audio/tts_1234567890.mp3", "text_length": 1250 } }

GET /audio/:filename

Serves MP3 audio files from storage.

GET /episodes

Lists all converted episodes.

Response:

{ "success": true, "episodes": [ { "id": 1, "name": "My First Episode", "text": "This is the text content...", "mp3_url": "https://your-val-url.web.val.run/audio/tts_1234567890.mp3", "date_added": "2024-01-01 12:00:00" } ] }

GET /stats

Get database statistics and cleanup information.

Response:

{ "success": true, "stats": { "totalEpisodes": 5, "recentEpisodes": 3, "oldEpisodes": 2, "oldestEpisode": { "name": "First Episode", "date_added": "2024-01-01T12:00:00.000Z" }, "newestEpisode": { "name": "Latest Episode", "date_added": "2024-01-15T12:00:00.000Z" }, "cleanupInfo": { "eligibleForCleanup": 2, "cleanupThreshold": "30 days", "nextCleanup": "Weekly (automated via cron)" } } }

POST /cleanup

Manually trigger cleanup of old episodes. Requires authorization.

Headers:

  • Authorization: Bearer YOUR_AUTH_TOKEN

Body (optional):

{ "days": 30 }

Parameters:

  • days (number, optional): Delete episodes older than this many days (1-365, default: 30)

Response:

{ "success": true, "message": "Cleanup completed for episodes older than 30 days", "result": { "deletedRecords": 2, "deletedFiles": 2, "failedFiles": 0, "deletedEpisodes": [ {"id": 1, "name": "Old Episode 1"}, {"id": 2, "name": "Old Episode 2"} ] } }

GET /podcast.xml

Generates an RSS podcast feed from all episodes. Requires authorization.

Query Parameters:

  • key (string): Must match the AUTH_TOKEN environment variable

Example:

https://your-val-url.web.val.run/podcast.xml?key=your-auth-token-here

Database Schema

The tts_episodes table contains:

  • id (INTEGER PRIMARY KEY)
  • name (TEXT) - Episode title
  • text (TEXT) - Original text content
  • mp3_url (TEXT) - URL to the MP3 file
  • date_added (DATETIME) - Timestamp when added

Features

  • ✅ Text file upload and conversion to MP3
  • ✅ SQLite database storage
  • ✅ MP3 file serving from blob storage
  • ✅ RSS podcast feed generation
  • ✅ Authorization protection for content creation and feed access
  • ✅ Error handling and validation
  • ✅ Automatic database initialization
  • ✅ Web test interface

Automatic Cleanup

A weekly cron job (/cleanup.ts) automatically deletes:

  • Database records older than 30 days
  • Associated MP3 files from blob storage
  • Runs every week to keep storage usage manageable

Cron Job Features

  • ✅ Deletes episodes older than 30 days
  • ✅ Removes both database records and MP3 files
  • ✅ Detailed logging of cleanup operations
  • ✅ Error handling and reporting
  • ✅ Runs weekly (schedule configurable in Val Town UI)

Manual Cleanup

  • Use POST /cleanup endpoint for immediate cleanup
  • Configurable age threshold (1-365 days)
  • Same authorization as content creation
  • Detailed cleanup reports

Security

  • POST /convert: Requires Authorization: Bearer YOUR_TOKEN header
  • GET /podcast.xml: Requires ?key=YOUR_TOKEN query parameter
  • Both use the same AUTH_TOKEN environment variable for validation
  • All other endpoints (episodes list, audio serving, test page) are public

Usage Notes

  • Uses OpenAI's tts-1 model with the alloy voice
  • MP3 files are stored in Val Town's blob storage
  • Database records include full text content for search/reference
  • Podcast feed is automatically generated from database records
  • All endpoints include proper error handling
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
© 2026 Val Town, Inc.