In the last few days I have decided to reconnect with my mostly dormant Twitter persona. Aside from tweeting links to a few Steem posts I had not paid serious attention to my Twitter account since 2016 or so.
Overall, I had tweeted about 1500 times since joining the service in August of 2007. This is not exactly prolific. Nevertheless, many of my older tweets did point to blog posts that were no longer available. Others discuss technical topics that were of little relevance today. A few were just silly. Or maybe incomprehensible.
CC-0 from Pixabay
Given the short and rapid format of Twitter, it seemed important to focus my feed on topics that matter in the moment. I decided to archive and delete most of the older content. And thereby I encountered a small challenge.
The feature to mass delete tweets is not built in to Twitter's web interface. Painstakingly vaporizing a thousand tweets didn't sound like much fun either.
As we often do in this age, I first turned to Google and the marketplace of apps. The first search result for my hastily devised "mass delete tweets" query was this listicle. It identifies five third party tools for deleting tweets in bulk.
From Tweet Deleter's dashboard
Hesitant to re-invent the wheel, I gave the first one listed, Tweet Deleter, a try. To be fair it didn't seem like an unworkable option. It had useful tools for filtering and searching for Tweets that you may wish to delete. These filters offered a variety of criteria.
I quickly encountered the main limitation, though. Tweet Deleter wanted to sell me a premium subscription in order to delete more than 5 of my own tweets on any given day.
Tweet Deleter's oAuth note
I also was rather skeptical of the application's twitter API authorization. It identified itself as "Global auth" for a variety of services rather than a specific application.
There was in fact only one purpose for which I was willing to temporarily grant access. I didn't really want to contemplate how "many cool services" would gain delete capable, write access to my account.
So, I could either pay for a shady feature that should have been built in anyway. Or I could make a year long project out of taking back control of my own feed.
Suspecting that the remaining options would eventually reveal comparable shortcomings, I chose to invent Option C ― build it my damned self (while standing on the shoulders of giants, of course).
Fortunately, I had just spent a good portion of the holidays reacquainting myself with Python. And there's a rule among developers. If there isn't a JavaScript for it there's one in Python. Actually there's probably both. But the more languages with which you're familiar, the greater the likelihood that you can adapt the first answers you find.
In this case a quick search of Stack Overflow and GitHub turned up two pieces of Python code. Each on its own came close to meeting my objective of deleting all tweets older than a certain date. But complete satisfaction would involve combining the two ideas.
First up, I noticed this gist under the GitHub account of Dave Jeffery. This is a handy bit of Python scripting using the open source tweepy library to nuke all of the tweets in a feed. There are a couple of things to note about this script.
It's written in Python 2 syntax. This isn't really a problem. To use the script with minimal modification there are readily available Python 2 environments that won't require any setup. For example, I used a Python 2 notebook at Google's Colaboratory. Alternatively, you could tweak the syntax to its Python 3 equivalent.
As mentioned in the comments of the gist it's necessary to have your own application keys. These are useful for any sort of Twitter automation you may wish to do on your own. And are readily obtainable for each Twitter account at https://dev.twitter.com/apps
The comments also mention a bug that may require refreshing your Twitter feed from time to time while the script runs. I did not encounter this. Perhaps it's an old bug that has since been fixed.
There is a further consideration regarding the use of Python 2. When the script authenticates to the Twitter API the server may, depending on the setup of your app, respond with a message in the browser that
Python 2.5 is no longer available.Don't panic. Even though you encounter a browser error message the required verification code will be available in a URL query parameter.
If you don't receive a code in your browser, just look for the parameteroauth_verifierin your callback URL. This value is the code for which the Python script is prompting you.
By itself this script was ready to do most of the heavy lifting as to the quest at hand. However, I wanted a slightly finer degree of control than that provided ― not necessarily the granular filtering offered by some of the fully polished apps out there. But I did, at least, wish to keep a few of my more recent, topical posts.
After skimming my eleven year Twitter history, I decided it would be sufficient to delete anything older than April 20th, 2016.
For advice on how to get that done I turned next to Stack Overflow and found this. It's a discussion of exactly the problem I faced ― how to use Tweepy to act only on tweets in a certain date range.
As noted by Siddarth Sreeni's answer the approach of fetching an entire feed and then weeding out each tweet by date is far from the most efficient. Since I had only hundreds of tweets to deal with I was not overly concerned about this. And indeed ultimately the script had handled my entire feed in less than two minutes.
However, if your feed is orders of magnitude larger than mine, you may wish to look for a safer and more efficient approach―requesting paged results, or a series of smaller date ranges, for example.
Here are the changes to the base script inspired by the Stack Overflow discussion:
- First, I did need to import the
datetimelibrary. This minor detail is actually not illustrated in the sample code on Stack Overflow. But it is easy enough...
import datetime
- Next, define the date range in which to delete tweets. I want to delete everything before a certain date. So I simply set the start of the date range earlier than the date I joined Twitter.
START_DATE = datetime.datetime(1970, 1, 1, 0, 0, 0)
END_DATE = datetime.datetime(2016, 4, 20, 0, 0, 0)
- Finally, we find the action loop in the original script. It starts out like this:
for status in tweepy.Cursor(api.user_timeline).items():
try:
api.destroy_status(status.id)
print "Deleted:", status.id
except:
print "Failed to delete:", status.id
Notice how in the code the formal name for a tweet is a status. And the act of permanently deleting one is called destroy.
All that is needed here is to add the date criteria to this loop so that it does not destroy a status that falls outside the targeted range. With our constants in place this will work:
for status in tweepy.Cursor(api.user_timeline).items():
if status.created_at < END_DATE and status.created_at > START_DATE:
try:
api.destroy_status(status.id)
print "Deleted:", status.id
except:
print "Failed to delete:", status.id
For Python code indentation matters. Remember to indent the try-except block to be within the conditional if.
It worked like a charm. And now if you visit my Twitter account, TrevorReidMBA, only my most recent tweets remain.
You can get the my modified version of the script from this gist.
Resources
Repository
https://github.com/tweepy/tweepy
Gists
https://gist.github.com/davej/113241
https://gist.github.com/tdreid/707a202edda9d3e5eb6fadd3031bedbe