Loading...
Chat
Chat
Chat

Chat

Real-time direct messages and group chats with @mentions, presence, and search.

MangoApps

Category
Productivity & Utility
Version
1.0.0
Installs
2
Published
Apr 2026
Type
App

Overview

Pusher-powered real-time chat with one-to-one DMs, group rooms, @mentions feeding the existing Notification system, per-room presence, and PostgreSQL full-text search. Built on the same business-scoping and authentication patterns as the rest of the platform — every message is searchable, auditable, and tenant-isolated.

Highlights

Real-time direct messages and group conversations powered by Pusher Channels.
Built on PostgreSQL — every message is searchable, auditable, and tenant-isolated.
Per-room presence shows who is online without flooding a global presence channel.
@mentions feed the existing Notification system for cross-app continuity.
Configurable per-business retention, attachment size limits, and feature toggles.
Mobile clients reuse the same authenticated WebSocket flow — no separate transport.

Capabilities

Conversations
  • One-to-one direct messages Auto-deduped per pair — starting a chat with someone you already DM'd opens the existing room.
  • Group rooms with role-based admin/member Creator becomes room admin; admins add/remove members, members can leave (sole-admin guard prevents orphaned rooms).
  • Public business channels `channel` is a first-class room_type alongside `direct` and `group`; member management mirrors groups today.
  • Threaded replies Flat one-level threads via an offcanvas panel; replies fan out over the parent room's Pusher channel.
  • Message edit and delete Edit re-flows the FTS vector and (when enabled) the semantic embedding; delete is soft (deleted_at) so audit trails survive.
Real-time Delivery
  • Sub-second message fan-out via Pusher Channels CreateMessageJob persists then triggers `message:created` on `private-room-<id>`.
  • Per-room presence (Pusher presence channels) `presence-room-<id>` authorized through the same business + room-membership gate; payload drives the avatar strip.
  • Typing indicators Client-event over the room's Pusher channel; admin-toggleable per business.
  • Global online status (cache-based heartbeat) `PresenceService.heartbeat!` keeps a per-business cache; `/presence/online` returns who is up in a single batch.
Notifications & Discovery
  • Unread message counts per room UpdateUnreadCountsJob pushes `inbox:unread-changed` to the per-user-per-business inbox channel.
  • Read receipts BroadcastReadReceiptJob fires `message:read` after the DB write commits; admin-toggleable; suppressed in channels.
  • @mention notifications via Notification NotifyMentionedUsersJob inserts platform Notification rows so the bell badge / Action Cable fan-out is reused.
  • Dedicated Mentions inbox Reverse-chronological feed of every chat mention with cursor pagination and jump-to-message.
  • PostgreSQL full-text search `search_vector` (tsvector + GIN index) written before_save; results highlight matches with `<mark>` tags.
  • Semantic search via pgvector Admin-gated (semantic_search_enabled). EmbedMessageJob keeps row embeddings fresh on create + edit; BackfillEmbeddingsJob seeds history.
Files & Reactions
  • File attachments via Active Storage Drag-and-drop or paperclip upload; up to 10 files per message; size + extension + MIME blocklist enforced server-side.
  • Emoji reactions on messages Toggleable from the 10-emoji default set via Platform::Reactable; BroadcastReactionJob pushes `message:reacted` to all subscribers.
Analytics & Insights
  • Admin analytics dashboard Adoption %, DAU/MAU stickiness, cross-department %, and mention response rate — admin_or_above? or chat_app_admin? gated.
  • CSV export of analytics Single file with summary metrics, 30-day DAU, 12-week adoption trend, and top department-pair message volumes.
  • Personal activity dashboard Active conversations, mention response time vs. team median, messaging-hours heatmap, top conversations.
Clients & API
  • Mobile web (iOS & Android browsers) Dedicated `/m/apps/chat` controllers and views — room list, room view, mentions, send.
  • Desktop client (Mac & Windows) MangoMessenger Electron app reuses the Pusher transport and JSON API; download surfaced from the chat dashboard.
  • REST API for every web feature `/api/v1/chat/{rooms,messages,members,threads,reactions,search,mentions,presence,settings,pusher}` — Bearer-token or session auth.
Admin Controls
  • Toggle direct messages globally
  • Toggle group chats globally Also gates channel creation today.
  • Toggle file uploads globally Hides the paperclip button when off; server-side validation refuses uploads either way.
  • Toggle typing indicators
  • Toggle read receipts
  • Toggle semantic search Off by default — flipping on requires a one-time embeddings backfill via BackfillEmbeddingsJob.
  • Configurable max attachment size Per-file MB cap, validated in the Message model on every save.
  • Configurable retention policy Auto-purge ships with pg_partman partitioning in Phase 4.
  • Per-business feature flags
Limits & Specs
  • Real-time transport: Pusher Channels (Premium / Growth tier)
  • Message storage: PostgreSQL (single non-partitioned table — partitioned at ~100M rows)
  • Default retention: Forever (auto-purge ships with Phase 4 partitioning)
  • Default max attachment size: 25 MB per file (admin-configurable, 1–500 MB)
  • Max attachments per message: 10
  • Reaction emoji set: 10 platform-default emojis (Platform::Reaction::DEFAULT_EMOJI_SET)
  • Mobile support: iOS & Android via mobile web; native via the same Pusher endpoint
  • Pricing: Included with MangoApps Workforce

Use cases

Quick coordination
Send a direct message to a teammate without leaving the workforce platform.
Project group chat
Spin up a group room scoped to a specific project with persistent searchable history.
Mention-driven follow-up
@mention a teammate to pull them into a conversation; the existing Notification system carries the alert through email and mobile push.
Compliance recordkeeping
All messages live in PostgreSQL alongside the rest of the platform, so exports, GDPR deletion, and audit trails reuse existing infrastructure.

FAQ

Pusher Channels handles fan-out. The browser subscribes to a per-room private channel; Rails authorizes the subscription against business and room membership before signing the auth response. Four background jobs trigger the four event types: `message:created` (CreateMessageJob), `message:read` (BroadcastReadReceiptJob), `message:reacted` (BroadcastReactionJob), and `inbox:unread-changed` (UpdateUnreadCountsJob).

Messages still persist to PostgreSQL via the standard HTTP request/response — CRUD never depends on Pusher. Real-time delivery, typing indicators, presence, and read receipts degrade gracefully; a refresh shows the missed messages. The Pusher auth endpoint returns a clean 503 (`pusher_unconfigured`) when env vars are blank so the JS client surfaces a friendly error rather than an opaque 500.

Yes. Pusher's Premium and Growth tiers handle 10k+ concurrent connections per cluster. The Rails layer only handles auth at subscription time, not the WebSocket itself, so it scales independently. Message storage is a single non-partitioned table today; pg_partman partitioning is planned at ~100M rows.

Three layers, all run inside the Pusher auth endpoint before signing: (1) channel-name regex (`private-room-`, `presence-room-`, `private-user-inbox--business-`), (2) business membership of current_user, and (3) room membership inside that business. Pusher itself never touches business data, and channel-derived ids are only ever used to look up records — server state is the source of truth.

Read receipts (`Seen by …`) appear on sent messages in DMs and group rooms; channels are intentionally excluded. The admin Settings page has a single toggle (Realtime → Read receipts); when off, BroadcastReadReceiptJob short-circuits and the UI hides the indicator on the next render.

Keyword (PostgreSQL full-text) search is on by default and covers most needs. Semantic search adds a "find a message about…" mode powered by pgvector embeddings — useful when you want to search by meaning rather than exact words. It is admin-gated (off by default) because flipping it on requires a one-time embedding backfill via BackfillEmbeddingsJob; ongoing inserts and edits keep their embeddings fresh automatically.

Up to 10 files per message, with a 25 MB per-file default cap that admins can tune from 1 to 500 MB. Executable / scriptable file types are server-side blocked by both extension and MIME type as a defense-in-depth measure — the composer rejects them client-side too, but the Message model is the source of truth.

Yes. Admins (or per-app `chat_app_admin?`) see four widgets at `/apps/chat/analytics`: Adoption (12-week trend), DAU/MAU stickiness (30-day), Cross-department communication (% of messages crossing departments, plus the top dept-pair breakdown), and Mention response rate (1h / 4h / 24h with median response time). All four are CSV-exportable in a single file.

Ask AI Product Advisor

Hi! I'm the MangoApps Product Advisor. I can help you with:

  • Understanding our 40+ workplace apps
  • Finding the right solution for your needs
  • Answering questions about pricing and features
  • Pointing you to free tools you can try right now

What would you like to know?