skip to Main Content

I want to post on Instagram using Facebook Graph API. To post image, it require URL of image saved in public server. Below is the python code which I am using –

def postInstagram():
post_url = "https://graph.facebook.com/my_id/media"

payload = {
    "image_url": image_url,
    "caption": my_caption,
    "access_token": my_token}
r = requests.post(post_url, data=payload)

result = json.loads(r.text)
if 'id' in result:
    creation_id = result['id']

    second_url = "https://graph.facebook.com/v13.0/my_id/media_publish"
    second_payload = {
        "creation_id": creation_id,
        "access_token": "my_token"
    }
    r = requests.post(second_url, data=second_payload)

But I want to post image directly by uploading it from my local device and not by URL. I don’t know how to do that. Please help me.

2

Answers


  1. Official documentation says URL should be a public one

    Login or Signup to reply.
  2. So google search brought me here and I have a good answer for this but I assume that the OP doesn’t use StackOverflow anymore as this question is years old. However for anyone else running into this issue you can use ngrok for this.

    1. Download and install ngrok. (If you are on windows and you download ngrok just have the exe in the same directory. If you are using linux download and install ngrok from your repo using apt-get, or yum, or snap depending on your linux flavor)

    2. Run http server and ngrok then your pictures will be servable to instagram.

    3. Instagram will take the url and get the picture.

    4. Once its done immediately close the http and ngrok server.

    Here is a python example that worked for me perfectly. You MUST have ngrok installed and you MUST get your api key (user token or app token……I hate meta’s token stuff. It took forever for me to understand. lol).

    import requests
    import http.server
    import socketserver
    import threading
    import subprocess
    import time
    import json
    
    # Start a simple HTTP server in a new thread
    PORT = 8000
    Handler = http.server.SimpleHTTPRequestHandler
    httpd = socketserver.TCPServer(("", PORT), Handler)
    thread = threading.Thread(target=httpd.serve_forever)
    thread.start()
    
    # Start ngrok
    ngrok = subprocess.Popen(["ngrok", "http", str(PORT)], stdout=subprocess.PIPE)
    
    # Give ngrok time to start up
    time.sleep(2)
    
    # Get the public URL from ngrok
    resp = requests.get("http://localhost:4040/api/tunnels")
    public_url = resp.json()["tunnels"][0]["public_url"]
    
    # Now you can use the public URL to access your local images
    image_url = public_url + "/test.jpg"
    print(image_url)
    
    access_token = "ENTER_ACCESS_TOKEN"
    
    def create_container(access_token, image_url, caption):
        url = "https://graph.facebook.com/v17.0/ENTER_INSTAGRAM_ID/media"
        payload = {
            "image_url": image_url,
            "caption": caption,
            "access_token": access_token
        }
        response = requests.post(url, params=payload)
        data = response.json()
        print(data)
        return data["id"]
    
    def publish_photo(access_token, creation_id):
        url = "https://graph.facebook.com/v17.0/ENTER_INSTAGRAM_ID/media_publish"
        payload = {
            "creation_id": creation_id,
            "access_token": access_token
        }
        response = requests.post(url, params=payload)
        data = response.json()
        print(data)
    
    caption = "ENTER_CAPTION"
    
    # get_instagram_media(access_token)
    creation_id = create_container(access_token, image_url, caption)
    publish_photo(access_token, creation_id)
    
    # Remember to stop ngrok and the HTTP server when you're done
    ngrok.terminate()
    httpd.shutdown()
    

    Remember to replace test.jpg with your actual photo.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search