chat 4.19.0 → 4.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-WAB7KMH4.js → chunk-JW7GYSMH.js} +3 -3
- package/dist/chunk-JW7GYSMH.js.map +1 -0
- package/dist/index.d.ts +134 -5
- package/dist/index.js +217 -46
- package/dist/index.js.map +1 -1
- package/dist/jsx-runtime.d.ts +1 -1
- package/dist/jsx-runtime.js +1 -1
- package/docs/adapters/whatsapp.mdx +222 -0
- package/docs/adapters.mdx +54 -0
- package/docs/api/channel.mdx +15 -0
- package/docs/api/index.mdx +1 -0
- package/docs/api/thread.mdx +50 -0
- package/docs/contributing/building.mdx +1 -0
- package/docs/error-handling.mdx +1 -1
- package/docs/getting-started.mdx +2 -0
- package/docs/guides/durable-chat-sessions-nextjs.mdx +331 -0
- package/docs/guides/meta.json +7 -1
- package/docs/guides/scheduled-posts-neon.mdx +447 -0
- package/docs/index.mdx +3 -1
- package/docs/threads-messages-channels.mdx +17 -0
- package/package.json +1 -1
- package/dist/chunk-WAB7KMH4.js.map +0 -1
- package/dist/{jsx-runtime-BYavlUk9.d.ts → jsx-runtime-C2ATKxHQ.d.ts} +95 -95
package/dist/jsx-runtime.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { A as ActionsComponent, B as ButtonComponent, V as ButtonProps, c as CardComponent, W as CardJSXElement, X as CardJSXProps, e as CardLinkComponent, Y as CardLinkProps, Z as CardProps, a as ChatElement, _ as ContainerProps, D as DividerComponent, $ as DividerProps, F as FieldComponent, a0 as FieldProps, f as FieldsComponent, an as Fragment, I as ImageComponent, a1 as ImageProps, ao as JSX, L as LinkButtonComponent, a2 as LinkButtonProps, n as ModalComponent, a3 as ModalProps, R as RadioSelectComponent, S as SectionComponent, o as SelectComponent, p as SelectOptionComponent, a4 as SelectOptionProps, a5 as SelectProps, ai as TableComponent, ah as TableProps, T as TextComponent, q as TextInputComponent, a6 as TextInputProps, a7 as TextProps, aj as isCardLinkProps, h as isJSX, ak as jsx, am as jsxDEV, al as jsxs, t as toCardElement, k as toModalElement } from './jsx-runtime-
|
|
1
|
+
export { A as ActionsComponent, B as ButtonComponent, V as ButtonProps, c as CardComponent, W as CardJSXElement, X as CardJSXProps, e as CardLinkComponent, Y as CardLinkProps, Z as CardProps, a as ChatElement, _ as ContainerProps, D as DividerComponent, $ as DividerProps, F as FieldComponent, a0 as FieldProps, f as FieldsComponent, an as Fragment, I as ImageComponent, a1 as ImageProps, ao as JSX, L as LinkButtonComponent, a2 as LinkButtonProps, n as ModalComponent, a3 as ModalProps, R as RadioSelectComponent, S as SectionComponent, o as SelectComponent, p as SelectOptionComponent, a4 as SelectOptionProps, a5 as SelectProps, ai as TableComponent, ah as TableProps, T as TextComponent, q as TextInputComponent, a6 as TextInputProps, a7 as TextProps, aj as isCardLinkProps, h as isJSX, ak as jsx, am as jsxDEV, al as jsxs, t as toCardElement, k as toModalElement } from './jsx-runtime-C2ATKxHQ.js';
|
package/dist/jsx-runtime.js
CHANGED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: WhatsApp
|
|
3
|
+
description: Configure the WhatsApp adapter for the WhatsApp Business Cloud API.
|
|
4
|
+
type: integration
|
|
5
|
+
prerequisites:
|
|
6
|
+
- /docs/getting-started
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```sh title="Terminal"
|
|
12
|
+
pnpm add @chat-adapter/whatsapp
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
The adapter auto-detects `WHATSAPP_ACCESS_TOKEN`, `WHATSAPP_APP_SECRET`, `WHATSAPP_PHONE_NUMBER_ID`, and `WHATSAPP_VERIFY_TOKEN` from environment variables:
|
|
18
|
+
|
|
19
|
+
```typescript title="lib/bot.ts" lineNumbers
|
|
20
|
+
import { Chat } from "chat";
|
|
21
|
+
import { createWhatsAppAdapter } from "@chat-adapter/whatsapp";
|
|
22
|
+
|
|
23
|
+
const bot = new Chat({
|
|
24
|
+
userName: "mybot",
|
|
25
|
+
adapters: {
|
|
26
|
+
whatsapp: createWhatsAppAdapter(),
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
bot.onNewMention(async (thread, message) => {
|
|
31
|
+
await thread.post(`You said: ${message.text}`);
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Since all WhatsApp conversations are 1:1 DMs, every incoming message is treated as a mention.
|
|
36
|
+
|
|
37
|
+
## Webhook route
|
|
38
|
+
|
|
39
|
+
WhatsApp uses two webhook mechanisms:
|
|
40
|
+
|
|
41
|
+
1. **Verification handshake** (GET) — Meta sends a `hub.verify_token` challenge that must match your `WHATSAPP_VERIFY_TOKEN`.
|
|
42
|
+
2. **Event delivery** (POST) — incoming messages, reactions, and interactive responses, verified via `X-Hub-Signature-256`.
|
|
43
|
+
|
|
44
|
+
Both are handled by the same `handleWebhook` method:
|
|
45
|
+
|
|
46
|
+
```typescript title="app/api/webhooks/whatsapp/route.ts" lineNumbers
|
|
47
|
+
import { bot } from "@/lib/bot";
|
|
48
|
+
|
|
49
|
+
export async function GET(request: Request): Promise<Response> {
|
|
50
|
+
return bot.webhooks.whatsapp(request);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function POST(request: Request): Promise<Response> {
|
|
54
|
+
return bot.webhooks.whatsapp(request);
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Meta app setup
|
|
59
|
+
|
|
60
|
+
### 1. Create a Meta app
|
|
61
|
+
|
|
62
|
+
1. Go to [developers.facebook.com/apps](https://developers.facebook.com/apps)
|
|
63
|
+
2. Click **Create App** and select **Business** type
|
|
64
|
+
3. Give it a name and click **Create App**
|
|
65
|
+
|
|
66
|
+
### 2. Add WhatsApp product
|
|
67
|
+
|
|
68
|
+
1. In the app dashboard, find **WhatsApp** and click **Set Up**
|
|
69
|
+
2. This creates a test phone number and sandbox environment
|
|
70
|
+
|
|
71
|
+
### 3. Get credentials
|
|
72
|
+
|
|
73
|
+
From the app dashboard:
|
|
74
|
+
|
|
75
|
+
| Credential | Where to find it |
|
|
76
|
+
|---|---|
|
|
77
|
+
| **Access Token** | WhatsApp > API Setup > Temporary access token (or create a System User token for production) |
|
|
78
|
+
| **Phone Number ID** | WhatsApp > API Setup > Phone number ID |
|
|
79
|
+
| **App Secret** | Settings > Basic > App Secret |
|
|
80
|
+
| **Verify Token** | You define this — any secret string you choose |
|
|
81
|
+
|
|
82
|
+
### 4. Configure webhooks
|
|
83
|
+
|
|
84
|
+
1. Go to **WhatsApp** > **Configuration** in your app dashboard
|
|
85
|
+
2. Click **Edit** next to Webhook URL
|
|
86
|
+
3. Set **Callback URL** to `https://your-domain.com/api/webhooks/whatsapp`
|
|
87
|
+
4. Set **Verify token** to the same value as your `WHATSAPP_VERIFY_TOKEN`
|
|
88
|
+
5. Click **Verify and Save**
|
|
89
|
+
6. Subscribe to the **messages** webhook field
|
|
90
|
+
|
|
91
|
+
### 5. Production access
|
|
92
|
+
|
|
93
|
+
For production use:
|
|
94
|
+
|
|
95
|
+
1. Add a real phone number under **WhatsApp** > **API Setup**
|
|
96
|
+
2. Create a **System User** in Meta Business Suite for a permanent access token
|
|
97
|
+
3. Complete Meta's **App Review** process for the `whatsapp_business_messaging` permission
|
|
98
|
+
|
|
99
|
+
## Interactive messages
|
|
100
|
+
|
|
101
|
+
Card elements are automatically converted to WhatsApp interactive messages:
|
|
102
|
+
|
|
103
|
+
- **3 or fewer buttons** — rendered as WhatsApp reply buttons (title max 20 characters)
|
|
104
|
+
- **More than 3 buttons** — falls back to formatted text
|
|
105
|
+
|
|
106
|
+
```typescript title="lib/bot.ts" lineNumbers
|
|
107
|
+
import { Card, Actions, Button, Body, BodyText } from "chat";
|
|
108
|
+
|
|
109
|
+
bot.onNewMention(async (thread) => {
|
|
110
|
+
await thread.post(
|
|
111
|
+
<Card>
|
|
112
|
+
<Body>
|
|
113
|
+
<BodyText>How can I help?</BodyText>
|
|
114
|
+
</Body>
|
|
115
|
+
<Actions>
|
|
116
|
+
<Button id="help" value="help">Get Help</Button>
|
|
117
|
+
<Button id="status" value="status">Check Status</Button>
|
|
118
|
+
</Actions>
|
|
119
|
+
</Card>
|
|
120
|
+
);
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Media attachments
|
|
125
|
+
|
|
126
|
+
Incoming media messages (images, documents, audio, video, voice, stickers) are exposed as attachments with a lazy `fetchData()` function. Media is downloaded in two steps via the Graph API — first fetching the media URL, then downloading the binary data.
|
|
127
|
+
|
|
128
|
+
```typescript title="lib/bot.ts" lineNumbers
|
|
129
|
+
bot.onNewMention(async (thread, message) => {
|
|
130
|
+
for (const attachment of message.attachments) {
|
|
131
|
+
if (attachment.fetchData) {
|
|
132
|
+
const data = await attachment.fetchData();
|
|
133
|
+
// Process the media buffer...
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## 24-hour messaging window
|
|
140
|
+
|
|
141
|
+
WhatsApp enforces a [24-hour customer service window](https://developers.facebook.com/docs/whatsapp/cloud-api/guides/send-messages#customer-service-windows). You can only send free-form messages to a user within 24 hours of their last message. After that, you must use approved **message templates**.
|
|
142
|
+
|
|
143
|
+
## Configuration
|
|
144
|
+
|
|
145
|
+
All options are auto-detected from environment variables when not provided.
|
|
146
|
+
|
|
147
|
+
| Option | Required | Description |
|
|
148
|
+
|--------|----------|-------------|
|
|
149
|
+
| `accessToken` | No* | Meta access token. Auto-detected from `WHATSAPP_ACCESS_TOKEN` |
|
|
150
|
+
| `appSecret` | No* | App secret for webhook signature verification. Auto-detected from `WHATSAPP_APP_SECRET` |
|
|
151
|
+
| `phoneNumberId` | No* | Bot's phone number ID. Auto-detected from `WHATSAPP_PHONE_NUMBER_ID` |
|
|
152
|
+
| `verifyToken` | No* | Secret for webhook verification handshake. Auto-detected from `WHATSAPP_VERIFY_TOKEN` |
|
|
153
|
+
| `apiVersion` | No | Graph API version (defaults to `v21.0`) |
|
|
154
|
+
| `userName` | No | Bot username. Auto-detected from `WHATSAPP_BOT_USERNAME` or defaults to `whatsapp-bot` |
|
|
155
|
+
| `logger` | No | Logger instance (defaults to `ConsoleLogger("info")`) |
|
|
156
|
+
|
|
157
|
+
*All four credentials are required — either via config or environment variables.
|
|
158
|
+
|
|
159
|
+
## Environment variables
|
|
160
|
+
|
|
161
|
+
```bash title=".env.local"
|
|
162
|
+
WHATSAPP_ACCESS_TOKEN=EAAx... # Meta access token
|
|
163
|
+
WHATSAPP_APP_SECRET=abc123... # App secret for signature verification
|
|
164
|
+
WHATSAPP_PHONE_NUMBER_ID=1234567890 # Phone number ID from Meta dashboard
|
|
165
|
+
WHATSAPP_VERIFY_TOKEN=my-secret # Your chosen webhook verify token
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Features
|
|
169
|
+
|
|
170
|
+
| Feature | Supported |
|
|
171
|
+
|---------|-----------|
|
|
172
|
+
| Mentions | N/A (all messages are DMs) |
|
|
173
|
+
| Reactions (add/remove) | Yes |
|
|
174
|
+
| Cards | Interactive messages (max 3 buttons) / text fallback |
|
|
175
|
+
| Modals | No |
|
|
176
|
+
| Streaming | No |
|
|
177
|
+
| DMs | Yes (all conversations) |
|
|
178
|
+
| Ephemeral messages | No |
|
|
179
|
+
| File uploads | Receive only |
|
|
180
|
+
| Typing indicator | Yes |
|
|
181
|
+
| Message history | No |
|
|
182
|
+
| Edit message | No (throws) |
|
|
183
|
+
| Delete message | No (throws) |
|
|
184
|
+
|
|
185
|
+
## Thread ID format
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
whatsapp:{phoneNumberId}:{userWaId}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Example: `whatsapp:1234567890:15551234567`
|
|
192
|
+
|
|
193
|
+
## Notes
|
|
194
|
+
|
|
195
|
+
- All WhatsApp conversations are 1:1 DMs between the business phone number and the user, so every message sets `isMention: true`.
|
|
196
|
+
- `editMessage()` and `deleteMessage()` throw errors — WhatsApp does not support these operations.
|
|
197
|
+
- `fetchMessages()` returns empty results — WhatsApp does not provide a message history API.
|
|
198
|
+
- Messages exceeding 4096 characters are automatically split at paragraph or line boundaries.
|
|
199
|
+
- Webhook signatures are verified using HMAC-SHA256 with `timingSafeEqual` for timing-attack resistance.
|
|
200
|
+
|
|
201
|
+
## Troubleshooting
|
|
202
|
+
|
|
203
|
+
### Webhook verification failing
|
|
204
|
+
|
|
205
|
+
- Verify `WHATSAPP_VERIFY_TOKEN` matches what you set in the Meta dashboard
|
|
206
|
+
- Ensure both GET and POST routes are configured for the webhook URL
|
|
207
|
+
|
|
208
|
+
### "Invalid signature" error
|
|
209
|
+
|
|
210
|
+
- Check that `WHATSAPP_APP_SECRET` is correct (find it under Settings > Basic in your Meta app)
|
|
211
|
+
- Ensure the raw request body is not parsed before verification
|
|
212
|
+
|
|
213
|
+
### Bot not responding
|
|
214
|
+
|
|
215
|
+
- Confirm the **messages** webhook field is subscribed in Meta dashboard
|
|
216
|
+
- Check that you're within the 24-hour messaging window (or using template messages)
|
|
217
|
+
- Verify the phone number ID matches your configured `WHATSAPP_PHONE_NUMBER_ID`
|
|
218
|
+
|
|
219
|
+
### Media downloads failing
|
|
220
|
+
|
|
221
|
+
- Ensure your access token has the required permissions
|
|
222
|
+
- Check that the media hasn't expired (WhatsApp media URLs are temporary)
|
package/docs/adapters.mdx
CHANGED
|
@@ -10,6 +10,60 @@ Adapters handle webhook verification, message parsing, and API calls for each pl
|
|
|
10
10
|
|
|
11
11
|
Ready to build your own? Follow the [building](/docs/contributing/building) guide.
|
|
12
12
|
|
|
13
|
+
## Feature matrix
|
|
14
|
+
|
|
15
|
+
### Messaging
|
|
16
|
+
|
|
17
|
+
| Feature | [Slack](/adapters/slack) | [Teams](/adapters/teams) | [Google Chat](/adapters/google-chat) | [Discord](/adapters/discord) | [Telegram](/adapters/telegram) | [GitHub](/adapters/github) | [Linear](/adapters/linear) | [WhatsApp](/adapters/whatsapp) |
|
|
18
|
+
|---------|-------|-------|-------------|---------|---------|--------|--------|-----------|
|
|
19
|
+
| Post message | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
20
|
+
| Edit message | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
21
|
+
| Delete message | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
|
|
22
|
+
| File uploads | ✅ | ✅ | ❌ | ✅ | ⚠️ Single file | ❌ | ❌ | ✅ Images, audio, docs |
|
|
23
|
+
| Streaming | ✅ Native | ⚠️ Post+Edit | ⚠️ Post+Edit | ⚠️ Post+Edit | ⚠️ Post+Edit | ❌ | ❌ | ❌ |
|
|
24
|
+
| Scheduled messages | ✅ Native | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
25
|
+
|
|
26
|
+
### Rich content
|
|
27
|
+
|
|
28
|
+
| Feature | Slack | Teams | Google Chat | Discord | Telegram | GitHub | Linear | WhatsApp |
|
|
29
|
+
|---------|-------|-------|-------------|---------|----------|--------|--------|-----------|
|
|
30
|
+
| Card format | Block Kit | Adaptive Cards | Google Chat Cards | Embeds | Markdown + inline keyboard buttons | GFM Markdown | Markdown | WhatsApp templates |
|
|
31
|
+
| Buttons | ✅ | ✅ | ✅ | ✅ | ⚠️ Inline keyboard callbacks | ❌ | ❌ | ✅ Interactive replies |
|
|
32
|
+
| Link buttons | ✅ | ✅ | ✅ | ✅ | ⚠️ Inline keyboard URLs | ❌ | ❌ | ❌ |
|
|
33
|
+
| Select menus | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
34
|
+
| Tables | ✅ Block Kit | ✅ GFM | ⚠️ ASCII | ✅ GFM | ⚠️ ASCII | ✅ GFM | ✅ GFM | ❌ |
|
|
35
|
+
| Fields | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⚠️ Template variables |
|
|
36
|
+
| Images in cards | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ |
|
|
37
|
+
| Modals | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
38
|
+
|
|
39
|
+
### Conversations
|
|
40
|
+
|
|
41
|
+
| Feature | Slack | Teams | Google Chat | Discord | Telegram | GitHub | Linear | WhatsApp |
|
|
42
|
+
|---------|-------|-------|-------------|---------|----------|--------|--------|-----------|
|
|
43
|
+
| Slash commands | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
44
|
+
| Mentions | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
|
|
45
|
+
| Add reactions | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
|
|
46
|
+
| Remove reactions | ✅ | ❌ | ✅ | ✅ | ✅ | ⚠️ | ⚠️ | ❌ |
|
|
47
|
+
| Typing indicator | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ |
|
|
48
|
+
| DMs | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ |
|
|
49
|
+
| Ephemeral messages | ✅ Native | ❌ | ✅ Native | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
50
|
+
|
|
51
|
+
### Message history
|
|
52
|
+
|
|
53
|
+
| Feature | Slack | Teams | Google Chat | Discord | Telegram | GitHub | Linear | WhatsApp |
|
|
54
|
+
|---------|-------|-------|-------------|---------|----------|--------|--------|-----------|
|
|
55
|
+
| Fetch messages | ✅ | ✅ | ✅ | ✅ | ⚠️ Cached | ✅ | ✅ | ⚠️ Cached sent messages only |
|
|
56
|
+
| Fetch single message | ✅ | ❌ | ❌ | ❌ | ⚠️ Cached | ❌ | ❌ | ⚠️ Cached sent messages only |
|
|
57
|
+
| Fetch thread info | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
|
|
58
|
+
| Fetch channel messages | ✅ | ✅ | ✅ | ✅ | ⚠️ Cached | ✅ | ❌ | ⚠️ Cached sent messages only |
|
|
59
|
+
| List threads | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ |
|
|
60
|
+
| Fetch channel info | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
|
|
61
|
+
| Post channel message | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ |
|
|
62
|
+
|
|
63
|
+
<Callout type="info">
|
|
64
|
+
⚠️ indicates partial support — the feature works with limitations. See individual adapter pages for details.
|
|
65
|
+
</Callout>
|
|
66
|
+
|
|
13
67
|
## How adapters work
|
|
14
68
|
|
|
15
69
|
Each adapter implements a standard interface that the `Chat` class uses to route events and send messages. When a webhook arrives:
|
package/docs/api/channel.mdx
CHANGED
|
@@ -104,6 +104,21 @@ await channel.post({ markdown: "**Announcement**: New release!" });
|
|
|
104
104
|
|
|
105
105
|
Accepts the same message formats as `thread.post()` — see [PostableMessage](/docs/api/postable-message).
|
|
106
106
|
|
|
107
|
+
## schedule
|
|
108
|
+
|
|
109
|
+
Schedule a message for future delivery to the channel top-level. Currently only supported by the Slack adapter — other adapters throw `NotImplementedError`.
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
const scheduled = await channel.schedule("Weekly reminder: update your status!", {
|
|
113
|
+
postAt: new Date("2026-03-10T09:00:00Z"),
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// Cancel before it's sent
|
|
117
|
+
await scheduled.cancel();
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Accepts the same message formats as `channel.post()` (except streaming). See [ScheduledMessage](/docs/api/thread#scheduledmessage) for the return type.
|
|
121
|
+
|
|
107
122
|
## fetchMetadata
|
|
108
123
|
|
|
109
124
|
Fetch channel metadata from the platform.
|
package/docs/api/index.mdx
CHANGED
|
@@ -18,6 +18,7 @@ import { Chat, root, paragraph, text, Card, Button, emoji } from "chat";
|
|
|
18
18
|
| [`Thread`](/docs/api/thread) | Conversation thread with methods for posting, subscribing, and state |
|
|
19
19
|
| [`Channel`](/docs/api/channel) | Channel/conversation container that holds threads |
|
|
20
20
|
| [`Message`](/docs/api/message) | Normalized message with text, AST, author, and metadata |
|
|
21
|
+
| [`ScheduledMessage`](/docs/api/thread#scheduledmessage) | Returned by `thread.schedule()` / `channel.schedule()` with `cancel()` |
|
|
21
22
|
|
|
22
23
|
## Message formats
|
|
23
24
|
|
package/docs/api/thread.mdx
CHANGED
|
@@ -93,6 +93,27 @@ await thread.postEphemeral(userId, "Only you can see this", {
|
|
|
93
93
|
|
|
94
94
|
**Returns:** `Promise<EphemeralMessage | null>`
|
|
95
95
|
|
|
96
|
+
## schedule
|
|
97
|
+
|
|
98
|
+
Schedule a message for future delivery. Currently only supported by the Slack adapter — other adapters throw `NotImplementedError`.
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
const scheduled = await thread.schedule("Reminder: standup in 5 minutes!", {
|
|
102
|
+
postAt: new Date("2026-03-09T09:00:00Z"),
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Cancel before it's sent
|
|
106
|
+
await scheduled.cancel();
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Parameters:** `message: string | PostableMessage | CardJSXElement`, `options: { postAt: Date }`
|
|
110
|
+
|
|
111
|
+
**Returns:** `Promise<ScheduledMessage>`
|
|
112
|
+
|
|
113
|
+
<Callout type="warn">
|
|
114
|
+
Streaming and file uploads are not supported in scheduled messages.
|
|
115
|
+
</Callout>
|
|
116
|
+
|
|
96
117
|
## subscribe / unsubscribe
|
|
97
118
|
|
|
98
119
|
Manage thread subscriptions. Subscribed threads route all messages to `onSubscribedMessage` handlers.
|
|
@@ -190,6 +211,35 @@ await data.thread.post("Hello from workflow!");
|
|
|
190
211
|
|
|
191
212
|
Under the hood, the reviver calls `ThreadImpl.fromJSON()` and `Message.fromJSON()` for any serialized objects it encounters.
|
|
192
213
|
|
|
214
|
+
## ScheduledMessage
|
|
215
|
+
|
|
216
|
+
Returned by `thread.schedule()` and `channel.schedule()`.
|
|
217
|
+
|
|
218
|
+
<TypeTable
|
|
219
|
+
type={{
|
|
220
|
+
scheduledMessageId: {
|
|
221
|
+
description: 'Platform-specific scheduled message ID.',
|
|
222
|
+
type: 'string',
|
|
223
|
+
},
|
|
224
|
+
channelId: {
|
|
225
|
+
description: 'Channel ID where the message will be posted.',
|
|
226
|
+
type: 'string',
|
|
227
|
+
},
|
|
228
|
+
postAt: {
|
|
229
|
+
description: 'When the message will be sent.',
|
|
230
|
+
type: 'Date',
|
|
231
|
+
},
|
|
232
|
+
raw: {
|
|
233
|
+
description: 'Platform-specific raw response.',
|
|
234
|
+
type: 'unknown',
|
|
235
|
+
},
|
|
236
|
+
'cancel()': {
|
|
237
|
+
description: 'Cancel the scheduled message before it is sent.',
|
|
238
|
+
type: '() => Promise<void>',
|
|
239
|
+
},
|
|
240
|
+
}}
|
|
241
|
+
/>
|
|
242
|
+
|
|
193
243
|
## SentMessage
|
|
194
244
|
|
|
195
245
|
Returned by `thread.post()`. Extends `Message` with mutation methods.
|
|
@@ -542,6 +542,7 @@ These methods are not required but extend your adapter's capabilities:
|
|
|
542
542
|
| `fetchMessage(threadId, messageId)` | Fetch a single message by ID |
|
|
543
543
|
| `fetchChannelMessages(channelId)` | Fetch top-level channel messages |
|
|
544
544
|
| `channelIdFromThreadId(threadId)` | Extract channel ID from a thread ID |
|
|
545
|
+
| `scheduleMessage(threadId, message, options)` | Schedule a message for future delivery; return a `ScheduledMessage` with `cancel()` |
|
|
545
546
|
|
|
546
547
|
Implement only the methods your platform supports. The SDK gracefully handles missing optional methods.
|
|
547
548
|
|
package/docs/error-handling.mdx
CHANGED
|
@@ -66,7 +66,7 @@ try {
|
|
|
66
66
|
|
|
67
67
|
### NotImplementedError
|
|
68
68
|
|
|
69
|
-
Thrown when you call a feature that a platform doesn't support. For example, calling `addReaction()` on Teams.
|
|
69
|
+
Thrown when you call a feature that a platform doesn't support. For example, calling `addReaction()` on Teams or `schedule()` on adapters without native scheduling support.
|
|
70
70
|
|
|
71
71
|
```typescript title="lib/bot.ts" lineNumbers
|
|
72
72
|
import { NotImplementedError } from "chat";
|
package/docs/getting-started.mdx
CHANGED
|
@@ -29,6 +29,8 @@ Step-by-step tutorials to get up and running on your platform of choice.
|
|
|
29
29
|
|
|
30
30
|
<Cards>
|
|
31
31
|
<Card title="Slack bot with Next.js and Redis" description="Build a Slack bot from scratch using Chat SDK, Next.js, and Redis." href="/docs/guides/slack-nextjs" />
|
|
32
|
+
<Card title="Durable chat sessions with Next.js, Workflow, and Redis" description="Build a bot whose thread sessions survive restarts by combining Chat SDK with Workflow." href="/docs/guides/durable-chat-sessions-nextjs" />
|
|
33
|
+
<Card title="Schedule Slack posts with Next.js, Workflow, and Neon" description="Build durable scheduled posts backed by Neon and Workflow timers." href="/docs/guides/scheduled-posts-neon" />
|
|
32
34
|
<Card title="Code review GitHub bot with Hono and Redis" description="Build a GitHub bot that reviews pull requests using AI SDK, Vercel Sandbox, and Chat SDK." href="/docs/guides/code-review-hono" />
|
|
33
35
|
<Card title="Discord support bot with Nuxt and Redis" description="Build a Discord support bot using Chat SDK, Nuxt, and AI SDK." href="/docs/guides/discord-nuxt" />
|
|
34
36
|
</Cards>
|