Creating a Chat Instance
The Chat class is the main entry point for your bot. It coordinates adapters, routes events to your handlers, and manages thread state.
Basic setup
This example uses Redis. Chat SDK also supports PostgreSQL and ioredis as production state adapters. See State Adapters for all options.
Adapter and state factories read their credentials from environment variables such as SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET, and REDIS_URL, so the example above passes no options. Pass explicit values to override them. For setup UIs and build scripts, @chat-adapter/catalog lists official and vendor-official adapter env specs without importing adapter packages.
Multiple adapters
Register several adapters to run the same bot on each of those platforms:
Your event handlers work the same way for every registered adapter, because the SDK normalizes messages, threads, and reactions into one format. Where platforms differ, such as rate limits or unsupported features, the SDK throws typed errors. See Error Handling.
Configuration options
| Option | Type | Default | Description |
|---|---|---|---|
userName | string | required | Default bot username across all adapters |
adapters | Record<string, Adapter> | required | Map of adapter name to adapter instance |
state | StateAdapter | required | State adapter for subscriptions and locking |
logger | Logger | LogLevel | "info" | Logger instance or log level ("debug", "info", "warn", "error", "silent") |
dedupeTtlMs | number | 600000 | TTL in ms for message deduplication (10 minutes) |
concurrency | "drop" | "queue" | "debounce" | "burst" | "concurrent" | ConcurrencyConfig | "drop" | Strategy for overlapping messages on the same thread |
streamingUpdateIntervalMs | number | 500 | Update interval in ms for post+edit streaming |
fallbackStreamingPlaceholderText | string | null | "..." | Placeholder text while streaming starts. Set to null to skip |
lockScope | "thread" | "channel" | function | Adapter default | Whether messages share a lock per thread or per channel. See Lock scope |
history | HistoryConfig | User, thread, and channel history settings. See History | |
onLockConflict | 'drop' | 'force' | (threadId, message) => 'drop' | 'force' | "drop" | Deprecated: use concurrency. Under the drop strategy, 'force' releases the existing lock and re-acquires it so a new message can interrupt a long-running handler |
Accessing adapters
Use getAdapter to access platform-specific APIs when you need functionality beyond the unified interface:
For typed access to the platform's native API client, use the SDK-named getter on each adapter:
The previous .client getter still works as a deprecated alias on all three adapters.
See getAdapter for multi-tenant constraints.
Webhook routing
The webhooks property provides a typed handler for each registered adapter. Wire each one to a route in your HTTP framework:
Your event handlers can keep running after the webhook responds. waitUntil keeps the function alive until they finish, so a serverless platform doesn't stop them early. These examples use Next.js after. In other Vercel Functions, pass waitUntil from @vercel/functions.
Lifecycle
The Chat instance initializes lazily on the first webhook. You can also initialize manually:
For graceful shutdown, such as during serverless teardown, call shutdown:
Singleton pattern
Register a singleton when you need to access the Chat instance from multiple files:
Direct messaging
Open a DM thread with a user by passing their platform user ID or an Author object:
Channel access
Get a channel directly by its ID:
Read more
Handling Events
Register handlers for mentions, messages, reactions, member joins, and platform-specific events.
Overview
Overview of Chat SDK adapters, adapter tiers, and where to find platform, state, and catalog guides.
State Adapters
State adapters store thread subscriptions, distributed locks, and cached data for your bot.
Chat
The class that coordinates adapters, state, and event handlers for a multi-platform chat bot.