GuidesMessaging
Architecture
Messaging — Architecture
The module is provider-agnostic: one interface, many adapters. Everything is async so a slow provider never blocks a request.
Request flow
UI ──REST──▶ Facade service ──▶ Bull queue ──▶ Provider adapter ──▶ Provider API
│
└──▶ Repository/Query service ──▶ DatabaseSending a message returns immediately ({ success: true }) and enqueues the
actual provider send. Once the worker persists it, the message is broadcast over
WebSocket to every admin allowed to see that chat.
Inbound flow (a customer replies)
Provider ──webhook──▶ UnifiedWebhookController ──▶ WebhookRouterService
──▶ per-provider handler factory ──▶ event handler
──▶ DB write ──▶ Redis pub/sub ──▶ MessagingEventsGateway ──▶ UIBuilding blocks
| Layer | Where | Job |
|---|---|---|
| Facade services | sessions/, chats/, messages/, calls/, labels/ | Coordinate repositories, queues, and providers |
| Provider adapters | providers/{waha,whatsapp-cloud,facebook,instagram,tiktok}/ | Implement IMessagingProvider (session, message, presence) |
| Provider registry | services/provider-registry | Resolve the adapter for a ProviderType |
| Queues (Bull) | core/constants/queue-names.ts | Text send, media send, read receipt, chat sync, message sync, ack update |
| Realtime | realtime/messaging-events.gateway.ts | Socket.IO namespace /messaging/events |
| Webhooks | webhooks/ | Inbound provider events, per-provider handler factories |
| Access control | core/services/chat-access-filter.builder.ts, chat-visibility.policy.ts | Row-level chat visibility (A/G/M/D) |
Dependency direction
Controllers → Facade services → Repository/Query services → Database
→ Provider registry → Provider adapters → External APIs
→ Queue services → Bull queues
Webhook handlers → Handler factories → Event handlers → DB → Redis → WebSocketDesign principles
- Provider abstraction — controllers never know which provider they're talking to.
- Factory pattern for webhooks — each provider has a
canHandle/handlefactory that dispatches to specialized handlers. - Repository services are pure DB; facade services coordinate. This keeps circular deps out.
- Barrel exports per folder; response DTOs via
@Exclude/@Expose+plainToInstance.
The full module reference lives in src/api/v1/messaging/ARCHITECTURE.md (and the
breaking-change log in CHANGES.md).