chat 4.13.0 → 4.13.2
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/README.md +19 -31
- package/dist/{chunk-WKJEG4FE.js → chunk-THM4ACIE.js} +12 -4
- package/dist/chunk-THM4ACIE.js.map +1 -0
- package/dist/index.d.ts +409 -415
- package/dist/index.js +63 -29
- package/dist/index.js.map +1 -1
- package/dist/{jsx-runtime-COVsDskT.d.ts → jsx-runtime-Bdt1Dwzf.d.ts} +71 -71
- package/dist/jsx-runtime.d.ts +1 -1
- package/dist/jsx-runtime.js +1 -1
- package/docs/actions.mdx +98 -0
- package/docs/adapters/discord.mdx +217 -0
- package/docs/adapters/gchat.mdx +232 -0
- package/docs/adapters/github.mdx +225 -0
- package/docs/adapters/index.mdx +110 -0
- package/docs/adapters/linear.mdx +207 -0
- package/docs/adapters/meta.json +12 -0
- package/docs/adapters/slack.mdx +293 -0
- package/docs/adapters/teams.mdx +225 -0
- package/docs/api/cards.mdx +217 -0
- package/docs/api/channel.mdx +176 -0
- package/docs/api/chat.mdx +469 -0
- package/docs/api/index.mdx +29 -0
- package/docs/api/markdown.mdx +235 -0
- package/docs/api/message.mdx +163 -0
- package/docs/api/meta.json +14 -0
- package/docs/api/modals.mdx +222 -0
- package/docs/api/postable-message.mdx +166 -0
- package/docs/api/thread.mdx +186 -0
- package/docs/cards.mdx +213 -0
- package/docs/direct-messages.mdx +56 -0
- package/docs/emoji.mdx +77 -0
- package/docs/ephemeral-messages.mdx +77 -0
- package/docs/error-handling.mdx +147 -0
- package/docs/files.mdx +77 -0
- package/docs/getting-started.mdx +12 -0
- package/docs/guides/code-review-hono.mdx +248 -0
- package/docs/guides/discord-nuxt.mdx +237 -0
- package/docs/guides/meta.json +4 -0
- package/docs/guides/slack-nextjs.mdx +245 -0
- package/docs/index.mdx +92 -0
- package/docs/meta.json +20 -0
- package/docs/modals.mdx +208 -0
- package/docs/posting-messages.mdx +177 -0
- package/docs/slash-commands.mdx +110 -0
- package/docs/state/index.mdx +31 -0
- package/docs/state/ioredis.mdx +81 -0
- package/docs/state/memory.mdx +52 -0
- package/docs/state/meta.json +9 -0
- package/docs/state/redis.mdx +93 -0
- package/docs/streaming.mdx +99 -0
- package/docs/usage.mdx +338 -0
- package/package.json +10 -10
- package/dist/chunk-WKJEG4FE.js.map +0 -1
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Linear
|
|
3
|
+
description: Configure the Linear adapter to respond to @mentions in issue comment threads.
|
|
4
|
+
type: integration
|
|
5
|
+
prerequisites:
|
|
6
|
+
- /docs/getting-started
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
The Linear adapter treats issue comments as messages and issues as threads.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```sh title="Terminal"
|
|
14
|
+
pnpm add @chat-adapter/linear
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```typescript title="lib/bot.ts" lineNumbers
|
|
20
|
+
import { Chat } from "chat";
|
|
21
|
+
import { createLinearAdapter } from "@chat-adapter/linear";
|
|
22
|
+
|
|
23
|
+
const bot = new Chat({
|
|
24
|
+
userName: "my-bot",
|
|
25
|
+
adapters: {
|
|
26
|
+
linear: createLinearAdapter({
|
|
27
|
+
apiKey: process.env.LINEAR_API_KEY!,
|
|
28
|
+
webhookSecret: process.env.LINEAR_WEBHOOK_SECRET!,
|
|
29
|
+
userName: "my-bot",
|
|
30
|
+
}),
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
bot.onNewMention(async (thread, message) => {
|
|
35
|
+
await thread.post("Hello from Linear!");
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Authentication
|
|
40
|
+
|
|
41
|
+
### Option A: Personal API key
|
|
42
|
+
|
|
43
|
+
Best for personal projects, testing, or single-workspace bots. Actions are attributed to you as an individual.
|
|
44
|
+
|
|
45
|
+
1. Go to [Settings > Security & Access](https://linear.app/settings/account/security)
|
|
46
|
+
2. Under **Personal API keys**, click **Create key**
|
|
47
|
+
3. Select **Only select permissions** and enable Create issues, Create comments
|
|
48
|
+
4. Choose team access
|
|
49
|
+
5. Click **Create** and set `LINEAR_API_KEY`
|
|
50
|
+
|
|
51
|
+
```typescript title="lib/bot.ts" lineNumbers
|
|
52
|
+
createLinearAdapter({
|
|
53
|
+
apiKey: process.env.LINEAR_API_KEY!,
|
|
54
|
+
webhookSecret: process.env.LINEAR_WEBHOOK_SECRET!,
|
|
55
|
+
userName: "my-bot",
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Option B: OAuth application (recommended)
|
|
60
|
+
|
|
61
|
+
The bot gets its own identity in Linear. The adapter handles token management internally.
|
|
62
|
+
|
|
63
|
+
1. Go to [Settings > API > Applications](https://linear.app/settings/api/applications/new)
|
|
64
|
+
2. Create an OAuth2 application with your bot's name and icon
|
|
65
|
+
3. **Enable client credentials tokens** in the app settings
|
|
66
|
+
4. Note the **Client ID** and **Client Secret**
|
|
67
|
+
|
|
68
|
+
```typescript title="lib/bot.ts" lineNumbers
|
|
69
|
+
createLinearAdapter({
|
|
70
|
+
clientId: process.env.LINEAR_CLIENT_ID!,
|
|
71
|
+
clientSecret: process.env.LINEAR_CLIENT_SECRET!,
|
|
72
|
+
webhookSecret: process.env.LINEAR_WEBHOOK_SECRET!,
|
|
73
|
+
userName: "my-bot",
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The adapter uses the client credentials grant to obtain tokens automatically. Tokens are valid for 30 days and auto-refresh when expired.
|
|
78
|
+
|
|
79
|
+
### Making the bot @-mentionable (optional)
|
|
80
|
+
|
|
81
|
+
To make the bot appear in Linear's `@` mention dropdown as an Agent:
|
|
82
|
+
|
|
83
|
+
1. In your OAuth app settings, enable **Agent session events** under webhooks
|
|
84
|
+
2. Have a workspace admin install the app with `actor=app` and the `app:mentionable` scope:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
https://linear.app/oauth/authorize?
|
|
88
|
+
client_id=your_client_id&
|
|
89
|
+
redirect_uri=https://your-domain.com/callback&
|
|
90
|
+
response_type=code&
|
|
91
|
+
scope=read,write,comments:create,app:mentionable&
|
|
92
|
+
actor=app
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
See the [Linear Agents docs](https://linear.app/developers/agents) for full details.
|
|
96
|
+
|
|
97
|
+
## Webhook setup
|
|
98
|
+
|
|
99
|
+
<Callout type="info">
|
|
100
|
+
Webhook management requires workspace admin access. If you don't see the API settings page, ask a workspace admin to create the webhook for you.
|
|
101
|
+
</Callout>
|
|
102
|
+
|
|
103
|
+
1. Go to **Settings > API** and click **Create webhook**
|
|
104
|
+
2. Fill in:
|
|
105
|
+
- **Label**: A descriptive name (e.g., "Chat Bot")
|
|
106
|
+
- **URL**: `https://your-domain.com/api/webhooks/linear`
|
|
107
|
+
3. Copy the **Signing secret** as `LINEAR_WEBHOOK_SECRET`
|
|
108
|
+
4. Under **Data change events**, select:
|
|
109
|
+
- **Comments** (required)
|
|
110
|
+
- **Issues** (recommended)
|
|
111
|
+
- **Emoji reactions** (optional)
|
|
112
|
+
5. Under **Team selection**, choose **All public teams** or a specific team
|
|
113
|
+
6. Click **Create webhook**
|
|
114
|
+
|
|
115
|
+
## Thread model
|
|
116
|
+
|
|
117
|
+
Linear has two levels of comment threading:
|
|
118
|
+
|
|
119
|
+
| Type | Description | Thread ID format |
|
|
120
|
+
|------|-------------|-----------------|
|
|
121
|
+
| Issue-level | Top-level comments on an issue | `linear:{issueId}` |
|
|
122
|
+
| Comment thread | Replies nested under a specific comment | `linear:{issueId}:c:{commentId}` |
|
|
123
|
+
|
|
124
|
+
When a user writes a comment, the bot replies within the same comment thread.
|
|
125
|
+
|
|
126
|
+
## Reactions
|
|
127
|
+
|
|
128
|
+
| SDK emoji | Linear emoji |
|
|
129
|
+
|-----------|-------------|
|
|
130
|
+
| `thumbs_up` | 👍 |
|
|
131
|
+
| `thumbs_down` | 👎 |
|
|
132
|
+
| `heart` | ❤️ |
|
|
133
|
+
| `fire` | 🔥 |
|
|
134
|
+
| `rocket` | 🚀 |
|
|
135
|
+
| `eyes` | 👀 |
|
|
136
|
+
| `sparkles` | ✨ |
|
|
137
|
+
| `wave` | 👋 |
|
|
138
|
+
|
|
139
|
+
## Configuration
|
|
140
|
+
|
|
141
|
+
| Option | Required | Description |
|
|
142
|
+
|--------|----------|-------------|
|
|
143
|
+
| `apiKey` | Yes* | Personal API key |
|
|
144
|
+
| `clientId` | Yes* | OAuth app client ID |
|
|
145
|
+
| `clientSecret` | Yes* | OAuth app client secret |
|
|
146
|
+
| `accessToken` | Yes* | Pre-obtained OAuth access token |
|
|
147
|
+
| `webhookSecret` | Yes | Webhook signing secret for verification |
|
|
148
|
+
| `userName` | Yes | Bot display name for @mention detection |
|
|
149
|
+
|
|
150
|
+
*One of `apiKey`, `clientId`/`clientSecret`, or `accessToken` is required.
|
|
151
|
+
|
|
152
|
+
## Environment variables
|
|
153
|
+
|
|
154
|
+
```bash title=".env.local"
|
|
155
|
+
# API Key auth
|
|
156
|
+
LINEAR_API_KEY=lin_api_xxxxxxxxxxxx
|
|
157
|
+
|
|
158
|
+
# OR OAuth app auth
|
|
159
|
+
LINEAR_CLIENT_ID=your-client-id
|
|
160
|
+
LINEAR_CLIENT_SECRET=your-client-secret
|
|
161
|
+
|
|
162
|
+
# Required
|
|
163
|
+
LINEAR_WEBHOOK_SECRET=your-webhook-secret
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Features
|
|
167
|
+
|
|
168
|
+
| Feature | Supported |
|
|
169
|
+
|---------|-----------|
|
|
170
|
+
| Mentions | Yes |
|
|
171
|
+
| Reactions (add) | Yes |
|
|
172
|
+
| Cards | Markdown |
|
|
173
|
+
| Modals | No |
|
|
174
|
+
| Streaming | No |
|
|
175
|
+
| DMs | No |
|
|
176
|
+
| File uploads | No |
|
|
177
|
+
| Typing indicator | No |
|
|
178
|
+
| Message history | Yes |
|
|
179
|
+
|
|
180
|
+
## Limitations
|
|
181
|
+
|
|
182
|
+
- **No typing indicators** — Linear doesn't support typing indicators
|
|
183
|
+
- **No streaming** — Messages posted in full (editing supported for updates)
|
|
184
|
+
- **No DMs** — Linear doesn't have direct messages
|
|
185
|
+
- **No modals** — Linear doesn't support interactive modals
|
|
186
|
+
- **Action buttons** — Rendered as text; use link buttons for clickable actions
|
|
187
|
+
- **Remove reaction** — Requires reaction ID lookup (not directly supported)
|
|
188
|
+
|
|
189
|
+
## Troubleshooting
|
|
190
|
+
|
|
191
|
+
### "Invalid signature" error
|
|
192
|
+
|
|
193
|
+
- Verify `LINEAR_WEBHOOK_SECRET` matches the secret from your webhook configuration
|
|
194
|
+
- The webhook secret is shown only once at creation — regenerate if lost
|
|
195
|
+
|
|
196
|
+
### Bot not responding to mentions
|
|
197
|
+
|
|
198
|
+
- Verify webhook events are configured with **Comments** resource type
|
|
199
|
+
- Check that the webhook URL is correct and accessible
|
|
200
|
+
- Ensure the `userName` config matches how users mention the bot
|
|
201
|
+
- Linear may auto-disable webhooks after repeated failures
|
|
202
|
+
|
|
203
|
+
### "Webhook expired" error
|
|
204
|
+
|
|
205
|
+
- Webhook timestamp is too old (> 5 minutes)
|
|
206
|
+
- Usually indicates a delivery delay or clock skew
|
|
207
|
+
- Check that your server time is synchronized
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Slack
|
|
3
|
+
description: Configure the Slack adapter for single-workspace or multi-workspace OAuth deployments.
|
|
4
|
+
type: integration
|
|
5
|
+
prerequisites:
|
|
6
|
+
- /docs/getting-started
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```sh title="Terminal"
|
|
12
|
+
pnpm add @chat-adapter/slack
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Single-workspace mode
|
|
16
|
+
|
|
17
|
+
For bots deployed to a single Slack workspace:
|
|
18
|
+
|
|
19
|
+
```typescript title="lib/bot.ts" lineNumbers
|
|
20
|
+
import { Chat } from "chat";
|
|
21
|
+
import { createSlackAdapter } from "@chat-adapter/slack";
|
|
22
|
+
|
|
23
|
+
const bot = new Chat({
|
|
24
|
+
userName: "mybot",
|
|
25
|
+
adapters: {
|
|
26
|
+
slack: createSlackAdapter({
|
|
27
|
+
botToken: process.env.SLACK_BOT_TOKEN!,
|
|
28
|
+
signingSecret: process.env.SLACK_SIGNING_SECRET!,
|
|
29
|
+
}),
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
bot.onNewMention(async (thread, message) => {
|
|
34
|
+
await thread.post("Hello from Slack!");
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Multi-workspace mode
|
|
39
|
+
|
|
40
|
+
For apps installed across multiple Slack workspaces via OAuth, omit `botToken` and provide OAuth credentials instead. The adapter resolves tokens dynamically from your state adapter using the `team_id` from incoming webhooks.
|
|
41
|
+
|
|
42
|
+
```typescript title="lib/bot.ts" lineNumbers
|
|
43
|
+
import { createSlackAdapter } from "@chat-adapter/slack";
|
|
44
|
+
import { createRedisState } from "@chat-adapter/state-redis";
|
|
45
|
+
|
|
46
|
+
const slackAdapter = createSlackAdapter({
|
|
47
|
+
signingSecret: process.env.SLACK_SIGNING_SECRET!,
|
|
48
|
+
clientId: process.env.SLACK_CLIENT_ID!,
|
|
49
|
+
clientSecret: process.env.SLACK_CLIENT_SECRET!,
|
|
50
|
+
encryptionKey: process.env.SLACK_ENCRYPTION_KEY,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const bot = new Chat({
|
|
54
|
+
userName: "mybot",
|
|
55
|
+
adapters: { slack: slackAdapter },
|
|
56
|
+
state: createRedisState({ url: process.env.REDIS_URL! }),
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### OAuth callback
|
|
61
|
+
|
|
62
|
+
The adapter handles the full Slack OAuth V2 exchange. Point your OAuth redirect URL to a route that calls `handleOAuthCallback`:
|
|
63
|
+
|
|
64
|
+
```typescript title="app/api/slack/install/callback/route.ts"
|
|
65
|
+
import { slackAdapter } from "@/lib/bot";
|
|
66
|
+
|
|
67
|
+
export async function GET(request: Request) {
|
|
68
|
+
const { teamId } = await slackAdapter.handleOAuthCallback(request);
|
|
69
|
+
return new Response(`Installed for team ${teamId}!`);
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Using the adapter outside webhooks
|
|
74
|
+
|
|
75
|
+
During webhook handling, the adapter resolves tokens automatically from `team_id`. Outside that context (e.g. cron jobs or background workers), use `getInstallation` and `withBotToken`:
|
|
76
|
+
|
|
77
|
+
```typescript title="lib/bot.ts" lineNumbers
|
|
78
|
+
const install = await slackAdapter.getInstallation(teamId);
|
|
79
|
+
if (!install) throw new Error("Workspace not installed");
|
|
80
|
+
|
|
81
|
+
await slackAdapter.withBotToken(install.botToken, async () => {
|
|
82
|
+
const thread = bot.thread("slack:C12345:1234567890.123456");
|
|
83
|
+
await thread.post("Hello from a cron job!");
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`withBotToken` uses `AsyncLocalStorage` under the hood, so concurrent calls with different tokens are isolated.
|
|
88
|
+
|
|
89
|
+
### Removing installations
|
|
90
|
+
|
|
91
|
+
```typescript title="lib/bot.ts"
|
|
92
|
+
await slackAdapter.deleteInstallation(teamId);
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Token encryption
|
|
96
|
+
|
|
97
|
+
Pass a base64-encoded 32-byte key as `encryptionKey` to encrypt bot tokens at rest using AES-256-GCM:
|
|
98
|
+
|
|
99
|
+
```sh title="Terminal"
|
|
100
|
+
openssl rand -base64 32
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
When `encryptionKey` is set, `setInstallation()` encrypts the token before storing and `getInstallation()` decrypts it transparently.
|
|
104
|
+
|
|
105
|
+
## Slack app setup
|
|
106
|
+
|
|
107
|
+
### 1. Create a Slack app from manifest
|
|
108
|
+
|
|
109
|
+
1. Go to [api.slack.com/apps](https://api.slack.com/apps)
|
|
110
|
+
2. Click **Create New App** then **From an app manifest**
|
|
111
|
+
3. Select your workspace and paste the following manifest:
|
|
112
|
+
|
|
113
|
+
```yaml title="slack-manifest.yml"
|
|
114
|
+
display_information:
|
|
115
|
+
name: My Bot
|
|
116
|
+
description: A bot built with chat-sdk
|
|
117
|
+
|
|
118
|
+
features:
|
|
119
|
+
bot_user:
|
|
120
|
+
display_name: My Bot
|
|
121
|
+
always_online: true
|
|
122
|
+
|
|
123
|
+
oauth_config:
|
|
124
|
+
scopes:
|
|
125
|
+
bot:
|
|
126
|
+
- app_mentions:read
|
|
127
|
+
- channels:history
|
|
128
|
+
- channels:read
|
|
129
|
+
- chat:write
|
|
130
|
+
- groups:history
|
|
131
|
+
- groups:read
|
|
132
|
+
- im:history
|
|
133
|
+
- im:read
|
|
134
|
+
- mpim:history
|
|
135
|
+
- mpim:read
|
|
136
|
+
- reactions:read
|
|
137
|
+
- reactions:write
|
|
138
|
+
- users:read
|
|
139
|
+
|
|
140
|
+
settings:
|
|
141
|
+
event_subscriptions:
|
|
142
|
+
request_url: https://your-domain.com/api/webhooks/slack
|
|
143
|
+
bot_events:
|
|
144
|
+
- app_mention
|
|
145
|
+
- message.channels
|
|
146
|
+
- message.groups
|
|
147
|
+
- message.im
|
|
148
|
+
- message.mpim
|
|
149
|
+
- assistant_thread_started
|
|
150
|
+
- assistant_thread_context_changed
|
|
151
|
+
interactivity:
|
|
152
|
+
is_enabled: true
|
|
153
|
+
request_url: https://your-domain.com/api/webhooks/slack
|
|
154
|
+
org_deploy_enabled: false
|
|
155
|
+
socket_mode_enabled: false
|
|
156
|
+
token_rotation_enabled: false
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
4. Replace `https://your-domain.com/api/webhooks/slack` with your deployed webhook URL
|
|
160
|
+
5. Click **Create**
|
|
161
|
+
|
|
162
|
+
### 2. Get credentials
|
|
163
|
+
|
|
164
|
+
After creating the app, go to **Basic Information** → **App Credentials** and copy:
|
|
165
|
+
|
|
166
|
+
- **Signing Secret** as `SLACK_SIGNING_SECRET`
|
|
167
|
+
- **Client ID** as `SLACK_CLIENT_ID` (multi-workspace only)
|
|
168
|
+
- **Client Secret** as `SLACK_CLIENT_SECRET` (multi-workspace only)
|
|
169
|
+
|
|
170
|
+
**Single workspace:** Go to **OAuth & Permissions**, click **Install to Workspace**, and copy the **Bot User OAuth Token** (`xoxb-...`) as `SLACK_BOT_TOKEN`.
|
|
171
|
+
|
|
172
|
+
**Multi-workspace:** Enable **Manage Distribution** under **Basic Information** and set up an OAuth redirect URL pointing to your callback route.
|
|
173
|
+
|
|
174
|
+
### 3. Configure slash commands (optional)
|
|
175
|
+
|
|
176
|
+
1. Go to **Slash Commands** in your app settings
|
|
177
|
+
2. Click **Create New Command**
|
|
178
|
+
3. Set **Command** (e.g., `/feedback`)
|
|
179
|
+
4. Set **Request URL** to `https://your-domain.com/api/webhooks/slack`
|
|
180
|
+
5. Add a description and click **Save**
|
|
181
|
+
|
|
182
|
+
## Configuration
|
|
183
|
+
|
|
184
|
+
| Option | Required | Description |
|
|
185
|
+
|--------|----------|-------------|
|
|
186
|
+
| `botToken` | No | Bot token (`xoxb-...`). Required for single-workspace, omit for multi-workspace |
|
|
187
|
+
| `signingSecret` | Yes | Signing secret for webhook verification |
|
|
188
|
+
| `clientId` | No | App client ID (required for multi-workspace OAuth) |
|
|
189
|
+
| `clientSecret` | No | App client secret (required for multi-workspace OAuth) |
|
|
190
|
+
| `encryptionKey` | No | Base64-encoded 32-byte AES-256-GCM key for encrypting stored tokens |
|
|
191
|
+
|
|
192
|
+
## Environment variables
|
|
193
|
+
|
|
194
|
+
```bash title=".env.local"
|
|
195
|
+
SLACK_BOT_TOKEN=xoxb-... # Single-workspace only
|
|
196
|
+
SLACK_SIGNING_SECRET=...
|
|
197
|
+
SLACK_CLIENT_ID=... # Multi-workspace only
|
|
198
|
+
SLACK_CLIENT_SECRET=... # Multi-workspace only
|
|
199
|
+
SLACK_ENCRYPTION_KEY=... # Optional, for token encryption
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Features
|
|
203
|
+
|
|
204
|
+
| Feature | Supported |
|
|
205
|
+
|---------|-----------|
|
|
206
|
+
| Mentions | Yes |
|
|
207
|
+
| Reactions (add/remove) | Yes |
|
|
208
|
+
| Cards (Block Kit) | Yes |
|
|
209
|
+
| Modals | Yes |
|
|
210
|
+
| Slash commands | Yes |
|
|
211
|
+
| Streaming | Native API |
|
|
212
|
+
| DMs | Yes |
|
|
213
|
+
| Ephemeral messages | Yes (native) |
|
|
214
|
+
| File uploads | Yes |
|
|
215
|
+
| Typing indicator | Yes |
|
|
216
|
+
| Message history | Yes |
|
|
217
|
+
| Assistants API | Yes |
|
|
218
|
+
| App Home tab | Yes |
|
|
219
|
+
|
|
220
|
+
## Slack Assistants API
|
|
221
|
+
|
|
222
|
+
The adapter supports Slack's [Assistants API](https://api.slack.com/docs/apps/ai) for building AI-powered assistant experiences. This enables suggested prompts, status indicators, and thread titles in assistant DM threads.
|
|
223
|
+
|
|
224
|
+
### Event handlers
|
|
225
|
+
|
|
226
|
+
Register handlers on the `Chat` instance:
|
|
227
|
+
|
|
228
|
+
```typescript title="lib/bot.ts" lineNumbers
|
|
229
|
+
bot.onAssistantThreadStarted(async (event) => {
|
|
230
|
+
const slack = bot.getAdapter("slack") as SlackAdapter;
|
|
231
|
+
await slack.setSuggestedPrompts(event.channelId, event.threadTs, [
|
|
232
|
+
{ title: "Summarize", message: "Summarize this channel" },
|
|
233
|
+
{ title: "Draft", message: "Help me draft a message" },
|
|
234
|
+
]);
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
bot.onAssistantContextChanged(async (event) => {
|
|
238
|
+
// User navigated to a different channel with the assistant panel open
|
|
239
|
+
});
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Adapter methods
|
|
243
|
+
|
|
244
|
+
The `SlackAdapter` exposes these methods for the Assistants API:
|
|
245
|
+
|
|
246
|
+
| Method | Description |
|
|
247
|
+
|--------|-------------|
|
|
248
|
+
| `setSuggestedPrompts(channelId, threadTs, prompts, title?)` | Show prompt suggestions in the thread |
|
|
249
|
+
| `setAssistantStatus(channelId, threadTs, status)` | Show a thinking/status indicator |
|
|
250
|
+
| `setAssistantTitle(channelId, threadTs, title)` | Set the thread title (shown in History) |
|
|
251
|
+
| `publishHomeView(userId, view)` | Publish a Home tab view for a user |
|
|
252
|
+
|
|
253
|
+
### Required scopes and events
|
|
254
|
+
|
|
255
|
+
Add these to your Slack app manifest for Assistants API support:
|
|
256
|
+
|
|
257
|
+
```yaml title="slack-manifest.yml"
|
|
258
|
+
oauth_config:
|
|
259
|
+
scopes:
|
|
260
|
+
bot:
|
|
261
|
+
- assistant:write
|
|
262
|
+
|
|
263
|
+
settings:
|
|
264
|
+
event_subscriptions:
|
|
265
|
+
bot_events:
|
|
266
|
+
- assistant_thread_started
|
|
267
|
+
- assistant_thread_context_changed
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Stream with stop blocks
|
|
271
|
+
|
|
272
|
+
When streaming in an assistant thread, you can attach Block Kit elements to the final message:
|
|
273
|
+
|
|
274
|
+
```typescript title="lib/bot.ts"
|
|
275
|
+
await thread.stream(textStream, {
|
|
276
|
+
stopBlocks: [
|
|
277
|
+
{ type: "actions", elements: [{ type: "button", text: { type: "plain_text", text: "Retry" }, action_id: "retry" }] },
|
|
278
|
+
],
|
|
279
|
+
});
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Troubleshooting
|
|
283
|
+
|
|
284
|
+
### "Invalid signature" error
|
|
285
|
+
|
|
286
|
+
- Verify `SLACK_SIGNING_SECRET` is correct
|
|
287
|
+
- Check that the request timestamp is within 5 minutes (clock sync issue)
|
|
288
|
+
|
|
289
|
+
### Bot not responding to messages
|
|
290
|
+
|
|
291
|
+
- Verify event subscriptions are configured
|
|
292
|
+
- Check that the bot has been added to the channel
|
|
293
|
+
- Ensure the webhook URL is correct and accessible
|