ThreeDRobot : Automating Twitter

I’m really into Twitter, I’m also really into automation & procedural content. What better side project than to try my hand at a twitter bot?

@ThreeDRobot was my attempt at this.

EDIT 2017: Since this post was written, @ThreeDRobot has been taken offline for maintenance and improvement. While it was running it amassed a crisp 972 followers (which is way more than my personal account, not that I’m comparing or anything.)

Similar to @GameDevRobot, @ThreeDRobot’s goal is to foster a sense of community and conversation around topics related to 3D art and computer graphics. Whether it’s on Reddit or on Twitter, I want people to feel more connected in the 3D graphics community, especially when networking is critical to success. Being able to post to a hashtag like #3Dmodeling or #3Dprinting and knowing that there’s a good chance it’ll be seen by hundreds of people even if your follower count is pretty low; that’s the goal.

Right now I have a lowly 3 or 4 followers, but the goal is to become as big as GameDevRobot, the center of an amazing twitter community.

For fun, here’s the code I used to write up @ThreeDRobot. Hope to see you on Twitter! 🙂

 

import pytumblr
import twitter
import praw
import time

class Bot(object):
    def __init__(self):
        self.tumblr_client = tumblr_setup()
        self.twitter_client = twitter_setup()
        self.reddit_client = reddit_setup()
        #Live Code
        while True:
            self.reddit_check(1)
            self.twitter_check(1)
            print('Sleeping for 30 minutes after Cycle 1 at %s' % time.strftime("%Y-%m-%d %H:%M:%S"))
            self.log_actions(gen='Sleeping for 30 minutes at %s' % time.strftime("%Y-%m-%d %H:%M:%S"))

            time.sleep(1800)

            self.reddit_check(2)
            self.twitter_check(2)
            print('Sleeping for 30 minutes after Cycle 2 at %s' % time.strftime("%Y-%m-%d %H:%M:%S"))
            time.sleep(1800)


    def reddit_check(self, cycle):
        maya = self.reddit_client.get_subreddit('Maya')
        threema = self.reddit_client.get_subreddit('3DMA')
        blender = self.reddit_client.get_subreddit('blender')
        comp_graph = self.reddit_client.get_subreddit('computergraphics')
        modeling = self.reddit_client.get_subreddit('3Dmodeling')
        printing = self.reddit_client.get_subreddit('3dprinting')
        smax = self.reddit_client.get_subreddit('3Dsmax')
        rigging = self.reddit_client.get_subreddit('3Drigging')
        posts = []
        if cycle == 1:
            posts.append(maya.get_hot(limit=3))
            posts.append(threema.get_hot(limit=3))
            posts.append(comp_graph.get_hot(limit=3))
            posts.append(rigging.get_hot(limit=3))
        elif cycle == 2:
            posts.append(modeling.get_hot(limit=3))
            posts.append(blender.get_hot(limit=3))
            posts.append(printing.get_hot(limit=3))
            posts.append(smax.get_hot(limit=3))
        for i in range(len(posts)):
            for submission in posts[i]:
                self.tweet(submission.id, type='tweet')

    def tweet(self, sub_id, **kwargs):
        operation = kwargs.setdefault('type')
        if self.is_unique(sub_id) is True:
            if operation is 'retweet':
                try:
                    print ('Retweeting %s to twitter!' % sub_id)
                    self.twitter_client.statuses.retweet(id=sub_id)
                except twitter.TwitterHTTPError:
                    print ('%s is not sharable! :(')
            elif operation is 'tweet':
                print ('Sending %s to twitter!' % sub_id)
                content = self.get_reddit_content(sub_id)
                print content
                self.twitter_client.statuses.update(status='From r/%s: %s : %s' % (content[2], content[0][:90], content[1])) #send reddit post to twitter
                if self.user_unique(content[3]) is True:
                    self.notify_user(content[3], content[2], content[0])
            self.log_actions(time=time.strftime("%Y-%m-%d %H:%M:%S"), id=sub_id, action=operation)
        else:
            print ('Skipped %s' % sub_id)

    def twitter_check(self, cycle):
        searches = []
        if cycle == 1:
            searches.append(self.twitter_client.search.tweets(q='#3Dart'))
            searches.append(self.twitter_client.search.tweets(q='#Maya3D'))
            searches.append(self.twitter_client.search.tweets(q='#whatididtoday3D'))
            searches.append(self.twitter_client.search.tweets(q='#computergraphics'))
            searches.append(self.twitter_client.search.tweets(q='#animtip'))
        elif cycle == 2:
            searches.append(self.twitter_client.search.tweets(q='#techart'))
            searches.append(self.twitter_client.search.tweets(q='#3Drobot'))
            searches.append(self.twitter_client.search.tweets(q='#3Dmodeling'))
            searches.append(self.twitter_client.search.tweets(q='#blender3D'))
            searches.append(self.twitter_client.search.tweets(q='#rigtip'))
        for i in range(0, len(searches)):
            for k in range(0, len(searches[i]['statuses'])):
                tweet_id = searches[i]['statuses'][k]['id_str']
                self.tweet(tweet_id, type='retweet')


    def twitter_test(self):
        searches = []
        searches.append(self.twitter_client.search.tweets(q='#whatididtoday3D'))
        print searches[0]['statuses'][0]['id']


    def is_unique(self, sub_id):
        prev_submission_file = open('/Users/evancox/Documents/3D_Robot/used_sub.txt', 'r+')
        for line in prev_submission_file:
            if sub_id in line:
                return False
        prev_submission_file.write(sub_id+'\n')
        prev_submission_file.close()
        return True

    def user_unique(self, user):
        prev_user_file = open('/Users/evancox/Documents/3D_Robot/users_notified.txt', 'r+')
        for line in prev_user_file:
            if user in line:
                return False
        prev_user_file.write(user+'\n')
        prev_user_file.close()
        return True

    def get_reddit_content(self, sub_id):
        submission = self.reddit_client.get_submission(submission_id=sub_id)
        content = (submission.title, submission.short_link, submission.subreddit, submission.author)
        return content

    def get_twitter_content(self, tweet_id):
        pass

    def notify_user(self, user, subreddit, post_title):
        self.reddit_client.send_message(user, 'You\'re Famous!', 'Hey %s! I\'m @ThreeDRobot, nice to meet you! I\'m a new twitter/reddit bot aimed at promoting and fostering\
         community among 3D artists on Twitter! At %s EST today I was snooping through r/%s and found your post (%s)! I\'ve posted a link to it on Twitter if that is okay!\
          [Here\'s a link to my feed if you are interested!](http://www.twitter.com/ThreeDRobot) Either way, have a great day and keep on making great art!'
        % (user, time.strftime("%H:%M"), subreddit, post_title))


    def log_actions(self, **kwargs):
        cur_time = kwargs.setdefault('time')
        sub_id = kwargs.setdefault('id')
        action = kwargs.setdefault('action')
        general = kwargs.setdefault('gen', '')
        log_file = open('/Users/evancox/Documents/3D_Robot/log.txt', 'r+')
        if len(general) < 1:
            log_file.write('At %s: %s %s\n' % (cur_time, sub_id, action))
        else:
            log_file.write(general+'\n')
        log_file.close()


def tumblr_setup():
    client = pytumblr.TumblrRestClient(secret)
    return client


def twitter_setup():
    client = twitter.Twitter(
        auth=twitter.OAuth(secret))
    return client


def reddit_setup():
    r = praw.Reddit('3D Art monitor by u/ach_hee')
    r.login(secret)
    return r


bot_inst = Bot()

Leave a Reply

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