📜 ⬆️ ⬇️

Facebook's sixth sense

Chrome extension shows when someone types




Some people spend too much time on social networks. So much so that they already have a dependency. One of these is programmer Alexander Kirzenberg (Alexandre Kirszenberg), who also likes to dig into the guts of Facebook — in JavaScript code that is responsible for the user interface and communication.

“A couple of months ago, I thought about a small status indicator that shows when one of your friends is typing you a text, Alexander writes . - Such a small extension UI gives a lot of information about the interlocutor. If the indicator lights up several times and goes out, this indicates indecision. If he caught fire for a long time, someone writes you a great essay. And there is nothing worse than that painful feeling when the indicator goes out and no longer lights up. ”

First of all, Alexander decided to find out if Facebook sends notifications that someone is typing messages on Facebook Messenger, even if you do not have this Facebook Messenger running. It turned out that sends.
')
All friends are sent typ event “long poll” /pull (long polling). A small study showed that the event is really sent out for each chat , even if the recipient did not open it and never received it.

This is how the Facebook expansion of the Sixth Sense for Chrome browser appeared. It shows right in the browser when someone types a message on Facebook.



The programmer used undocumented Facebook API to create this extension. I had to deal with the JavaScript code, which Facebook ruthlessly minimizes, turning into a jumble of characters.

First, he found out which modules Facebook imports through the program interface of the Asynchronous Module Definition module organization system for asynchronous loading (Facebook has its own implementation of AMD). Modules and dependencies are defined by the standard function __d(name, dependencies, factory) . There are also require and requireLazy for importing modules.

The easiest way to see how this works is in the browser console (although Facebook strictly prohibits it). It seems that serious guys work there, it’s better not to joke with them.



But we still dare.



As you can see, Facebook always loads the latest version of React - an excellent library of user interface components. Facebook uses React quite extensively throughout the site. There are more than 15,000 React components in the Facebook code (as of October 2015).

In the source code, you can search for __d( and see the list of modules available for import. For the main page there are only 3000 modules.

The Facebook Messenger chat, of course, also uses React components. We need to intercept typing notifications. For a more detailed study of the code, Alexander Kirzenberg recommends using the React Developer Tools tool.





After installing this extension, a new React tab appears in the Chrome developer tools. On it we select the chat.



Here, among the various components of Facebook Messenger, we are looking for a typing indicator, it is located between <ChatTabComposerContainer /> and <MercuryLastMessageIndicator /> .

Search __d('ChatTyping in the code base React finds two modules: ChatTypingIndicator.react.js and ChatTypingIndicators.react.js . This is exactly what we need, says Kirzenberg. He notices that some modules are loaded as needed, so ChatTypingIndicators.react.js can only be found from the second time.

Here is his code.

 function() { var k = c('MercuryThreadInformer').getForFBID(this.props.viewer) , l = c('MercuryTypingReceiver').getForFBID(this.props.viewer); this._subscriptions = new (c('SubscriptionsHandler'))(); this._subscriptions.addSubscriptions( l.addRetroactiveListener( 'state-changed', this.typingStateChanged ), k.subscribe( 'messages-received', this.messagesReceived ) ); }, 

Namely, we are interested in calling c('MercuryTypingReceiver') .

In the console, you can see how it works.

 > MercuryTypingReceiver.getForFBID // function (i){var j=this._getInstances();if(!j[i])j[i]=new this(i);return j[i];} > MercuryTypingReceiver.get // function (){return this.getForFBID(c('CurrentUser').getID());} 

To check how the status indicator works, Alexander used the Messenger application on his own smartphone to send the corresponding events to his PC and catch them in the console.

MercuryThreads studying the code in more detail, he found two more useful modules MercuryThreads and ShortProfiles . The first one gets all the information about the Messenger thread by its ID, the second one does the same for the profile.

In general, after all the research, this is what the final extension code for Chrome looks like, just 40 lines.

 function getUserId(fbid) { return fbid.split(':')[1]; } requireLazy( ['MercuryTypingReceiver', 'MercuryThreads', 'ShortProfiles'], (MercuryTypingReceiver, MercuryThreads, ShortProfiles) => { MercuryTypingReceiver .get() .addRetroactiveListener('state-changed', onStateChanged); // Called every time a user starts or stops typing in a thread function onStateChanged(state) { // State is a dictionary that maps thread ids to the list of the // currently typing users ids' const threadIds = Object.keys(state); // Walk through all threads in order to retrieve a list of all // user ids const userIds = threadIds.reduce( (res, threadId) => res.concat(state[threadId].map(getUserId)), [] ); MercuryThreads.get().getMultiThreadMeta(threadIds, threads => { ShortProfiles.getMulti(userIds, users => { // Now that we've retrieved all the information we need // about the threads and the users, we send it to the // Chrome application to process and display it to the user. window.postMessage({ type: 'update', threads, users, state, }, '*'); }); }); } } ); 

Not a bad hack, slightly revealing the insides of Facebook.

The source code for the extension is published on Github .

By the way, you can even track your friends' sleep mode ( source code ) by timestamps from Facebook messenger.

Source: https://habr.com/ru/post/302506/


All Articles