My @ Caught fire 😇

MissMissM (she/her)
8 min readMay 4, 2021
Disaster Girl — Original sold as NFT for 500k$

Or how @Jack didn’t give me “Delete All Tweets” Button

So I made my own button kind of..

There isn’t much fun to be had from pressing that deactivate button thing alone either considering the shenanigans web apps do with your personal data — that was like meant for security.

When you are finally ready to go thermonuclear with your account you may as well burn everything down first — and if you are lucky to be “a data subject” follow with a Art. 17 GDPR request.

meme: Philosoraptor

It is an understatement to say that it is out of control

Especially as today everyone from your poodle’s pawdicurist to your grocer to your television are data hoarders feverishly scraping on whatever they can.

Like have you already met the selfie cam on your local grocery shop they claim it’s just a mirror and not used for anything else?

Sometimes it’s just fun burning your footprints down despite how pointless this exercise may or may not be.

The options

For twitter when I decided to set my tweets on fire

Use the Twitter Application Programming Interface (API)

It is very easy to do for example with some python scripting using the Twitter API and I fully recommend doing that.

You could run python on a web browser too but ….

Script in browser to trigger mass deletion of data thru UI

… we want to easily delete data from any Web App that makes it difficult with or without API

However for education purposes especially for apps that don’t have the public APIs I wanted to show this using just a browser likes Chrome / Firefox with some simple JavaScript — without any extra trickery.

This education can be used really for any web app that provides the one-by-one delete function but not “delete all” or “delete many” like they should.

You can put the script to the browser console / greasemonkey / trapmonkey or even easily create a browser extension from it that gives you and everyone else a real button :)

Make what uBlock Origin did for blocking trackers/ads

I want to see uBlock origin similarity here where we have managed repositories to share “deletion patterns” or other “automation pattern” across apps like even getting data out that otherwise would require unsustainable amounts of clickibunti.

Register with some random “we’ll delete your tweets” provider or

meme: Roll Safe

There were few browser scripts but all of them:

  • Worked only on the ancient version of twitter
  • Relied on hard coded dynamic generated / obfuscated CSS class id’s
  • One-by-One fragile execution chain with pointless recursion
  • Didn’t delete Tweet replies (now threads)

So I went to hack quick and dirty on my own

So this “hackety hack” route can be applied to really any web app that frustrates us with those clunky make-it-hard “delete one-by-one” interfaces whether they provide API or not..

Sounds groovy… right? Well let’s see how difficult Twitter makes it..

For deleting all tweets twitter wants you go clickibunti x3 for each

First press that More button.. coz it’s not that important right?

Second you might think it’s all done when you get to finally press Delete?

Third twitter really wants to know you are for sure really sure you want?

So we’ll just pick some elements and drive this thing right?

By using those dynamic generated / obfuscated CSS class id’s?

I mean those that Twitter’s React front-end spits out?

This will barely work one time and it’s not going to work long as few people already have found out quite few times if you look around the gists..

So I dug in to the Domain Object Model (DOM)

And found the ARIA: button (W3C) I can just send a click event on

Hovering over that the correct element is also highlighted

And wrote a little snippet to just dispatch those clicks en masse

Using querySelectorAll we can use CSS Attribute Selector on aria-label

Another way is to use XPath but I’ll leave that exercise for you :)

But problem is we still trigger that “More” seemingly everywhere

psst: data-testid[“caret”] sees the same yes ;)

I could just nest another selector under each data-testid=tweet but that still triggers the menu from retweets and any quoted tweets on reply tweets written by others.

Let’s just delete my own replies/tweets?

So what I instead did was write couple of help routines to filter on where the tweet was written by my account — where a child element has a href to your /account indicating who wrote the tweet.

On downside we now have huge script we could refactor..

Oh wait we still have to trigger that Delete button

We find the clickable span element but trouble is we need to match the Inner HTML instead of attribute.

We can just use XPath text() or just innerHTML

So instead of checking that no child exist with the given CSS Selector as we did with querySelectorHas we can do a querySelectorInner that matches nested nodes that contain a certain innerHTML

All this can be written shorter but for education purposes it’s better.

Finally you need to trigger the modals to confirm the deletes

And then the easy things

Now learning from the above if we want to delete Likes / Retweets they are very easy as there are no menus/thread views to deal with

We also need to add scrolling

window.scrollTo(0, document.body.scrollHeight)

Problem with the twitter threaded view is when you delete your tweets/replies along the thread itself doesn’t disappear when you don’t have any tweets left in the view.

To deal with Lazy Loading ..

In addition since twitter loads tweets dynamically when you scroll down we need to add scrolling, ideally triggered when nothing was deleted (you can count from the array on clicks) and adjust the interval sleep timer accordingly.

If you want to go better you could just implement a DOM Mutation Observer to see added nodes.

Lazy loader isn’t always great for everything

Lazy loader is often also used in image loaders and often those loaders are implemented wonky thus you see a lot of stutter and often with infinite scrolling when it doesn’t change the URL it messes up the navigation.

Meet infinite scrolling breaking navigation

Or even reload when evidently you scroll someone’s 10 year tweets and then the browser decides to discard that tab hogging memory (iOS was the first to do this as Apple devices severely lacked RAM and swap on their soldered SSD would wear it too much)

Plus to continuously scroll

You can simply wrap everything on setInterval e.g. every 3 sec

setInterval(() => {
}, 3000)

If you put all the deletions / do everything else and then scroll the window you delete everything that is on the screen every three seconds.

Meet Race Condition

You will need to manually scroll up sometimes as there will be race conditions where for example twitter has not yet lazy loaded elements (which you can use DOM Mutation Observer for if you care) among other things.

Maybe other than observer you can scroll up upon detecting the end but I leave that nut for you to crack ;)

Watch the limits!

I didn’t hit a wall — or any UI limits as I did it gradually but I do know that twitter does have API rate limits separately at the back-end outside the front-end / UI that may or may not be irrelevant.

Just be aware that twitter may think you are a bot :)

Or apps say using Content Distribution Network (CDN) may have some ever evolving magic as well if you do this at scale.

Thus it is essential to set appropriate value(s) for the setInterval() re-run delay(s) to beat those algorithms watching you burning your own data.

Other fun Twitter bugs or say… features

Twitter seems to have greyed out unretweets and unlikes for < year 2015 data and seems this cannot be even removed thru API.

I suspect they did some data migration and made all this migrated data immutable somehow or it’s in some referenced archive that is read-only.

Data doesn’t always scale easily

All I know how Twitter infra migrated gradually off Ruby + Rails to Node/JVM/Scala at their back-end and how they not surprisingly had growth pains with MySQL and added layers/sharding to try to overcome to that until at April 2014 they did this Manhattan thing which seems to coincidence the times I am seeing.. coincidence or not who knows? Gibb’s rule #39

When I deleted all my tweets up to that point the legacy data disappeared from the view as well but as soon as I added a tweet it all came back.

I also don’t like the fact that all the comments / replies to you stay there and there is no way to control that — compared to say to reddit when you delete your handle it joins the army of [deleted] and one cannot search deleted handles.

Jack fix it…. please.