Skip to content

Architecture Overview

┌──────────────────────────────────────────────────────────┐
│ Clients │
│ Mobile App │ Web Dashboard │ AI Agents (MCP) │
└──────┬───────┴────────┬────────┴────────┬────────────────┘
│ │ │
▼ ▼ ▼
┌──────────────────────────────────────────────────────────┐
│ Nginx (Reverse Proxy) │
│ HTTP → Gunicorn WS → Daphne │
└──────┬───────────────────────────────┬───────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ Django REST │ │ Django Channels │
│ Framework │ │ (WebSocket) │
│ │ │ │
│ JWT Auth │ │ TeamInboxConsumer │
│ ViewSets │ │ Real-time msgs │
│ Serializers │ │ │
└──────┬──────────┘ └────────┬──────────┘
│ │
▼ ▼
┌──────────────────────────────────────────────────────────┐
│ Channel Registry │
│ ┌──────────┐ ┌──────────┐ ┌──────┐ ┌──────┐ │
│ │ WhatsApp │ │ Telegram │ │ SMS │ │ RCS │ │
│ │ (Meta, │ │ │ │(Twil,│ │(GRBM,│ │
│ │ Gupshup) │ │ │ │MSG91,│ │MetaR)│ │
│ │ │ │ │ │F2SMS)│ │ │ │
│ └──────────┘ └──────────┘ └──────┘ └──────┘ │
└──────────────────────────────────────────────────────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌──────────────────────────────────────────────────────────┐
│ External APIs │
│ Meta Graph API │ Telegram Bot │ Twilio │ Google RBM │
└──────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────┐
│ PostgreSQL │ Redis │ Celery Workers │
└──────────────────────────────────────────────────────────┘

Jina Connect is organized into Django apps, each owning a bounded context:

AppResponsibilityKey Models
usersUser accounts, auth, password resetUser
tenantsMulti-tenancy, RBAC, API keys, mediaTenant, TenantUser, TenantRole, TenantAccessKey
waWhatsApp messaging, BSP adapters, templatesWATemplate, WAMessage, TenantWAApp
telegramTelegram bot management, messagingTelegramBotApp, TelegramOutboundMessage
smsSMS multi-provider messagingSMSApp, SMSOutboundMessage
rcsRCS messaging with SMS fallbackRCSApp, RCSOutboundMessage
broadcastCampaign management, URL trackingBroadcast, BroadcastMessage
contactsUnified contact managementTenantContact
team_inboxReal-time shared inbox (WebSocket)Messages, MessageEventIds
chat_flowVisual conversation flow builderChatFlow, ChatFlowNode, ChatFlowEdge
notificationsIn-app notification systemNotification
razorpayPayment gateway integrationRazorpayOrder
transactionWallet credit managementTenantTransaction
mcp_serverMCP server for AI agent integration— (stateless tools)
  1. Client sends HTTP request with JWT Authorization: Bearer <token>
  2. Nginx routes to Gunicorn (or Daphne for ASGI)
  3. SimpleJWT authenticates and resolves User
  4. ViewSet validates tenant context from URL/headers
  5. Serializer validates input, creates/updates models
  6. Channel adapter dispatches to appropriate BSP if messaging
  7. Celery handles async tasks (broadcast batches, webhook delivery)
  8. Response returned with standard pagination
  1. Client connects to ws://host/ws/team-inbox/{tenant_id}/
  2. AuthMiddlewareStack validates JWT from query params
  3. TeamInboxConsumer joins tenant-specific channel group
  4. Messages broadcast to all connected agents in real-time
  5. Typing indicators, read receipts, assignment updates — all via WebSocket
  1. External provider (Meta, Telegram, Twilio, Google) sends webhook POST
  2. Webhook view verifies signature (provider-specific)
  3. Raw event stored in *WebhookEvent table
  4. Message parsed and stored in app-specific message model
  5. Team inbox notified via Channels (WebSocket broadcast)
  6. Chat flow engine evaluates if any active flows should trigger

Jina Connect uses Django Channels with a ProtocolTypeRouter:

jina_connect/routing.py
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": AuthMiddlewareStack(
URLRouter(
team_inbox.routing.websocket_urlpatterns
)
),
})

Both HTTP and WebSocket traffic is served through Daphne in Docker. In production, you can split HTTP → Gunicorn and WebSocket → Daphne behind Nginx.

Background task processing handles:

TaskScheduleDescription
Template status syncEvery 2 minutesSyncs template approval status from BSPs
Broadcast status checkEvery 1 minuteUpdates campaign delivery metrics
Notification cleanupDaily at 3:00 AMRemoves old notification records
SMS/RCS counter resetDaily at midnightResets daily message counters
Broadcast batch processingOn-demandSends messages in configurable batches
Webhook event deliveryOn-demandDelivers webhook events to subscriber endpoints

All models inherit from BaseModel (in abstract/models.py) which provides:

  • id — UUID primary key
  • created_at — Auto-set creation timestamp
  • updated_at — Auto-updated modification timestamp

Sensitive fields (API tokens, provider credentials, bot tokens) use django-encrypted-model-fields with the FIELD_ENCRYPTION_KEY Fernet key.