summaryrefslogtreecommitdiff
path: root/JKTwitterBot/src/thebot.py
blob: cae309d937cd1181204e5dc249b1a60ac5811b71 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
'''
Created on May 9, 2011

Based on the_shrink.py, by Vivek Halder:
using a cheezy little Eliza knock-off by Joe Strout <joe@strout.net>
http://blog.vivekhaldar.com/post/2830035130/how-to-write-a-twitter-bot-in-python

Modified by: Karl, Jesse
'''

from datetime import datetime
from random import random
from twitter.api import Twitter, TwitterError
from twitter.oauth import OAuth, read_token_file
from optparse import OptionParser
import pickle
import os
import time
import json
import urllib2
import eliza

CONSUMER_KEY='uS6hO2sV6tDKIOeVjhnFnQ'
CONSUMER_SECRET='MEYTOS97VvlHX7K1rwHPEqVpTSqZ71HtvoK4sVuYk'

# Setting this to true causes tweets to be printed to the screen
# instead of tweeted.
TEST_MODE = True

DEFAULT_USERNAME = 'ziggster00' # "this will need to be changed"
DEFAULT_AUTH_FILENAME = '.twitter_oauth'
DEFAULT_LASTID_FILENAME = '.twitter_lastid'
Response_File = 'Response.txt'
public_Status_update_File = 'Status_update.txt'
questions_status_update_File = 'question_status.txt'
make_Friends_File = 'friends.txt'
count = 0 
response_count = 0 

def status_update(outgoing_text):  
    if not TEST_MODE:
        print '====> Resp =', outgoing_text
        try:
            poster.statuses.update(status=outgoing_text)
        except TwitterError as e:
            print '*** Twitter returned an error:\n***%s' % e
            
    else:
        print '====> (TEST MODE) Resp =', outgoing_text
           
def follow_user(user): 
    if not TEST_MODE:
        try:
            poster.friendships.create(id=user) 
        except TwitterError as e:
            print e
            poster.friendships.destroy(id=user)
            poster.friendships.create(id=user)
    
    else:
        print '====> (TEST MODE) Following =', user 
     
def reply_to_tweets():
    lastid = ''
    results = reader.search(q=username, since_id=lastid)['results']
    for result in reversed(results):
        asker = result['from_user']
        msgid = str(result['id'])
        incoming_text = result['text']
        
        print " <<< " + asker + ": " + incoming_text
        
        if incoming_text.lower().find(username) != 0:
            print '====> No response (not directed to %s)' % (username,)
        elif (lastid != '') and (long(msgid) <= long(lastid)):
            print '====> No response (%s < %s)' % (msgid, lastid)
        else:
            # Found a tweet directed to us.
            # Should we use Eliza? 
            usedoctor = random() > 0.33
            
            if usedoctor:
                doctor_response = doctor.respond(incoming_text.strip())
                outgoing_text = "@%s %s" % (str(asker), doctor_response)
            
            else:
                outgoing_text = '@%s %s' % (str(asker), str(response[response_count]))
                response_count = (response_count + 1) % len(response); 
                
            print '====> Resp = %s' % outgoing_text
            try:
                print outgoing_text
                status_update(outgoing_text)
                
            except TwitterError as e:
                print '*** Twitter returned an error:\n***%s' % e
                
            else:
                lastid = msgid
                print 'Last id replied = ', lastid
                with open(lastid_filename, 'w') as f:
                    f.write(lastid)
                    
        # Sleep for a second
        time.sleep(1)
        
        
def ask_questions():
    # may want to add ask questions to friends too
    # Ask questions specific to followers
    connection = urllib2.urlopen('http://api.twitter.com/1/statuses/followers.json?screen_name=' + username)
    friendship = urllib2.urlopen('http://api.twitter.com/1/statuses/friends.json?screen_name=' + username)
    following_str = connection.read()
    following_obj = json.loads(following_str)        
    friend_str = friendship.read()
    friend_obj = json.loads(friend_str)
    following_list = []
    friend_list = []
    for i in range(len(following_obj)):
        followers = following_obj[i]
        following_list.append(followers[u'screen_name'])
    for x in range(len(friend_obj)):
        supfriend = friend_obj[x]
        friend_list.append(supfriend[u'screen_name'])
    if count == len(question):
            postnumber = 0 
    else: postnumber = count
    
    for follow_me in friend_list:
        if not (follow_me in following_list):
            post = follow_me + ' ' + question[postnumber] 
            #print post    
            #status_update(post) #May want to ask everyone questions regardless of friendship 
            time.sleep(1)
            postnumber = postnumber + 1
        if (follow_me in following_list):#Left open if we want to make specific questions to friends
            print follow_me 
        if postnumber == len(question):
            postnumber = 0
            
            
            
#########################
# Execution starts here #
#########################
if __name__ == '__main__':

    parser = OptionParser()
    parser.add_option('-u', '--username', dest='username')
    parser.add_option('-o', '--oauthfile', dest='oauthfile')
    parser.add_option('-l', '--lastid', dest='lastid')
    (options, args) = parser.parse_args()
    
    home_dir = os.environ.get('HOME', '')
    
    if options.username:
        username = options.username
    else:
        username = DEFAULT_USERNAME

    if username[0] != '@':
        username = '@' + username
    
    if options.oauthfile:
        oauth_filename = options.oauthfile
    else:
        oauth_filename = home_dir + os.sep + DEFAULT_AUTH_FILENAME
    oauth_token, oauth_token_secret = read_token_file(oauth_filename)
    
    if options.lastid:
        lastid = options.lastid
    else:
        lastid_filename = home_dir + os.sep + DEFAULT_LASTID_FILENAME
        try:
            with open(lastid_filename, 'r') as f:
                lastid = f.readline()
        except IOError:
            lastid = ''
            
    reader = Twitter(domain='search.twitter.com')
    reader.uriparts=()
    
    poster = Twitter(
        auth=OAuth(
            oauth_token, oauth_token_secret, CONSUMER_KEY, CONSUMER_SECRET),
        secure=True,
        api_version='1',
        domain='api.twitter.com')
    
    "All files need to be the same length as public_Status_update_File"
    with open(public_Status_update_File, 'r') as f:
        tweet = pickle.load(f)
    with open(questions_status_update_File, 'r') as f:
        question = pickle.load(f)
    with open(Response_File, 'r') as f:
        response = pickle.load(f)
    with open(make_Friends_File, 'r') as f:
        friends = pickle.load(f) 
         
    # Prepare Eliza (code from the_shrink.py)
    doctor = eliza.eliza()
    
    # commented out so all friends are not added 
    #for friend in friends: # adds all friends from friends.txt
    #   follow_user(friend)
       
    while True:
        # We sleep between midnight at 6 am.
        hour = datetime.now().hour
        if hour < 6:
            # Sleep until 6 am.
            time.sleep((6 - hour) * 3600)
        
    
        # Reply to tweets directed to us
        reply_to_tweets()
        
        # Send out a generic tweet
        print count 
        status_update(tweet[count]) # post a status update
        print tweet[count]
        count = (count + 1) % len(tweet);
        
        # Sleep for a bit to add some realism.
        print 'Now sleeping... \n'
        time.sleep(1) # set at 5min but is at 2min
        
        # Pose a question
        status_update(question[count])
        print question[count]
        # Sleep for a bit to add some realism.
        print 'Now sleeping... \n' 
        time.sleep(1) # set for 2min.
        
        ask_questions()