2.10.2 Inbox — Channels and Connected Sources

The Inbox aggregates communication from multiple external and internal origins through a unified channel abstraction. A channel represents a technical and semantic bridge between Praisma Hub and an external system, platform, or internal service. Channels normalize inbound and outbound messages into a consistent conversation model while preserving source-specific metadata for traceability, automation, and compliance.

Channel Abstraction Model

Each channel is defined as a first-class entity with explicit configuration, authentication scope, and lifecycle state. Channels are not UI constructs; they are infrastructural objects that govern how data enters and exits the Inbox.

Core properties include:

Channel type (social, email, webhook, internal)

Authentication context and permissions

Message directionality (inbound, outbound, bidirectional)

Activation and suspension state

This abstraction allows heterogeneous sources to behave uniformly at the Inbox level without leaking protocol-specific complexity into conversation handling.

Connected Source Mapping

Incoming events from connected sources are deterministically mapped to conversations and threads. Mapping rules are stable and idempotent to prevent duplication during retries or delayed delivery.

Typical mapping keys include:

External thread or conversation identifiers

Participant or sender identifiers

Channel-specific correlation IDs

Example pseudo-mapping logic:

$conversation = Conversation::firstOrCreate([ 'channel_id' => $channel->id, 'external_reference' => $payload['thread_id'], ]); $conversation->messages()->create([ 'direction' => 'inbound', 'source' => $channel->type, 'payload' => $payload, ]);

Authentication and Permissions

Each channel operates under a scoped authentication context. Tokens, secrets, or credentials are stored encrypted and resolved at runtime only when required. Permissions are evaluated at both the channel and action level to ensure that only authorized operations are performed.

Channel permissions govern:

Read access to incoming messages

Write or reply capabilities

Event subscription scope

Example configuration fragment:

{ "channel": "instagram", "permissions": ["messages.read","messages.write"], "status": "active" }

Message Normalization

All inbound messages are normalized into a canonical internal schema before persistence. This schema abstracts away protocol differences while retaining raw payloads for audit and debugging.

Normalized fields typically include:

Message body and attachments

Sender identity and role

Timestamps and delivery status

Raw source payload (immutable)

This ensures that downstream features such as analytics, automation, and search operate consistently across channels.

Reliability, Retries, and Idempotency

Connected channels are designed to tolerate network failures and third-party instability. Inbound processing is idempotent, and outbound delivery supports retries with exponential backoff where applicable.

Key guarantees:

Duplicate events do not create duplicate messages

Temporary failures do not corrupt conversation state

Delivery outcomes are explicitly recorded

Example retry-safe handler:

if ($event->alreadyProcessed()) { return; } $event->markProcessed(); $inboxService->handle($event);

Channel Lifecycle Management

Channels can be enabled, disabled, or rotated without impacting existing conversations. Historical data remains accessible even when a channel is disconnected or credentials expire.

Lifecycle actions include:

Credential rotation

Temporary suspension

Permanent disconnection

These actions never delete conversation or message data.

Security and Isolation

All channel operations are tenant-scoped and isolated by design. No channel can read or write data outside its assigned tenant or organization context. Secrets are never exposed to the client layer.