YouTubeShortsBot
YouTubeShortsBot
An automated, multi-platform bot that generates short‑story videos with AI and publishes them on a schedule to YouTube, Facebook, and Instagram.
The bot generates original horror/mystery stories with Google Gemini, turns them into vertical (9:16) videos with on‑screen text and narration, and uploads them automatically at configured times throughout the day. It supports two formats:
- Shorts – ~20s clips with the story text overlaid on a random background video and music.
- Long videos – ~5‑minute narrated stories built with FFmpeg, using Google Cloud Text‑to‑Speech for voiceover.
Features
- 🤖 AI story generation via Google Gemini (
gemini-2.5-flash) across a wide range of horror/mystery categories, with built‑in fallback stories if the API is unavailable. - 🎬 Short video creation using MoviePy: random background video + audio track + title/story text overlay, rendered to 1080×1920.
- 🎙️ Long video creation using FFmpeg with Google Cloud TTS narration and background music mixing.
- 📤 Multi-platform publishing to YouTube (resumable upload), Facebook Reels (chunked upload), and Instagram (stub — see notes).
- ⏰ Scheduling of uploads at configurable times (IST), with automatic Facebook long‑lived token refresh every 55 days.
- 🐳 Docker support with FFmpeg bundled in the image.
Project structure
.
├── main.py # Entry point: scheduling, orchestration, token refresh
├── story_generator.py # Gemini story generation (short & long) + fallbacks
├── video_creator.py # Short videos (MoviePy) + long video orchestration & Google TTS
├── ffmpeg_video_creator.py # Long video rendering via raw FFmpeg
├── platform_uploaders.py # YouTube / Facebook / Instagram uploaders
├── config/
│ └── constants.py # Paths, scopes, fallback stories
├── assets/
│ ├── background_videos/ # Background clips (.mp4/.avi/.mov/.mkv)
│ ├── audio_tracks/ # Background music (.mp3/.wav/.aac)
│ └── fonts/ # TTF fonts used for text overlays
├── data/ # Generated output (videos, audio) — gitignored
├── requirements.txt
├── Dockerfile
└── Jenkinsfile
Requirements
- Python 3.12+
- FFmpeg and
ffprobeavailable onPATH(required for long videos) - Python dependencies in
requirements.txt:moviepy,google-auth,google-api-python-client,google-auth-oauthlib,requests,pytz,schedule,python-dotenv,google-genai,google-cloud-texttospeech,google-cloud-storage
Setup
-
Clone and install dependencies
git clone https://github.com/sumannath/YouTubeShortsBot.git cd YouTubeShortsBot pip install -r requirements.txt -
Add assets to the
assets/directory:- One or more background videos in
assets/background_videos/ - One or more background music tracks in
assets/audio_tracks/ - A TTF font in
assets/fonts/(referenced byFONT_PATH)
- One or more background videos in
-
Configure credentials in
config/:config/.env— environment variables (see below)config/client_secret.json— Google OAuth client secrets for the YouTube Data API. On first run a browser flow generatesconfig/yt_token.json.
-
Google Cloud (required for long videos): enable the Text‑to‑Speech and Cloud Storage APIs, create a bucket for synthesized audio, and authenticate (e.g. set
GOOGLE_APPLICATION_CREDENTIALSto a service‑account key).
Configuration
Create config/.env with the variables your enabled platforms and formats need.
Core
| Variable | Default | Description |
|---|---|---|
ENABLED_PLATFORMS | youtube | Comma‑separated list: youtube, facebook, instagram. |
VIDEO_TYPES | short | Comma‑separated: short, long. |
SHORTS_UPLOAD_TIMES | — | Comma‑separated HH:MM times (IST) for short uploads. |
LONG_UPLOAD_TIMES | — | Comma‑separated HH:MM times (IST) for long uploads. |
FONT_PATH | — | Required. Font filename inside assets/fonts/ used for overlays. |
CLIP_DURATION | 20 | Short video length in seconds. |
Story generation
| Variable | Description |
|---|---|
GOOGLE_GEMINI_API_KEY | Gemini API key. If unset, fallback stories are used. |
Google Cloud TTS / Storage (long videos)
| Variable | Description |
|---|---|
GCP_PROJECT_ID | Google Cloud project ID. |
GCP_BUCKET_REGION | Location for the long‑audio synthesis (e.g. us-central1). |
GCP_BUCKET_NAME | Cloud Storage bucket for synthesized audio. |
GCP_BUCKET_AUDIO_PATH | Path/prefix within the bucket for audio output. |
| Variable | Description |
|---|---|
FACEBOOK_ACCESS_TOKEN | Long‑lived user access token (auto‑refreshed every 55 days). |
FACEBOOK_APP_ID | Facebook app ID. |
FACEBOOK_APP_SECRET | Facebook app secret. |
FACEBOOK_PAGE_ID | Target page ID for Reels. |
| Variable | Description |
|---|---|
INSTAGRAM_ACCESS_TOKEN | Instagram access token. |
INSTAGRAM_ACCOUNT_ID | Instagram account ID. |
Note: The Instagram uploader is currently a placeholder/stub and does not yet perform real uploads.
Usage
python main.pyOn startup the bot:
- Loads
config/.envand validates required variables. - Runs an initial Facebook token refresh and generates/uploads one long video (useful for testing).
- Enters the scheduler loop, publishing shorts and long videos at the configured
*_UPLOAD_TIMESand refreshing the Facebook token every 55 days at 03:00.
Successfully uploaded local video files are deleted automatically; the loop continues running until interrupted (Ctrl+C).
Docker
docker build -t youtubeshortsbot .
docker run --rm \
-v "$(pwd)/config:/app/config" \
-v "$(pwd)/assets:/app/assets" \
-v "$(pwd)/data:/app/data" \
youtubeshortsbotThe image is based on python:3.12-slim and installs FFmpeg and required system libraries.
License
No license file is currently included. Add one if you intend others to reuse this code.