Chat SDK

SkillDev tools

Guides your agent to build chat SDK skill-based bots that run across Slack, Teams, Discord, Telegram and more.

Use Chat SDK in Claude, ChatGPT or Ahel Desktop

Free. Sign in, add Chat SDK and connect your AI. About a minute.

Also: Claude Code · Cursor · Codex

Then ask your AI: use the Chat SDK skill

Details

Instructions available. Your AI can read the instructions. Execution depends on the setup they require.

Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.

Chat SDKStart free
About this skill

Use for multi-platform bots built with chat SDK: webhooks, mentions, slash commands, cards, modals and streaming.

What this skill tells your AI

The instructions your AI receives, as published by lobehub/lobehub in .agents/skills/chat-sdk/SKILL.md and read by ahel’s review.

Unified TypeScript SDK for building chat bots across Slack, Teams, Google Chat, Discord, GitHub, and Linear. Write bot logic once, deploy everywhere.

Critical: Read the bundled docs

The chat package ships with full documentation in node_modules/chat/docs/ and TypeScript source types. Always read these before writing code:

node_modules/chat/docs/           # Full documentation (MDX files)
node_modules/chat/dist/           # Built types (.d.ts files)

Key docs to read based on task:

  • docs/getting-started.mdx — setup guides
  • docs/usage.mdx — event handlers, threads, messages, channels
  • docs/streaming.mdx — AI streaming with AI SDK
  • docs/cards.mdx — JSX interactive cards
  • docs/actions.mdx — button/dropdown handlers
  • docs/modals.mdx — form dialogs (Slack only)
  • docs/adapters.mdx, docs/platform-adapters.mdx — adapter overview and platform-specific setup
  • docs/state-adapters.mdx — state adapter config (Redis, ioredis, memory)

Also read the TypeScript types from node_modules/chat/dist/ to understand the full API surface.

Quick start

import { Chat } from 'chat';
import { createSlackAdapter } from '@chat-adapter/slack';
import { createRedisState } from '@chat-adapter/state-redis';

const bot = new Chat({
  userName: 'mybot',
  adapters: {
    slack: createSlackAdapter({
      botToken: process.env.SLACK_BOT_TOKEN!,
      signingSecret: process.env.SLACK_SIGNING_SECRET!,
    }),
  },
  state: createRedisState({ url: process.env.REDIS_URL! }),
});

bot.onNewMention(async (thread) => {
  await thread.subscribe();
  await thread.post("Hello! I'm listening to this thread.");
});

bot.onSubscribedMessage(async (thread, message) => {
  await thread.post(`You said: ${message.text}`);
});

Core concepts

  • Chat — main entry point, coordinates adapters and routes events
  • Adapters — platform-specific (Slack, Teams, GChat, Discord, GitHub, Linear)
  • State — pluggable persistence (Redis for prod, memory for dev)
  • Thread — conversation thread with post(), subscribe(), startTyping()
  • Message — normalized format with text, formatted (mdast AST), raw
  • Channel — container for threads, supports listing and posting

Event handlers

HandlerTrigger
onNewMentionBot @-mentioned in unsubscribed thread
onSubscribedMessageAny message in subscribed thread
onNewMessage(regex)Messages matching pattern in unsubscribed threads
onSlashCommand("/cmd")Slash command invocations
onReaction(emojis)Emoji reactions added/removed
onAction(actionId)Button clicks and dropdown selections
onAssistantThreadStartedSlack Assistants API thread opened
onAppHomeOpenedSlack App Home tab opened

Streaming

Pass any AsyncIterable<string> to thread.post(). Works with AI SDK's textStream:

import { ToolLoopAgent } from 'ai';
const agent = new ToolLoopAgent({ model: 'anthropic/claude-sonnet-5' });

bot.onNewMention(async (thread, message) => {
  const result = await agent.stream({ prompt: message.text });
  await thread.post(result.textStream);
});

Cards (JSX)

Set jsxImportSource: "chat" in tsconfig. Components: Card, CardText, Button, Actions, Fields, Field, Select, SelectOption, Image, Divider, LinkButton, Section, RadioSelect.

await thread.post(
  <Card title="Order #1234">
    <CardText>Your order has been received!</CardText>
    <Actions>
      <Button id="approve" style="primary">
        Approve
      </Button>
      <Button id="reject" style="danger">
        Reject
      </Button>
    </Actions>
  </Card>,
);

Packages

chat and the @chat-adapter/* packages are an external SDK this repo consumes (pinned via semver range in package.json), not something built or versioned here — there's no Changesets/release flow to document for them.

PackagePurpose
chatCore SDK
@chat-adapter/discordDiscord
@chat-adapter/slackSlack
@chat-adapter/telegramTelegram
@chat-adapter/state-ioredisioredis state
@lobechat/chat-adapter-feishuLark/Feishu — built in-repo (packages/chat-adapter-feishu), not from @chat-adapter/
@lobechat/chat-adapter-imessageiMessage via BlueBubbles — built in-repo
@lobechat/chat-adapter-lineLINE Messaging API — built in-repo
@lobechat/chat-adapter-qqQQ Bot — built in-repo
@lobechat/chat-adapter-wechatWeChat (iLink) — built in-repo

Webhook setup

Each adapter exposes a webhook handler via bot.webhooks.{platform}. Wire these to your HTTP framework's routes (e.g. Next.js API routes, Hono, Express).

Advanced
Item type
skill
Key
chat-sdk-lobehub
Source
github.com/lobehub/lobehub