YouTube/ Instagram Auto Uploader (2024)
To automate the upload of YouTube shorts and Instagram reels, I created a custom python script. I will provide the full code for download here. I also created a file tree that you can copy.
The script works by pulling a random video from an AWS S3 bucket and uploading it to instagram. You can also add captions and hashtags that will be added randomly. I made this script to constantly re-upload the 50 videos I had, for a chance to get pushed by the algorithm.
If this is what you’re looking for, you came to the right place. You can access the script for free and modify it to your needs.
Create four files:
- instagram_uploader.py
- aws_config.txt
- intsagram_config.txt
- upload_log.txt
The code I will provide is for the instagram_uploader.py file. Get your credentials and fill put them in your config files. the upload_log.txt file stays empty for now.
I will make a YouTube video detailing each step in the future as well. I also started working on a guide book too. I just haven’t had the time to finish it yet.
I will go into more detail as to how you can get your credentials in my book. I will also explain the code and what it does in detail. Stay tuned.
Here’s the code:
import requests
import time
import os
import random
import boto3
import urllib.parse
from datetime import datetime
# Skriptverzeichnis ermitteln und dorthin wechseln
current_dir = os.path.dirname(os.path.abspath(__file__))
os.chdir(current_dir)
# S3-Bucket-Name
S3_BUCKET_NAME = "testbucket"
# Hashtags
HASHTAGS = [
"example", "car", "beauty", "shopping", "fashion", "trend", "nature"
]
def load_instagram_config():
config_file = "instagram_config.txt"
try:
with open(config_file, "r") as f:
config_data = {}
for line in f:
key, value = line.strip().split("=")
config_data[key.strip()] = value.strip()
return config_data
except (FileNotFoundError, ValueError):
return None
def load_aws_config():
config_file = "aws_config.txt"
try:
with open(config_file, "r") as f:
config_data = {}
for line in f:
key, value = line.strip().split("=")
config_data[key.strip()] = value.strip()
return config_data
except (FileNotFoundError, ValueError):
return None
def get_random_video_from_s3():
aws_config = load_aws_config()
if not aws_config:
return None
aws_access_key_id = aws_config.get("aws_access_key_id")
aws_secret_access_key = aws_config.get("aws_secret_access_key")
region_name = aws_config.get("region")
s3 = boto3.client(
's3',
aws_access_key_id=aws_access_key_id,
aws_secret_access_key=aws_secret_access_key,
region_name=region_name
)
try:
objects = s3.list_objects_v2(Bucket=S3_BUCKET_NAME).get('Contents', [])
if not objects:
return None
random_object = random.choice(objects)
video_key = random_object['Key']
video_key = urllib.parse.quote(video_key)
video_url = f"https://{S3_BUCKET_NAME}.s3.amazonaws.com/{video_key}"
return video_url
except Exception:
return None
def get_random_caption():
captions_file = "descriptions.txt"
try:
with open(captions_file, "r") as f:
captions = f.readlines()
if not captions:
return ""
return random.choice(captions).strip()
except (FileNotFoundError, ValueError):
return ""
def get_random_hashtags():
return " ".join(random.sample(HASHTAGS, 3))
def upload_video_to_instagram(video_url):
instagram_config = load_instagram_config()
if not instagram_config:
return False
INSTAGRAM_ACCOUNT_ID = instagram_config.get("INSTAGRAM_ACCOUNT_ID")
ACCESS_TOKEN = instagram_config.get("ACCESS_TOKEN")
container_url = f"https://graph.facebook.com/v18.0/{INSTAGRAM_ACCOUNT_ID}/media"
caption = get_random_caption()
hashtags = get_random_hashtags()
caption_with_hashtags = f"{caption}\n\n{hashtags}"
container_data = {
"media_type": "REELS",
"video_url": video_url,
"caption": caption_with_hashtags,
"access_token": ACCESS_TOKEN,
"share_to_feed": "true"
}
try:
container_response = requests.post(container_url, data=container_data)
if container_response.status_code != 200:
return False
creation_id = container_response.json().get("id")
if not creation_id:
return False
publish_url = f"https://graph.facebook.com/v18.0/{INSTAGRAM_ACCOUNT_ID}/media_publish"
publish_data = {
"creation_id": creation_id,
"access_token": ACCESS_TOKEN
}
publish_response = requests.post(publish_url, data=publish_data)
return publish_response.status_code == 200
except Exception:
return False
LOG_FILE = "upload_log.txt"
def count_uploads_today():
"""Zählt die Anzahl der heutigen Uploads anhand der Log-Datei."""
if not os.path.exists(LOG_FILE):
return 0
today_date = datetime.now().date()
try:
with open(LOG_FILE, "r") as f:
uploads = [line.strip() for line in f.readlines()]
# Nur Einträge zählen, die vom heutigen Tag sind
return sum(1 for entry in uploads if entry == str(today_date))
except Exception:
return 0
def log_upload():
"""Loggt den Upload mit dem aktuellen Datum."""
with open(LOG_FILE, "a") as f:
f.write(f"{datetime.now().date()}\n")
def main():
# Prüfen, wie viele Videos heute schon hochgeladen wurden
uploads_today = count_uploads_today()
if uploads_today >= 2:
print("Tageslimit erreicht. Skript wird beendet.")
return # Skript direkt beenden
while True:
video_url = get_random_video_from_s3()
if video_url:
success = upload_video_to_instagram(video_url)
if success:
log_upload() # Upload loggen
uploads_today += 1
print(f"Video erfolgreich hochgeladen! ({uploads_today}/2 heute)")
# Nach dem Hochladen nochmal prüfen
if uploads_today >= 2:
print("Tageslimit erreicht. Skript wird beendet.")
return
time.sleep(120) # 2 Minuten warten
else:
time.sleep(120) # 2 Minuten warten, wenn kein Video gefunden wurde
if __name__ == "__main__":
main()