The Client
A packaging manufacturer in Indonesia that sells directly and through the big online marketplaces. Customers ask about products, prices and orders wherever they found the company, so a single sales team has to keep up with conversations on WhatsApp, Shopee, Tokopedia, Lazada and TikTok Shop at the same time.
The company already had a platform that collects those chats in one place, with an API and realtime events behind it. What it did not have was a way to use it from a phone.
The Problem
Answering quickly is how a sales chat turns into an order, and the team could only work properly from a computer:
- New chats only showed up for someone sitting at the web dashboard, so messages waited while the sales team was out.
- New messages were easy to miss away from the screen.
- Assigning a conversation to the right person, tagging it and finding an old message all needed the desktop.
The backend was ready, so the missing piece was an app on top of it.
What I Did
I was the main developer of the app. I started it in September 2025 and built it from the first commit to version 1.3.2. Three more developers joined later and continued from there.
- A customer writes on WhatsApp or a marketplace
- The chat platform Collects every channel behind one API
- The message reaches the sales team's phones
- App open It arrives over a WebSocket
- App closed A push notification opens the chat
One inbox for every channel
The chat list shows each conversation with its channel’s icon, filters by several criteria at once and loads more as the agent scrolls. A workspace switcher moves between the company’s workspaces without logging out.
Realtime when open, push when closed
New messages and status changes arrive over a WebSocket while the app is open and update the list and the open chat in place. When the app is in the background or closed, push notifications take over, with badges on iOS and a tap that opens the right conversation.
The tools of the desktop, on a phone
Agents can assign a chat to a colleague and see who is online, add tags, search inside a conversation, use quick replies, look up the customer’s details and block abusive senders, with a confirmation first. Images and videos keep their proportions in the chat bubbles.
Staying signed in
Phones sleep, lose their connection and resume hours later. The app checks its token when it comes back to the foreground, refreshes it and retries the request, and registers the device for notifications again, so agents don’t land on an empty list or a login screen.
A project others could pick up
I added Husky pre-commit checks for formatting, linting and types, a build script for Expo Application Services and the iOS submission setup. The developers who joined later built on that: they added voice calls and carried on with the store releases.
The Stack
| Layer | Tool | Role |
|---|---|---|
| App | React Native, Expo, Expo Router | One codebase for Android and iOS |
| Interface | NativeWind | Tailwind-style styling shared across screens |
| Realtime | WebSocket | New messages and status changes while the app is open |
| Notifications | Expo Notifications, Firebase | Push messages when the app is closed, with deep links |
| Builds | Expo Application Services | Android and iOS builds, internal previews, store builds |
| Quality | TypeScript, ESLint, Prettier, Husky | Checks before every commit |
The Result
The sales team can answer customers from any of the five channels on their phones.
| Before | After |
|---|---|
| Chats answered only at a desk | One inbox for five channels on Android and iOS |
| New messages missed away from the screen | Push notifications that open the conversation |
| Assigning, tagging and search on the desktop only | Assign, tag, search and quick replies in the app |
| One developer’s project | Checks, build scripts and a codebase a team continued |
I wrote 141 of the 226 commits in the repository so far, and the team still develops the app. Learning React Native along the way is the subject of a separate note, Building with Copilot.
If your team needs an app on top of a system you already have, get in touch.