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 start → Auth → Props
Platform / SREData model → Configuration → Deployment
Security reviewSecurity
Day-2 opsOperations

AW Chat SDK — integration & platform handoff docs.