theahura / shoot-the-messenger

Script to auto-unsend all messages from a facebook messenger chat
Other
189 stars 28 forks source link

Unsend not working, only removal #97

Closed Thie1e closed 1 year ago

Thie1e commented 1 year ago

Describe the bug When using the extension on Chrome on messenger.com, unsending messages does not work (nothing happens). I could only remove messages from a very old chat that stayed visible to the other person.

To Reproduce Steps to reproduce the behavior:

  1. Go to messenger.com and open any chat
  2. Click on the extension and "remove messages"
  3. Nothing happens... See logs.

Expected behavior That the extension clicks sequentially through the chat and unsends messages, so they become invisible to the other person.

Desktop (please complete the following information):

Thanks for your work and enjoy the coffee :-) These are the logs after clicking remove:

Logs

Got action:  REMOVE
main.js:282 Starting runner removal for N iterations:  10
main.js:284 Running count: 0
main.js:84 What is el? <div class=​"x6prxxf x1fc57z9 x1yc453h x126k92a xzsf02u" dir=​"auto" role=​"none">​…​</div>​
main.js:84 What is el? <div role=​"none" class=​"x9f619 x1n2onr6 x1ja2u2z __fb-light-mode" style=​"--mwp-reply-background-color:​ var(--comment-footer-background)​;​ --mwp-message-list-profile-start-padding:​ 12px;​ --mw-blockquote-border-start-color:​ var(--placeholder-text)​;​">​…​</div>​
main.js:84 What is el? <div class=​"x1tlxs6b x1g8br2z x1gn5b1j x230xth x14ctfv x1okitfd x6ikm8r x10wlt62 x1mzt3pk x1y1aw1k xn6708d xwib8y2 x1ye3gou x1n2onr6 x13faqbe x1vjfegm" role=​"none" style=​"background-color:​ var(--wash)​;​">​…​</div>​
main.js:84 What is el? <div class=​"x78zum5 xh8yej3" role=​"none">​…​</div>​flex
main.js:84 What is el? <span class=​"x4k7w5x x1h91t0o x1h9r5lt x1jfb8zj xv2umb2 x1beo9mf xaigb6o x12ejxvf x3igimt xarpa2k xedcshv x1lytzrv x1t2pt76 x7ja8zs x1qrby5j">​…​</span>​flex
main.js:84 What is el? <div class=​"x1cy8zhl x78zum5 xdt5ytf x193iq5w x1n2onr6">​…​</div>​flex
main.js:84 What is el? <div class=​"x78zum5 xh8yej3" role=​"none">​…​</div>​flex
main.js:84 What is el? <div class=​"x1h91t0o xkh2ocl x78zum5 xdt5ytf x13a6bvl xcrg951 x1r145dm" role=​"none">​…​</div>​flex
main.js:84 What is el? <div class=​"x78zum5 x1iyjqo2 xs83m0k xeuugli" role=​"none">​…​</div>​flex
main.js:84 What is el? <div class=​"x78zum5" role=​"none">​…​</div>​flex
main.js:84 What is el? <div>​…​</div>​
main.js:84 What is el? <div class=​"x78zum5 xdt5ytf x1n2onr6" data-release-focus-from=​"CLICK" data-scope=​"messages_table" role=​"gridcell" tabindex=​"0">​…​</div>​flex
main.js:84 What is el? <div class>​…​</div>​
main.js:84 What is el? <div class=​"__fb-light-mode x1n2onr6" role=​"row" style=​"--mwp-reply-background-color:​ var(--comment-footer-background)​;​ --mwp-message-list-profile-start-padding:​ 12px;​">​…​</div>​
main.js:84 What is el? <div class=​"x1n2onr6">​…​</div>​
main.js:84 What is el? <div class>​…​</div>​
main.js:84 What is el? <div class=​"x78zum5 xdt5ytf x1iyjqo2 xs83m0k x1xzczws x6ikm8r x1rife3k x1n2onr6 xh8yej3">​…​</div>​flex
main.js:84 What is el? <div class=​"x78zum5 xdt5ytf x1iyjqo2 x6ikm8r x10wlt62 x1n2onr6 x1xzczws">​…​</div>​flex
main.js:84 What is el? <div class=​"x78zum5 xdt5ytf x1iyjqo2 xs83m0k xc8icb0 x6ikm8r x10wlt62 x1ja2u2z">​…​</div>​flex
main.js:84 What is el? <div class=​"x1qjc9v5 x9f619 xdl72j9 x2lwn1j xeuugli x1n2onr6 x78zum5 xdt5ytf x1iyjqo2 xs83m0k xc8icb0 x6ikm8r x10wlt62 x1ja2u2z">​…​</div>​flex
main.js:84 What is el? <div aria-label=​"Messages in conversation with Michael Mayer" class=​"x63ui4o x18i3tt1 x6ikm8r x10wlt62 x78zum5 x1iyjqo2 xdt5ytf" role=​"grid">​…​</div>​flex
main.js:84 What is el? <div class=​"x78zum5 x1r8uery xdt5ytf x1iyjqo2 xmz0i5r x6ikm8r x10wlt62 x1n2onr6">​…​</div>​flex
main.js:84 What is el? <div class=​"x78zum5 xdt5ytf x1iyjqo2">​…​</div>​flex
main.js:84 What is el? <div class=​"x78zum5 xdt5ytf x1iyjqo2 x193iq5w x2lwn1j x1n2onr6 x1ja2u2z">​…​</div>​flex
main.js:84 What is el? <div class=​"x5yr21d x1uvtmcs x78zum5 x1iyjqo2" role=​"none" tabindex=​"-1">​…​</div>​flex
main.js:84 What is el? <div class=​"x1uvtmcs x4k7w5x x1h91t0o x1beo9mf xaigb6o x12ejxvf x3igimt xarpa2k xedcshv x1lytzrv x1t2pt76 x7ja8zs x1n2onr6 x1qrby5j x1jfb8zj" tabindex=​"-1">​…​</div>​flex
main.js:84 What is el? <div class=​"x9f619 x1ja2u2z x193iq5w xeuugli x1r8uery x1iyjqo2 xs83m0k x78zum5 xdt5ytf x6ikm8r x10wlt62 x1n2onr6">​…​</div>​flex
main.js:84 What is el? <div class=​"x9f619 x1n2onr6 x1ja2u2z x78zum5 x1r8uery x1iyjqo2 xs83m0k xeuugli x1qughib x1qjc9v5 xozqiw3 x1q0g3np xexx8yu x85a59c">​…​</div>​flex
main.js:84 What is el? <div class=​"x9f619 x1n2onr6 x1ja2u2z x78zum5 xdt5ytf x193iq5w x1l7klhg x1iyjqo2 xs83m0k x2lwn1j">​…​</div>​flex
main.js:84 What is el? <div class=​"x9f619 x1n2onr6 x1ja2u2z x78zum5 xdt5ytf x1iyjqo2 x2lwn1j">​…​</div>​flex
main.js:84 What is el? <div aria-label=​"Conversation with Michael Mayer" role=​"main" class=​"x1ja2u2z x9f619 x78zum5 xdt5ytf x193iq5w x1l7klhg x1iyjqo2 xs83m0k x2lwn1j xcrg951 x6prxxf x85a59c x6ikm8r x10wlt62 x1n2onr6 x1gvwcb">​…​</div>​flex
main.js:84 What is el? <div class=​"x78zum5 xdt5ytf x1iyjqo2 xs83m0k">​…​</div>​flex
main.js:84 What is el? <div class=​"x78zum5 xdt5ytf x1iyjqo2 x1t2pt76 xeuugli x1n2onr6 x1ja2u2z">​…​</div>​flex
main.js:84 What is el? <div class=​"x9f619 x1n2onr6 x1ja2u2z xdt5ytf x193iq5w xeuugli x1r8uery x1iyjqo2 xs83m0k x78zum5 x1t2pt76">​…​</div>​flex
main.js:84 What is el? <div class=​"x9f619 x2lah0s x1nhvcw1 x1qjc9v5 xozqiw3 x1q0g3np x78zum5 x1iyjqo2 x1t2pt76 x1n2onr6 x1ja2u2z">​…​</div>​flex
main.js:84 What is el? <div class=​"x78zum5 xdt5ytf x10cihs4 x1t2pt76 x1n2onr6 x1ja2u2z">​…​</div>​flex
main.js:84 What is el? <div class=​"x78zum5 xdt5ytf x1n2onr6 xat3117 xxzkxad">​…​</div>​flex
main.js:84 What is el? <div class=​"x78zum5 xdt5ytf x1n2onr6">​…​</div>​flex
main.js:84 What is el? <div class=​"x78zum5 xdt5ytf x1n2onr6 x1ja2u2z">​…​</div>​flex
main.js:84 What is el? <div class=​"x9f619 x1n2onr6 x1ja2u2z">​…​</div>​
main.js:84 What is el? <div class=​"x9f619 x1n2onr6 x1ja2u2z">​…​</div>​
main.js:84 What is el? <div class>​…​</div>​
main.js:84 What is el? <div>​…​</div>​
main.js:84 What is el? <div id=​"mount_0_0_R7" style>​…​</div>​
main.js:84 What is el? <body class=​"_6s5d _71pn system-fonts--body segoe">​…​</body>​
main.js:84 What is el? <html id=​"facebook" class=​"_9dls __fb-light-mode" lang=​"en" dir=​"ltr">​<head>​…​</head>​<body class=​"_6s5d _71pn system-fonts--body segoe">​…​</body>​</html>​
main.js:83 Uncaught (in promise) TypeError: Cannot use 'in' operator to search for 'scrollTop' in null
    at getScroller (main.js:83:24)
    at prepareDOMForRemoval (main.js:133:3)
    at unsendAllVisibleMessages (main.js:162:36)
    at runner (main.js:285:29)
    at removeHandler (main.js:393:24)
getScroller @ main.js:83
prepareDOMForRemoval @ main.js:133
unsendAllVisibleMessages @ main.js:162
runner @ main.js:285
removeHandler @ main.js:393
await in removeHandler (async)
(anonymous) @ main.js:471
Show 6 more frames
Show less
theahura commented 1 year ago

so there's definitely a bug here:

main.js:83 Uncaught (in promise) TypeError: Cannot use 'in' operator to search for 'scrollTop' in null
    at getScroller (main.js:83:24)
    at prepareDOMForRemoval (main.js:133:3)
    at unsendAllVisibleMessages (main.js:162:36)
    at runner (main.js:285:29)
    at removeHandler (main.js:393:24)

this occurs when the tool is unable to find the scrollbar, and as a result can't actually scroll up. The associated function is here: https://github.com/theahura/shoot-the-messenger/blob/main/main.js#L79

The way StM finds the messenger scrollbar is by using a query that selects for any of your messages OR any of the receivers messages OR any unsent messages. It grabs the first one and then tries to go up the DOM till it finds the scrollbar. I've generally found this pretty foolproof, but sometimes it will break if fb changes the class names and so on in the DOM.

Unfortunately I can't replicate this on my end :thinking: It's possible though that you're on a version of fb messenger where NONE of those queries work. The queries are here: https://github.com/theahura/shoot-the-messenger/blob/main/main.js#L11C1-L15C1

MY_ROW_QUERY = '.x78zum5.xdt5ytf.x193iq5w.x1n2onr6.xuk3077:has(> span)'; // Also used for finding the scroller (we just go up to the first parent w/ scrollTop)
PARTNER_CHAT_QUERY = '.x6prxxf.x1fc57z9.x1yc453h.x126k92a.xzsf02u'; // Partner chat text innerText, used for searching
UNSENT_MESSAGE_QUERY = '[aria-label="You unsent a message"]'; // In case a user has none of their own messages on screen and only unsent messages, this serves to pick up the scroll parent.

Debugging is tricky since I can't replicate. If you don't mind, could you run the following script in your console? See if anything pops up?

const MY_ROW_QUERY = '.x78zum5.xdt5ytf.x193iq5w.x1n2onr6.xuk3077:has(> span)';
const PARTNER_CHAT_QUERY = '.x6prxxf.x1fc57z9.x1yc453h.x126k92a.xzsf02u';
const UNSENT_MESSAGE_QUERY = '[aria-label="You unsent a message"]';

const elements = document.querySelectorAll(`${MY_ROW_QUERY}, ${PARTNER_CHAT_QUERY}, ${UNSENT_MESSAGE_QUERY}`);

console.log(elements)
Thie1e commented 1 year ago

Hi, thanks for your quick reply.

I don't know anything about web-development, so here is the copy-paste of the script and the output. Hopefully this helps:

const MY_ROW_QUERY = '.x78zum5.xdt5ytf.x193iq5w.x1n2onr6.xuk3077:has(> span)'; const PARTNER_CHAT_QUERY = '.x6prxxf.x1fc57z9.x1yc453h.x126k92a.xzsf02u'; const UNSENT_MESSAGE_QUERY = '[aria-label="You unsent a message"]';

const elements = document.querySelectorAll(${MY_ROW_QUERY}, ${PARTNER_CHAT_QUERY}, ${UNSENT_MESSAGE_QUERY});

console.log(elements)

VM658:7 NodeList(8) [div.x6prxxf.x1fc57z9.x1yc453h.x126k92a.xzsf02u, div.x78zum5.xdt5ytf.x193iq5w.x1n2onr6.xuk3077, div.x1n2xptk.xkbpzyx.xdppsyt.x1rr5fae.x1gn5b1j.x230xth.x1g8br2z.x1tlxs6b.x1dntmbh.x193iq5w.x889kno.…, div.x6prxxf.x1fc57z9.x1yc453h.x126k92a.xzsf02u, div.x1n2xptk.xkbpzyx.xdppsyt.x1rr5fae.x1gn5b1j.x230xth.x1g8br2z.x1tlxs6b.x1dntmbh.x193iq5w.x889kno.…, div.x1n2xptk.xkbpzyx.xdppsyt.x1rr5fae.x1gn5b1j.x230xth.x1g8br2z.x1tlxs6b.x1dntmbh.x193iq5w.x889kno.…, div.x78zum5.xdt5ytf.x193iq5w.x1n2onr6.xuk3077, div.x78zum5.xdt5ytf.x193iq5w.x1n2onr6.xuk3077]

Thie1e commented 1 year ago

Did this maybe not work in my testing because I was using it on a short chat that does not have a scrollbar at all? I think that's the problem.

theahura commented 1 year ago

Ah! that would do it. My recommendation: try testing it in a messenger chat to yourself with a bunch of random messages in it. I just type test over and over when im testing

Thie1e commented 1 year ago

OK, this was easier to troubleshoot than expexted :-) The plugin unsent >20k messages in about 24 hours.

I had to restart it several times, though, when it failed to skip to the part of the chat where it had left off using the search bar.

Maybe mention in the docs (if it is not mentioned already) that the plugin relies on the scrollbar. Otherwise other people might use it on short chats for testing as well.

Thanks again.