How to Schedule Your Twitter Account Posts

Do People Ever Sleep? Have you ever wondered how businesses stay at the top of your Twitter feed? Yeah, me too. It turns out they don’t actually make those posts everyday. They use a company like Crowdfire to schedule their posts! Who cares how it got there as long as the content is relevant to you right? I mean….it’s not like my boss would be thrilled to see me Tweeting incessantly during the morning meeting.

How To Be A Lazy Tweeter

Forget paying Crowdfire, I can be lazy without losing money. It’s not really lazy if I’ve spent some of my vacation (while there’s a blizzard outside) hammering away at an app that automates my Twitter account right? Nope. Not lazy here.

First, let’s discuss the method. We already know about Tweepy from a previous blog post and we know that Tweepy’s api.update_status(‘someText’) really takes care of the tough part of posting. How should we approach the scheduling? Since Python has such a lovely community, I found an amazing package! pip install schedule.



It Can’t Be This Easy…

Or maybe it can be. Let’s define our features first before we get to the code.

Features I need:

  • app that can ingest a list of URLs, Image URLs, Catchy Text and Twitter Handles
  • able to schedule posts on days of the week, every hour, every minute (you get the idea)
  • some way to space out our posts so people don’t think we’re a robot?
  • maybe we can crawl our own website to update itself? Have you checked out this blogpost?

"""--------------The Process------------
Tweepy ref - http://docs.tweepy.org/en/v3.5.0/api.html
0. Get a twitter account and create a new app -- apps.twitter.com
1. Crawl your own website and make a list of URLs you will want to tweet out
2. Create the Scheduler function
3. Create the Post function
4. Integrate a timer function
5. Drink a beer while you watch it post
-------------------------------------
You will need the below for this to work (apps.twitter.com)
-------------------------------------
Consumer Key (API Key)	        
Consumer Secret (API Secret)	
Access Token	        
Access Token Secret
-------------------------------------



Make The Schedule Function

Let’s make the function called runAMLautoPoster() and the subsequent makeSchedule(job,interval). In runAMLautoPoster() you will notice that the “interval” variable is being sent a number and unit as a string (i.e. ’30min’, ‘5hr’). It’s important for your program to be half-smart about the time interval.


def runAMLautoPoster():
"""the RUN function for Automate My Lifes automated Twitter Scheduler"""
###this is a twitter post job
interval = '30min'
job = tweetScheduled
makeSchedule(job,interval)
###this is a schedule to check for new posts on RSS feed
interval = '10:30wed'
job = makeLinkList

 

Thanks to Daniel Bader @dbader for making the Schedule module so Pythonic, you can now create a function like makeSchedule(job,interval) that totally makes sense.

    
def makeSchedule(job,interval):
"""Morning, Afternoon or Evening"""
if 'sec' in interval:
print "Scheduling ",interval
interval = int(interval.replace('sec',''))
print interval
schedule.every(interval).seconds.do(job)
elif 'min' in interval:
print "Scheduling ",interval
interval = int(interval.replace('min',''))
schedule.every(interval).minutes.do(job)
elif 'hr' in interval:
print "Scheduling ",interval
interval = int(interval.replace('hr',''))
schedule.every(interval).hours.do(job)
elif ':' in interval and 'each' in interval:
print "Scheduling ",interval
#interval formal 10:30
interval = interval.replace('each','')
schedule.every().day.at(interval).do(job)
elif 'mon' in interval:
print "Scheduling ",interval
interval = interval.replace('mon','')
schedule.every().monday.do(job)
elif ':' in interval and 'wed' in interval:
print "scheduling ",interval
interval = interval.replace('wed','')
print interval
schedule.every().wednesday.at(interval).do(job)
while True:
schedule.run_pending()

 

Now Let’s Tweet Something

Tweepy makes it crazy simple to post using api.update_status(‘someText’) or if you want to add an image, api.update_with_media(fileName,status=message). I created two separate functions to handle it just because typing tweet(‘xyz’) takes less time. Lazy programming is focused programming.

tweet_image() does some fancy bits by fetching the URL for you, creating a local image file on your computer, uploading that to Twitter and finish by deleting the temporary file. That whole process is wrapped up in the function getImageAndSave(url).

def tweet_image(url, message):
filename = 'temp.jpg'
request = requests.get(url, verify=False,stream=True)
if request.status_code == 200:
imageName = getImageAndSave(url)
raw_input("hold before posting")
api.update_with_media(filename, status=message)
os.remove(filename)
else:
print("Unable to download image")

 

Major Operations

Now that we have the Schedule function and the Tweet functions, let’s talk about the main function that does most of the work called tweetScheduled(). Remember that one of our features required the ability to ingest a URL and text from an input source? We’re going to create an input CSV file that contains a list of all the URLs to my blog post, the links to the related images, and also the text. Using that CSV, Python will read it in as a Pandas dataframe and loop through each line and post to Twitter for us!! Below is the last method to Tweet the scheduled posts.

Happy Lazy Tweeting

-j

*Note: if you want to run your script as a daemon on a Linux server use the command:

…$ nohup nice python <yourScriptName> &

 

def tweetScheduled():
"""function used to send scheduled posts"""
countT = 2
c=0
alreadyTweeted = []
#get the visitedLinks database
##headers should be [index,Links,StartText,EndText,imageURL]
visitedLinks = pd.read_csv('visitedLinks.csv')
#put the urls 
#loop through links and use time to stagger posts
for index,schedText in visitedLinks.iterrows():
#don't tweet an infinite loop
print c
if c == len(visitedLinks):
print "All links have been tweeted...\n\n"
return
else:
if schedText['Links'] != '':
#in case something goes wrong ensure a tweet
try:
#i = countT - 1
url = schedText['Links']
imageURL = schedText['imageURL']
startText = schedText['StartText']#randomPhraseList[i]
endText = schedText['EndText']#closing[i]
newText = startText+ " " +endText+" "+url+""
if newText not in alreadyTweeted:
alreadyTweeted.append(newText)
#check to see if there is an image
if imageURL != '':
raw_input("hold")
#post containing image
#api.update_with_media(imageURL,status=newText)
tweet_image(imageURL,newText)
else:
raw_input("hold")
#post with no image
api.update_status(newText)
#send a message confirming it worked
print "You just tweeted: ",newText
else:
print "You already tweeted: ",newText
except Exception,e:
print str(e)
print "There was an erorr in the posting"
raw_input("Please review...<ENTER>")
print "\nStaggering..."
time.sleep(timeDelay)
else:
print "I dont tweet blank stuff..."
countT += 1
c += 1

 

 

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *