Skip to content

System overview

AW Chat is a custom in-app support stack. Clients never talk to Intercom directly: they call your @aw-chat/server, which owns secrets, storage, and fan-out to Intercom / push providers.

Topology

┌─────────────────┐     ┌─────────────────┐
│  Host app (web) │     │ Host app (RN)   │
│  @aw-chat/web   │     │ @aw-chat/rn     │
└────────┬────────┘     └────────┬────────┘
         │  HTTP + polling       │
         └───────────┬───────────┘

              @aw-chat/server
         ┌───────────┼───────────┐
         ▼           ▼           ▼
     Intercom    PostgreSQL     S3
   (chat/tickets (channel,      (file
    contacts)     comments,      bytes)
                  CSAT, …)

         ├── FCM / Telegram (push)
         └── Admin SPA ──▶ /admin/*
ComponentPackage / pathRole
Web / TMA SDK@aw-chat/webDOM UI; polls the backend
React Native SDK@aw-chat/react-nativeNative UI (no WebView)
Shared client@aw-chat/coreTypes, ApiClient, polling helpers
API@aw-chat/serverHono + Drizzle; Intercom adapter
Admin panel@aw-chat/adminVite SPA for operators / authors
Docs@aw-chat/docsThis VitePress site

Critical design rules

  1. Clients never call Intercom. Access tokens stay on the server.
  2. No WebSocket / SSE. Delivery is HTTP polling (default ~4s). See Limitations.
  3. Two product surfaces, two stores. Support chat/tickets live in Intercom. AW Channel posts and comments live in Postgres. Details in Data model.
  4. CSAT and complaints are first-class in Postgres (admin panel), with best-effort Intercom notes/tags.
  5. One-line host integration. Mount <AWChat /> with props; mint the JWT on your backend.

Request flows (high level)

Support message

  1. Host mints JWT → SDK POST /api/conversations (or reply).
  2. Server resolves userId → Intercom contact (user_contacts cache).
  3. Message + attachment URLs written via Intercom REST.
  4. Operator replies in Intercom → webhook POST /webhooks/intercom.
  5. Server invalidates cache, may send push; SDK picks up on next poll.

Channel comment

  1. SDK POST /api/channel/:id/posts/:postId/comments (body + optional image).
  2. Server enforces DLP / link guard / rate limit → row in channel_comments.
  3. Other clients see it on comment poll (~5s while the thread is open).
  4. Moderation is Postgres + admin APIs (not Intercom).

Channel post publish

  1. Admin authors in @aw-chat/admin → Postgres channel_posts (+ S3 media).
  2. Publish / schedule job marks the post live.
  3. Optional push to devices with channel notifications enabled.
  4. SDK channel feed poll shows the post.

Where to go next

AudienceStart here
App integratorsQuick startAuthProps
Platform / SREData modelConfigurationDeployment
Security reviewSecurity
Day-2 opsOperations

AW Chat SDK — integration & platform handoff docs.