Skip to content

Promoting website content on Instagram with Python (and for FREE!)

Posted on:October 27, 2023 at 01:22 PM

Instagram is a popular social networking platform that allows users to share photos and videos with their followers. It is also a great way to promote your business or brand. However, manually posting content to Instagram can be time-consuming, so I found a different solution.

In this post, I will cover how I used Apps Script and Python to generate screenshots of the content of my website and automatically post them to Instagram for promotion and for FREE. Here is an example:

View this post on Instagram

A post shared by Compara.cat (@compara.cat)

The process

The process involves:

  1. Python + Selenium
  2. Apps script
  3. Instagram API

Using Selenium to create the image

There are probably multiple ways to achieve this, but here is the way I did it:

  1. Create a Python script and setup Selenium
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

# Create a headless Chrom driver
options = Options()
options.add_argument(f"--headless")
driver = webdriver.Chrome(options=options)
  1. Find the content and screenshot it!
def create_screenshot(url, element_id):
    # Load the content url
    driver.get(url) 

    # Find the element you want to capture and scroll into it. Otherwise it might be blank
    element = driver.find_element(By.ID, element_id)
    driver.execute_script("arguments[0].scrollIntoView();", driver.find_element(By.ID, element_id))

    # Take the screenshot
    element.screenshot('screenshot.png')
  1. (Optional) Add a header or decoration to the image
def add_header_to_image(image, text):  
  # Create a blank image for the header.
  header = np.zeros((100, image.shape[1], 3), dtype=np.uint8)
  
  # Set the background color of the header to yellow.
  header[:, :, :] = (7, 193, 255)

  # Add the text to the header.
  cv2.putText(header, text, (20, 60), cv2.QT_FONT_NORMAL, 1, (255, 255, 255), 2)

  # Create a new image that is the height of the header plus the height of the image.
  new_image = np.zeros((header.shape[0] + image.shape[0], image.shape[1], 3), dtype=np.uint8)

  # Copy the header to the top of the new image.
  new_image[:header.shape[0], :, :] = header

  # Copy the image to the bottom of the new image.
  new_image[header.shape[0]:, :, :] = image

Use Apps Script to automate posting to Instagram

Apps Script is an excellent free option (with some limitations) to automate stuff. The setup is the following

  1. A Google spreadsheet with the links to all the images I generated, and some AI-generated content.
  2. An Apps Script associated with the sheet.
  3. A function to get the next item in the sheet to post
  4. A function to post to Instagram
  5. A trigger to daily post the next item in the sheet :)

I will skip the first two points. Let’s check the function to find the next item:

function postOfTheDay() {
  // Get the associated spreadsheet  
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("names");
  const data = sheet.getDataRange().getValues();

  // Find the first row without and insta post id (in my case that's in the column N thus 13)
  const row = data.find((row, index) => index > 0 && !row[13]);
  
  // Create insta post
  const id = createInstagramNamePost(row)

  // Save id so we don't publish again
  sheet.getRange(data.indexOf(row) + 1, 14).setValue(id);
}

Next, is to implement the actual posting… that part was annoying because the Instagram API and onboarding are challenging. I don’t want to get into that in this post, but following this guide should help.

Let’s focus on the posting API:

function createInstagramNamePost(row) {
  // Get your Instagram Business Account ID.
  var businessAccountId = "17XXXXXXXXXXX";

  // Get access token (if expired refresh at https://developers.facebook.com/tools/debug/accesstoken/) .
  var accessToken = PropertiesService.getScriptProperties().getProperty("INSTA_TOKEN");

  // Create the caption using the info from the sheet
  const name = row[2]
  const caption = `#BuildingInPublic`

  // Url of the image hosted in a public accessible domain
  const imageUrl = row[3]
  
  // Create the media post
  var response = UrlFetchApp.fetch(
    "https://graph.facebook.com/" + businessAccountId + "/media?image_url=" + encodeURIComponent(imageUrl) + "&caption=" + encodeURIComponent(caption), 
    {
      headers: {
        Authorization: "Bearer " + accessToken
      },
      method: "post"
    }
  );

  // Use the response id to publish the post
  const mediaResponse = JSON.parse(response.getContentText());
  response = UrlFetchApp.fetch("https://graph.facebook.com/" + businessAccountId + "/media_publish?creation_id=" + mediaResponse.id, {
    headers: {
      Authorization: "Bearer " + accessToken,
    },
      method: "post"
  });

  // If succesful return the post id.
  return JSON.parse(response.getContentText()).id
}

Now, we just need to create an Apps Script trigger to run the postOfTheDay function daily (or whatever frequency you need).

And… that’s all :)

There are probably plenty of different ways to do this (and probably better ways), but this is fairly simple, and it’s for free, allowing me to spend less time promoting the content of my website and (hopefully) attract more people to the website.