DEV Community

Sam Chen
Sam Chen

Posted on Originally published at getaab.com

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

Tool Plan / Price* Role
Reddit API (via OAuth) Free tier (subject to provider limits) - check the current Reddit API pricing page Source of trending threads
Python 3.11+ Free (open-source) Orchestrates the workflow
ElevenLabs TTS API Free trial (subject to provider limits) - check ElevenLabs pricing Generates voiceover
CapCut Desktop (Windows) Free tier (subject to provider limits) - check CapCut pricing Video editing and export
TikTok API (via third-party service or manual upload) Free tier (subject to provider limits) - check the service you choose Publishes the final video
n8n (optional) Community Edition (self-hosted, free) or Cloud plan - check n8n pricing Visual orchestration, webhook trigger
GitHub (for code storage) Free tier - check GitHub pricing Version 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

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

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:

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"
Enter fullscreen mode Exit fullscreen mode

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

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']
Enter fullscreen mode Exit fullscreen mode

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

5. Convert each post into a concise script

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)
Enter fullscreen mode Exit fullscreen mode

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

6. Generate voiceovers with ElevenLabs

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)
Enter fullscreen mode Exit fullscreen mode

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

7. Capture screenshots of the Reddit post

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
Enter fullscreen mode Exit fullscreen mode

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:

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

Now generate a project per story:

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)
Enter fullscreen mode Exit fullscreen mode

Render each project:

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

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.

{
 "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" } ] ] }
 }
}
Enter fullscreen mode Exit fullscreen mode

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:

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)
Enter fullscreen mode Exit fullscreen mode

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.

# 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
Enter fullscreen mode Exit fullscreen mode

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 mode Symptom Fix
Reddit OAuth token expires (1 hour) 401 Unauthorized from Reddit API Refresh 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 exceeded API returns 429 Too Many Requests or empty audio file Monitor 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 images No MP4 output, process stays alive Resize screenshots to 1080 × 1920 before feeding CapCut; limit image duration to ≤ 5 seconds.
Third-party TikTok uploader rejects file HTTP 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 upload Deploy 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 bill Set 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.

Is there a way to add background music without violating TikTok's copyright rules?

Yes. Use royalty-free tracks from sites like Free Music Archive or YouTube Audio Library. Append the music to the MP4 with ffmpeg before uploading:

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

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!

Top comments (0)