← All posts
How-ToSeptember 5, 2026 · 8 min

How to Make a Reddit Story Bot for TikTok

You can build a fully automated pipeline that pulls the day's hottest Reddit threads, rewrites them into a short script, generates a natural-sounding voiceover with ElevenLabs, stitches the audio and screenshots together in CapCut, and publishes the final video to TikTok - all without lifting a finger. The result is a self-sustaining "automated content creation bot" that delivers fresh, voice-narrated TikTok stories every few hours.

automated content creation bot is a software system that automatically gathers source material, transforms it, and publishes the result without human intervention.

Below you'll find everything you need to replicate this workflow, from the exact stack to the code you can copy-paste, plus the pitfalls that usually trip people up.


What you need

ToolPlan / Price*Role
Reddit API (via OAuth)Free tier (subject to provider limits) - check the current Reddit API pricing pageSource of trending threads
Python 3.11+Free (open-source)Orchestrates the workflow
ElevenLabs TTS APIFree trial (subject to provider limits) - check ElevenLabs pricingGenerates voiceover
CapCut Desktop (Windows)Free tier (subject to provider limits) - check CapCut pricingVideo editing and export
TikTok API (via third-party service or manual upload)Free tier (subject to provider limits) - check the service you choosePublishes the final video
n8n (optional)Community Edition (self-hosted, free) or Cloud plan - check n8n pricingVisual orchestration, webhook trigger
GitHub (for code storage)Free tier - check GitHub pricingVersion control

\When a specific quota or price is not publicly confirmed, we advise you to check the provider's current pricing* before committing.

Estimated build time: 4-6 hours (including testing and TikTok account linking).


Step-by-step build

1. Set up Reddit credentials

  1. Create a Reddit app at <https://www.reddit.com/prefs/apps>. Choose "script" as the type.
  2. Note the client ID, client secret, and your Reddit username/password - you'll need them for OAuth.

Why: Reddit requires OAuth for any API access beyond the public read-only endpoints.

2. Create a Python virtual environment

bash
python -m venv venv
source venv/bin/activate # macOS/Linux
# .\venv\Scripts\activate # Windows
pip install requests python-dotenv elevenlabs-sdk

What this does: Installs the HTTP client, environment variable loader, and the official ElevenLabs SDK.

3. Store secrets securely

Create a .env file in the project root:

dotenv
REDDIT_CLIENT_ID=your_client_id
REDDIT_CLIENT_SECRET=your_client_secret
REDDIT_USERNAME=your_username
REDDIT_PASSWORD=your_password
ELEVENLABS_API_KEY=your_elevenlabs_key
CAPCUT_PATH="C:\\Program Files\\CapCut\\CapCut.exe"

What this does: Keeps credentials out of source code; the python-dotenv package will load them at runtime.

4. Fetch the top-day Reddit posts

python
import os, requests, json
from dotenv import load_dotenv

load_dotenv()
auth = requests.auth.HTTPBasicAuth(os.getenv('REDDIT_CLIENT_ID'), os.getenv('REDDIT_CLIENT_SECRET'))
data = {
 'grant_type': 'password',
 'username': os.getenv('REDDIT_USERNAME'),
 'password': os.getenv('REDDIT_PASSWORD')
}
headers = {'User-Agent': 'RedditStoryBot/0.1'}

# Obtain access token
token_res = requests.post('https://www.reddit.com/api/v1/access_token',
 auth=auth, data=data, headers=headers)
token = token_res.json()['access_token']
headers['Authorization'] = f'bearer {token}'

# Pull top posts from r/AskReddit (you can swap any subreddit)
resp = requests.get('https://oauth.reddit.com/r/AskReddit/top',
 params={'t': 'day', 'limit': 5},
 headers=headers)
posts = resp.json()['data']['children']

What this does: Authenticates with Reddit and pulls the five most-upvoted posts of the day.

5. Convert each post into a concise script

python
def clean_text(text):
 # Strip markdown, URLs, and limit length for TTS
 import re
 text = re.sub(r'\[.*?\]\(.*?\)', '', text) # remove markdown links
 text = re.sub(r'http\S+', '', text) # remove URLs
 return text[:1500] # ElevenLabs limit per request

scripts = []
for post in posts:
 title = post['data']['title']
 selftext = post['data'].get('selftext', '')
 script = f"Title: {title}. {clean_text(selftext)}"
 scripts.append(script)

Why: ElevenLabs caps the payload; trimming prevents errors and keeps the video under TikTok's 60-second limit.

6. Generate voiceovers with ElevenLabs

python
from elevenlabs import generate, set_api_key

set_api_key(os.getenv('ELEVENLABS_API_KEY'))

audio_files = []
for i, script in enumerate(scripts):
 audio = generate(
 text=script,
 voice="Rachel", # pick a voice you like
 model="eleven_multilingual_v2"
 )
 filename = f"audio_{i}.mp3"
 with open(filename, "wb") as f:
 f.write(audio)
 audio_files.append(filename)

What this does: Calls ElevenLabs' TTS endpoint, writes each MP3 to disk.

7. Capture screenshots of the Reddit post

python
import subprocess, time

def capture_screenshot(url, out_path):
 # Use headless Chrome via puppeteer (install with npm i -g puppeteer)
 cmd = [
 "node", "-e",
 f\"\"\"const puppeteer = require('puppeteer');
 (async () => {{
 const browser = await puppeteer.launch({{args:['--no-sandbox']}});
 const page = await browser.newPage();
 await page.goto('{url}', {{waitUntil:'networkidle2'}});
 await page.screenshot({{path:'{out_path}', fullPage:true}});
 await browser.close();
 }})();\"\"\"
 ]
 subprocess.run(cmd, check=True)

screenshot_files = []
for i, post in enumerate(posts):
 url = f"https://reddit.com{post['data']['permalink']}"
 out = f"screenshot_{i}.png"
 capture_screenshot(url, out)
 screenshot_files.append(out)
 time.sleep(2) # be gentle on Reddit

Why: Visuals make the TikTok story engaging; puppeteer provides reliable, headless screenshots.

8. Assemble video in CapCut via command line

CapCut's desktop app can be driven with a simple JSON project file. Create a template project_template.json (export one from CapCut once, then replace placeholders). Here's a minimal excerpt you'll edit programmatically:

json
{
 "timeline": [
 {
 "type": "image",
 "path": "{{IMAGE_PATH}}",
 "duration": 5
 },
 {
 "type": "audio",
 "path": "{{AUDIO_PATH}}",
 "start": 0
 }
 ],
 "output": {
 "resolution": "1080x1920",
 "format": "mp4"
 }
}

Now generate a project per story:

python
import json, shutil

def build_capcut_project(img_path, audio_path, out_json):
 with open('project_template.json') as f:
 tmpl = json.load(f)
 for item in tmpl['timeline']:
 if item['type'] == 'image':
 item['path'] = img_path
 elif item['type'] == 'audio':
 item['path'] = audio_path
 with open(out_json, 'w') as f:
 json.dump(tmpl, f, indent=2)

project_files = []
for i in range(len(scripts)):
 proj = f"project_{i}.json"
 build_capcut_project(screenshot_files[i], audio_files[i], proj)
 project_files.append(proj)

Render each project:

python
for proj in project_files:
 subprocess.run([
 os.getenv('CAPCUT_PATH'),
 "--open", proj,
 "--export", f"{proj.replace('.json', '.mp4')}"
 ], check=True)

What this does: Replaces placeholders with the actual image and audio, then tells CapCut to open the project and export a TikTok-ready MP4.

9. Publish to TikTok

TikTok does not expose a public upload API, so most creators use a third-party service (e.g., TikTokUploader or Zapier). The simplest approach is to set up an n8n webhook that receives the MP4 path and forwards it to the service's API.

json
{
 "nodes": [
 {
 "type": "Webhook",
 "name": "Receive video path",
 "webhookId": "tiktok_upload"
 },
 {
 "type": "HTTP Request",
 "name": "Upload to TikTok",
 "method": "POST",
 "url": "https://api.tiktokuploader.com/v1/upload",
 "authentication": "Header",
 "headerParameters": [
 { "name": "Authorization", "value": "Bearer {{ $json.apiKey }}" }
 ],
 "bodyParameters": [
 { "name": "file", "value": "={{ $json.filePath }}" },
 { "name": "caption", "value": "Daily Reddit Story #Reddit #TikTok" }
 ]
 }
 ],
 "connections": {
 "Receive video path": { "main": [ [ { "node": "Upload to TikTok", "type": "main" } ] ] }
 }
}

What this does: n8n listens for a POST containing filePath; it then calls the third-party uploader with your API key.

You can trigger the webhook from the Python script after each export:

python
import requests, os

def trigger_n8n(mp4_path):
 webhook_url = "https://your-n8n-instance.com/webhook/tiktok_upload"
 payload = {"filePath": os.path.abspath(mp4_path), "apiKey": "YOUR_N8N_API_KEY"}
 requests.post(webhook_url, json=payload)

for proj in project_files:
 mp4 = proj.replace('.json', '.mp4')
 trigger_n8n(mp4)

10. Automate the whole run

Wrap the steps 4-9 into a single main() function and schedule it with cron (Linux/macOS) or Task Scheduler (Windows) to run every 4 hours.

bash
# Example cron entry (runs at 00:00, 04:00, 08:00, 12:00, 16:00, 20:00)
0 */4 * * * /usr/bin/python3 /path/to/reddit_tiktok_bot.py >> /var/log/reddit_tiktok.log 2>&1

Why: Regular execution ensures a steady stream of fresh TikTok content without manual intervention.


Where this breaks

Never assume unlimited API calls. Each provider enforces rate limits that can halt your pipeline in minutes.

Failure modeSymptomFix
Reddit OAuth token expires (1 hour)401 Unauthorized from Reddit APIRefresh token each run (the script already requests a new token) or store a long-lived refresh token if you switch to the newer OAuth2 flow.
ElevenLabs TTS quota exceededAPI returns 429 Too Many Requests or empty audio fileMonitor usage via ElevenLabs dashboard; add exponential back-off and fallback to a cheaper TTS (e.g., Google Cloud TTS) if you hit limits.
CapCut CLI hangs on large imagesNo MP4 output, process stays aliveResize screenshots to 1080 × 1920 before feeding CapCut; limit image duration to ≤ 5 seconds.
Third-party TikTok uploader rejects fileHTTP 400 with "invalid format"Ensure MP4 is encoded with H.264 video and AAC audio; use ffmpeg -i input.mp4 -c:v libx264 -c:a aac output.mp4 as a sanity check.
n8n webhook unreachable (network change)No POST reaches the workflow, videos never uploadDeploy n8n behind a static IP or use a tunneling service like ngrok during development; add health-check alerts (e.g., Slack webhook).
Cost blow-up (voice generation per minute)Unexpected monthly billSet a hard cap in your script: stop after generating N videos per day; log usage to a spreadsheet for audit.

For a deeper technical reference, see n8n's documentation.

FAQ

How do I choose the right subreddit for TikTok audiences? Pick communities with high visual potential and short, story-like posts (e.g., r/AskReddit, r/NoSleep, r/TIFU). Use Reddit's "top" filter for the past day to surface content that's already proven popular.

Can I run this entirely on a free tier cloud VM? Yes, a modest VPS (1 vCPU, 2 GB RAM) can host the Python script, n8n, and a headless Chrome instance for screenshots. Just watch the ElevenLabs and TikTok uploader limits; you may need to upgrade if you exceed free quotas.

What if I don't have a Windows machine for CapCut? CapCut's desktop client is Windows-only, but you can run it in a Windows Docker container or use an alternative open-source editor like Shotcut with a similar JSON-based project file. The rest of the pipeline (Reddit, ElevenLabs, n8n) remains unchanged.

How do I keep my API keys safe when the repo is public? Never commit .env files. Add .env to .gitignore and store keys in your CI/CD secret manager (GitHub Actions Secrets, GitLab CI variables, etc.). The script reads them at runtime via python-dotenv.

bash
ffmpeg -i video.mp4 -i music.mp3 -filter_complex "[0:a][1:a]amix=inputs=2:duration=first" -c:v copy final.mp4

Where can I learn more about selling automation services? Check out our guide on AI automations you can sell and grab the free guide for deeper business tactics.


By following these steps you'll have a reliable automated content creation bot that turns Reddit's hottest stories into TikTok videos on autopilot. The pipeline is modular, so you can swap out ElevenLabs for another TTS, replace CapCut with a different editor, or expand the Reddit source list. Keep an eye on rate limits, monitor costs, and you'll be able to scale the bot into a full-time content engine without ever opening a video editor again. Happy building!

Get the full toolkit

Grab the free guide with the node-by-node build for all 10 automations.

No spam. Unsubscribe anytime. Just the good stuff.