Corteksa
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 ──▶ Database

Sending 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 ──▶ UI

Building blocks

LayerWhereJob
Facade servicessessions/, chats/, messages/, calls/, labels/Coordinate repositories, queues, and providers
Provider adaptersproviders/{waha,whatsapp-cloud,facebook,instagram,tiktok}/Implement IMessagingProvider (session, message, presence)
Provider registryservices/provider-registryResolve the adapter for a ProviderType
Queues (Bull)core/constants/queue-names.tsText send, media send, read receipt, chat sync, message sync, ack update
Realtimerealtime/messaging-events.gateway.tsSocket.IO namespace /messaging/events
Webhookswebhooks/Inbound provider events, per-provider handler factories
Access controlcore/services/chat-access-filter.builder.ts, chat-visibility.policy.tsRow-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 → WebSocket

Design principles

  • Provider abstraction — controllers never know which provider they're talking to.
  • Factory pattern for webhooks — each provider has a canHandle / handle factory 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).

On this page