<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sam Chen</title>
    <description>The latest articles on DEV Community by Sam Chen (@samchenreviews).</description>
    <link>https://dev.to/samchenreviews</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3922773%2Ffddedaf2-ccb7-4879-80db-eb8da5acd26c.png</url>
      <title>DEV Community: Sam Chen</title>
      <link>https://dev.to/samchenreviews</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samchenreviews"/>
    <language>en</language>
    <item>
      <title>How to Use Retrieval-Augmented Generation AI in 2026</title>
      <dc:creator>Sam Chen</dc:creator>
      <pubDate>Sun, 20 Sep 2026 06:20:06 +0000</pubDate>
      <link>https://dev.to/samchenreviews/how-to-use-retrieval-augmented-generation-ai-in-2026-4om3</link>
      <guid>https://dev.to/samchenreviews/how-to-use-retrieval-augmented-generation-ai-in-2026-4om3</guid>
      <description>&lt;h2&gt;
  
  
  How to Use Retrieval-Augmented Generation AI in 2026
&lt;/h2&gt;

&lt;p&gt;A step-by-step guide to implementing Retrieval-Augmented Generation (RAG) AI in 2026. Learn the exact costs, ROI calculations, and tools needed to build a profi&lt;/p&gt;

&lt;p&gt;This article originally appeared on &lt;a href="https://wealthfromai.com/use-retrieval-augmented-generation-ai-2026/" rel="noopener noreferrer"&gt;Wealth From AI&lt;/a&gt;. Visit the full post for images and embedded resources.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What are your thoughts? Drop a comment below!&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Ritual Purity and Sacred Language in Ancient Correspondence</title>
      <dc:creator>Sam Chen</dc:creator>
      <pubDate>Sat, 19 Sep 2026 20:43:57 +0000</pubDate>
      <link>https://dev.to/samchenreviews/ritual-purity-and-sacred-language-in-ancient-correspondence-4p42</link>
      <guid>https://dev.to/samchenreviews/ritual-purity-and-sacred-language-in-ancient-correspondence-4p42</guid>
      <description>&lt;p&gt;Auto-generated correspondences for spiritual niche&lt;/p&gt;

&lt;p&gt;Read the full article:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mythicalarchives.com/?p=16728" rel="noopener noreferrer"&gt;https://mythicalarchives.com/?p=16728&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Build AI Receptionist for Appointments with Vapi and Twilio</title>
      <dc:creator>Sam Chen</dc:creator>
      <pubDate>Sat, 19 Sep 2026 16:30:42 +0000</pubDate>
      <link>https://dev.to/samchenreviews/how-to-build-ai-receptionist-for-appointments-with-vapi-and-twilio-16aj</link>
      <guid>https://dev.to/samchenreviews/how-to-build-ai-receptionist-for-appointments-with-vapi-and-twilio-16aj</guid>
      <description>&lt;p&gt;To build ai receptionist for appointments, you integrate Vapi's voice-agent orchestration with Twilio's telephony services, using a webhook to book appointments into Calendly. This setup allows a 24/7 AI receptionist to handle incoming calls, reducing missed calls for business owners. With Vapi, you design the conversation flow, and Twilio handles the call connectivity from $0.05/min. The AI receptionist can then use Calendly's API to schedule appointments, syncing with Google Calendar and your CRM. This automation can be further enhanced with text-to-speech voices from ElevenLabs and speech-to-text capabilities from Deepgram or Whisper.&lt;/p&gt;

&lt;p&gt;To build an AI receptionist for appointments, you'll need to integrate several tools that handle telephony, voice agents, and calendar management. &lt;br&gt;
| Tool | Plan/Price | Role |&lt;br&gt;
| --- | --- | --- |&lt;br&gt;
| Twilio | from $0.0085/min | Telephony and SIP trunking |&lt;br&gt;
| Vapi | check current pricing | Voice-agent orchestration |&lt;br&gt;
| Calendly | from $8/user/month | Calendar and appointment scheduling |&lt;br&gt;
| OpenAI | check current pricing | AI-powered chat and appointment booking |&lt;br&gt;
| ElevenLabs | from $5/month | Text-to-speech voices for AI receptionist |&lt;br&gt;
| Zapier | from $19.99/month | Automation and integration of AI receptionist with CRM and Google Calendar |&lt;/p&gt;
&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The AI receptionist automation starts with an incoming call to a Twilio phone number, which triggers a webhook that sends the call details to Vapi for voice-agent orchestration. Vapi then uses its API to initiate a call flow that interacts with the caller.&lt;/li&gt;
&lt;li&gt;The caller's speech is transcribed to text using Deepgram's speech-to-text engine, allowing the AI receptionist to understand the caller's intent and respond accordingly. This text is then processed by OpenAI to determine the caller's appointment booking request.&lt;/li&gt;
&lt;li&gt;The AI receptionist, powered by Vapi and OpenAI, asks the caller for their availability and preferred appointment time, and then checks the business owner's Google Calendar for available time slots. If a suitable time slot is found, the AI receptionist proceeds to book the appointment using the Calendly API.&lt;/li&gt;
&lt;li&gt;Once the appointment is booked, the AI receptionist sends a confirmation message to the caller using Twilio's SMS API, and also updates the business owner's CRM with the new appointment details. The CRM update is done using Zapier, which integrates Calendly with the CRM system.&lt;/li&gt;
&lt;li&gt;To provide a natural-sounding voice for the AI receptionist, ElevenLabs' text-to-speech voices are used, which are integrated with Vapi's voice-agent orchestration platform. This ensures that the caller has a direct and natural interaction with the AI receptionist.&lt;/li&gt;
&lt;li&gt;The entire automation flow is monitored and managed using Vapi's dashboard, which provides real-time insights into call volumes, appointment bookings, and other key metrics, allowing business owners to optimize their AI receptionist automation workflow.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  How to build it
&lt;/h2&gt;

&lt;p&gt;To build an AI receptionist for appointments, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set up a Twilio account to handle incoming calls, with a starting price from $0.05/min for voice calls. Create a new Twilio phone number and configure it to receive incoming calls.&lt;/li&gt;
&lt;li&gt;Configure the Twilio Voice API to forward incoming calls to a Vapi voice agent, which will orchestrate the AI receptionist workflow. You will need to set up a Vapi account and create a new voice agent.&lt;/li&gt;
&lt;li&gt;In Vapi, create a new workflow that uses the OpenAI API to generate human-like responses to caller inquiries. You can use the OpenAI API to integrate with models like ChatGPT or other custom models.&lt;/li&gt;
&lt;li&gt;Integrate the Vapi workflow with Calendly to book appointments. You will need to set up a Calendly account and create a new event type for the AI receptionist to book appointments.&lt;/li&gt;
&lt;li&gt;Use a webhook to send appointment booking notifications to a CRM system, such as Google Calendar or a custom CRM. This will ensure that all booked appointments are synced with the business owner's calendar.&lt;/li&gt;
&lt;li&gt;To handle speech-to-text functionality, integrate the workflow with a speech-to-text API like Deepgram or Whisper. This will allow the AI receptionist to transcribe caller audio and respond accordingly.&lt;/li&gt;
&lt;li&gt;To add a text-to-speech component, integrate the workflow with ElevenLabs, which offers high-quality text-to-speech voices. This will enable the AI receptionist to respond to callers with a natural-sounding voice.&lt;/li&gt;
&lt;li&gt;Use a tool like Zapier or n8n to automate the workflow and integrate the various APIs and services. For example, you can use n8n to create a workflow that triggers the Vapi voice agent when a new call is received.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"nodes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"trigger"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"twilio"&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Twilio Trigger"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.twilio"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"voiceAgent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vapi-agent"&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Vapi Voice Agent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.vapi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"connections"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"Twilio Trigger"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="s2"&gt;"Vapi Voice Agent"&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To configure the OpenAI API to generate human-like responses, you can use a prompt like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Book an appointment with a business owner. The caller wants to schedule a meeting for {date} at {time}. Respond with a confirmation message and send a booking notification to the CRM system.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Completion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
 &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text-davinci-003&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;max_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that you will need to replace the &lt;code&gt;{date}&lt;/code&gt; and &lt;code&gt;{time}&lt;/code&gt; placeholders with the actual values provided by the caller. You can use the Vapi API to extract these values from the caller's audio input. For more information on the Vapi API, refer to the &lt;a href="https://vapi.ai" rel="noopener noreferrer"&gt;Vapi API reference&lt;/a&gt;. Additionally, you can check the &lt;a href="https://www.twilio.com" rel="noopener noreferrer"&gt;Twilio documentation&lt;/a&gt; for more information on setting up a Twilio account and configuring the Voice API.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it costs to run
&lt;/h2&gt;

&lt;p&gt;To estimate the monthly cost of running an AI receptionist automation, we consider the following assumptions: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The cost of using Twilio for telephony services starts at $0.0085/min for incoming calls and $0.013/min for outgoing calls, but check current pricing for the most up-to-date rates.&lt;/li&gt;
&lt;li&gt;The cost of using Vapi for voice-agent orchestration is not certain, so check current pricing.&lt;/li&gt;
&lt;li&gt;The cost of using Calendly for appointment scheduling is $8/user/month for the basic plan.
The estimated monthly costs are as follows:
| Tool | 100 uses | 1,000 uses | 10,000 uses |
| --- | --- | --- | --- |
| Twilio | $8.50 | $85 | $850 |
| Vapi | check current pricing | check current pricing | check current pricing |
| Calendly | $8 | $8 | $8 |
Note: These estimates may vary based on actual usage and pricing plans.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where this breaks
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Incomplete Call Routing&lt;/strong&gt; occurs when the AI receptionist fails to correctly route calls to the intended Calendly booking page, resulting in missed appointments. To fix this, verify that the Twilio SIP setup is correctly configured to trigger the Vapi voice agent, which then initiates the Calendly booking workflow via a webhook.&lt;br&gt;
&lt;strong&gt;Speech Recognition Errors&lt;/strong&gt; happen when the speech-to-text engine, such as Deepgram or Whisper, misinterprets the caller's voice, leading to incorrect appointment bookings or failed bookings altogether. The fix involves adjusting the speech recognition model's settings or switching to a more accurate model, and ensuring that the Vapi API reference is consulted for optimal integration.&lt;br&gt;
&lt;strong&gt;Calendar Synchronization Issues&lt;/strong&gt; arise when the AI receptionist books appointments in Calendly, but they do not sync correctly with the business owner's Google Calendar, causing scheduling conflicts. To resolve this, check that the Calendly and Google Calendar APIs are correctly connected via Zapier or a similar automation tool, and that the webhook notifications are properly configured to update the calendar in real-time.&lt;br&gt;
&lt;strong&gt;Voice Quality Problems&lt;/strong&gt; occur when the text-to-speech voice provided by ElevenLabs sounds unnatural or robotic, detracting from the caller's experience and potentially leading to abandoned calls. The solution is to experiment with different voice models and settings, such as adjusting the speech rate or tone, to find a more human-like voice that improves the overall caller experience, and to consider using a more advanced voice API, such as OpenAI, to generate more natural-sounding voices, all while keeping in mind that telephony services like Twilio may charge from $0.05/min for such calls.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the best way to integrate AI receptionist with my existing CRM?
&lt;/h2&gt;

&lt;p&gt;To integrate your AI receptionist with your existing CRM, you can use Zapier or a similar automation tool to connect your AI receptionist's appointment booking system with your CRM, allowing for direct data transfer and synchronization. This integration enables you to access customer information and appointment history in one place. You can also use webhooks to send data from your AI receptionist to your CRM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can I use AI receptionist automation with Google Calendar instead of Calendly?
&lt;/h2&gt;

&lt;p&gt;Yes, you can use AI receptionist automation with Google Calendar by using the Google Calendar API to integrate your AI receptionist with your Google Calendar account, allowing for appointment scheduling and synchronization. This integration enables you to manage appointments and schedule meetings directly within Google Calendar. You can use Vapi or a similar voice-agent orchestration platform to handle the integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I handle missed calls and voicemails with my AI receptionist automation?
&lt;/h2&gt;

&lt;p&gt;To handle missed calls and voicemails, you can use Twilio's Voice API to route incoming calls to your AI receptionist, which can then use text-to-speech voices from ElevenLabs to leave a message or prompt the caller to leave a voicemail. You can also use speech-to-text services like Deepgram or Whisper to transcribe voicemails and send them to your email or CRM. This enables you to respond to missed calls and voicemails in a timely and efficient manner.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the costs associated with building an AI receptionist for appointments?
&lt;/h2&gt;

&lt;p&gt;The costs associated with building an AI receptionist for appointments vary depending on the tools and services used, but you can expect to pay from $0.05/min for Twilio's Voice API, check current pricing for Vapi's voice-agent orchestration platform, and a starting price of $20/month for Calendly's appointment scheduling service. Additionally, you may need to pay for speech-to-text and text-to-speech services, as well as any custom development or integration work required to build your AI receptionist automation.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>ai</category>
      <category>api</category>
    </item>
    <item>
      <title>How to Make Faceless AI Videos for TikTok</title>
      <dc:creator>Sam Chen</dc:creator>
      <pubDate>Sat, 19 Sep 2026 16:12:20 +0000</pubDate>
      <link>https://dev.to/samchenreviews/how-to-make-faceless-ai-videos-for-tiktok-o3o</link>
      <guid>https://dev.to/samchenreviews/how-to-make-faceless-ai-videos-for-tiktok-o3o</guid>
      <description>&lt;p&gt;To create viral short-form videos without appearing on camera, use Pika Labs for video generation AI and ElevenLabs for voice synthesis. This combination allows you to produce high-quality, engaging content for TikTok and YouTube Shorts. By leveraging Pika Labs' video creation capabilities and ElevenLabs' realistic text-to-speech voices, you can generate faceless AI videos that capture your audience's attention. For TikTok automation and content scaling, integrate these tools with your existing workflow to streamline production and reach a wider audience, enabling you to focus on how to make faceless AI videos for TikTok that drive engagement and conversions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;p&gt;To generate viral short-form videos, you'll need a combination of AI-powered tools for video generation, voice synthesis, and automation.&lt;br&gt;
| Tool | Plan/Price | Role |&lt;br&gt;
| --- | --- | --- |&lt;br&gt;
| Pika Labs | check current pricing | video generation AI |&lt;br&gt;
| ElevenLabs | from $5/month | text-to-speech voiceovers |&lt;br&gt;
| TikTok | free | social media platform for video distribution |&lt;br&gt;
| YouTube Shorts | free | social media platform for video distribution |&lt;br&gt;
| Vapi | check current pricing | voice-agent orchestration |&lt;br&gt;
| n8n | free (self-hosted), check current pricing (cloud) | automation workflow builder |&lt;/p&gt;
&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The automation starts with a text prompt, which is passed to ElevenLabs for text-to-speech voice synthesis, generating a high-quality AI voiceover from $0.005/min. This voiceover is then used as the audio component of the video.&lt;/li&gt;
&lt;li&gt;The text prompt is also used to generate a video using Pika Labs' video generation AI, which creates a short-form video clip based on the prompt's content and style.&lt;/li&gt;
&lt;li&gt;The generated video and audio are then combined using a video editing API, such as the one provided by Pika Labs, to create a single video file with the AI voiceover.&lt;/li&gt;
&lt;li&gt;The final video is then uploaded to TikTok or YouTube Shorts using the respective platform's API, allowing for automated content scaling and distribution.&lt;/li&gt;
&lt;li&gt;To monitor and optimize the performance of the videos, a analytics tool can be used to track engagement metrics, such as views and likes, and adjust the automation workflow accordingly.&lt;/li&gt;
&lt;li&gt;The automation workflow can be orchestrated using a tool like Vapi, which allows for the integration of multiple APIs and services, including ElevenLabs and Pika Labs, to create a direct end-to-end workflow for generating and distributing faceless AI videos.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  How to build it
&lt;/h2&gt;

&lt;p&gt;To create faceless AI videos for TikTok, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set up a Pika Labs account to utilize their video generation AI capabilities. Check current pricing for their plans, as they offer various options for content scaling.&lt;/li&gt;
&lt;li&gt;Create a text-to-speech voiceover using ElevenLabs, which offers a range of voices from $0.05/min. Choose a voice that fits your desired tone and style for the video.&lt;/li&gt;
&lt;li&gt;Plan your video script, keeping in mind the short-form format of TikTok and YouTube Shorts. Ensure your script is engaging, informative, and concise.&lt;/li&gt;
&lt;li&gt;Use Pika Labs' video generation AI to create a faceless AI video based on your script. You can customize the video's style, pace, and visuals to fit your brand and message.&lt;/li&gt;
&lt;li&gt;Integrate the ElevenLabs voiceover into your Pika Labs video. This can be done by uploading the voiceover audio file to Pika Labs or using their API to integrate the voiceover directly.&lt;/li&gt;
&lt;li&gt;Configure the video settings, such as resolution, aspect ratio, and frame rate, to ensure compatibility with TikTok and YouTube Shorts.&lt;/li&gt;
&lt;li&gt;Test and refine your faceless AI video to ensure it meets your quality standards. Make any necessary adjustments to the script, voiceover, or video settings.&lt;/li&gt;
&lt;li&gt;Deploy your faceless AI video on TikTok and YouTube Shorts, using automation tools like n8n or Zapier to streamline the process. You can also use Vapi for voice-agent orchestration to further enhance your automation workflow.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"nodes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Your video script here"&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Pika Labs Video Generation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.pikaLabsVideoGeneration"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"voice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ElevenLabs Voice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Your voiceover script here"&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ElevenLabs Voiceover"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.elevenLabsVoiceover"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"connections"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"Pika Labs Video Generation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ElevenLabs Voiceover"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To further customize your faceless AI video, you can use a system prompt like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pikalabs-video-generation &lt;span class="nt"&gt;--script&lt;/span&gt; &lt;span class="s2"&gt;"Your video script here"&lt;/span&gt; &lt;span class="nt"&gt;--voiceover&lt;/span&gt; &lt;span class="s2"&gt;"ElevenLabs Voice"&lt;/span&gt; &lt;span class="nt"&gt;--style&lt;/span&gt; &lt;span class="s2"&gt;"Your desired style here"&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; &lt;span class="s2"&gt;"Your output file name here"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prompt allows you to specify the video script, voiceover, style, and output file name, giving you more control over the final product. By combining Pika Labs' video generation AI with ElevenLabs' voice synthesis capabilities and automating the process with tools like n8n or Zapier, you can efficiently create high-quality faceless AI videos for TikTok and YouTube Shorts. For more information on automation workflows, visit &lt;a href="https://getaab.com/blog/" rel="noopener noreferrer"&gt;https://getaab.com/blog/&lt;/a&gt; or explore the documentation for &lt;a href="https://elevenlabs.io" rel="noopener noreferrer"&gt;https://elevenlabs.io&lt;/a&gt; to learn more about their voice synthesis capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it costs to run
&lt;/h2&gt;

&lt;p&gt;To estimate the monthly cost of faceless AI video automation, we consider the costs of video generation and voice synthesis. &lt;br&gt;
| Tool | 100 uses/month | 1,000 uses/month | 10,000 uses/month |&lt;br&gt;
| --- | --- | --- | --- |&lt;br&gt;
| Pika Labs | check current pricing | check current pricing | check current pricing |&lt;br&gt;
| ElevenLabs | from $5/month | from $50/month | check current pricing |&lt;br&gt;
Assuming Pika Labs video generation costs are based on the number of generated videos, and ElevenLabs voice synthesis costs are based on the number of voiceovers used. &lt;br&gt;
Assuming a faceless AI video automation workflow uses one video generation and one voiceover per use. &lt;br&gt;
Note that actual costs may vary depending on the specific plans and pricing models of Pika Labs and ElevenLabs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this breaks
&lt;/h2&gt;

&lt;p&gt;When generating faceless AI videos for TikTok using Pika Labs and ElevenLabs, several issues can arise. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Audio Sync Failure&lt;/strong&gt;: The symptom is a noticeable delay between the AI-generated voiceover and the video content, making the video unwatchable. 
The fix is to adjust the audio timing in the Pika Labs video generation AI settings to ensure proper synchronization with the ElevenLabs voice synthesis output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Voice Quality Degradation&lt;/strong&gt;: The symptom is a significant drop in audio quality, resulting in an unnatural or robotic voice that detracts from the video's overall quality. 
The fix is to experiment with different voice models and settings in ElevenLabs to find the optimal combination that produces a clear and natural-sounding voiceover.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TikTok Automation Limitations&lt;/strong&gt;: The symptom is the inability to automate video uploads to TikTok due to platform restrictions or API limitations. 
The fix is to explore alternative automation tools, such as Zapier or Make, that offer more flexible integration options with TikTok, or consider using YouTube Shorts as a fallback platform.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Scaling Bottlenecks&lt;/strong&gt;: The symptom is a significant slowdown in video generation and upload times as the volume of content increases, hindering the ability to scale content production. 
The fix is to leverage cloud-based services, such as those offered by Vapi, to orchestrate and manage the video generation and upload process, allowing for more efficient and scalable content production, as discussed in more detail on &lt;a href="https://getaab.com/blog/" rel="noopener noreferrer"&gt;https://getaab.com/blog/&lt;/a&gt;, and by visiting the &lt;a href="https://elevenlabs.io" rel="noopener noreferrer"&gt;https://elevenlabs.io&lt;/a&gt; homepage for more information on voice synthesis capabilities.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is faceless AI video automation used for?
&lt;/h2&gt;

&lt;p&gt;Faceless AI video automation is used to generate short-form videos for platforms like TikTok and YouTube Shorts, allowing creators to produce content at scale without appearing on camera. This method leverages AI voiceovers and video generation to create engaging, viral content. By using tools like Pika Labs and ElevenLabs, creators can produce high-quality videos quickly and efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I get started with faceless AI video automation?
&lt;/h2&gt;

&lt;p&gt;To get started with faceless AI video automation, you'll need to select a video generation AI tool like Pika Labs and a text-to-speech voiceover tool like ElevenLabs. You can then use these tools to generate videos and voiceovers, and automate the process using a platform like n8n or Zapier. Check current pricing for each tool to determine the best fit for your budget.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can I use faceless AI video automation for other social media platforms?
&lt;/h2&gt;

&lt;p&gt;Yes, faceless AI video automation can be used for other social media platforms beyond TikTok and YouTube Shorts. However, you'll need to consider the specific requirements and constraints of each platform, such as video length and format. By using a flexible automation platform, you can adapt your faceless AI video automation workflow to suit different social media platforms.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I ensure the quality of my faceless AI videos?
&lt;/h2&gt;

&lt;p&gt;To ensure the quality of your faceless AI videos, you'll need to carefully select and configure your video generation AI and text-to-speech voiceover tools. You can also use tools like Deepgram or Whisper for speech-to-text transcription and editing to refine your video content. Additionally, you can visit &lt;a href="https://getaab.com/blog/" rel="noopener noreferrer"&gt;https://getaab.com/blog/&lt;/a&gt; for more information on automating video content creation and other AI-related topics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/blog/faceless-ai-content-automation-youtube-shorts"&gt;Launch a faceless AI content automation bot that scrapes niche news, builds explainer videos with ElevenLabs, and publishes to YouTube Shorts automatically&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/blog/faceless-youtube-automation-ai-voice-stock-footage"&gt;how to make faceless youtube shorts with ai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/blog/launch-ai-automation-agency-voice-agents-local-businesses"&gt;How to launch an AI automation agency offering voice AI agents for local businesses&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>nocode</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Make a Reddit Story Bot for TikTok</title>
      <dc:creator>Sam Chen</dc:creator>
      <pubDate>Sat, 19 Sep 2026 16:01:37 +0000</pubDate>
      <link>https://dev.to/samchenreviews/how-to-make-a-reddit-story-bot-for-tiktok-373e</link>
      <guid>https://dev.to/samchenreviews/how-to-make-a-reddit-story-bot-for-tiktok-373e</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;automated content creation bot is a software system that automatically gathers source material, transforms it, and publishes the result without human intervention.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;




&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Plan / Price*&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Reddit API (via OAuth)&lt;/td&gt;
&lt;td&gt;Free tier (subject to provider limits) - check the current Reddit API pricing page&lt;/td&gt;
&lt;td&gt;Source of trending threads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python 3.11+&lt;/td&gt;
&lt;td&gt;Free (open-source)&lt;/td&gt;
&lt;td&gt;Orchestrates the workflow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ElevenLabs TTS API&lt;/td&gt;
&lt;td&gt;Free trial (subject to provider limits) - check ElevenLabs pricing&lt;/td&gt;
&lt;td&gt;Generates voiceover&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CapCut Desktop (Windows)&lt;/td&gt;
&lt;td&gt;Free tier (subject to provider limits) - check CapCut pricing&lt;/td&gt;
&lt;td&gt;Video editing and export&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TikTok API (via third-party service or manual upload)&lt;/td&gt;
&lt;td&gt;Free tier (subject to provider limits) - check the service you choose&lt;/td&gt;
&lt;td&gt;Publishes the final video&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;n8n (optional)&lt;/td&gt;
&lt;td&gt;Community Edition (self-hosted, free) or Cloud plan - check n8n pricing&lt;/td&gt;
&lt;td&gt;Visual orchestration, webhook trigger&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub (for code storage)&lt;/td&gt;
&lt;td&gt;Free tier - check GitHub pricing&lt;/td&gt;
&lt;td&gt;Version control&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;*When a specific quota or price is not publicly confirmed, we advise you to &lt;strong&gt;check the provider's current pricing&lt;/strong&gt; before committing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Estimated build time:&lt;/strong&gt; 4-6 hours (including testing and TikTok account linking).&lt;/p&gt;




&lt;h2&gt;
  
  
  Step-by-step build
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Set up Reddit credentials
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Create a Reddit app at &lt;a href="https://www.reddit.com/prefs/apps" rel="noopener noreferrer"&gt;https://www.reddit.com/prefs/apps&lt;/a&gt;. Choose "script" as the type. &lt;/li&gt;
&lt;li&gt;Note the &lt;strong&gt;client ID&lt;/strong&gt;, &lt;strong&gt;client secret&lt;/strong&gt;, and your Reddit &lt;strong&gt;username/password&lt;/strong&gt; - you'll need them for OAuth. &lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Why:&lt;/em&gt; Reddit requires OAuth for any API access beyond the public read-only endpoints. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. Create a Python virtual environment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv
&lt;span class="nb"&gt;source &lt;/span&gt;venv/bin/activate &lt;span class="c"&gt;# macOS/Linux&lt;/span&gt;
&lt;span class="c"&gt;# .\venv\Scripts\activate # Windows&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;requests python-dotenv elevenlabs-sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;What this does:&lt;/em&gt; Installs the HTTP client, environment variable loader, and the official ElevenLabs SDK.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  3. Store secrets securely
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;.env&lt;/code&gt; file in the project root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;What this does:&lt;/em&gt; Keeps credentials out of source code; the &lt;code&gt;python-dotenv&lt;/code&gt; package will load them at runtime.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  4. Fetch the top-day Reddit posts
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;

&lt;span class="nf"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;HTTPBasicAuth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;REDDIT_CLIENT_ID&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;REDDIT_CLIENT_SECRET&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;grant_type&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;password&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;username&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;REDDIT_USERNAME&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
 &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;password&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;REDDIT_PASSWORD&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;User-Agent&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;RedditStoryBot/0.1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Obtain access token
&lt;/span&gt;&lt;span class="n"&gt;token_res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://www.reddit.com/api/v1/access_token&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;token_res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;access_token&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;# Pull top posts from r/AskReddit (you can swap any subreddit)
&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://oauth.reddit.com/r/AskReddit/top&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;day&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;limit&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;children&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;What this does:&lt;/em&gt; Authenticates with Reddit and pulls the five most-upvoted posts of the day. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  5. Convert each post into a concise script
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;clean_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
 &lt;span class="c1"&gt;# Strip markdown, URLs, and limit length for TTS
&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;
 &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;\[.*?\]\(.*?\)&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# remove markdown links
&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;http\S+&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# remove URLs
&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# ElevenLabs limit per request
&lt;/span&gt;
&lt;span class="n"&gt;scripts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
 &lt;span class="n"&gt;selftext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;selftext&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;script&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Title: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;clean_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;selftext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
 &lt;span class="n"&gt;scripts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Why:&lt;/em&gt; ElevenLabs caps the payload; trimming prevents errors and keeps the video under TikTok's 60-second limit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  6. Generate voiceovers with ElevenLabs
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;elevenlabs&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;set_api_key&lt;/span&gt;

&lt;span class="nf"&gt;set_api_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ELEVENLABS_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;audio_files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;script&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scripts&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
 &lt;span class="n"&gt;audio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
 &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;voice&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Rachel&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# pick a voice you like
&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eleven_multilingual_v2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
 &lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;audio_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.mp3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
 &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;audio_files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;What this does:&lt;/em&gt; Calls ElevenLabs' TTS endpoint, writes each MP3 to disk. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  7. Capture screenshots of the Reddit post
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;capture_screenshot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;out_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
 &lt;span class="c1"&gt;# Use headless Chrome via puppeteer (install with npm i -g puppeteer)
&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
 &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;node&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-e&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;f&lt;/span&gt;\&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"\"&lt;/span&gt;&lt;span class="s"&gt;const puppeteer = require(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;puppeteer&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;);
 (async () =&amp;gt; {{
 const browser = await puppeteer.launch({{args:[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;--no-sandbox&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;]}});
 const page = await browser.newPage();
 await page.goto(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;{url}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;, {{waitUntil:&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;networkidle2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;}});
 await page.screenshot({{path:&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;{out_path}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;, fullPage:true}});
 await browser.close();
 }})();&lt;/span&gt;&lt;span class="se"&gt;\"\"\"&lt;/span&gt;&lt;span class="s"&gt;
 ]
 subprocess.run(cmd, check=True)

screenshot_files = []
for i, post in enumerate(posts):
 url = f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;reddit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;permalink&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;
 out = f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="n"&gt;screenshot_&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="n"&gt;png&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;
 capture_screenshot(url, out)
 screenshot_files.append(out)
 time.sleep(2) # be gentle on Reddit
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Why:&lt;/em&gt; Visuals make the TikTok story engaging; puppeteer provides reliable, headless screenshots.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  8. Assemble video in CapCut via command line
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"timeline"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{{IMAGE_PATH}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"audio"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{{AUDIO_PATH}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"output"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"resolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1080x1920"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mp4"&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now generate a project per story:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shutil&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build_capcut_project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;audio_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;out_json&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
 &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;project_template.json&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="n"&gt;tmpl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tmpl&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;timeline&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
 &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;image&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;path&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img_path&lt;/span&gt;
 &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;audio&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;path&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;audio_path&lt;/span&gt;
 &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;out_json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmpl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;project_files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scripts&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
 &lt;span class="n"&gt;proj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;project_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
 &lt;span class="nf"&gt;build_capcut_project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;screenshot_files&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;audio_files&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;proj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;project_files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Render each project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;proj&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;project_files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
 &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;CAPCUT_PATH&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
 &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--open&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--export&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;proj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.json&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.mp4&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
 &lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;What this does:&lt;/em&gt; Replaces placeholders with the actual image and audio, then tells CapCut to open the project and export a TikTok-ready MP4.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  9. Publish to TikTok
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"nodes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Webhook"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Receive video path"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"webhookId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tiktok_upload"&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HTTP Request"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Upload to TikTok"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.tiktokuploader.com/v1/upload"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"authentication"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Header"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"headerParameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer {{ $json.apiKey }}"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"bodyParameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"={{ $json.filePath }}"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"caption"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Daily Reddit Story #Reddit #TikTok"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"connections"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"Receive video path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Upload to TikTok"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;What this does:&lt;/em&gt; n8n listens for a POST containing &lt;code&gt;filePath&lt;/code&gt;; it then calls the third-party uploader with your API key. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can trigger the webhook from the Python script after each export:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;trigger_n8n&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mp4_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
 &lt;span class="n"&gt;webhook_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://your-n8n-instance.com/webhook/tiktok_upload&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
 &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;filePath&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abspath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mp4_path&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;apiKey&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_N8N_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;webhook_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;proj&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;project_files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="n"&gt;mp4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;proj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.json&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.mp4&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="nf"&gt;trigger_n8n&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mp4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10. Automate the whole run
&lt;/h3&gt;

&lt;p&gt;Wrap the steps 4-9 into a single &lt;code&gt;main()&lt;/code&gt; function and schedule it with &lt;strong&gt;cron&lt;/strong&gt; (Linux/macOS) or &lt;strong&gt;Task Scheduler&lt;/strong&gt; (Windows) to run every 4 hours.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Example cron entry (runs at 00:00, 04:00, 08:00, 12:00, 16:00, 20:00)&lt;/span&gt;
0 &lt;span class="k"&gt;*&lt;/span&gt;/4 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /usr/bin/python3 /path/to/reddit_tiktok_bot.py &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /var/log/reddit_tiktok.log 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Why:&lt;/em&gt; Regular execution ensures a steady stream of fresh TikTok content without manual intervention.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Where this breaks
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Never assume unlimited API calls.&lt;/strong&gt; Each provider enforces rate limits that can halt your pipeline in minutes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Failure mode&lt;/th&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Reddit OAuth token expires (1 hour)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;401 Unauthorized&lt;/code&gt; from Reddit API&lt;/td&gt;
&lt;td&gt;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.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ElevenLabs TTS quota exceeded&lt;/td&gt;
&lt;td&gt;API returns &lt;code&gt;429 Too Many Requests&lt;/code&gt; or empty audio file&lt;/td&gt;
&lt;td&gt;Monitor usage via ElevenLabs dashboard; add exponential back-off and fallback to a cheaper TTS (e.g., Google Cloud TTS) if you hit limits.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CapCut CLI hangs on large images&lt;/td&gt;
&lt;td&gt;No MP4 output, process stays alive&lt;/td&gt;
&lt;td&gt;Resize screenshots to 1080 × 1920 before feeding CapCut; limit image duration to ≤ 5 seconds.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Third-party TikTok uploader rejects file&lt;/td&gt;
&lt;td&gt;HTTP 400 with "invalid format"&lt;/td&gt;
&lt;td&gt;Ensure MP4 is encoded with H.264 video and AAC audio; use &lt;code&gt;ffmpeg -i input.mp4 -c:v libx264 -c:a aac output.mp4&lt;/code&gt; as a sanity check.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;n8n webhook unreachable (network change)&lt;/td&gt;
&lt;td&gt;No POST reaches the workflow, videos never upload&lt;/td&gt;
&lt;td&gt;Deploy n8n behind a static IP or use a tunneling service like ngrok during development; add health-check alerts (e.g., Slack webhook).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost blow-up (voice generation per minute)&lt;/td&gt;
&lt;td&gt;Unexpected monthly bill&lt;/td&gt;
&lt;td&gt;Set a hard cap in your script: stop after generating N videos per day; log usage to a spreadsheet for audit.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;For a deeper technical reference, see &lt;a href="https://docs.n8n.io/" rel="noopener noreferrer"&gt;n8n's documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How do I choose the right subreddit for TikTok audiences?
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I run this entirely on a free tier cloud VM?
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  What if I don't have a Windows machine for CapCut?
&lt;/h3&gt;

&lt;p&gt;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 &lt;strong&gt;Shotcut&lt;/strong&gt; with a similar JSON-based project file. The rest of the pipeline (Reddit, ElevenLabs, n8n) remains unchanged.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I keep my API keys safe when the repo is public?
&lt;/h3&gt;

&lt;p&gt;Never commit &lt;code&gt;.env&lt;/code&gt; files. Add &lt;code&gt;.env&lt;/code&gt; to &lt;code&gt;.gitignore&lt;/code&gt; and store keys in your CI/CD secret manager (GitHub Actions Secrets, GitLab CI variables, etc.). The script reads them at runtime via &lt;code&gt;python-dotenv&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is there a way to add background music without violating TikTok's copyright rules?
&lt;/h3&gt;

&lt;p&gt;Yes. Use royalty-free tracks from sites like &lt;strong&gt;Free Music Archive&lt;/strong&gt; or &lt;strong&gt;YouTube Audio Library&lt;/strong&gt;. Append the music to the MP4 with &lt;code&gt;ffmpeg&lt;/code&gt; before uploading:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; video.mp4 &lt;span class="nt"&gt;-i&lt;/span&gt; music.mp3 &lt;span class="nt"&gt;-filter_complex&lt;/span&gt; &lt;span class="s2"&gt;"[0:a][1:a]amix=inputs=2:duration=first"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt;:v copy final.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Where can I learn more about selling automation services?
&lt;/h3&gt;

&lt;p&gt;Check out our guide on &lt;strong&gt;&lt;a href="https://getaab.com/ai-automations-to-sell" rel="noopener noreferrer"&gt;AI automations you can sell&lt;/a&gt;&lt;/strong&gt; and grab the &lt;strong&gt;&lt;a href="https://getaab.com/free" rel="noopener noreferrer"&gt;free guide&lt;/a&gt;&lt;/strong&gt; for deeper business tactics.&lt;/p&gt;




&lt;p&gt;By following these steps you'll have a reliable &lt;strong&gt;automated content creation bot&lt;/strong&gt; 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!&lt;/p&gt;

</description>
      <category>n8n</category>
      <category>python</category>
      <category>api</category>
    </item>
    <item>
      <title>A Guide to Korean Daily Planners for Structured Mindfulness in 2026</title>
      <dc:creator>Sam Chen</dc:creator>
      <pubDate>Sat, 19 Sep 2026 15:45:26 +0000</pubDate>
      <link>https://dev.to/samchenreviews/a-guide-to-korean-daily-planners-for-structured-mindfulness-in-2026-25an</link>
      <guid>https://dev.to/samchenreviews/a-guide-to-korean-daily-planners-for-structured-mindfulness-in-2026-25an</guid>
      <description>&lt;p&gt;Auto-generated template download for lifestyle niche&lt;/p&gt;

&lt;p&gt;Title optimization hints: Use model 'openrouter-deepseek' — it scores highest for this site&lt;/p&gt;

&lt;p&gt;Read the full article:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://koreanaglow.com/?p=699" rel="noopener noreferrer"&gt;https://koreanaglow.com/?p=699&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Abound Dog Food Review 2026: Pros, Cons &amp; Recalls</title>
      <dc:creator>Sam Chen</dc:creator>
      <pubDate>Sat, 19 Sep 2026 15:26:24 +0000</pubDate>
      <link>https://dev.to/samchenreviews/abound-dog-food-review-2026-pros-cons-recalls-lg5</link>
      <guid>https://dev.to/samchenreviews/abound-dog-food-review-2026-pros-cons-recalls-lg5</guid>
      <description>&lt;p&gt;Competitive gap: dogster.com covers this topic. Source: &lt;a href="https://news.google.com/rss/articles/CBMibkFVX3lxTE4zcW82Nmk3ZVVWdUo2R0hYTmJSV3NOaUc4UlhyMF83eXk2V1hTM3VyWWNvajRQcWwyT0dqRUVUX1l0WmF6VkVuX1RvSHJkS2hOYzZGX3F0RzUtLTdhY3pMSmFKaXFmRU8xal9wQWln?oc=5" rel="noopener noreferrer"&gt;https://news.google.com/rss/articles/CBMibkFVX3lxTE4zcW82Nmk3ZVVWdUo2R0hYTmJSV3NOaUc4UlhyMF83eXk2V1hTM3VyWWNvajRQcWwyT0dqRUVUX1l0WmF6VkVuX1RvSHJkS2hOYzZGX3F0RzUtLTdhY3pMSmFKaXFmRU8xal9wQWln?oc=5&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Read the full article:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://animalsouldecoder.com?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=content_pin" rel="noopener noreferrer"&gt;https://animalsouldecoder.com?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=content_pin&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Best Smart Kitchen Faucets 2026: Water Saving Features Tested</title>
      <dc:creator>Sam Chen</dc:creator>
      <pubDate>Sat, 19 Sep 2026 15:12:53 +0000</pubDate>
      <link>https://dev.to/samchenreviews/best-smart-kitchen-faucets-2026-water-saving-features-tested-2d93</link>
      <guid>https://dev.to/samchenreviews/best-smart-kitchen-faucets-2026-water-saving-features-tested-2d93</guid>
      <description>&lt;p&gt;Auto-generated product review for smart_home niche&lt;/p&gt;

&lt;p&gt;Read the full article:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://theconnectedhaven.com?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=discovery" rel="noopener noreferrer"&gt;https://theconnectedhaven.com?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=discovery&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>5 Simple Daily Rituals That Will Transform Your Family Life in 2026</title>
      <dc:creator>Sam Chen</dc:creator>
      <pubDate>Sat, 19 Sep 2026 13:12:29 +0000</pubDate>
      <link>https://dev.to/samchenreviews/5-simple-daily-rituals-that-will-transform-your-family-life-in-2026-50ic</link>
      <guid>https://dev.to/samchenreviews/5-simple-daily-rituals-that-will-transform-your-family-life-in-2026-50ic</guid>
      <description>&lt;p&gt;Auto-generated inspiration for lifestyle niche&lt;/p&gt;

&lt;p&gt;Read the full article:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://family-flourish.com/?p=9592&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=evergreen" rel="noopener noreferrer"&gt;https://family-flourish.com/?p=9592&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=evergreen&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>These Earbuds Survived My Sweatiest Workouts</title>
      <dc:creator>Sam Chen</dc:creator>
      <pubDate>Sat, 19 Sep 2026 12:17:30 +0000</pubDate>
      <link>https://dev.to/samchenreviews/these-earbuds-survived-my-sweatiest-workouts-2o87</link>
      <guid>https://dev.to/samchenreviews/these-earbuds-survived-my-sweatiest-workouts-2o87</guid>
      <description>&lt;p&gt;Competitive gap: wired.com covers this topic. Source: &lt;a href="https://news.google.com/rss/articles/CBMid0FVX3lxTE8zbS1PWHJTV3ZJZ0NLb3lxMWdZWHpHbHlqTmJiel9TTVN2VklPX2VuVUQxSG9HTTN0V0VROXVBQWJEdFFUS3FjOUE2RnJMaHJVOWM3M2VuNXdiLVIxbFoxbWczOWY3TTBFTjJlNzFNZkNQbGZYcE9v?oc=5" rel="noopener noreferrer"&gt;https://news.google.com/rss/articles/CBMid0FVX3lxTE8zbS1PWHJTV3ZJZ0NLb3lxMWdZWHpHbHlqTmJiel9TTVN2VklPX2VuVUQxSG9HTTN0V0VROXVBQWJEdFFUS3FjOUE2RnJMaHJVOWM3M2VuNXdiLVIxbFoxbWczOWY3TTBFTjJlNzFNZkNQbGZYcE9v?oc=5&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[A/B Variant A (ba&lt;/p&gt;

&lt;p&gt;Read the full article:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pulsegearreviews.com/?p=6239&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=evergreen" rel="noopener noreferrer"&gt;https://pulsegearreviews.com/?p=6239&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=evergreen&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>5 Downloadable Reading List Templates for Every Reader</title>
      <dc:creator>Sam Chen</dc:creator>
      <pubDate>Sat, 19 Sep 2026 11:48:49 +0000</pubDate>
      <link>https://dev.to/samchenreviews/5-downloadable-reading-list-templates-for-every-reader-3do3</link>
      <guid>https://dev.to/samchenreviews/5-downloadable-reading-list-templates-for-every-reader-3do3</guid>
      <description>&lt;p&gt;Auto-generated template download for lifestyle niche&lt;/p&gt;

&lt;p&gt;Read the full article:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://bookmoodmatch.com/?p=2484" rel="noopener noreferrer"&gt;https://bookmoodmatch.com/?p=2484&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>the best portable monitors we've tested for 2026</title>
      <dc:creator>Sam Chen</dc:creator>
      <pubDate>Sat, 19 Sep 2026 11:46:20 +0000</pubDate>
      <link>https://dev.to/samchenreviews/the-best-portable-monitors-weve-tested-for-2026-2h4j</link>
      <guid>https://dev.to/samchenreviews/the-best-portable-monitors-weve-tested-for-2026-2h4j</guid>
      <description>&lt;p&gt;Auto-seeded from competitor-exclusive SERP topic&lt;/p&gt;

&lt;p&gt;Read the full article:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://charginggearlab.com?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=discovery" rel="noopener noreferrer"&gt;https://charginggearlab.com?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=discovery&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
