Development of Chatbot Management Mobile App
Chatbot works 24/7, owner doesn't. Mobile management app lets operator handle conversations escalated to human, change bot scripts and get problem notifications — from phone, no computer needed.
What "Bot Management" Covers
App covers several tasks that can't mix on one screen:
Human Takeover (conversation handoff to operator). Bot couldn't answer or user requested human. Operator gets push, opens chat in app, replies. After completion — returns to bot or closes. Central function operators use constantly.
Scenario Management. Edit bot responses, add new triggers, enable/disable scenarios. Not all operators should see — need role model.
Monitoring. Active conversations right now, bot status (running/down), queue of unprocessed requests.
Human Takeover: Technical Details
Most latency-sensitive function. Conversation "stuck" — user waiting. Notification flow:
- Bot decides to escalate → publishes event to queue (RabbitMQ/Kafka)
- Notification service sends push via FCM/APNs to available operator
- Operator accepts — app opens chat
- App maintains WebSocket for real-time message exchange
FCM high priority + data payload (not notification) — otherwise Android in Doze mode won't wake app in time.
// iOS — operator chat screen
class OperatorChatViewModel: ObservableObject {
@Published var messages: [Message] = []
@Published var isConnected = false
private var wsTask: URLSessionWebSocketTask?
func connect(conversationId: String) {
let url = URL(string: "wss://api.example.com/operator/conversations/\(conversationId)/ws")!
wsTask = URLSession.shared.webSocketTask(with: url)
wsTask?.resume()
isConnected = true
receiveNext()
}
private func receiveNext() {
wsTask?.receive { [weak self] result in
guard let self else { return }
if case .success(let msg) = result,
case .string(let text) = msg,
let decoded = try? JSONDecoder().decode(Message.self, from: Data(text.utf8)) {
DispatchQueue.main.async { self.messages.append(decoded) }
}
self.receiveNext()
}
}
func send(_ text: String) {
let msg = OutgoingMessage(text: text, conversationId: conversationId)
let payload = try! JSONEncoder().encode(msg)
wsTask?.send(.string(String(data: payload, encoding: .utf8)!)) { _ in }
}
func returnToBot() {
Task { await conversationService.handoff(conversationId, to: .bot) }
}
}
Operator Queue. Multiple free operators — round robin or first to accept. All busy — conversation queues, SLA timer starts. Push repeated after N minutes if unclaimed.
Active Conversations List
Main screen — conversation list with indicators:
- Awaiting operator — red badge with wait time
- In progress with operator — operator name, duration
- Active with bot — green, no urgency
- Closed — archive
Sort: awaiting operator first, within group by wait time (longest on top).
On Android LazyColumn with three stickyHeader for groups. Update via WebSocket: backend broadcasts conversation_updated events to all connected app operators.
Role Model
Minimum two levels:
- Operator — chat and accepting conversations only
- Admin — plus scenario editing, operator management, analytics
At UI level: tabs and role-restricted functions either hidden or shown grayed with Lock icon (for transparency). At API level: role check on backend, client hiding doesn't replace server auth.
What's Included
- Conversation list with status grouping and real-time update
- Operator chat screen with WebSocket
- Push notifications on new conversations (FCM high priority)
- Queue with SLA timer and retry notifications
- Role model (operator / admin)
- Scenario management (enable/disable, edit responses)
Timeline
8–14 working days depending on channel count (Telegram, WhatsApp, Web) and scenario management complexity. Cost calculated individually after requirements analysis.







