I have a twitter bot that responds to tweets containing a hashtag. I've been using the twt = api.search(q='param') to pull tweets and it's been working perfectly but I've since switched to myStreamListener = MyStreamListener()
twt = tweepy.Stream(auth = api.auth, listener=myStreamListener()) to pull tweets in real time. this isn't working though and I don't know why. Here's my code:
myStreamListener = MyStreamListener()
twt = tweepy.Stream(auth = api.auth, listener=myStreamListener())
twt.filter(track=['#www'], async=True)
#list of specific strings we want to omit from responses
badWords = ['xxx','yyy' ]
#list of specific strings I want to check for in tweets and reply to
genericparam = ['#zzz']
def does_contain_words(tweet, wordsToCheck):
for word in wordsToCheck:
if word in tweet:
return True
return False
for currentTweet in twt:
#if the tweet contains a good word and doesn't contain a bad word
if does_contain_words(currentTweet.text, genericparam) and not does_contain_words(currentTweet.text, badWords):
#reply to tweet
screen = currentTweet.user.screen_name
message = "#%s this is a reply" % (screen)
currentTweet = api.update_status(message, currentTweet.id)
I believe your problem is you're trying to send the reply through the stream instead of using an http request in a separate thread. It's not possible to do this as explained here:
https://dev.twitter.com/streaming/overview
Just stumbled across this.
When you create myStreamListener = MyStreamListener(self.api) self.api instance you want to use needs to be passed to StreamListner constructor or it will be null.
Related
So I am trying to create a function that basically is able to use the stream.listener function in tweepy to send a message when a user follows a new person. So basically the function would be in pseudocode of course
if user follow new:
print(¨User has followed{user}¨)
This is the code I have right now I am able to stream new tweets that come out of a user using the documentation but I couldn't find anything to stream new followers and such. Any help would be appreciated!!! Thanks!
class MyStreamListener(tweepy.StreamListener):
def on_status(self, status):
print(status.text)
myStreamListener = MyStreamListener()
myStream = tweepy.Stream(auth = api.auth, listener=myStreamListener)
myStream.filter(follow=["(Id private)"])
I have created a twitter bot with tweepy.
Here are the functions of this bot:
Search for keyword.
Retweet.
Reply with standard message.
My problem:
I keep running into duplicate tweets and the program stops.
What this error is not:
Twitter is not stopping me from replying with the same message.
What I noticed is that I keep getting the same user id. I have tried many methods to avoid this but they do not work as indented or work for a few moments until they stop working, because of this I have not added any of the methods to this code sample as the result is absolutely the same with different variations.
Questions:
How do I stop getting duplicated tweet ids?
Is there a better method than using api.search such as StreamListener? If so how?
How do I get the newest tweets instead of random tweets?
Notice that all three questions are related to the original concept of removing duplicates.
Full code:
import tweepy
import time
consumer_key = 'MYKEY'
consumer_secret = 'MYSECRET'
key = 'KEY'
secret = 'SECRET'
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(key, secret)
api = tweepy.API(auth, wait_on_rate_limit=True)
tweetNumber = 20
q = "MY SEARCH"
tweets = list(tweepy.Cursor(api.search, q, tweet_mode='extended').items(tweetNumber))
def crashBot():
for tweet in reversed(tweets):
try:
if q in tweet.full_text.lower():
print(str(tweet.id) + '-' + tweet.full_text)
api.update_status("#" + tweet.user.screen_name + " MY MESSAGE", tweet.id)
api.retweet(tweet.id)
print("done!")
time.sleep(30)
except tweepy.tweepyError as e:
print(e.reason)
time.sleep(30)
while True:
crashBot()
time.sleep(30)
tweets = list(tweepy.Cursor(api.search, q, tweet_mode='extended').items(tweetNumber))
Since this line only executes once, its contents will never change. So when crashBot runs for the second time, it will reply to the same tweets that it already replied to the first time.
One possible solution is to repopulate the list in between calls to crashBot.
while True:
tweets = list(tweepy.Cursor(api.search, q, tweet_mode='extended').items(tweetNumber))
crashBot()
time.sleep(30)
You could also ensure you don't reply to the same tweet more than once by keeping a set of all the tweet ids that you've seen already.
tweetNumber = 20
q = "MY SEARCH"
seen = set()
def crashBot():
for tweet in reversed(tweets):
try:
if tweet.id in seen:
print("Skipping", tweet.id, "because we already replied to it")
continue
if q in tweet.full_text.lower():
seen.add(tweet.id)
#rest of code continues as before
I have a problem while I want to stream a specific public Twitter list using Tweepy. I can stream a specific user, but the filter follow doesn't work in this case. I have quite a long list of accounts I would like to stream to do further analysis, so I prepared a list with all of them on twitter. Does anyone know how to handle that?
My code is as follows:
import tweepy
import sys
class MyStreamListener(tweepy.StreamListener):
def on_status(self, status):
print(status.id_str)
# if "retweeted_status" attribute exists, flag this tweet as a retweet.
is_retweet = hasattr(status, "retweeted_status")
# check if text has been truncated
if hasattr(status,"extended_tweet"):
text = status.extended_tweet["full_text"]
else:
text = status.text
# check if this is a quote tweet.
is_quote = hasattr(status, "quoted_status")
quoted_text = ""
if is_quote:
# check if quoted tweet's text has been truncated before recording it
if hasattr(status.quoted_status,"extended_tweet"):
quoted_text = status.quoted_status.extended_tweet["full_text"]
else:
quoted_text = status.quoted_status.text
# remove characters that might cause problems with csv encoding
remove_characters = [",","\n"]
for c in remove_characters:
text.replace(c," ")
quoted_text.replace(c, " ")
with open("out.csv", "a", encoding='utf-8') as f:
f.write("%s,%s,%s,%s,%s,%s\n" % (status.created_at,status.user.screen_name,is_retweet,is_quote,text,quoted_text))
def on_error(self, status_code):
print("Encountered streaming error (", status_code, ")")
sys.exit()
consumer_key = "..."
consumer_secret = "..."
access_token = "..."
access_token_secret = "..."
auth = tweepy.OAuthHandler(consumer_key,consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth)
if (not api):
print("Authentication failed!")
sys.exit(-1)
myStreamListener = MyStreamListener()
myStream = tweepy.Stream(auth = api.auth, listener=myStreamListener,tweet_mode='extended')
with open("out.csv", "w", encoding='utf-8') as f:
f.write("date,user,is_retweet,is_quote,text,quoted_text\n")
myStream.filter(follow=['52286608'])
You should be able to use the follow parameter with a comma-separated list of user IDs. From the Twitter API documentation:
follow
A comma-separated list of user IDs, indicating the users whose Tweets should be delivered on the stream. Following protected users is not supported. For each user specified, the stream will contain:
- Tweets created by the user.
- Tweets which are retweeted by the user.
- Replies to any Tweet created by the user.
- Retweets of any Tweet created by the user.
- Manual replies, created without pressing a reply button (e.g. “#twitterapi I agree”).
The stream will not contain:
- Tweets mentioning the user (e.g. “Hello #twitterapi!”).
- Manual Retweets created without pressing a Retweet button (e.g. “RT #twitterapi The API is great”).
- Tweets by protected users.
You can follow up to 5000 IDs this way.
Note that the API you are connecting has been superseded by the v2 filtered stream API, but Tweepy does not currently support that.
I have a small script (not created by me) in python to tweet, in this way however I can only tweet text, there is a way to also tweet images, videos, retweets and replies. The script work with tweepy
Here is the script:
import tweepy
auth = tweepy.OAuthHandler("API KEY", "API SECRET")
auth.set_access_token("ACCESS TOKEN", "ACCESS TOKEN SECRET")
api = tweepy.API(auth)
tweet = input("What Would You Like To Tweet? ")
api.update_status(status =(tweet))
print ("Done!")
In order to tweet images, videos, retweets etc. indeed you need other functions of the api to call (otherwise how it could differ between different commands?)
You need the checkout the tweepy documentation to get comprehensive answers but:
Tweet with Media:
filename = "image_to_be_sent.png"
status = "Hello World!"
api.update_with_media(filename = filename, status = status)
Retweet:
api.retweet(id) # you should now the tweet id you want to retweet
Reply:
In order to reply you can use either api.update_status() or api.update_with_media() depending on if, you want to attach an image or video or not. You should only set the optional argument in_reply_to_status_id.
e.g:
filename = "image_to_be_sent.png"
status = "Hello World!"
api.update_with_media(filename = filename, status = status, in_reply_to_status_id = in_reply_to_status_id)
I am using tweepy and python 2.7.6 to return the tweets of a specified user
My code looks like:
import tweepy
ckey = 'myckey'
csecret = 'mycsecret'
atoken = 'myatoken'
asecret = 'myasecret'
auth = tweepy.OAuthHandler(ckey, csecret)
auth.set_access_token(atoken, asecret)
api = tweepy.API(auth)
stuff = api.user_timeline(screen_name = 'danieltosh', count = 100, include_rts = True)
print stuff
However this yields a set of messages which look like<tweepy.models.Status object at 0x7ff2ca3c1050>
Is it possible to print out useful information from these objects? where can I find all of their attributes?
Unfortunately, Status model is not really well documented in the tweepy docs.
user_timeline() method returns a list of Status object instances. You can explore the available properties and methods using dir(), or look at the actual implementation.
For example, from the source code you can see that there are author, user and other attributes:
for status in stuff:
print status.author, status.user
Or, you can print out the _json attribute value which contains the actual response of an API call:
for status in stuff:
print status._json
import tweepy
import tkinter
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True)
# set parser=tweepy.parsers.JSONParser() if you want a nice printed json response.
userID = "userid"
user = api.get_user(userID)
tweets = api.user_timeline(screen_name=userID,
# 200 is the maximum allowed count
count=200,
include_rts = False,
# Necessary to keep full_text
# otherwise only the first 140 words are extracted
tweet_mode = 'extended'
)
for info in tweets[:3]:
print("ID: {}".format(info.id))
print(info.created_at)
print(info.full_text)
print("\n")
Credit to https://fairyonice.github.io/extract-someones-tweet-using-tweepy.html
In Tweeter API v2 getting tweets of a specified user is fairly easy, provided that you won’t exceed the limit of 3200 tweets. See documentation for more info.
import tweepy
# create client object
tweepy.Client(
bearer_token=TWITTER_BEARER_TOKEN,
consumer_key=TWITTER_API_KEY,
consumer_secret=TWITTER_API_KEY_SECRET,
access_token=TWITTER_ACCESS_TOKEN,
access_token_secret=TWITTER_TOKEN_SECRET,
)
# retrieve first n=`max_results` tweets
tweets = client.get_users_tweets(id=user_id, **kwargs)
# retrieve using pagination until no tweets left
while True:
if not tweets.data:
break
tweets_list.extend(tweets.data)
if not tweets.meta.get('next_token'):
break
tweets = client.get_users_tweets(
id=user_id,
pagination_token=tweets.meta['next_token'],
**kwargs,
)
The tweets_list is going to be a list of tweepy.tweet.Tweet objects.