The Story behind
Most of my time is spent on Instagram and I use it mostly for the memes.
So, some of my friends told me that most of the memes are uploaded to Reddit and later spread to Instagram, and Reddit was the best place to go for funny content but I wasn't a big fan of the Reddit UI and didn't really get used to it.
One day I randomly thought, what if I could start a meme page that gets content from Reddit but without downloading and uploading the images manually and still be the first account to upload those memes on Instagram straight from Reddit?
And, I Built a BOT which uploads memes from some subreddits like r/dankmemes and r/memes and uploads it on my Instagram account - @thiru.bot
How did I do it?
At this stage, I was a beginner and knew few things about python, had some experience building flask apps, had some experience in web scrapping and had huge hunger to build this just to flex my skills with my friends.
Before I started building it I had to visualize what I needed?
- Reddit API & Basics of web scrapping to get the images and save them.
- Any Instagram API which lets me upload photos to my account.
- A server to host this later to make it work 24/7
Friends, When you are a beginner you just google things, mix code from different repositories, add your own code and make it work.
and that's what I did!
There were no Instagram Reddit bot but I found a Reddit to twitter project which gave me a clarity of thought in building this.
The Working Instagram API
The Official Instagram API doesn't allow developers to upload photos or videos to post. Most of the other third party APIs also dint work but at last found this pip package.
pip install instabot
Later Tested if this worked by giving my Instagram credentials and uploaded a random photo from my computer.
from instabot import Bot
bot=Bot()
bot.login(username="thiru.jpg",password="followMeOnInstagram")
bot.upload_photo('hey.png',caption=("Test Upload "))
and it worked :)
Next step - Scrapping the latest images from subreddits
Getting Images from Reddit
To get the latest submissions from our subreddits we will be using PRAW API from subreddit. it's pretty simple not to worry.
Setting up Praw API
reddit = praw.Reddit(client_id='',
client_secret='',
username='',
password='',
user_agent='')
Creating an Reddit App
To Fill the above details you need to create an app on Reddit, Just Open https://ssl.reddit.com/prefs/apps/ and click on create app.
I am here creating an app with the name test app. Client_Id parameter (the one which is below personal use script in the image above), client_secret is the secret key available. For username and password give your Reddit username and password. User Agent can be blank or chrome.
Setting up subreddits to get memes
red='dankmemes'
subreddit = reddit.subreddit(red)
newMemes = subreddit.hot(limit=3)
I choose the subreddit 'dankmemes' and ** NewMemess ** Praw Class has all the hottest submissions from the subreddit.
You can get any type of submissions
(refer to official documentation here )
Validating and Picking only Photos
for submission in new_memes:
if submission.is_self == True:
print("Post was text, skipping to next post.")
continue
else:
pass
url = submission.url
time.sleep(waitTime)
You want just photos to upload.
So, You need to validate them and choose only the submissions which have photos.
Downloading the images
Before Storing the images from Reddit we check Two Things
- if the submission is an Video/text or an image using isImageLink(url) Function and it returns the extension name of the image(Eg: jpg,png)
- If the image was posted before using already_uploaded(id) function so that we don't post the same memes again.
You can check out those functions and full code on my GitHub Repo here also follow me on GitHub.
if isImageLink(url) and not already_uploaded(id):
try:
img=requests.get(submission.url)
filename=str(counter)+'.'+IsImageLink(submission.url)
filename=os.path.join('images', filename)
imagefile=open(filename, 'wb')
imagefile.write(img.content)
imagefile.close()
post_ids.append(submission.id) # A list of all submission ids
log_insta(post_ids)
photoAlbum.append({'File':filename, 'Title':submission.title})
#dictionary of all photos
counter+=1
except Exception as e:
print(e)
After checking, You can download the image and save it with the count+ the extension (Eg: 2.png or 3.jpg).
Later you save a list with all the post id.
Remember you had to check if the post was already uploaded. How will it know if it is posted already?
Yes, you will be logging the post_id of the image using the function ** log_insta(post_ids)**
def log_insta(post_ids):
for post_id in post_ids:
with open(POSTED_CACHE, 'a') as out_file:
out_file.write(str(post_id) + '\n')
Downloading the images from Imgur
Some Redditors upload photos to Imgur, and to download those images, You will using beautifulSoup and scrape data from those submissions. After you download, the saving part is same as above so I won't be posting the whole code.
elif str(submission.url).lower().startswith('https://imgur.com') or str(submission.url).lower().startswith('http://imgur.com') and counter<max_images:
try:
html_page = urllib.request.urlopen(submission.url)
soup = BeautifulSoup(html_page, 'lxml')
images = []
for img in soup.findAll('img'):
images.append('https:'+img.get('src'))
img=requests.get(images[0])
filename=str(counter)+'.'+images[0][-3:]
Downloaded the images, What next?
Now that we have all the 3 images in the photo album Dictionary with the File and Title we can upload it to instagram using our *** unofficial Instagram API *** and give credits to the authors,subreddit and also add captionTags.
authors = ''.join(str(e + ', ') for e in authors)
captionTags='#binod #memes #dank'
for photo in photoAlbum:
img=photo['File']
captionText=photo['Title']
bot.upload_photo(img,caption=(captionText + '\n' +'Reddit Authors:'+authors+'\n' captionTags))
Later we delete the image we downloaded just not to waste disk space.
for filename in glob(filePath + '/*'):
os.remove(filename)
** Now Put all this code together into a single Python File, Run it and Hola, You have now uploaded a meme from Reddit to Instagram from your Python Code ** In my case, I named the file bot.py, thought of telling you this as this might be useful later in the deployment part.
But the bot.py is run on the local machine and we can't just run this 24/7 on our local machine. Any Fix?
Deployment
To Run The Bot in a server for 24/7 you need to deploy this to cloud.
I used Heroku to deploy this Instagram meme bot. Follow this article to set up a Heroku account and know the basics of Heroku. I will soon be writing an article on the same.How to Upload Flask apps to Heroku .
You need 3 files to be created for the deployment of your bot into Heroku .
- ProcFile
- Runtime.txt
- Requirements.txt
** Runtime.txt **
python-3.7.3
In *** Runtime.txt *** you specify what language your code is in.
** The ProcFile **
web: python3 bot.py
worker: python3 bot.py
Here you will be specifying the python file to be run by the dynos and note that I created two of these just to make sure one of them always stays on and doesn't sleep. You later need to scale them.
** Requirements.txt **
imageio==2.4.1
praw
requests
urllib3
keyboard
pillow
beautifulsoup4
instabot
Heroku in simple words creates a virtual machine so you need to mention what are the packages you want to install for your bot.py to work.
After Uploading these files into a single folder. It's time to scale your dynos
heroku ps:scale web=1 worker=1
A working meme BOT
But yeah , I need to work on the followers count lol.
Problems & Suggestions
- Instagram Detecting Bots
- Upload Frequency
- Heroku Running out of Credits
- Dynamic Tags
Instagram Detecting Bots
Instagram DOES NOT like Bots.
Initially, when I started this, my bot was detected and banned for 1 day and was not allowed to use any Instagram features like liking, etc for 1 week.
Solution which worked for me
It took me weeks to crack this but the reason why my bot was getting detected is that my posts were only from one subreddit and the authors were mostly same and hashtags as well so every post had somethings similar and with same upload frequency and Instagram started detecting.
With no options left, I had to stop giving credits to authors in the caption and created a list of subreddits and used ** random ** function in Python to select one subreddit and stoped using tags which fixed the issue.Upload frequency also matters and I will be speaking about it in the next paragraphs.
Upload Frequency
How many Posts should you upload at a time?
How many hours once should you upload?
The safe bet is ** 3 posts /hour **
Heroku Running out of credits
Heroku gives 550 hours of free dynos when you create an account. I had used all the 550 dynos and all my projects on Heroku had shut down, luckily I gave my credit card information and was able to get an extra 450 hours of dynos, But that won't be sufficient if you want to run this bot forever as 30 days = 1800 hours.
I usually was turning off the dynos when I was going to sleep and turning it on when required so worked. This is the solution that worked out for me and just to remind you, this is hosted for completely free of cost so nothing to complain.
Dynamic Tags
So, removing tags helped with not getting banned but I wanted better reach as my account had just 3 followers from weeks so created multiple lists of ** trending hashtags ** and wrote a code to choose the hashtags according to the subreddit and its working great.
What Did we learn from this?
- You Don't need to know everything to start building things. Just the Hunger is enough.
- The results don't come just in the first iteration. Experiment Fix experiment.
- You can't get a girlfriend by creating a Meme bot :(
Github Repository
I still haven't added a ReadMe file(working on it). But this article is sufficient to understand the working of the same.
** Here is the complete Code - GitHub Repo **
Top comments (0)