> ## Documentation Index
> Fetch the complete documentation index at: https://docs.switchbord.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Advanced Inbox Features

> Powering agent productivity with media support, advanced search, and CRM integration.

The Switchbord Inbox is more than just a chat interface; it's a high-performance tool for customer relationship management.

## Media and Attachments

Support for rich media allows agents to provide comprehensive support:

* **Image/Video Support**: Inline rendering of received media.
* **Document Sending**: Share PDFs, receipts, or manuals directly in the chat.
* **Voice Messages**: Listen to customer voice notes directly within the inbox.
* **Drag-and-Drop**: Easily upload attachments by dragging them into the composer.

## Advanced Search and Filtering

Find exactly what you need in seconds, even across thousands of conversations.

### Global Search

Search for keywords across all message histories. The engine indexes both incoming and outgoing messages for rapid retrieval.

### Conversation Filtering

Filter the inbox view by:

* **Assignee**: View chats handled by specific team members.
* **Tags**: Drill down into segments (e.g., "Urgent", "Lead").
* **Status**: Toggle between `Open`, `Pending`, and `Resolved` states.
* **Unread / Unresponded**: Focus the list on threads that still require operator attention.
* **Groups**: Show only metadata-backed WhatsApp group conversations, useful for internal team pilots and tourism cohort operations.
* **Last Interaction**: Find conversations that have been idle for a specific duration.

### WhatsApp group conversations

Switchbord can mark conversations as groups through `conversations.metadata` and expose them in the inbox via a **Groups** pill next to the conversation filters. This first release is a visibility and filtering foundation: full group lifecycle management, participant management, invite-link controls, and group-specific send constraints remain follow-up work.

## Connection health

### Realtime keepalive and the connection banner

The inbox depends on a persistent Supabase Realtime WebSocket to show inbound messages live. Backgrounded or sleeping browser tabs throttle timers and the OS can drop that socket without the tab noticing — the classic "the app looks down until I hard-refresh" failure. A `useRealtimeKeepalive` hook now keeps the connection honest:

* **On tab wake** (`visibilitychange → visible`, window `focus`, or the browser's `online` event) it reconnects the realtime socket and channels if they're unhealthy, and **always** runs a catch-up refetch of conversations plus the open thread — a slept tab has usually missed events even if the socket itself survived.
* **A heartbeat check** every 20 seconds, only while the tab is visible, verifies the socket still reports connected. If not, it recovers automatically — the connection can't silently stay dead indefinitely.
* **Wake bursts are debounced** into a single recovery pass, since `visibilitychange`, `focus`, and `online` often fire together.

The inbox surfaces this state through a non-silent banner above the conversation list, localized in all 7 app locales:

| Banner            | When                                                        | Look                                       |
| ----------------- | ----------------------------------------------------------- | ------------------------------------------ |
| "Reconnecting…"   | Socket is unhealthy and the keepalive hook is recovering it | Amber, spinner icon                        |
| "You're offline…" | `navigator.onLine` is false                                 | Red, offline icon                          |
| *(hidden)*        | Connected (the steady state)                                | No banner — zero chrome in the common case |

<Info>
  The whole point of this feature is that the inbox must never *appear* live while actually disconnected. If you see stale conversations with no banner, that's a bug — file it rather than assuming a hard refresh fixed something silently broken.
</Info>

## Persisted conversation tabs

Above the chat pane, the inbox keeps Chrome-style tabs for the conversations an operator has open — so switching between a handful of active threads doesn't require going back to the sidebar every time.

* Tabs are capped at **8** — opening a ninth conversation drops the oldest tab.
* Since v0.18.14/v0.18.22, tabs **persist across refresh** (manual F5, a server-component refresh, or a realtime-driven remount) via `localStorage`, namespaced per workspace (`switchbord.inbox.tabs.<workspaceId>`) so tabs never bleed between workspaces. Reads/writes are SSR-safe and tolerant of corrupt or empty stored values.
* A tab whose conversation has unread inbound messages gets the same emerald highlight as an unread row in the conversation list — fill, a top-edge accent, an emerald dot, and a bolded title. The active tab never shows unread (viewing a conversation clears it).
* Each tab also carries that conversation's live GB-Agent "Draft with me" status badge (violet/pulsing while generating, green when ready, amber on handoff, red on failure, hidden when idle) — see [gb-agent Connector → Draft with me](/platform/gb-agent-connector#draft-with-me-per-conversation-streaming-assist) for the full status-badge semantics.

## CRM Integration

The Inbox is tightly integrated with the contact database:

* **Contact Sidebar**: View detailed customer profiles, including custom fields and past activity, without leaving the conversation.
* **Tag Management**: Add or remove tags in real-time to update a contact's segment.
* **Avatar Resolution**: Automatically pulls avatars from public profiles or CRM integrations to help agents recognize frequent contacts.

## Productivity Tools

* **Quick Replies**: Pre-defined templates for common questions to ensure fast, consistent responses.
* **Internal Notes**: Leave private comments for other team members within a conversation thread.
* **Assignment Logic**: Manually or automatically route conversations to the right agent or team.
