By @readwithai - Creating tools for reading and agency with Obsidian. Sharing my work and thoughts along the way.
Twitter seems to have quite a lot of bots on it. They do things like like your posts when they haven’t even read it, follow people while no actually post things, and tend to mostly be there for the link in their profile.
What’s worse reporting them is an infuriating 5 clicks and a couple of scrolls away - so while I was in a “web scraping mood” I decided to automate this using a bookmarklet - which only requires one click
To use this add this bookmarklet to your browser - then when you want to report and block someone, click on their profile page and run the bookmarklet.
To create the bookmarklet, create a new bookmark and copy and paste this for the URL:
javascript:(function()%7Basync%20function%20run()%20%7B%0Afunction%20sleep(ms)%20%7B%0A%20%20%20%20return%20new%20Promise(resolve%20%3D%3E%20setTimeout(resolve%2C%20ms))%3B%0A%7D%0Adocument.evaluate('%2F%2F*%5B%40data-testid%3D%22userActions%22%5D'%2C%20document).iterateNext().click()%20%20%0Aawait%20sleep(1000)%0Adocument.evaluate('%2F%2F*%5B%40role%3D%22menuitem%22%5D%5Bdescendant%3A%3A*%5Bstarts-with(text()%2C%20%22Report%22)%5D%5D'%2C%20document).iterateNext().click()%20%20%0Aawait%20sleep(1000)%0Adocument.evaluate('%2F%2F*%5B%40role%3D%22dialog%22%5D%2Fdescendant%3A%3A*%5Btext()%3D%22Spam%22%5D%2Fancestor%3A%3Alabel%2Fdescendant%3A%3Ainput'%2C%20document).iterateNext().click()%0Aawait%20sleep(1000)%0Adocument.evaluate('%2F%2F*%5B%40role%3D%22dialog%22%5D%2Fdescendant%3A%3A*%5Btext()%3D%22Next%22%5D'%2C%20document).iterateNext().click()%0Aawait%20sleep(1000)%0Adocument.evaluate('%2F%2F*%5B%40role%3D%22dialog%22%5D%2Fdescendant%3A%3A*%5Bstarts-with(text()%2C%20%22Block%22)%5D%2Fancestor%3A%3AButton'%2C%20document).iterateNext().click()%0A%7D%0Arun()%7D)()%3B
Obvious caveats: only report spam bots - you might be tempted to try this out on a random user but that would be unfair.
Demo
Details for the programmers among you
If you want to know how this works. I use XPaths with document.evaluate and the “.click” method in JavaScript to automate all this code. There is a bit of magic with Xpath axes and the text() method to find the correct element since nothing seems to be labelled in html any more these days.
There are some “race conditions” in the code where things take a long time to run. I work around by sleeping for a period of time. A better way to do this would be to “poll” for elements to be created but this works okay as a hack.
async function run() {
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
document.evaluate('//*[@data-testid="userActions"]', document).iterateNext().click()
await sleep(1000)
document.evaluate('//*[@role="menuitem"][descendant::*[starts-with(text(), "Report")]]', document).iterateNext().click()
await sleep(1000)
document.evaluate('//*[@role="dialog"]/descendant::*[text()="Spam"]/ancestor::label/descendant::input', document).iterateNext().click()
await sleep(1000)
document.evaluate('//*[@role="dialog"]/descendant::*[text()="Next"]', document).iterateNext().click()
await sleep(1000)
document.evaluate('//*[@role="dialog"]/descendant::*[starts-with(text(), "Block")]/ancestor::Button', document).iterateNext().click()
}
run()
Related
If you are interested in this you might be interested in how I automated creating twitter posts from within Obsidian.