I have this code that retweets a tweet if that said tweet includes the mention of #oogabooga.
How would I change it so that it would retweet every tweet tweeted by #oogabooga without the need of a mention in those said tweets?
So basically I want to retweet everything that #oogabooga tweets, regardless of content. I tried modifying it myself and went through tweepy docs, API, and looked up some similar problems trying to build from there, but with no luck. Help a noob out!
import logging
import time
import random
from datetime import datetime, timedelta
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger()
auth = tweepy.OAuthHandler('hiddenkey1','hiddenkey2')
auth.set_access_token('hiddenkey3','hiddenkey4')
api = tweepy.API(auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True)
user = api.me()
def fav_retweet_user(api, user_handle):
search_query = f"{user_handle} -filter:retweets"
logger.info(f'Retrieving tweets mentioning {user_handle}...')
tweets = api.search(q=search_query, lang ="en")
for tweet in tweets:
if tweet.in_reply_to_status_id is not None or \
tweet.user.id == api.me().id:
return
if not tweet.favorited:
try:
tweet.favorite()
logger.info(f"Liked a tweet mentioning {user_handle}")
except Exception as e:
logger.error("Error on fav", exc_info=True)
if not tweet.retweeted:
try:
tweet.retweet()
logger.info(f"Retweeted a tweet mentioning {user_handle}")
except Exception as e:
logger.error("Error on fav and retweet", exc_info=True)
while True:
fav_retweet_user(api, "#oogabooga")
logger.info("Waiting...")
time.sleep(30)
Changing your search query to the following will work:
search_query = f"-filter:from:{user_handle}"
Related
I'm attempting to build a Twitter bot that retrieves #Fortnite tweets on Twitter, and then retweets them. The problem I'm encountering is Tweepy is retrieving tweets that are very old. Is it possible to make it so it won't retrieve tweets older than a week old?
I looked that the Twitter API docs, and found since_id, Is this what I need to implement?
import tweepy
import keys
import time, datetime
auth = tweepy.OAuthHandler(keys.API_KEY, keys.API_SECRET_KEY)
auth.set_access_token(keys.ACCESS_TOKEN, keys.SECRET_ACCESS_TOKEN)
api = tweepy.API(auth)
def twitter_bot(hashtag, delay):
while True:
print(f"\n{datetime.datetime.now()}\n")
for tweets in api.search_tweets(q=hashtag, result_type="recent", count=30):
try:
tweet_id = dict(tweets._json)["id"]
tweet_text = dict(tweets._json)["text"]
print("id: " + str(tweet_id))
print("text: " + str(tweet_text))
api.retweet(tweet_id)
print("[+] Retweeted successfully!")
except tweepy.TweepyException as e:
print(e)
time.sleep(delay)
twitter_bot("#Fortnite", 480)
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've been following the tutorial available at realpython to try and create a twitter bot that retweets a specific user based on keywords within their tweet. By using the follow and track parameters, I should be able to retweet only those tweets that contain goal AND assist but the listener seems to retweets all tweets that contain these keywords not the specific user.
#!/usr/bin/env python
# tweepy-bots/bots/retweet.py
import tweepy
import logging
from config import create_api
import json
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger()
class RetweetListener(tweepy.StreamListener):
def __init__(self, api):
self.api = api
self.me = api.me()
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.retweeted:
# if 'GOAL' and 'ASSIST' in tweet.full_text:
# 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 = RetweetListener(api)
stream = tweepy.Stream(api.auth, tweets_listener)
stream.filter(follow=['761568335138058240'],
track=keywords, languages=["en"])
if __name__ == "__main__":
main(["Goal Assist"])
Posting my own answer based on how I hacked it together, not sure if it's the best method but it works.
class RetweetListener(tweepy.StreamListener):
def __init__(self, api):
self.api = api
self.me = api.me()
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.retweeted:
if 'Goal -' and 'Assist -' in tweet.text:
try:
# Retweet, since we have not retweeted it yet
tweet.retweet()
except Exception as e:
logger.error("Error on fav and retweet", exc_info=True)
def on_error(self, status):
logger.error(status)
How can I use twython to post a reply to any twitter id?
The way to post a status update on twitter by this awesome twython library is as follows -
try:
a = twitter.update_status(status=message)
return HttpResponse("1", content_type='text/plain')
except TwythonError as e:
return HttpResponse(e, content_type='text/plain')
Just wanted to know, how can I post a reply to a tweet using twython?
Assuming you have the twitter id, you can simply do add in_reply_to_status to the update_status function.
try:
a = twitter.update_status(status=message, in_reply_to_status_id=twitter_id)
return HttpResponse("1", content_type='text/plain')
except TwythonError as e:
return HttpResponse(e, content_type="'text/plain')
This can be found here.
Also, you should check out the endpoints.py in the twython package for more functions to use Twython.