Cross-Service Communication
There is no shared database. Services integrate over three channels:
- HTTP / REST — service-to-service calls and webhooks (the primary channel).
- Socket.IO — realtime, fanned out across pods via a Redis adapter.
- Redis — shared for socket adapters, BullMQ queues, throttling, and caches (each service uses its own logical Redis/keys; not a shared data model).
Who calls whom
| From → To | Transport | Purpose |
|---|---|---|
| widget / frontend / desktop → backend | HTTP + Socket.IO | App API, auth, live dashboards, call/chat signalling |
| widget → ms-sessions | Socket.IO (widget:event) | rrweb event ingest |
| widget → ms-communication | Socket.IO | Chat messages, AI chat streaming |
| backend → ms-ai | HTTP (Bearer MS_AI_SECRET_TOKEN) | Fact extraction, Knox sync, voice handoff |
| backend → ms-sessions | HTTP | Enqueue/backfill recording analysis |
| ms-sessions → ms-ai | HTTP | Hand analyzed recordings off for enrichment |
| ms-ai → backend | HTTP + gRPC (identity) | Identity-graph lookups, callbacks |
| ms-communication / ms-sessions ↔ each other | HTTP | Visitor presence checks (is the participant live?) |
| backend ↔ External CRMs | HTTP webhooks + API | GHL/HubSpot/Slack/Stripe/Twilio |
backend ↔ ms-ai
The backend integrates with ms-ai through helper clients in
backend/app/lib/:
msAiHandoff.js— send a finalizedSessionFile/transcript for voice/AI processing.msAiKnoxClient.js— Knox pipeline calls:/internal/knox/*, brief snapshots (/knox-agent/brief-snapshot), admin memory queries (/knox-agent/memories/admin), GHL sync events, action events.- Auth is a shared secret: backend sends
Bearer ${MS_AI_SECRET_TOKEN}(alsoMS_AI_API_KEY); ms-ai validates via itssecretauth guard.
A sweeper cron (MsAiHandoffSweeperJob, every 5 min) retries failed handoffs so
a transient ms-ai outage doesn't drop work.
backend ↔ ms-sessions
backend/app/lib/msSessionsRecordingClient.jsenqueues aSessionFilefor analysis.RecordingBackfillSweeperJob(every 15 min) backfills anySessionFilewhose handoff to ms-sessions failed.
Service URLs & secrets
Backend resolves peer services from env (backend/app/configs/app.js):
| Env var | Points at |
|---|---|
MS_AI_URL | ms-ai base URL |
MS_SESSION_URL | ms-sessions base URL |
MS_COMMUNICATION_URL | ms-communication base URL |
MS_AI_API_KEY, MS_AI_SECRET_TOKEN | shared secret for ms-ai calls |
In the cluster these come from ConfigMaps + SOPS-encrypted secrets; locally from
.env. See Local Development.
Realtime (Socket.IO)
- backend runs the main Socket.IO server with a Redis adapter (falls back to
in-memory for single-pod dev). It tracks session→socket mappings in Redis
(
session_sockets:prefix, 24h TTL) and throttles heartbeat writes (heartbeat_status:prefix, 5m TTL). - ms-sessions uses
@socket.io/redis-streams-adapterand a cross-pod tab registry (session_tabs:{room}hashes, 90s TTL renewed every 30s) so visitor presence is globally visible regardless of which pod a tab connected to. - ms-communication uses the standard
@socket.io/redis-adapterfor chat/call fan-out and mirrors message state to Firestore.
The frontend holds two sockets: window.main_socket (agent/internal
notifications) and window.socket (user-facing call/chat/session events). Key
events are documented on the frontend page.
Auth model summary
| Caller | Mechanism |
|---|---|
| Browser → backend | JWT bearer (issued by backend; passport OAuth for social login) |
| Browser → ms-ai (public tools) | rate-limited, no auth (e.g. calendar availability/booking) |
| Service → ms-ai | secret guard: x-api-key or Bearer shared token |
| Webhooks (Shopify/ElevenLabs/Slack) | HMAC signature over raw body |
| backend → CRMs | per-integration OAuth tokens / API keys stored per company |