-
-
Save Throwaway-MM/5a8e74895293eae0071cec612477c72f to your computer and use it in GitHub Desktop.
// This is a hack, a quick and dirty console script for RT/tweets (with replies) removal w/o API | |
// To be used in: https://twitter.com/Username/with_replies | |
// Set your username (without @) below (case-sensitive) to correctly trigger the right Menu | |
const tweetUser = 'Username' | |
// BUG, With above we still trigger Menu on some replies but relatively harmless. | |
// @Hack Implement simple has() for querySelector | |
const querySelectorHas = function( parent, child ){ | |
return [].filter.call( document.querySelectorAll( parent ), function( elem ){ | |
if(elem.querySelector( child ) !== null ) { | |
return true | |
} | |
else { | |
return false | |
} | |
}); | |
} | |
// @Hack Implement xpath text() selector returning matching holder element | |
// equiv XPath //find[text()='inner'] | |
const querySelectorInner = function( parent, inner ){ | |
return [].filter.call( document.querySelectorAll( parent ), function( elem ){ | |
if(elem.innerHTML == inner ) { | |
return true | |
} | |
else { | |
return false | |
} | |
}); | |
} | |
setInterval(() => { | |
console.log('--- Twitter Removal Clicks Round') | |
// For Old RT's may need (?) to RT and then Unretweet - Just watch for the UI rate limits | |
var unretweets = 0 | |
for (const d of document.querySelectorAll('div[data-testid="unretweet"]')) { | |
unretweets++ | |
d.click() | |
} | |
var unretweetconfirms = 0 | |
for (const r of document.querySelectorAll('div[data-testid="unretweetConfirm"]')) { | |
unretweetconfirms++ | |
r.click() | |
} | |
console.log('Unretweets: ' + unretweets + ', Confirms: ' + unretweetconfirms) | |
var clicks = 0 | |
for(const d of querySelectorHas("div[data-testid='tweet']", "a[href='/" + tweetUser + "']")) { | |
const moreButton = d.querySelector("div[aria-label='More']") | |
clicks++ | |
moreButton.click() | |
} | |
var clickDeletes = 0 | |
for(const deleteButton of querySelectorInner("span", 'Delete')) { | |
deleteButton.click() | |
clickDeletes++ | |
} | |
var clickConfirms = 0 | |
for(const deleteConfirm of document.querySelectorAll("div[data-testid='confirmationSheetConfirm']")) { | |
deleteConfirm.click() | |
clickConfirms++ | |
} | |
console.log('Menu: ' + clicks + ', Deletes: ' + clickDeletes + ', Confirms: ' + clickConfirms) | |
// Scrolling is more involved/difficult as twitter does not hide rest of the thread if reply deleted | |
// As work-around scroll yourself when removals hit zero. API would be best option but this solution is WEB UI driven. | |
window.scrollTo(0, document.body.scrollHeight) | |
}, 3000) // Run every 3s | |
/******************************************************************************************* | |
* | |
* THIS GIST IS PROVIDED "AS IS" AND | |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
* DISCLAIMED. IN NO EVENT SHALL WE BE LIABLE FOR ANY | |
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
* | |
*******************************************************************************************/ |
it worked, thanks so much!
Thanks for the script! It only seemed to only work for retweets for me though. To get it to work for tweets I hacked it yet further. I got rid of the querySelectorHas
and just matched the "More" button on each tweet directly. This has the side-effect of opening up other menus on the page with "More" such as trends, but these don't open a menu with a "Delete" item so nothing bad happens. Note this only deletes tweets now, not retweets, so run the original code to get them too. It also doesn't run with a delay between deletes, so you eventually get rate limited. For a few hundred tweets this is fine but if you've got thousands you might want to adapt the script to add a delay (my JavaScript knowledge is not good enough and I'm too lazy to look it up since it worked well enough for me already).
// This is a hack, a quick and dirty console script for RT/tweets (with replies) removal w/o API
// To be used in: https://twitter.com/Username/with_replies
// Set your username (without @) below (case-sensitive) to correctly trigger the right Menu
const tweetUser = 'Username'
// BUG, With above we still trigger Menu on some replies but relatively harmless.
// @Hack Implement xpath text() selector returning matching holder element
// equiv XPath //find[text()='inner']
const querySelectorInner = function( parent, inner ){
return [].filter.call( document.querySelectorAll( parent ), function( elem ){
if(elem.innerHTML == inner ) {
return true
}
else {
return false
}
});
}
setInterval(() => {
console.log('--- Twitter Removal Clicks Round')
var clicks = 0
for(const d of document.querySelectorAll("div[data-testid='tweet'], div[aria-label='More']")) {
clicks++
d.click()
}
var clickDeletes = 0
for(const deleteButton of querySelectorInner("span", 'Delete')) {
deleteButton.click()
clickDeletes++
}
var clickConfirms = 0
for(const deleteConfirm of document.querySelectorAll("div[data-testid='confirmationSheetConfirm']")) {
deleteConfirm.click()
clickConfirms++
}
console.log('Menu: ' + clicks + ', Deletes: ' + clickDeletes + ', Confirms: ' + clickConfirms)
// Scrolling is more involved/difficult as twitter does not hide rest of the thread if reply deleted
// As work-around scroll yourself when removals hit zero. API would be best option but this solution is WEB UI driven.
window.scrollTo(0, document.body.scrollHeight)
}, 3000) // Run every 3s
/*******************************************************************************************
*
* THIS GIST IS PROVIDED "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL WE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************************/
Guys, it needed a fresh update for 2023+:
// BUG, With above we still trigger Menu on some replies but relatively harmless.
// @Hack Implement xpath text() selector returning matching holder element
// equiv XPath //find[text()='inner']
const querySelectorInner = function( parent, inner ){
return [].filter.call( document.querySelectorAll( parent ), function( elem ){
if(elem.innerHTML == inner ) {
return true
}
else {
return false
}
});
}
setInterval(() => {
console.log('--- Twitter Removal Clicks Round')
var clicks = 0
for(const d of document.querySelectorAll("div[data-testid='tweet'], div[aria-label='Plus']")) {
clicks++
d.click()
}
var clickDeletes = 0
for(const deleteButton of querySelectorInner("span", 'Supprimer')) {
deleteButton.click()
clickDeletes++
}
var clickConfirms = 0
for(const deleteConfirm of document.querySelectorAll("div[data-testid='confirmationSheetDialog']")) {
for(const deleteButton2 of querySelectorInner("span", 'Supprimer')) {
deleteButton2.click()
clickConfirms++
}
}
console.log('Menu: ' + clicks + ', Deletes: ' + clickDeletes + ', Confirms: ' + clickConfirms)
// Scrolling is more involved/difficult as twitter does not hide rest of the thread if reply deleted
// As work-around scroll yourself when removals hit zero. API would be best option but this solution is WEB UI driven.
window.scrollTo(0, document.body.scrollHeight)
}, 3000);
Steps for only unretweeting-