I’m writing a Twitter bot using Tweepy to retweet the tweets that have specific keywords.
Using the method is_not_a_reply
, I tried to retweet only the tweets that are not a reply to another tweet. It works correctly almost 99% of the time, but rarely are some replies still retweeted.
I really don’t know what’s wrong with my code!!!
import os
import tweepy
from dotenv import load_dotenv
# take environment variables from .env.
load_dotenv()
# get environment variables for Twitter API
consumer_key = os.environ.get("CONSUMER_KEY")
consumer_secret = os.environ.get("CONSUMER_SECRET")
access_token = os.environ.get("ACCESS_TOKEN")
access_token_secret = os.environ.get("ACCESS_TOKEN_SECRET")
def twitter_api_authenticate():
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
return tweepy.API(auth, wait_on_rate_limit=True)
class MyStream(tweepy.Stream):
def __init__(
self, consumer_key, consumer_secret, access_token, access_token_secret
):
super().__init__(
consumer_key, consumer_secret, access_token, access_token_secret
)
self.twitterApi = twitter_api_authenticate()
# when a new tweet is posted on Twitter with my filtered keywords
def on_status(self, status):
# If the found tweet is not a reply to another tweet
if self.is_not_a_reply(status):
# Retweet the found tweet (status)
self.retweet(status)
# Like the found tweet (status)
self.like(status)
def retweet(self, status):
# Retweet the tweet
self.twitterApi.retweet(status.id)
def like(self, status):
# Like the tweet
self.twitterApi.create_favorite(status.id)
def is_not_a_reply(self, status):
if status.in_reply_to_status_id == None:
return True
else:
return False
if __name__ == "__main__":
trackList = ["Keyword1", "Keyword2"]
stream = MyStream(
consumer_key, consumer_secret, access_token, access_token_secret
)
stream.filter(track=trackList, languages=["fa"])
Tweepy version: 4.1.0
Python version: 3.8.10
2
Answers
I found my mistake. The unwanted tweets are not replies themselves but retweets of a reply!
This was due to my poor understanding of the tweet object in Twitter API. In the Twitter API the retweet of a reply is not considered a reply itself.
So I must first check whether the filtered tweet is a "retweet" or not and then check whether it is a "reply" or not.
According to the point rv.kvetch mentioned in his answer, I modified the
is_not_a_reply
method as follows:I’m not entirely sure what the problem is, but you can always try to simplify the logic in the
is_not_a_reply
method. For debugging, I’d also suggest logging thestatus
object and thein_reply_to_status_id
attribute for example.Note that in the original version, you were doing a
==
comparison with None, but if you use an IDE it’ll suggest having it likeis
andis not
, because that’s the ideal way to do comparisons with None or a boolean. In this case I’ve just updated it to handle any "falsy" value like a 0 value or an empty list – again, it all depends on what the type ofin_reply_to_status_id
is here.