How to automate Twitter and make a bit of a tit of yourself at the same time …

Free twitter badge

Free twitter badge (Photo credit: Wikipedia)

Oh dear, oh dear – post in haste repent at leisure ! ( If you don’t know what I’m talking about – see here. ) I’m glad to say that I recently read a book1 on business that suggested that an Agile approach ( release early, release often, and fix your bugs as you go along ) was definitely  the way towards successful business, so I’m going to imply that I did it on purpose.

So what’s gone wrong ? I can see that the script ( twitter.py -r )is running fine from cron ( /var/log/cron – it appears to run every five minutes ) – I know that if I run it from the command line within 5 minutes of creating the schedule that it works, that implies that the logic in the program ( if badly written ) is at least ok … So where is the issue occurring ? I thought initially that it was a path problem – I guess that my fault so far is that I’ve not made any effort to capture any errors. Ok, so I’ll give that a go … Great, nada being reported by cron. That’s not helpful.

Ah hah ! Got an error at last.

tweepy.error.TweepError: Status is a duplicate.

Whilst I can’t find any specific references to the error, it seems to me to be quite self explanatory. You can’t keep re-tweeting the same message – it needs to differ. That explains why the HootSuite interface was such a pain in the neck as they offload this onto the user to populate their CSV file with. I guess that the outstanding question then is “How much does a Tweet need to differ by _not_ to be considered a duplicate ?” by definition this should be a single char, so, for my 24 scheduled tweets I need to create 24 unique chars to add to the tweet. The simplest way would be to either count up or count down, this would hopefully give sufficent change to be different, as well as indicating easily to me, if not the casual observer, how far through the re-Tweet lifecycle it currently is.

The code now reads as follows:

#!/usr/bin/env python
##########################
# Python Auto Re-Tweeter #
# (C) Simon Biles 2012   #
# http://www.biles.net   #
##########################
# Version 0.01 -         #
# A first stab at it !   #
##########################
# Version 0.02 -         #
# A working version !    #
##########################

# All those tasty Python imports
import argparse
import datetime
import struct
import sys
import tweepy

from ConfigParser import SafeConfigParser

# Get the command line arguments
parser = argparse.ArgumentParser(description='Regular Tweet Generator.')
parser.add_argument('-s','--schedule', action='store_true', help='Schedule a Tweet for the next 7 days')
parser.add_argument('-r', '--run', action='store_true', help='Run the schedule')
parser.add_argument('-u','--update', action='store_true', help='Update Status Tweet immediately')
parser.add_argument('tweet', nargs='?')
args = parser.parse_args();

# Global variable
time_fmt = "%Y-%m-%d %H:%M"

# Get the config file data
parser = SafeConfigParser()
parser.read('twitter.conf')
CONSUMER_KEY = parser.get('consumer_keys','CONSUMER_KEY')
CONSUMER_SECRET = parser.get('consumer_keys','CONSUMER_SECRET')
ACCESS_KEY = parser.get('access_keys','ACCESS_KEY')
ACCESS_SECRET = parser.get('access_keys','ACCESS_SECRET')
FILE_NAME = parser.get('file_name', 'SCHEDULE_FILE')

# Main body

# Quick Command Line Update
if args.run == False and args.schedule == False and args.update == True:
   auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
   auth.set_access_token(ACCESS_KEY, ACCESS_SECRET)
   api = tweepy.API(auth)
   api.update_status(sys.argv[1])
   sys.exit()
# Schedule a Tweet by adding it to the schedule file
elif args.run == False and args.schedule == True and args.update == False:
   file_obj = open(FILE_NAME, 'a')
   current = datetime.datetime.now()
   nexttweet = current;
   count = 0
   while (count < 24):
      diff = datetime.timedelta(hours=count)
      nexttweet = nexttweet + diff
      tweettime = nexttweet.strftime(time_fmt) + " " + str(count+1) + "/24 " + args.tweet +"\n"
      file_obj.write(tweettime)
      count = count + 1
   file_obj.close 
   sys.exit() 
# Parse the schedule file and see if anything should have happend within 5 minutes of now.
elif args.run == True and args.schedule == False and args.update == False:
   file_obj = open(FILE_NAME, 'r')
   auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
   auth.set_access_token(ACCESS_KEY, ACCESS_SECRET)
   api = tweepy.API(auth)
   current = datetime.datetime.now()
   baseformat = "16s 1x"
   for line in file_obj:
      line = line.rstrip('\n')
      numremain = len(line) - struct.calcsize(baseformat)
      lformat = "%s %ds" % (baseformat, numremain)
      tweettime, tweet = struct.unpack(lformat, line)
      linetime = datetime.datetime.strptime(tweettime, time_fmt)
      delta = linetime - current
      if delta <= datetime.timedelta(minutes=5) and delta >= datetime.timedelta(minutes=-5):
         if delta <= datetime.timedelta(minutes=5):
            api.update_status(tweet)
   file_obj.close
   sys.exit()

So there you have it, a working version ! I’ve watched 10/24 Tweets fly by over the weekend, and the other 14 will play out over the next week and a bit – I must admit though that it is a bit front loaded at the moment, and behaves a little “spamily” for my liking. I think before I unleash it again, I might start it off at 6 hour intervals and let it grow from there for 18 Tweets. I’m thinking of how to track it’s success, and I have an idea, but more of that later !

 


1. The book is question was ReWork: Change the Way You Work Forever. Which I rather enjoyed, it was short and to the point – I don’t think that it is necessarily a “how-to” guide, but did get me thinking about a few things and gave me some inspiration to go out on the web and make a tit of myself like this 😉

Tagged , , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: