Python script · 2024
Post a random video to Instagram every day
I made this script to keep re-uploading the 50 videos I had, hoping to get pushed by the algorithm. It pulls a random video from an AWS S3 bucket and uploads it to Instagram as a Reel. Captions and hashtags are added randomly. You can use it for free and change it to fit your needs.
What the script does
- Checks the log file to see how many videos were uploaded today. After 2, it stops.
- Picks a random video from your S3 bucket.
- Picks a random caption from a text file and three random hashtags from a list in the script.
- Creates the Reel through the Instagram Graph API, publishes it and writes today’s date to the log.
- Waits 2 minutes before the next upload.
This script only handles Instagram. I did not include a YouTube uploader here.
Setup
Put these files in one folder:
- instagram_uploader.py: the script below
- aws_config.txt: one
key=valueper line withaws_access_key_id,aws_secret_access_keyandregion - instagram_config.txt: one
key=valueper line withINSTAGRAM_ACCOUNT_IDandACCESS_TOKEN - descriptions.txt: one caption per line
- upload_log.txt: leave it empty, the script fills it
Install the libraries with pip install requests boto3, replace the bucket name and hashtags in the script, and run it once a day, for example with a scheduler.
Good to know
- Instagram has to download the video from a public URL. The script builds a public S3 link, so the videos in your bucket must be publicly readable.
- Never publish your AWS or Instagram keys, and keep the config files out of any public repository.
- The script calls version 18 of the Meta Graph API, which I used in 2024. Meta changes its API, so check the current documentation if uploads fail.
- Some messages in the script are in German, because I wrote it for my own use.
- Posting the same videos over and over may go against the platform’s rules or hurt your reach, so use it carefully.
I plan to make a YouTube video that walks through each step, and I have started a guidebook that explains how to get the credentials and what the code does in detail. I just haven’t had the time to finish it yet.
The script
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"
# Log-Datei
LOG_FILE = "upload_log.txt"
# 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
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()
This post may contain affiliate links. These links are marked with an * and I may earn a commission from qualifying purchases.