How can I manage to update this script - python

#!/usr/bin/env python
# twitterbots/bots/favretweet.py
import tweepy
import logging
from config import create_api
import seacret
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger()
#stream = tweepy.Stream(seacret.KEY, seacret.SECRET, seacret.TOKEN, seacret.TOKEN_SECRET)
class FavRetweetListener(tweepy.Stream):
def __init__(self, api):
self.api = api
self.user = api.get_user(screen_name='MyGasAndEnergy1')
def on_status(self, tweet):
logger.info(f"Prosessing tweet id {tweet.id}")
if tweet.in_reply_to_status_id is not None or tweet.user.id == self.user.user_id:
return
if not tweet.favorite:
try:
tweet.favorite()
except Exception as e:
logger.error("Error on Fav", exc_info=True)
if not tweet.retweeted:
try:
tweet.retweet()
except Exception as e:
logger.error("Error on vav and retweet", exc_info=True)
def on_error(self, status):
logger.error(status)
def main(keywords):
api = create_api()
tweets_listener = FavRetweetListener(api)
#new way to auth
stream = tweepy.Stream(seacret.KEY, seacret.SECRET, seacret.TOKEN, seacret.TOKEN_SECRET)
#old way to auto + important tweets_listener for actions
stream = tweepy.Stream(api.auth, tweets_listener)
stream.filter(track=keywords, languages=["en"])
if __name__ == "__main__":
main(["Python", "Tweepy"])
I have older code for editing for my use. But this part I can not figure, because of my noobines. Code is suppose to fav and retweet in twitter if it founds suitable keyword.
New code needs:
stream = tweepy.Stream(seacret.KEY, seacret.SECRET, seacret.TOKEN, seacret.TOKEN_SECRET)
Old code needs:
tweets_listener = FavRetweetListener(api)
stream = tweepy.Stream(api.auth, tweets_listener)
But new tweepy don't work with older api.auth method but want all secret tokens to be in tweepy.Stream() and that mean that I can not launch rest of my code via tweets_listener becauce it wont accept anything more.
How can I continue. I haven't found solution for this after googling or/and can not ask proper questions to move on with this problem.
Tweepy is python module/packet for working twitter-things. This script is originally from realpython.com. Problem is that I don't want to downgrade tweepy.
So I need include FavRetweetListener, but I don't have knowledge how I have to refactor code.

I switched to tweepy.Cursor and get it working. Thanks to all. Better question next time.
https://docs.tweepy.org/en/stable/v1_pagination.html#tweepy.Cursor

Related

Tweepy.errors.NotFound: 404 Not Found 50 - User not found

I am trying to make a twitter bot in python using tweepy, when running the below code I get error:
tweepy.errors.NotFound: 404 Not Found
50 - User not found.
My code:
import tweepy
import logging
from config import create_api
import json
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger()
class FavRetweetListener(tweepy.Stream):
def __init__(self, api):
self.api = api
self.me = api.get_user()
def on_status(self, tweet):
logger.info(f"Processing tweet id {tweet.id}")
if tweet.in_reply_to_status_id is not None or \
tweet.user.id == self.me.id:
# This tweet is a reply or I'm its author so, ignore it
return
if not tweet.favorited:
# Mark it as Liked, since we have not done it yet
try:
tweet.favorite()
except Exception as e:
logger.error("Error on fav", exc_info=True)
if not tweet.retweeted:
# Retweet, since we have not retweeted it yet
try:
tweet.retweet()
except Exception as e:
logger.error("Error on fav and retweet", exc_info=True)
def on_error(self, status):
logger.error(status)
def main(keywords):
api = create_api()
tweets_listener = FavRetweetListener(api)
stream = tweepy.Stream(api.auth, tweets_listener)
stream.filter(track=keywords, languages=["en"])
if __name__ == "__main__":
main(["Python", "Tweepy"])
Is this something with the `tweet.user.id == self.me.id:` ?
The user does not exist anymore in Twitter.
You must catch the error with an except statement in python.
You did not provide the exact line where the error happen but you should try to catch it with something like this:
try:
api.get_user()
except tweepy.errors.NotFound:
print("user not found")

on_direct_message is not listening the direct message streaming using tweepy

The on_direct_message never called when a message arrives. i have used python3.7 and latest tweepy library. i n twitter account it works fine but not working with the code snippet am using. But the code snippet is working well to listen tweets.
twitter_stream=Stream(auth,StdOutListener())
print('Stream created...')
twitter_stream.filter(follow=[user.id_str], is_async=True)
NB:Permission taken for read, write and direct message. And all access parameters are correct
The StdOutListener is:
class StdOutListener( StreamListener ):
def __init__( self ):
self.tweetCount = 0
def on_connect( self ):
print("Connection established!!")
def on_disconnect( self, notice ):
print("Connection lost!! : ", notice)
def on_data( self, status ):
print("Entered on_data()")
print(status, flush = True)
return True
def on_direct_message( self, status ):
print("Entered on_direct_message()")
try:
print(status, flush = True)
return True
except BaseException as e:
print("Failed on_direct_message()", str(e))
def on_error( self, status ):
print(status)
Direct Messages are not supported in the Twitter streaming API (they were a part of the User Streams API, which was removed in 2018 and replaced with the Account Activity API).
To receive Direct Messages in realtime, you will need to implement a webhook handler for the Account Activity API. You could try the twitivity library, or look at this Python sample app. Tweepy does not have built-in support for this API.

I want to set the limit of maximum number of Tweets

I am very new to python. I'm using tweepy library to scrape tweets via twitter streaming API. but it seems like connection gets broken after running for an hour. I want to know if there is any way to stop the program from running before the connections get broken. In short limiting the tweets.
I have tried the .items method but it did'nt work as it gives the name Error.
from tweepy import Stream
from tweepy import OAuthHandler
from tweepy.streaming import StreamListener
ckey="xxxxxxxxxxxxxxxxxxxxxxxxxxx"
csecret="xxxxxxxxxxxxxxxxxxxxxx"
atoken="xxxxxxxxxxxxxxxxxxxxx"
asecret="xxxxxxxxxxxxxxxxxxxxxxxxxxx"
class listener(StreamListener):
def on_data(self, data):
print(data)
return(True)
def on_error(self, status):
print status
auth = OAuthHandler(ckey, csecret)
auth.set_access_token(atoken, asecret)
twitterStream = Stream(auth, listener())
twitterStream.filter(track=["Obama"])
thanks
To solve your connection issue take help from this:
Tweepy Connection broken: IncompleteRead - best way to handle exception? or, can threading help avoid?
To achieve tweets limitation you can return False from the class def on_data method, when the desired number of tweets are fetched. Set max number of tweets in the init method and use try and except for error handling. This might help
def __init__(self):
super().__init__()
self.max_tweets = 10
self.tweet_count = 0
def on_data(self, data):
try:
data
except TypeError:
print(completed)
else:
self.tweet_count+=1
if(self.tweet_count==self.max_tweets):
print("completed")
return(False)
else:
decoded = json.loads(data)

Automated Direct Message Response using Tweepy

I currently am making use of the tweepy package in python for a DM listener. I wish to send a reply to the sender on reception of their message. I have the following:
class StdOutListener( StreamListener ):
def __init__( self ):
self.tweetCount = 0
def on_connect( self ):
print("Connection established!!")
def on_disconnect( self, notice ):
print("Connection lost!! : ", notice)
def on_data( self, status ):
status = str(status)
try:
json_acceptable_string = status.replace('\\','')
#string to dict
status=json.loads(json_acceptable_string)
if 'direct_message' in status.keys():
print '\n'
print status[u'direct_message'][u'sender_screen_name'] +' sent: '+ status[u'direct_message'][u'text']
message=str(status[u'direct_message'][u'text'])
api.send_direct_message(screen_name=str(status[u'direct_message'][u'sender_screen_name']),text='Out of office now - will respond to you asap')
print 'auto response submitted'
else:
#not direct message flow
pass
except:
#not important flows - couldn't convert to json/not correct flow in stream
pass
return True
def main():
global api
try:
auth = OAuthHandler(consumer_key, consumer_secret)
auth.secure = True
auth.set_access_token(access_token, access_token_secret)
api = API(auth)
print(api.me().name)
stream = Stream(auth, StdOutListener())
stream.userstream()
except BaseException as e:
print("Error in main()", e)
if __name__ == '__main__':
main()
For some reason, I can see the print statement of the user and what they sent but when it gets to the send_direct_message method it hangs.
Oddly enough, if I message myself, I receive a barrage of messages as it loops. Is this because it's on_data()? How can I make this work for other senders?
UPDATE: Resolved - regnerated tokens and add conditional to check for sender, essentially blacklisting myself.
UPDATE: Resolved - regenerated tokens and add conditional to check for sender, essentially blacklisting myself.

Is it possible to stop twython streaming at certain point of time?

I have the codes for twython streaming and it is working.
def read_cred(file):
in_handle = open(file,'r')
cred = {}
for ln in in_handle:
data = ln.strip('\r\n').split('=')
if len(data) > 1:
key = data[0].strip(' ').lower()
value = data[1].strip(' ')
cred[key] = value
else:
print "error in parsing credentials file"
return cred
cred = read_cred(sys.argv[1])
class MyStreamer(TwythonStreamer):
def on_success(self, data):
act(data)
def on_error(self, status_code, data):
print status_code, data
stream = MyStreamer(cred['consumer_key'], cred['consumer_secret'],
cred['access_token_key'], cred['access_token_secret'])
keywords = sys.argv[2]
stream.statuses.filter(track=keywords)
However, I want to create a UI in django framework which consist of a 'start' and a 'stop' button. What should I do to stop the twython streaming when I clicked on the button 'stop' ? Can give me some simple examples pls?
As long as the stop button is bound to the rest of the app (I haven't used Django, so I can't provide a simple example) then calling sys.exit() should do the job.
Django might have some other method for terminating a process built into it or some specific examples in its documentation. You should check that to confirm this answer.
You can use the disconnect() function as described in the documentation of Twython - https://twython.readthedocs.org/en/latest/api.html#twython.TwythonStreamer.disconnect
def on_stop(self, status_code, data):
self.disconnect()
def on_start(keywords):
stream = MyStreamer(cred['consumer_key'], cred['consumer_secret'],
cred['access_token_key'], cred['access_token_secret'])
stream.statuses.filter(track=keywords)

Categories