Looking under the hood of a Chrome extension - Part 1
In a recent conversation with a friend, I learned that there's a Chrome browser extension that purges Slack chat messages from the currently selected channel, and I got curious about its internals since Slack doesn't seem to offer this capability out of the box. In this series, I won't focus on the extension itself, but on the steps I took to figure out how it works, which can be helpful to understand runtime behaviours of web applications in general.
I created a brand new Slack org, a couple of test users and populated a channel with messages from these test users, enough to generate a few scrollable pages. Then I installed and used the extension to start deleting messages.
Observing the behaviour
The first thing I noticed was that only the messages displayed on screen were deleted, and there was a delay of roughly 1 second between each deletion request - we'll get to this later. I also opened Chrome DevTools in the Network tab and found the request that was created for every deletion - screenshot below:
Slack sends a lot of requests constantly, so for me to pinpoint which one I was interested in, I tried to filter by anything that had the word "delete" in it, as you can see in the search bar of Chrome DevTools screenshot above. Then I proceeded to inspect the request's contents and found out that it's a regular POST
with a "Form Data" payload, which means the data is passed as if it was a regular form being posted, not as a JSON object. From my initial assessment, it looked like channel
, ts
and token
were the important fields, the first pointing to the ID of the channel I was in, the second to the timespan of the message being deleted and the third to an authentication token.
The request had a token in its payload, and considering that most modern web applications send authentication tokens in an authorization header, I went to confirm whether the request had an actual authorization header and it didn't, which led me to believe Slack used a custom authentication mechanism. I googled Slack chat.delete and found the API documentation, which confirmed my assumptions regarding the authentication mechanism used in their API and gave me another important piece of information, that Stack API requests are rate limited, meaning you can't just send a burst of requests or Slack will start blocking them. This could be the reason why the extension was slow in sending the requests to delete the messages, still, it felt like it was too slow and it could have been be optimized to delay requests only when the rate limit was reached.
The next piece of the puzzle was the scrolling behaviour. I knew that once all messages on the screen were deleted, you had to scroll the page for the extension to pick the next ones. The extension also took ~1 second to detect the new messages - it looked like the code was scheduling the check for new messages through a setInterval
or setTimeout
and continuously querying the DOM for the message nodes. To validate this assumption, I needed to intercept the DOM queries and check what was being returned, which I did with this code:
// storing the original implementations