Event routing WebSocket
Event routing WebSocket
ws-server bertindak sebagai jembatan antara Redis pub/sub dan klien browser. Ia berlangganan empat channel Redis dan meneruskan setiap pesan ke koneksi yang relevan dengan aturan routing yang bervariasi per channel.
Halaman ini mendokumentasikan channel mana yang dilangganan, cara routing per peran, dan skema JSON setiap event.
Channel Redis
Subscriber di crates/ws-server/src/subscriber.rs mengikat diri pada empat channel:
| Redis channel | Dipublikasikan oleh | Routing |
|---|---|---|
conversation_updates | chat-engine-*, api-gateway | Admin/supervisor dapat semua; agent hanya yang di-assign + percakapan baru |
typing_indicators | api-gateway (saat agent mengetik) | Broadcast ke semua koneksi |
agent_presence | ws-server (saat agent online/offline) | Broadcast ke semua koneksi |
sla_breaches | api-gateway (scheduler) | Assigned agent + semua supervisor/admin |
Kode referensi: subscriber.rs::run, subscriber.rs::dispatch.
Envelope pesan
Setiap pesan yang diterima klien dibungkus dengan struktur:
Code
channel mengidentifikasi jenis event; data berisi payload spesifik. Frontend sebaiknya men-switch berdasarkan channel untuk menentukan handler.
conversation_updates
Channel utama untuk pembaruan percakapan. Payload adalah ConversationUpdateEvent yang diterbitkan oleh chat-engine (saat pesan masuk) atau api-gateway (saat pesan keluar, resolve, transfer).
Routing
Code
Efek praktis:
- Agent hanya menerima event untuk percakapan yang memang miliknya.
- Admin dan supervisor menerima event untuk semua percakapan, termasuk yang belum di-assign.
- Agent yang belum memiliki percakapan apa pun tetap menerima event
ConversationCreateddari percakapan yang baru muncul sehingga UI dapat menampilkan notifikasi "percakapan baru".
Variants ConversationUpdateEvent
Enum sumbernya ada di crates/omni-common/src/models/events.rs:
Code
Mapping ke webhook keluar dibahas di Outgoing webhook.
Contoh payload MessageReceived
Code
Contoh payload ConversationAssigned
Code
typing_indicators
Dikirim ketika agent memulai atau berhenti mengetik pada percakapan tertentu. Dipublikasikan oleh api-gateway saat menerima pesan WebSocket {"type":"typing", ...} dari klien (lihat Client messages).
Routing
Broadcast ke semua koneksi, tanpa filter peran. Frontend bertanggung jawab menyaring: hanya menampilkan indikator pada percakapan yang sedang dibuka user.
Code
Payload
Code
agent_presence
Dikirim ketika agent connect (pertama kali) atau disconnect (koneksi terakhir). ws-server sendiri yang mempublikasikannya berdasarkan state registry internal — tidak ada proses eksternal yang mengetahui presence selain ws-server.
Routing
Broadcast ke semua koneksi. Frontend memakainya untuk menampilkan badge online/offline di daftar agent.
Payload
Code
Nilai status: "online" saat koneksi pertama, "offline" saat koneksi terakhir tutup.
sla_breaches
Dikirim oleh scheduler di api-gateway ketika SLA policy dilanggar (mis. percakapan tidak dibalas dalam waktu yang ditentukan). Berguna untuk notifikasi real-time ke supervisor.
Routing
- Assigned agent pemilik percakapan mendapat event
- Semua admin dan supervisor juga mendapat event (broadcast_to_supervisors)
- Agent lain tidak mendapat event
Code
Payload
Code
Pemicu dan prioritas SLA policy dijelaskan di crates/api-gateway/src/scheduler.rs::find_policy.
Matriks routing ringkas
| Channel | Admin | Supervisor | Agent (pemilik) | Agent (bukan pemilik) |
|---|---|---|---|---|
conversation_updates (assigned) | ✔ | ✔ | ✔ | ✘ |
conversation_updates (unassigned / created) | ✔ | ✔ | ✔ | ✔ |
typing_indicators | ✔ | ✔ | ✔ | ✔ |
agent_presence | ✔ | ✔ | ✔ | ✔ |
sla_breaches | ✔ | ✔ | ✔ | ✘ |
✔ diterima, ✘ tidak diteruskan oleh server.
Idempotency di frontend
Karena klien dapat memiliki banyak koneksi (multi-tab) dan reconnect dapat menyebabkan duplikasi ringan, frontend harus idempoten:
- Pesan — dedup berdasarkan
message_id. - Conversation update — dedup berdasarkan
(conversation_id, timestamp)atau state-last-wins. - Presence — simpan nilai terakhir saja; event lama tidak relevan.
Troubleshooting
- Agent tidak menerima event untuk percakapan yang di-assign — pastikan
assigned_agent_iddi DB benar-benar terisi dengan UUID agent yang sedang login. Tanpa assignment yang valid, filter server tidak meneruskan event. - Supervisor tidak menerima typing indicator agent lain — typing indicators di-broadcast ke semua; jika tidak terlihat, frontend mungkin menyaring berdasarkan percakapan yang sedang dibuka. Buka percakapan tersebut untuk memverifikasi.
- Presence
onlinetidak muncul — hanya dipublikasikan saat koneksi pertama agent muncul. Jika agent sudah memiliki tab lain yang aktif, tab baru tidak menghasilkan event presence. - SLA breach event tidak sampai ke supervisor — periksa scheduler
api-gateway; ia adalah satu-satunya publisher kesla_breaches. Event hanya diterbitkan ketika policy cocok — lihat prioritas matching di CLAUDE.md.
File terkait
- Subscriber:
crates/ws-server/src/subscriber.rs - Handler registry:
crates/ws-server/src/handler.rs - Event types:
crates/omni-common/src/models/events.rs - Publisher (inbound):
crates/chat-engine/src/main.rs - Publisher (outbound + SLA):
crates/api-gateway/src/scheduler.rs,crates/api-gateway/src/routes/messages/mod.rs