Unsend Recall for Messenger — Recalling removed messages in Facebook Messenger

Ever since it was reported that Mark Zuckerberg had retracted messages from users’ inboxes, Facebook began to work on a feature that would let the everyday Facebook user do the same. Last week Facebook finally launched a feature that allows users to remove messages for everyone in the chat, not just for yourself. Since the user has 10 minutes to delete the message, I wanted to see if it was possible to intercept the messages before they got deleted so I can read them even after they were removed from my chat.

If you recall from my last article, I was able to temporarily bring back the Thankful reaction by hooking into Facebook’s own React components and injecting my own code via a Chrome extension. After inspecting and reverse engineering the React components for Messenger, I was indeed able to intercept new messages and recover deleted messages using the same procedures. I present to you: Unsend Recall for Messenger. How does it work? Well, simply put, it intercepts new messages you receive and saves them to the browser’s local storage. If someone deletes their message, it will retrieve it from local storage and show it. Simple, right? But technically speaking, how does it work? Let me explain below.

First things first, let’s inspect the DOM node of a removed message, then switch to the React tab in React Dev Tools to see the component.

As you can see from the screenshot above, the React component that renders a removed message (“You removed a message” on the left) is called MessengerRemovedMessageTombstone. Sounds about right… RIP message 💀⚰️

If you search “RemovedMessageTombstone” in the Sources tab, you’ll find the source code for the module that is responsible for rendering the content inside a removed message as seen in the screenshot below.

It looks like the ‘getTombstoneContent’ method returns the text that is rendered inside the MessengerRemovedMessageTombstone component. By requiring the RemovedMessageTombstone module, we can override the getTombstoneContent method and return whatever we want instead. If we have the deleted message already saved in local storage, we can just return it in this method and it will be rendered in the chat window. But how do we intercept and save messages anyways?

If you scroll up in the same source file, you’ll come across a module called MercuryThreadInformer which has a method called informNewMessage.

It turns out the informNewMessage method does exactly what it sounds like it does — it informs you whenever you receive a new message. Even though the parameters of the function are obfuscated as ‘a’ and ‘b’, you can see that the inform method maps threadId to ‘a’ and message to ‘b’, so we know that the second parameter, ‘b’ is the object of the new message. We just need to override the informNewMessage method and write our logic to persist the message in local storage.

Now that we are successfully intercepting new messages and saving them to local storage, we can go back to our getTombstoneContent method hook and return the message from local storage if it exists. And just like that, we are able to see messages that people have removed by letting our Chrome extension do all the hard work. As long as we have Facebook or Messenger running in the browser, if someone sends us a message and then removes it, we will be able to see what they actually said.

Install Unsend Recall for Messenger Extension

Are you ready to start recalling what your Facebook friends’ removed messages say? You can install the Chrome extension from the Chrome Web Store:

Open Source on GitHub

Curious how it really works? Feel free to check out the source code:

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Alec Garcia

Alec Garcia

Code 👨‍💻 and coffee ☕️. Software Engineer at Google.