Railway Deployment, Auth Flow, and Facebook Chat Detection
Another productive day wrestling with infrastructure and Facebook's ever-changing DOM structure. Working on MsgDesk, my Chrome extension + Next.js backend for managing Facebook messages.
Railway Deployment Headaches
Railway was giving me grief with Node versions and port binding. The ${PORT:-3000} shell expansion that works everywhere else just... doesn't work in Railway's Nix environment. Classic deployment gotcha.
Solution was pretty straightforward — created a custom server.js that reads process.env.PORT directly and a nixpacks.toml to force Node 20. Sometimes the boring solution is the right solution.
The Facebook DOM Detective Game
Spent way too much time figuring out Facebook's chat popup detection. You know how Facebook loves to obfuscate everything? Well, their class names change and DOM structure shifts like quicksand.
Ended up going through 3 different selector strategies before landing on role-based selectors (role="dialog" and role="complementary") with aria-label containers. Much more resilient than trying to chase their data-pagelet attributes.
Broadened the extension to match all of facebook.com/* instead of just /messages/* so it can catch those popup chats that appear anywhere on the site.
Auth Flow Redesign
Originally had the extension opening a new tab for login, which worked but felt clunky. Redesigned it to use an inline login form right in the sidebar.
The flow now is: user enters email/password → form submits → token gets stored directly in chrome.storage.local. Much cleaner UX since users stay in the sidebar context.
CORS Wrestling
Had to add proper CORS middleware since the extension needs to talk to the API. The tricky part is that Access-Control-Allow-Credentials: true rejects wildcard origins, so I'm dynamically mirroring the request origin if it's allowlisted.
Polish & Branding
Added the ™ symbol everywhere (because why not look professional), created a proper privacy policy page with dark theme, and generated some decent teal icons with a white "M".
Updated all the domain references to point to the final msgdesk.app instead of the old API subdomain setup.
What's Next
I've got 3 files with uncommitted changes for the inline login form that I'm still testing locally. The popup detection might need more tuning once I test it against Facebook's actual chat popups in the wild.
Also need to think about migrating from middleware.ts to proxy.ts since Next.js 16 is deprecating the old approach. But that can wait — this works for now.
9 commits today, 309 insertions. Not bad for a day of infrastructure wrangling and DOM archaeology.