Tools: Google Meet Reactions: Reverse Engineering The Webrtc Channel For...
I spend a lot of time in Google Meet — sometimes 3-4 hours a day. Google recently added a ton of new emoji reactions, and we use them actively. But the UX for finding them is… not great. Colleagues keep sending cool new emoji, and I struggle to find that exact one they just used.
Of course, an enthusiastic programmer can break improve any UX! The result is Google Meet Reactions, an extension that adds instant search right into Meet’s interface. Most importantly for me — it remembers which emoji I use and which ones my colleagues send, and boosts them in search results.
My first thought was simple: find emoji buttons in the DOM, simulate clicks. But Google Meet is heavily obfuscated with class names like .b1bzTb or .VfPpkd-rymPhb, and hunting for the full emoji list in popup depths didn’t seem like a great idea.
Then I opened chrome://webrtc-internals during a call and spotted something interesting: among dozens of RTCDataChannels, there’s one named “reactions” — and it turns out emoji are sent through it. If I could get a reference to this channel and decode the message format, I could send reactions programmatically.
WebRTC DataChannel is created via RTCPeerConnection.prototype.createDataChannel(). Simply patch this method before Meet’s code calls it and save the reference.
The idea is simple, but there’s a small problem with code injection.
Chrome extensions can inject code into pages in several ways. Content scripts run in an isolated world and don’t have access to the page’s RTCPeerConnection. You need to inject the script directly into the page context.
But script.src = URL requires a network request. By that time, Meet might have already created the “reactions” channel, and my hook would miss it.
In most cases, the hook installs before Meet creates the channel. I assume a race condition is still possible, and I have a fallback UI with a “please refresh” message, but in practice I’ve never seen it happen.
Once the channel is captured and open (channel.readyState === 'open'), you can listen to incoming messages and — more interestingly — observe what you send yourself.
Source: HackerNews